Add a new zero-sized `Overlay` element and paint it in the foreground

Antonio Scandurra created

Change summary

gpui/src/elements.rs         |  2 +
gpui/src/elements/overlay.rs | 57 ++++++++++++++++++++++++++++++++++++++
2 files changed, 59 insertions(+)

Detailed changes

gpui/src/elements.rs 🔗

@@ -9,6 +9,7 @@ mod label;
 mod line_box;
 mod list;
 mod mouse_event_handler;
+mod overlay;
 mod stack;
 mod svg;
 mod text;
@@ -26,6 +27,7 @@ pub use label::*;
 pub use line_box::*;
 pub use list::*;
 pub use mouse_event_handler::*;
+pub use overlay::*;
 pub use stack::*;
 pub use svg::*;
 pub use text::*;

gpui/src/elements/overlay.rs 🔗

@@ -0,0 +1,57 @@
+use crate::{
+    geometry::{rect::RectF, vector::Vector2F},
+    DebugContext, Element, ElementBox, Event, EventContext, LayoutContext, PaintContext,
+    SizeConstraint,
+};
+
+pub struct Overlay {
+    child: ElementBox,
+}
+
+impl Overlay {
+    pub fn new(child: ElementBox) -> Self {
+        Self { child }
+    }
+}
+
+impl Element for Overlay {
+    type LayoutState = Vector2F;
+    type PaintState = ();
+
+    fn layout(
+        &mut self,
+        constraint: SizeConstraint,
+        cx: &mut LayoutContext,
+    ) -> (Vector2F, Self::LayoutState) {
+        let size = self.child.layout(constraint, cx);
+        (Vector2F::zero(), size)
+    }
+
+    fn paint(&mut self, bounds: RectF, size: &mut Self::LayoutState, cx: &mut PaintContext) {
+        let bounds = RectF::new(bounds.origin(), *size);
+        cx.scene.push_foreground_layer(Some(bounds));
+        self.child.paint(bounds.origin(), cx);
+        cx.scene.pop_layer();
+    }
+
+    fn dispatch_event(
+        &mut self,
+        event: &Event,
+        _: RectF,
+        _: &mut Self::LayoutState,
+        _: &mut Self::PaintState,
+        cx: &mut EventContext,
+    ) -> bool {
+        self.child.dispatch_event(event, cx)
+    }
+
+    fn debug(
+        &self,
+        _: RectF,
+        _: &Self::LayoutState,
+        _: &Self::PaintState,
+        cx: &DebugContext,
+    ) -> serde_json::Value {
+        self.child.debug(cx)
+    }
+}