Flexbox: clamp indefinite available space by min- and max- size as appropriate (#742)
* Add test for bevyengine/bevy#16304
* Clamp indefinite available space by min- and max- size as appropriate
8c748748e3920e280d71642abd89de0b2ed74b91 · por Nico Burns · (hace 1 año) · padre 137496576 · ver el árbol en este commit
Delta semántico · 4
tests/generated/flex/bevy_issue_16304.rs
tests/generated/flex/mod.rs
diff --git a/src/compute/flexbox.rs b/src/compute/flexbox.rs
index 9f1fcc1f4..0c9dcc3b0 100644
--- a/src/compute/flexbox.rs
+++ b/src/compute/flexbox.rs
@@ -640,10 +640,21 @@ fn determine_flex_base_size(
let cross_axis_margin_sum = constants.margin.cross_axis_sum(dir);
let child_min_cross = child.min_size.cross(dir).maybe_add(cross_axis_margin_sum);
let child_max_cross = child.max_size.cross(dir).maybe_add(cross_axis_margin_sum);
- let cross_axis_available_space: AvailableSpace = available_space
- .cross(dir)
- .map_definite_value(|val| cross_axis_parent_size.unwrap_or(val))
- .maybe_clamp(child_min_cross, child_max_cross);
+
+ // Clamp available space by min- and max- size
+ let cross_axis_available_space: AvailableSpace = match available_space.cross(dir) {
+ AvailableSpace::Definite(val) => AvailableSpace::Definite(
+ cross_axis_parent_size.unwrap_or(val).maybe_clamp(child_min_cross, child_max_cross),
+ ),
+ AvailableSpace::MinContent => match child_min_cross {
+ Some(min) => AvailableSpace::Definite(min),
+ None => AvailableSpace::MinContent,
+ },
+ AvailableSpace::MaxContent => match child_max_cross {
+ Some(max) => AvailableSpace::Definite(max),
+ None => AvailableSpace::MaxContent,
+ },
+ };
// Known dimensions for child sizing
let child_known_dimensions = {
diff --git a/test_fixtures/flex/bevy_issue_16304.html b/test_fixtures/flex/bevy_issue_16304.html
new file mode 100644
index 000000000..90944fa39
--- /dev/null
+++ b/test_fixtures/flex/bevy_issue_16304.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <script src="../../scripts/gentest/test_helper.js"></script>
+ <link rel="stylesheet" type="text/css" href="../../scripts/gentest/test_base_style.css">
+ <title>
+ min width causing height issues
+ </title>
+</head>
+<body>
+
+<div id="test-root" style="display: flex; background-color: grey;">
+ <div style="display: flex; flex-direction: column; width: 50px;">
+ <div style="display: flex; min-width: 50px; flex-wrap: wrap; gap: 10px; background-color: blue;">
+ <div style="width: 20px; height: 40px; background-color: red;"></div>
+ <div style="width: 20px; height: 40px; background-color: red;"></div>
+ </div>
+ </div>
+</div>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/tests/generated/flex/bevy_issue_16304.rs b/tests/generated/flex/bevy_issue_16304.rs
new file mode 100644
index 000000000..50267e6f1
--- /dev/null
+++ b/tests/generated/flex/bevy_issue_16304.rs
@@ -0,0 +1,188 @@
+#[test]
+#[allow(non_snake_case)]
+fn bevy_issue_16304__border_box() {
+ #[allow(unused_imports)]
+ use taffy::{prelude::*, tree::Layout, TaffyTree};
+ let mut taffy: TaffyTree<crate::TextMeasure> = TaffyTree::new();
+ let node000 = taffy
+ .new_leaf(taffy::style::Style {
+ size: taffy::geometry::Size {
+ width: taffy::style::Dimension::Length(20f32),
+ height: taffy::style::Dimension::Length(40f32),
+ },
+ ..Default::default()
+ })
+ .unwrap();
+ let node001 = taffy
+ .new_leaf(taffy::style::Style {
+ size: taffy::geometry::Size {
+ width: taffy::style::Dimension::Length(20f32),
+ height: taffy::style::Dimension::Length(40f32),
+ },
+ ..Default::default()
+ })
+ .unwrap();
+ let node00 = taffy
+ .new_with_children(
+ taffy::style::Style {
+ display: taffy::style::Display::Flex,
+ flex_wrap: taffy::style::FlexWrap::Wrap,
+ gap: taffy::geometry::Size {
+ width: taffy::style::LengthPercentage::Length(10f32),
+ height: taffy::style::LengthPercentage::Length(10f32),
+ },
+ min_size: taffy::geometry::Size { width: taffy::style::Dimension::Length(50f32), height: auto() },
+ ..Default::default()
+ },
+ &[node000, node001],
+ )
+ .unwrap();
+ let node0 = taffy
+ .new_with_children(
+ taffy::style::Style {
+ display: taffy::style::Display::Flex,
+ flex_direction: taffy::style::FlexDirection::Column,
+ size: taffy::geometry::Size { width: taffy::style::Dimension::Length(50f32), height: auto() },
+ ..Default::default()
+ },
+ &[node00],
+ )
+ .unwrap();
+ let node = taffy
+ .new_with_children(taffy::style::Style { display: taffy::style::Display::Flex, ..Default::default() }, &[node0])
+ .unwrap();
+ taffy.compute_layout_with_measure(node, taffy::geometry::Size::MAX_CONTENT, crate::test_measure_function).unwrap();
+ println!("\nComputed tree:");
+ taffy.print_tree(node);
+ println!();
+ let layout = taffy.layout(node).unwrap();
+ let Layout { size, location, .. } = layout;
+ assert_eq!(size.width, 50f32, "width of node {:?}. Expected {}. Actual {}", node, 50f32, size.width);
+ assert_eq!(size.height, 40f32, "height of node {:?}. Expected {}. Actual {}", node, 40f32, size.height);
+ assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node, 0f32, location.x);
+ assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node, 0f32, location.y);
+ let layout = taffy.layout(node0).unwrap();
+ let Layout { size, location, .. } = layout;
+ assert_eq!(size.width, 50f32, "width of node {:?}. Expected {}. Actual {}", node0, 50f32, size.width);
+ assert_eq!(size.height, 40f32, "height of node {:?}. Expected {}. Actual {}", node0, 40f32, size.height);
+ assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node0, 0f32, location.x);
+ assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node0, 0f32, location.y);
+ let layout = taffy.layout(node00).unwrap();
+ let Layout { size, location, .. } = layout;
+ assert_eq!(size.width, 50f32, "width of node {:?}. Expected {}. Actual {}", node00, 50f32, size.width);
+ assert_eq!(size.height, 40f32, "height of node {:?}. Expected {}. Actual {}", node00, 40f32, size.height);
+ assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node00, 0f32, location.x);
+ assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node00, 0f32, location.y);
+ let layout = taffy.layout(node000).unwrap();
+ let Layout { size, location, .. } = layout;
+ assert_eq!(size.width, 20f32, "width of node {:?}. Expected {}. Actual {}", node000, 20f32, size.width);
+ assert_eq!(size.height, 40f32, "height of node {:?}. Expected {}. Actual {}", node000, 40f32, size.height);
+ assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node000, 0f32, location.x);
+ assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node000, 0f32, location.y);
+ let layout = taffy.layout(node001).unwrap();
+ let Layout { size, location, .. } = layout;
+ assert_eq!(size.width, 20f32, "width of node {:?}. Expected {}. Actual {}", node001, 20f32, size.width);
+ assert_eq!(size.height, 40f32, "height of node {:?}. Expected {}. Actual {}", node001, 40f32, size.height);
+ assert_eq!(location.x, 30f32, "x of node {:?}. Expected {}. Actual {}", node001, 30f32, location.x);
+ assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node001, 0f32, location.y);
+}
+
+#[test]
+#[allow(non_snake_case)]
+fn bevy_issue_16304__content_box() {
+ #[allow(unused_imports)]
+ use taffy::{prelude::*, tree::Layout, TaffyTree};
+ let mut taffy: TaffyTree<crate::TextMeasure> = TaffyTree::new();
+ let node000 = taffy
+ .new_leaf(taffy::style::Style {
+ box_sizing: taffy::style::BoxSizing::ContentBox,
+ size: taffy::geometry::Size {
+ width: taffy::style::Dimension::Length(20f32),
+ height: taffy::style::Dimension::Length(40f32),
+ },
+ ..Default::default()
+ })
+ .unwrap();
+ let node001 = taffy
+ .new_leaf(taffy::style::Style {
+ box_sizing: taffy::style::BoxSizing::ContentBox,
+ size: taffy::geometry::Size {
+ width: taffy::style::Dimension::Length(20f32),
+ height: taffy::style::Dimension::Length(40f32),
+ },
+ ..Default::default()
+ })
+ .unwrap();
+ let node00 = taffy
+ .new_with_children(
+ taffy::style::Style {
+ display: taffy::style::Display::Flex,
+ box_sizing: taffy::style::BoxSizing::ContentBox,
+ flex_wrap: taffy::style::FlexWrap::Wrap,
+ gap: taffy::geometry::Size {
+ width: taffy::style::LengthPercentage::Length(10f32),
+ height: taffy::style::LengthPercentage::Length(10f32),
+ },
+ min_size: taffy::geometry::Size { width: taffy::style::Dimension::Length(50f32), height: auto() },
+ ..Default::default()
+ },
+ &[node000, node001],
+ )
+ .unwrap();
+ let node0 = taffy
+ .new_with_children(
+ taffy::style::Style {
+ display: taffy::style::Display::Flex,
+ box_sizing: taffy::style::BoxSizing::ContentBox,
+ flex_direction: taffy::style::FlexDirection::Column,
+ size: taffy::geometry::Size { width: taffy::style::Dimension::Length(50f32), height: auto() },
+ ..Default::default()
+ },
+ &[node00],
+ )
+ .unwrap();
+ let node = taffy
+ .new_with_children(
+ taffy::style::Style {
+ display: taffy::style::Display::Flex,
+ box_sizing: taffy::style::BoxSizing::ContentBox,
+ ..Default::default()
+ },
+ &[node0],
+ )
+ .unwrap();
+ taffy.compute_layout_with_measure(node, taffy::geometry::Size::MAX_CONTENT, crate::test_measure_function).unwrap();
+ println!("\nComputed tree:");
+ taffy.print_tree(node);
+ println!();
+ let layout = taffy.layout(node).unwrap();
+ let Layout { size, location, .. } = layout;
+ assert_eq!(size.width, 50f32, "width of node {:?}. Expected {}. Actual {}", node, 50f32, size.width);
+ assert_eq!(size.height, 40f32, "height of node {:?}. Expected {}. Actual {}", node, 40f32, size.height);
+ assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node, 0f32, location.x);
+ assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node, 0f32, location.y);
+ let layout = taffy.layout(node0).unwrap();
+ let Layout { size, location, .. } = layout;
+ assert_eq!(size.width, 50f32, "width of node {:?}. Expected {}. Actual {}", node0, 50f32, size.width);
+ assert_eq!(size.height, 40f32, "height of node {:?}. Expected {}. Actual {}", node0, 40f32, size.height);
+ assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node0, 0f32, location.x);
+ assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node0, 0f32, location.y);
+ let layout = taffy.layout(node00).unwrap();
+ let Layout { size, location, .. } = layout;
+ assert_eq!(size.width, 50f32, "width of node {:?}. Expected {}. Actual {}", node00, 50f32, size.width);
+ assert_eq!(size.height, 40f32, "height of node {:?}. Expected {}. Actual {}", node00, 40f32, size.height);
+ assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node00, 0f32, location.x);
+ assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node00, 0f32, location.y);
+ let layout = taffy.layout(node000).unwrap();
+ let Layout { size, location, .. } = layout;
+ assert_eq!(size.width, 20f32, "width of node {:?}. Expected {}. Actual {}", node000, 20f32, size.width);
+ assert_eq!(size.height, 40f32, "height of node {:?}. Expected {}. Actual {}", node000, 40f32, size.height);
+ assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node000, 0f32, location.x);
+ assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node000, 0f32, location.y);
+ let layout = taffy.layout(node001).unwrap();
+ let Layout { size, location, .. } = layout;
+ assert_eq!(size.width, 20f32, "width of node {:?}. Expected {}. Actual {}", node001, 20f32, size.width);
+ assert_eq!(size.height, 40f32, "height of node {:?}. Expected {}. Actual {}", node001, 40f32, size.height);
+ assert_eq!(location.x, 30f32, "x of node {:?}. Expected {}. Actual {}", node001, 30f32, location.x);
+ assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node001, 0f32, location.y);
+}
diff --git a/tests/generated/flex/mod.rs b/tests/generated/flex/mod.rs
index 046c71e88..c55c311f6 100644
--- a/tests/generated/flex/mod.rs
+++ b/tests/generated/flex/mod.rs
@@ -179,6 +179,7 @@ mod aspect_ratio_flex_row_stretch_fill_width;
mod bevy_issue_10343_block;
mod bevy_issue_10343_flex;
mod bevy_issue_10343_grid;
+mod bevy_issue_16304;
mod bevy_issue_7976_3_level;
mod bevy_issue_7976_4_level;
mod bevy_issue_7976_reduced;