Merge pull request #65 from Smithay/feature/winit_handler

Winit handler
This commit is contained in:
Victor Brekenfeld 2018-02-19 11:16:38 +01:00 committed by GitHub
commit 00329824d2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 72 additions and 8 deletions

View File

@ -71,6 +71,7 @@ pub struct WinitGraphicsBackend {
/// You need to call `dispatch_new_events` periodically to receive any events.
pub struct WinitInputBackend {
events_loop: EventsLoop,
events_handler: Option<Box<WinitEventsHandler>>,
window: Rc<Window>,
time_counter: u32,
key_counter: u32,
@ -160,6 +161,7 @@ where
},
WinitInputBackend {
events_loop,
events_handler: None,
window,
time_counter: 0,
key_counter: 0,
@ -178,6 +180,27 @@ 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 {
/// Get a reference to the internally used `winit::Window`
pub fn winit_window(&self) -> &WinitWindow {
self.window.window()
}
}
impl GraphicsBackend for WinitGraphicsBackend {
type CursorFormat = MouseCursor;
type Error = ();
@ -558,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 {
type InputConfig = ();
type EventError = WinitInputError;
@ -634,20 +678,34 @@ impl InputBackend for WinitInputBackend {
let seat = &self.seat;
let window = &self.window;
let mut handler = self.handler.as_mut();
let mut events_handler = self.events_handler.as_mut();
let logger = &self.logger;
self.events_loop.poll_events(move |event| {
if let Event::WindowEvent { event, .. } = event {
match (event, handler.as_mut()) {
(WindowEvent::Resized(x, y), _) => {
trace!(logger, "Resizing window to {:?}", (x, y));
window.window().set_inner_size(x, y);
match (event, handler.as_mut(), events_handler.as_mut()) {
(WindowEvent::Resized(w, h), _, events_handler) => {
trace!(logger, "Resizing window to {:?}", (w, h));
window.window().set_inner_size(w, h);
match **window {
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 {
@ -658,6 +716,7 @@ impl InputBackend for WinitInputBackend {
..
},
Some(handler),
_,
) => {
match state {
ElementState::Pressed => *key_counter += 1,
@ -686,6 +745,7 @@ impl InputBackend for WinitInputBackend {
position: (x, y), ..
},
Some(handler),
_,
) => {
trace!(logger, "Calling on_pointer_move_absolute with {:?}", (x, y));
handler.on_pointer_move_absolute(
@ -699,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) => {
if x != 0.0 {
let event = WinitMouseWheelEvent {
@ -729,7 +789,7 @@ impl InputBackend for WinitInputBackend {
}
}
},
(WindowEvent::MouseInput { state, button, .. }, Some(handler)) => {
(WindowEvent::MouseInput { state, button, .. }, Some(handler), _) => {
trace!(
logger,
"Calling on_pointer_button with {:?}",
@ -753,6 +813,7 @@ impl InputBackend for WinitInputBackend {
..
}),
Some(handler),
_,
) => {
trace!(logger, "Calling on_touch_down at {:?}", (x, y));
handler.on_touch_down(
@ -774,6 +835,7 @@ impl InputBackend for WinitInputBackend {
..
}),
Some(handler),
_,
) => {
trace!(logger, "Calling on_touch_motion at {:?}", (x, y));
handler.on_touch_motion(
@ -795,6 +857,7 @@ impl InputBackend for WinitInputBackend {
..
}),
Some(handler),
_,
) => {
trace!(logger, "Calling on_touch_motion at {:?}", (x, y));
handler.on_touch_motion(
@ -824,6 +887,7 @@ impl InputBackend for WinitInputBackend {
..
}),
Some(handler),
_,
) => {
trace!(logger, "Calling on_touch_cancel");
handler.on_touch_cancel(
@ -835,7 +899,7 @@ impl InputBackend for WinitInputBackend {
},
)
}
(WindowEvent::Closed, _) => {
(WindowEvent::Closed, _, _) => {
warn!(logger, "Window closed");
*closed_ptr = true;
}