use crate::math::Position;
use std::collections::HashSet;
use winit::event::{ElementState, MouseButton, WindowEvent};
use winit::keyboard::{KeyCode, PhysicalKey};
#[derive(Debug, Default)]
pub struct Input {
keys_pressed: HashSet<KeyCode>,
keys_just_pressed: HashSet<KeyCode>,
keys_just_released: HashSet<KeyCode>,
mouse_position: Position,
mouse_buttons_pressed: HashSet<MouseButton>,
mouse_buttons_just_pressed: HashSet<MouseButton>,
mouse_buttons_just_released: HashSet<MouseButton>,
}
impl Input {
pub fn new() -> Self {
Self::default()
}
pub fn new_frame(&mut self) {
self.keys_just_pressed.clear();
self.keys_just_released.clear();
self.mouse_buttons_just_pressed.clear();
self.mouse_buttons_just_released.clear();
}
pub fn handle_event(&mut self, event: &WindowEvent) {
match event {
WindowEvent::KeyboardInput { event, .. } => {
if let PhysicalKey::Code(keycode) = event.physical_key {
match event.state {
ElementState::Pressed => {
if !self.keys_pressed.contains(&keycode) {
self.keys_just_pressed.insert(keycode);
}
self.keys_pressed.insert(keycode);
}
ElementState::Released => {
self.keys_pressed.remove(&keycode);
self.keys_just_released.insert(keycode);
}
}
}
}
WindowEvent::MouseInput { state, button, .. } => {
match state {
ElementState::Pressed => {
if !self.mouse_buttons_pressed.contains(button) {
self.mouse_buttons_just_pressed.insert(*button);
}
self.mouse_buttons_pressed.insert(*button);
}
ElementState::Released => {
self.mouse_buttons_pressed.remove(button);
self.mouse_buttons_just_released.insert(*button);
}
}
}
WindowEvent::CursorMoved { position, .. } => {
self.mouse_position = Position::new(position.x as f32, position.y as f32);
}
_ => {}
}
}
pub fn is_key_pressed(&self, keycode: KeyCode) -> bool {
self.keys_pressed.contains(&keycode)
}
pub fn is_key_just_pressed(&self, keycode: KeyCode) -> bool {
self.keys_just_pressed.contains(&keycode)
}
pub fn is_key_just_released(&self, keycode: KeyCode) -> bool {
self.keys_just_released.contains(&keycode)
}
pub fn mouse_position(&self) -> Position {
self.mouse_position
}
pub fn is_mouse_button_pressed(&self, button: MouseButton) -> bool {
self.mouse_buttons_pressed.contains(&button)
}
pub fn is_mouse_button_just_pressed(&self, button: MouseButton) -> bool {
self.mouse_buttons_just_pressed.contains(&button)
}
pub fn is_mouse_button_just_released(&self, button: MouseButton) -> bool {
self.mouse_buttons_just_released.contains(&button)
}
pub fn is_arrow_key_pressed(&self, direction: ArrowKey) -> bool {
let keycode = match direction {
ArrowKey::Up => KeyCode::ArrowUp,
ArrowKey::Down => KeyCode::ArrowDown,
ArrowKey::Left => KeyCode::ArrowLeft,
ArrowKey::Right => KeyCode::ArrowRight,
};
self.is_key_pressed(keycode)
}
pub fn is_wasd_pressed(&self, direction: ArrowKey) -> bool {
let keycode = match direction {
ArrowKey::Up => KeyCode::KeyW,
ArrowKey::Down => KeyCode::KeyS,
ArrowKey::Left => KeyCode::KeyA,
ArrowKey::Right => KeyCode::KeyD,
};
self.is_key_pressed(keycode)
}
}
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum ArrowKey {
Up,
Down,
Left,
Right,
}