1//! Contains both [a high-level interface to Taffy](crate::TaffyTree) using a ready-made node tree, and [a trait for defining a custom node trees](crate::tree::LayoutTree) / utility types to help with that.
23use crate::geometry::{AbsoluteAxis, Line, Size};
4use crate::style::{AvailableSpace, Style};
56// Submodules
7mod cache;
8pub use cache::Cache;
9mod node;
10#[cfg(feature = "taffy_tree")]
11use node::NodeData;
12pub use node::NodeId;
13#[cfg(feature = "taffy_tree")]
14mod taffy_tree;
15#[cfg(feature = "taffy_tree")]
16pub use taffy_tree::{TaffyError, TaffyResult, TaffyTree};
17mod layout;
18pub use layout::{CollapsibleMarginSet, Layout, LayoutInput, LayoutOutput, RequestedAxis, RunMode, SizingMode};
1920/// This if the core abstraction in Taffy. Any type that *correctly* implements `PartialLayoutTree` can be laid out using Taffy's algorithms.
21///
22/// The type implementing `PartialLayoutTree` would typically be an entire tree of nodes (or a view over an entire tree of nodes).
23/// However, `PartialLayoutTree` and Taffy's algorithm implementations have been designed such that they can be used for a laying out a single
24/// node that only has access to it's immediate children.
25pub trait PartialLayoutTree {
26/// Type representing an iterator of the children of a node
27type ChildIter<'a>: Iterator<Item = NodeId>
28where
29Self: 'a;
3031/// Get the list of children IDs for the given node
32fn child_ids(&self, parent_node_id: NodeId) -> Self::ChildIter<'_>;
3334/// Get the number of children for the given node
35fn child_count(&self, parent_node_id: NodeId) -> usize;
3637/// Get a specific child of a node, where the index represents the nth child
38fn get_child_id(&self, parent_node_id: NodeId, child_index: usize) -> NodeId;
3940/// Get a reference to the [`Style`] for this node.
41fn get_style(&self, node_id: NodeId) -> &Style;
4243/// Set the node's unrounded layout
44fn set_unrounded_layout(&mut self, node_id: NodeId, layout: &Layout);
4546/// Get a mutable reference to the [`Cache`] for this node.
47fn get_cache_mut(&mut self, node_id: NodeId) -> &mut Cache;
4849/// Compute the specified node's size or full layout given the specified constraints
50fn compute_child_layout(&mut self, node_id: NodeId, inputs: LayoutInput) -> LayoutOutput;
51}
5253/// Extends [`PartialLayoutTree`] with an additional guarantee: that the child/children methods can be used to recurse
54/// infinitely down the tree. Enables Taffy's rounding and debug printing methods to be used.
55pub trait LayoutTree: PartialLayoutTree {
56/// Get the node's unrounded layout
57fn get_unrounded_layout(&self, node_id: NodeId) -> &Layout;
58/// Get a reference to the node's final layout
59fn get_final_layout(&self, node_id: NodeId) -> &Layout;
60/// Get a mutable reference to the node's final layout
61fn set_final_layout(&mut self, node_id: NodeId, layout: &Layout);
62}
6364/// A private trait which allows us to add extra convenience methods to types which implement
65/// LayoutTree without making those methods public.
66pub(crate) trait PartialLayoutTreeExt: PartialLayoutTree {
67/// Compute the size of the node given the specified constraints
68#[inline(always)]
69 #[allow(clippy::too_many_arguments)]
70fn measure_child_size(
71&mut self,
72 node_id: NodeId,
73 known_dimensions: Size<Option<f32>>,
74 parent_size: Size<Option<f32>>,
75 available_space: Size<AvailableSpace>,
76 sizing_mode: SizingMode,
77 axis: AbsoluteAxis,
78 vertical_margins_are_collapsible: Line<bool>,
79 ) -> f32 {
80self.compute_child_layout(
81 node_id,
82 LayoutInput {
83 known_dimensions,
84 parent_size,
85 available_space,
86 sizing_mode,
87 axis: axis.into(),
88 run_mode: RunMode::ComputeSize,
89 vertical_margins_are_collapsible,
90 },
91 )
92 .size
93 .get_abs(axis)
94 }
9596/// Perform a full layout on the node given the specified constraints
97#[inline(always)]
98fn perform_child_layout(
99&mut self,
100 node_id: NodeId,
101 known_dimensions: Size<Option<f32>>,
102 parent_size: Size<Option<f32>>,
103 available_space: Size<AvailableSpace>,
104 sizing_mode: SizingMode,
105 vertical_margins_are_collapsible: Line<bool>,
106 ) -> LayoutOutput {
107self.compute_child_layout(
108 node_id,
109 LayoutInput {
110 known_dimensions,
111 parent_size,
112 available_space,
113 sizing_mode,
114 axis: RequestedAxis::Both,
115 run_mode: RunMode::PerformLayout,
116 vertical_margins_are_collapsible,
117 },
118 )
119 }
120}
121122impl<T: PartialLayoutTree> PartialLayoutTreeExt for T {}