1#![deny(missing_docs)]
6
7use winit::dpi::PhysicalPosition;
8use winit::event::DeviceEvent::MouseMotion;
9use winit::event::ElementState::{Pressed, Released};
10use winit::event::Event::{self, DeviceEvent, WindowEvent};
11use winit::event::KeyboardInput;
12pub use winit::event::MouseButton;
13use winit::event::MouseScrollDelta;
14pub use winit::event::VirtualKeyCode as Key;
15use winit::event::WindowEvent::KeyboardInput as WKeyboardInput;
16use winit::event::WindowEvent::{
17 AxisMotion, CursorMoved, MouseInput, MouseWheel, ReceivedCharacter,
18};
19use winit::window::Window;
20
21pub struct Input {
23 pub mouse_pos: (f32, f32),
25 pub mouse_delta: (f32, f32),
27 pub raw_mouse_delta: (f32, f32),
29 pub mouse_axis_motion: (f32, f32),
31 pub mouse_wheel_delta: (f32, f32),
33 pub keys_down: Vec<Key>,
35 pub keys_pressed: Vec<Key>,
37 pub keys_released: Vec<Key>,
39 pub characters_down: Vec<char>,
41 pub mouse_btns_down: Vec<MouseButton>,
43 pub mouse_btns_pressed: Vec<MouseButton>,
45 pub mouse_btns_released: Vec<MouseButton>,
47 pub hide_mouse: bool,
49}
50
51impl Default for Input {
52 fn default() -> Self {
54 Self::new()
55 }
56}
57
58impl Input {
59 pub fn new() -> Input {
61 Input {
62 mouse_pos: (0f32, 0f32),
63 mouse_delta: (0f32, 0f32),
64 raw_mouse_delta: (0f32, 0f32),
65 mouse_axis_motion: (0f32, 0f32),
66 mouse_wheel_delta: (0f32, 0f32),
67 keys_down: Vec::new(),
68 keys_pressed: Vec::new(),
69 keys_released: Vec::new(),
70 characters_down: Vec::new(),
71 mouse_btns_down: Vec::new(),
72 mouse_btns_pressed: Vec::new(),
73 mouse_btns_released: Vec::new(),
74 hide_mouse: true,
75 }
76 }
77
78 pub fn update_inputs(&mut self, window: &Window, events: &Vec<Event<()>>) {
80 let (width, height): (u32, u32) = window.inner_size().into();
81 let h_width = (width as u32 / 2u32) as f32;
82 let h_height = (height / 2u32) as f32;
83
84 {
86 self.mouse_delta = (0f32, 0f32);
88 self.mouse_wheel_delta = (0f32, 0f32);
89
90 self.keys_pressed.clear();
92 self.keys_released.clear();
93 self.mouse_btns_pressed.clear();
94 self.mouse_btns_released.clear();
95 self.characters_down.clear();
96 }
97
98 let keys_down = &mut self.keys_down;
99 let keys_pressed = &mut self.keys_pressed;
100 let keys_released = &mut self.keys_released;
101 let mouse_delta = &mut self.mouse_delta;
102 let raw_mouse_delta = &mut self.raw_mouse_delta;
103 let mouse_axis_motion = &mut self.mouse_axis_motion;
104 let mouse_pos = &mut self.mouse_pos;
105 let mouse_btns_down = &mut self.mouse_btns_down;
106 let mouse_btns_pressed = &mut self.mouse_btns_pressed;
107 let mouse_btns_released = &mut self.mouse_btns_released;
108 let mouse_wheel_delta = &mut self.mouse_wheel_delta;
109 let characters_down = &mut self.characters_down;
110
111 for event in events {
113 match event {
114 WindowEvent { event, .. } => match event {
115 WKeyboardInput {
116 input:
117 KeyboardInput {
118 state: Pressed,
119 virtual_keycode: vkey,
120 ..
121 },
122 ..
123 } => {
124 if let Some(key) = vkey {
125 keys_down.push(*key);
126 keys_pressed.push(*key);
127 }
128 }
129 WKeyboardInput {
130 input:
131 KeyboardInput {
132 state: Released,
133 virtual_keycode: vkey,
134 ..
135 },
136 ..
137 } => {
138 if let Some(key) = vkey {
139 keys_down.retain(|&k| k != *key);
140 keys_released.push(*key);
141 }
142 }
143 CursorMoved { position: pos, .. } => {
144 let (x, y): (i32, i32) = (*pos).into();
145 mouse_delta.0 = (h_width - x as f32) / width as f32;
146 mouse_delta.1 = (h_height - y as f32) / height as f32;
147 (*mouse_pos) = (x as f32, y as f32);
148 }
149 AxisMotion { axis, value, .. } => match axis {
150 0 => mouse_axis_motion.0 = *value as f32,
151 1 => mouse_axis_motion.1 = *value as f32,
152 _ => {}
153 },
154 MouseInput {
155 state: Pressed,
156 button: btn,
157 ..
158 } => {
159 mouse_btns_down.push(*btn);
160 mouse_btns_pressed.push(*btn);
161 }
162 MouseInput {
163 state: Released,
164 button: btn,
165 ..
166 } => {
167 mouse_btns_down.retain(|&mb| mb != *btn);
168 mouse_btns_released.push(*btn);
169 }
170 MouseWheel { delta, .. } => {
171 (*mouse_wheel_delta) = match delta {
172 MouseScrollDelta::LineDelta(x, y) => (*x, *y),
173 MouseScrollDelta::PixelDelta(pos) => {
174 let (x, y): (i32, i32) = (*pos).into();
175 (x as f32, y as f32)
176 }
177 };
178 }
179 ReceivedCharacter(c) => characters_down.push(*c),
180 _ => (),
181 },
182 DeviceEvent { event, .. } => {
183 if let MouseMotion { delta } = event {
184 (*raw_mouse_delta) = (delta.0 as f32, delta.1 as f32);
185 }
186 }
187 _ => (),
188 }
189 }
190
191 if self.hide_mouse {
192 window.set_cursor_visible(false);
193 window.set_cursor_grab(true).unwrap();
194 let _ = window.set_cursor_position(PhysicalPosition::new(h_width, h_height));
195 } else {
196 window.set_cursor_visible(true);
197 window.set_cursor_grab(false).unwrap();
198 }
199 }
200}