Files
2026-10-25 21:25:43 +08:00

163 lines
4.3 KiB
Rust

//! Owned immutable visual derivation; no managed VM handles.
use std::sync::Arc;
#[derive(Debug, Clone, PartialEq)]
pub struct UiNode {
pub flex: f32,
pub flex_policy: crate::layout::FlexPolicy,
pub main_align: crate::layout::MainAlign,
pub block_id: String,
pub protocol_key: String,
pub slots: Vec<u64>,
pub interactive: bool,
pub kind: UiKind,
}
impl UiNode {
pub fn children(&self) -> &[Arc<UiNode>] {
match &self.kind {
UiKind::Column { children, .. }
| UiKind::Row { children, .. }
| UiKind::Button { children, .. }
| UiKind::Scroll { children, .. } => children,
_ => &[],
}
}
pub fn has_flex(&self) -> bool {
self.flex > 0.0 || self.flex_policy != crate::layout::FlexPolicy::default()
}
pub fn shallow_eq(&self, other: &Self) -> bool {
if self.flex_policy != other.flex_policy
|| self.flex != other.flex
|| self.main_align != other.main_align
|| self.block_id != other.block_id
|| self.protocol_key != other.protocol_key
|| self.slots != other.slots
|| self.interactive != other.interactive
{
return false;
}
let same_children = || {
self.children().len() == other.children().len()
&& self
.children()
.iter()
.zip(other.children())
.all(|(a, b)| Arc::ptr_eq(a, b))
};
match (&self.kind, &other.kind) {
(
UiKind::Text {
value: a,
size: sa,
color: ca,
},
UiKind::Text {
value: b,
size: sb,
color: cb,
},
) => a == b && sa == sb && ca == cb,
(
UiKind::Rect {
width: a,
height: b,
radius: c,
color: d,
},
UiKind::Rect {
width: e,
height: f,
radius: g,
color: h,
},
) => (a, b, c, d) == (e, f, g, h),
(UiKind::Spacer(a), UiKind::Spacer(b)) => a == b,
(
UiKind::Scroll {
axis: aa,
width: a,
height: b,
padding: pa,
gap: ga,
children: _,
},
UiKind::Scroll {
axis: ab,
width: c,
height: d,
padding: pb,
gap: gb,
children: _,
},
) => aa == ab && a == c && b == d && pa == pb && ga == gb && same_children(),
(
UiKind::Column {
padding: a, gap: b, ..
},
UiKind::Column {
padding: c, gap: d, ..
},
)
| (
UiKind::Row {
padding: a, gap: b, ..
},
UiKind::Row {
padding: c, gap: d, ..
},
)
| (
UiKind::Button {
padding: a, gap: b, ..
},
UiKind::Button {
padding: c, gap: d, ..
},
) => a == c && b == d && same_children(),
_ => false,
}
}
}
#[derive(Debug, Clone, PartialEq)]
pub enum UiKind {
Button {
padding: f32,
gap: f32,
children: Vec<Arc<UiNode>>,
},
Text {
value: String,
size: u32,
color: String,
},
Rect {
width: f32,
height: f32,
radius: f32,
color: String,
},
Column {
padding: f32,
gap: f32,
children: Vec<Arc<UiNode>>,
},
Row {
padding: f32,
gap: f32,
children: Vec<Arc<UiNode>>,
},
Spacer(f32),
Scroll {
axis: crate::scroll::Axis,
width: f32,
height: f32,
padding: f32,
gap: f32,
children: Vec<Arc<UiNode>>,
},
}