compose_taffy/
layout.rs

1use compose_rt::{NodeKey, Recomposer};
2use taffy::{compute_root_layout, print_tree, round_layout, AvailableSpace, NodeId, Size};
3
4use crate::traits::{IntoNodeId, TaffyConfig, TaffyNode};
5use crate::{TaffyTree, TaffyTreeView};
6
7#[derive(Debug, Clone, PartialEq, Eq)]
8pub enum LayoutError {
9    /// The supplied node was not found in the composer instance.
10    InvalidInputNode(NodeKey),
11}
12
13pub type LayoutResult = std::result::Result<(), LayoutError>;
14
15pub trait TaffyLayout<NodeContext, CoreContainerStyle> {
16    fn compute_layout_with<MeasureFn>(
17        &mut self,
18        available_space: Size<AvailableSpace>,
19        node_key: NodeKey,
20        measure_fn: MeasureFn,
21    ) -> LayoutResult
22    where
23        MeasureFn: FnMut(
24            Size<Option<f32>>,
25            Size<AvailableSpace>,
26            NodeId,
27            Option<&mut NodeContext>,
28            &CoreContainerStyle,
29        ) -> Size<f32>;
30
31    fn compute_layout(&mut self, available_space: Size<AvailableSpace>) -> LayoutResult;
32
33    fn print_layout_tree_with(&self, node_key: NodeKey) -> LayoutResult;
34
35    fn print_layout_tree(&self) -> LayoutResult;
36}
37
38impl<S, T> TaffyLayout<T::NodeContext, T::CoreContainerStyle> for Recomposer<S, T>
39where
40    S: 'static,
41    T: TaffyNode,
42    T::Context: TaffyConfig,
43{
44    fn compute_layout_with<MeasureFn>(
45        &mut self,
46        available_space: Size<AvailableSpace>,
47        node_key: NodeKey,
48        measure_function: MeasureFn,
49    ) -> LayoutResult
50    where
51        MeasureFn: FnMut(
52            Size<Option<f32>>,
53            Size<AvailableSpace>,
54            NodeId,
55            Option<&mut T::NodeContext>,
56            &T::CoreContainerStyle,
57        ) -> Size<f32>,
58    {
59        self.with_composer_mut(|composer| {
60            if !composer.nodes.contains(node_key) {
61                return Err(LayoutError::InvalidInputNode(node_key));
62            }
63            let node_id = node_key.into_node_id();
64            let mut tree = TaffyTree::new(composer, measure_function);
65            compute_root_layout(&mut tree, node_id, available_space);
66            if tree.composer.context.use_rounding() {
67                round_layout(&mut tree, node_id);
68            }
69            Ok(())
70        })
71    }
72
73    #[inline(always)]
74    fn compute_layout(&mut self, available_space: Size<AvailableSpace>) -> LayoutResult {
75        let node_key = self.root_node_key();
76        self.compute_layout_with(available_space, node_key, |_, _, _, _, _| Size::ZERO)
77    }
78
79    fn print_layout_tree_with(&self, node_key: NodeKey) -> LayoutResult {
80        self.with_composer(|composer| {
81            if !composer.nodes.contains(node_key) {
82                return Err(LayoutError::InvalidInputNode(node_key));
83            }
84            let node_id = node_key.into_node_id();
85            let tree = TaffyTreeView::new(composer);
86            print_tree(&tree, node_id);
87            Ok(())
88        })
89    }
90
91    #[inline(always)]
92    fn print_layout_tree(&self) -> LayoutResult {
93        let node_key = self.root_node_key();
94        self.print_layout_tree_with(node_key)
95    }
96}