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