tawasuyu

tawasuyu/taffy

A high performance rust-powered UI layout library

Rust 707HTML 660Markdown 12TOML 62344 Sutichaykuna

⎇ 6d7f3cf86a923a02c9d7b67053096a8b3486f15f src/tree/mod.rs Rust · 120 siq'ikuna · 4.6 KB Ñawpa willay Pi imata llamkarqan ch'uya

Pass axis information when measuring a child's size (#575) 6d7f3cf86 · Nico Burns ·

1//! Contains both [a high-level interface to Taffy](crate::Taffy) using a ready-made node tree, and [a trait for defining a custom node trees](crate::tree::LayoutTree) / utility types to help with that.
2
3use crate::geometry::{AbsoluteAxis, Line, Size};
4use crate::style::{AvailableSpace, Style};
5
6// 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::{Taffy, TaffyError, TaffyResult};
17mod layout;
18pub use layout::{CollapsibleMarginSet, Layout, LayoutInput, LayoutOutput, RequestedAxis, RunMode, SizingMode};
19
20/// 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
27    type ChildIter<'a>: Iterator<Item = NodeId>
28    where
29        Self: 'a;
30
31    /// Get the list of children IDs for the given node
32    fn child_ids(&self, parent_node_id: NodeId) -> Self::ChildIter<'_>;
33
34    /// Get the number of children for the given node
35    fn child_count(&self, parent_node_id: NodeId) -> usize;
36
37    /// Get a specific child of a node, where the index represents the nth child
38    fn get_child_id(&self, parent_node_id: NodeId, child_index: usize) -> NodeId;
39
40    /// Get a reference to the [`Style`] for this node.
41    fn get_style(&self, node_id: NodeId) -> &Style;
42
43    /// Get a mutable reference to the node's unrounded layout
44    fn get_unrounded_layout_mut(&mut self, node_id: NodeId) -> &mut Layout;
45
46    /// Get a mutable reference to the [`Cache`] for this node.
47    fn get_cache_mut(&mut self, node_id: NodeId) -> &mut Cache;
48
49    /// Compute the specified node's size or full layout given the specified constraints
50    fn compute_child_layout(&mut self, node_id: NodeId, inputs: LayoutInput) -> LayoutOutput;
51}
52
53/// 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 a reference to the node's final layout
57    fn get_final_layout(&self, node_id: NodeId) -> &Layout;
58    /// Get a mutable reference to the node's final layout
59    fn get_final_layout_mut(&mut self, node_id: NodeId) -> &mut Layout;
60}
61
62/// A private trait which allows us to add extra convenience methods to types which implement
63/// LayoutTree without making those methods public.
64pub(crate) trait PartialLayoutTreeExt: PartialLayoutTree {
65    /// Compute the size of the node given the specified constraints
66    #[inline(always)]
67    #[allow(clippy::too_many_arguments)]
68    fn measure_child_size(
69        &mut self,
70        node_id: NodeId,
71        known_dimensions: Size<Option<f32>>,
72        parent_size: Size<Option<f32>>,
73        available_space: Size<AvailableSpace>,
74        sizing_mode: SizingMode,
75        axis: AbsoluteAxis,
76        vertical_margins_are_collapsible: Line<bool>,
77    ) -> f32 {
78        self.compute_child_layout(
79            node_id,
80            LayoutInput {
81                known_dimensions,
82                parent_size,
83                available_space,
84                sizing_mode,
85                axis: axis.into(),
86                run_mode: RunMode::ComputeSize,
87                vertical_margins_are_collapsible,
88            },
89        )
90        .size
91        .get_abs(axis)
92    }
93
94    /// Perform a full layout on the node given the specified constraints
95    #[inline(always)]
96    fn perform_child_layout(
97        &mut self,
98        node_id: NodeId,
99        known_dimensions: Size<Option<f32>>,
100        parent_size: Size<Option<f32>>,
101        available_space: Size<AvailableSpace>,
102        sizing_mode: SizingMode,
103        vertical_margins_are_collapsible: Line<bool>,
104    ) -> LayoutOutput {
105        self.compute_child_layout(
106            node_id,
107            LayoutInput {
108                known_dimensions,
109                parent_size,
110                available_space,
111                sizing_mode,
112                axis: RequestedAxis::Both,
113                run_mode: RunMode::PerformLayout,
114                vertical_margins_are_collapsible,
115            },
116        )
117    }
118}
119
120impl<T: PartialLayoutTree> PartialLayoutTreeExt for T {}