Add in-window on-move-out mouse handler concept

This commit is contained in:
Julia 2023-01-19 12:34:13 -05:00
parent 5189dea3d5
commit ad1947fa50
5 changed files with 66 additions and 4 deletions

View file

@ -190,6 +190,9 @@ impl EditorElement {
} }
} }
}) })
.on_move_out(|e, cx| {
println!("on move out");
})
.on_scroll({ .on_scroll({
let position_map = position_map.clone(); let position_map = position_map.clone();
move |e, cx| { move |e, cx| {

View file

@ -7,7 +7,7 @@ use crate::{
platform::CursorStyle, platform::CursorStyle,
scene::{ scene::{
CursorRegion, HandlerSet, MouseClick, MouseDown, MouseDownOut, MouseDrag, MouseHover, CursorRegion, HandlerSet, MouseClick, MouseDown, MouseDownOut, MouseDrag, MouseHover,
MouseMove, MouseScrollWheel, MouseUp, MouseUpOut, MouseMove, MouseMoveOut, MouseScrollWheel, MouseUp, MouseUpOut,
}, },
DebugContext, Element, ElementBox, EventContext, LayoutContext, MeasurementContext, DebugContext, Element, ElementBox, EventContext, LayoutContext, MeasurementContext,
MouseButton, MouseRegion, MouseState, PaintContext, RenderContext, SizeConstraint, View, MouseButton, MouseRegion, MouseState, PaintContext, RenderContext, SizeConstraint, View,
@ -82,6 +82,14 @@ impl<Tag> MouseEventHandler<Tag> {
self self
} }
pub fn on_move_out(
mut self,
handler: impl Fn(MouseMoveOut, &mut EventContext) + 'static,
) -> Self {
self.handlers = self.handlers.on_move_out(handler);
self
}
pub fn on_down( pub fn on_down(
mut self, mut self,
button: MouseButton, button: MouseButton,

View file

@ -8,7 +8,7 @@ use crate::{
platform::{CursorStyle, Event}, platform::{CursorStyle, Event},
scene::{ scene::{
CursorRegion, MouseClick, MouseDown, MouseDownOut, MouseDrag, MouseEvent, MouseHover, CursorRegion, MouseClick, MouseDown, MouseDownOut, MouseDrag, MouseEvent, MouseHover,
MouseMove, MouseScrollWheel, MouseUp, MouseUpOut, Scene, MouseMove, MouseMoveOut, MouseScrollWheel, MouseUp, MouseUpOut, Scene,
}, },
text_layout::TextLayoutCache, text_layout::TextLayoutCache,
Action, AnyModelHandle, AnyViewHandle, AnyWeakModelHandle, AnyWeakViewHandle, Appearance, Action, AnyModelHandle, AnyViewHandle, AnyWeakModelHandle, AnyWeakViewHandle, Appearance,
@ -245,8 +245,11 @@ impl Presenter {
// -> Also updates mouse-related state // -> Also updates mouse-related state
match &event { match &event {
Event::KeyDown(e) => return cx.dispatch_key_down(self.window_id, e), Event::KeyDown(e) => return cx.dispatch_key_down(self.window_id, e),
Event::KeyUp(e) => return cx.dispatch_key_up(self.window_id, e), Event::KeyUp(e) => return cx.dispatch_key_up(self.window_id, e),
Event::ModifiersChanged(e) => return cx.dispatch_modifiers_changed(self.window_id, e), Event::ModifiersChanged(e) => return cx.dispatch_modifiers_changed(self.window_id, e),
Event::MouseDown(e) => { Event::MouseDown(e) => {
// Click events are weird because they can be fired after a drag event. // Click events are weird because they can be fired after a drag event.
// MDN says that browsers handle this by starting from 'the most // MDN says that browsers handle this by starting from 'the most
@ -279,6 +282,7 @@ impl Presenter {
platform_event: e.clone(), platform_event: e.clone(),
})); }));
} }
Event::MouseUp(e) => { Event::MouseUp(e) => {
// NOTE: The order of event pushes is important! MouseUp events MUST be fired // NOTE: The order of event pushes is important! MouseUp events MUST be fired
// before click events, and so the MouseUp events need to be pushed before // before click events, and so the MouseUp events need to be pushed before
@ -296,6 +300,7 @@ impl Presenter {
platform_event: e.clone(), platform_event: e.clone(),
})); }));
} }
Event::MouseMoved( Event::MouseMoved(
e @ MouseMovedEvent { e @ MouseMovedEvent {
position, position,
@ -347,9 +352,13 @@ impl Presenter {
platform_event: e.clone(), platform_event: e.clone(),
started: false, started: false,
})); }));
mouse_events.push(MouseEvent::MoveOut(MouseMoveOut {
region: Default::default(),
}));
self.last_mouse_moved_event = Some(event.clone()); self.last_mouse_moved_event = Some(event.clone());
} }
Event::ScrollWheel(e) => mouse_events.push(MouseEvent::ScrollWheel(MouseScrollWheel { Event::ScrollWheel(e) => mouse_events.push(MouseEvent::ScrollWheel(MouseScrollWheel {
region: Default::default(), region: Default::default(),
platform_event: e.clone(), platform_event: e.clone(),
@ -407,6 +416,7 @@ impl Presenter {
} }
} }
} }
MouseEvent::Down(_) | MouseEvent::Up(_) => { MouseEvent::Down(_) | MouseEvent::Up(_) => {
for (region, _) in self.mouse_regions.iter().rev() { for (region, _) in self.mouse_regions.iter().rev() {
if region.bounds.contains_point(self.mouse_position) { if region.bounds.contains_point(self.mouse_position) {
@ -417,6 +427,7 @@ impl Presenter {
} }
} }
} }
MouseEvent::Click(e) => { MouseEvent::Click(e) => {
// Only raise click events if the released button is the same as the one stored // Only raise click events if the released button is the same as the one stored
if self if self
@ -439,6 +450,7 @@ impl Presenter {
} }
} }
} }
MouseEvent::Drag(_) => { MouseEvent::Drag(_) => {
for (mouse_region, _) in self.mouse_regions.iter().rev() { for (mouse_region, _) in self.mouse_regions.iter().rev() {
if self.clicked_region_ids.contains(&mouse_region.id()) { if self.clicked_region_ids.contains(&mouse_region.id()) {
@ -447,7 +459,7 @@ impl Presenter {
} }
} }
MouseEvent::UpOut(_) | MouseEvent::DownOut(_) => { MouseEvent::MoveOut(_) | MouseEvent::UpOut(_) | MouseEvent::DownOut(_) => {
for (mouse_region, _) in self.mouse_regions.iter().rev() { for (mouse_region, _) in self.mouse_regions.iter().rev() {
// NOT contains // NOT contains
if !mouse_region.bounds.contains_point(self.mouse_position) { if !mouse_region.bounds.contains_point(self.mouse_position) {
@ -455,6 +467,7 @@ impl Presenter {
} }
} }
} }
_ => { _ => {
for (mouse_region, _) in self.mouse_regions.iter().rev() { for (mouse_region, _) in self.mouse_regions.iter().rev() {
// Contains // Contains

View file

@ -21,6 +21,11 @@ impl Deref for MouseMove {
} }
} }
#[derive(Debug, Default, Clone)]
pub struct MouseMoveOut {
pub region: RectF,
}
#[derive(Debug, Default, Clone)] #[derive(Debug, Default, Clone)]
pub struct MouseDrag { pub struct MouseDrag {
pub region: RectF, pub region: RectF,
@ -138,6 +143,7 @@ impl Deref for MouseScrollWheel {
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub enum MouseEvent { pub enum MouseEvent {
Move(MouseMove), Move(MouseMove),
MoveOut(MouseMoveOut),
Drag(MouseDrag), Drag(MouseDrag),
Hover(MouseHover), Hover(MouseHover),
Down(MouseDown), Down(MouseDown),
@ -152,6 +158,7 @@ impl MouseEvent {
pub fn set_region(&mut self, region: RectF) { pub fn set_region(&mut self, region: RectF) {
match self { match self {
MouseEvent::Move(r) => r.region = region, MouseEvent::Move(r) => r.region = region,
MouseEvent::MoveOut(r) => r.region = region,
MouseEvent::Drag(r) => r.region = region, MouseEvent::Drag(r) => r.region = region,
MouseEvent::Hover(r) => r.region = region, MouseEvent::Hover(r) => r.region = region,
MouseEvent::Down(r) => r.region = region, MouseEvent::Down(r) => r.region = region,
@ -168,6 +175,7 @@ impl MouseEvent {
pub fn is_capturable(&self) -> bool { pub fn is_capturable(&self) -> bool {
match self { match self {
MouseEvent::Move(_) => true, MouseEvent::Move(_) => true,
MouseEvent::MoveOut(_) => false,
MouseEvent::Drag(_) => true, MouseEvent::Drag(_) => true,
MouseEvent::Hover(_) => false, MouseEvent::Hover(_) => false,
MouseEvent::Down(_) => true, MouseEvent::Down(_) => true,
@ -185,6 +193,10 @@ impl MouseEvent {
discriminant(&MouseEvent::Move(Default::default())) discriminant(&MouseEvent::Move(Default::default()))
} }
pub fn move_out_disc() -> Discriminant<MouseEvent> {
discriminant(&MouseEvent::MoveOut(Default::default()))
}
pub fn drag_disc() -> Discriminant<MouseEvent> { pub fn drag_disc() -> Discriminant<MouseEvent> {
discriminant(&MouseEvent::Drag(Default::default())) discriminant(&MouseEvent::Drag(Default::default()))
} }
@ -220,6 +232,7 @@ impl MouseEvent {
pub fn handler_key(&self) -> HandlerKey { pub fn handler_key(&self) -> HandlerKey {
match self { match self {
MouseEvent::Move(_) => HandlerKey::new(Self::move_disc(), None), MouseEvent::Move(_) => HandlerKey::new(Self::move_disc(), None),
MouseEvent::MoveOut(_) => HandlerKey::new(Self::move_out_disc(), None),
MouseEvent::Drag(e) => HandlerKey::new(Self::drag_disc(), e.pressed_button), MouseEvent::Drag(e) => HandlerKey::new(Self::drag_disc(), e.pressed_button),
MouseEvent::Hover(_) => HandlerKey::new(Self::hover_disc(), None), MouseEvent::Hover(_) => HandlerKey::new(Self::hover_disc(), None),
MouseEvent::Down(e) => HandlerKey::new(Self::down_disc(), Some(e.button)), MouseEvent::Down(e) => HandlerKey::new(Self::down_disc(), Some(e.button)),

View file

@ -12,7 +12,7 @@ use super::{
MouseClick, MouseDown, MouseDownOut, MouseDrag, MouseEvent, MouseHover, MouseMove, MouseUp, MouseClick, MouseDown, MouseDownOut, MouseDrag, MouseEvent, MouseHover, MouseMove, MouseUp,
MouseUpOut, MouseUpOut,
}, },
MouseScrollWheel, MouseMoveOut, MouseScrollWheel,
}; };
#[derive(Clone)] #[derive(Clone)]
@ -124,6 +124,14 @@ impl MouseRegion {
self self
} }
pub fn on_move_out(
mut self,
handler: impl Fn(MouseMoveOut, &mut EventContext) + 'static,
) -> Self {
self.handlers = self.handlers.on_move_out(handler);
self
}
pub fn on_scroll( pub fn on_scroll(
mut self, mut self,
handler: impl Fn(MouseScrollWheel, &mut EventContext) + 'static, handler: impl Fn(MouseScrollWheel, &mut EventContext) + 'static,
@ -289,6 +297,23 @@ impl HandlerSet {
self self
} }
pub fn on_move_out(
mut self,
handler: impl Fn(MouseMoveOut, &mut EventContext) + 'static,
) -> Self {
self.insert(MouseEvent::move_out_disc(), None,
Rc::new(move |region_event, cx| {
if let MouseEvent::MoveOut(e) = region_event {
handler(e, cx);
} else {
panic!(
"Mouse Region Event incorrectly called with mismatched event type. Expected MouseRegionEvent::MoveOut, found {:?}",
region_event);
}
}));
self
}
pub fn on_down( pub fn on_down(
mut self, mut self,
button: MouseButton, button: MouseButton,