1use crate::component::{Component, EventCx, LayoutCx, MeasureCx};
2use crate::event::Event;
3use crate::geom::{Rect, Size};
4use crate::layout::Constraint;
5use crate::node::Node;
6use crate::render::RenderCx;
7use crate::style::{Layout, Style};
8
9pub struct Stack {
11 children: Vec<Node>,
12 style: Style,
13}
14
15impl Stack {
16 pub fn new() -> Self {
17 Self {
18 children: Vec::new(),
19 style: Style::default().layout(Layout::Horizontal),
20 }
21 }
22
23 pub fn child(mut self, component: impl Component + 'static) -> Self {
24 self.children.push(Node::new(component));
25 self
26 }
27
28 pub fn padding(mut self, value: u16) -> Self {
29 self.style = self.style.padding(value);
30 self
31 }
32}
33
34impl Component for Stack {
35 fn render(&self, cx: &mut RenderCx) {
36 for child in &self.children {
37 child.render_with_parent(cx.buffer, cx.focused_id, cx.clip_rect, cx.wrap, cx.truncate, cx.align, Some(&cx.style));
38 }
39 }
40
41 fn for_each_child(&self, f: &mut dyn FnMut(&Node)) {
42 for child in &self.children {
43 f(child);
44 }
45 }
46
47 fn for_each_child_mut(&mut self, f: &mut dyn FnMut(&mut Node)) {
48 for child in &mut self.children {
49 f(child);
50 }
51 }
52
53 fn measure(&self, constraint: Constraint, _cx: &mut MeasureCx) -> Size {
54 let mut max_w: u16 = 0;
55 let mut max_h: u16 = 0;
56 for child in &self.children {
57 let s = child.measure(constraint);
58 max_w = max_w.max(s.width);
59 max_h = max_h.max(s.height);
60 }
61 Size {
62 width: max_w.saturating_add(self.style.padding.left).saturating_add(self.style.padding.right),
63 height: max_h.saturating_add(self.style.padding.top).saturating_add(self.style.padding.bottom),
64 }
65 }
66
67 fn focusable(&self) -> bool {
68 false
69 }
70
71
72 fn event(&mut self, event: &Event, cx: &mut EventCx) {
73 if matches!(event, Event::Focus | Event::Blur | Event::Tick) {
74 return;
75 }
76
77 for child in self.children.iter_mut().rev() {
79 let mut child_cx =
80 EventCx::with_task_sender(&mut child.dirty, cx.global_dirty, cx.quit, cx.phase, cx.propagation_stopped, cx.task_sender.clone());
81 child.component.event(event, &mut child_cx);
82 }
83 }
84
85 fn layout(&mut self, rect: Rect, _cx: &mut LayoutCx) {
86 let inner = rect.inner(self.style.padding);
87 for child in &mut self.children {
88 child.layout(inner);
89 }
90 }
91
92 fn style(&self) -> Style {
93 self.style.clone()
94 }
95}