Checkpoint

Nathan Sobo created

Change summary

crates/gpui3/src/events.rs              | 10 +-
crates/gpui3/src/interactive.rs         | 73 ++++++++++++++++++++++++--
crates/gpui3/src/platform/mac/events.rs | 10 +-
crates/gpui3/src/platform/mac/window.rs |  6 +-
4 files changed, 79 insertions(+), 20 deletions(-)

Detailed changes

crates/gpui3/src/events.rs 🔗

@@ -89,7 +89,7 @@ impl Default for NavigationDirection {
 }
 
 #[derive(Clone, Debug, Default)]
-pub struct MouseMovedEvent {
+pub struct MouseMoveEvent {
     pub position: Point<Pixels>,
     pub pressed_button: Option<MouseButton>,
     pub modifiers: Modifiers,
@@ -140,13 +140,13 @@ impl ScrollDelta {
 }
 
 #[derive(Clone, Debug, Default)]
-pub struct MouseExitedEvent {
+pub struct MouseExitEvent {
     pub position: Point<Pixels>,
     pub pressed_button: Option<MouseButton>,
     pub modifiers: Modifiers,
 }
 
-impl Deref for MouseExitedEvent {
+impl Deref for MouseExitEvent {
     type Target = Modifiers;
 
     fn deref(&self) -> &Self::Target {
@@ -161,8 +161,8 @@ pub enum Event {
     ModifiersChanged(ModifiersChangedEvent),
     MouseDown(MouseDownEvent),
     MouseUp(MouseUpEvent),
-    MouseMoved(MouseMovedEvent),
-    MouseExited(MouseExitedEvent),
+    MouseMoved(MouseMoveEvent),
+    MouseExited(MouseExitEvent),
     ScrollWheel(ScrollWheelEvent),
 }
 

crates/gpui3/src/interactive.rs 🔗

@@ -1,5 +1,6 @@
 use crate::{
-    Bounds, DispatchPhase, MouseButton, MouseDownEvent, MouseUpEvent, Pixels, ViewContext,
+    Bounds, DispatchPhase, MouseButton, MouseDownEvent, MouseMoveEvent, MouseUpEvent, Pixels,
+    ScrollWheelEvent, ViewContext,
 };
 use parking_lot::Mutex;
 use smallvec::SmallVec;
@@ -122,6 +123,40 @@ pub trait Interactive<S: 'static + Send + Sync> {
             }
         })
     }
+
+    fn on_mouse_move(
+        mut self,
+        handler: impl Fn(&mut S, &MouseMoveEvent, &mut ViewContext<S>) + Send + Sync + 'static,
+    ) -> Self
+    where
+        Self: Sized,
+    {
+        self.listeners()
+            .mouse_move
+            .push(Arc::new(move |view, event, bounds, phase, cx| {
+                if phase == DispatchPhase::Bubble && bounds.contains_point(event.position) {
+                    handler(view, event, cx);
+                }
+            }));
+        self
+    }
+
+    fn on_scroll_wheel(
+        mut self,
+        handler: impl Fn(&mut S, &ScrollWheelEvent, &mut ViewContext<S>) + Send + Sync + 'static,
+    ) -> Self
+    where
+        Self: Sized,
+    {
+        self.listeners()
+            .scroll_wheel
+            .push(Arc::new(move |view, event, bounds, phase, cx| {
+                if phase == DispatchPhase::Bubble && bounds.contains_point(event.position) {
+                    handler(view, event, cx);
+                }
+            }));
+        self
+    }
 }
 
 type MouseDownHandler<V> = Arc<
@@ -137,25 +172,47 @@ type MouseUpHandler<V> = Arc<
         + 'static,
 >;
 
+type MouseMoveHandler<V> = Arc<
+    dyn Fn(&mut V, &MouseMoveEvent, &Bounds<Pixels>, DispatchPhase, &mut ViewContext<V>)
+        + Send
+        + Sync
+        + 'static,
+>;
+type ScrollWheelHandler<V> = Arc<
+    dyn Fn(&mut V, &ScrollWheelEvent, &Bounds<Pixels>, DispatchPhase, &mut ViewContext<V>)
+        + Send
+        + Sync
+        + 'static,
+>;
+
 pub struct MouseEventListeners<V: 'static> {
     mouse_down: SmallVec<[MouseDownHandler<V>; 2]>,
     mouse_up: SmallVec<[MouseUpHandler<V>; 2]>,
+    mouse_move: SmallVec<[MouseMoveHandler<V>; 2]>,
+    scroll_wheel: SmallVec<[ScrollWheelHandler<V>; 2]>,
 }
 
 impl<S: Send + Sync + 'static> MouseEventListeners<S> {
     pub fn paint(&self, bounds: Bounds<Pixels>, cx: &mut ViewContext<S>) {
         for handler in self.mouse_down.iter().cloned() {
             cx.on_mouse_event(move |view, event: &MouseDownEvent, phase, cx| {
-                if bounds.contains_point(event.position) {
-                    handler(view, event, &bounds, phase, cx);
-                }
+                handler(view, event, &bounds, phase, cx);
             })
         }
         for handler in self.mouse_up.iter().cloned() {
             cx.on_mouse_event(move |view, event: &MouseUpEvent, phase, cx| {
-                if bounds.contains_point(event.position) {
-                    handler(view, event, &bounds, phase, cx);
-                }
+                handler(view, event, &bounds, phase, cx);
+            })
+        }
+        for handler in self.mouse_move.iter().cloned() {
+            cx.on_mouse_event(move |view, event: &MouseMoveEvent, phase, cx| {
+                handler(view, event, &bounds, phase, cx);
+            })
+        }
+
+        for handler in self.scroll_wheel.iter().cloned() {
+            cx.on_mouse_event(move |view, event: &ScrollWheelEvent, phase, cx| {
+                handler(view, event, &bounds, phase, cx);
             })
         }
     }
