Add winit events handler
This commit is contained in:
parent
b53ff34aab
commit
d3a454ad72
|
@ -71,6 +71,7 @@ pub struct WinitGraphicsBackend {
|
||||||
/// You need to call `dispatch_new_events` periodically to receive any events.
|
/// You need to call `dispatch_new_events` periodically to receive any events.
|
||||||
pub struct WinitInputBackend {
|
pub struct WinitInputBackend {
|
||||||
events_loop: EventsLoop,
|
events_loop: EventsLoop,
|
||||||
|
events_handler: Option<Box<WinitEventsHandler>>,
|
||||||
window: Rc<Window>,
|
window: Rc<Window>,
|
||||||
time_counter: u32,
|
time_counter: u32,
|
||||||
key_counter: u32,
|
key_counter: u32,
|
||||||
|
@ -160,6 +161,7 @@ where
|
||||||
},
|
},
|
||||||
WinitInputBackend {
|
WinitInputBackend {
|
||||||
events_loop,
|
events_loop,
|
||||||
|
events_handler: None,
|
||||||
window,
|
window,
|
||||||
time_counter: 0,
|
time_counter: 0,
|
||||||
key_counter: 0,
|
key_counter: 0,
|
||||||
|
@ -178,6 +180,20 @@ where
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Handler trait to recieve window-related events to provide a better *nested* experience.
|
||||||
|
pub trait WinitEventsHandler {
|
||||||
|
/// The window was resized, can be used to adjust the associated `wayland::output::Output`s mode.
|
||||||
|
fn resized(&mut self, evlh: &mut EventLoopHandle, width: u32, height: u32);
|
||||||
|
/// The window was moved
|
||||||
|
fn moved(&mut self, evlh: &mut EventLoopHandle, x: i32, h: i32);
|
||||||
|
/// The window gained or lost focus
|
||||||
|
fn focus_changed(&mut self, evlh: &mut EventLoopHandle, focused: bool);
|
||||||
|
/// The window needs to be redrawn
|
||||||
|
fn refresh(&mut self, evlh: &mut EventLoopHandle);
|
||||||
|
/// The window's hidpi factor changed
|
||||||
|
fn hidpi_changed(&mut self, evlh: &mut EventLoopHandle, scale: f32);
|
||||||
|
}
|
||||||
|
|
||||||
impl WinitGraphicsBackend {
|
impl WinitGraphicsBackend {
|
||||||
/// Get a reference to the internally used `winit::Window`
|
/// Get a reference to the internally used `winit::Window`
|
||||||
pub fn winit_window(&self) -> &WinitWindow {
|
pub fn winit_window(&self) -> &WinitWindow {
|
||||||
|
@ -565,6 +581,27 @@ impl TouchCancelEvent for WinitTouchCancelledEvent {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl WinitInputBackend {
|
||||||
|
/// Set the events handler
|
||||||
|
pub fn set_events_handler<H: WinitEventsHandler + 'static>(&mut self, handler: H) {
|
||||||
|
self.events_handler = Some(Box::new(handler));
|
||||||
|
info!(self.logger, "New events handler set.");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get a reference to the set events handler, if any
|
||||||
|
pub fn get_events_handler(&mut self) -> Option<&mut WinitEventsHandler> {
|
||||||
|
self.events_handler
|
||||||
|
.as_mut()
|
||||||
|
.map(|handler| &mut **handler as &mut WinitEventsHandler)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Clear out the currently set events handler
|
||||||
|
pub fn clear_events_handler(&mut self) {
|
||||||
|
self.events_handler = None;
|
||||||
|
info!(self.logger, "Events handler unset.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl InputBackend for WinitInputBackend {
|
impl InputBackend for WinitInputBackend {
|
||||||
type InputConfig = ();
|
type InputConfig = ();
|
||||||
type EventError = WinitInputError;
|
type EventError = WinitInputError;
|
||||||
|
@ -641,20 +678,34 @@ impl InputBackend for WinitInputBackend {
|
||||||
let seat = &self.seat;
|
let seat = &self.seat;
|
||||||
let window = &self.window;
|
let window = &self.window;
|
||||||
let mut handler = self.handler.as_mut();
|
let mut handler = self.handler.as_mut();
|
||||||
|
let mut events_handler = self.events_handler.as_mut();
|
||||||
let logger = &self.logger;
|
let logger = &self.logger;
|
||||||
|
|
||||||
self.events_loop.poll_events(move |event| {
|
self.events_loop.poll_events(move |event| {
|
||||||
if let Event::WindowEvent { event, .. } = event {
|
if let Event::WindowEvent { event, .. } = event {
|
||||||
match (event, handler.as_mut()) {
|
match (event, handler.as_mut(), events_handler.as_mut()) {
|
||||||
(WindowEvent::Resized(x, y), _) => {
|
(WindowEvent::Resized(w, h), _, events_handler) => {
|
||||||
trace!(logger, "Resizing window to {:?}", (x, y));
|
trace!(logger, "Resizing window to {:?}", (w, h));
|
||||||
window.window().set_inner_size(x, y);
|
window.window().set_inner_size(w, h);
|
||||||
match **window {
|
match **window {
|
||||||
Window::Wayland { ref surface, .. } => {
|
Window::Wayland { ref surface, .. } => {
|
||||||
surface.resize(x as i32, y as i32, 0, 0)
|
surface.resize(w as i32, h as i32, 0, 0)
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
};
|
};
|
||||||
|
if let Some(events_handler) = events_handler {
|
||||||
|
events_handler.resized(evlh, w, h);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
(WindowEvent::Moved(x, y), _, Some(events_handler)) => {
|
||||||
|
events_handler.moved(evlh, x, y)
|
||||||
|
}
|
||||||
|
(WindowEvent::Focused(focus), _, Some(events_handler)) => {
|
||||||
|
events_handler.focus_changed(evlh, focus)
|
||||||
|
}
|
||||||
|
(WindowEvent::Refresh, _, Some(events_handler)) => events_handler.refresh(evlh),
|
||||||
|
(WindowEvent::HiDPIFactorChanged(factor), _, Some(events_handler)) => {
|
||||||
|
events_handler.hidpi_changed(evlh, factor)
|
||||||
}
|
}
|
||||||
(
|
(
|
||||||
WindowEvent::KeyboardInput {
|
WindowEvent::KeyboardInput {
|
||||||
|
@ -665,6 +716,7 @@ impl InputBackend for WinitInputBackend {
|
||||||
..
|
..
|
||||||
},
|
},
|
||||||
Some(handler),
|
Some(handler),
|
||||||
|
_,
|
||||||
) => {
|
) => {
|
||||||
match state {
|
match state {
|
||||||
ElementState::Pressed => *key_counter += 1,
|
ElementState::Pressed => *key_counter += 1,
|
||||||
|
@ -693,6 +745,7 @@ impl InputBackend for WinitInputBackend {
|
||||||
position: (x, y), ..
|
position: (x, y), ..
|
||||||
},
|
},
|
||||||
Some(handler),
|
Some(handler),
|
||||||
|
_,
|
||||||
) => {
|
) => {
|
||||||
trace!(logger, "Calling on_pointer_move_absolute with {:?}", (x, y));
|
trace!(logger, "Calling on_pointer_move_absolute with {:?}", (x, y));
|
||||||
handler.on_pointer_move_absolute(
|
handler.on_pointer_move_absolute(
|
||||||
|
@ -706,7 +759,7 @@ impl InputBackend for WinitInputBackend {
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
(WindowEvent::MouseWheel { delta, .. }, Some(handler)) => match delta {
|
(WindowEvent::MouseWheel { delta, .. }, Some(handler), _) => match delta {
|
||||||
MouseScrollDelta::LineDelta(x, y) | MouseScrollDelta::PixelDelta(x, y) => {
|
MouseScrollDelta::LineDelta(x, y) | MouseScrollDelta::PixelDelta(x, y) => {
|
||||||
if x != 0.0 {
|
if x != 0.0 {
|
||||||
let event = WinitMouseWheelEvent {
|
let event = WinitMouseWheelEvent {
|
||||||
|
@ -736,7 +789,7 @@ impl InputBackend for WinitInputBackend {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
(WindowEvent::MouseInput { state, button, .. }, Some(handler)) => {
|
(WindowEvent::MouseInput { state, button, .. }, Some(handler), _) => {
|
||||||
trace!(
|
trace!(
|
||||||
logger,
|
logger,
|
||||||
"Calling on_pointer_button with {:?}",
|
"Calling on_pointer_button with {:?}",
|
||||||
|
@ -760,6 +813,7 @@ impl InputBackend for WinitInputBackend {
|
||||||
..
|
..
|
||||||
}),
|
}),
|
||||||
Some(handler),
|
Some(handler),
|
||||||
|
_,
|
||||||
) => {
|
) => {
|
||||||
trace!(logger, "Calling on_touch_down at {:?}", (x, y));
|
trace!(logger, "Calling on_touch_down at {:?}", (x, y));
|
||||||
handler.on_touch_down(
|
handler.on_touch_down(
|
||||||
|
@ -781,6 +835,7 @@ impl InputBackend for WinitInputBackend {
|
||||||
..
|
..
|
||||||
}),
|
}),
|
||||||
Some(handler),
|
Some(handler),
|
||||||
|
_,
|
||||||
) => {
|
) => {
|
||||||
trace!(logger, "Calling on_touch_motion at {:?}", (x, y));
|
trace!(logger, "Calling on_touch_motion at {:?}", (x, y));
|
||||||
handler.on_touch_motion(
|
handler.on_touch_motion(
|
||||||
|
@ -802,6 +857,7 @@ impl InputBackend for WinitInputBackend {
|
||||||
..
|
..
|
||||||
}),
|
}),
|
||||||
Some(handler),
|
Some(handler),
|
||||||
|
_,
|
||||||
) => {
|
) => {
|
||||||
trace!(logger, "Calling on_touch_motion at {:?}", (x, y));
|
trace!(logger, "Calling on_touch_motion at {:?}", (x, y));
|
||||||
handler.on_touch_motion(
|
handler.on_touch_motion(
|
||||||
|
@ -831,6 +887,7 @@ impl InputBackend for WinitInputBackend {
|
||||||
..
|
..
|
||||||
}),
|
}),
|
||||||
Some(handler),
|
Some(handler),
|
||||||
|
_,
|
||||||
) => {
|
) => {
|
||||||
trace!(logger, "Calling on_touch_cancel");
|
trace!(logger, "Calling on_touch_cancel");
|
||||||
handler.on_touch_cancel(
|
handler.on_touch_cancel(
|
||||||
|
@ -842,7 +899,7 @@ impl InputBackend for WinitInputBackend {
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
(WindowEvent::Closed, _) => {
|
(WindowEvent::Closed, _, _) => {
|
||||||
warn!(logger, "Window closed");
|
warn!(logger, "Window closed");
|
||||||
*closed_ptr = true;
|
*closed_ptr = true;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue