input.rs
1 //! The default input system by the engine. 2 3 use let_engine_core::{backend::gpu::Loaded, camera::CameraScaling, scenes::LayerView}; 4 use std::collections::HashSet; 5 pub use winit::event::MouseButton; 6 use winit::event::{ElementState, WindowEvent}; 7 pub use winit::keyboard::*; 8 9 use glam::f32::{Vec2, vec2}; 10 11 /// Holds the input information to be used in game. 12 /// 13 /// Updates each frame. 14 #[derive(Debug, Default, Clone)] 15 pub struct Input { 16 /// pressed keyboard keycodes. 17 keys_down: HashSet<PhysicalKey>, 18 19 /// pressed keyboard modifiers 20 keyboard_modifiers: ModifiersState, 21 22 /// pressed mouse buttons 23 mouse_down: HashSet<MouseButton>, 24 25 /// mouse position 26 cursor_position: Vec2, 27 28 /// True if the cursor is contained within the window. 29 cursor_inside: bool, 30 31 /// dimensions of the window 32 dimensions: Vec2, 33 } 34 35 impl Input { 36 /// Updates the input with the event. 37 pub(crate) fn update(&mut self, event: &WindowEvent) { 38 match event { 39 WindowEvent::Resized(size) => { 40 self.dimensions = vec2(size.width as f32, size.height as f32); 41 } 42 WindowEvent::KeyboardInput { event, .. } => { 43 if event.state == ElementState::Pressed { 44 self.keys_down.insert(event.physical_key); 45 } else { 46 self.keys_down.remove(&event.physical_key); 47 } 48 } 49 WindowEvent::ModifiersChanged(modifiers) => { 50 self.keyboard_modifiers = modifiers.state(); 51 } 52 WindowEvent::MouseInput { state, button, .. } => { 53 if state == &ElementState::Pressed { 54 self.mouse_down.insert(*button); 55 } else { 56 self.mouse_down.remove(button); 57 } 58 } 59 WindowEvent::CursorMoved { position, .. } => { 60 self.cursor_position = vec2( 61 (position.x as f32 / self.dimensions.x) * 2.0 - 1.0, 62 (position.y as f32 / self.dimensions.y) * 2.0 - 1.0, 63 ); 64 } 65 WindowEvent::CursorEntered { .. } => self.cursor_inside = true, 66 WindowEvent::CursorLeft { .. } => self.cursor_inside = false, 67 WindowEvent::Focused(focus) => { 68 if !focus { 69 self.keys_down.clear(); 70 } 71 } 72 _ => (), 73 } 74 } 75 76 /// Returns true if the given keycode is pressed on the keyboard. 77 pub fn key_down(&self, key: &PhysicalKey) -> bool { 78 self.keys_down.contains(key) 79 } 80 81 /// Releases all keys that are currently down. 82 pub fn release_all_keys(&mut self) { 83 self.keys_down.clear(); 84 self.mouse_down.clear(); 85 } 86 87 /// Returns all the pressed keys in a HashSet 88 pub fn pressed_keys(&self) -> HashSet<PhysicalKey> { 89 self.keys_down.clone() 90 } 91 92 /// Returns true if the given mouse button is pressed. 93 pub fn mouse_down(&self, button: &MouseButton) -> bool { 94 self.mouse_down.contains(button) 95 } 96 97 /// Returns the cursor position going from -1.0 to 1.0 x and y. 98 pub fn cursor_position(&self) -> Vec2 { 99 self.cursor_position 100 } 101 102 /// Returns the cursor position going from -1.0 to 1.0 x and y scaled with the inserted layers scaling properties. 103 pub fn scaled_cursor(&self, scaling: CameraScaling) -> Vec2 { 104 let dimensions = scaling.scale(self.dimensions); 105 let cp = self.cursor_position; 106 vec2(cp[0], cp[1]) * dimensions 107 } 108 109 /// Returns the cursor position in layer world space. 110 pub fn cursor_to_world<T: Loaded>(&self, view: &LayerView<T>) -> Vec2 { 111 view.screen_to_world(self.cursor_position, self.dimensions) 112 } 113 114 /// Returns true if shift is pressed on the keyboard. 115 pub fn shift(&self) -> bool { 116 self.keyboard_modifiers.shift_key() 117 } 118 119 /// Returns true if ctrl is pressed on the keyboard. 120 pub fn ctrl(&self) -> bool { 121 self.keyboard_modifiers.control_key() 122 } 123 124 /// Returns true if alt is pressed on the keyboard. 125 pub fn alt(&self) -> bool { 126 self.keyboard_modifiers.alt_key() 127 } 128 129 /// Returns true if the super key is pressed on the keyboard. 130 /// 131 /// Super key also means "Windows" key on Windows or "Command" key on Mac. 132 pub fn super_key(&self) -> bool { 133 self.keyboard_modifiers.super_key() 134 } 135 136 /// Returns true if the cursor is located in the window. 137 pub fn cursor_inside(&self) -> bool { 138 self.cursor_inside 139 } 140 }