Skip to content
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions _release-content/migration-guides/computed_stack_index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
title: "`ComputedNode::stack_index` has been replaced by `ComputedStackIndex`"
pull_requests: [23878]
---

The `stack_index` field has been removed from `ComputedNode`. Instead the stack index for each UI node is stored on a specialized component `ComputedStackIndex`, which is required by `ComputedNode`.

2 changes: 1 addition & 1 deletion crates/bevy_ui/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ use bevy_input::InputSystems;
use bevy_transform::TransformSystems;
use layout::ui_surface::UiSurface;
use stack::ui_stack_system;
pub use stack::UiStack;
pub use stack::{ComputedStackIndex, UiStack};
use update::{propagate_ui_target_cameras, update_clipping_system};

/// The basic plugin for Bevy UI
Expand Down
25 changes: 18 additions & 7 deletions crates/bevy_ui/src/stack.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,19 @@

use crate::{
experimental::{UiChildren, UiRootNodes},
ComputedNode, GlobalZIndex, ZIndex,
GlobalZIndex, ZIndex,
};
use bevy_derive::{Deref, DerefMut};
use bevy_ecs::{entity::EntityHashSet, prelude::*};
use core::ops::Range;

/// The order of the node in the UI layout.
/// Nodes with a higher stack index are drawn on top of and receive interactions before nodes with lower stack indices.
///
/// Automatically calculated in [`UiSystems::Stack`](`super::UiSystems::Stack`).
#[derive(Component, Default, PartialEq, Eq, Deref, DerefMut)]
pub struct ComputedStackIndex(pub u32);

