telar_ui_core/
layout_leaf.rs1use geometry_core::Rect;
2use layout_core::{LayoutError, LayoutStyle, NodeId};
3use reactive_core::RwSignal;
4use ui_tree::{NodeVec, RenderNode};
5
6use crate::context;
7
8pub struct LayoutLeaf {
9 pub node: NodeId,
10 pub rect: RwSignal<Rect>,
11}
12
13impl LayoutLeaf {
14 pub fn register(layout_style: LayoutStyle) -> Result<Self, LayoutError> {
15 let (node, rect) = context::new_leaf(layout_style)?;
16 Ok(Self { node, rect })
17 }
18
19 pub(crate) fn at_layout_position(&self, content: RenderNode) -> RenderNode {
20 let r = self.rect.get();
21 RenderNode::Transform {
22 matrix: [1.0, 0.0, 0.0, 1.0, r.x, r.y],
23 children: NodeVec::collect([content]),
24 }
25 }
26}
27
28pub(crate) fn resolve_intrinsic_size(
32 style: LayoutStyle,
33 intrinsic: impl FnOnce() -> (f32, f32),
34) -> LayoutStyle {
35 match (style.is_width_auto(), style.is_height_auto()) {
36 (true, true) => {
37 let (iw, ih) = intrinsic();
38 style.width(iw).height(ih)
39 }
40 (true, false) => match style.height_px() {
41 Some(h) => {
42 let (iw, ih) = intrinsic();
43 if ih > 0.0 {
44 style.width(h * iw / ih)
45 } else {
46 style
47 }
48 }
49 None => style,
50 },
51 (false, true) => match style.width_px() {
52 Some(w) => {
53 let (iw, ih) = intrinsic();
54 if iw > 0.0 {
55 style.height(w * ih / iw)
56 } else {
57 style
58 }
59 }
60 None => style,
61 },
62 (false, false) => style,
63 }
64}