@@ -1,6 +1,6 @@
use crate::{
- AnyElement, Bounds, DispatchPhase, Element, Interactive, MouseEventListeners, MouseMoveEvent,
- ParentElement, Pixels, Styled, ViewContext,
+ AnyElement, Bounds, DispatchPhase, Element, ElementId, Identified, Interactive,
+ MouseEventListeners, MouseMoveEvent, ParentElement, Pixels, Styled, ViewContext,
};
use anyhow::Result;
use refineable::{CascadeSlot, Refineable, RefinementCascade};
@@ -95,3 +95,9 @@ impl<E: ParentElement + Styled> ParentElement for Hoverable<E> {
self.child.children_mut()
}
}
+
+impl<E: Identified + Styled> Identified for Hoverable<E> {
+ fn id(&self) -> ElementId {
+ self.child.id()
+ }
+}
@@ -1,16 +1,16 @@
-use crate::{ElementId, Element, Bounds, ViewContext, LayoutId};
+use crate::{BorrowWindow, Bounds, Element, ElementId, LayoutId, ViewContext};
use anyhow::Result;
-use derive_more::{Deref, DerefMut}
-#[derive(Deref, DerefMut)]
-pub struct Identified<E> {
- #[deref]
- #[deref_mut]
- element: E,
- id: ElementId,
+pub trait Identified {
+ fn id(&self) -> ElementId;
}
-impl<E: Element> Element for Identified<E> {
+pub struct ElementWithId<E> {
+ pub(crate) element: E,
+ pub(crate) id: ElementId,
+}
+
+impl<E: Element> Element for ElementWithId<E> {
type State = E::State;
type FrameState = E::FrameState;
@@ -29,8 +29,14 @@ impl<E: Element> Element for Identified<E> {
frame_state: &mut Self::FrameState,
cx: &mut ViewContext<Self::State>,
) -> Result<()> {
- cx.with_element_id(self.id, |cx| {
+ cx.with_element_id(self.id.clone(), |cx| {
self.element.paint(bounds, state, frame_state, cx)
})
}
}
+
+impl<E> Identified for ElementWithId<E> {
+ fn id(&self) -> ElementId {
+ self.id.clone()
+ }
+}
@@ -6,6 +6,7 @@ mod elements;
mod events;
mod executor;
mod geometry;
+mod identified;
mod image_cache;
mod interactive;
mod platform;
@@ -30,6 +31,7 @@ pub use events::*;
pub use executor::*;
pub use geometry::*;
pub use gpui3_macros::*;
+pub use identified::*;
pub use image_cache::*;
pub use interactive::*;
pub use platform::*;
@@ -39,22 +41,24 @@ pub use serde;
pub use serde_json;
pub use smallvec;
pub use smol::Timer;
-use std::{
- mem,
- ops::{Deref, DerefMut},
- sync::Arc,
-};
pub use style::*;
pub use style_helpers::*;
pub use styled::*;
pub use svg_renderer::*;
-use taffy::TaffyLayoutEngine;
pub use taffy::{AvailableSpace, LayoutId};
pub use text_system::*;
pub use util::arc_cow::ArcCow;
pub use view::*;
pub use window::*;
+use derive_more::{Deref, DerefMut};
+use std::{
+ mem,
+ ops::{Deref, DerefMut},
+ sync::Arc,
+};
+use taffy::TaffyLayoutEngine;
+
pub trait Context {
type EntityContext<'a, 'w, T: 'static + Send + Sync>;
type Result<T>;
@@ -167,9 +171,12 @@ impl<T> Flatten<T> for Result<T> {
#[derive(Clone, Eq, PartialEq, Hash)]
pub struct SharedString(ArcCow<'static, str>);
-#[derive(Clone, Eq, PartialEq, Hash)]
+#[derive(Clone, Debug, Eq, PartialEq, Hash)]
pub struct ElementId(ArcCow<'static, [u8]>);
+#[derive(Default, Deref, DerefMut, Clone, Debug)]
+pub(crate) struct GlobalElementId(SmallVec<[ElementId; 8]>);
+
impl Default for SharedString {
fn default() -> Self {
Self(ArcCow::Owned("".into()))
@@ -1,12 +1,12 @@
use crate::{
image_cache::RenderImageParams, px, size, AnyView, AppContext, AsyncWindowContext,
AvailableSpace, BorrowAppContext, Bounds, BoxShadow, Context, Corners, DevicePixels, DisplayId,
- 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,
- SUBPIXEL_VARIANTS,
+ Edges, Effect, Element, ElementId, EntityId, Event, FontId, GlobalElementId, 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, SUBPIXEL_VARIANTS,
};
use anyhow::Result;
use collections::HashMap;
@@ -21,7 +21,7 @@ use std::{
mem,
sync::Arc,
};
-use util::{arc_cow::ArcCow, ResultExt};
+use util::ResultExt;
#[derive(Deref, DerefMut, Ord, PartialOrd, Eq, PartialEq, Clone, Default)]
pub struct StackingOrder(pub(crate) SmallVec<[u32; 16]>);
@@ -51,7 +51,7 @@ pub struct Window {
content_size: Size<Pixels>,
layout_engine: TaffyLayoutEngine,
pub(crate) root_view: Option<AnyView<()>>,
- element_id_stack: SmallVec<[ElementId; 8]>,
+ pub(crate) element_id_stack: GlobalElementId,
z_index_stack: StackingOrder,
content_mask_stack: Vec<ContentMask<Pixels>>,
mouse_event_handlers: HashMap<TypeId, Vec<(StackingOrder, MouseEventHandler)>>,
@@ -113,6 +113,7 @@ impl Window {
content_size,
layout_engine: TaffyLayoutEngine::new(),
root_view: None,
+ element_id_stack: GlobalElementId::default(),
z_index_stack: StackingOrder(SmallVec::new()),
content_mask_stack: Vec::new(),
mouse_event_handlers: HashMap::default(),
@@ -729,6 +730,17 @@ pub trait BorrowWindow: BorrowAppContext {
fn window(&self) -> &Window;
fn window_mut(&mut self) -> &mut Window;
+ fn with_element_id<R>(
+ &mut self,
+ id: impl Into<ElementId>,
+ f: impl FnOnce(&mut Self) -> R,
+ ) -> R {
+ self.window_mut().element_id_stack.push(id.into());
+ let result = f(self);
+ self.window_mut().element_id_stack.pop();
+ result
+ }
+
fn with_content_mask<R>(
&mut self,
mask: ContentMask<Pixels>,