/// The current UI stack, which contains all UI nodes ordered by their depth (back-to-front).
///
/// The first entry is the furthest node from the camera and is the first one to get rendered
Expand Down Expand Up @@ -46,10 +54,13 @@ pub fn ui_stack_system(
mut ui_stack: ResMut<UiStack>,
ui_root_nodes: UiRootNodes,
root_node_query: Query<(Entity, Option<&GlobalZIndex>, Option<&ZIndex>)>,
zindex_global_node_query: Query<(Entity, &GlobalZIndex, Option<&ZIndex>), With<ComputedNode>>,
zindex_global_node_query: Query<
(Entity, &GlobalZIndex, Option<&ZIndex>),
With<ComputedStackIndex>,
>,
ui_children: UiChildren,
zindex_query: Query<Option<&ZIndex>, (With<ComputedNode>, Without<GlobalZIndex>)>,
mut update_query: Query<&mut ComputedNode>,
zindex_query: Query<Option<&ZIndex>, (With<ComputedStackIndex>, Without<GlobalZIndex>)>,
mut update_query: Query<&mut ComputedStackIndex>,
) {
ui_stack.partition.clear();
ui_stack.uinodes.clear();
Expand Down Expand Up @@ -96,8 +107,8 @@ pub fn ui_stack_system(
}

for (i, entity) in ui_stack.uinodes.iter().enumerate() {
if let Ok(mut node) = update_query.get_mut(*entity) {
node.bypass_change_detection().stack_index = i as u32;
if let Ok(mut stack_index) = update_query.get_mut(*entity) {
stack_index.0 = i as u32;
}
}
}
Expand All @@ -106,7 +117,7 @@ fn update_uistack_recursive(
cache: &mut ChildBufferCache,
node_entity: Entity,
ui_children: &UiChildren,
zindex_query: &Query<Option<&ZIndex>, (With<ComputedNode>, Without<GlobalZIndex>)>,
zindex_query: &Query<Option<&ZIndex>, (With<ComputedStackIndex>, Without<GlobalZIndex>)>,
ui_stack: &mut Vec<Entity>,
) {
ui_stack.push(node_entity);
Expand Down
18 changes: 3 additions & 15 deletions crates/bevy_ui/src/ui_node.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::{
ui_transform::{UiGlobalTransform, UiTransform},
ContentSize, FocusPolicy, UiRect, Val,
ComputedStackIndex, ContentSize, FocusPolicy, UiRect, Val,
};
use bevy_camera::{visibility::Visibility, Camera, RenderTarget};
use bevy_color::{Alpha, Color};
Expand All @@ -25,12 +25,8 @@ use tracing::warn;
/// handle size without any delays.
#[derive(Component, Debug, Copy, Clone, PartialEq, Reflect)]
#[reflect(Component, Default, Debug, Clone)]
#[require(ComputedStackIndex)]
pub struct ComputedNode {
/// The order of the node in the UI layout.
/// Nodes with a higher stack index are drawn on top of and receive interactions before nodes with lower stack indices.
///
/// Automatically calculated in [`UiSystems::Stack`](`super::UiSystems::Stack`).
pub stack_index: u32,
/// The size of the node as width and height in physical pixels.
///
/// Automatically calculated by [`ui_layout_system`](`super::layout::ui_layout_system`).
Expand Down Expand Up @@ -108,14 +104,6 @@ impl ComputedNode {
self.size.x <= 0. || self.size.y <= 0.
}

/// The order of the node in the UI layout.
/// Nodes with a higher stack index are drawn on top of and receive interactions before nodes with lower stack indices.
///
/// Automatically calculated in [`UiSystems::Stack`](super::UiSystems::Stack).
pub const fn stack_index(&self) -> u32 {
self.stack_index
}

/// The calculated node size as width and height in physical pixels before rounding.
///
/// Automatically calculated by [`ui_layout_system`](`super::layout::ui_layout_system`).
Expand Down Expand Up @@ -393,7 +381,6 @@ impl ComputedNode {

impl ComputedNode {
pub const DEFAULT: Self = Self {
stack_index: 0,
size: Vec2::ZERO,
content_size: Vec2::ZERO,
scrollbar_size: Vec2::ZERO,
Expand Down Expand Up @@ -481,6 +468,7 @@ impl From<BVec2> for IgnoreScroll {
#[derive(Component, Clone, PartialEq, Debug, Reflect)]
#[require(
ComputedNode,
ComputedStackIndex,
ContentSize,
ComputedUiTargetCamera,
ComputedUiRenderTargetInfo,
Expand Down
9 changes: 5 additions & 4 deletions crates/bevy_ui_render/src/box_shadow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ use bevy_render::{
use bevy_render::{GpuResourceAppExt, RenderApp, RenderStartup};
use bevy_shader::{Shader, ShaderDefVal};
use bevy_ui::{
BoxShadow, CalculatedClip, ComputedNode, ComputedUiRenderTargetInfo, ComputedUiTargetCamera,
ResolvedBorderRadius, UiGlobalTransform, Val,
BoxShadow, CalculatedClip, ComputedNode, ComputedStackIndex, ComputedUiRenderTargetInfo,
ComputedUiTargetCamera, ResolvedBorderRadius, UiGlobalTransform, Val,
};
use bevy_utils::default;
use bytemuck::{Pod, Zeroable};
Expand Down Expand Up @@ -210,6 +210,7 @@ pub fn extract_shadows(
Query<(
Entity,
&ComputedNode,
&ComputedStackIndex,
&UiGlobalTransform,
&InheritedVisibility,
&BoxShadow,
Expand All @@ -222,7 +223,7 @@ pub fn extract_shadows(
) {
let mut mapping = camera_map.get_mapper();

for (entity, uinode, transform, visibility, box_shadow, clip, camera, target) in
for (entity, uinode, stack_index, transform, visibility, box_shadow, clip, camera, target) in
&box_shadow_query
{
// Skip if no visible shadows
Expand Down Expand Up @@ -277,7 +278,7 @@ pub fn extract_shadows(

extracted_box_shadows.box_shadows.push(ExtractedBoxShadow {
render_entity: commands.spawn(TemporaryRenderEntity).id(),
stack_index: uinode.stack_index,
stack_index: stack_index.0,
transform: Affine2::from(transform) * Affine2::from_translation(offset),
color: drop_shadow.color.into(),
bounds: shadow_size + 6. * blur_radius,
Expand Down
7 changes: 5 additions & 2 deletions crates/bevy_ui_render/src/debug_overlay.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ use bevy_sprite::BorderRect;
use bevy_ui::ui_transform::UiGlobalTransform;
use bevy_ui::CalculatedClip;
use bevy_ui::ComputedNode;
use bevy_ui::ComputedStackIndex;
use bevy_ui::ComputedUiTargetCamera;
use bevy_ui::ResolvedBorderRadius;
use bevy_ui::UiStack;
Expand Down Expand Up @@ -176,6 +177,7 @@ pub fn extract_debug_overlay(
Query<(
Entity,
&ComputedNode,
&ComputedStackIndex,
&UiGlobalTransform,
&InheritedVisibility,
Option<&CalculatedClip>,
Expand All @@ -188,7 +190,8 @@ pub fn extract_debug_overlay(
) {
let mut camera_mapper = camera_map.get_mapper();

for (entity, uinode, transform, visibility, maybe_clip, computed_target, debug) in &uinode_query
for (entity, uinode, stack_index, transform, visibility, maybe_clip, computed_target, debug) in
&uinode_query
{
let debug_options = debug.copied().unwrap_or((*debug_options.as_ref()).into());
if !debug_options.enabled {
Expand All @@ -205,7 +208,7 @@ pub fn extract_debug_overlay(
let color = debug_options
.line_color_override
.unwrap_or_else(|| Hsla::sequential_dispersed(entity.index_u32()).into());
let z_order = (ui_stack.uinodes.len() as u32 + uinode.stack_index()) as f32;
let z_order = (ui_stack.uinodes.len() as u32 + stack_index.0) as f32;
let border = BorderRect::all(debug_options.line_width / uinode.inverse_scale_factor());
let transform = transform.affine();

Expand Down
15 changes: 9 additions & 6 deletions crates/bevy_ui_render/src/gradient.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,9 @@ use bevy_render::{sync_world::MainEntity, GpuResourceAppExt, RenderStartup};
use bevy_shader::Shader;
use bevy_sprite::BorderRect;
use bevy_ui::{
BackgroundGradient, BorderGradient, ColorStop, ComputedUiRenderTargetInfo, ConicGradient,
Gradient, InterpolationColorSpace, LinearGradient, RadialGradient, ResolvedBorderRadius, Val,
BackgroundGradient, BorderGradient, ColorStop, ComputedStackIndex, ComputedUiRenderTargetInfo,
ConicGradient, Gradient, InterpolationColorSpace, LinearGradient, RadialGradient,
ResolvedBorderRadius, Val,
};
use bevy_utils::default;
use bytemuck::{Pod, Zeroable};
Expand Down Expand Up @@ -343,6 +344,7 @@ pub fn extract_gradients(
Query<(
Entity,
&ComputedNode,
&ComputedStackIndex,
&ComputedUiTargetCamera,
&ComputedUiRenderTargetInfo,
&UiGlobalTransform,
Expand All @@ -359,6 +361,7 @@ pub fn extract_gradients(
for (
entity,
uinode,
stack_index,
camera,
target,
transform,
Expand Down Expand Up @@ -390,7 +393,7 @@ pub fn extract_gradients(
if let Some(color) = gradient.get_single() {
// With a single color stop there's no gradient, fill the node with the color
extracted_uinodes.uinodes.push(ExtractedUiNode {
z_order: uinode.stack_index as f32
z_order: stack_index.0 as f32
+ match node_type {
NodeType::Rect | NodeType::Inverted => stack_z_offsets::GRADIENT,
NodeType::Border(_) => stack_z_offsets::BORDER_GRADIENT,
Expand Down Expand Up @@ -438,7 +441,7 @@ pub fn extract_gradients(

extracted_gradients.items.push(ExtractedGradient {
render_entity: commands.spawn(TemporaryRenderEntity).id(),
stack_index: uinode.stack_index,
stack_index: stack_index.0,
transform: transform.into(),
stops_range: range_start..extracted_color_stops.0.len(),
rect: Rect {
Expand Down Expand Up @@ -488,7 +491,7 @@ pub fn extract_gradients(

extracted_gradients.items.push(ExtractedGradient {
render_entity: commands.spawn(TemporaryRenderEntity).id(),
stack_index: uinode.stack_index,
stack_index: stack_index.0,
transform: transform.into(),
stops_range: range_start..extracted_color_stops.0.len(),
rect: Rect {
Expand Down Expand Up @@ -544,7 +547,7 @@ pub fn extract_gradients(

extracted_gradients.items.push(ExtractedGradient {
render_entity: commands.spawn(TemporaryRenderEntity).id(),
stack_index: uinode.stack_index,
stack_index: stack_index.0,
transform: transform.into(),
stops_range: range_start..extracted_color_stops.0.len(),
rect: Rect {
Expand Down
Loading
Loading