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