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