Checkpoint

Nathan Sobo created

Change summary

crates/gpui3/src/arc_cow.rs             |   0 
crates/gpui3/src/element.rs             |  20 +
crates/gpui3/src/elements/hoverable.rs  |  14 
crates/gpui3/src/elements/identified.rs |  20 
crates/gpui3/src/elements/pressable.rs  | 339 +++++++++++++-------------
crates/gpui3/src/gpui3.rs               |   9 
crates/gpui3/src/identified.rs          |   1 
7 files changed, 201 insertions(+), 202 deletions(-)

Detailed changes

crates/gpui3/src/element.rs 🔗

@@ -1,12 +1,16 @@
-use crate::{Bounds, ElementId, ElementWithId};
-
-use super::{LayoutId, Pixels, Point, Result, ViewContext};
+use crate::{Bounds, Identified, LayoutId, Pixels, Point, Result, ViewContext};
+use derive_more::{Deref, DerefMut};
 pub(crate) use smallvec::SmallVec;
+use util::arc_cow::ArcCow;
 
 pub trait Element: 'static {
     type State;
     type FrameState;
 
+    fn element_id(&self) -> Option<ElementId> {
+        None
+    }
+
     fn layout(
         &mut self,
         state: &mut Self::State,
@@ -21,14 +25,20 @@ pub trait Element: 'static {
         cx: &mut ViewContext<Self::State>,
     ) -> Result<()>;
 
-    fn id(self, id: ElementId) -> ElementWithId<Self>
+    fn id(self, id: ElementId) -> Identified<Self>
     where
         Self: Sized,
     {
-        ElementWithId { element: self, id }
+        Identified { element: self, id }
     }
 }
 
