diff --git a/crates/bevy_ui/src/layout/mod.rs b/crates/bevy_ui/src/layout/mod.rs index 8c808be06d..75dc688f8b 100644 --- a/crates/bevy_ui/src/layout/mod.rs +++ b/crates/bevy_ui/src/layout/mod.rs @@ -1,13 +1,14 @@ mod convert; -use crate::{CalculatedSize, Node, Style, UiScale}; +use crate::{ContentSize, Node, Style, UiScale}; use bevy_ecs::{ change_detection::DetectChanges, entity::Entity, event::EventReader, - query::{Changed, Or, With, Without}, + query::{Changed, With, Without}, removal_detection::RemovedComponents, system::{Query, Res, ResMut, Resource}, + world::Ref, }; use bevy_hierarchy::{Children, Parent}; use bevy_log::warn; @@ -16,11 +17,7 @@ use bevy_transform::components::Transform; use bevy_utils::HashMap; use bevy_window::{PrimaryWindow, Window, WindowResolution, WindowScaleFactorChanged}; use std::fmt; -use taffy::{ - prelude::{AvailableSpace, Size}, - style_helpers::TaffyMaxContent, - Taffy, -}; +use taffy::{prelude::Size, style_helpers::TaffyMaxContent, Taffy}; pub struct LayoutContext { pub scale_factor: f64, @@ -75,6 +72,8 @@ impl Default for UiSurface { } impl UiSurface { + /// Retrieves the taffy node corresponding to given entity exists, or inserts a new taffy node into the layout if no corresponding node exists. + /// Then convert the given `Style` and use it update the taffy node's style. pub fn upsert_node(&mut self, entity: Entity, style: &Style, context: &LayoutContext) { let mut added = false; let taffy = &mut self.taffy; @@ -90,43 +89,13 @@ impl UiSurface { } } - pub fn upsert_leaf( - &mut self, - entity: Entity, - style: &Style, - calculated_size: &CalculatedSize, - context: &LayoutContext, - ) { - let taffy = &mut self.taffy; - let taffy_style = convert::from_style(context, style); - let measure = calculated_size.measure.dyn_clone(); - let measure_func = taffy::node::MeasureFunc::Boxed(Box::new( - move |constraints: Size>, available: Size| { - let size = measure.measure( - constraints.width, - constraints.height, - available.width, - available.height, - ); - taffy::geometry::Size { - width: size.x, - height: size.y, - } - }, - )); - if let Some(taffy_node) = self.entity_to_taffy.get(&entity) { - self.taffy.set_style(*taffy_node, taffy_style).unwrap(); - self.taffy - .set_measure(*taffy_node, Some(measure_func)) - .unwrap(); - } else { - let taffy_node = taffy - .new_leaf_with_measure(taffy_style, measure_func) - .unwrap(); - self.entity_to_taffy.insert(entity, taffy_node); - } + /// Update the `MeasureFunc` of the taffy node corresponding to the given [`Entity`]. + pub fn update_measure(&mut self, entity: Entity, measure_func: taffy::node::MeasureFunc) { + let taffy_node = self.entity_to_taffy.get(&entity).unwrap(); + self.taffy.set_measure(*taffy_node, Some(measure_func)).ok(); } + /// Update the children of the taffy node corresponding to the given [`Entity`]. pub fn update_children(&mut self, entity: Entity, children: &Children) { let mut taffy_children = Vec::with_capacity(children.len()); for child in children { @@ -160,6 +129,7 @@ without UI components as a child of an entity with UI components, results may be } } + /// Retrieve or insert the root layout node and update its size to match the size of the window. pub fn update_window(&mut self, window: Entity, window_resolution: &WindowResolution) { let taffy = &mut self.taffy; let node = self @@ -185,6 +155,7 @@ without UI components as a child of an entity with UI components, results may be .unwrap(); } + /// Set the ui node entities without a [`Parent`] as children to the root node in the taffy layout. pub fn set_window_children( &mut self, parent_window: Entity, @@ -197,6 +168,7 @@ without UI components as a child of an entity with UI components, results may be self.taffy.set_children(*taffy_node, &child_nodes).unwrap(); } + /// Compute the layout for each window entity's corresponding root node in the layout. pub fn compute_window_layouts(&mut self) { for window_node in self.window_nodes.values() { self.taffy @@ -214,6 +186,8 @@ without UI components as a child of an entity with UI components, results may be } } + /// Get the layout geometry for the taffy node corresponding to the ui node [`Entity`]. + /// Does not compute the layout geometry, `compute_window_layouts` should be run before using this function. pub fn get_layout(&self, entity: Entity) -> Result<&taffy::layout::Layout, LayoutError> { if let Some(taffy_node) = self.entity_to_taffy.get(&entity) { self.taffy @@ -235,6 +209,7 @@ pub enum LayoutError { TaffyError(taffy::error::TaffyError), } +/// Updates the UI's layout tree, computes the new layout geometry and then updates the sizes and transforms of all the UI nodes. #[allow(clippy::too_many_arguments)] pub fn ui_layout_system( primary_window: Query<(Entity, &Window), With>, @@ -244,18 +219,11 @@ pub fn ui_layout_system( mut resize_events: EventReader, mut ui_surface: ResMut, root_node_query: Query, Without)>, - full_node_query: Query<(Entity, &Style, Option<&CalculatedSize>), With>, - changed_style_query: Query< - (Entity, &Style), - (With, Without, Changed