mirror of
https://github.com/italicsjenga/winit-sonoma-fix.git
synced 2024-12-23 13:51:30 +11:00
Remove MouseEvent
fallback support
This commit is contained in:
parent
fbba203c4a
commit
a134a59917
|
@ -65,6 +65,7 @@ And please only add new entries to the top of this list, right below the `# Unre
|
|||
- On Web, fix pen treated as mouse input.
|
||||
- On Web, send mouse position on button release as well.
|
||||
- On Web, fix touch input not gaining or loosing focus.
|
||||
- **Breaking:** On Web, dropped support for Safari versions below 13.
|
||||
|
||||
# 0.28.6
|
||||
|
||||
|
|
|
@ -132,7 +132,6 @@ package = "web-sys"
|
|||
version = "0.3.22"
|
||||
features = [
|
||||
'console',
|
||||
"AddEventListenerOptions",
|
||||
'CssStyleDeclaration',
|
||||
'BeforeUnloadEvent',
|
||||
'Document',
|
||||
|
@ -147,7 +146,6 @@ features = [
|
|||
'KeyboardEvent',
|
||||
'MediaQueryList',
|
||||
'MediaQueryListEvent',
|
||||
'MouseEvent',
|
||||
'Node',
|
||||
'PointerEvent',
|
||||
'Window',
|
||||
|
|
|
@ -352,11 +352,10 @@ impl<T> EventLoopWindowTarget<T> {
|
|||
let has_focus = has_focus.clone();
|
||||
|
||||
move |pointer_id, position, button, active_modifiers| {
|
||||
let focus_changed =
|
||||
(!has_focus.replace(true)).then_some(Event::WindowEvent {
|
||||
window_id: RootWindowId(id),
|
||||
event: WindowEvent::Focused(true),
|
||||
});
|
||||
let focus_changed = (!has_focus.replace(true)).then_some(Event::WindowEvent {
|
||||
window_id: RootWindowId(id),
|
||||
event: WindowEvent::Focused(true),
|
||||
});
|
||||
|
||||
let modifiers_changed = (modifiers.get() != active_modifiers).then(|| {
|
||||
modifiers.set(active_modifiers);
|
||||
|
@ -393,11 +392,10 @@ impl<T> EventLoopWindowTarget<T> {
|
|||
let has_focus = has_focus.clone();
|
||||
|
||||
move |device_id, location, force| {
|
||||
let focus_changed =
|
||||
(!has_focus.replace(true)).then_some(Event::WindowEvent {
|
||||
window_id: RootWindowId(id),
|
||||
event: WindowEvent::Focused(true),
|
||||
});
|
||||
let focus_changed = (!has_focus.replace(true)).then_some(Event::WindowEvent {
|
||||
window_id: RootWindowId(id),
|
||||
event: WindowEvent::Focused(true),
|
||||
});
|
||||
|
||||
runner.send_events(focus_changed.into_iter().chain(iter::once(
|
||||
Event::WindowEvent {
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
use super::event_handle::EventListenerHandle;
|
||||
use super::media_query_handle::MediaQueryListHandle;
|
||||
use super::pointer::PointerHandler;
|
||||
use super::{event, ButtonsState};
|
||||
use crate::dpi::{LogicalPosition, PhysicalPosition, PhysicalSize};
|
||||
use crate::error::OsError as RootOE;
|
||||
|
@ -16,13 +17,9 @@ use wasm_bindgen::prelude::wasm_bindgen;
|
|||
use wasm_bindgen::{closure::Closure, JsCast, JsValue};
|
||||
use wasm_bindgen_futures::JsFuture;
|
||||
use web_sys::{
|
||||
AddEventListenerOptions, Event, FocusEvent, HtmlCanvasElement, KeyboardEvent,
|
||||
MediaQueryListEvent, MouseEvent, WheelEvent,
|
||||
Event, FocusEvent, HtmlCanvasElement, KeyboardEvent, MediaQueryListEvent, WheelEvent,
|
||||
};
|
||||
|
||||
mod mouse_handler;
|
||||
mod pointer_handler;
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub struct Canvas {
|
||||
common: Common,
|
||||
|
@ -35,12 +32,12 @@ pub struct Canvas {
|
|||
on_mouse_wheel: Option<EventListenerHandle<dyn FnMut(WheelEvent)>>,
|
||||
on_fullscreen_change: Option<EventListenerHandle<dyn FnMut(Event)>>,
|
||||
on_dark_mode: Option<MediaQueryListHandle>,
|
||||
mouse_state: MouseState,
|
||||
pointer_handler: PointerHandler,
|
||||
}
|
||||
|
||||
struct Common {
|
||||
pub struct Common {
|
||||
/// Note: resizing the HTMLCanvasElement should go through `backend::set_canvas_size` to ensure the DPI factor is maintained.
|
||||
raw: HtmlCanvasElement,
|
||||
pub raw: HtmlCanvasElement,
|
||||
wants_fullscreen: Rc<RefCell<bool>>,
|
||||
}
|
||||
|
||||
|
@ -74,12 +71,6 @@ impl Canvas {
|
|||
.map_err(|_| os_error!(OsError("Failed to set a tabindex".to_owned())))?;
|
||||
}
|
||||
|
||||
let mouse_state = if has_pointer_event() {
|
||||
MouseState::HasPointerEvent(pointer_handler::PointerHandler::new())
|
||||
} else {
|
||||
MouseState::NoPointerEvent(mouse_handler::MouseHandler::new())
|
||||
};
|
||||
|
||||
Ok(Canvas {
|
||||
common: Common {
|
||||
raw: canvas,
|
||||
|
@ -94,7 +85,7 @@ impl Canvas {
|
|||
on_mouse_wheel: None,
|
||||
on_fullscreen_change: None,
|
||||
on_dark_mode: None,
|
||||
mouse_state,
|
||||
pointer_handler: PointerHandler::new(),
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -225,20 +216,14 @@ impl Canvas {
|
|||
where
|
||||
F: 'static + FnMut(i32, ModifiersState),
|
||||
{
|
||||
match &mut self.mouse_state {
|
||||
MouseState::HasPointerEvent(h) => h.on_cursor_leave(&self.common, handler),
|
||||
MouseState::NoPointerEvent(h) => h.on_cursor_leave(&self.common, handler),
|
||||
}
|
||||
self.pointer_handler.on_cursor_leave(&self.common, handler)
|
||||
}
|
||||
|
||||
pub fn on_cursor_enter<F>(&mut self, handler: F)
|
||||
where
|
||||
F: 'static + FnMut(i32, ModifiersState),
|
||||
{
|
||||
match &mut self.mouse_state {
|
||||
MouseState::HasPointerEvent(h) => h.on_cursor_enter(&self.common, handler),
|
||||
MouseState::NoPointerEvent(h) => h.on_cursor_enter(&self.common, handler),
|
||||
}
|
||||
self.pointer_handler.on_cursor_enter(&self.common, handler)
|
||||
}
|
||||
|
||||
pub fn on_mouse_release<M, T>(&mut self, mouse_handler: M, touch_handler: T)
|
||||
|
@ -246,12 +231,8 @@ impl Canvas {
|
|||
M: 'static + FnMut(i32, PhysicalPosition<f64>, MouseButton, ModifiersState),
|
||||
T: 'static + FnMut(i32, PhysicalPosition<f64>, Force),
|
||||
{
|
||||
match &mut self.mouse_state {
|
||||
MouseState::HasPointerEvent(h) => {
|
||||
h.on_mouse_release(&self.common, mouse_handler, touch_handler)
|
||||
}
|
||||
MouseState::NoPointerEvent(h) => h.on_mouse_release(&self.common, mouse_handler),
|
||||
}
|
||||
self.pointer_handler
|
||||
.on_mouse_release(&self.common, mouse_handler, touch_handler)
|
||||
}
|
||||
|
||||
pub fn on_mouse_press<M, T>(&mut self, mouse_handler: M, touch_handler: T)
|
||||
|
@ -259,12 +240,8 @@ impl Canvas {
|
|||
M: 'static + FnMut(i32, PhysicalPosition<f64>, MouseButton, ModifiersState),
|
||||
T: 'static + FnMut(i32, PhysicalPosition<f64>, Force),
|
||||
{
|
||||
match &mut self.mouse_state {
|
||||
MouseState::HasPointerEvent(h) => {
|
||||
h.on_mouse_press(&self.common, mouse_handler, touch_handler)
|
||||
}
|
||||
MouseState::NoPointerEvent(h) => h.on_mouse_press(&self.common, mouse_handler),
|
||||
}
|
||||
self.pointer_handler
|
||||
.on_mouse_press(&self.common, mouse_handler, touch_handler)
|
||||
}
|
||||
|
||||
pub fn on_cursor_move<MOD, M, T, B>(
|
||||
|
@ -280,28 +257,21 @@ impl Canvas {
|
|||
T: 'static + FnMut(i32, PhysicalPosition<f64>, Force),
|
||||
B: 'static + FnMut(i32, PhysicalPosition<f64>, ButtonsState, MouseButton),
|
||||
{
|
||||
match &mut self.mouse_state {
|
||||
MouseState::HasPointerEvent(h) => h.on_cursor_move(
|
||||
&self.common,
|
||||
modifier_handler,
|
||||
mouse_handler,
|
||||
touch_handler,
|
||||
button_handler,
|
||||
prevent_default,
|
||||
),
|
||||
MouseState::NoPointerEvent(h) => {
|
||||
h.on_cursor_move(&self.common, modifier_handler, mouse_handler)
|
||||
}
|
||||
}
|
||||
self.pointer_handler.on_cursor_move(
|
||||
&self.common,
|
||||
modifier_handler,
|
||||
mouse_handler,
|
||||
touch_handler,
|
||||
button_handler,
|
||||
prevent_default,
|
||||
)
|
||||
}
|
||||
|
||||
pub fn on_touch_cancel<F>(&mut self, handler: F)
|
||||
where
|
||||
F: 'static + FnMut(i32, PhysicalPosition<f64>, Force),
|
||||
{
|
||||
if let MouseState::HasPointerEvent(h) = &mut self.mouse_state {
|
||||
h.on_touch_cancel(&self.common, handler)
|
||||
}
|
||||
self.pointer_handler.on_touch_cancel(&self.common, handler)
|
||||
}
|
||||
|
||||
pub fn on_mouse_wheel<F>(&mut self, mut handler: F, prevent_default: bool)
|
||||
|
@ -358,15 +328,12 @@ impl Canvas {
|
|||
self.on_mouse_wheel = None;
|
||||
self.on_fullscreen_change = None;
|
||||
self.on_dark_mode = None;
|
||||
match &mut self.mouse_state {
|
||||
MouseState::HasPointerEvent(h) => h.remove_listeners(),
|
||||
MouseState::NoPointerEvent(h) => h.remove_listeners(),
|
||||
}
|
||||
self.pointer_handler.remove_listeners()
|
||||
}
|
||||
}
|
||||
|
||||
impl Common {
|
||||
fn add_event<E, F>(
|
||||
pub fn add_event<E, F>(
|
||||
&self,
|
||||
event_name: &'static str,
|
||||
mut handler: F,
|
||||
|
@ -391,7 +358,7 @@ impl Common {
|
|||
// The difference between add_event and add_user_event is that the latter has a special meaning
|
||||
// for browser security. A user event is a deliberate action by the user (like a mouse or key
|
||||
// press) and is the only time things like a fullscreen request may be successfully completed.)
|
||||
fn add_user_event<E, F>(
|
||||
pub fn add_user_event<E, F>(
|
||||
&self,
|
||||
event_name: &'static str,
|
||||
mut handler: F,
|
||||
|
@ -415,43 +382,6 @@ impl Common {
|
|||
})
|
||||
}
|
||||
|
||||
// This function is used exclusively for mouse events (not pointer events).
|
||||
// Due to the need for mouse capturing, the mouse event handlers are added
|
||||
// to the window instead of the canvas element, which requires special
|
||||
// handling to control event propagation.
|
||||
fn add_window_mouse_event<F>(
|
||||
&self,
|
||||
event_name: &'static str,
|
||||
mut handler: F,
|
||||
) -> EventListenerHandle<dyn FnMut(MouseEvent)>
|
||||
where
|
||||
F: 'static + FnMut(MouseEvent),
|
||||
{
|
||||
let wants_fullscreen = self.wants_fullscreen.clone();
|
||||
let canvas = self.raw.clone();
|
||||
let window = web_sys::window().expect("Failed to obtain window");
|
||||
|
||||
let closure = Closure::wrap(Box::new(move |event: MouseEvent| {
|
||||
handler(event);
|
||||
|
||||
if *wants_fullscreen.borrow() {
|
||||
canvas
|
||||
.request_fullscreen()
|
||||
.expect("Failed to enter fullscreen");
|
||||
*wants_fullscreen.borrow_mut() = false;
|
||||
}
|
||||
}) as Box<dyn FnMut(_)>);
|
||||
|
||||
let listener = EventListenerHandle::with_options(
|
||||
&window,
|
||||
event_name,
|
||||
closure,
|
||||
AddEventListenerOptions::new().capture(true),
|
||||
);
|
||||
|
||||
listener
|
||||
}
|
||||
|
||||
pub fn request_fullscreen(&self) {
|
||||
#[wasm_bindgen]
|
||||
extern "C" {
|
||||
|
@ -483,21 +413,3 @@ impl Common {
|
|||
super::is_fullscreen(&self.raw)
|
||||
}
|
||||
}
|
||||
|
||||
/// Pointer events are supported or not.
|
||||
enum MouseState {
|
||||
HasPointerEvent(pointer_handler::PointerHandler),
|
||||
NoPointerEvent(mouse_handler::MouseHandler),
|
||||
}
|
||||
|
||||
/// Returns whether pointer events are supported.
|
||||
/// Used to decide whether to use pointer events
|
||||
/// or plain mouse events. Note that Safari
|
||||
/// doesn't support pointer events now.
|
||||
fn has_pointer_event() -> bool {
|
||||
if let Some(window) = web_sys::window() {
|
||||
window.get("PointerEvent").is_some()
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,234 +0,0 @@
|
|||
use super::event;
|
||||
use super::EventListenerHandle;
|
||||
use crate::dpi::PhysicalPosition;
|
||||
use crate::event::MouseButton;
|
||||
use crate::keyboard::ModifiersState;
|
||||
|
||||
use std::cell::RefCell;
|
||||
use std::rc::Rc;
|
||||
|
||||
use web_sys::{EventTarget, MouseEvent};
|
||||
|
||||
type MouseLeaveHandler = Rc<RefCell<Option<Box<dyn FnMut(i32, ModifiersState)>>>>;
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub(super) struct MouseHandler {
|
||||
on_mouse_leave: Option<EventListenerHandle<dyn FnMut(MouseEvent)>>,
|
||||
on_mouse_enter: Option<EventListenerHandle<dyn FnMut(MouseEvent)>>,
|
||||
on_mouse_move: Option<EventListenerHandle<dyn FnMut(MouseEvent)>>,
|
||||
on_mouse_press: Option<EventListenerHandle<dyn FnMut(MouseEvent)>>,
|
||||
on_mouse_release: Option<EventListenerHandle<dyn FnMut(MouseEvent)>>,
|
||||
on_mouse_leave_handler: MouseLeaveHandler,
|
||||
mouse_capture_state: Rc<RefCell<MouseCaptureState>>,
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Eq)]
|
||||
pub(super) enum MouseCaptureState {
|
||||
NotCaptured,
|
||||
Captured,
|
||||
OtherElement,
|
||||
}
|
||||
|
||||
impl MouseHandler {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
on_mouse_leave: None,
|
||||
on_mouse_enter: None,
|
||||
on_mouse_move: None,
|
||||
on_mouse_press: None,
|
||||
on_mouse_release: None,
|
||||
on_mouse_leave_handler: Rc::new(RefCell::new(None)),
|
||||
mouse_capture_state: Rc::new(RefCell::new(MouseCaptureState::NotCaptured)),
|
||||
}
|
||||
}
|
||||
pub fn on_cursor_leave<F>(&mut self, canvas_common: &super::Common, handler: F)
|
||||
where
|
||||
F: 'static + FnMut(i32, ModifiersState),
|
||||
{
|
||||
*self.on_mouse_leave_handler.borrow_mut() = Some(Box::new(handler));
|
||||
let on_mouse_leave_handler = self.on_mouse_leave_handler.clone();
|
||||
let mouse_capture_state = self.mouse_capture_state.clone();
|
||||
self.on_mouse_leave = Some(canvas_common.add_event(
|
||||
"mouseout",
|
||||
move |event: MouseEvent| {
|
||||
// If the mouse is being captured, it is always considered
|
||||
// to be "within" the the canvas, until the capture has been
|
||||
// released, therefore we don't send cursor leave events.
|
||||
if *mouse_capture_state.borrow() != MouseCaptureState::Captured {
|
||||
if let Some(handler) = on_mouse_leave_handler.borrow_mut().as_mut() {
|
||||
let modifiers = event::mouse_modifiers(&event);
|
||||
handler(0, modifiers);
|
||||
}
|
||||
}
|
||||
},
|
||||
));
|
||||
}
|
||||
|
||||
pub fn on_cursor_enter<F>(&mut self, canvas_common: &super::Common, mut handler: F)
|
||||
where
|
||||
F: 'static + FnMut(i32, ModifiersState),
|
||||
{
|
||||
let mouse_capture_state = self.mouse_capture_state.clone();
|
||||
self.on_mouse_enter = Some(canvas_common.add_event(
|
||||
"mouseover",
|
||||
move |event: MouseEvent| {
|
||||
// We don't send cursor leave events when the mouse is being
|
||||
// captured, therefore we do the same with cursor enter events.
|
||||
if *mouse_capture_state.borrow() != MouseCaptureState::Captured {
|
||||
let modifiers = event::mouse_modifiers(&event);
|
||||
handler(0, modifiers);
|
||||
}
|
||||
},
|
||||
));
|
||||
}
|
||||
|
||||
pub fn on_mouse_release<F>(&mut self, canvas_common: &super::Common, mut handler: F)
|
||||
where
|
||||
F: 'static + FnMut(i32, PhysicalPosition<f64>, MouseButton, ModifiersState),
|
||||
{
|
||||
let on_mouse_leave_handler = self.on_mouse_leave_handler.clone();
|
||||
let mouse_capture_state = self.mouse_capture_state.clone();
|
||||
let canvas = canvas_common.raw.clone();
|
||||
self.on_mouse_release = Some(canvas_common.add_window_mouse_event(
|
||||
"mouseup",
|
||||
move |event: MouseEvent| {
|
||||
let canvas = canvas.clone();
|
||||
let mut mouse_capture_state = mouse_capture_state.borrow_mut();
|
||||
match &*mouse_capture_state {
|
||||
// Shouldn't happen but we'll just ignore it.
|
||||
MouseCaptureState::NotCaptured => return,
|
||||
MouseCaptureState::OtherElement => {
|
||||
if event.buttons() == 0 {
|
||||
// No buttons are pressed anymore so reset
|
||||
// the capturing state.
|
||||
*mouse_capture_state = MouseCaptureState::NotCaptured;
|
||||
}
|
||||
return;
|
||||
}
|
||||
MouseCaptureState::Captured => {}
|
||||
}
|
||||
event.stop_propagation();
|
||||
handler(
|
||||
0,
|
||||
event::mouse_position(&event).to_physical(super::super::scale_factor()),
|
||||
event::mouse_button(&event).expect("no mouse button released"),
|
||||
event::mouse_modifiers(&event),
|
||||
);
|
||||
if event
|
||||
.target()
|
||||
.map_or(false, |target| target != EventTarget::from(canvas))
|
||||
{
|
||||
// Since we do not send cursor leave events while the
|
||||
// cursor is being captured, we instead send it after
|
||||
// the capture has been released.
|
||||
if let Some(handler) = on_mouse_leave_handler.borrow_mut().as_mut() {
|
||||
let modifiers = event::mouse_modifiers(&event);
|
||||
handler(0, modifiers);
|
||||
}
|
||||
}
|
||||
if event.buttons() == 0 {
|
||||
// No buttons are pressed anymore so reset
|
||||
// the capturing state.
|
||||
*mouse_capture_state = MouseCaptureState::NotCaptured;
|
||||
}
|
||||
},
|
||||
));
|
||||
}
|
||||
|
||||
pub fn on_mouse_press<F>(&mut self, canvas_common: &super::Common, mut handler: F)
|
||||
where
|
||||
F: 'static + FnMut(i32, PhysicalPosition<f64>, MouseButton, ModifiersState),
|
||||
{
|
||||
let mouse_capture_state = self.mouse_capture_state.clone();
|
||||
let canvas = canvas_common.raw.clone();
|
||||
self.on_mouse_press = Some(canvas_common.add_window_mouse_event(
|
||||
"mousedown",
|
||||
move |event: MouseEvent| {
|
||||
let canvas = canvas.clone();
|
||||
let mut mouse_capture_state = mouse_capture_state.borrow_mut();
|
||||
match &*mouse_capture_state {
|
||||
MouseCaptureState::NotCaptured
|
||||
if event
|
||||
.target()
|
||||
.map_or(false, |target| target != EventTarget::from(canvas)) =>
|
||||
{
|
||||
// The target isn't our canvas which means the
|
||||
// mouse is pressed outside of it.
|
||||
*mouse_capture_state = MouseCaptureState::OtherElement;
|
||||
return;
|
||||
}
|
||||
MouseCaptureState::OtherElement => return,
|
||||
_ => {}
|
||||
}
|
||||
*mouse_capture_state = MouseCaptureState::Captured;
|
||||
event.stop_propagation();
|
||||
handler(
|
||||
0,
|
||||
event::mouse_position(&event).to_physical(super::super::scale_factor()),
|
||||
event::mouse_button(&event).expect("no mouse button pressed"),
|
||||
event::mouse_modifiers(&event),
|
||||
);
|
||||
},
|
||||
));
|
||||
}
|
||||
|
||||
pub fn on_cursor_move<MOD, M>(
|
||||
&mut self,
|
||||
canvas_common: &super::Common,
|
||||
mut modifier_handler: MOD,
|
||||
mut mouse_handler: M,
|
||||
) where
|
||||
MOD: 'static + FnMut(ModifiersState),
|
||||
M: 'static + FnMut(i32, PhysicalPosition<f64>, PhysicalPosition<f64>),
|
||||
{
|
||||
let mouse_capture_state = self.mouse_capture_state.clone();
|
||||
let canvas = canvas_common.raw.clone();
|
||||
self.on_mouse_move = Some(canvas_common.add_window_mouse_event(
|
||||
"mousemove",
|
||||
move |event: MouseEvent| {
|
||||
modifier_handler(event::mouse_modifiers(&event));
|
||||
|
||||
let canvas = canvas.clone();
|
||||
let mouse_capture_state = mouse_capture_state.borrow();
|
||||
let is_over_canvas = event
|
||||
.target()
|
||||
.map_or(false, |target| target == EventTarget::from(canvas.clone()));
|
||||
match &*mouse_capture_state {
|
||||
// Don't handle hover events outside of canvas.
|
||||
MouseCaptureState::NotCaptured | MouseCaptureState::OtherElement
|
||||
if !is_over_canvas => {}
|
||||
// If hovering over the canvas, just send the cursor move event.
|
||||
MouseCaptureState::NotCaptured
|
||||
| MouseCaptureState::OtherElement
|
||||
| MouseCaptureState::Captured => {
|
||||
if *mouse_capture_state == MouseCaptureState::Captured {
|
||||
event.stop_propagation();
|
||||
}
|
||||
let mouse_pos = if is_over_canvas {
|
||||
event::mouse_position(&event)
|
||||
} else {
|
||||
// Since the mouse is not on the canvas, we cannot
|
||||
// use `offsetX`/`offsetY`.
|
||||
event::mouse_position_by_client(&event, &canvas)
|
||||
};
|
||||
let mouse_delta = event::mouse_delta(&event);
|
||||
mouse_handler(
|
||||
0,
|
||||
mouse_pos.to_physical(super::super::scale_factor()),
|
||||
mouse_delta.to_physical(super::super::scale_factor()),
|
||||
);
|
||||
}
|
||||
}
|
||||
},
|
||||
));
|
||||
}
|
||||
|
||||
pub fn remove_listeners(&mut self) {
|
||||
self.on_mouse_leave = None;
|
||||
self.on_mouse_enter = None;
|
||||
self.on_mouse_move = None;
|
||||
self.on_mouse_press = None;
|
||||
self.on_mouse_release = None;
|
||||
*self.on_mouse_leave_handler.borrow_mut() = None;
|
||||
}
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
use wasm_bindgen::{prelude::Closure, JsCast};
|
||||
use web_sys::{AddEventListenerOptions, EventListenerOptions, EventTarget};
|
||||
use web_sys::{EventListenerOptions, EventTarget};
|
||||
|
||||
pub(super) struct EventListenerHandle<T: ?Sized> {
|
||||
pub struct EventListenerHandle<T: ?Sized> {
|
||||
target: EventTarget,
|
||||
event_type: &'static str,
|
||||
listener: Closure<T>,
|
||||
|
@ -24,31 +24,6 @@ impl<T: ?Sized> EventListenerHandle<T> {
|
|||
options: EventListenerOptions::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn with_options<U>(
|
||||
target: &U,
|
||||
event_type: &'static str,
|
||||
listener: Closure<T>,
|
||||
options: &AddEventListenerOptions,
|
||||
) -> Self
|
||||
where
|
||||
U: Clone + Into<EventTarget>,
|
||||
{
|
||||
let target = target.clone().into();
|
||||
target
|
||||
.add_event_listener_with_callback_and_add_event_listener_options(
|
||||
event_type,
|
||||
listener.as_ref().unchecked_ref(),
|
||||
options,
|
||||
)
|
||||
.expect("Failed to add event listener");
|
||||
EventListenerHandle {
|
||||
target,
|
||||
event_type,
|
||||
listener,
|
||||
options: options.clone().unchecked_into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: ?Sized> Drop for EventListenerHandle<T> {
|
||||
|
|
|
@ -2,6 +2,7 @@ mod canvas;
|
|||
mod event;
|
||||
mod event_handle;
|
||||
mod media_query_handle;
|
||||
mod pointer;
|
||||
mod scaling;
|
||||
mod timeout;
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
use super::canvas::Common;
|
||||
use super::event;
|
||||
use super::EventListenerHandle;
|
||||
use super::event_handle::EventListenerHandle;
|
||||
use crate::dpi::PhysicalPosition;
|
||||
use crate::event::{Force, MouseButton};
|
||||
use crate::keyboard::ModifiersState;
|
||||
|
@ -31,7 +32,7 @@ impl PointerHandler {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn on_cursor_leave<F>(&mut self, canvas_common: &super::Common, mut handler: F)
|
||||
pub fn on_cursor_leave<F>(&mut self, canvas_common: &Common, mut handler: F)
|
||||
where
|
||||
F: 'static + FnMut(i32, ModifiersState),
|
||||
{
|
||||
|
@ -50,7 +51,7 @@ impl PointerHandler {
|
|||
));
|
||||
}
|
||||
|
||||
pub fn on_cursor_enter<F>(&mut self, canvas_common: &super::Common, mut handler: F)
|
||||
pub fn on_cursor_enter<F>(&mut self, canvas_common: &Common, mut handler: F)
|
||||
where
|
||||
F: 'static + FnMut(i32, ModifiersState),
|
||||
{
|
||||
|
@ -71,7 +72,7 @@ impl PointerHandler {
|
|||
|
||||
pub fn on_mouse_release<M, T>(
|
||||
&mut self,
|
||||
canvas_common: &super::Common,
|
||||
canvas_common: &Common,
|
||||
mut mouse_handler: M,
|
||||
mut touch_handler: T,
|
||||
) where
|
||||
|
@ -81,29 +82,26 @@ impl PointerHandler {
|
|||
let canvas = canvas_common.raw.clone();
|
||||
self.on_pointer_release = Some(canvas_common.add_user_event(
|
||||
"pointerup",
|
||||
move |event: PointerEvent| {
|
||||
match event.pointer_type().as_str() {
|
||||
"touch" => touch_handler(
|
||||
event.pointer_id(),
|
||||
event::touch_position(&event, &canvas)
|
||||
.to_physical(super::super::scale_factor()),
|
||||
Force::Normalized(event.pressure() as f64),
|
||||
),
|
||||
"mouse" => mouse_handler(
|
||||
event.pointer_id(),
|
||||
event::mouse_position(&event).to_physical(super::super::scale_factor()),
|
||||
event::mouse_button(&event).expect("no mouse button released"),
|
||||
event::mouse_modifiers(&event),
|
||||
),
|
||||
_ => (),
|
||||
}
|
||||
move |event: PointerEvent| match event.pointer_type().as_str() {
|
||||
"touch" => touch_handler(
|
||||
event.pointer_id(),
|
||||
event::touch_position(&event, &canvas).to_physical(super::scale_factor()),
|
||||
Force::Normalized(event.pressure() as f64),
|
||||
),
|
||||
"mouse" => mouse_handler(
|
||||
event.pointer_id(),
|
||||
event::mouse_position(&event).to_physical(super::scale_factor()),
|
||||
event::mouse_button(&event).expect("no mouse button released"),
|
||||
event::mouse_modifiers(&event),
|
||||
),
|
||||
_ => (),
|
||||
},
|
||||
));
|
||||
}
|
||||
|
||||
pub fn on_mouse_press<M, T>(
|
||||
&mut self,
|
||||
canvas_common: &super::Common,
|
||||
canvas_common: &Common,
|
||||
mut mouse_handler: M,
|
||||
mut touch_handler: T,
|
||||
) where
|
||||
|
@ -119,14 +117,14 @@ impl PointerHandler {
|
|||
touch_handler(
|
||||
event.pointer_id(),
|
||||
event::touch_position(&event, &canvas)
|
||||
.to_physical(super::super::scale_factor()),
|
||||
.to_physical(super::scale_factor()),
|
||||
Force::Normalized(event.pressure() as f64),
|
||||
);
|
||||
}
|
||||
"mouse" => {
|
||||
mouse_handler(
|
||||
event.pointer_id(),
|
||||
event::mouse_position(&event).to_physical(super::super::scale_factor()),
|
||||
event::mouse_position(&event).to_physical(super::scale_factor()),
|
||||
event::mouse_button(&event).expect("no mouse button pressed"),
|
||||
event::mouse_modifiers(&event),
|
||||
);
|
||||
|
@ -144,7 +142,7 @@ impl PointerHandler {
|
|||
|
||||
pub fn on_cursor_move<MOD, M, T, B>(
|
||||
&mut self,
|
||||
canvas_common: &super::Common,
|
||||
canvas_common: &Common,
|
||||
mut modifier_handler: MOD,
|
||||
mut mouse_handler: M,
|
||||
mut touch_handler: T,
|
||||
|
@ -196,7 +194,7 @@ impl PointerHandler {
|
|||
|
||||
button_handler(
|
||||
id,
|
||||
event::mouse_position(&event).to_physical(super::super::scale_factor()),
|
||||
event::mouse_position(&event).to_physical(super::scale_factor()),
|
||||
event::mouse_buttons(&event),
|
||||
button,
|
||||
);
|
||||
|
@ -227,13 +225,13 @@ impl PointerHandler {
|
|||
match pointer_type.as_str() {
|
||||
"mouse" => mouse_handler(
|
||||
id,
|
||||
event::mouse_position(&event).to_physical(super::super::scale_factor()),
|
||||
event::mouse_delta(&event).to_physical(super::super::scale_factor()),
|
||||
event::mouse_position(&event).to_physical(super::scale_factor()),
|
||||
event::mouse_delta(&event).to_physical(super::scale_factor()),
|
||||
),
|
||||
"touch" => touch_handler(
|
||||
id,
|
||||
event::touch_position(&event, &canvas)
|
||||
.to_physical(super::super::scale_factor()),
|
||||
.to_physical(super::scale_factor()),
|
||||
Force::Normalized(event.pressure() as f64),
|
||||
),
|
||||
_ => unreachable!("didn't return early before"),
|
||||
|
@ -243,7 +241,7 @@ impl PointerHandler {
|
|||
));
|
||||
}
|
||||
|
||||
pub fn on_touch_cancel<F>(&mut self, canvas_common: &super::Common, mut handler: F)
|
||||
pub fn on_touch_cancel<F>(&mut self, canvas_common: &Common, mut handler: F)
|
||||
where
|
||||
F: 'static + FnMut(i32, PhysicalPosition<f64>, Force),
|
||||
{
|
||||
|
@ -254,8 +252,7 @@ impl PointerHandler {
|
|||
if event.pointer_type() == "touch" {
|
||||
handler(
|
||||
event.pointer_id(),
|
||||
event::touch_position(&event, &canvas)
|
||||
.to_physical(super::super::scale_factor()),
|
||||
event::touch_position(&event, &canvas).to_physical(super::scale_factor()),
|
||||
Force::Normalized(event.pressure() as f64),
|
||||
);
|
||||
}
|
Loading…
Reference in a new issue