bottomless_pit/
input.rs

1//! Contains Both the MouseKey and Key Enums for input
2//! ```rust,no_run
3//! impl Game For Struct {
4//!     fn update(&mut self, engine_handle: &mut Engine) {
5//!         if engine_handle.is_key_down(Key::W) {
6//!             // do something
7//!         }
8//!
9//!         if engine.check_modifiers(ModifierKeys::Ctrl) && engine.is_key_pressed(Key::S) {
10//!             // wow ctrl + s better save
11//!         }
12//!
13//!         if engine_handle.is_mouse_key_down(MouseKey::Left) {
14//!             // do more things
15//!         }
16//!     }
17//! }
18
19const INPUT_MAP_SIZE: usize = 112;
20
21use winit::event::{ElementState, KeyEvent, Modifiers, MouseButton, WindowEvent};
22use winit::keyboard::{KeyCode, ModifiersState, PhysicalKey};
23
24use crate::vectors::Vec2;
25
26pub(crate) struct InputHandle {
27    previous_keyboard_state: [bool; INPUT_MAP_SIZE],
28    current_keyboard_state: [bool; INPUT_MAP_SIZE],
29    modifier_state: ModifiersState,
30    previous_mouse_state: [bool; 6],
31    current_mouse_state: [bool; 6],
32    current_text: Option<String>,
33    mouse_position: Vec2<f32>,
34    mouse_delta: Vec2<f32>,
35}
36
37impl InputHandle {
38    pub(crate) fn new() -> Self {
39        Self {
40            previous_keyboard_state: [false; INPUT_MAP_SIZE],
41            current_keyboard_state: [false; INPUT_MAP_SIZE],
42            modifier_state: ModifiersState::empty(),
43            previous_mouse_state: [false; 6],
44            current_mouse_state: [false; 6],
45            current_text: None,
46            mouse_position: Vec2 { x: 0.0, y: 0.0 },
47            mouse_delta: Vec2 { x: 0.0, y: 0.0 },
48        }
49    }
50
51    pub(crate) fn end_of_frame_refresh(&mut self) {
52        self.previous_keyboard_state = self.current_keyboard_state;
53        self.previous_mouse_state = self.current_mouse_state;
54        self.current_text = None;
55        self.mouse_delta = Vec2 { x: 0.0, y: 0.0 };
56    }
57
58    pub(crate) fn process_input(&mut self, event: &WindowEvent) -> bool {
59        match event {
60            WindowEvent::KeyboardInput {
61                event: key_event, ..
62            } => self.process_keyboard_input(key_event),
63            WindowEvent::MouseInput { state, button, .. } => {
64                self.process_mouse_input(*state, *button)
65            }
66            WindowEvent::CursorMoved { position, .. } => {
67                let pos = Vec2 {
68                    x: position.x as f32,
69                    y: position.y as f32,
70                };
71                self.mouse_delta += pos - self.mouse_position;
72
73                self.mouse_position = pos;
74                true
75            }
76            WindowEvent::ModifiersChanged(m) => self.process_modifiers(m),
77            _ => false,
78        }
79    }
80
81    fn process_mouse_input(&mut self, state: ElementState, button: MouseButton) -> bool {
82        let key_bool = state == ElementState::Pressed;
83        let key: MouseKey = button.into();
84        let idx: usize = key as usize;
85
86        self.current_mouse_state[idx] = key_bool;
87        true
88    }
89
90    fn process_keyboard_input(&mut self, event: &KeyEvent) -> bool {
91        let key_bool = event.state == ElementState::Pressed;
92        let key_code = match event.physical_key {
93            PhysicalKey::Code(c) => c,
94            PhysicalKey::Unidentified(_) => return false,
95        };
96
97        if key_bool {
98            self.current_text = event.text.as_ref().map(|s| s.to_string());
99        }
100
101        let key: Key = key_code.into();
102
103        if key == Key::Unrecognized {
104            return false;
105        }
106
107        let index = key as usize;
108        self.current_keyboard_state[index] = key_bool;
109        true
110    }
111
112    fn process_modifiers(&mut self, modifier: &Modifiers) -> bool {
113        self.modifier_state = modifier.state();
114
115        true
116    }
117
118    pub(crate) fn is_key_down(&self, key: Key) -> bool {
119        let index = key as usize;
120        self.current_keyboard_state[index]
121    }
122
123    pub(crate) fn is_key_up(&self, key: Key) -> bool {
124        let index = key as usize;
125        !self.current_keyboard_state[index]
126    }
127
128    pub(crate) fn is_key_pressed(&self, key: Key) -> bool {
129        let index = key as usize;
130        !self.previous_keyboard_state[index] && self.current_keyboard_state[index]
131    }
132
133    pub(crate) fn is_key_released(&self, key: Key) -> bool {
134        let index = key as usize;
135        self.previous_keyboard_state[index] && !self.current_keyboard_state[index]
136    }
137
138    pub(crate) fn is_mouse_key_down(&self, key: MouseKey) -> bool {
139        let index = key as usize;
140        self.current_mouse_state[index]
141    }
142
143    pub(crate) fn get_text_value(&self) -> Option<&str> {
144        self.current_text.as_deref()
145    }
146
147    pub(crate) fn check_modifiers(&self, modifer: ModifierKeys) -> bool {
148        let state: ModifiersState = modifer.into();
149
150        self.modifier_state.intersects(state)
151    }
152
153    pub(crate) fn is_mouse_key_up(&self, key: MouseKey) -> bool {
154        let index = key as usize;
155        !self.current_keyboard_state[index]
156    }
157
158    pub(crate) fn is_mouse_key_pressed(&self, key: MouseKey) -> bool {
159        let index = key as usize;
160        !self.previous_mouse_state[index] && self.current_mouse_state[index]
161    }
162
163    pub(crate) fn is_mouse_key_released(&self, key: MouseKey) -> bool {
164        let index = key as usize;
165        self.previous_mouse_state[index] && !self.current_mouse_state[index]
166    }
167
168    pub(crate) fn get_mouse_position(&self) -> Vec2<f32> {
169        self.mouse_position
170    }
171
172    pub(crate) fn get_mouse_delta(&self) -> Vec2<f32> {
173        self.mouse_delta
174    }
175}
176
177/// Representation of mouse buttons
178#[repr(u8)]
179#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
180pub enum MouseKey {
181    Left,
182    Right,
183    Middle,
184    Back,
185    Fowrawrds,
186    Other,
187}
188
189impl From<MouseButton> for MouseKey {
190    fn from(val: MouseButton) -> Self {
191        match val {
192            MouseButton::Left => MouseKey::Left,
193            MouseButton::Right => MouseKey::Right,
194            MouseButton::Middle => MouseKey::Middle,
195            MouseButton::Forward => MouseKey::Fowrawrds,
196            MouseButton::Back => MouseKey::Back,
197            MouseButton::Other(_) => MouseKey::Other,
198        }
199    }
200}
201
202/// Representation of keyboard keys
203#[repr(u8)]
204#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
205pub enum Key {
206    Key1,
207    Key2,
208    Key3,
209    Key4,
210    Key5,
211    Key6,
212    Key7,
213    Key8,
214    Key9,
215    Key0,
216    A,
217    B,
218    C,
219    D,
220    E,
221    F,
222    G,
223    H,
224    I,
225    J,
226    K,
227    L,
228    M,
229    N,
230    O,
231    P,
232    Q,
233    R,
234    S,
235    T,
236    U,
237    V,
238    W,
239    X,
240    Y,
241    Z,
242    Esc,
243    F1,
244    F2,
245    F3,
246    F4,
247    F5,
248    F6,
249    F7,
250    F8,
251    F9,
252    F10,
253    F11,
254    F12,
255    F13,
256    F14,
257    F15,
258    F16,
259    F17,
260    F18,
261    F19,
262    F20,
263    F21,
264    F22,
265    F23,
266    F24,
267    ScrollLock,
268    Home,
269    Delete,
270    End,
271    PageDown,
272    PageUp,
273    Left,
274    Up,
275    Right,
276    Down,
277    BackSpace,
278    Enter,
279    Space,
280    Numlock,
281    Numpad0,
282    Numpad1,
283    Numpad2,
284    Numpad3,
285    Numpad4,
286    Numpad5,
287    Numpad6,
288    Numpad7,
289    Numpad8,
290    Numpad9,
291    NumpadAdd,
292    NumpadDivide,
293    NumpadDecimial,
294    NumpadComma,
295    NumpadEnter,
296    NumpadEquals,
297    NumpadMultiply,
298    NumpadSubtract,
299    BackSlash,
300    CapsLock,
301    Comma,
302    Equals,
303    LeftAlt,
304    LeftBracket,
305    LeftControl,
306    LeftShift,
307    Minus,
308    Period,
309    Plus,
310    RightAlt,
311    RightBracket,
312    RightControl,
313    RightShift,
314    SemiColon,
315    Slash,
316    Tab,
317    BackQoute,
318    Unrecognized,
319}
320
321impl From<KeyCode> for Key {
322    fn from(val: KeyCode) -> Self {
323        match val {
324            KeyCode::Digit0 => Key::Key0,
325            KeyCode::Digit1 => Key::Key1,
326            KeyCode::Digit2 => Key::Key2,
327            KeyCode::Digit3 => Key::Key3,
328            KeyCode::Digit4 => Key::Key4,
329            KeyCode::Digit5 => Key::Key5,
330            KeyCode::Digit6 => Key::Key6,
331            KeyCode::Digit7 => Key::Key7,
332            KeyCode::Digit8 => Key::Key8,
333            KeyCode::Digit9 => Key::Key9,
334            KeyCode::Equal => Key::Equals,
335            KeyCode::KeyA => Key::A,
336            KeyCode::KeyB => Key::B,
337            KeyCode::KeyC => Key::C,
338            KeyCode::KeyD => Key::D,
339            KeyCode::KeyE => Key::E,
340            KeyCode::KeyF => Key::F,
341            KeyCode::KeyG => Key::G,
342            KeyCode::KeyH => Key::H,
343            KeyCode::KeyI => Key::I,
344            KeyCode::KeyJ => Key::J,
345            KeyCode::KeyK => Key::K,
346            KeyCode::KeyL => Key::L,
347            KeyCode::KeyM => Key::M,
348            KeyCode::KeyN => Key::N,
349            KeyCode::KeyO => Key::O,
350            KeyCode::KeyP => Key::P,
351            KeyCode::KeyQ => Key::Q,
352            KeyCode::KeyR => Key::R,
353            KeyCode::KeyS => Key::S,
354            KeyCode::KeyT => Key::T,
355            KeyCode::KeyU => Key::U,
356            KeyCode::KeyV => Key::V,
357            KeyCode::KeyW => Key::W,
358            KeyCode::KeyX => Key::X,
359            KeyCode::KeyY => Key::Y,
360            KeyCode::KeyZ => Key::Z,
361            KeyCode::Escape => Key::Esc,
362            KeyCode::F1 => Key::F1,
363            KeyCode::F2 => Key::F2,
364            KeyCode::F3 => Key::F3,
365            KeyCode::F4 => Key::F4,
366            KeyCode::F5 => Key::F5,
367            KeyCode::F6 => Key::F6,
368            KeyCode::F7 => Key::F7,
369            KeyCode::F8 => Key::F8,
370            KeyCode::F9 => Key::F9,
371            KeyCode::F10 => Key::F10,
372            KeyCode::F11 => Key::F11,
373            KeyCode::F12 => Key::F12,
374            KeyCode::F13 => Key::F13,
375            KeyCode::F14 => Key::F14,
376            KeyCode::F15 => Key::F15,
377            KeyCode::F16 => Key::F16,
378            KeyCode::F17 => Key::F17,
379            KeyCode::F18 => Key::F18,
380            KeyCode::F19 => Key::F19,
381            KeyCode::F20 => Key::F20,
382            KeyCode::F21 => Key::F21,
383            KeyCode::F22 => Key::F22,
384            KeyCode::F23 => Key::F23,
385            KeyCode::F24 => Key::F24,
386            KeyCode::ScrollLock => Key::ScrollLock,
387            KeyCode::Home => Key::Home,
388            KeyCode::Delete => Key::Delete,
389            KeyCode::End => Key::End,
390            KeyCode::PageUp => Key::PageUp,
391            KeyCode::PageDown => Key::PageDown,
392            KeyCode::ArrowLeft => Key::Left,
393            KeyCode::ArrowUp => Key::Up,
394            KeyCode::ArrowRight => Key::Right,
395            KeyCode::ArrowDown => Key::Down,
396            KeyCode::Backspace => Key::BackSpace,
397            KeyCode::Enter => Key::Enter,
398            KeyCode::Space => Key::Space,
399            KeyCode::NumLock => Key::Numlock,
400            KeyCode::Numpad0 => Key::Numpad0,
401            KeyCode::Numpad1 => Key::Numpad1,
402            KeyCode::Numpad2 => Key::Numpad2,
403            KeyCode::Numpad3 => Key::Numpad3,
404            KeyCode::Numpad4 => Key::Numpad4,
405            KeyCode::Numpad5 => Key::Numpad5,
406            KeyCode::Numpad6 => Key::Numpad6,
407            KeyCode::Numpad7 => Key::Numpad7,
408            KeyCode::Numpad8 => Key::Numpad8,
409            KeyCode::Numpad9 => Key::Numpad9,
410            KeyCode::NumpadAdd => Key::NumpadAdd,
411            KeyCode::NumpadDivide => Key::NumpadDivide,
412            KeyCode::NumpadDecimal => Key::NumpadDecimial,
413            KeyCode::NumpadComma => Key::NumpadComma,
414            KeyCode::NumpadEnter => Key::NumpadEnter,
415            KeyCode::NumpadEqual => Key::NumpadEquals,
416            KeyCode::NumpadMultiply => Key::NumpadMultiply,
417            KeyCode::NumpadSubtract => Key::NumpadSubtract,
418            KeyCode::Backslash => Key::BackSlash,
419            KeyCode::CapsLock => Key::CapsLock,
420            KeyCode::Comma => Key::Comma,
421            KeyCode::AltLeft => Key::LeftAlt,
422            KeyCode::BracketLeft => Key::LeftBracket,
423            KeyCode::ControlLeft => Key::LeftControl,
424            KeyCode::ShiftLeft => Key::LeftShift,
425            KeyCode::Minus => Key::Minus,
426            KeyCode::Period => Key::Period,
427            KeyCode::AltRight => Key::RightAlt,
428            KeyCode::BracketRight => Key::RightBracket,
429            KeyCode::ControlRight => Key::RightControl,
430            KeyCode::ShiftRight => Key::RightShift,
431            KeyCode::Semicolon => Key::SemiColon,
432            KeyCode::Slash => Key::Slash,
433            KeyCode::Tab => Key::Tab,
434            KeyCode::Backquote => Key::BackQoute,
435            _ => Key::Unrecognized,
436        }
437    }
438}
439
440/// Keys such as Shift Ctrl and Alt that can be used to "modify inputs"
441/// think about shortcuts like Ctrl + S to save on most text editors.
442/// Note that these do not diffrentiate between sides so LeftShift will
443/// be considered the same as RightShift for modifiers. To get specific keys use [Key](Key::LeftAlt)
444#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
445pub enum ModifierKeys {
446    Shift,
447    Alt,
448    Ctrl,
449    Super,
450}
451
452impl From<ModifierKeys> for ModifiersState {
453    fn from(value: ModifierKeys) -> Self {
454        match value {
455            ModifierKeys::Shift => ModifiersState::SHIFT,
456            ModifierKeys::Alt => ModifiersState::ALT,
457            ModifierKeys::Ctrl => ModifiersState::CONTROL,
458            ModifierKeys::Super => ModifiersState::SUPER,
459        }
460    }
461}