mod event;
mod wheel_movement;
pub use crate::graphics::window::winit::event::MouseButton as Button;
pub use event::Event;
pub use wheel_movement::WheelMovement;
use super::{ButtonState, Event as InputEvent, Input};
use crate::graphics::Point;
use std::collections::{HashMap, HashSet};
#[derive(Debug, Clone)]
pub struct Mouse {
cursor_position: Point,
wheel_movement: WheelMovement,
is_cursor_taken: bool,
is_cursor_within_window: bool,
button_clicks: HashMap<Button, Vec<Point>>,
pressed_buttons: HashSet<Button>,
}
impl Mouse {
pub fn cursor_position(&self) -> Point {
self.cursor_position
}
pub fn wheel_movement(&self) -> WheelMovement {
self.wheel_movement
}
pub fn is_cursor_taken(&self) -> bool {
self.is_cursor_taken
}
pub fn is_cursor_within_window(&self) -> bool {
self.is_cursor_within_window
}
pub fn is_button_pressed(&self, button: Button) -> bool {
self.pressed_buttons.contains(&button)
}
pub fn button_clicks(&self, button: Button) -> &[Point] {
self.button_clicks
.get(&button)
.map(|v| &v[..])
.unwrap_or(&[])
}
}
impl Input for Mouse {
fn new() -> Mouse {
Mouse {
cursor_position: Point::new(0.0, 0.0),
wheel_movement: WheelMovement::new(0.0, 0.0),
is_cursor_taken: false,
is_cursor_within_window: false,
button_clicks: HashMap::new(),
pressed_buttons: HashSet::new(),
}
}
fn update(&mut self, event: InputEvent) {
match event {
InputEvent::Mouse(mouse_event) => match mouse_event {
Event::CursorMoved { x, y } => {
self.cursor_position = Point::new(x, y);
}
Event::CursorTaken => {
self.is_cursor_taken = true;
}
Event::CursorReturned => {
self.is_cursor_taken = false;
}
Event::Input { state, button } => {
match state {
ButtonState::Pressed => {
if !self.is_cursor_taken {
let _ = self.pressed_buttons.insert(button);
}
}
ButtonState::Released => {
if !self.is_cursor_taken
&& self.is_button_pressed(button)
{
self.button_clicks
.entry(button)
.or_insert_with(Vec::new)
.push(self.cursor_position);
}
let _ = self.pressed_buttons.remove(&button);
}
};
}
Event::CursorEntered => {
self.is_cursor_within_window = true;
}
Event::CursorLeft => {
self.is_cursor_within_window = false;
}
Event::WheelScrolled { delta_x, delta_y } => {
self.wheel_movement.horizontal += delta_x;
self.wheel_movement.vertical += delta_y;
}
},
InputEvent::Keyboard { .. } => {
}
InputEvent::Gamepad { .. } => {
}
InputEvent::Window { .. } => {
}
}
}
fn clear(&mut self) {
self.button_clicks.values_mut().for_each(Vec::clear);
self.wheel_movement.horizontal = 0.0;
self.wheel_movement.vertical = 0.0;
}
}