WIP

Antonio Scandurra created

Change summary

crates/gpui3/src/elements.rs            |  2 +
crates/gpui3/src/elements/identified.rs | 36 ++++++++++++++++++++++++++
crates/gpui3/src/gpui3.rs               |  3 ++
crates/gpui3/src/window.rs              | 37 +++++++++++++-------------
4 files changed, 60 insertions(+), 18 deletions(-)

Detailed changes

crates/gpui3/src/elements.rs 🔗

@@ -1,5 +1,6 @@
 mod div;
 mod hoverable;
+mod identified;
 mod img;
 mod stateless;
 mod svg;
@@ -7,6 +8,7 @@ mod text;
 
 pub use div::*;
 pub use hoverable::*;
+pub use identified::*;
 pub use img::*;
 pub use stateless::*;
 pub use svg::*;

crates/gpui3/src/elements/identified.rs 🔗

@@ -0,0 +1,36 @@
+use crate::{ElementId, Element, Bounds, ViewContext, LayoutId};
+use anyhow::Result;
+use derive_more::{Deref, DerefMut}
+
+#[derive(Deref, DerefMut)]
+pub struct Identified<E> {
+    #[deref]
+    #[deref_mut]
+    element: E,
+    id: ElementId,
+}
+
+impl<E: Element> Element for Identified<E> {
+    type State = E::State;
+    type FrameState = E::FrameState;
+
+    fn layout(
+        &mut self,
+        state: &mut Self::State,
+        cx: &mut ViewContext<Self::State>,
+    ) -> Result<(LayoutId, Self::FrameState)> {
+        self.element.layout(state, cx)
+    }
+
+    fn paint(
+        &mut self,
+        bounds: Bounds<crate::Pixels>,
+        state: &mut Self::State,
+        frame_state: &mut Self::FrameState,
+        cx: &mut ViewContext<Self::State>,
+    ) -> Result<()> {
+        cx.with_element_id(self.id, |cx| {
+            self.element.paint(bounds, state, frame_state, cx)
+        })
+    }
+}

crates/gpui3/src/gpui3.rs 🔗

