overlay.rs

 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}