use std::marker::PhantomData; use crate::prelude::*; pub struct Stack { pub children: Vec, pub size: StackSize, } impl Widget for Stack { fn draw(&mut self, painter: &mut Painter) -> Size { let sizing = match self.size { StackSize::Default => None, StackSize::Child(i) => Some(i), }; let mut size = Size::default(); for (i, child) in self.children.iter().enumerate() { match i { 0 => painter.child_layer(), _ => painter.next_layer(), } let drawn = painter.widget(child); // Only the child that sizes the stack is read, so the others // changing size does not redraw it. if sizing == Some(i) { size = drawn.size(); } } size } } #[derive(Default, Debug)] pub enum StackSize { #[default] Default, Child(usize), } pub struct StackBuilder, Tag> { pub children: Wa, pub size: StackSize, _pd: PhantomData<(State, Tag)>, } impl, Tag> WidgetFnTrait for StackBuilder { type Widget = Stack; #[track_caller] fn run(self, rsc: &mut Rsc) -> Self::Widget { Stack { children: self.children.add(rsc).arr.into_iter().collect(), size: self.size, } } } impl, Tag> StackBuilder { pub fn new(children: Wa) -> Self { Self { children, size: StackSize::default(), _pd: PhantomData, } } pub fn size(mut self, size: StackSize) -> Self { self.size = size; self } }