Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
bevyengine
GitHub Repository: bevyengine/bevy
Path: blob/main/crates/bevy_ui_render/src/debug_overlay.rs
6596 views
1
use super::ExtractedUiItem;
2
use super::ExtractedUiNode;
3
use super::ExtractedUiNodes;
4
use super::NodeType;
5
use super::UiCameraMap;
6
use crate::shader_flags;
7
use bevy_asset::AssetId;
8
use bevy_camera::visibility::InheritedVisibility;
9
use bevy_color::Hsla;
10
use bevy_ecs::entity::Entity;
11
use bevy_ecs::resource::Resource;
12
use bevy_ecs::system::Commands;
13
use bevy_ecs::system::Query;
14
use bevy_ecs::system::Res;
15
use bevy_ecs::system::ResMut;
16
use bevy_math::Rect;
17
use bevy_math::Vec2;
18
use bevy_render::sync_world::TemporaryRenderEntity;
19
use bevy_render::Extract;
20
use bevy_sprite::BorderRect;
21
use bevy_ui::ui_transform::UiGlobalTransform;
22
use bevy_ui::CalculatedClip;
23
use bevy_ui::ComputedNode;
24
use bevy_ui::ComputedUiTargetCamera;
25
use bevy_ui::UiStack;
26
27
/// Configuration for the UI debug overlay
28
#[derive(Resource)]
29
pub struct UiDebugOptions {
30
/// Set to true to enable the UI debug overlay
31
pub enabled: bool,
32
/// Width of the overlay's lines in logical pixels
33
pub line_width: f32,
34
/// Show outlines for non-visible UI nodes
35
pub show_hidden: bool,
36
/// Show outlines for clipped sections of UI nodes
37
pub show_clipped: bool,
38
}
39
40
impl UiDebugOptions {
41
pub fn toggle(&mut self) {
42
self.enabled = !self.enabled;
43
}
44
}
45
46
impl Default for UiDebugOptions {
47
fn default() -> Self {
48
Self {
49
enabled: false,
50
line_width: 1.,
51
show_hidden: false,
52
show_clipped: false,
53
}
54
}
55
}
56
57
pub fn extract_debug_overlay(
58
mut commands: Commands,
59
debug_options: Extract<Res<UiDebugOptions>>,
60
mut extracted_uinodes: ResMut<ExtractedUiNodes>,
61
uinode_query: Extract<
62
Query<(
63
Entity,
64
&ComputedNode,
65
&UiGlobalTransform,
66
&InheritedVisibility,
67
Option<&CalculatedClip>,
68
&ComputedUiTargetCamera,
69
)>,
70
>,
71
ui_stack: Extract<Res<UiStack>>,
72
camera_map: Extract<UiCameraMap>,
73
) {
74
if !debug_options.enabled {
75
return;
76
}
77
78
let mut camera_mapper = camera_map.get_mapper();
79
80
for (entity, uinode, transform, visibility, maybe_clip, computed_target) in &uinode_query {
81
if !debug_options.show_hidden && !visibility.get() {
82
continue;
83
}
84
85
let Some(extracted_camera_entity) = camera_mapper.map(computed_target) else {
86
continue;
87
};
88
89
// Extract a border box to display an outline for every UI Node in the layout
90
extracted_uinodes.uinodes.push(ExtractedUiNode {
91
render_entity: commands.spawn(TemporaryRenderEntity).id(),
92
// Add a large number to the UI node's stack index so that the overlay is always drawn on top
93
z_order: (ui_stack.uinodes.len() as u32 + uinode.stack_index()) as f32,
94
clip: maybe_clip
95
.filter(|_| !debug_options.show_clipped)
96
.map(|clip| clip.clip),
97
image: AssetId::default(),
98
extracted_camera_entity,
99
transform: transform.into(),
100
item: ExtractedUiItem::Node {
101
color: Hsla::sequential_dispersed(entity.index()).into(),
102
rect: Rect {
103
min: Vec2::ZERO,
104
max: uinode.size,
105
},
106
atlas_scaling: None,
107
flip_x: false,
108
flip_y: false,
109
border: BorderRect::all(debug_options.line_width / uinode.inverse_scale_factor()),
110
border_radius: uinode.border_radius(),
111
node_type: NodeType::Border(shader_flags::BORDER_ALL),
112
},
113
main_entity: entity.into(),
114
});
115
}
116
}
117
118