tawasuyu

tawasuyu/taffy

A high performance rust-powered UI layout library

HTML 231Rust 8TOML 3CSS 1317 Definiciones

Move `hidden_layout()` to parent scope (#208)

* Separate out hide_layout

* Cleanup formatting

* Added change to releases

* Fix typo

* Improve docs

* Cleanup and clarify test

* Apply suggestions from code review

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>

* fix incorrect call

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>

dee9e76ca619d24eb9a95314c20fa0a86457a407 · por Andreas Weibye · (hace 4 años) · padre 3535699e0 · ver el árbol en este commit

Delta semántico · 4

src/flexbox.rs

src/layout.rs

3 archivos · +71 −18

diff --git a/RELEASES.md b/RELEASES.md
index f74c3d06d..582b691fa 100644
--- a/RELEASES.md
+++ b/RELEASES.md
@@ -7,7 +7,8 @@
 - Added `taffy::error::InvalidChild` Error type
 - `taffy::node::Taffy.new_leaf()` which allows the creation of new leaf-nodes without having to supply a measure function
 - Builder methods are now `const` where possible
-  - Several convenenience constants have been defined: notably `FlexboxLayout::DEFAULT`
+  - Several convenience constants have been defined: notably `FlexboxLayout::DEFAULT`
+- New `Layout` convenience constructor: `with_order(order: u32)`
 
 ### 0.2.0 Changed
 
diff --git a/src/flexbox.rs b/src/flexbox.rs
index 5dcd4712a..fabcdddbe 100644
--- a/src/flexbox.rs
+++ b/src/flexbox.rs
@@ -1715,22 +1715,7 @@ impl Taffy {
         // Before returning we perform absolute layout on all absolutely positioned children
         self.perform_absolute_layout_on_absolute_children(node, &constants);
 
-        /// Lay out all hidden nodes recursively
-        ///
-        /// Each hidden node has zero size and is placed at the origin
-        fn hidden_layout(
-            nodes: &mut SlotMap<Node, NodeData>,
-            children: &SlotMap<Node, ChildrenVec<Node>>,
-            node: Node,
-            order: u32,
-        ) {
-            nodes[node].layout = Layout { order, size: Size::ZERO, location: Point::ZERO };
-
-            for (order, child) in children[node].iter().enumerate() {
-                hidden_layout(nodes, children, *child, order as _);
-            }
-        }
-
+        // Recursively hide all nodes set to Display::None
         for (order, child) in self.children[node].iter().enumerate() {
             if self.nodes[*child].style.display == Display::None {
                 hidden_layout(&mut self.nodes, &self.children, *child, order as _);
@@ -1744,8 +1729,26 @@ impl Taffy {
     }
 }
 
+/// Creates a zero-sized layout for this node and its children, recursively.
+fn hidden_layout(
+    nodes: &mut SlotMap<Node, NodeData>,
+    children: &SlotMap<Node, ChildrenVec<Node>>,
+    node: Node,
+    order: u32,
+) {
+    nodes[node].layout = Layout::with_order(order);
+
+    for (order, child) in children[node].iter().enumerate() {
+        hidden_layout(nodes, children, *child, order as _);
+    }
+}
+
 #[cfg(test)]
 mod tests {
+    use crate::flexbox::hidden_layout;
+    use crate::geometry::Point;
+    use crate::style::Display;
+    use crate::style::Display::Flex;
     use crate::{
         math::MaybeMath,
         prelude::{Rect, Size},
@@ -1800,4 +1803,40 @@ mod tests {
         assert_eq!(constants.container_size, Size::ZERO);
         assert_eq!(constants.inner_container_size, Size::ZERO);
     }
+
+    #[test]
+    fn hidden_layout_should_hide_recursively() {
+        let mut taffy = Taffy::new();
+
+        let style: FlexboxLayout =
+            FlexboxLayout { display: Flex, size: Size::from_points(50.0, 50.0), ..Default::default() };
+
+        let grandchild_00 = taffy.new_leaf(style).unwrap();
+
+        let grandchild_01 = taffy.new_leaf(style).unwrap();
+
+        let grandchild_02 = taffy.new_leaf(style).unwrap();
+
+        let child_00 = taffy.new_with_children(style, &[grandchild_00, grandchild_01]).unwrap();
+
+        let child_01 = taffy.new_with_children(style, &[grandchild_02]).unwrap();
+
+        let root = taffy
+            .new_with_children(
+                FlexboxLayout { display: Display::None, size: Size::from_points(50.0, 50.0), ..Default::default() },
+                &[child_00, child_01],
+            )
+            .unwrap();
+
+        hidden_layout(&mut taffy.nodes, &taffy.children, root, 0);
+
+        // Whatever size and display-mode the nodes had previously,
+        // all layouts should resolve to ZERO due to the root's DISPLAY::NONE
+        for (node, _) in &taffy.nodes {
+            if let Ok(layout) = taffy.layout(node) {
+                assert_eq!(layout.size, Size::ZERO);
+                assert_eq!(layout.location, Point::ZERO);
+            }
+        }
+    }
 }
diff --git a/src/layout.rs b/src/layout.rs
index 49ea2251f..e7fc21382 100644
--- a/src/layout.rs
+++ b/src/layout.rs
@@ -17,11 +17,24 @@ pub struct Layout {
 }
 
 impl Layout {
-    /// Creates a new [`Layout`] struct with zero size positioned at the origin
+    /// Creates a new zero-[`Layout`].
+    ///
+    /// The Zero-layout has size and location set to ZERO.
+    /// The `order` value of this layout is set to the minimum value of 0.
+    /// This means it should be rendered below all other [`Layout`]s.
     #[must_use]
     pub const fn new() -> Self {
         Self { order: 0, size: Size::ZERO, location: Point::ZERO }
     }
+
+    /// Creates a new zero-[`Layout`] with the supplied `order` value.
+    ///
+    /// Nodes with a higher order should be rendered on top of those with a lower order.
+    /// The Zero-layout has size and location set to ZERO.
+    #[must_use]
+    pub const fn with_order(order: u32) -> Self {
+        Self { order, size: Size::ZERO, location: Point::ZERO }
+    }
 }
 
 /// Cached intermediate layout results