diff --git a/examples/custom_tree_owned_partial.rs b/examples/custom_tree_owned_partial.rs index 79f693296..f12277286 100644 --- a/examples/custom_tree_owned_partial.rs +++ b/examples/custom_tree_owned_partial.rs @@ -110,10 +110,8 @@ impl Iterator for ChildIter { } impl taffy::TraversePartialTree for Node { - type ChildIter<'a> = ChildIter; - - fn child_ids(&self, _node_id: NodeId) -> Self::ChildIter<'_> { - ChildIter(0..self.children.len()) + fn child_ids<'a>(&'a self, _node_id: NodeId) -> Box + 'a> { + Box::new(ChildIter(0..self.children.len())) } fn child_count(&self, _node_id: NodeId) -> usize { diff --git a/examples/custom_tree_owned_unsafe.rs b/examples/custom_tree_owned_unsafe.rs index 96f31527f..7080f98ee 100644 --- a/examples/custom_tree_owned_unsafe.rs +++ b/examples/custom_tree_owned_unsafe.rs @@ -112,10 +112,8 @@ unsafe fn node_from_id_mut<'a>(node_id: NodeId) -> &'a mut Node { struct StatelessLayoutTree; impl TraversePartialTree for StatelessLayoutTree { - type ChildIter<'a> = ChildIter<'a>; - - fn child_ids(&self, node_id: NodeId) -> Self::ChildIter<'_> { - unsafe { ChildIter(node_from_id(node_id).children.iter()) } + fn child_ids<'a>(&'a self, node_id: NodeId) -> Box + 'a> { + Box::new(unsafe { ChildIter(node_from_id(node_id).children.iter()) }) } fn child_count(&self, node_id: NodeId) -> usize { diff --git a/examples/custom_tree_vec.rs b/examples/custom_tree_vec.rs index f3e86568a..4ab2b2319 100644 --- a/examples/custom_tree_vec.rs +++ b/examples/custom_tree_vec.rs @@ -121,10 +121,8 @@ impl<'a> Iterator for ChildIter<'a> { } impl taffy::TraversePartialTree for Tree { - type ChildIter<'a> = ChildIter<'a>; - - fn child_ids(&self, node_id: NodeId) -> Self::ChildIter<'_> { - ChildIter(self.node_from_id(node_id).children.iter()) + fn child_ids<'a>(&'a self, node_id: NodeId) -> Box + 'a> { + Box::new(ChildIter(self.node_from_id(node_id).children.iter())) } fn child_count(&self, node_id: NodeId) -> usize { diff --git a/src/style/mod.rs b/src/style/mod.rs index f77973156..2acf7f432 100644 --- a/src/style/mod.rs +++ b/src/style/mod.rs @@ -44,6 +44,17 @@ pub enum Display { /// The children will follow the CSS Grid layout algorithm #[cfg(feature = "grid")] Grid, + /// The children will follow the algorithm provided by the user + Custom { + /// name for this custom display + name: &'static str, + /// solver for this custom display + solver: fn( + tree: Box<&mut dyn crate::LayoutPartialTree>, + node: crate::NodeId, + inputs: crate::LayoutInput, + ) -> crate::LayoutOutput, + }, /// The children will not be laid out, and will follow absolute positioning None, } @@ -76,6 +87,7 @@ impl core::fmt::Display for Display { Display::Flex => write!(f, "FLEX"), #[cfg(feature = "grid")] Display::Grid => write!(f, "GRID"), + Display::Custom { name, .. } => write!(f, "{name}"), } } } diff --git a/src/tree/taffy_tree.rs b/src/tree/taffy_tree.rs index b465bed5a..ed889dd58 100644 --- a/src/tree/taffy_tree.rs +++ b/src/tree/taffy_tree.rs @@ -163,11 +163,9 @@ impl<'a> Iterator for TaffyTreeChildIter<'a> { // TraversePartialTree impl for TaffyTree impl TraversePartialTree for TaffyTree { - type ChildIter<'a> = TaffyTreeChildIter<'a> where Self: 'a; - #[inline(always)] - fn child_ids(&self, parent_node_id: NodeId) -> Self::ChildIter<'_> { - TaffyTreeChildIter(self.children[parent_node_id.into()].iter()) + fn child_ids<'a>(&'a self, parent_node_id: NodeId) -> Box + 'a> { + Box::new(TaffyTreeChildIter(self.children[parent_node_id.into()].iter())) } #[inline(always)] @@ -207,6 +205,7 @@ impl PrintTree for TaffyTree { } #[cfg(feature = "grid")] (_, Display::Grid) => "GRID", + (_, Display::Custom { name, .. }) => name, } } @@ -234,11 +233,9 @@ impl<'t, NodeContext, MeasureFunction> TraversePartialTree for TaffyView<'t, Nod where MeasureFunction: FnMut(Size>, Size, NodeId, Option<&mut NodeContext>) -> Size, { - type ChildIter<'a> = TaffyTreeChildIter<'a> where Self: 'a; - #[inline(always)] - fn child_ids(&self, parent_node_id: NodeId) -> Self::ChildIter<'_> { - self.taffy.child_ids(parent_node_id) + fn child_ids<'a>(&'a self, parent_node_id: NodeId) -> Box + 'a> { + Box::new(self.taffy.child_ids(parent_node_id)) } #[inline(always)] @@ -314,6 +311,7 @@ where (Display::Flex, true) => compute_flexbox_layout(tree, node, inputs), #[cfg(feature = "grid")] (Display::Grid, true) => compute_grid_layout(tree, node, inputs), + (Display::Custom { solver, .. }, true) => solver(Box::new(tree), node, inputs), (_, false) => { let node_key = node.into(); let style = &tree.taffy.nodes[node_key].style; diff --git a/src/tree/traits.rs b/src/tree/traits.rs index ce6688294..163d6f17b 100644 --- a/src/tree/traits.rs +++ b/src/tree/traits.rs @@ -133,13 +133,8 @@ use crate::style::{AvailableSpace, Style}; /// This trait is Taffy's abstraction for downward tree traversal. /// However, this trait does *not* require access to any node's other than a single container node's immediate children unless you also intend to implement `TraverseTree`. pub trait TraversePartialTree { - /// Type representing an iterator of the children of a node - type ChildIter<'a>: Iterator - where - Self: 'a; - /// Get the list of children IDs for the given node - fn child_ids(&self, parent_node_id: NodeId) -> Self::ChildIter<'_>; + fn child_ids<'a>(&'a self, parent_node_id: NodeId) -> Box + 'a>; /// Get the number of children for the given node fn child_count(&self, parent_node_id: NodeId) -> usize;