Checkpoint

Nathan Sobo created

Change summary

crates/gpui2/src/elements/node.rs | 118 ++++++++++++++++----------------
1 file changed, 58 insertions(+), 60 deletions(-)

Detailed changes

crates/gpui2/src/elements/node.rs 🔗

@@ -11,12 +11,14 @@ use refineable::Refineable;
 use smallvec::SmallVec;
 use std::{
     any::{Any, TypeId},
+    fmt::Debug,
     marker::PhantomData,
     mem,
     sync::Arc,
     time::Duration,
 };
 use taffy::style::Overflow;
+use util::ResultExt;
 
 const DRAG_THRESHOLD: f64 = 2.;
 const TOOLTIP_DELAY: Duration = Duration::from_millis(500);
@@ -30,10 +32,36 @@ pub struct GroupStyle {
 pub trait InteractiveComponent<V: 'static>: Sized + Element<V> {
     fn interactivity(&mut self) -> &mut Interactivity<V>;
 
-    fn hover(mut self, f: impl FnOnce(StyleRefinement) -> StyleRefinement) -> Self
+    fn id(mut self, id: impl Into<ElementId>) -> Stateful<V, Self> {
+        self.interactivity().element_id = Some(id.into());
+
+        Stateful {
+            element: self,
+            view_type: PhantomData,
+        }
+    }
+
+    fn track_focus(mut self, focus_handle: FocusHandle) -> Focusable<V, Self> {
+        self.interactivity().focusable = true;
+        self.interactivity().tracked_focus_handle = Some(focus_handle);
+        Focusable {
+            element: self,
+            view_type: PhantomData,
+        }
+    }
+
+    fn key_context<C, E>(mut self, key_context: C) -> Self
     where
-        Self: Sized,
+        C: TryInto<KeyContext, Error = E>,
+        E: Debug,
     {
+        if let Some(key_context) = key_context.try_into().log_err() {
+            self.interactivity().key_context = key_context;
+        }
+        self
+    }
+
+    fn hover(mut self, f: impl FnOnce(StyleRefinement) -> StyleRefinement) -> Self {
         self.interactivity().hover_style = f(StyleRefinement::default());
         self
     }
@@ -42,10 +70,7 @@ pub trait InteractiveComponent<V: 'static>: Sized + Element<V> {
         mut self,
         group_name: impl Into<SharedString>,
         f: impl FnOnce(StyleRefinement) -> StyleRefinement,
-    ) -> Self
-    where
-        Self: Sized,
-    {
+    ) -> Self {
         self.interactivity().group_hover_style = Some(GroupStyle {
             group: group_name.into(),
             style: f(StyleRefinement::default()),
@@ -57,10 +82,7 @@ pub trait InteractiveComponent<V: 'static>: Sized + Element<V> {
         mut self,
         button: MouseButton,
         handler: impl Fn(&mut V, &MouseDownEvent, &mut ViewContext<V>) + 'static,
-    ) -> Self
-    where
-        Self: Sized,
-    {
+    ) -> Self {
         self.interactivity().mouse_down_listeners.push(Box::new(
             move |view, event, bounds, phase, cx| {
                 if phase == DispatchPhase::Bubble
@@ -78,10 +100,7 @@ pub trait InteractiveComponent<V: 'static>: Sized + Element<V> {
         mut self,
         button: MouseButton,
         handler: impl Fn(&mut V, &MouseUpEvent, &mut ViewContext<V>) + 'static,
-    ) -> Self
-    where
-        Self: Sized,
-    {
+    ) -> Self {
         self.interactivity().mouse_up_listeners.push(Box::new(
             move |view, event, bounds, phase, cx| {
                 if phase == DispatchPhase::Bubble
@@ -98,10 +117,7 @@ pub trait InteractiveComponent<V: 'static>: Sized + Element<V> {
     fn on_mouse_down_out(
         mut self,
         handler: impl Fn(&mut V, &MouseDownEvent, &mut ViewContext<V>) + 'static,
-    ) -> Self
-    where
-        Self: Sized,
-    {
+    ) -> Self {
         self.interactivity().mouse_down_listeners.push(Box::new(
             move |view, event, bounds, phase, cx| {
                 if phase == DispatchPhase::Capture && !bounds.contains_point(&event.position) {
@@ -116,10 +132,7 @@ pub trait InteractiveComponent<V: 'static>: Sized + Element<V> {
         mut self,
         button: MouseButton,
         handler: impl Fn(&mut V, &MouseUpEvent, &mut ViewContext<V>) + 'static,
-    ) -> Self
-    where
-        Self: Sized,
-    {
+    ) -> Self {
         self.interactivity().mouse_up_listeners.push(Box::new(
             move |view, event, bounds, phase, cx| {
                 if phase == DispatchPhase::Capture
@@ -136,10 +149,7 @@ pub trait InteractiveComponent<V: 'static>: Sized + Element<V> {
     fn on_mouse_move(
         mut self,
         handler: impl Fn(&mut V, &MouseMoveEvent, &mut ViewContext<V>) + 'static,
-    ) -> Self
-    where
-        Self: Sized,
-    {
+    ) -> Self {
         self.interactivity().mouse_move_listeners.push(Box::new(
             move |view, event, bounds, phase, cx| {
                 if phase == DispatchPhase::Bubble && bounds.contains_point(&event.position) {
@@ -153,10 +163,7 @@ pub trait InteractiveComponent<V: 'static>: Sized + Element<V> {
     fn on_scroll_wheel(
         mut self,
         handler: impl Fn(&mut V, &ScrollWheelEvent, &mut ViewContext<V>) + 'static,
-    ) -> Self
-    where
-        Self: Sized,
-    {
+    ) -> Self {
         self.interactivity().scroll_wheel_listeners.push(Box::new(
             move |view, event, bounds, phase, cx| {
                 if phase == DispatchPhase::Bubble && bounds.contains_point(&event.position) {
@@ -171,10 +178,7 @@ pub trait InteractiveComponent<V: 'static>: Sized + Element<V> {
     fn capture_action<A: Action>(
         mut self,
         listener: impl Fn(&mut V, &A, &mut ViewContext<V>) + 'static,
-    ) -> Self
-    where
-        Self: Sized,
-    {
+    ) -> Self {
         self.interactivity().action_listeners.push((
             TypeId::of::<A>(),
             Box::new(move |view, action, phase, cx| {
@@ -191,10 +195,7 @@ pub trait InteractiveComponent<V: 'static>: Sized + Element<V> {
     fn on_action<A: Action>(
         mut self,
         listener: impl Fn(&mut V, &A, &mut ViewContext<V>) + 'static,
-    ) -> Self
-    where
-        Self: Sized,
-    {
+    ) -> Self {
         self.interactivity().action_listeners.push((
             TypeId::of::<A>(),
             Box::new(move |view, action, phase, cx| {
@@ -210,10 +211,7 @@ pub trait InteractiveComponent<V: 'static>: Sized + Element<V> {
     fn on_key_down(
         mut self,
         listener: impl Fn(&mut V, &KeyDownEvent, DispatchPhase, &mut ViewContext<V>) + 'static,
-    ) -> Self
-    where
-        Self: Sized,
-    {
+    ) -> Self {
         self.interactivity()
             .key_down_listeners
             .push(Box::new(move |view, event, phase, cx| {
@@ -225,10 +223,7 @@ pub trait InteractiveComponent<V: 'static>: Sized + Element<V> {
     fn on_key_up(
         mut self,
         listener: impl Fn(&mut V, &KeyUpEvent, DispatchPhase, &mut ViewContext<V>) + 'static,
-    ) -> Self
-    where
-        Self: Sized,
-    {
+    ) -> Self {
         self.interactivity()
             .key_up_listeners
             .push(Box::new(move |view, event, phase, cx| {
@@ -237,10 +232,7 @@ pub trait InteractiveComponent<V: 'static>: Sized + Element<V> {
         self
     }
 
-    fn drag_over<S: 'static>(mut self, f: impl FnOnce(StyleRefinement) -> StyleRefinement) -> Self
-    where
-        Self: Sized,
-    {
+    fn drag_over<S: 'static>(mut self, f: impl FnOnce(StyleRefinement) -> StyleRefinement) -> Self {
         self.interactivity()
             .drag_over_styles
             .push((TypeId::of::<S>(), f(StyleRefinement::default())));
@@ -251,10 +243,7 @@ pub trait InteractiveComponent<V: 'static>: Sized + Element<V> {
         mut self,
         group_name: impl Into<SharedString>,
         f: impl FnOnce(StyleRefinement) -> StyleRefinement,
-    ) -> Self
-    where
-        Self: Sized,
-    {
+    ) -> Self {
         self.interactivity().group_drag_over_styles.push((
             TypeId::of::<S>(),
             GroupStyle {
@@ -268,10 +257,7 @@ pub trait InteractiveComponent<V: 'static>: Sized + Element<V> {
     fn on_drop<W: 'static>(
         mut self,
         listener: impl Fn(&mut V, View<W>, &mut ViewContext<V>) + 'static,
-    ) -> Self
-    where
-        Self: Sized,
-    {
+    ) -> Self {
         self.interactivity().drop_listeners.push((
             TypeId::of::<W>(),
             Box::new(move |view, dragged_view, cx| {
@@ -283,6 +269,11 @@ pub trait InteractiveComponent<V: 'static>: Sized + Element<V> {
 }
 
 pub trait StatefulInteractiveComponent<V: 'static, E: Element<V>>: InteractiveComponent<V> {
+    fn focusable(mut self) -> Self {
+        self.interactivity().focusable = true;
+        self
+    }
+
     fn active(mut self, f: impl FnOnce(StyleRefinement) -> StyleRefinement) -> Self
     where
         Self: Sized,
@@ -523,6 +514,13 @@ pub type KeyUpListener<V> =
 pub type ActionListener<V> =
     Box<dyn Fn(&mut V, &dyn Any, DispatchPhase, &mut ViewContext<V>) + 'static>;
 
+pub fn node<V: 'static>() -> Node<V> {
+    Node {
+        interactivity: Interactivity::default(),
+        children: Vec::default(),
+    }
+}
+
 pub struct Node<V> {
     interactivity: Interactivity<V>,
     children: Vec<AnyElement<V>>,
@@ -1203,8 +1201,8 @@ impl GroupBounds {
 }
 
 pub struct Focusable<V, E> {
-    view_type: PhantomData<V>,
     element: E,
+    view_type: PhantomData<V>,
 }
 
 impl<V: 'static, E: InteractiveComponent<V>> FocusableComponent<V> for Focusable<V, E> {}
@@ -1265,8 +1263,8 @@ where
 }
 
 pub struct Stateful<V, E> {
-    view_type: PhantomData<V>,
     element: E,
+    view_type: PhantomData<V>,
 }
 
 impl<V, E> StatefulInteractiveComponent<V, E> for Stateful<V, E>