+#[derive(Clone, Debug, Eq, PartialEq, Hash)]
+pub struct ElementId(ArcCow<'static, [u8]>);
+
+#[derive(Deref, DerefMut, Default, Clone, Debug)]
+pub(crate) struct GlobalElementId(SmallVec<[ElementId; 8]>);
+
 pub trait ParentElement {
     type State;
 

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

@@ -1,6 +1,6 @@
 use crate::{
-    AnyElement, Bounds, DispatchPhase, Element, ElementId, Identified, Interactive,
-    MouseEventListeners, MouseMoveEvent, ParentElement, Pixels, Styled, ViewContext,
+    AnyElement, Bounds, DispatchPhase, Element, ElementId, Interactive, MouseEventListeners,
+    MouseMoveEvent, ParentElement, Pixels, Stateful, Styled, ViewContext,
 };
 use anyhow::Result;
 use refineable::{CascadeSlot, Refineable, RefinementCascade};
@@ -53,6 +53,10 @@ impl<E: Element + Styled> Element for Hoverable<E> {
     type State = E::State;
     type FrameState = E::FrameState;
 
+    fn element_id(&self) -> Option<ElementId> {
+        self.child.element_id()
+    }
+
     fn layout(
         &mut self,
         state: &mut Self::State,
@@ -96,8 +100,4 @@ impl<E: ParentElement + Styled> ParentElement for Hoverable<E> {
     }
 }
 
-impl<E: Identified + Styled> Identified for Hoverable<E> {
-    fn id(&self) -> ElementId {
-        self.child.id()
-    }
-}
+impl<E: Stateful + Styled> Stateful for Hoverable<E> {}

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

@@ -1,19 +1,25 @@
 use crate::{BorrowWindow, Bounds, Element, ElementId, LayoutId, ViewContext};
 use anyhow::Result;
 
-pub trait Identified {
-    fn id(&self) -> ElementId;
+pub trait Stateful: Element {
+    fn element_id(&self) -> ElementId {
+        Element::element_id(self).unwrap()
+    }
 }
 
-pub struct ElementWithId<E> {
+pub struct Identified<E> {
     pub(crate) element: E,
     pub(crate) id: ElementId,
 }
 
-impl<E: Element> Element for ElementWithId<E> {
+impl<E: Element> Element for Identified<E> {
     type State = E::State;
     type FrameState = E::FrameState;
 
+    fn element_id(&self) -> Option<ElementId> {
+        Some(self.id.clone())
+    }
+
     fn layout(
         &mut self,
         state: &mut Self::State,
@@ -35,8 +41,4 @@ impl<E: Element> Element for ElementWithId<E> {
     }
 }
 
-impl<E> Identified for ElementWithId<E> {
-    fn id(&self) -> ElementId {
-        self.id.clone()
-    }
-}
+impl<E: Element> Stateful for Identified<E> {}

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

@@ -1,214 +1,211 @@
-use crate::{
-    AnyElement, Bounds, DispatchPhase, Element, Identified, Interactive, MouseDownEvent,
-    MouseEventListeners, MouseMoveEvent, MouseUpEvent, ParentElement, Pixels, Styled, ViewContext,
-};
-use anyhow::Result;
-use refineable::{CascadeSlot, Refineable, RefinementCascade};
-use smallvec::SmallVec;
-use std::sync::{
-    atomic::{AtomicBool, Ordering::SeqCst},
-    Arc,
-};
-
-pub struct Pressable<E: Styled> {
-    pressed: Arc<AtomicBool>,
-    cascade_slot: CascadeSlot,
-    pressed_style: <E::Style as Refineable>::Refinement,
-    child: E,
-}
-
-impl<E: Identified + Styled> Pressable<E> {
-    pub fn new(mut child: E) -> Self {
-        Self {
-            pressed: Arc::new(AtomicBool::new(false)),
-            cascade_slot: child.style_cascade().reserve(),
-            pressed_style: Default::default(),
-            child,
-        }
-    }
-}
-
-impl<E> Styled for Pressable<E>
-where
-    E: Styled,
-{
-    type Style = E::Style;
-
-    fn style_cascade(&mut self) -> &mut RefinementCascade<E::Style> {
-        self.child.style_cascade()
-    }
-
-    fn declared_style(&mut self) -> &mut <Self::Style as refineable::Refineable>::Refinement {
-        &mut self.pressed_style
-    }
-}
-
-impl<S: 'static + Send + Sync, E: Interactive<S> + Styled> Interactive<S> for Pressable<E> {
-    fn listeners(&mut self) -> &mut MouseEventListeners<S> {
-        self.child.listeners()
-    }
-}
-
-impl<E: Element + Identified + Styled> Element for Pressable<E> {
-    type State = E::State;
-    type FrameState = E::FrameState;
-
-    fn layout(
-        &mut self,
-        state: &mut Self::State,
-        cx: &mut ViewContext<Self::State>,
-    ) -> Result<(crate::LayoutId, Self::FrameState)> {
-        Ok(self.child.layout(state, cx)?)
-    }
-
-    fn paint(
-        &mut self,
-        bounds: Bounds<Pixels>,
-        state: &mut Self::State,
-        frame_state: &mut Self::FrameState,
-        cx: &mut ViewContext<Self::State>,
-    ) -> Result<()> {
-        let pressed = bounds.contains_point(cx.mouse_position());
-        let slot = self.cascade_slot;
-        let style = pressed.then_some(self.pressed_style.clone());
-        self.style_cascade().set(slot, style);
-        self.pressed.store(pressed, SeqCst);
-
-        let hovered = self.pressed.clone();
-        cx.on_mouse_event(move |event: &MouseDownEvent, phase, cx| {
-            if phase == DispatchPhase::Capture {
-                if bounds.contains_point(event.position) != hovered.load(SeqCst) {
-                    cx.notify();
-                }
-            }
-        });
-        cx.on_mouse_event(move |event: &MouseUpEvent, phase, cx| {
-            if phase == DispatchPhase::Capture {
-                if bounds.contains_point(event.position) != hovered.load(SeqCst) {
-                    cx.notify();
-                }
-            }
-        });
-
-        cx.frame_state::<Self>(self.id().to_global(cx))
-        // cx.frame_state
-
-        self.child.paint(bounds, state, frame_state, cx)?;
-        Ok(())
-    }
-}
-
-impl<E: ParentElement + Styled> ParentElement for Pressable<E> {
-    type State = E::State;
-
-    fn children_mut(&mut self) -> &mut SmallVec<[AnyElement<Self::State>; 2]> {
-        self.child.children_mut()
-    }
-}
-
 // use crate::{
-//     element::{AnyElement, Element, IntoElement, Layout, ParentElement},
-//     interactive::{InteractionHandlers, Interactive},
-//     style::{Style, StyleHelpers, Styleable},
-//     ViewContext,
+//     AnyElement, Bounds, DispatchPhase, Element, Identified, Interactive, MouseDownEvent,
+//     MouseEventListeners, MouseUpEvent, ParentElement, Pixels, Styled, ViewContext,
 // };
 // use anyhow::Result;
-// use gpui::{geometry::vector::Vector2F, platform::MouseButtonEvent, LayoutId};
 // use refineable::{CascadeSlot, Refineable, RefinementCascade};
 // use smallvec::SmallVec;
-// use std::{cell::Cell, rc::Rc};
+// use std::sync::{
+//     atomic::{AtomicBool, Ordering::SeqCst},
+//     Arc,
+// };
 
-// pub struct Pressable<E: Styleable> {
-//     pressed: Rc<Cell<bool>>,
-//     pressed_style: <E::Style as Refineable>::Refinement,
+// pub struct Pressable<E: Styled> {
+//     pressed: Arc<AtomicBool>,
 //     cascade_slot: CascadeSlot,
+//     pressed_style: <E::Style as Refineable>::Refinement,
 //     child: E,
 // }
 
-// pub fn pressable<E: Styleable>(mut child: E) -> Pressable<E> {
-//     Pressable {
-//         pressed: Rc::new(Cell::new(false)),
-//         pressed_style: Default::default(),
-//         cascade_slot: child.style_cascade().reserve(),
-//         child,
+// impl<E: Identified + Styled> Pressable<E> {
+//     pub fn new(mut child: E) -> Self {
+//         Self {
+//             pressed: Arc::new(AtomicBool::new(false)),
+//             cascade_slot: child.style_cascade().reserve(),
+//             pressed_style: Default::default(),
+//             child,
+//         }
 //     }
 // }
 
-// impl<E: Styleable> Styleable for Pressable<E> {
+// impl<E> Styled for Pressable<E>
+// where
+//     E: Styled,
+// {
 //     type Style = E::Style;
 
-//     fn declared_style(&mut self) -> &mut <Self::Style as Refineable>::Refinement {
+//     fn style_cascade(&mut self) -> &mut RefinementCascade<E::Style> {
+//         self.child.style_cascade()
+//     }
+
+//     fn declared_style(&mut self) -> &mut <Self::Style as refineable::Refineable>::Refinement {
 //         &mut self.pressed_style
 //     }
+// }
 
-//     fn style_cascade(&mut self) -> &mut RefinementCascade<E::Style> {
-//         self.child.style_cascade()
+// impl<S: 'static + Send + Sync, E: Interactive<S> + Styled> Interactive<S> for Pressable<E> {
+//     fn listeners(&mut self) -> &mut MouseEventListeners<S> {
+//         self.child.listeners()
 //     }
 // }
 
-// impl<V: 'static, E: Element<V> + Styleable> Element<V> for Pressable<E> {
-//     type PaintState = E::PaintState;
+// impl<E: Element + Identified + Styled> Element for Pressable<E> {
+//     type State = E::State;
+//     type FrameState = E::FrameState;
 
 //     fn layout(
 //         &mut self,
-//         view: &mut V,
-//         cx: &mut ViewContext<V>,
-//     ) -> Result<(LayoutId, Self::PaintState)>
-//     where
-//         Self: Sized,
-//     {
-//         self.child.layout(view, cx)
+//         state: &mut Self::State,
+//         cx: &mut ViewContext<Self::State>,
+//     ) -> Result<(crate::LayoutId, Self::FrameState)> {
+//         Ok(self.child.layout(state, cx)?)
 //     }
 
 //     fn paint(
 //         &mut self,
-//         view: &mut V,
-//         parent_origin: Vector2F,
-//         layout: &Layout,
-//         paint_state: &mut Self::PaintState,
-//         cx: &mut ViewContext<V>,
-//     ) where
-//         Self: Sized,
-//     {
+//         bounds: Bounds<Pixels>,
+//         state: &mut Self::State,
+//         frame_state: &mut Self::FrameState,
+//         cx: &mut ViewContext<Self::State>,
+//     ) -> Result<()> {
+//         let pressed = bounds.contains_point(cx.mouse_position());
 //         let slot = self.cascade_slot;
-//         let style = self.pressed.get().then_some(self.pressed_style.clone());
+//         let style = pressed.then_some(self.pressed_style.clone());
 //         self.style_cascade().set(slot, style);
+//         self.pressed.store(pressed, SeqCst);
 
-//         let pressed = self.pressed.clone();
-//         let bounds = layout.bounds + parent_origin;
-//         cx.on_event(layout.order, move |_view, event: &MouseButtonEvent, cx| {
-//             if event.is_down {
-//                 if bounds.contains_point(event.position) {
-//                     pressed.set(true);
-//                     cx.repaint();
+//         let hovered = self.pressed.clone();
+//         cx.on_mouse_event(move |event: &MouseDownEvent, phase, cx| {
+//             if phase == DispatchPhase::Capture {
+//                 if bounds.contains_point(event.position) != hovered.load(SeqCst) {
+//                     cx.notify();
+//                 }
+//             }
+//         });
+//         cx.on_mouse_event(move |event: &MouseUpEvent, phase, cx| {
+//             if phase == DispatchPhase::Capture {
+//                 if bounds.contains_point(event.position) != hovered.load(SeqCst) {
+//                     cx.notify();
 //                 }
-//             } else if pressed.get() {
-//                 pressed.set(false);
-//                 cx.repaint();
 //             }
 //         });
 
-//         self.child
-//             .paint(view, parent_origin, layout, paint_state, cx);
+//         self.child.paint(bounds, state, frame_state, cx)?;
+//         Ok(())
 //     }
 // }
 
-// impl<V: 'static, E: Interactive<V> + Styleable> Interactive<V> for Pressable<E> {
-//     fn interaction_handlers(&mut self) -> &mut InteractionHandlers<V> {
-//         self.child.interaction_handlers()
-//     }
-// }
+// impl<E: ParentElement + Styled> ParentElement for Pressable<E> {
+//     type State = E::State;
 
-// impl<V: 'static, E: ParentElement<V> + Styleable> ParentElement<V> for Pressable<E> {
-//     fn children_mut(&mut self) -> &mut SmallVec<[AnyElement<V>; 2]> {
+//     fn children_mut(&mut self) -> &mut SmallVec<[AnyElement<Self::State>; 2]> {
 //         self.child.children_mut()
 //     }
 // }
 
-// impl<V: 'static, E: Element<V> + Styleable> IntoElement<V> for Pressable<E> {
-//     type Element = Self;
-
-//     fn into_element(self) -> Self::Element {
-//         self
-//     }
-// }
+// // use crate::{
+// //     element::{AnyElement, Element, IntoElement, Layout, ParentElement},
+// //     interactive::{InteractionHandlers, Interactive},
+// //     style::{Style, StyleHelpers, Styleable},
+// //     ViewContext,
+// // };
+// // use anyhow::Result;
+// // use gpui::{geometry::vector::Vector2F, platform::MouseButtonEvent, LayoutId};
+// // use refineable::{CascadeSlot, Refineable, RefinementCascade};
+// // use smallvec::SmallVec;
+// // use std::{cell::Cell, rc::Rc};
+
+// // pub struct Pressable<E: Styleable> {
+// //     pressed: Rc<Cell<bool>>,
+// //     pressed_style: <E::Style as Refineable>::Refinement,
+// //     cascade_slot: CascadeSlot,
+// //     child: E,
+// // }
+
+// // pub fn pressable<E: Styleable>(mut child: E) -> Pressable<E> {
+// //     Pressable {
+// //         pressed: Rc::new(Cell::new(false)),
+// //         pressed_style: Default::default(),
+// //         cascade_slot: child.style_cascade().reserve(),
+// //         child,
+// //     }
+// // }
+
+// // impl<E: Styleable> Styleable for Pressable<E> {
+// //     type Style = E::Style;
+
+// //     fn declared_style(&mut self) -> &mut <Self::Style as Refineable>::Refinement {
+// //         &mut self.pressed_style
+// //     }
+
+// //     fn style_cascade(&mut self) -> &mut RefinementCascade<E::Style> {
+// //         self.child.style_cascade()
+// //     }
+// // }
+
+// // impl<V: 'static, E: Element<V> + Styleable> Element<V> for Pressable<E> {
+// //     type PaintState = E::PaintState;
+
+// //     fn layout(
+// //         &mut self,
+// //         view: &mut V,
+// //         cx: &mut ViewContext<V>,
+// //     ) -> Result<(LayoutId, Self::PaintState)>
+// //     where
+// //         Self: Sized,
+// //     {
+// //         self.child.layout(view, cx)
+// //     }
+
+// //     fn paint(
+// //         &mut self,
+// //         view: &mut V,
+// //         parent_origin: Vector2F,
+// //         layout: &Layout,
+// //         paint_state: &mut Self::PaintState,
+// //         cx: &mut ViewContext<V>,
+// //     ) where
+// //         Self: Sized,
+// //     {
+// //         let slot = self.cascade_slot;
+// //         let style = self.pressed.get().then_some(self.pressed_style.clone());
+// //         self.style_cascade().set(slot, style);
+
+// //         let pressed = self.pressed.clone();
+// //         let bounds = layout.bounds + parent_origin;
+// //         cx.on_event(layout.order, move |_view, event: &MouseButtonEvent, cx| {
+// //             if event.is_down {
+// //                 if bounds.contains_point(event.position) {
+// //                     pressed.set(true);
+// //                     cx.repaint();
+// //                 }
+// //             } else if pressed.get() {
+// //                 pressed.set(false);
+// //                 cx.repaint();
+// //             }
+// //         });
+
+// //         self.child
+// //             .paint(view, parent_origin, layout, paint_state, cx);
+// //     }
+// // }
+
+// // impl<V: 'static, E: Interactive<V> + Styleable> Interactive<V> for Pressable<E> {
+// //     fn interaction_handlers(&mut self) -> &mut InteractionHandlers<V> {
+// //         self.child.interaction_handlers()
+// //     }
+// // }
+
+// // impl<V: 'static, E: ParentElement<V> + Styleable> ParentElement<V> for Pressable<E> {
+// //     fn children_mut(&mut self) -> &mut SmallVec<[AnyElement<V>; 2]> {
+// //         self.child.children_mut()
+// //     }
+// // }
+
+// // impl<V: 'static, E: Element<V> + Styleable> IntoElement<V> for Pressable<E> {
+// //     type Element = Self;
+
+// //     fn into_element(self) -> Self::Element {
+// //         self
+// //     }
+// // }

crates/gpui3/src/gpui3.rs 🔗

@@ -6,7 +6,6 @@ mod elements;
 mod events;
 mod executor;
 mod geometry;
-mod identified;
 mod image_cache;
 mod interactive;
 mod platform;
@@ -31,7 +30,6 @@ 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::*;
@@ -51,7 +49,6 @@ pub use util::arc_cow::ArcCow;
 pub use view::*;
 pub use window::*;
 
-use derive_more::{Deref, DerefMut};
 use std::{
     mem,
     ops::{Deref, DerefMut},
@@ -171,12 +168,6 @@ impl<T> Flatten<T> for Result<T> {
 #[derive(Clone, Eq, PartialEq, Hash)]
 pub struct SharedString(ArcCow<'static, str>);
 
-#[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()))