@@ -166,6 +223,8 @@ impl<V> Default for MouseEventListeners<V> {
         Self {
             mouse_down: Default::default(),
             mouse_up: Default::default(),
+            mouse_move: Default::default(),
+            scroll_wheel: Default::default(),
         }
     }
 }

crates/gpui3/src/platform/mac/events.rs 🔗

@@ -1,7 +1,7 @@
 use crate::{
     point, px, Event, KeyDownEvent, KeyUpEvent, Keystroke, Modifiers, ModifiersChangedEvent,
-    MouseButton, MouseDownEvent, MouseExitedEvent, MouseMovedEvent, MouseUpEvent,
-    NavigationDirection, Pixels, ScrollDelta, ScrollWheelEvent, TouchPhase,
+    MouseButton, MouseDownEvent, MouseExitEvent, MouseMoveEvent, MouseUpEvent, NavigationDirection,
+    Pixels, ScrollDelta, ScrollWheelEvent, TouchPhase,
 };
 use cocoa::{
     appkit::{NSEvent, NSEventModifierFlags, NSEventPhase, NSEventType},
@@ -202,7 +202,7 @@ impl Event {
                 };
 
                 window_height.map(|window_height| {
-                    Self::MouseMoved(MouseMovedEvent {
+                    Self::MouseMoved(MouseMoveEvent {
                         pressed_button: Some(pressed_button),
                         position: point(
                             px(native_event.locationInWindow().x as f32),
@@ -213,7 +213,7 @@ impl Event {
                 })
             }
             NSEventType::NSMouseMoved => window_height.map(|window_height| {
-                Self::MouseMoved(MouseMovedEvent {
+                Self::MouseMoved(MouseMoveEvent {
                     position: point(
                         px(native_event.locationInWindow().x as f32),
                         window_height - px(native_event.locationInWindow().y as f32),
@@ -223,7 +223,7 @@ impl Event {
                 })
             }),
             NSEventType::NSMouseExited => window_height.map(|window_height| {
-                Self::MouseExited(MouseExitedEvent {
+                Self::MouseExited(MouseExitEvent {
                     position: point(
                         px(native_event.locationInWindow().x as f32),
                         window_height - px(native_event.locationInWindow().y as f32),

crates/gpui3/src/platform/mac/window.rs 🔗

@@ -2,7 +2,7 @@ use super::{display_bounds_from_native, ns_string, MacDisplay, MetalRenderer, NS
 use crate::{
     display_bounds_to_native, point, px, size, AnyWindowHandle, Bounds, Event, Executor,
     GlobalPixels, KeyDownEvent, Keystroke, Modifiers, ModifiersChangedEvent, MouseButton,
-    MouseDownEvent, MouseMovedEvent, MouseUpEvent, Pixels, PlatformAtlas, PlatformDisplay,
+    MouseDownEvent, MouseMoveEvent, MouseUpEvent, Pixels, PlatformAtlas, PlatformDisplay,
     PlatformInputHandler, PlatformWindow, Point, Scene, Size, Timer, WindowAppearance,
     WindowBounds, WindowKind, WindowOptions, WindowPromptLevel,
 };
@@ -1141,7 +1141,7 @@ extern "C" fn handle_view_event(this: &Object, _: Sel, native_event: id) {
 
         match &event {
             Event::MouseMoved(
-                event @ MouseMovedEvent {
+                event @ MouseMoveEvent {
                     pressed_button: Some(_),
                     ..
                 },
@@ -1596,7 +1596,7 @@ extern "C" fn accepts_first_mouse(this: &Object, _: Sel, _: id) -> BOOL {
 async fn synthetic_drag(
     window_state: Weak<Mutex<MacWindowState>>,
     drag_id: usize,
-    event: MouseMovedEvent,
+    event: MouseMoveEvent,
 ) {
     loop {
         Timer::after(Duration::from_millis(16)).await;