From 0fbf84e6bc9cd7ae06ab9b8fcaed44997bfb2144 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Thu, 19 Oct 2023 22:28:42 +0200 Subject: [PATCH] Checkpoint --- crates/gpui3/src/element.rs | 68 ++++++++++++++++++++++++++------ crates/gpui3/src/elements/div.rs | 47 +++++++++++----------- crates/gpui3/src/elements/img.rs | 34 ++++++++-------- crates/gpui3/src/elements/svg.rs | 34 ++++++++-------- 4 files changed, 115 insertions(+), 68 deletions(-) diff --git a/crates/gpui3/src/element.rs b/crates/gpui3/src/element.rs index 961a22a5f9..7e0e46cb26 100644 --- a/crates/gpui3/src/element.rs +++ b/crates/gpui3/src/element.rs @@ -5,7 +5,7 @@ use crate::{ use derive_more::{Deref, DerefMut}; use refineable::Refineable; pub(crate) use smallvec::SmallVec; -use std::mem; +use std::{marker::PhantomData, mem}; pub trait Element: 'static + Send + Sync + IntoAnyElement { type ViewState: 'static + Send + Sync; @@ -39,22 +39,66 @@ pub trait Element: 'static + Send + Sync + IntoAnyElement { #[derive(Deref, DerefMut, Default, Clone, Debug, Eq, PartialEq, Hash)] pub struct GlobalElementId(SmallVec<[ElementId; 32]>); -pub trait ElementIdentity: 'static + Send + Sync { - fn id(&self) -> Option; -} +pub trait ElementInteractivity: 'static + Send + Sync { + fn as_stateful(&self) -> Option<&StatefulInteractivity>; -pub struct Identified(pub(crate) ElementId); - -impl ElementIdentity for Identified { - fn id(&self) -> Option { - Some(self.0.clone()) + fn initialize( + &self, + cx: &mut ViewContext, + f: impl FnOnce(Option, &mut ViewContext) -> R, + ) -> R { + if let Some(identified) = self.as_stateful() { + cx.with_element_id(identified.id.clone(), |global_id, cx| { + f(Some(global_id), cx) + }) + } else { + f(None, cx) + } } } -pub struct Anonymous; +#[derive(Deref, DerefMut)] +pub struct StatefulInteractivity { + pub id: ElementId, + #[deref] + #[deref_mut] + common: StatelessInteractivity, +} -impl ElementIdentity for Anonymous { - fn id(&self) -> Option { +impl ElementInteractivity for StatefulInteractivity +where + V: 'static + Send + Sync, +{ + fn as_stateful(&self) -> Option<&StatefulInteractivity> { + Some(self) + } +} + +impl From for StatefulInteractivity +where + V: 'static + Send + Sync, +{ + fn from(id: ElementId) -> Self { + Self { + id, + common: StatelessInteractivity::default(), + } + } +} + +pub struct StatelessInteractivity(PhantomData); + +impl Default for StatelessInteractivity { + fn default() -> Self { + Self(PhantomData) + } +} + +impl ElementInteractivity for StatelessInteractivity +where + V: 'static + Send + Sync, +{ + fn as_stateful(&self) -> Option<&StatefulInteractivity> { None } } diff --git a/crates/gpui3/src/elements/div.rs b/crates/gpui3/src/elements/div.rs index 33dbe15671..5621ece1c5 100644 --- a/crates/gpui3/src/elements/div.rs +++ b/crates/gpui3/src/elements/div.rs @@ -1,9 +1,10 @@ use crate::{ - Active, Anonymous, AnyElement, AppContext, BorrowWindow, Bounds, Click, DispatchPhase, Element, - ElementFocusability, ElementId, ElementIdentity, Focus, FocusHandle, FocusListeners, Focusable, - GlobalElementId, Hover, Identified, Interactive, Interactivity, IntoAnyElement, KeyDownEvent, + Active, AnyElement, AppContext, BorrowWindow, Bounds, Click, DispatchPhase, Element, + ElementFocusability, ElementId, ElementInteractivity, Focus, FocusHandle, FocusListeners, + Focusable, GlobalElementId, Hover, Interactive, Interactivity, IntoAnyElement, KeyDownEvent, KeyMatch, LayoutId, MouseDownEvent, MouseMoveEvent, MouseUpEvent, NonFocusable, Overflow, - ParentElement, Pixels, Point, SharedString, Style, StyleRefinement, Styled, ViewContext, + ParentElement, Pixels, Point, SharedString, StatefulInteractivity, StatelessInteractivity, + Style, StyleRefinement, Styled, ViewContext, }; use collections::HashMap; use parking_lot::Mutex; @@ -62,7 +63,7 @@ impl ScrollState { pub struct Div< V: 'static + Send + Sync, - I: ElementIdentity = Anonymous, + I: ElementInteractivity = StatelessInteractivity, F: ElementFocusability = NonFocusable, > { identity: I, @@ -77,12 +78,12 @@ pub struct Div< group_active: Option, } -pub fn div() -> Div +pub fn div() -> Div, NonFocusable> where V: 'static + Send + Sync, { Div { - identity: Anonymous, + identity: StatelessInteractivity::default(), focusability: NonFocusable, interactivity: Interactivity::default(), children: SmallVec::new(), @@ -100,14 +101,14 @@ struct GroupStyle { style: StyleRefinement, } -impl Div +impl Div, F> where F: ElementFocusability, V: 'static + Send + Sync, { - pub fn id(self, id: impl Into) -> Div { + pub fn id(self, id: impl Into) -> Div, F> { Div { - identity: Identified(id.into()), + identity: id.into().into(), focusability: self.focusability, interactivity: self.interactivity, children: self.children, @@ -123,7 +124,7 @@ where impl Div where - I: ElementIdentity, + I: ElementInteractivity, F: ElementFocusability, V: 'static + Send + Sync, { @@ -271,7 +272,7 @@ where impl Div where - I: ElementIdentity, + I: ElementInteractivity, V: 'static + Send + Sync, { pub fn focusable(self, handle: &FocusHandle) -> Div> { @@ -292,7 +293,7 @@ where impl Focus for Div> where - I: ElementIdentity, + I: ElementInteractivity, V: 'static + Send + Sync, { fn focus_listeners(&mut self) -> &mut FocusListeners { @@ -318,7 +319,7 @@ where impl Element for Div where - I: ElementIdentity, + I: ElementInteractivity, F: ElementFocusability, V: 'static + Send + Sync, { @@ -326,7 +327,9 @@ where type ElementState = DivState; fn id(&self) -> Option { - self.identity.id() + self.identity + .as_stateful() + .map(|identified| identified.id.clone()) } fn initialize( @@ -456,7 +459,7 @@ where impl IntoAnyElement for Div where - I: ElementIdentity, + I: ElementInteractivity, F: ElementFocusability, V: 'static + Send + Sync, { @@ -467,7 +470,7 @@ where impl ParentElement for Div where - I: ElementIdentity, + I: ElementInteractivity, F: ElementFocusability, V: 'static + Send + Sync, { @@ -478,7 +481,7 @@ where impl Styled for Div where - I: ElementIdentity, + I: ElementInteractivity, F: ElementFocusability, V: 'static + Send + Sync, { @@ -489,7 +492,7 @@ where impl Interactive for Div where - I: ElementIdentity, + I: ElementInteractivity, F: ElementFocusability, V: 'static + Send + Sync, { @@ -500,7 +503,7 @@ where impl Hover for Div where - I: ElementIdentity, + I: ElementInteractivity, F: ElementFocusability, V: 'static + Send + Sync, { @@ -513,14 +516,14 @@ where } } -impl Click for Div +impl Click for Div, F> where F: ElementFocusability, V: 'static + Send + Sync, { } -impl Active for Div +impl Active for Div, F> where F: ElementFocusability, V: 'static + Send + Sync, diff --git a/crates/gpui3/src/elements/img.rs b/crates/gpui3/src/elements/img.rs index abc6e1f36a..cf3ceda614 100644 --- a/crates/gpui3/src/elements/img.rs +++ b/crates/gpui3/src/elements/img.rs @@ -1,15 +1,15 @@ use crate::{ - div, Active, Anonymous, AnyElement, BorrowWindow, Bounds, Click, Div, DivState, Element, - ElementFocusability, ElementId, ElementIdentity, Focus, FocusListeners, Focusable, Hover, - Identified, Interactive, Interactivity, IntoAnyElement, LayoutId, NonFocusable, Pixels, - SharedString, StyleRefinement, Styled, ViewContext, + div, Active, AnyElement, BorrowWindow, Bounds, Click, Div, DivState, Element, + ElementFocusability, ElementId, ElementInteractivity, Focus, FocusListeners, Focusable, Hover, + Interactive, Interactivity, IntoAnyElement, LayoutId, NonFocusable, Pixels, SharedString, + StatefulInteractivity, StatelessInteractivity, StyleRefinement, Styled, ViewContext, }; use futures::FutureExt; use util::ResultExt; pub struct Img< V: 'static + Send + Sync, - I: ElementIdentity = Anonymous, + I: ElementInteractivity = StatelessInteractivity, F: ElementFocusability = NonFocusable, > { base: Div, @@ -17,7 +17,7 @@ pub struct Img< grayscale: bool, } -pub fn img() -> Img +pub fn img() -> Img, NonFocusable> where V: 'static + Send + Sync, { @@ -31,7 +31,7 @@ where impl Img where V: 'static + Send + Sync, - I: ElementIdentity, + I: ElementInteractivity, F: ElementFocusability, { pub fn uri(mut self, uri: impl Into) -> Self { @@ -45,12 +45,12 @@ where } } -impl Img +impl Img, F> where V: 'static + Send + Sync, F: ElementFocusability, { - pub fn id(self, id: impl Into) -> Img { + pub fn id(self, id: impl Into) -> Img, F> { Img { base: self.base.id(id), uri: self.uri, @@ -62,7 +62,7 @@ where impl IntoAnyElement for Img where V: 'static + Send + Sync, - I: ElementIdentity, + I: ElementInteractivity, F: ElementFocusability, { fn into_any(self) -> AnyElement { @@ -73,7 +73,7 @@ where impl Element for Img where V: Send + Sync + 'static, - I: ElementIdentity, + I: ElementInteractivity, F: ElementFocusability, { type ViewState = V; @@ -142,7 +142,7 @@ where impl Styled for Img where V: 'static + Send + Sync, - I: ElementIdentity, + I: ElementInteractivity, F: ElementFocusability, { fn style(&mut self) -> &mut StyleRefinement { @@ -153,7 +153,7 @@ where impl Interactive for Img where V: 'static + Send + Sync, - I: ElementIdentity, + I: ElementInteractivity, F: ElementFocusability, { fn interactivity(&mut self) -> &mut Interactivity { @@ -164,7 +164,7 @@ where impl Hover for Img where V: 'static + Send + Sync, - I: ElementIdentity, + I: ElementInteractivity, F: ElementFocusability, { fn set_hover_style(&mut self, group: Option, style: StyleRefinement) { @@ -172,14 +172,14 @@ where } } -impl Click for Img +impl Click for Img, F> where V: 'static + Send + Sync, F: ElementFocusability, { } -impl Active for Img +impl Active for Img, F> where V: 'static + Send + Sync, F: ElementFocusability, @@ -192,7 +192,7 @@ where impl Focus for Img> where V: 'static + Send + Sync, - I: ElementIdentity, + I: ElementInteractivity, { fn focus_listeners(&mut self) -> &mut FocusListeners { self.base.focus_listeners() diff --git a/crates/gpui3/src/elements/svg.rs b/crates/gpui3/src/elements/svg.rs index 7ed328a95f..d29e9fbdf3 100644 --- a/crates/gpui3/src/elements/svg.rs +++ b/crates/gpui3/src/elements/svg.rs @@ -1,21 +1,21 @@ use crate::{ - div, Active, Anonymous, AnyElement, Bounds, Click, Div, DivState, Element, ElementFocusability, - ElementId, ElementIdentity, Focus, FocusListeners, Focusable, Hover, Identified, Interactive, - Interactivity, IntoAnyElement, LayoutId, NonFocusable, Pixels, SharedString, StyleRefinement, - Styled, ViewContext, + div, Active, AnyElement, Bounds, Click, Div, DivState, Element, ElementFocusability, ElementId, + ElementInteractivity, Focus, FocusListeners, Focusable, Hover, Interactive, Interactivity, + IntoAnyElement, LayoutId, NonFocusable, Pixels, SharedString, StatefulInteractivity, + StatelessInteractivity, StyleRefinement, Styled, ViewContext, }; use util::ResultExt; pub struct Svg< V: 'static + Send + Sync, - I: ElementIdentity = Anonymous, + I: ElementInteractivity = StatelessInteractivity, F: ElementFocusability = NonFocusable, > { base: Div, path: Option, } -pub fn svg() -> Svg +pub fn svg() -> Svg, NonFocusable> where V: 'static + Send + Sync, { @@ -28,7 +28,7 @@ where impl Svg where V: 'static + Send + Sync, - I: ElementIdentity, + I: ElementInteractivity, F: ElementFocusability, { pub fn path(mut self, path: impl Into) -> Self { @@ -37,12 +37,12 @@ where } } -impl Svg +impl Svg, F> where V: 'static + Send + Sync, F: ElementFocusability, { - pub fn id(self, id: impl Into) -> Svg { + pub fn id(self, id: impl Into) -> Svg, F> { Svg { base: self.base.id(id), path: self.path, @@ -53,7 +53,7 @@ where impl IntoAnyElement for Svg where V: 'static + Send + Sync, - I: ElementIdentity, + I: ElementInteractivity, F: ElementFocusability, { fn into_any(self) -> AnyElement { @@ -64,7 +64,7 @@ where impl Element for Svg where V: 'static + Send + Sync, - I: ElementIdentity, + I: ElementInteractivity, F: ElementFocusability, { type ViewState = V; @@ -116,7 +116,7 @@ where impl Styled for Svg where V: 'static + Send + Sync, - I: ElementIdentity, + I: ElementInteractivity, F: ElementFocusability, { fn style(&mut self) -> &mut StyleRefinement { @@ -127,7 +127,7 @@ where impl Interactive for Svg where V: 'static + Send + Sync, - I: ElementIdentity, + I: ElementInteractivity, F: ElementFocusability, { fn interactivity(&mut self) -> &mut Interactivity { @@ -138,7 +138,7 @@ where impl Hover for Svg where V: 'static + Send + Sync, - I: ElementIdentity, + I: ElementInteractivity, F: ElementFocusability, { fn set_hover_style(&mut self, group: Option, style: StyleRefinement) { @@ -146,14 +146,14 @@ where } } -impl Click for Svg +impl Click for Svg, F> where V: 'static + Send + Sync, F: ElementFocusability, { } -impl Active for Svg +impl Active for Svg, F> where V: 'static + Send + Sync, F: ElementFocusability, @@ -166,7 +166,7 @@ where impl Focus for Svg> where V: 'static + Send + Sync, - I: ElementIdentity, + I: ElementInteractivity, { fn focus_listeners(&mut self) -> &mut FocusListeners { self.base.focus_listeners()