@@ -167,6 +167,9 @@ impl<T> Flatten<T> for Result<T> {
 #[derive(Clone, Eq, PartialEq, Hash)]
 pub struct SharedString(ArcCow<'static, str>);
 
+#[derive(Clone, Eq, PartialEq, Hash)]
+pub struct ElementId(ArcCow<'static, [u8]>);
+
 impl Default for SharedString {
     fn default() -> Self {
         Self(ArcCow::Owned("".into()))

crates/gpui3/src/window.rs 🔗

@@ -1,8 +1,8 @@
 use crate::{
     image_cache::RenderImageParams, px, size, AnyView, AppContext, AsyncWindowContext,
     AvailableSpace, BorrowAppContext, Bounds, BoxShadow, Context, Corners, DevicePixels, DisplayId,
-    Edges, Effect, Element, EntityId, Event, FontId, GlyphId, Handle, Hsla, ImageData, IsZero,
-    LayoutId, MainThread, MainThreadOnly, MonochromeSprite, MouseMoveEvent, Path, Pixels,
+    Edges, Effect, Element, ElementId, EntityId, Event, FontId, GlyphId, Handle, Hsla, ImageData,
+    IsZero, LayoutId, MainThread, MainThreadOnly, MonochromeSprite, MouseMoveEvent, Path, Pixels,
     PlatformAtlas, PlatformWindow, Point, PolychromeSprite, Quad, Reference, RenderGlyphParams,
     RenderSvgParams, ScaledPixels, SceneBuilder, Shadow, SharedString, Size, Style,
     TaffyLayoutEngine, Task, Underline, UnderlineStyle, WeakHandle, WindowOptions,
@@ -21,7 +21,7 @@ use std::{
     mem,
     sync::Arc,
 };
-use util::ResultExt;
+use util::{arc_cow::ArcCow, ResultExt};
 
 #[derive(Deref, DerefMut, Ord, PartialOrd, Eq, PartialEq, Clone, Default)]
 pub struct StackingOrder(pub(crate) SmallVec<[u32; 16]>);
@@ -51,7 +51,8 @@ pub struct Window {
     content_size: Size<Pixels>,
     layout_engine: TaffyLayoutEngine,
     pub(crate) root_view: Option<AnyView<()>>,
-    current_stacking_order: StackingOrder,
+    element_id_stack: SmallVec<[ElementId; 8]>,
+    z_index_stack: StackingOrder,
     content_mask_stack: Vec<ContentMask<Pixels>>,
     mouse_event_handlers: HashMap<TypeId, Vec<(StackingOrder, MouseEventHandler)>>,
     propagate_event: bool,
@@ -112,7 +113,7 @@ impl Window {
             content_size,
             layout_engine: TaffyLayoutEngine::new(),
             root_view: None,
-            current_stacking_order: StackingOrder(SmallVec::new()),
+            z_index_stack: StackingOrder(SmallVec::new()),
             content_mask_stack: Vec::new(),
             mouse_event_handlers: HashMap::default(),
             propagate_event: true,
@@ -287,7 +288,7 @@ impl<'a, 'w> WindowContext<'a, 'w> {
         &mut self,
         handler: impl Fn(&Event, DispatchPhase, &mut WindowContext) + Send + Sync + 'static,
     ) {
-        let order = self.window.current_stacking_order.clone();
+        let order = self.window.z_index_stack.clone();
         self.window
             .mouse_event_handlers
             .entry(TypeId::of::<Event>())
@@ -305,9 +306,9 @@ impl<'a, 'w> WindowContext<'a, 'w> {
     }
 
     pub fn stack<R>(&mut self, order: u32, f: impl FnOnce(&mut Self) -> R) -> R {
-        self.window.current_stacking_order.push(order);
+        self.window.z_index_stack.push(order);
         let result = f(self);
-        self.window.current_stacking_order.pop();
+        self.window.z_index_stack.pop();
         result
     }
 
@@ -325,7 +326,7 @@ impl<'a, 'w> WindowContext<'a, 'w> {
             shadow_bounds.origin += shadow.offset;
             shadow_bounds.dilate(shadow.spread_radius);
             window.scene_builder.insert(
-                &window.current_stacking_order,
+                &window.z_index_stack,
                 Shadow {
                     order: 0,
                     bounds: shadow_bounds.scale(scale_factor),
@@ -351,7 +352,7 @@ impl<'a, 'w> WindowContext<'a, 'w> {
 
         let window = &mut *self.window;
         window.scene_builder.insert(
-            &window.current_stacking_order,
+            &window.z_index_stack,
             Quad {
                 order: 0,
                 bounds: bounds.scale(scale_factor),
@@ -372,7 +373,7 @@ impl<'a, 'w> WindowContext<'a, 'w> {
         let window = &mut *self.window;
         window
             .scene_builder
-            .insert(&window.current_stacking_order, path.scale(scale_factor));
+            .insert(&window.z_index_stack, path.scale(scale_factor));
     }
 
     pub fn paint_underline(
@@ -394,7 +395,7 @@ impl<'a, 'w> WindowContext<'a, 'w> {
         let content_mask = self.content_mask();
         let window = &mut *self.window;
         window.scene_builder.insert(
-            &window.current_stacking_order,
+            &window.z_index_stack,
             Underline {
                 order: 0,
                 bounds: bounds.scale(scale_factor),
@@ -446,7 +447,7 @@ impl<'a, 'w> WindowContext<'a, 'w> {
             let content_mask = self.content_mask().scale(scale_factor);
             let window = &mut *self.window;
             window.scene_builder.insert(
-                &window.current_stacking_order,
+                &window.z_index_stack,
                 MonochromeSprite {
                     order: 0,
                     bounds,
@@ -495,7 +496,7 @@ impl<'a, 'w> WindowContext<'a, 'w> {
             let window = &mut *self.window;
 
             window.scene_builder.insert(
-                &window.current_stacking_order,
+                &window.z_index_stack,
                 PolychromeSprite {
                     order: 0,
                     bounds,
@@ -536,7 +537,7 @@ impl<'a, 'w> WindowContext<'a, 'w> {
 
         let window = &mut *self.window;
         window.scene_builder.insert(
-            &window.current_stacking_order,
+            &window.z_index_stack,
             MonochromeSprite {
                 order: 0,
                 bounds,
@@ -571,7 +572,7 @@ impl<'a, 'w> WindowContext<'a, 'w> {
 
         let window = &mut *self.window;
         window.scene_builder.insert(
-            &window.current_stacking_order,
+            &window.z_index_stack,
             PolychromeSprite {
                 order: 0,
                 bounds,
@@ -824,9 +825,9 @@ impl<'a, 'w, S: Send + Sync + 'static> ViewContext<'a, 'w, S> {
     }
 
     pub fn stack<R>(&mut self, order: u32, f: impl FnOnce(&mut Self) -> R) -> R {
-        self.window.current_stacking_order.push(order);
+        self.window.z_index_stack.push(order);
         let result = f(self);
-        self.window.current_stacking_order.pop();
+        self.window.z_index_stack.pop();
         result
     }