1 use std::path::PathBuf; 2 3 use gilrs::Event as GilEvent; 4 use legion::world::SubWorld; 5 use legion::*; 6 use winit_24::dpi::{PhysicalPosition, PhysicalSize, LogicalPosition}; 7 use winit_24::event::DeviceEvent::MouseMotion; 8 use winit_24::event::{AxisId, DeviceEvent, DeviceId, ElementState, Event, KeyboardInput, ModifiersState, MouseButton, MouseScrollDelta, StartCause, Touch, TouchPhase, WindowEvent, VirtualKeyCode}; 9 use winit_24::window::{Theme, WindowId, Window}; 10 11 use crate::camera::{Camera, CameraController}; 12 use crate::owned_event::OwnedWindowEvent::MouseWheel; 13 use std::sync::{Mutex, Arc}; 14 use std::cmp::Ordering; 15 use imgui::Io; 16 use crate::imgui_supp::imgui_support::{ImguiContext, ImguiPlatform}; 17 18 #[derive(Clone)] 19 pub enum OwnedUIEvent<T> { 20 UIEvent(T), 21 } 22 23 #[derive(Clone)] 24 pub enum OwnedEventExtension { 25 /// Custom events here 26 MouseHeldEvent {}, 27 KeyHeldEvent {}, 28 GamepadEvent { 29 gil_event: GilEvent, 30 }, 31 } 32 33 #[derive(Clone, Debug)] 34 pub enum OwnedEvent<T> { 35 /// Custom events here 36 MouseHeldEvent {}, 37 KeyHeldEvent {}, 38 GamepadEvent { 39 gil_event: GilEvent, 40 }, 41 42 /// Winit events here 43 NewEvents(StartCause), 44 WindowEvent { 45 window_id: WindowId, 46 event: OwnedWindowEvent, 47 }, 48 DeviceEvent { 49 device_id: DeviceId, 50 event: DeviceEvent, 51 }, 52 UserEvent(T), 53 Suspended, 54 Resumed, 55 MainEventsCleared, 56 RedrawRequested(WindowId), 57 RedrawEventsCleared, 58 LoopDestroyed, 59 } 60 61 impl<T> From<Event<'_, T>> for OwnedEvent<T> { 62 fn from(event: Event<T>) -> Self { 63 match event { 64 Event::NewEvents(cause) => OwnedEvent::NewEvents(cause), 65 Event::WindowEvent { 66 window_id: window_id, 67 event: event, 68 } => OwnedEvent::WindowEvent { 69 window_id: window_id, 70 event: match event { 71 WindowEvent::AxisMotion { 72 device_id, 73 axis, 74 value, 75 } => OwnedWindowEvent::AxisMotion { 76 device_id, 77 axis, 78 value, 79 }, 80 WindowEvent::Resized(physical_size) => OwnedWindowEvent::Resized(physical_size), 81 WindowEvent::Moved(physical_position) => { 82 OwnedWindowEvent::Moved(physical_position) 83 } 84 WindowEvent::CloseRequested => OwnedWindowEvent::CloseRequested, 85 WindowEvent::Destroyed => OwnedWindowEvent::Destroyed, 86 WindowEvent::DroppedFile(path_buf) => OwnedWindowEvent::DroppedFile(path_buf), 87 WindowEvent::HoveredFile(path_buf) => OwnedWindowEvent::HoveredFile(path_buf), 88 WindowEvent::HoveredFileCancelled => OwnedWindowEvent::HoveredFileCancelled, 89 WindowEvent::ReceivedCharacter(char) => { 90 OwnedWindowEvent::ReceivedCharacter(char) 91 } 92 WindowEvent::Focused(bool) => OwnedWindowEvent::Focused(bool), 93 WindowEvent::KeyboardInput { 94 device_id: device_id, 95 input: input, 96 is_synthetic: is_synthetic, 97 } => OwnedWindowEvent::KeyboardInput { 98 device_id, 99 input, 100 is_synthetic, 101 }, 102 WindowEvent::ModifiersChanged(modifiers_state) => { 103 OwnedWindowEvent::ModifiersChanged(modifiers_state) 104 } 105 WindowEvent::CursorMoved { 106 device_id: device_id, 107 position: position, 108 modifiers: modifiers, 109 } => OwnedWindowEvent::CursorMoved { 110 device_id, 111 position, 112 modifiers, 113 }, 114 WindowEvent::CursorEntered { 115 device_id: device_id, 116 } => OwnedWindowEvent::CursorEntered { device_id }, 117 WindowEvent::CursorLeft { 118 device_id: device_id, 119 } => OwnedWindowEvent::CursorLeft { device_id }, 120 WindowEvent::MouseWheel { 121 device_id: device_id, 122 delta: delta, 123 phase: phase, 124 modifiers: modifiers, 125 } => OwnedWindowEvent::MouseWheel { 126 device_id, 127 delta, 128 phase, 129 modifiers, 130 }, 131 WindowEvent::MouseInput { 132 device_id: device_id, 133 state: state, 134 button: button, 135 modifiers: modifiers, 136 } => OwnedWindowEvent::MouseInput { 137 device_id, 138 state, 139 button, 140 modifiers, 141 }, 142 WindowEvent::TouchpadPressure { 143 device_id: device_id, 144 pressure: pressure, 145 stage: stage, 146 } => OwnedWindowEvent::TouchpadPressure { 147 device_id, 148 pressure, 149 stage, 150 }, 151 WindowEvent::Touch(touch) => OwnedWindowEvent::Touch(touch), 152 WindowEvent::ScaleFactorChanged { 153 scale_factor: scale_factor, 154 new_inner_size: new_inner_size, 155 } => OwnedWindowEvent::ScaleFactorChanged { 156 scale_factor, 157 new_inner_size: PhysicalSize { 158 width: new_inner_size.width, 159 height: new_inner_size.height, 160 }, 161 }, 162 WindowEvent::ThemeChanged(theme) => OwnedWindowEvent::ThemeChanged(theme), 163 }, 164 }, 165 Event::DeviceEvent { 166 device_id: device_id, 167 event: event, 168 } => OwnedEvent::DeviceEvent { device_id, event }, 169 Event::UserEvent(user_event) => OwnedEvent::UserEvent(user_event), 170 Event::Suspended => OwnedEvent::Suspended, 171 Event::Resumed => OwnedEvent::Resumed, 172 Event::MainEventsCleared => OwnedEvent::MainEventsCleared, 173 Event::RedrawRequested(window_id) => OwnedEvent::RedrawRequested(window_id), 174 Event::RedrawEventsCleared => OwnedEvent::RedrawEventsCleared, 175 Event::LoopDestroyed => OwnedEvent::LoopDestroyed, 176 } 177 } 178 } 179 180 #[derive(Debug, PartialEq, Clone)] 181 pub enum OwnedWindowEvent { 182 Resized(PhysicalSize<u32>), 183 Moved(PhysicalPosition<i32>), 184 CloseRequested, 185 Destroyed, 186 DroppedFile(PathBuf), 187 HoveredFile(PathBuf), 188 HoveredFileCancelled, 189 ReceivedCharacter(char), 190 Focused(bool), 191 KeyboardInput { 192 device_id: DeviceId, 193 input: KeyboardInput, 194 is_synthetic: bool, 195 }, 196 ModifiersChanged(ModifiersState), 197 CursorMoved { 198 device_id: DeviceId, 199 position: PhysicalPosition<f64>, 200 #[deprecated = "Deprecated in favor of WindowEvent::ModifiersChanged"] 201 modifiers: ModifiersState, 202 }, 203 CursorEntered { 204 device_id: DeviceId, 205 }, 206 CursorLeft { 207 device_id: DeviceId, 208 }, 209 MouseWheel { 210 device_id: DeviceId, 211 delta: MouseScrollDelta, 212 phase: TouchPhase, 213 #[deprecated = "Deprecated in favor of WindowEvent::ModifiersChanged"] 214 modifiers: ModifiersState, 215 }, 216 MouseInput { 217 device_id: DeviceId, 218 state: ElementState, 219 button: MouseButton, 220 #[deprecated = "Deprecated in favor of WindowEvent::ModifiersChanged"] 221 modifiers: ModifiersState, 222 }, 223 TouchpadPressure { 224 device_id: DeviceId, 225 pressure: f32, 226 stage: i64, 227 }, 228 AxisMotion { 229 device_id: DeviceId, 230 axis: AxisId, 231 value: f64, 232 }, 233 Touch(Touch), 234 ScaleFactorChanged { 235 scale_factor: f64, 236 new_inner_size: PhysicalSize<u32>, 237 }, 238 ThemeChanged(Theme), 239 } 240 241 242 /// Because I am a glutton for punishment I am going to just do a mono-event-dispatch-magoooo 243 #[system] 244 #[write_component(Camera)] 245 #[write_component(CameraController)] 246 pub fn event_dispatch( 247 world: &mut SubWorld, 248 #[resource] event_stack: &mut Vec<OwnedEvent<OwnedEventExtension>>, 249 #[resource] imgui_context: &mut Arc<Mutex<ImguiContext>>, 250 #[resource] imgui_platform: &mut Arc<Mutex<ImguiPlatform>>, 251 #[resource] winit_window: &mut Window, 252 ) { 253 use winit_24::event::Event::DeviceEvent; 254 255 for event in event_stack { 256 257 match event { 258 OwnedEvent::DeviceEvent { 259 event: winit_24::event::DeviceEvent::MouseMotion { delta }, 260 .. 261 } => { 262 let mut query = <(&mut CameraController)>::query(); 263 for (camera_controller) in query.iter_mut(world) { 264 camera_controller.process_mouse(delta.0, delta.1); 265 } 266 267 }, 268 OwnedEvent::DeviceEvent { 269 event: winit_24::event::DeviceEvent::Key(keyboard_input), 270 .. 271 } => { 272 let mut query = <(&mut CameraController)>::query(); 273 for (camera_controller) in query.iter_mut(world) { 274 camera_controller.process_keyboard( 275 keyboard_input.virtual_keycode.unwrap(), 276 keyboard_input.state, 277 ); 278 } 279 280 match keyboard_input.virtual_keycode.unwrap() { 281 VirtualKeyCode::R => { 282 if keyboard_input.state == ElementState::Pressed { 283 284 285 //winit_window.set_cursor_grab(true); 286 } 287 } 288 VirtualKeyCode::Escape => { 289 if keyboard_input.state == ElementState::Pressed { 290 //winit_window.set_cursor_grab(false); 291 } 292 } 293 _ => () 294 } 295 } 296 _ => {} 297 } 298 299 let mut imgui_context = &mut imgui_context.lock().unwrap().context; 300 let mut imgui_platform = &mut imgui_platform.lock().unwrap().platform; 301 302 imgui_platform.handle_event(imgui_context.io_mut(), &winit_window, &event); 303 } 304 } 305