Pass cross-axis known_dimension when computing flex item min size (#545)
* Pass cross-axis known_dimension when computing flex item min size
(fixes sizing of children that have inherent aspect ratio (e.g. images))
* Update changelog for inherent aspect ratio fix
120bb7a2e501822b324fd48de955450ebbba1c1a · ruwaq Nico Burns · 2023-10-02T22:37:46Z (3 wata ñawpaq) · tayta 65bedf128 · kay commitpi sach'ata qhaway
diff --git a/RELEASES.md b/RELEASES.md
index fe4a13471..63b59671e 100644
--- a/RELEASES.md
+++ b/RELEASES.md
@@ -50,6 +50,12 @@ Example usage change:
- All types from the `node`, `data`, `layout`, `error` and `cache` modules have been moved to the the `tree` module.
- Fixed misspelling: `RunMode::PeformLayout` renamed into `RunMode::PerformLayout` (added missing `r`).
+## 0.3.14
+
+### Fixes
+
+- Flex: Fix issue where constraints were not being propagated, causing nodes with inherent aspect-ratio (typically images) to not apply that aspect-ratio (#545) (Fixes bevyengine/bevy#9841)
+
## 0.3.13
### Fixes
diff --git a/src/compute/flexbox.rs b/src/compute/flexbox.rs
index 3fff92e12..689b82717 100644
--- a/src/compute/flexbox.rs
+++ b/src/compute/flexbox.rs
@@ -628,6 +628,7 @@ fn determine_flex_base_size(
// Parent size for child sizing
let cross_axis_parent_size = constants.node_inner_size.cross(dir);
+ let child_parent_size = Size::NONE.with_cross(dir, cross_axis_parent_size);
// Available space for child sizing
let cross_axis_margin_sum = constants.margin.cross_axis_sum(dir);
@@ -638,6 +639,18 @@ fn determine_flex_base_size(
.map_definite_value(|val| cross_axis_parent_size.unwrap_or(val))
.maybe_clamp(child_min_cross, child_max_cross);
+ // Known dimensions for child sizing
+ let child_known_dimensions = {
+ let mut ckd = child.size.with_main(dir, None);
+ if child.align_self == AlignSelf::Stretch && ckd.cross(dir).is_none() {
+ ckd.set_cross(
+ dir,
+ cross_axis_available_space.into_option().maybe_sub(child.margin.cross_axis_sum(dir)),
+ );
+ }
+ ckd
+ };
+
child.flex_basis = 'flex_basis: {
// A. If the item has a definite used flex basis, that’s the flex base size.
@@ -679,7 +692,6 @@ fn determine_flex_base_size(
// is auto and not definite, in this calculation use fit-content as the
// flex item’s cross size. The flex base size is the item’s resulting main size.
- let child_parent_size = Size::NONE.with_cross(dir, cross_axis_parent_size);
let child_available_space = Size::MAX_CONTENT
.with_main(
dir,
@@ -692,21 +704,6 @@ fn determine_flex_base_size(
)
.with_cross(dir, cross_axis_available_space);
- let child_known_dimensions = {
- let mut ckd = child.size;
- if child.align_self == AlignSelf::Stretch && ckd.cross(dir).is_none() {
- ckd.set_cross(
- dir,
- child_available_space
- .cross(dir)
- .into_option()
- .maybe_clamp(child_min_cross, child_max_cross)
- .maybe_sub(child.margin.cross_axis_sum(dir)),
- );
- }
- ckd
- };
-
break 'flex_basis tree
.measure_child_size(
child.node,
@@ -756,12 +753,11 @@ fn determine_flex_base_size(
child.resolved_minimum_main_size = style_min_main_size.unwrap_or({
let min_content_size = {
- let child_parent_size = Size::NONE.with_cross(dir, cross_axis_parent_size);
let child_available_space = Size::MIN_CONTENT.with_cross(dir, cross_axis_available_space);
tree.measure_child_size(
child.node,
- Size::NONE,
+ child_known_dimensions,
child_parent_size,
child_available_space,
SizingMode::ContentSize,