rustmotion_core/engine/
box_tree.rs1use std::sync::Arc;
2
3use crate::css::CssStyle;
4
5pub type NodeId = u32;
6
7pub struct BoxNode {
8 pub id: NodeId,
9 pub kind: BoxKind,
10 pub css: CssStyle,
11 pub children: Vec<BoxNode>,
12 pub intrinsic: Option<Arc<dyn IntrinsicMeasure>>,
13 pub source_path: Option<String>,
14 pub window: Option<PaintWindow>,
15}
16
17#[derive(Debug, Clone, Copy, PartialEq)]
18pub struct PaintWindow {
19 pub start: Option<f64>,
20 pub end: Option<f64>,
21}
22
23impl PaintWindow {
24 pub fn contains(&self, t: f64) -> bool {
25 self.start.is_none_or(|s| t >= s) && self.end.is_none_or(|e| t < e)
26 }
27}
28
29impl BoxNode {
30 pub fn container(css: CssStyle, children: Vec<BoxNode>) -> Self {
31 Self {
32 id: 0,
33 kind: BoxKind::Container,
34 css,
35 children,
36 intrinsic: None,
37 source_path: None,
38 window: None,
39 }
40 }
41
42 pub fn leaf(css: CssStyle, intrinsic: Arc<dyn IntrinsicMeasure>) -> Self {
43 Self {
44 id: 0,
45 kind: BoxKind::Container,
46 css,
47 children: Vec::new(),
48 intrinsic: Some(intrinsic),
49 source_path: None,
50 window: None,
51 }
52 }
53
54 pub fn assign_ids(&mut self, mut next: NodeId) -> NodeId {
55 self.id = next;
56 next += 1;
57 for c in self.children.iter_mut() {
58 next = c.assign_ids(next);
59 }
60 next
61 }
62
63 pub fn find(&self, id: NodeId) -> Option<&BoxNode> {
64 if self.id == id {
65 return Some(self);
66 }
67 for c in &self.children {
68 if let Some(r) = c.find(id) {
69 return Some(r);
70 }
71 }
72 None
73 }
74}
75
76#[derive(Clone)]
77pub enum BoxKind {
78 Container,
79 Component(Arc<dyn std::any::Any + Send + Sync>),
80 Ghost(Arc<dyn std::any::Any + Send + Sync>),
81}
82
83pub trait IntrinsicMeasure: Send + Sync {
84 fn measure(
85 &self,
86 known: (Option<f32>, Option<f32>),
87 available: (AvailableSpace, AvailableSpace),
88 ) -> (f32, f32);
89}
90
91#[derive(Debug, Clone, Copy, PartialEq)]
92pub enum AvailableSpace {
93 Definite(f32),
94 MinContent,
95 MaxContent,
96}
97
98impl From<taffy::AvailableSpace> for AvailableSpace {
99 fn from(v: taffy::AvailableSpace) -> Self {
100 match v {
101 taffy::AvailableSpace::Definite(p) => Self::Definite(p),
102 taffy::AvailableSpace::MinContent => Self::MinContent,
103 taffy::AvailableSpace::MaxContent => Self::MaxContent,
104 }
105 }
106}