gioser

tawasuyu/taffy

A high performance rust-powered UI layout library

HTML 5544Rust 88Markdown 11TOML 91926 Definiciones

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

src/compute/flexbox.rs

tests/generated/flex/bevy_issue_16304.rs

tests/generated/flex/mod.rs

4 archivos · +226 −4

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;