use geometry_core::Rect;
use layout_core::{LayoutError, LayoutStyle, NodeId};
use reactive_core::RwSignal;
use ui_tree::{NodeVec, RenderNode};
use crate::context;
pub struct LayoutLeaf {
pub node: NodeId,
pub rect: RwSignal<Rect>,
}
impl LayoutLeaf {
pub fn register(layout_style: LayoutStyle) -> Result<Self, LayoutError> {
let (node, rect) = context::new_leaf(layout_style)?;
Ok(Self { node, rect })
}
pub(crate) fn at_layout_position(&self, content: RenderNode) -> RenderNode {
let r = self.rect.get();
RenderNode::Transform {
matrix: [1.0, 0.0, 0.0, 1.0, r.x, r.y],
children: NodeVec::collect([content]),
}
}
}
pub(crate) fn resolve_intrinsic_size(
style: LayoutStyle,
intrinsic: impl FnOnce() -> (f32, f32),
) -> LayoutStyle {
match (style.is_width_auto(), style.is_height_auto()) {
(true, true) => {
let (iw, ih) = intrinsic();
style.width(iw).height(ih)
}
(true, false) => match style.height_px() {
Some(h) => {
let (iw, ih) = intrinsic();
if ih > 0.0 {
style.width(h * iw / ih)
} else {
style
}
}
None => style,
},
(false, true) => match style.width_px() {
Some(w) => {
let (iw, ih) = intrinsic();
if iw > 0.0 {
style.height(w * ih / iw)
} else {
style
}
}
None => style,
},
(false, false) => style,
}
}