rustmotion-core 0.8.1

Core types, traits, and rendering utilities for rustmotion
Documentation
use std::sync::Arc;

use crate::css::CssStyle;

pub type NodeId = u32;

pub struct BoxNode {
    pub id: NodeId,
    pub kind: BoxKind,
    pub css: CssStyle,
    pub children: Vec<BoxNode>,
    pub intrinsic: Option<Arc<dyn IntrinsicMeasure>>,
    pub source_path: Option<String>,
    pub window: Option<PaintWindow>,
}

#[derive(Debug, Clone, Copy, PartialEq)]
pub struct PaintWindow {
    pub start: Option<f64>,
    pub end: Option<f64>,
}

impl PaintWindow {
    pub fn contains(&self, t: f64) -> bool {
        self.start.is_none_or(|s| t >= s) && self.end.is_none_or(|e| t < e)
    }
}

impl BoxNode {
    pub fn container(css: CssStyle, children: Vec<BoxNode>) -> Self {
        Self {
            id: 0,
            kind: BoxKind::Container,
            css,
            children,
            intrinsic: None,
            source_path: None,
            window: None,
        }
    }

    pub fn leaf(css: CssStyle, intrinsic: Arc<dyn IntrinsicMeasure>) -> Self {
        Self {
            id: 0,
            kind: BoxKind::Container,
            css,
            children: Vec::new(),
            intrinsic: Some(intrinsic),
            source_path: None,
            window: None,
        }
    }

    pub fn assign_ids(&mut self, mut next: NodeId) -> NodeId {
        self.id = next;
        next += 1;
        for c in self.children.iter_mut() {
            next = c.assign_ids(next);
        }
        next
    }

    pub fn find(&self, id: NodeId) -> Option<&BoxNode> {
        if self.id == id {
            return Some(self);
        }
        for c in &self.children {
            if let Some(r) = c.find(id) {
                return Some(r);
            }
        }
        None
    }
}

#[derive(Clone)]
pub enum BoxKind {
    Container,
    Component(Arc<dyn std::any::Any + Send + Sync>),
    Ghost(Arc<dyn std::any::Any + Send + Sync>),
}

pub trait IntrinsicMeasure: Send + Sync {
    fn measure(
        &self,
        known: (Option<f32>, Option<f32>),
        available: (AvailableSpace, AvailableSpace),
    ) -> (f32, f32);
}

#[derive(Debug, Clone, Copy, PartialEq)]
pub enum AvailableSpace {
    Definite(f32),
    MinContent,
    MaxContent,
}

impl From<taffy::AvailableSpace> for AvailableSpace {
    fn from(v: taffy::AvailableSpace) -> Self {
        match v {
            taffy::AvailableSpace::Definite(p) => Self::Definite(p),
            taffy::AvailableSpace::MinContent => Self::MinContent,
            taffy::AvailableSpace::MaxContent => Self::MaxContent,
        }
    }
}