1use std::ops::Range;
2
3use crate::{
4 geometry::{rect::RectF, vector::Vector2F},
5 json::{self, json, ToJson},
6 presenter::MeasurementContext,
7 DebugContext, Element, ElementBox, Event, EventContext, LayoutContext, PaintContext,
8 SizeConstraint,
9};
10
11#[derive(Default)]
12pub struct Stack {
13 children: Vec<ElementBox>,
14}
15
16impl Stack {
17 pub fn new() -> Self {
18 Self::default()
19 }
20}
21
22impl Element for Stack {
23 type LayoutState = ();
24 type PaintState = ();
25
26 fn layout(
27 &mut self,
28 constraint: SizeConstraint,
29 cx: &mut LayoutContext,
30 ) -> (Vector2F, Self::LayoutState) {
31 let mut size = constraint.min;
32 for child in &mut self.children {
33 size = size.max(child.layout(constraint, cx));
34 }
35 (size, ())
36 }
37
38 fn paint(
39 &mut self,
40 bounds: RectF,
41 visible_bounds: RectF,
42 _: &mut Self::LayoutState,
43 cx: &mut PaintContext,
44 ) -> Self::PaintState {
45 for child in &mut self.children {
46 cx.scene.push_layer(None);
47 child.paint(bounds.origin(), visible_bounds, cx);
48 cx.scene.pop_layer();
49 }
50 }
51
52 fn dispatch_event(
53 &mut self,
54 event: &Event,
55 _: RectF,
56 _: RectF,
57 _: &mut Self::LayoutState,
58 _: &mut Self::PaintState,
59 cx: &mut EventContext,
60 ) -> bool {
61 for child in self.children.iter_mut().rev() {
62 if child.dispatch_event(event, cx) {
63 return true;
64 }
65 }
66 false
67 }
68
69 fn rect_for_text_range(
70 &self,
71 range_utf16: Range<usize>,
72 _: RectF,
73 _: RectF,
74 _: &Self::LayoutState,
75 _: &Self::PaintState,
76 cx: &MeasurementContext,
77 ) -> Option<RectF> {
78 self.children
79 .iter()
80 .rev()
81 .find_map(|child| child.rect_for_text_range(range_utf16.clone(), cx))
82 }
83
84 fn debug(
85 &self,
86 bounds: RectF,
87 _: &Self::LayoutState,
88 _: &Self::PaintState,
89 cx: &DebugContext,
90 ) -> json::Value {
91 json!({
92 "type": "Stack",
93 "bounds": bounds.to_json(),
94 "children": self.children.iter().map(|child| child.debug(cx)).collect::<Vec<json::Value>>()
95 })
96 }
97}
98
99impl Extend<ElementBox> for Stack {
100 fn extend<T: IntoIterator<Item = ElementBox>>(&mut self, children: T) {
101 self.children.extend(children)
102 }
103}