Reviewed-on: iris/iris#16 Reviewed-by: iris <2+iris@noreply.localhost> Co-authored-by: iris-ai <4+iris-ai@noreply.localhost>
76 lines
1.8 KiB
Rust
76 lines
1.8 KiB
Rust
use std::marker::PhantomData;
|
|
|
|
use crate::prelude::*;
|
|
|
|
pub struct Stack {
|
|
pub children: Vec<StrongWidget>,
|
|
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<State, const LEN: usize, Wa: WidgetArrLike<State, LEN, Tag>, Tag> {
|
|
pub children: Wa,
|
|
pub size: StackSize,
|
|
_pd: PhantomData<(State, Tag)>,
|
|
}
|
|
|
|
impl<Rsc, const LEN: usize, Wa: WidgetArrLike<Rsc, LEN, Tag>, Tag> WidgetFnTrait<Rsc>
|
|
for StackBuilder<Rsc, LEN, Wa, Tag>
|
|
{
|
|
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<State, const LEN: usize, Wa: WidgetArrLike<State, LEN, Tag>, Tag>
|
|
StackBuilder<State, LEN, Wa, Tag>
|
|
{
|
|
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
|
|
}
|
|
}
|