1use serde_json::json;
2
3use crate::{
4 geometry::{rect::RectF, vector::Vector2F},
5 json::ToJson,
6 DebugContext, Element, ElementBox, Event, EventContext, LayoutContext, PaintContext,
7 SizeConstraint,
8};
9
10pub struct Overlay {
11 child: ElementBox,
12 abs_position: Option<Vector2F>,
13}
14
15impl Overlay {
16 pub fn new(child: ElementBox) -> Self {
17 Self {
18 child,
19 abs_position: None,
20 }
21 }
22
23 pub fn with_abs_position(mut self, position: Vector2F) -> Self {
24 self.abs_position = Some(position);
25 self
26 }
27}
28
29impl Element for Overlay {
30 type LayoutState = Vector2F;
31 type PaintState = ();
32
33 fn layout(
34 &mut self,
35 constraint: SizeConstraint,
36 cx: &mut LayoutContext,
37 ) -> (Vector2F, Self::LayoutState) {
38 let constraint = if self.abs_position.is_some() {
39 SizeConstraint::new(Vector2F::zero(), cx.window_size)
40 } else {
41 constraint
42 };
43 let size = self.child.layout(constraint, cx);
44 (Vector2F::zero(), size)
45 }
46
47 fn paint(
48 &mut self,
49 bounds: RectF,
50 _: RectF,
51 size: &mut Self::LayoutState,
52 cx: &mut PaintContext,
53 ) {
54 let origin = self.abs_position.unwrap_or(bounds.origin());
55 let visible_bounds = RectF::new(origin, *size);
56 cx.scene.push_stacking_context(None);
57 self.child.paint(origin, visible_bounds, cx);
58 cx.scene.pop_stacking_context();
59 }
60
61 fn dispatch_event(
62 &mut self,
63 event: &Event,
64 _: RectF,
65 _: RectF,
66 _: &mut Self::LayoutState,
67 _: &mut Self::PaintState,
68 cx: &mut EventContext,
69 ) -> bool {
70 self.child.dispatch_event(event, cx)
71 }
72
73 fn debug(
74 &self,
75 _: RectF,
76 _: &Self::LayoutState,
77 _: &Self::PaintState,
78 cx: &DebugContext,
79 ) -> serde_json::Value {
80 json!({
81 "type": "Overlay",
82 "abs_position": self.abs_position.to_json(),
83 "child": self.child.debug(cx),
84 })
85 }
86}