Skip to main content

rustmotion_core/engine/
box_tree.rs

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