/ let-engine / src / input.rs
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  }