1 //! The `Event` enum and assorted supporting types. 2 //! 3 //! These are sent to the closure given to [`EventLoop::run(...)`][event_loop_run], where they get 4 //! processed and used to modify the program state. For more details, see the root-level documentation. 5 //! 6 //! Some of these events represent different "parts" of a traditional event-handling loop. You could 7 //! approximate the basic ordering loop of [`EventLoop::run(...)`][event_loop_run] like this: 8 //! 9 //! ```rust,ignore 10 //! let mut control_flow = ControlFlow::Poll; 11 //! let mut start_cause = StartCause::Init; 12 //! 13 //! while control_flow != ControlFlow::Exit { 14 //! event_handler(NewEvents(start_cause), ..., &mut control_flow); 15 //! 16 //! for e in (window events, user events, device events) { 17 //! event_handler(e, ..., &mut control_flow); 18 //! } 19 //! event_handler(MainEventsCleared, ..., &mut control_flow); 20 //! 21 //! for w in (redraw windows) { 22 //! event_handler(RedrawRequested(w), ..., &mut control_flow); 23 //! } 24 //! event_handler(RedrawEventsCleared, ..., &mut control_flow); 25 //! 26 //! start_cause = wait_if_necessary(control_flow); 27 //! } 28 //! 29 //! event_handler(LoopDestroyed, ..., &mut control_flow); 30 //! ``` 31 //! 32 //! This leaves out timing details like `ControlFlow::WaitUntil` but hopefully 33 //! describes what happens in what order. 34 //! 35 //! [event_loop_run]: crate::event_loop::EventLoop::run 36 use instant::Instant; 37 use std::path::PathBuf; 38 39 use crate::{ 40 dpi::{PhysicalPosition, PhysicalSize}, 41 platform_impl, 42 window::{Theme, WindowId}, 43 }; 44 45 /// Describes a generic event. 46 /// 47 /// See the module-level docs for more information on the event loop manages each event. 48 #[derive(Debug, PartialEq)] 49 pub enum Event<'a, T: 'static> { 50 /// Emitted when new events arrive from the OS to be processed. 51 /// 52 /// This event type is useful as a place to put code that should be done before you start 53 /// processing events, such as updating frame timing information for benchmarking or checking 54 /// the [`StartCause`][crate::event::StartCause] to see if a timer set by 55 /// [`ControlFlow::WaitUntil`](crate::event_loop::ControlFlow::WaitUntil) has elapsed. 56 NewEvents(StartCause), 57 58 /// Emitted when the OS sends an event to a winit window. 59 WindowEvent { 60 window_id: WindowId, 61 event: WindowEvent<'a>, 62 }, 63 64 /// Emitted when the OS sends an event to a device. 65 DeviceEvent { 66 device_id: DeviceId, 67 event: DeviceEvent, 68 }, 69 70 /// Emitted when an event is sent from [`EventLoopProxy::send_event`](crate::event_loop::EventLoopProxy::send_event) 71 UserEvent(T), 72 73 /// Emitted when the application has been suspended. 74 Suspended, 75 76 /// Emitted when the application has been resumed. 77 Resumed, 78 79 /// Emitted when all of the event loop's input events have been processed and redraw processing 80 /// is about to begin. 81 /// 82 /// This event is useful as a place to put your code that should be run after all 83 /// state-changing events have been handled and you want to do stuff (updating state, performing 84 /// calculations, etc) that happens as the "main body" of your event loop. If your program only draws 85 /// graphics when something changes, it's usually better to do it in response to 86 /// [`Event::RedrawRequested`](crate::event::Event::RedrawRequested), which gets emitted 87 /// immediately after this event. Programs that draw graphics continuously, like most games, 88 /// can render here unconditionally for simplicity. 89 MainEventsCleared, 90 91 /// Emitted after `MainEventsCleared` when a window should be redrawn. 92 /// 93 /// This gets triggered in two scenarios: 94 /// - The OS has performed an operation that's invalidated the window's contents (such as 95 /// resizing the window). 96 /// - The application has explicitly requested a redraw via 97 /// [`Window::request_redraw`](crate::window::Window::request_redraw). 98 /// 99 /// During each iteration of the event loop, Winit will aggregate duplicate redraw requests 100 /// into a single event, to help avoid duplicating rendering work. 101 /// 102 /// Mainly of interest to applications with mostly-static graphics that avoid redrawing unless 103 /// something changes, like most non-game GUIs. 104 RedrawRequested(WindowId), 105 106 /// Emitted after all `RedrawRequested` events have been processed and control flow is about to 107 /// be taken away from the program. If there are no `RedrawRequested` events, it is emitted 108 /// immediately after `MainEventsCleared`. 109 /// 110 /// This event is useful for doing any cleanup or bookkeeping work after all the rendering 111 /// tasks have been completed. 112 RedrawEventsCleared, 113 114 /// Emitted when the event loop is being shut down. 115 /// 116 /// This is irreversable - if this event is emitted, it is guaranteed to be the last event that 117 /// gets emitted. You generally want to treat this as an "do on quit" event. 118 LoopDestroyed, 119 } 120 121 impl<T: Clone> Clone for Event<'static, T> { clone(&self) -> Self122 fn clone(&self) -> Self { 123 use self::Event::*; 124 match self { 125 WindowEvent { window_id, event } => WindowEvent { 126 window_id: *window_id, 127 event: event.clone(), 128 }, 129 UserEvent(event) => UserEvent(event.clone()), 130 DeviceEvent { device_id, event } => DeviceEvent { 131 device_id: *device_id, 132 event: event.clone(), 133 }, 134 NewEvents(cause) => NewEvents(cause.clone()), 135 MainEventsCleared => MainEventsCleared, 136 RedrawRequested(wid) => RedrawRequested(*wid), 137 RedrawEventsCleared => RedrawEventsCleared, 138 LoopDestroyed => LoopDestroyed, 139 Suspended => Suspended, 140 Resumed => Resumed, 141 } 142 } 143 } 144 145 impl<'a, T> Event<'a, T> { map_nonuser_event<U>(self) -> Result<Event<'a, U>, Event<'a, T>>146 pub fn map_nonuser_event<U>(self) -> Result<Event<'a, U>, Event<'a, T>> { 147 use self::Event::*; 148 match self { 149 UserEvent(_) => Err(self), 150 WindowEvent { window_id, event } => Ok(WindowEvent { window_id, event }), 151 DeviceEvent { device_id, event } => Ok(DeviceEvent { device_id, event }), 152 NewEvents(cause) => Ok(NewEvents(cause)), 153 MainEventsCleared => Ok(MainEventsCleared), 154 RedrawRequested(wid) => Ok(RedrawRequested(wid)), 155 RedrawEventsCleared => Ok(RedrawEventsCleared), 156 LoopDestroyed => Ok(LoopDestroyed), 157 Suspended => Ok(Suspended), 158 Resumed => Ok(Resumed), 159 } 160 } 161 162 /// If the event doesn't contain a reference, turn it into an event with a `'static` lifetime. 163 /// Otherwise, return `None`. to_static(self) -> Option<Event<'static, T>>164 pub fn to_static(self) -> Option<Event<'static, T>> { 165 use self::Event::*; 166 match self { 167 WindowEvent { window_id, event } => event 168 .to_static() 169 .map(|event| WindowEvent { window_id, event }), 170 UserEvent(event) => Some(UserEvent(event)), 171 DeviceEvent { device_id, event } => Some(DeviceEvent { device_id, event }), 172 NewEvents(cause) => Some(NewEvents(cause)), 173 MainEventsCleared => Some(MainEventsCleared), 174 RedrawRequested(wid) => Some(RedrawRequested(wid)), 175 RedrawEventsCleared => Some(RedrawEventsCleared), 176 LoopDestroyed => Some(LoopDestroyed), 177 Suspended => Some(Suspended), 178 Resumed => Some(Resumed), 179 } 180 } 181 } 182 183 /// Describes the reason the event loop is resuming. 184 #[derive(Debug, Clone, Copy, PartialEq, Eq)] 185 pub enum StartCause { 186 /// Sent if the time specified by `ControlFlow::WaitUntil` has been reached. Contains the 187 /// moment the timeout was requested and the requested resume time. The actual resume time is 188 /// guaranteed to be equal to or after the requested resume time. 189 ResumeTimeReached { 190 start: Instant, 191 requested_resume: Instant, 192 }, 193 194 /// Sent if the OS has new events to send to the window, after a wait was requested. Contains 195 /// the moment the wait was requested and the resume time, if requested. 196 WaitCancelled { 197 start: Instant, 198 requested_resume: Option<Instant>, 199 }, 200 201 /// Sent if the event loop is being resumed after the loop's control flow was set to 202 /// `ControlFlow::Poll`. 203 Poll, 204 205 /// Sent once, immediately after `run` is called. Indicates that the loop was just initialized. 206 Init, 207 } 208 209 /// Describes an event from a `Window`. 210 #[derive(Debug, PartialEq)] 211 pub enum WindowEvent<'a> { 212 /// The size of the window has changed. Contains the client area's new dimensions. 213 Resized(PhysicalSize<u32>), 214 215 /// The position of the window has changed. Contains the window's new position. 216 Moved(PhysicalPosition<i32>), 217 218 /// The window has been requested to close. 219 CloseRequested, 220 221 /// The window has been destroyed. 222 Destroyed, 223 224 /// A file has been dropped into the window. 225 /// 226 /// When the user drops multiple files at once, this event will be emitted for each file 227 /// separately. 228 DroppedFile(PathBuf), 229 230 /// A file is being hovered over the window. 231 /// 232 /// When the user hovers multiple files at once, this event will be emitted for each file 233 /// separately. 234 HoveredFile(PathBuf), 235 236 /// A file was hovered, but has exited the window. 237 /// 238 /// There will be a single `HoveredFileCancelled` event triggered even if multiple files were 239 /// hovered. 240 HoveredFileCancelled, 241 242 /// The window received a unicode character. 243 ReceivedCharacter(char), 244 245 /// The window gained or lost focus. 246 /// 247 /// The parameter is true if the window has gained focus, and false if it has lost focus. 248 Focused(bool), 249 250 /// An event from the keyboard has been received. 251 KeyboardInput { 252 device_id: DeviceId, 253 input: KeyboardInput, 254 /// If `true`, the event was generated synthetically by winit 255 /// in one of the following circumstances: 256 /// 257 /// * Synthetic key press events are generated for all keys pressed 258 /// when a window gains focus. Likewise, synthetic key release events 259 /// are generated for all keys pressed when a window goes out of focus. 260 /// ***Currently, this is only functional on X11 and Windows*** 261 /// 262 /// Otherwise, this value is always `false`. 263 is_synthetic: bool, 264 }, 265 266 /// The keyboard modifiers have changed. 267 /// 268 /// Platform-specific behavior: 269 /// - **Web**: This API is currently unimplemented on the web. This isn't by design - it's an 270 /// issue, and it should get fixed - but it's the current state of the API. 271 ModifiersChanged(ModifiersState), 272 273 /// The cursor has moved on the window. 274 CursorMoved { 275 device_id: DeviceId, 276 277 /// (x,y) coords in pixels relative to the top-left corner of the window. Because the range of this data is 278 /// limited by the display area and it may have been transformed by the OS to implement effects such as cursor 279 /// acceleration, it should not be used to implement non-cursor-like interactions such as 3D camera control. 280 position: PhysicalPosition<f64>, 281 #[deprecated = "Deprecated in favor of WindowEvent::ModifiersChanged"] 282 modifiers: ModifiersState, 283 }, 284 285 /// The cursor has entered the window. 286 CursorEntered { device_id: DeviceId }, 287 288 /// The cursor has left the window. 289 CursorLeft { device_id: DeviceId }, 290 291 /// A mouse wheel movement or touchpad scroll occurred. 292 MouseWheel { 293 device_id: DeviceId, 294 delta: MouseScrollDelta, 295 phase: TouchPhase, 296 #[deprecated = "Deprecated in favor of WindowEvent::ModifiersChanged"] 297 modifiers: ModifiersState, 298 }, 299 300 /// An mouse button press has been received. 301 MouseInput { 302 device_id: DeviceId, 303 state: ElementState, 304 button: MouseButton, 305 #[deprecated = "Deprecated in favor of WindowEvent::ModifiersChanged"] 306 modifiers: ModifiersState, 307 }, 308 309 /// Touchpad pressure event. 310 /// 311 /// At the moment, only supported on Apple forcetouch-capable macbooks. 312 /// The parameters are: pressure level (value between 0 and 1 representing how hard the touchpad 313 /// is being pressed) and stage (integer representing the click level). 314 TouchpadPressure { 315 device_id: DeviceId, 316 pressure: f32, 317 stage: i64, 318 }, 319 320 /// Motion on some analog axis. May report data redundant to other, more specific events. 321 AxisMotion { 322 device_id: DeviceId, 323 axis: AxisId, 324 value: f64, 325 }, 326 327 /// Touch event has been received 328 Touch(Touch), 329 330 /// The window's scale factor has changed. 331 /// 332 /// The following user actions can cause DPI changes: 333 /// 334 /// * Changing the display's resolution. 335 /// * Changing the display's scale factor (e.g. in Control Panel on Windows). 336 /// * Moving the window to a display with a different scale factor. 337 /// 338 /// After this event callback has been processed, the window will be resized to whatever value 339 /// is pointed to by the `new_inner_size` reference. By default, this will contain the size suggested 340 /// by the OS, but it can be changed to any value. 341 /// 342 /// For more information about DPI in general, see the [`dpi`](crate::dpi) module. 343 ScaleFactorChanged { 344 scale_factor: f64, 345 new_inner_size: &'a mut PhysicalSize<u32>, 346 }, 347 348 /// The system window theme has changed. 349 /// 350 /// Applications might wish to react to this to change the theme of the content of the window 351 /// when the system changes the window theme. 352 /// 353 /// At the moment this is only supported on Windows. 354 ThemeChanged(Theme), 355 } 356 357 impl Clone for WindowEvent<'static> { clone(&self) -> Self358 fn clone(&self) -> Self { 359 use self::WindowEvent::*; 360 return match self { 361 Resized(size) => Resized(size.clone()), 362 Moved(pos) => Moved(pos.clone()), 363 CloseRequested => CloseRequested, 364 Destroyed => Destroyed, 365 DroppedFile(file) => DroppedFile(file.clone()), 366 HoveredFile(file) => HoveredFile(file.clone()), 367 HoveredFileCancelled => HoveredFileCancelled, 368 ReceivedCharacter(c) => ReceivedCharacter(*c), 369 Focused(f) => Focused(*f), 370 KeyboardInput { 371 device_id, 372 input, 373 is_synthetic, 374 } => KeyboardInput { 375 device_id: *device_id, 376 input: *input, 377 is_synthetic: *is_synthetic, 378 }, 379 380 ModifiersChanged(modifiers) => ModifiersChanged(modifiers.clone()), 381 #[allow(deprecated)] 382 CursorMoved { 383 device_id, 384 position, 385 modifiers, 386 } => CursorMoved { 387 device_id: *device_id, 388 position: *position, 389 modifiers: *modifiers, 390 }, 391 CursorEntered { device_id } => CursorEntered { 392 device_id: *device_id, 393 }, 394 CursorLeft { device_id } => CursorLeft { 395 device_id: *device_id, 396 }, 397 #[allow(deprecated)] 398 MouseWheel { 399 device_id, 400 delta, 401 phase, 402 modifiers, 403 } => MouseWheel { 404 device_id: *device_id, 405 delta: *delta, 406 phase: *phase, 407 modifiers: *modifiers, 408 }, 409 #[allow(deprecated)] 410 MouseInput { 411 device_id, 412 state, 413 button, 414 modifiers, 415 } => MouseInput { 416 device_id: *device_id, 417 state: *state, 418 button: *button, 419 modifiers: *modifiers, 420 }, 421 TouchpadPressure { 422 device_id, 423 pressure, 424 stage, 425 } => TouchpadPressure { 426 device_id: *device_id, 427 pressure: *pressure, 428 stage: *stage, 429 }, 430 AxisMotion { 431 device_id, 432 axis, 433 value, 434 } => AxisMotion { 435 device_id: *device_id, 436 axis: *axis, 437 value: *value, 438 }, 439 Touch(touch) => Touch(*touch), 440 ThemeChanged(theme) => ThemeChanged(theme.clone()), 441 ScaleFactorChanged { .. } => { 442 unreachable!("Static event can't be about scale factor changing") 443 } 444 }; 445 } 446 } 447 448 impl<'a> WindowEvent<'a> { to_static(self) -> Option<WindowEvent<'static>>449 pub fn to_static(self) -> Option<WindowEvent<'static>> { 450 use self::WindowEvent::*; 451 match self { 452 Resized(size) => Some(Resized(size)), 453 Moved(position) => Some(Moved(position)), 454 CloseRequested => Some(CloseRequested), 455 Destroyed => Some(Destroyed), 456 DroppedFile(file) => Some(DroppedFile(file)), 457 HoveredFile(file) => Some(HoveredFile(file)), 458 HoveredFileCancelled => Some(HoveredFileCancelled), 459 ReceivedCharacter(c) => Some(ReceivedCharacter(c)), 460 Focused(focused) => Some(Focused(focused)), 461 KeyboardInput { 462 device_id, 463 input, 464 is_synthetic, 465 } => Some(KeyboardInput { 466 device_id, 467 input, 468 is_synthetic, 469 }), 470 ModifiersChanged(modifiers) => Some(ModifiersChanged(modifiers)), 471 #[allow(deprecated)] 472 CursorMoved { 473 device_id, 474 position, 475 modifiers, 476 } => Some(CursorMoved { 477 device_id, 478 position, 479 modifiers, 480 }), 481 CursorEntered { device_id } => Some(CursorEntered { device_id }), 482 CursorLeft { device_id } => Some(CursorLeft { device_id }), 483 #[allow(deprecated)] 484 MouseWheel { 485 device_id, 486 delta, 487 phase, 488 modifiers, 489 } => Some(MouseWheel { 490 device_id, 491 delta, 492 phase, 493 modifiers, 494 }), 495 #[allow(deprecated)] 496 MouseInput { 497 device_id, 498 state, 499 button, 500 modifiers, 501 } => Some(MouseInput { 502 device_id, 503 state, 504 button, 505 modifiers, 506 }), 507 TouchpadPressure { 508 device_id, 509 pressure, 510 stage, 511 } => Some(TouchpadPressure { 512 device_id, 513 pressure, 514 stage, 515 }), 516 AxisMotion { 517 device_id, 518 axis, 519 value, 520 } => Some(AxisMotion { 521 device_id, 522 axis, 523 value, 524 }), 525 Touch(touch) => Some(Touch(touch)), 526 ThemeChanged(theme) => Some(ThemeChanged(theme)), 527 ScaleFactorChanged { .. } => None, 528 } 529 } 530 } 531 532 /// Identifier of an input device. 533 /// 534 /// Whenever you receive an event arising from a particular input device, this event contains a `DeviceId` which 535 /// identifies its origin. Note that devices may be virtual (representing an on-screen cursor and keyboard focus) or 536 /// physical. Virtual devices typically aggregate inputs from multiple physical devices. 537 #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] 538 pub struct DeviceId(pub(crate) platform_impl::DeviceId); 539 540 impl DeviceId { 541 /// Returns a dummy `DeviceId`, useful for unit testing. The only guarantee made about the return 542 /// value of this function is that it will always be equal to itself and to future values returned 543 /// by this function. No other guarantees are made. This may be equal to a real `DeviceId`. 544 /// 545 /// **Passing this into a winit function will result in undefined behavior.** dummy() -> Self546 pub unsafe fn dummy() -> Self { 547 DeviceId(platform_impl::DeviceId::dummy()) 548 } 549 } 550 551 /// Represents raw hardware events that are not associated with any particular window. 552 /// 553 /// Useful for interactions that diverge significantly from a conventional 2D GUI, such as 3D camera or first-person 554 /// game controls. Many physical actions, such as mouse movement, can produce both device and window events. Because 555 /// window events typically arise from virtual devices (corresponding to GUI cursors and keyboard focus) the device IDs 556 /// may not match. 557 /// 558 /// Note that these events are delivered regardless of input focus. 559 #[derive(Clone, Debug, PartialEq)] 560 pub enum DeviceEvent { 561 Added, 562 Removed, 563 564 /// Change in physical position of a pointing device. 565 /// 566 /// This represents raw, unfiltered physical motion. Not to be confused with `WindowEvent::CursorMoved`. 567 MouseMotion { 568 /// (x, y) change in position in unspecified units. 569 /// 570 /// Different devices may use different units. 571 delta: (f64, f64), 572 }, 573 574 /// Physical scroll event 575 MouseWheel { 576 delta: MouseScrollDelta, 577 }, 578 579 /// Motion on some analog axis. This event will be reported for all arbitrary input devices 580 /// that winit supports on this platform, including mouse devices. If the device is a mouse 581 /// device then this will be reported alongside the MouseMotion event. 582 Motion { 583 axis: AxisId, 584 value: f64, 585 }, 586 587 Button { 588 button: ButtonId, 589 state: ElementState, 590 }, 591 592 Key(KeyboardInput), 593 594 Text { 595 codepoint: char, 596 }, 597 } 598 599 /// Describes a keyboard input event. 600 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 601 #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] 602 pub struct KeyboardInput { 603 /// Identifies the physical key pressed 604 /// 605 /// This should not change if the user adjusts the host's keyboard map. Use when the physical location of the 606 /// key is more important than the key's host GUI semantics, such as for movement controls in a first-person 607 /// game. 608 pub scancode: ScanCode, 609 610 pub state: ElementState, 611 612 /// Identifies the semantic meaning of the key 613 /// 614 /// Use when the semantics of the key are more important than the physical location of the key, such as when 615 /// implementing appropriate behavior for "page up." 616 pub virtual_keycode: Option<VirtualKeyCode>, 617 618 /// Modifier keys active at the time of this input. 619 /// 620 /// This is tracked internally to avoid tracking errors arising from modifier key state changes when events from 621 /// this device are not being delivered to the application, e.g. due to keyboard focus being elsewhere. 622 #[deprecated = "Deprecated in favor of WindowEvent::ModifiersChanged"] 623 pub modifiers: ModifiersState, 624 } 625 626 /// Describes touch-screen input state. 627 #[derive(Debug, Hash, PartialEq, Eq, Clone, Copy)] 628 #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] 629 pub enum TouchPhase { 630 Started, 631 Moved, 632 Ended, 633 Cancelled, 634 } 635 636 /// Represents a touch event 637 /// 638 /// Every time the user touches the screen, a new `Start` event with an unique 639 /// identifier for the finger is generated. When the finger is lifted, an `End` 640 /// event is generated with the same finger id. 641 /// 642 /// After a `Start` event has been emitted, there may be zero or more `Move` 643 /// events when the finger is moved or the touch pressure changes. 644 /// 645 /// The finger id may be reused by the system after an `End` event. The user 646 /// should assume that a new `Start` event received with the same id has nothing 647 /// to do with the old finger and is a new finger. 648 /// 649 /// A `Cancelled` event is emitted when the system has canceled tracking this 650 /// touch, such as when the window loses focus, or on iOS if the user moves the 651 /// device against their face. 652 #[derive(Debug, Clone, Copy, PartialEq)] 653 pub struct Touch { 654 pub device_id: DeviceId, 655 pub phase: TouchPhase, 656 pub location: PhysicalPosition<f64>, 657 /// Describes how hard the screen was pressed. May be `None` if the platform 658 /// does not support pressure sensitivity. 659 /// 660 /// ## Platform-specific 661 /// 662 /// - Only available on **iOS** 9.0+ and **Windows** 8+. 663 pub force: Option<Force>, 664 /// Unique identifier of a finger. 665 pub id: u64, 666 } 667 668 /// Describes the force of a touch event 669 #[derive(Debug, Clone, Copy, PartialEq)] 670 pub enum Force { 671 /// On iOS, the force is calibrated so that the same number corresponds to 672 /// roughly the same amount of pressure on the screen regardless of the 673 /// device. 674 Calibrated { 675 /// The force of the touch, where a value of 1.0 represents the force of 676 /// an average touch (predetermined by the system, not user-specific). 677 /// 678 /// The force reported by Apple Pencil is measured along the axis of the 679 /// pencil. If you want a force perpendicular to the device, you need to 680 /// calculate this value using the `altitude_angle` value. 681 force: f64, 682 /// The maximum possible force for a touch. 683 /// 684 /// The value of this field is sufficiently high to provide a wide 685 /// dynamic range for values of the `force` field. 686 max_possible_force: f64, 687 /// The altitude (in radians) of the stylus. 688 /// 689 /// A value of 0 radians indicates that the stylus is parallel to the 690 /// surface. The value of this property is Pi/2 when the stylus is 691 /// perpendicular to the surface. 692 altitude_angle: Option<f64>, 693 }, 694 /// If the platform reports the force as normalized, we have no way of 695 /// knowing how much pressure 1.0 corresponds to – we know it's the maximum 696 /// amount of force, but as to how much force, you might either have to 697 /// press really really hard, or not hard at all, depending on the device. 698 Normalized(f64), 699 } 700 701 impl Force { 702 /// Returns the force normalized to the range between 0.0 and 1.0 inclusive. 703 /// Instead of normalizing the force, you should prefer to handle 704 /// `Force::Calibrated` so that the amount of force the user has to apply is 705 /// consistent across devices. normalized(&self) -> f64706 pub fn normalized(&self) -> f64 { 707 match self { 708 Force::Calibrated { 709 force, 710 max_possible_force, 711 altitude_angle, 712 } => { 713 let force = match altitude_angle { 714 Some(altitude_angle) => force / altitude_angle.sin(), 715 None => *force, 716 }; 717 force / max_possible_force 718 } 719 Force::Normalized(force) => *force, 720 } 721 } 722 } 723 724 /// Hardware-dependent keyboard scan code. 725 pub type ScanCode = u32; 726 727 /// Identifier for a specific analog axis on some device. 728 pub type AxisId = u32; 729 730 /// Identifier for a specific button on some device. 731 pub type ButtonId = u32; 732 733 /// Describes the input state of a key. 734 #[derive(Debug, Hash, PartialEq, Eq, Clone, Copy)] 735 #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] 736 pub enum ElementState { 737 Pressed, 738 Released, 739 } 740 741 /// Describes a button of a mouse controller. 742 #[derive(Debug, Hash, PartialEq, Eq, Clone, Copy)] 743 #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] 744 pub enum MouseButton { 745 Left, 746 Right, 747 Middle, 748 Other(u16), 749 } 750 751 /// Describes a difference in the mouse scroll wheel state. 752 #[derive(Debug, Clone, Copy, PartialEq)] 753 #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] 754 pub enum MouseScrollDelta { 755 /// Amount in lines or rows to scroll in the horizontal 756 /// and vertical directions. 757 /// 758 /// Positive values indicate movement forward 759 /// (away from the user) or rightwards. 760 LineDelta(f32, f32), 761 /// Amount in pixels to scroll in the horizontal and 762 /// vertical direction. 763 /// 764 /// Scroll events are expressed as a PixelDelta if 765 /// supported by the device (eg. a touchpad) and 766 /// platform. 767 PixelDelta(PhysicalPosition<f64>), 768 } 769 770 /// Symbolic name for a keyboard key. 771 #[derive(Debug, Hash, Ord, PartialOrd, PartialEq, Eq, Clone, Copy)] 772 #[repr(u32)] 773 #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] 774 pub enum VirtualKeyCode { 775 /// The '1' key over the letters. 776 Key1, 777 /// The '2' key over the letters. 778 Key2, 779 /// The '3' key over the letters. 780 Key3, 781 /// The '4' key over the letters. 782 Key4, 783 /// The '5' key over the letters. 784 Key5, 785 /// The '6' key over the letters. 786 Key6, 787 /// The '7' key over the letters. 788 Key7, 789 /// The '8' key over the letters. 790 Key8, 791 /// The '9' key over the letters. 792 Key9, 793 /// The '0' key over the 'O' and 'P' keys. 794 Key0, 795 796 A, 797 B, 798 C, 799 D, 800 E, 801 F, 802 G, 803 H, 804 I, 805 J, 806 K, 807 L, 808 M, 809 N, 810 O, 811 P, 812 Q, 813 R, 814 S, 815 T, 816 U, 817 V, 818 W, 819 X, 820 Y, 821 Z, 822 823 /// The Escape key, next to F1. 824 Escape, 825 826 F1, 827 F2, 828 F3, 829 F4, 830 F5, 831 F6, 832 F7, 833 F8, 834 F9, 835 F10, 836 F11, 837 F12, 838 F13, 839 F14, 840 F15, 841 F16, 842 F17, 843 F18, 844 F19, 845 F20, 846 F21, 847 F22, 848 F23, 849 F24, 850 851 /// Print Screen/SysRq. 852 Snapshot, 853 /// Scroll Lock. 854 Scroll, 855 /// Pause/Break key, next to Scroll lock. 856 Pause, 857 858 /// `Insert`, next to Backspace. 859 Insert, 860 Home, 861 Delete, 862 End, 863 PageDown, 864 PageUp, 865 866 Left, 867 Up, 868 Right, 869 Down, 870 871 /// The Backspace key, right over Enter. 872 // TODO: rename 873 Back, 874 /// The Enter key. 875 Return, 876 /// The space bar. 877 Space, 878 879 /// The "Compose" key on Linux. 880 Compose, 881 882 Caret, 883 884 Numlock, 885 Numpad0, 886 Numpad1, 887 Numpad2, 888 Numpad3, 889 Numpad4, 890 Numpad5, 891 Numpad6, 892 Numpad7, 893 Numpad8, 894 Numpad9, 895 NumpadAdd, 896 NumpadDivide, 897 NumpadDecimal, 898 NumpadComma, 899 NumpadEnter, 900 NumpadEquals, 901 NumpadMultiply, 902 NumpadSubtract, 903 904 AbntC1, 905 AbntC2, 906 Apostrophe, 907 Apps, 908 Asterisk, 909 At, 910 Ax, 911 Backslash, 912 Calculator, 913 Capital, 914 Colon, 915 Comma, 916 Convert, 917 Equals, 918 Grave, 919 Kana, 920 Kanji, 921 LAlt, 922 LBracket, 923 LControl, 924 LShift, 925 LWin, 926 Mail, 927 MediaSelect, 928 MediaStop, 929 Minus, 930 Mute, 931 MyComputer, 932 // also called "Next" 933 NavigateForward, 934 // also called "Prior" 935 NavigateBackward, 936 NextTrack, 937 NoConvert, 938 OEM102, 939 Period, 940 PlayPause, 941 Plus, 942 Power, 943 PrevTrack, 944 RAlt, 945 RBracket, 946 RControl, 947 RShift, 948 RWin, 949 Semicolon, 950 Slash, 951 Sleep, 952 Stop, 953 Sysrq, 954 Tab, 955 Underline, 956 Unlabeled, 957 VolumeDown, 958 VolumeUp, 959 Wake, 960 WebBack, 961 WebFavorites, 962 WebForward, 963 WebHome, 964 WebRefresh, 965 WebSearch, 966 WebStop, 967 Yen, 968 Copy, 969 Paste, 970 Cut, 971 } 972 973 impl ModifiersState { 974 /// Returns `true` if the shift key is pressed. shift(&self) -> bool975 pub fn shift(&self) -> bool { 976 self.intersects(Self::SHIFT) 977 } 978 /// Returns `true` if the control key is pressed. ctrl(&self) -> bool979 pub fn ctrl(&self) -> bool { 980 self.intersects(Self::CTRL) 981 } 982 /// Returns `true` if the alt key is pressed. alt(&self) -> bool983 pub fn alt(&self) -> bool { 984 self.intersects(Self::ALT) 985 } 986 /// Returns `true` if the logo key is pressed. logo(&self) -> bool987 pub fn logo(&self) -> bool { 988 self.intersects(Self::LOGO) 989 } 990 } 991 992 bitflags! { 993 /// Represents the current state of the keyboard modifiers 994 /// 995 /// Each flag represents a modifier and is set if this modifier is active. 996 #[derive(Default)] 997 pub struct ModifiersState: u32 { 998 // left and right modifiers are currently commented out, but we should be able to support 999 // them in a future release 1000 /// The "shift" key. 1001 const SHIFT = 0b100 << 0; 1002 // const LSHIFT = 0b010 << 0; 1003 // const RSHIFT = 0b001 << 0; 1004 /// The "control" key. 1005 const CTRL = 0b100 << 3; 1006 // const LCTRL = 0b010 << 3; 1007 // const RCTRL = 0b001 << 3; 1008 /// The "alt" key. 1009 const ALT = 0b100 << 6; 1010 // const LALT = 0b010 << 6; 1011 // const RALT = 0b001 << 6; 1012 /// This is the "windows" key on PC and "command" key on Mac. 1013 const LOGO = 0b100 << 9; 1014 // const LLOGO = 0b010 << 9; 1015 // const RLOGO = 0b001 << 9; 1016 } 1017 } 1018 1019 #[cfg(feature = "serde")] 1020 mod modifiers_serde { 1021 use super::ModifiersState; 1022 use serde::{Deserialize, Deserializer, Serialize, Serializer}; 1023 1024 #[derive(Default, Serialize, Deserialize)] 1025 #[serde(default)] 1026 #[serde(rename = "ModifiersState")] 1027 pub struct ModifiersStateSerialize { 1028 pub shift: bool, 1029 pub ctrl: bool, 1030 pub alt: bool, 1031 pub logo: bool, 1032 } 1033 1034 impl Serialize for ModifiersState { serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer,1035 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> 1036 where 1037 S: Serializer, 1038 { 1039 let s = ModifiersStateSerialize { 1040 shift: self.shift(), 1041 ctrl: self.ctrl(), 1042 alt: self.alt(), 1043 logo: self.logo(), 1044 }; 1045 s.serialize(serializer) 1046 } 1047 } 1048 1049 impl<'de> Deserialize<'de> for ModifiersState { deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: Deserializer<'de>,1050 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> 1051 where 1052 D: Deserializer<'de>, 1053 { 1054 let ModifiersStateSerialize { 1055 shift, 1056 ctrl, 1057 alt, 1058 logo, 1059 } = ModifiersStateSerialize::deserialize(deserializer)?; 1060 let mut m = ModifiersState::empty(); 1061 m.set(ModifiersState::SHIFT, shift); 1062 m.set(ModifiersState::CTRL, ctrl); 1063 m.set(ModifiersState::ALT, alt); 1064 m.set(ModifiersState::LOGO, logo); 1065 Ok(m) 1066 } 1067 } 1068 } 1069