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