Detailed changes
@@ -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),
}
@@ -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(),
}
}
}
@@ -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),
@@ -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;