wip tab drag and drop

This commit is contained in:
K Simmons 2022-07-26 10:04:16 -07:00
parent 86fdd55fd4
commit 133c194f4a
20 changed files with 1642 additions and 413 deletions

View file

@ -104,6 +104,11 @@ impl Container {
self
}
pub fn with_padding_top(mut self, padding: f32) -> Self {
self.style.padding.top = padding;
self
}
pub fn with_padding_bottom(mut self, padding: f32) -> Self {
self.style.padding.bottom = padding;
self

View file

@ -5,10 +5,13 @@ use crate::{
vector::{vec2f, Vector2F},
},
platform::CursorStyle,
scene::{CursorRegion, HandlerSet},
scene::{
ClickRegionEvent, CursorRegion, DownOutRegionEvent, DownRegionEvent, DragOverRegionEvent,
DragRegionEvent, HandlerSet, HoverRegionEvent, MoveRegionEvent, UpOutRegionEvent,
UpRegionEvent,
},
DebugContext, Element, ElementBox, Event, EventContext, LayoutContext, MeasurementContext,
MouseButton, MouseButtonEvent, MouseMovedEvent, MouseRegion, MouseState, PaintContext,
RenderContext, SizeConstraint, View,
MouseButton, MouseRegion, MouseState, PaintContext, RenderContext, SizeConstraint, View,
};
use serde_json::json;
use std::{any::TypeId, ops::Range};
@ -42,10 +45,18 @@ impl MouseEventHandler {
self
}
pub fn on_move(
mut self,
handler: impl Fn(MoveRegionEvent, &mut EventContext) + 'static,
) -> Self {
self.handlers = self.handlers.on_move(handler);
self
}
pub fn on_down(
mut self,
button: MouseButton,
handler: impl Fn(MouseButtonEvent, &mut EventContext) + 'static,
handler: impl Fn(DownRegionEvent, &mut EventContext) + 'static,
) -> Self {
self.handlers = self.handlers.on_down(button, handler);
self
@ -54,7 +65,7 @@ impl MouseEventHandler {
pub fn on_up(
mut self,
button: MouseButton,
handler: impl Fn(MouseButtonEvent, &mut EventContext) + 'static,
handler: impl Fn(UpRegionEvent, &mut EventContext) + 'static,
) -> Self {
self.handlers = self.handlers.on_up(button, handler);
self
@ -63,7 +74,7 @@ impl MouseEventHandler {
pub fn on_click(
mut self,
button: MouseButton,
handler: impl Fn(MouseButtonEvent, &mut EventContext) + 'static,
handler: impl Fn(ClickRegionEvent, &mut EventContext) + 'static,
) -> Self {
self.handlers = self.handlers.on_click(button, handler);
self
@ -72,7 +83,7 @@ impl MouseEventHandler {
pub fn on_down_out(
mut self,
button: MouseButton,
handler: impl Fn(MouseButtonEvent, &mut EventContext) + 'static,
handler: impl Fn(DownOutRegionEvent, &mut EventContext) + 'static,
) -> Self {
self.handlers = self.handlers.on_down_out(button, handler);
self
@ -81,16 +92,16 @@ impl MouseEventHandler {
pub fn on_up_out(
mut self,
button: MouseButton,
handler: impl Fn(MouseButtonEvent, &mut EventContext) + 'static,
handler: impl Fn(UpOutRegionEvent, &mut EventContext) + 'static,
) -> Self {
self.handlers = self.handlers.on_up(button, handler);
self.handlers = self.handlers.on_up_out(button, handler);
self
}
pub fn on_drag(
mut self,
button: MouseButton,
handler: impl Fn(Vector2F, MouseMovedEvent, &mut EventContext) + 'static,
handler: impl Fn(DragRegionEvent, &mut EventContext) + 'static,
) -> Self {
self.handlers = self.handlers.on_drag(button, handler);
self
@ -99,7 +110,7 @@ impl MouseEventHandler {
pub fn on_drag_over(
mut self,
button: MouseButton,
handler: impl Fn(bool, MouseMovedEvent, &mut EventContext) + 'static,
handler: impl Fn(DragOverRegionEvent, &mut EventContext) + 'static,
) -> Self {
self.handlers = self.handlers.on_drag_over(button, handler);
self
@ -107,7 +118,7 @@ impl MouseEventHandler {
pub fn on_hover(
mut self,
handler: impl Fn(bool, MouseMovedEvent, &mut EventContext) + 'static,
handler: impl Fn(HoverRegionEvent, &mut EventContext) + 'static,
) -> Self {
self.handlers = self.handlers.on_hover(handler);
self

View file

@ -7,8 +7,8 @@ use crate::{
geometry::{rect::RectF, vector::Vector2F},
json::json,
presenter::MeasurementContext,
Action, Axis, ElementStateHandle, LayoutContext, MouseMovedEvent, PaintContext, RenderContext,
SizeConstraint, Task, View,
Action, Axis, ElementStateHandle, LayoutContext, PaintContext, RenderContext, SizeConstraint,
Task, View,
};
use serde::Deserialize;
use std::{
@ -93,10 +93,11 @@ impl Tooltip {
};
let child =
MouseEventHandler::new::<MouseEventHandlerState<Tag>, _, _>(id, cx, |_, _| child)
.on_hover(move |hover, MouseMovedEvent { position, .. }, cx| {
.on_hover(move |e, cx| {
let position = e.position;
let window_id = cx.window_id();
if let Some(view_id) = cx.view_id() {
if hover {
if e.started {
if !state.visible.get() {
state.position.set(position);

View file

@ -6,7 +6,11 @@ use crate::{
json::{self, ToJson},
keymap::Keystroke,
platform::{CursorStyle, Event},
scene::{CursorRegion, MouseRegionEvent},
scene::{
ClickRegionEvent, CursorRegion, DownOutRegionEvent, DownRegionEvent, DragOverRegionEvent,
DragRegionEvent, HoverRegionEvent, MouseRegionEvent, MoveRegionEvent, UpOutRegionEvent,
UpRegionEvent,
},
text_layout::TextLayoutCache,
Action, AnyModelHandle, AnyViewHandle, AnyWeakModelHandle, AssetCache, ElementBox, Entity,
FontSystem, ModelHandle, MouseButtonEvent, MouseMovedEvent, MouseRegion, MouseRegionId,
@ -140,8 +144,7 @@ impl Presenter {
if cx.window_is_active(self.window_id) {
if let Some(event) = self.last_mouse_moved_event.clone() {
let mut invalidated_views = Vec::new();
self.handle_hover_events(&event, &mut invalidated_views, cx);
let invalidated_views = self.handle_hover_events(&event, cx).invalidated_views;
for view_id in invalidated_views {
cx.notify_view(self.window_id, view_id);
@ -216,48 +219,60 @@ impl Presenter {
pub fn dispatch_event(&mut self, event: Event, cx: &mut MutableAppContext) -> bool {
if let Some(root_view_id) = cx.root_view_id(self.window_id) {
let mut invalidated_views = Vec::new();
let mut events_to_send = Vec::new();
match &event {
Event::MouseDown(e @ MouseButtonEvent { position, .. }) => {
let mut hit = false;
for (region, _) in self.mouse_regions.iter().rev() {
if region.bounds.contains_point(*position) {
if !hit {
hit = true;
invalidated_views.push(region.view_id);
events_to_send
.push((region.clone(), MouseRegionEvent::Down(e.clone())));
self.clicked_region = Some(region.clone());
self.prev_drag_position = Some(*position);
}
events_to_send.push((
region.clone(),
MouseRegionEvent::Down(DownRegionEvent {
region: region.bounds,
platform_event: e.clone(),
}),
));
} else {
events_to_send
.push((region.clone(), MouseRegionEvent::DownOut(e.clone())));
events_to_send.push((
region.clone(),
MouseRegionEvent::DownOut(DownOutRegionEvent {
region: region.bounds,
platform_event: e.clone(),
}),
));
}
}
}
Event::MouseUp(e @ MouseButtonEvent { position, .. }) => {
let mut hit = false;
for (region, _) in self.mouse_regions.iter().rev() {
if region.bounds.contains_point(*position) {
if !hit {
hit = true;
invalidated_views.push(region.view_id);
events_to_send
.push((region.clone(), MouseRegionEvent::Up(e.clone())));
}
events_to_send.push((
region.clone(),
MouseRegionEvent::Up(UpRegionEvent {
region: region.bounds,
platform_event: e.clone(),
}),
));
} else {
events_to_send
.push((region.clone(), MouseRegionEvent::UpOut(e.clone())));
events_to_send.push((
region.clone(),
MouseRegionEvent::UpOut(UpOutRegionEvent {
region: region.bounds,
platform_event: e.clone(),
}),
));
}
}
self.prev_drag_position.take();
if let Some(region) = self.clicked_region.take() {
invalidated_views.push(region.view_id);
if region.bounds.contains_point(*position) {
events_to_send.push((region, MouseRegionEvent::Click(e.clone())));
let bounds = region.bounds.clone();
events_to_send.push((
region,
MouseRegionEvent::Click(ClickRegionEvent {
region: bounds,
platform_event: e.clone(),
}),
));
}
}
}
@ -269,9 +284,28 @@ impl Presenter {
{
events_to_send.push((
clicked_region.clone(),
<<<<<<< HEAD
MouseRegionEvent::Drag(*prev_drag_position, *e),
=======
MouseRegionEvent::Drag(DragRegionEvent {
region: clicked_region.bounds,
prev_drag_position: *prev_drag_position,
platform_event: e.clone(),
}),
>>>>>>> 4bd8a4b0 (wip tab drag and drop)
));
*prev_drag_position = *position;
}
for (region, _) in self.mouse_regions.iter().rev() {
if region.bounds.contains_point(*position) {
events_to_send.push((
region.clone(),
MouseRegionEvent::Move(MoveRegionEvent {
region: region.bounds,
platform_event: e.clone(),
}),
));
}
}
self.last_mouse_moved_event = Some(event.clone());
@ -279,12 +313,12 @@ impl Presenter {
_ => {}
}
let (mut handled, mut event_cx) =
self.handle_hover_events(&event, &mut invalidated_views, cx);
let (invalidated_views, dispatch_directives, handled) = {
let mut event_cx = self.handle_hover_events(&event, cx);
event_cx.process_region_events(events_to_send);
for (region, event) in events_to_send {
if event.is_local() {
handled = true;
if !event_cx.handled {
event_cx.handled = event_cx.dispatch_event(root_view_id, &event);
}
if let Some(callback) = region.handlers.get(&event.handler_key()) {
@ -292,7 +326,13 @@ impl Presenter {
callback(event, event_cx);
})
}
}
(
event_cx.invalidated_views,
event_cx.dispatched_actions,
event_cx.handled,
)
};
if !handled {
handled = event_cx.dispatch_event(root_view_id, &event);
@ -313,9 +353,8 @@ impl Presenter {
fn handle_hover_events<'a>(
&'a mut self,
event: &Event,
invalidated_views: &mut Vec<usize>,
cx: &'a mut MutableAppContext,
) -> (bool, EventContext<'a>) {
) -> EventContext<'a> {
let mut events_to_send = Vec::new();
if let Event::MouseMoved(
@ -343,46 +382,48 @@ impl Presenter {
hover_depth = Some(*depth);
if let Some(region_id) = region.id() {
if !self.hovered_region_ids.contains(&region_id) {
invalidated_views.push(region.view_id);
let region_event = if pressed_button.is_some() {
MouseRegionEvent::DragOver(true, e.clone())
MouseRegionEvent::DragOver(DragOverRegionEvent {
region: region.bounds,
started: true,
platform_event: e.clone(),
})
} else {
MouseRegionEvent::Hover(true, e.clone())
MouseRegionEvent::Hover(HoverRegionEvent {
region: region.bounds,
started: true,
platform_event: e.clone(),
})
};
events_to_send.push((region.clone(), region_event));
self.hovered_region_ids.insert(region_id);
}
}
} else if let Some(region_id) = region.id() {
if self.hovered_region_ids.contains(&region_id) {
invalidated_views.push(region.view_id);
let region_event = if pressed_button.is_some() {
MouseRegionEvent::DragOver(false, e.clone())
} else {
MouseRegionEvent::Hover(false, e.clone())
};
events_to_send.push((region.clone(), region_event));
self.hovered_region_ids.remove(&region_id);
}
if self.hovered_region_ids.contains(&region_id) {
let region_event = if pressed_button.is_some() {
MouseRegionEvent::DragOver(DragOverRegionEvent {
region: region.bounds,
started: false,
platform_event: e.clone(),
})
} else {
MouseRegionEvent::Hover(HoverRegionEvent {
region: region.bounds,
started: false,
platform_event: e.clone(),
})
};
events_to_send.push((region.clone(), region_event));
self.hovered_region_ids.remove(&region_id);
}
}
}
}
let mut event_cx = self.build_event_context(cx);
let mut handled = false;
for (region, event) in events_to_send {
if event.is_local() {
handled = true;
}
if let Some(callback) = region.handlers.get(&event.handler_key()) {
event_cx.with_current_view(region.view_id, |event_cx| {
callback(event, event_cx);
})
}
}
(handled, event_cx)
event_cx.process_region_events(events_to_send);
event_cx
}
pub fn build_event_context<'a>(
@ -396,6 +437,9 @@ impl Presenter {
view_stack: Default::default(),
invalidated_views: Default::default(),
notify_count: 0,
clicked_region: &mut self.clicked_region,
prev_drag_position: &mut self.prev_drag_position,
handled: false,
window_id: self.window_id,
app: cx,
}
@ -615,6 +659,9 @@ pub struct EventContext<'a> {
pub window_id: usize,
pub notify_count: usize,
view_stack: Vec<usize>,
clicked_region: &'a mut Option<MouseRegion>,
prev_drag_position: &'a mut Option<Vector2F>,
handled: bool,
invalidated_views: HashSet<usize>,
}
@ -630,6 +677,36 @@ impl<'a> EventContext<'a> {
}
}
fn process_region_events(&mut self, events: Vec<(MouseRegion, MouseRegionEvent)>) {
for (region, event) in events {
if event.is_local() {
if self.handled {
continue;
}
match &event {
MouseRegionEvent::Down(e) => {
*self.clicked_region = Some(region.clone());
*self.prev_drag_position = Some(e.position);
}
MouseRegionEvent::Drag(e) => {
*self.prev_drag_position = Some(e.position);
}
_ => {}
}
self.invalidated_views.insert(region.view_id);
}
if let Some(callback) = region.handlers.get(&event.handler_key()) {
self.handled = true;
self.with_current_view(region.view_id, |event_cx| {
callback(event, event_cx);
})
}
}
}
fn with_current_view<F, T>(&mut self, view_id: usize, f: F) -> T
where
F: FnOnce(&mut Self) -> T,
@ -681,6 +758,10 @@ impl<'a> EventContext<'a> {
pub fn notify_count(&self) -> usize {
self.notify_count
}
pub fn propogate_event(&mut self) {
self.handled = false;
}
}
impl<'a> Deref for EventContext<'a> {

View file

@ -1,4 +1,5 @@
mod mouse_region;
mod mouse_region_event;
use serde::Deserialize;
use serde_json::json;
@ -13,6 +14,7 @@ use crate::{
ImageData,
};
pub use mouse_region::*;
pub use mouse_region_event::*;
pub struct Scene {
scale_factor: f32,

View file

@ -1,13 +1,14 @@
use std::{
any::TypeId,
mem::{discriminant, Discriminant},
rc::Rc,
};
use std::{any::TypeId, mem::Discriminant, rc::Rc};
use collections::HashMap;
use pathfinder_geometry::{rect::RectF, vector::Vector2F};
use pathfinder_geometry::rect::RectF;
use crate::{EventContext, MouseButton, MouseButtonEvent, MouseMovedEvent, ScrollWheelEvent};
use crate::{EventContext, MouseButton};
use super::mouse_region_event::{
ClickRegionEvent, DownOutRegionEvent, DownRegionEvent, DragOverRegionEvent, DragRegionEvent,
HoverRegionEvent, MouseRegionEvent, MoveRegionEvent, UpOutRegionEvent, UpRegionEvent,
};
#[derive(Clone, Default)]
pub struct MouseRegion {
@ -52,7 +53,7 @@ impl MouseRegion {
pub fn on_down(
mut self,
button: MouseButton,
handler: impl Fn(MouseButtonEvent, &mut EventContext) + 'static,
handler: impl Fn(DownRegionEvent, &mut EventContext) + 'static,
) -> Self {
self.handlers = self.handlers.on_down(button, handler);
self
@ -61,7 +62,7 @@ impl MouseRegion {
pub fn on_up(
mut self,
button: MouseButton,
handler: impl Fn(MouseButtonEvent, &mut EventContext) + 'static,
handler: impl Fn(UpRegionEvent, &mut EventContext) + 'static,
) -> Self {
self.handlers = self.handlers.on_up(button, handler);
self
@ -70,7 +71,7 @@ impl MouseRegion {
pub fn on_click(
mut self,
button: MouseButton,
handler: impl Fn(MouseButtonEvent, &mut EventContext) + 'static,
handler: impl Fn(ClickRegionEvent, &mut EventContext) + 'static,
) -> Self {
self.handlers = self.handlers.on_click(button, handler);
self
@ -79,7 +80,7 @@ impl MouseRegion {
pub fn on_down_out(
mut self,
button: MouseButton,
handler: impl Fn(MouseButtonEvent, &mut EventContext) + 'static,
handler: impl Fn(DownOutRegionEvent, &mut EventContext) + 'static,
) -> Self {
self.handlers = self.handlers.on_down_out(button, handler);
self
@ -88,7 +89,7 @@ impl MouseRegion {
pub fn on_up_out(
mut self,
button: MouseButton,
handler: impl Fn(MouseButtonEvent, &mut EventContext) + 'static,
handler: impl Fn(UpOutRegionEvent, &mut EventContext) + 'static,
) -> Self {
self.handlers = self.handlers.on_up_out(button, handler);
self
@ -97,7 +98,7 @@ impl MouseRegion {
pub fn on_drag(
mut self,
button: MouseButton,
handler: impl Fn(Vector2F, MouseMovedEvent, &mut EventContext) + 'static,
handler: impl Fn(DragRegionEvent, &mut EventContext) + 'static,
) -> Self {
self.handlers = self.handlers.on_drag(button, handler);
self
@ -106,7 +107,7 @@ impl MouseRegion {
pub fn on_drag_over(
mut self,
button: MouseButton,
handler: impl Fn(bool, MouseMovedEvent, &mut EventContext) + 'static,
handler: impl Fn(DragOverRegionEvent, &mut EventContext) + 'static,
) -> Self {
self.handlers = self.handlers.on_drag_over(button, handler);
self
@ -114,7 +115,7 @@ impl MouseRegion {
pub fn on_hover(
mut self,
handler: impl Fn(bool, MouseMovedEvent, &mut EventContext) + 'static,
handler: impl Fn(HoverRegionEvent, &mut EventContext) + 'static,
) -> Self {
self.handlers = self.handlers.on_hover(handler);
self
@ -191,15 +192,32 @@ impl HandlerSet {
self.set.get(key).cloned()
}
pub fn on_move(
mut self,
handler: impl Fn(MoveRegionEvent, &mut EventContext) + 'static,
) -> Self {
self.set.insert((MouseRegionEvent::move_disc(), None),
Rc::new(move |region_event, cx| {
if let MouseRegionEvent::Move(e) = region_event {
handler(e, cx);
} else {
panic!(
"Mouse Region Event incorrectly called with mismatched event type. Expected MouseRegionEvent::Move, found {:?}",
region_event);
}
}));
self
}
pub fn on_down(
mut self,
button: MouseButton,
handler: impl Fn(MouseButtonEvent, &mut EventContext) + 'static,
handler: impl Fn(DownRegionEvent, &mut EventContext) + 'static,
) -> Self {
self.set.insert((MouseRegionEvent::down_disc(), Some(button)),
Rc::new(move |region_event, cx| {
if let MouseRegionEvent::Down(mouse_button_event) = region_event {
handler(mouse_button_event, cx);
if let MouseRegionEvent::Down(e) = region_event {
handler(e, cx);
} else {
panic!(
"Mouse Region Event incorrectly called with mismatched event type. Expected MouseRegionEvent::Down, found {:?}",
@ -212,12 +230,12 @@ impl HandlerSet {
pub fn on_up(
mut self,
button: MouseButton,
handler: impl Fn(MouseButtonEvent, &mut EventContext) + 'static,
handler: impl Fn(UpRegionEvent, &mut EventContext) + 'static,
) -> Self {
self.set.insert((MouseRegionEvent::up_disc(), Some(button)),
Rc::new(move |region_event, cx| {
if let MouseRegionEvent::Up(mouse_button_event) = region_event {
handler(mouse_button_event, cx);
if let MouseRegionEvent::Up(e) = region_event {
handler(e, cx);
} else {
panic!(
"Mouse Region Event incorrectly called with mismatched event type. Expected MouseRegionEvent::Up, found {:?}",
@ -230,12 +248,12 @@ impl HandlerSet {
pub fn on_click(
mut self,
button: MouseButton,
handler: impl Fn(MouseButtonEvent, &mut EventContext) + 'static,
handler: impl Fn(ClickRegionEvent, &mut EventContext) + 'static,
) -> Self {
self.set.insert((MouseRegionEvent::click_disc(), Some(button)),
Rc::new(move |region_event, cx| {
if let MouseRegionEvent::Click(mouse_button_event) = region_event {
handler(mouse_button_event, cx);
if let MouseRegionEvent::Click(e) = region_event {
handler(e, cx);
} else {
panic!(
"Mouse Region Event incorrectly called with mismatched event type. Expected MouseRegionEvent::Click, found {:?}",
@ -248,12 +266,12 @@ impl HandlerSet {
pub fn on_down_out(
mut self,
button: MouseButton,
handler: impl Fn(MouseButtonEvent, &mut EventContext) + 'static,
handler: impl Fn(DownOutRegionEvent, &mut EventContext) + 'static,
) -> Self {
self.set.insert((MouseRegionEvent::down_out_disc(), Some(button)),
Rc::new(move |region_event, cx| {
if let MouseRegionEvent::DownOut(mouse_button_event) = region_event {
handler(mouse_button_event, cx);
if let MouseRegionEvent::DownOut(e) = region_event {
handler(e, cx);
} else {
panic!(
"Mouse Region Event incorrectly called with mismatched event type. Expected MouseRegionEvent::DownOut, found {:?}",
@ -266,12 +284,12 @@ impl HandlerSet {
pub fn on_up_out(
mut self,
button: MouseButton,
handler: impl Fn(MouseButtonEvent, &mut EventContext) + 'static,
handler: impl Fn(UpOutRegionEvent, &mut EventContext) + 'static,
) -> Self {
self.set.insert((MouseRegionEvent::up_out_disc(), Some(button)),
Rc::new(move |region_event, cx| {
if let MouseRegionEvent::UpOut(mouse_button_event) = region_event {
handler(mouse_button_event, cx);
if let MouseRegionEvent::UpOut(e) = region_event {
handler(e, cx);
} else {
panic!(
"Mouse Region Event incorrectly called with mismatched event type. Expected MouseRegionEvent::UpOut, found {:?}",
@ -284,12 +302,12 @@ impl HandlerSet {
pub fn on_drag(
mut self,
button: MouseButton,
handler: impl Fn(Vector2F, MouseMovedEvent, &mut EventContext) + 'static,
handler: impl Fn(DragRegionEvent, &mut EventContext) + 'static,
) -> Self {
self.set.insert((MouseRegionEvent::drag_disc(), Some(button)),
Rc::new(move |region_event, cx| {
if let MouseRegionEvent::Drag(prev_drag_position, mouse_moved_event) = region_event {
handler(prev_drag_position, mouse_moved_event, cx);
if let MouseRegionEvent::Drag(e) = region_event {
handler(e, cx);
} else {
panic!(
"Mouse Region Event incorrectly called with mismatched event type. Expected MouseRegionEvent::Drag, found {:?}",
@ -302,12 +320,12 @@ impl HandlerSet {
pub fn on_drag_over(
mut self,
button: MouseButton,
handler: impl Fn(bool, MouseMovedEvent, &mut EventContext) + 'static,
handler: impl Fn(DragOverRegionEvent, &mut EventContext) + 'static,
) -> Self {
self.set.insert((MouseRegionEvent::drag_over_disc(), Some(button)),
Rc::new(move |region_event, cx| {
if let MouseRegionEvent::DragOver(started, mouse_moved_event) = region_event {
handler(started, mouse_moved_event, cx);
if let MouseRegionEvent::DragOver(e) = region_event {
handler(e, cx);
} else {
panic!(
"Mouse Region Event incorrectly called with mismatched event type. Expected MouseRegionEvent::DragOver, found {:?}",
@ -319,12 +337,12 @@ impl HandlerSet {
pub fn on_hover(
mut self,
handler: impl Fn(bool, MouseMovedEvent, &mut EventContext) + 'static,
handler: impl Fn(HoverRegionEvent, &mut EventContext) + 'static,
) -> Self {
self.set.insert((MouseRegionEvent::hover_disc(), None),
Rc::new(move |region_event, cx| {
if let MouseRegionEvent::Hover(started, mouse_moved_event) = region_event {
handler(started, mouse_moved_event, cx);
if let MouseRegionEvent::Hover(e) = region_event {
handler(e, cx);
} else {
panic!(
"Mouse Region Event incorrectly called with mismatched event type. Expected MouseRegionEvent::Hover, found {:?}",
@ -334,106 +352,3 @@ impl HandlerSet {
self
}
}
#[derive(Debug)]
pub enum MouseRegionEvent {
Move(MouseMovedEvent),
Drag(Vector2F, MouseMovedEvent),
DragOver(bool, MouseMovedEvent),
Hover(bool, MouseMovedEvent),
Down(MouseButtonEvent),
Up(MouseButtonEvent),
Click(MouseButtonEvent),
UpOut(MouseButtonEvent),
DownOut(MouseButtonEvent),
ScrollWheel(ScrollWheelEvent),
}
impl MouseRegionEvent {
pub fn move_disc() -> Discriminant<MouseRegionEvent> {
discriminant(&MouseRegionEvent::Move(Default::default()))
}
pub fn drag_disc() -> Discriminant<MouseRegionEvent> {
discriminant(&MouseRegionEvent::Drag(
Default::default(),
Default::default(),
))
}
pub fn drag_over_disc() -> Discriminant<MouseRegionEvent> {
discriminant(&MouseRegionEvent::DragOver(
Default::default(),
Default::default(),
))
}
pub fn hover_disc() -> Discriminant<MouseRegionEvent> {
discriminant(&MouseRegionEvent::Hover(
Default::default(),
Default::default(),
))
}
pub fn down_disc() -> Discriminant<MouseRegionEvent> {
discriminant(&MouseRegionEvent::Down(Default::default()))
}
pub fn up_disc() -> Discriminant<MouseRegionEvent> {
discriminant(&MouseRegionEvent::Up(Default::default()))
}
pub fn up_out_disc() -> Discriminant<MouseRegionEvent> {
discriminant(&MouseRegionEvent::UpOut(Default::default()))
}
pub fn click_disc() -> Discriminant<MouseRegionEvent> {
discriminant(&MouseRegionEvent::Click(Default::default()))
}
pub fn down_out_disc() -> Discriminant<MouseRegionEvent> {
discriminant(&MouseRegionEvent::DownOut(Default::default()))
}
pub fn scroll_wheel_disc() -> Discriminant<MouseRegionEvent> {
discriminant(&MouseRegionEvent::ScrollWheel(Default::default()))
}
pub fn is_local(&self) -> bool {
match self {
MouseRegionEvent::DownOut(_)
| MouseRegionEvent::UpOut(_)
| MouseRegionEvent::DragOver(_, _) => false,
_ => true,
}
}
pub fn handler_key(&self) -> (Discriminant<MouseRegionEvent>, Option<MouseButton>) {
match self {
MouseRegionEvent::Move(_) => (Self::move_disc(), None),
MouseRegionEvent::Drag(_, MouseMovedEvent { pressed_button, .. }) => {
(Self::drag_disc(), *pressed_button)
}
MouseRegionEvent::DragOver(_, MouseMovedEvent { pressed_button, .. }) => {
(Self::drag_over_disc(), *pressed_button)
}
MouseRegionEvent::Hover(_, _) => (Self::hover_disc(), None),
MouseRegionEvent::Down(MouseButtonEvent { button, .. }) => {
(Self::down_disc(), Some(*button))
}
MouseRegionEvent::Up(MouseButtonEvent { button, .. }) => {
(Self::up_disc(), Some(*button))
}
MouseRegionEvent::Click(MouseButtonEvent { button, .. }) => {
(Self::click_disc(), Some(*button))
}
MouseRegionEvent::UpOut(MouseButtonEvent { button, .. }) => {
(Self::up_out_disc(), Some(*button))
}
MouseRegionEvent::DownOut(MouseButtonEvent { button, .. }) => {
(Self::down_out_disc(), Some(*button))
}
MouseRegionEvent::ScrollWheel(_) => (Self::scroll_wheel_disc(), None),
}
}
}

View file

@ -0,0 +1,231 @@
use std::{
mem::{discriminant, Discriminant},
ops::Deref,
};
use pathfinder_geometry::{rect::RectF, vector::Vector2F};
use crate::{MouseButton, MouseButtonEvent, MouseMovedEvent, ScrollWheelEvent};
#[derive(Debug, Default)]
pub struct MoveRegionEvent {
pub region: RectF,
pub platform_event: MouseMovedEvent,
}
impl Deref for MoveRegionEvent {
type Target = MouseMovedEvent;
fn deref(&self) -> &Self::Target {
&self.platform_event
}
}
#[derive(Debug, Default)]
pub struct DragRegionEvent {
pub region: RectF,
pub prev_drag_position: Vector2F,
pub platform_event: MouseMovedEvent,
}
impl Deref for DragRegionEvent {
type Target = MouseMovedEvent;
fn deref(&self) -> &Self::Target {
&self.platform_event
}
}
#[derive(Debug, Default)]
pub struct DragOverRegionEvent {
pub region: RectF,
pub started: bool,
pub platform_event: MouseMovedEvent,
}
impl Deref for DragOverRegionEvent {
type Target = MouseMovedEvent;
fn deref(&self) -> &Self::Target {
&self.platform_event
}
}
#[derive(Debug, Default)]
pub struct HoverRegionEvent {
pub region: RectF,
pub started: bool,
pub platform_event: MouseMovedEvent,
}
impl Deref for HoverRegionEvent {
type Target = MouseMovedEvent;
fn deref(&self) -> &Self::Target {
&self.platform_event
}
}
#[derive(Debug, Default)]
pub struct DownRegionEvent {
pub region: RectF,
pub platform_event: MouseButtonEvent,
}
impl Deref for DownRegionEvent {
type Target = MouseButtonEvent;
fn deref(&self) -> &Self::Target {
&self.platform_event
}
}
#[derive(Debug, Default)]
pub struct UpRegionEvent {
pub region: RectF,
pub platform_event: MouseButtonEvent,
}
impl Deref for UpRegionEvent {
type Target = MouseButtonEvent;
fn deref(&self) -> &Self::Target {
&self.platform_event
}
}
#[derive(Debug, Default)]
pub struct ClickRegionEvent {
pub region: RectF,
pub platform_event: MouseButtonEvent,
}
impl Deref for ClickRegionEvent {
type Target = MouseButtonEvent;
fn deref(&self) -> &Self::Target {
&self.platform_event
}
}
#[derive(Debug, Default)]
pub struct DownOutRegionEvent {
pub region: RectF,
pub platform_event: MouseButtonEvent,
}
impl Deref for DownOutRegionEvent {
type Target = MouseButtonEvent;
fn deref(&self) -> &Self::Target {
&self.platform_event
}
}
#[derive(Debug, Default)]
pub struct UpOutRegionEvent {
pub region: RectF,
pub platform_event: MouseButtonEvent,
}
impl Deref for UpOutRegionEvent {
type Target = MouseButtonEvent;
fn deref(&self) -> &Self::Target {
&self.platform_event
}
}
#[derive(Debug, Default)]
pub struct ScrollWheelRegionEvent {
pub region: RectF,
pub platform_event: ScrollWheelEvent,
}
impl Deref for ScrollWheelRegionEvent {
type Target = ScrollWheelEvent;
fn deref(&self) -> &Self::Target {
&self.platform_event
}
}
#[derive(Debug)]
pub enum MouseRegionEvent {
Move(MoveRegionEvent),
Drag(DragRegionEvent),
DragOver(DragOverRegionEvent),
Hover(HoverRegionEvent),
Down(DownRegionEvent),
Up(UpRegionEvent),
Click(ClickRegionEvent),
DownOut(DownOutRegionEvent),
UpOut(UpOutRegionEvent),
ScrollWheel(ScrollWheelRegionEvent),
}
impl MouseRegionEvent {
pub fn move_disc() -> Discriminant<MouseRegionEvent> {
discriminant(&MouseRegionEvent::Move(Default::default()))
}
pub fn drag_disc() -> Discriminant<MouseRegionEvent> {
discriminant(&MouseRegionEvent::Drag(Default::default()))
}
pub fn drag_over_disc() -> Discriminant<MouseRegionEvent> {
discriminant(&MouseRegionEvent::DragOver(Default::default()))
}
pub fn hover_disc() -> Discriminant<MouseRegionEvent> {
discriminant(&MouseRegionEvent::Hover(Default::default()))
}
pub fn down_disc() -> Discriminant<MouseRegionEvent> {
discriminant(&MouseRegionEvent::Down(Default::default()))
}
pub fn up_disc() -> Discriminant<MouseRegionEvent> {
discriminant(&MouseRegionEvent::Up(Default::default()))
}
pub fn up_out_disc() -> Discriminant<MouseRegionEvent> {
discriminant(&MouseRegionEvent::UpOut(Default::default()))
}
pub fn click_disc() -> Discriminant<MouseRegionEvent> {
discriminant(&MouseRegionEvent::Click(Default::default()))
}
pub fn down_out_disc() -> Discriminant<MouseRegionEvent> {
discriminant(&MouseRegionEvent::DownOut(Default::default()))
}
pub fn scroll_wheel_disc() -> Discriminant<MouseRegionEvent> {
discriminant(&MouseRegionEvent::ScrollWheel(Default::default()))
}
pub fn is_local(&self) -> bool {
match self {
MouseRegionEvent::DownOut(_)
| MouseRegionEvent::UpOut(_)
| MouseRegionEvent::DragOver(_) => false,
_ => true,
}
}
pub fn handler_key(&self) -> (Discriminant<MouseRegionEvent>, Option<MouseButton>) {
match self {
MouseRegionEvent::Move(_) => (Self::move_disc(), None),
MouseRegionEvent::Drag(e) => (Self::drag_disc(), e.pressed_button),
MouseRegionEvent::DragOver(e) => (Self::drag_over_disc(), e.pressed_button),
MouseRegionEvent::Hover(_) => (Self::hover_disc(), None),
MouseRegionEvent::Down(e) => (Self::down_disc(), Some(e.button)),
MouseRegionEvent::Up(e) => (Self::up_disc(), Some(e.button)),
MouseRegionEvent::Click(e) => (Self::click_disc(), Some(e.button)),
MouseRegionEvent::UpOut(e) => (Self::up_out_disc(), Some(e.button)),
MouseRegionEvent::DownOut(e) => (Self::down_out_disc(), Some(e.button)),
MouseRegionEvent::ScrollWheel(_) => (Self::scroll_wheel_disc(), None),
}
}
}