1//! The baseline requirements of any UI Tree so Taffy can efficiently calculate the layout
2
3use slotmap::DefaultKey;
4
5use crate::{
6 error::TaffyResult,
7 layout::{Cache, Layout},
8 prelude::*,
9};
10
11/// Any item that implements the LayoutTree can be layed out using Taffy's algorithms.
12///
13/// Generally, Taffy expects your Node tree to be indexable by stable indices. A "stable" index means that the Node's ID
14/// remains the same between re-layouts.
15pub trait LayoutTree {
16 /// Type representing an iterator of the children of a node
17 type ChildIter<'a>: Iterator<Item = &'a DefaultKey>
18 where
19 Self: 'a;
20
21 /// Get the list of children IDs for the given node
22 fn children(&self, node: Node) -> Self::ChildIter<'_>;
23
24 /// Get the number of children for the given node
25 fn child_count(&self, node: Node) -> usize;
26
27 /// Returns true if the node has no children
28 fn is_childless(&self, node: Node) -> bool;
29
30 /// Get a specific child of a node, where the index represents the nth child
31 fn child(&self, node: Node, index: usize) -> Node;
32
33 /// Get any available parent for this node
34 fn parent(&self, node: Node) -> Option<Node>;
35
36 // todo: allow abstractions over this so we don't prescribe how layout works
37 // for reference, CSS cascades require context, and storing a full flexbox layout for each node could be inefficient
38 //
39 /// Get the [`Style`] for this Node.
40 fn style(&self, node: Node) -> &Style;
41
42 /// Get the node's output "Final Layout"
43 fn layout(&self, node: Node) -> &Layout;
44
45 /// Modify the node's output layout
46 fn layout_mut(&mut self, node: Node) -> &mut Layout;
47
48 /// Mark a node as dirty to tell Taffy that something has changed and it needs to be recomputed.
49 ///
50 /// Commonly done if the style of the node has changed.
51 fn mark_dirty(&mut self, node: Node) -> TaffyResult<()>;
52
53 /// Measure a node. Taffy uses this to force reflows of things like text and overflowing content.
54 fn measure_node(
55 &self,
56 node: Node,
57 known_dimensions: Size<Option<f32>>,
58 available_space: Size<AvailableSpace>,
59 ) -> Size<f32>;
60
61 /// Node needs to be measured
62 fn needs_measure(&self, node: Node) -> bool;
63
64 /// Get a cache entry for this Node by index
65 fn cache_mut(&mut self, node: Node, index: usize) -> &mut Option<Cache>;
66}