diff --git a/Cargo.toml b/Cargo.toml index c6ec1f14d6bd0..4375754a589ce 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1463,6 +1463,16 @@ description = "Illustrates how FontAtlases are populated (used to optimize text category = "UI (User Interface)" wasm = true +[[example]] +name = "layout" +path = "examples/ui/layout.rs" + +[package.metadata.example.layout] +name = "Layout" +description = "Creates a more complex UI layout and demonstrates how the different JustifyContent and AlignItems variants compose." +category = "UI (User Interface)" +wasm = false + [[example]] name = "text" path = "examples/ui/text.rs" diff --git a/crates/bevy_ui/src/flex/mod.rs b/crates/bevy_ui/src/flex/mod.rs index ebe6e1ad4d394..ec244e4f27181 100644 --- a/crates/bevy_ui/src/flex/mod.rs +++ b/crates/bevy_ui/src/flex/mod.rs @@ -4,7 +4,7 @@ use crate::{CalculatedSize, Node, Style, UiScale}; use bevy_ecs::{ entity::Entity, event::EventReader, - query::{Changed, ReadOnlyWorldQuery, With, Without}, + query::{Changed, With, Without}, system::{Query, RemovedComponents, Res, ResMut, Resource}, }; use bevy_hierarchy::{Children, Parent}; @@ -86,11 +86,15 @@ impl FlexSurface { match (constraints.width, constraints.height) { (Number::Undefined, Number::Undefined) => {} (Number::Defined(width), Number::Undefined) => { - size.height = width * size.height / size.width; + if calculated_size.preserve_aspect_ratio { + size.height = width * size.height / size.width; + } size.width = width; } (Number::Undefined, Number::Defined(height)) => { - size.width = height * size.width / size.height; + if calculated_size.preserve_aspect_ratio { + size.width = height * size.width / size.height; + } size.height = height; } (Number::Defined(width), Number::Defined(height)) => { @@ -111,6 +115,52 @@ impl FlexSurface { } } + fn upsert_widget( + &mut self, + entity: Entity, + calculated_size: CalculatedSize, + scale_factor: f64, + ) { + let taffy = &mut self.taffy; + let measure = taffy::node::MeasureFunc::Boxed(Box::new( + move |constraints: taffy::geometry::Size| { + let mut size = convert::from_f32_size(scale_factor, calculated_size.size); + match (constraints.width, constraints.height) { + (Number::Undefined, Number::Undefined) => {} + (Number::Defined(width), Number::Undefined) => { + if calculated_size.preserve_aspect_ratio { + size.height = width * size.height / size.width; + } + size.width = width; + } + (Number::Undefined, Number::Defined(height)) => { + if calculated_size.preserve_aspect_ratio { + size.width = height * size.width / size.height; + } + size.height = height; + } + (Number::Defined(width), Number::Defined(height)) => { + size.width = width; + size.height = height; + } + } + size + }, + )); + + if let Some(taffy_node) = self.entity_to_taffy.get(&entity) { + self.taffy + .set_style(*taffy_node, taffy::style::Style::default()) + .unwrap(); + self.taffy.set_measure(*taffy_node, Some(measure)).unwrap(); + } else { + let taffy_node = taffy + .new_leaf(taffy::style::Style::default(), measure) + .unwrap(); + self.entity_to_taffy.insert(entity, taffy_node); + } + } + pub fn update_children(&mut self, entity: Entity, children: &Children) { let mut taffy_children = Vec::with_capacity(children.len()); for child in children { @@ -216,13 +266,18 @@ pub fn flex_node_system( mut scale_factor_events: EventReader, mut flex_surface: ResMut, root_node_query: Query, Without)>, - node_query: Query<(Entity, &Style, Option<&CalculatedSize>), (With, Changed