1use oxide_ecs::Resource;
2use winit::dpi::PhysicalPosition;
3
4#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
5pub enum MouseButton {
6 Left,
7 Right,
8 Middle,
9 Other(u16),
10}
11
12impl From<winit::event::MouseButton> for MouseButton {
13 fn from(button: winit::event::MouseButton) -> Self {
14 match button {
15 winit::event::MouseButton::Left => MouseButton::Left,
16 winit::event::MouseButton::Right => MouseButton::Right,
17 winit::event::MouseButton::Middle => MouseButton::Middle,
18 winit::event::MouseButton::Other(v) => MouseButton::Other(v),
19 _ => MouseButton::Other(0),
20 }
21 }
22}
23
24#[derive(Debug, Clone, Copy, Default)]
25pub struct MouseDelta {
26 pub x: f64,
27 pub y: f64,
28}
29
30#[derive(Resource, Default)]
31pub struct MouseInput {
32 pub position: Option<PhysicalPosition<f64>>,
33 pub delta: MouseDelta,
34 pub left_pressed: bool,
35 pub right_pressed: bool,
36 pub middle_pressed: bool,
37 cursor_grabbed: bool,
38}
39
40impl MouseInput {
41 pub fn update(&mut self) {
42 self.delta = MouseDelta::default();
43 }
44
45 pub fn process_move(&mut self, position: PhysicalPosition<f64>) {
46 if let Some(old) = self.position {
47 self.delta.x += position.x - old.x;
48 self.delta.y += position.y - old.y;
49 }
50 self.position = Some(position);
51 }
52
53 pub fn process_button(&mut self, button: MouseButton, pressed: bool) {
54 match button {
55 MouseButton::Left => self.left_pressed = pressed,
56 MouseButton::Right => self.right_pressed = pressed,
57 MouseButton::Middle => self.middle_pressed = pressed,
58 _ => {}
59 }
60 }
61
62 pub fn set_position(&mut self, position: PhysicalPosition<f64>) {
63 self.position = Some(position);
64 self.delta = MouseDelta::default();
65 }
66
67 pub fn delta(&self) -> (f32, f32) {
68 (self.delta.x as f32, self.delta.y as f32)
69 }
70
71 pub fn set_cursor_grabbed(&mut self, grabbed: bool) {
72 self.cursor_grabbed = grabbed;
73 }
74
75 pub fn cursor_grabbed(&self) -> bool {
76 self.cursor_grabbed
77 }
78}