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, LayoutContext, PaintContext, SizeConstraint,
8};
9
10#[derive(Default)]
11pub struct Stack {
12 children: Vec<ElementBox>,
13}
14
15impl Stack {
16 pub fn new() -> Self {
17 Self::default()
18 }
19}
20
21impl Element for Stack {
22 type LayoutState = ();
23 type PaintState = ();
24
25 fn layout(
26 &mut self,
27 mut constraint: SizeConstraint,
28 cx: &mut LayoutContext,
29 ) -> (Vector2F, Self::LayoutState) {
30 let mut size = constraint.min;
31 for child in &mut self.children {
32 size = size.max(child.layout(constraint, cx));
33 constraint.min = size;
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.paint_layer(None, |cx| {
47 child.paint(bounds.origin(), visible_bounds, cx);
48 });
49 }
50 }
51
52 fn rect_for_text_range(
53 &self,
54 range_utf16: Range<usize>,
55 _: RectF,
56 _: RectF,
57 _: &Self::LayoutState,
58 _: &Self::PaintState,
59 cx: &MeasurementContext,
60 ) -> Option<RectF> {
61 self.children
62 .iter()
63 .rev()
64 .find_map(|child| child.rect_for_text_range(range_utf16.clone(), cx))
65 }
66
67 fn debug(
68 &self,
69 bounds: RectF,
70 _: &Self::LayoutState,
71 _: &Self::PaintState,
72 cx: &DebugContext,
73 ) -> json::Value {
74 json!({
75 "type": "Stack",
76 "bounds": bounds.to_json(),
77 "children": self.children.iter().map(|child| child.debug(cx)).collect::<Vec<json::Value>>()
78 })
79 }
80}
81
82impl Extend<ElementBox> for Stack {
83 fn extend<T: IntoIterator<Item = ElementBox>>(&mut self, children: T) {
84 self.children.extend(children)
85 }
86}