rosace_widgets/tree/
stack.rs1use rosace_core::types::Size;
2use super::{Widget, LayoutCtx, PaintCtx, BoxedWidget, avail_w, avail_h};
3
4pub struct Stack {
6 children: Vec<BoxedWidget>,
7 fit: StackFit,
8}
9
10#[derive(Debug, Clone, Copy, Default)]
12pub enum StackFit {
13 #[default]
15 Loose,
16 Expand,
18}
19
20impl Stack {
21 pub fn new() -> Self { Self { children: Vec::new(), fit: StackFit::Loose } }
22 pub fn fit(mut self, f: StackFit) -> Self { self.fit = f; self }
23 pub fn child(mut self, w: impl Widget + 'static) -> Self {
24 self.children.push(Box::new(w)); self
25 }
26}
27
28impl Default for Stack {
29 fn default() -> Self { Self::new() }
30}
31
32impl Widget for Stack {
33 fn layout(&self, ctx: &LayoutCtx) -> Size {
34 let constraints = ctx.constraints;
35 match self.fit {
36 StackFit::Expand => Size {
37 width: avail_w(constraints),
38 height: avail_h(constraints),
39 },
40 StackFit::Loose => {
41 let mut max_w = 0.0_f32;
42 let mut max_h = 0.0_f32;
43 for child in &self.children {
44 let s = child.layout(ctx);
45 max_w = max_w.max(s.width);
46 max_h = max_h.max(s.height);
47 }
48 Size { width: max_w, height: max_h }
49 }
50 }
51 }
52
53 fn paint(&self, ctx: &mut PaintCtx) {
54 for child in &self.children {
55 child.paint(&mut ctx.child(ctx.rect));
56 }
57 }
58}