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 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}