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