use crate::viewport::Viewport;
pub use winit::event::{ElementState, MouseButton};
pub use winit::keyboard::KeyCode;
#[derive(Clone, Debug)]
pub enum InputEvent {
MouseButton {
button: MouseButton,
state: ElementState,
screen_x: f32,
screen_y: f32,
scene_x: f32,
scene_y: f32,
},
MouseMove {
screen_x: f32,
screen_y: f32,
scene_x: f32,
scene_y: f32,
},
KeyboardKey {
key: KeyCode,
state: ElementState,
},
Scroll {
delta_x: f32,
delta_y: f32,
},
ModifiersChanged {
alt: bool,
ctrl: bool,
shift: bool,
super_key: bool,
},
}
pub struct InputQueue {
events: Vec<InputEvent>,
}
impl Default for InputQueue {
fn default() -> Self {
Self::new()
}
}
impl InputQueue {
pub fn new() -> Self {
Self { events: Vec::new() }
}
pub fn push(&mut self, event: InputEvent) {
self.events.push(event);
}
pub fn drain(&mut self) -> Vec<InputEvent> {
std::mem::take(&mut self.events)
}
}
pub fn convert_window_event(
event: &winit::event::WindowEvent,
viewport: &Viewport,
window_width: f32,
window_height: f32,
last_cursor_pos: &mut (f32, f32),
) -> Option<InputEvent> {
match event {
winit::event::WindowEvent::MouseInput { state, button, .. } => {
let (scene_x, scene_y) = viewport.window_to_scene(
last_cursor_pos.0, last_cursor_pos.1, window_width, window_height,
);
Some(InputEvent::MouseButton {
button: *button, state: *state,
screen_x: last_cursor_pos.0, screen_y: last_cursor_pos.1,
scene_x, scene_y,
})
}
winit::event::WindowEvent::CursorMoved { position, .. } => {
last_cursor_pos.0 = position.x as f32;
last_cursor_pos.1 = position.y as f32;
let (scene_x, scene_y) = viewport.window_to_scene(
position.x as f32, position.y as f32, window_width, window_height,
);
Some(InputEvent::MouseMove {
screen_x: position.x as f32, screen_y: position.y as f32,
scene_x, scene_y,
})
}
winit::event::WindowEvent::KeyboardInput { event, .. } => {
if let winit::keyboard::PhysicalKey::Code(key_code) = event.physical_key {
Some(InputEvent::KeyboardKey { key: key_code, state: event.state })
} else {
None
}
}
winit::event::WindowEvent::MouseWheel { delta, .. } => {
let (dx, dy) = match delta {
winit::event::MouseScrollDelta::LineDelta(x, y) => (*x, *y),
winit::event::MouseScrollDelta::PixelDelta(pos) => {
const PIXELS_PER_LINE: f32 = 20.0;
(pos.x as f32 / PIXELS_PER_LINE, pos.y as f32 / PIXELS_PER_LINE)
}
};
Some(InputEvent::Scroll { delta_x: dx, delta_y: dy })
}
winit::event::WindowEvent::ModifiersChanged(modifiers) => {
let state = modifiers.state();
Some(InputEvent::ModifiersChanged {
alt: state.alt_key(), ctrl: state.control_key(),
shift: state.shift_key(), super_key: state.super_key(),
})
}
_ => None,
}
}