2022-07-21 22:22:36 +03:00
|
|
|
use std::cell::RefCell;
|
|
|
|
|
use std::clone::Clone;
|
|
|
|
|
use std::collections::{vec_deque::IntoIter as VecDequeIter, VecDeque};
|
|
|
|
|
use std::rc::Rc;
|
|
|
|
|
|
|
|
|
|
use raw_window_handle::{RawDisplayHandle, WebDisplayHandle};
|
|
|
|
|
|
2022-03-18 14:09:39 +01:00
|
|
|
use super::{
|
|
|
|
|
super::monitor::MonitorHandle, backend, device::DeviceId, proxy::EventLoopProxy, runner,
|
|
|
|
|
window::WindowId,
|
|
|
|
|
};
|
2019-12-31 14:39:33 -08:00
|
|
|
use crate::dpi::{PhysicalSize, Size};
|
2021-02-16 17:50:46 -05:00
|
|
|
use crate::event::{
|
2022-03-18 14:09:39 +01:00
|
|
|
DeviceEvent, DeviceId as RootDeviceId, ElementState, Event, KeyboardInput, TouchPhase,
|
|
|
|
|
WindowEvent,
|
2021-02-16 17:50:46 -05:00
|
|
|
};
|
2022-03-18 14:09:39 +01:00
|
|
|
use crate::window::{Theme, WindowId as RootWindowId};
|
2019-06-25 03:15:34 +02:00
|
|
|
|
2022-03-18 14:09:39 +01:00
|
|
|
pub struct EventLoopWindowTarget<T: 'static> {
|
2019-06-25 03:15:34 +02:00
|
|
|
pub(crate) runner: runner::Shared<T>,
|
|
|
|
|
}
|
|
|
|
|
|
2022-03-18 14:09:39 +01:00
|
|
|
impl<T> Clone for EventLoopWindowTarget<T> {
|
2019-06-25 03:15:34 +02:00
|
|
|
fn clone(&self) -> Self {
|
2022-03-18 14:09:39 +01:00
|
|
|
Self {
|
2019-06-25 03:15:34 +02:00
|
|
|
runner: self.runner.clone(),
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-03-18 14:09:39 +01:00
|
|
|
impl<T> EventLoopWindowTarget<T> {
|
2019-06-25 03:15:34 +02:00
|
|
|
pub fn new() -> Self {
|
2022-03-18 14:09:39 +01:00
|
|
|
Self {
|
2019-06-25 03:15:34 +02:00
|
|
|
runner: runner::Shared::new(),
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-03-18 14:09:39 +01:00
|
|
|
pub fn proxy(&self) -> EventLoopProxy<T> {
|
|
|
|
|
EventLoopProxy::new(self.runner.clone())
|
2019-06-25 03:15:34 +02:00
|
|
|
}
|
|
|
|
|
|
2022-11-23 13:07:58 +01:00
|
|
|
pub fn run(&self, event_handler: Box<runner::EventHandler<T>>) {
|
2019-06-25 03:15:34 +02:00
|
|
|
self.runner.set_listener(event_handler);
|
2020-08-30 21:15:44 +08:00
|
|
|
let runner = self.runner.clone();
|
|
|
|
|
self.runner.set_on_scale_change(move |arg| {
|
|
|
|
|
runner.handle_scale_changed(arg.old_scale, arg.new_scale)
|
|
|
|
|
});
|
2019-06-25 03:15:34 +02:00
|
|
|
}
|
|
|
|
|
|
2022-03-18 14:09:39 +01:00
|
|
|
pub fn generate_id(&self) -> WindowId {
|
|
|
|
|
WindowId(self.runner.generate_id())
|
2019-09-19 18:40:18 -04:00
|
|
|
}
|
|
|
|
|
|
2022-07-14 13:22:31 -02:30
|
|
|
pub fn register(
|
|
|
|
|
&self,
|
|
|
|
|
canvas: &Rc<RefCell<backend::Canvas>>,
|
|
|
|
|
id: WindowId,
|
|
|
|
|
prevent_default: bool,
|
|
|
|
|
) {
|
2022-03-18 14:09:39 +01:00
|
|
|
self.runner.add_canvas(RootWindowId(id), canvas);
|
2020-09-21 06:42:07 +08:00
|
|
|
let mut canvas = canvas.borrow_mut();
|
2019-09-27 17:06:14 -04:00
|
|
|
canvas.set_attribute("data-raw-handle", &id.0.to_string());
|
|
|
|
|
|
2022-09-04 13:45:30 +10:00
|
|
|
canvas.on_touch_start(prevent_default);
|
|
|
|
|
canvas.on_touch_end(prevent_default);
|
|
|
|
|
|
2020-09-21 06:42:07 +08:00
|
|
|
let runner = self.runner.clone();
|
2019-06-25 21:01:13 +02:00
|
|
|
canvas.on_blur(move || {
|
|
|
|
|
runner.send_event(Event::WindowEvent {
|
2022-03-18 14:09:39 +01:00
|
|
|
window_id: RootWindowId(id),
|
2019-06-25 21:01:13 +02:00
|
|
|
event: WindowEvent::Focused(false),
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
let runner = self.runner.clone();
|
|
|
|
|
canvas.on_focus(move || {
|
|
|
|
|
runner.send_event(Event::WindowEvent {
|
2022-03-18 14:09:39 +01:00
|
|
|
window_id: RootWindowId(id),
|
2019-06-25 21:01:13 +02:00
|
|
|
event: WindowEvent::Focused(true),
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
let runner = self.runner.clone();
|
2022-07-14 13:22:31 -02:30
|
|
|
canvas.on_keyboard_press(
|
|
|
|
|
move |scancode, virtual_keycode, modifiers| {
|
|
|
|
|
#[allow(deprecated)]
|
|
|
|
|
runner.send_event(Event::WindowEvent {
|
|
|
|
|
window_id: RootWindowId(id),
|
|
|
|
|
event: WindowEvent::KeyboardInput {
|
|
|
|
|
device_id: RootDeviceId(unsafe { DeviceId::dummy() }),
|
|
|
|
|
input: KeyboardInput {
|
|
|
|
|
scancode,
|
|
|
|
|
state: ElementState::Pressed,
|
|
|
|
|
virtual_keycode,
|
|
|
|
|
modifiers,
|
|
|
|
|
},
|
|
|
|
|
is_synthetic: false,
|
2019-06-25 21:01:13 +02:00
|
|
|
},
|
2022-07-14 13:22:31 -02:30
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
prevent_default,
|
|
|
|
|
);
|
2019-06-25 21:01:13 +02:00
|
|
|
|
|
|
|
|
let runner = self.runner.clone();
|
2022-07-14 13:22:31 -02:30
|
|
|
canvas.on_keyboard_release(
|
|
|
|
|
move |scancode, virtual_keycode, modifiers| {
|
|
|
|
|
#[allow(deprecated)]
|
|
|
|
|
runner.send_event(Event::WindowEvent {
|
|
|
|
|
window_id: RootWindowId(id),
|
|
|
|
|
event: WindowEvent::KeyboardInput {
|
|
|
|
|
device_id: RootDeviceId(unsafe { DeviceId::dummy() }),
|
|
|
|
|
input: KeyboardInput {
|
|
|
|
|
scancode,
|
|
|
|
|
state: ElementState::Released,
|
|
|
|
|
virtual_keycode,
|
|
|
|
|
modifiers,
|
|
|
|
|
},
|
|
|
|
|
is_synthetic: false,
|
2019-06-25 21:01:13 +02:00
|
|
|
},
|
2022-07-14 13:22:31 -02:30
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
prevent_default,
|
|
|
|
|
);
|
2019-06-25 21:01:13 +02:00
|
|
|
|
2019-06-25 21:18:11 +02:00
|
|
|
let runner = self.runner.clone();
|
2022-07-14 13:22:31 -02:30
|
|
|
canvas.on_received_character(
|
|
|
|
|
move |char_code| {
|
|
|
|
|
runner.send_event(Event::WindowEvent {
|
|
|
|
|
window_id: RootWindowId(id),
|
|
|
|
|
event: WindowEvent::ReceivedCharacter(char_code),
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
prevent_default,
|
|
|
|
|
);
|
2019-06-25 21:18:11 +02:00
|
|
|
|
2019-06-25 18:07:47 +02:00
|
|
|
let runner = self.runner.clone();
|
2019-06-25 21:36:24 +02:00
|
|
|
canvas.on_cursor_leave(move |pointer_id| {
|
2019-06-25 03:15:34 +02:00
|
|
|
runner.send_event(Event::WindowEvent {
|
2022-03-18 14:09:39 +01:00
|
|
|
window_id: RootWindowId(id),
|
2019-06-25 03:15:34 +02:00
|
|
|
event: WindowEvent::CursorLeft {
|
2022-03-18 14:09:39 +01:00
|
|
|
device_id: RootDeviceId(DeviceId(pointer_id)),
|
2019-06-25 03:15:34 +02:00
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
2019-06-25 18:07:47 +02:00
|
|
|
let runner = self.runner.clone();
|
2019-06-25 21:36:24 +02:00
|
|
|
canvas.on_cursor_enter(move |pointer_id| {
|
2019-06-25 03:15:34 +02:00
|
|
|
runner.send_event(Event::WindowEvent {
|
2022-03-18 14:09:39 +01:00
|
|
|
window_id: RootWindowId(id),
|
2019-06-25 03:15:34 +02:00
|
|
|
event: WindowEvent::CursorEntered {
|
2022-03-18 14:09:39 +01:00
|
|
|
device_id: RootDeviceId(DeviceId(pointer_id)),
|
2019-06-25 03:15:34 +02:00
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
2019-06-25 18:07:47 +02:00
|
|
|
let runner = self.runner.clone();
|
2022-09-04 13:45:30 +10:00
|
|
|
canvas.on_cursor_move(
|
|
|
|
|
move |pointer_id, position, delta, modifiers| {
|
|
|
|
|
runner.send_event(Event::WindowEvent {
|
|
|
|
|
window_id: RootWindowId(id),
|
|
|
|
|
event: WindowEvent::CursorMoved {
|
|
|
|
|
device_id: RootDeviceId(DeviceId(pointer_id)),
|
|
|
|
|
position,
|
|
|
|
|
modifiers,
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
runner.send_event(Event::DeviceEvent {
|
2022-03-18 14:09:39 +01:00
|
|
|
device_id: RootDeviceId(DeviceId(pointer_id)),
|
2022-09-04 13:45:30 +10:00
|
|
|
event: DeviceEvent::MouseMotion {
|
|
|
|
|
delta: (delta.x, delta.y),
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
prevent_default,
|
|
|
|
|
);
|
2019-06-25 03:15:34 +02:00
|
|
|
|
2019-06-25 18:07:47 +02:00
|
|
|
let runner = self.runner.clone();
|
2020-08-22 08:23:08 +08:00
|
|
|
canvas.on_mouse_press(move |pointer_id, position, button, modifiers| {
|
|
|
|
|
// A mouse down event may come in without any prior CursorMoved events,
|
|
|
|
|
// therefore we should send a CursorMoved event to make sure that the
|
|
|
|
|
// user code has the correct cursor position.
|
2020-08-27 00:11:27 +08:00
|
|
|
runner.send_events(
|
|
|
|
|
std::iter::once(Event::WindowEvent {
|
2022-07-13 08:46:15 +10:00
|
|
|
window_id: RootWindowId(id),
|
|
|
|
|
event: WindowEvent::Focused(true),
|
|
|
|
|
})
|
|
|
|
|
.chain(std::iter::once(Event::WindowEvent {
|
2022-03-18 14:09:39 +01:00
|
|
|
window_id: RootWindowId(id),
|
2020-08-27 00:11:27 +08:00
|
|
|
event: WindowEvent::CursorMoved {
|
2022-03-18 14:09:39 +01:00
|
|
|
device_id: RootDeviceId(DeviceId(pointer_id)),
|
2020-08-27 00:11:27 +08:00
|
|
|
position,
|
|
|
|
|
modifiers,
|
|
|
|
|
},
|
2022-07-13 08:46:15 +10:00
|
|
|
}))
|
2020-08-27 00:11:27 +08:00
|
|
|
.chain(std::iter::once(Event::WindowEvent {
|
2022-03-18 14:09:39 +01:00
|
|
|
window_id: RootWindowId(id),
|
2020-08-27 00:11:27 +08:00
|
|
|
event: WindowEvent::MouseInput {
|
2022-03-18 14:09:39 +01:00
|
|
|
device_id: RootDeviceId(DeviceId(pointer_id)),
|
2020-08-27 00:11:27 +08:00
|
|
|
state: ElementState::Pressed,
|
|
|
|
|
button,
|
|
|
|
|
modifiers,
|
|
|
|
|
},
|
|
|
|
|
})),
|
|
|
|
|
);
|
2019-06-25 03:15:34 +02:00
|
|
|
});
|
|
|
|
|
|
2019-06-25 18:07:47 +02:00
|
|
|
let runner = self.runner.clone();
|
2019-06-25 21:36:24 +02:00
|
|
|
canvas.on_mouse_release(move |pointer_id, button, modifiers| {
|
2019-06-25 03:15:34 +02:00
|
|
|
runner.send_event(Event::WindowEvent {
|
2022-03-18 14:09:39 +01:00
|
|
|
window_id: RootWindowId(id),
|
2019-06-25 03:15:34 +02:00
|
|
|
event: WindowEvent::MouseInput {
|
2022-03-18 14:09:39 +01:00
|
|
|
device_id: RootDeviceId(DeviceId(pointer_id)),
|
2019-06-29 17:48:22 +02:00
|
|
|
state: ElementState::Released,
|
2019-06-25 03:15:34 +02:00
|
|
|
button,
|
|
|
|
|
modifiers,
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
2019-06-25 18:07:47 +02:00
|
|
|
let runner = self.runner.clone();
|
2022-07-14 13:22:31 -02:30
|
|
|
canvas.on_mouse_wheel(
|
|
|
|
|
move |pointer_id, delta, modifiers| {
|
|
|
|
|
runner.send_event(Event::WindowEvent {
|
|
|
|
|
window_id: RootWindowId(id),
|
|
|
|
|
event: WindowEvent::MouseWheel {
|
|
|
|
|
device_id: RootDeviceId(DeviceId(pointer_id)),
|
|
|
|
|
delta,
|
|
|
|
|
phase: TouchPhase::Moved,
|
|
|
|
|
modifiers,
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
prevent_default,
|
|
|
|
|
);
|
2019-10-11 11:45:07 -04:00
|
|
|
|
|
|
|
|
let runner = self.runner.clone();
|
|
|
|
|
let raw = canvas.raw().clone();
|
2019-12-31 14:39:33 -08:00
|
|
|
|
|
|
|
|
// The size to restore to after exiting fullscreen.
|
|
|
|
|
let mut intended_size = PhysicalSize {
|
2022-12-22 21:35:33 +02:00
|
|
|
width: raw.width(),
|
|
|
|
|
height: raw.height(),
|
2019-10-11 11:45:07 -04:00
|
|
|
};
|
|
|
|
|
canvas.on_fullscreen_change(move || {
|
|
|
|
|
// If the canvas is marked as fullscreen, it is moving *into* fullscreen
|
|
|
|
|
// If it is not, it is moving *out of* fullscreen
|
|
|
|
|
let new_size = if backend::is_fullscreen(&raw) {
|
2019-12-31 14:39:33 -08:00
|
|
|
intended_size = PhysicalSize {
|
2022-12-22 21:35:33 +02:00
|
|
|
width: raw.width(),
|
|
|
|
|
height: raw.height(),
|
2019-10-11 11:45:07 -04:00
|
|
|
};
|
|
|
|
|
|
2020-01-03 14:52:27 -05:00
|
|
|
backend::window_size().to_physical(backend::scale_factor())
|
2019-10-11 11:45:07 -04:00
|
|
|
} else {
|
|
|
|
|
intended_size
|
|
|
|
|
};
|
2019-12-31 14:39:33 -08:00
|
|
|
|
|
|
|
|
backend::set_canvas_size(&raw, Size::Physical(new_size));
|
2019-10-11 11:45:07 -04:00
|
|
|
runner.send_event(Event::WindowEvent {
|
2022-03-18 14:09:39 +01:00
|
|
|
window_id: RootWindowId(id),
|
2019-10-11 11:45:07 -04:00
|
|
|
event: WindowEvent::Resized(new_size),
|
|
|
|
|
});
|
2022-03-18 14:09:39 +01:00
|
|
|
runner.request_redraw(RootWindowId(id));
|
2019-10-11 11:45:07 -04:00
|
|
|
});
|
2020-02-17 20:25:27 +01:00
|
|
|
|
|
|
|
|
let runner = self.runner.clone();
|
|
|
|
|
canvas.on_dark_mode(move |is_dark_mode| {
|
|
|
|
|
let theme = if is_dark_mode {
|
|
|
|
|
Theme::Dark
|
|
|
|
|
} else {
|
|
|
|
|
Theme::Light
|
|
|
|
|
};
|
|
|
|
|
runner.send_event(Event::WindowEvent {
|
2022-03-18 14:09:39 +01:00
|
|
|
window_id: RootWindowId(id),
|
2020-02-17 20:25:27 +01:00
|
|
|
event: WindowEvent::ThemeChanged(theme),
|
|
|
|
|
});
|
|
|
|
|
});
|
2019-06-25 03:15:34 +02:00
|
|
|
}
|
2020-07-04 15:46:41 -04:00
|
|
|
|
2022-03-18 14:09:39 +01:00
|
|
|
pub fn available_monitors(&self) -> VecDequeIter<MonitorHandle> {
|
2020-07-04 15:46:41 -04:00
|
|
|
VecDeque::new().into_iter()
|
|
|
|
|
}
|
|
|
|
|
|
2022-09-21 10:04:28 +02:00
|
|
|
pub fn primary_monitor(&self) -> Option<MonitorHandle> {
|
|
|
|
|
Some(MonitorHandle)
|
2020-07-04 15:46:41 -04:00
|
|
|
}
|
2022-07-21 22:22:36 +03:00
|
|
|
|
|
|
|
|
pub fn raw_display_handle(&self) -> RawDisplayHandle {
|
|
|
|
|
RawDisplayHandle::Web(WebDisplayHandle::empty())
|
|
|
|
|
}
|
2019-06-25 03:15:34 +02:00
|
|
|
}
|