azul_winit/
event.rs

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
36use instant::Instant;
37use std::path::PathBuf;
38
39use 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)]
49pub 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
121impl<T: Clone> Clone for Event<'static, T> {
122    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
145impl<'a, T> 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`.
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)]
185pub 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)]
211pub 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    /// Custom command (currently only emitted on Windows). Win32 allows the user to
357    /// register custom command IDs for app menus, context menus and so on
358    /// (see the `WM_COMMAND` message in the Windows API). This event allows
359    /// you to, for example, react to when a user has clicked an item in an application menu.
360    ///
361    /// The ID contained in the `Command` has to be registered by the user of the library,
362    /// usually by using the `WindowBuilder::with_create_callback` function.
363    /// For an example of how to use it, see the `menu_bar_win32` example.
364    Command(u16),
365}
366
367impl Clone for WindowEvent<'static> {
368    fn clone(&self) -> Self {
369        use self::WindowEvent::*;
370        return match self {
371            Resized(size) => Resized(size.clone()),
372            Moved(pos) => Moved(pos.clone()),
373            CloseRequested => CloseRequested,
374            Destroyed => Destroyed,
375            DroppedFile(file) => DroppedFile(file.clone()),
376            HoveredFile(file) => HoveredFile(file.clone()),
377            HoveredFileCancelled => HoveredFileCancelled,
378            ReceivedCharacter(c) => ReceivedCharacter(*c),
379            Focused(f) => Focused(*f),
380            KeyboardInput {
381                device_id,
382                input,
383                is_synthetic,
384            } => KeyboardInput {
385                device_id: *device_id,
386                input: *input,
387                is_synthetic: *is_synthetic,
388            },
389
390            ModifiersChanged(modifiers) => ModifiersChanged(modifiers.clone()),
391            #[allow(deprecated)]
392            CursorMoved {
393                device_id,
394                position,
395                modifiers,
396            } => CursorMoved {
397                device_id: *device_id,
398                position: *position,
399                modifiers: *modifiers,
400            },
401            CursorEntered { device_id } => CursorEntered {
402                device_id: *device_id,
403            },
404            CursorLeft { device_id } => CursorLeft {
405                device_id: *device_id,
406            },
407            #[allow(deprecated)]
408            MouseWheel {
409                device_id,
410                delta,
411                phase,
412                modifiers,
413            } => MouseWheel {
414                device_id: *device_id,
415                delta: *delta,
416                phase: *phase,
417                modifiers: *modifiers,
418            },
419            #[allow(deprecated)]
420            MouseInput {
421                device_id,
422                state,
423                button,
424                modifiers,
425            } => MouseInput {
426                device_id: *device_id,
427                state: *state,
428                button: *button,
429                modifiers: *modifiers,
430            },
431            TouchpadPressure {
432                device_id,
433                pressure,
434                stage,
435            } => TouchpadPressure {
436                device_id: *device_id,
437                pressure: *pressure,
438                stage: *stage,
439            },
440            AxisMotion {
441                device_id,
442                axis,
443                value,
444            } => AxisMotion {
445                device_id: *device_id,
446                axis: *axis,
447                value: *value,
448            },
449            Touch(touch) => Touch(*touch),
450            ThemeChanged(theme) => ThemeChanged(theme.clone()),
451            ScaleFactorChanged { .. } => {
452                unreachable!("Static event can't be about scale factor changing")
453            },
454            Command(c) => Command(*c),
455        };
456    }
457}
458
459impl<'a> WindowEvent<'a> {
460    pub fn to_static(self) -> Option<WindowEvent<'static>> {
461        use self::WindowEvent::*;
462        match self {
463            Resized(size) => Some(Resized(size)),
464            Moved(position) => Some(Moved(position)),
465            CloseRequested => Some(CloseRequested),
466            Destroyed => Some(Destroyed),
467            DroppedFile(file) => Some(DroppedFile(file)),
468            HoveredFile(file) => Some(HoveredFile(file)),
469            HoveredFileCancelled => Some(HoveredFileCancelled),
470            ReceivedCharacter(c) => Some(ReceivedCharacter(c)),
471            Focused(focused) => Some(Focused(focused)),
472            KeyboardInput {
473                device_id,
474                input,
475                is_synthetic,
476            } => Some(KeyboardInput {
477                device_id,
478                input,
479                is_synthetic,
480            }),
481            ModifiersChanged(modifiers) => Some(ModifiersChanged(modifiers)),
482            #[allow(deprecated)]
483            CursorMoved {
484                device_id,
485                position,
486                modifiers,
487            } => Some(CursorMoved {
488                device_id,
489                position,
490                modifiers,
491            }),
492            CursorEntered { device_id } => Some(CursorEntered { device_id }),
493            CursorLeft { device_id } => Some(CursorLeft { device_id }),
494            #[allow(deprecated)]
495            MouseWheel {
496                device_id,
497                delta,
498                phase,
499                modifiers,
500            } => Some(MouseWheel {
501                device_id,
502                delta,
503                phase,
504                modifiers,
505            }),
506            #[allow(deprecated)]
507            MouseInput {
508                device_id,
509                state,
510                button,
511                modifiers,
512            } => Some(MouseInput {
513                device_id,
514                state,
515                button,
516                modifiers,
517            }),
518            TouchpadPressure {
519                device_id,
520                pressure,
521                stage,
522            } => Some(TouchpadPressure {
523                device_id,
524                pressure,
525                stage,
526            }),
527            AxisMotion {
528                device_id,
529                axis,
530                value,
531            } => Some(AxisMotion {
532                device_id,
533                axis,
534                value,
535            }),
536            Touch(touch) => Some(Touch(touch)),
537            ThemeChanged(theme) => Some(ThemeChanged(theme)),
538            ScaleFactorChanged { .. } => None,
539            Command(c) => Some(Command(c)),
540        }
541    }
542}
543
544/// Identifier of an input device.
545///
546/// Whenever you receive an event arising from a particular input device, this event contains a `DeviceId` which
547/// identifies its origin. Note that devices may be virtual (representing an on-screen cursor and keyboard focus) or
548/// physical. Virtual devices typically aggregate inputs from multiple physical devices.
549#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
550pub struct DeviceId(pub(crate) platform_impl::DeviceId);
551
552impl DeviceId {
553    /// Returns a dummy `DeviceId`, useful for unit testing. The only guarantee made about the return
554    /// value of this function is that it will always be equal to itself and to future values returned
555    /// by this function.  No other guarantees are made. This may be equal to a real `DeviceId`.
556    ///
557    /// **Passing this into a winit function will result in undefined behavior.**
558    pub unsafe fn dummy() -> Self {
559        DeviceId(platform_impl::DeviceId::dummy())
560    }
561}
562
563/// Represents raw hardware events that are not associated with any particular window.
564///
565/// Useful for interactions that diverge significantly from a conventional 2D GUI, such as 3D camera or first-person
566/// game controls. Many physical actions, such as mouse movement, can produce both device and window events. Because
567/// window events typically arise from virtual devices (corresponding to GUI cursors and keyboard focus) the device IDs
568/// may not match.
569///
570/// Note that these events are delivered regardless of input focus.
571#[derive(Clone, Debug, PartialEq)]
572pub enum DeviceEvent {
573    Added,
574    Removed,
575
576    /// Change in physical position of a pointing device.
577    ///
578    /// This represents raw, unfiltered physical motion. Not to be confused with `WindowEvent::CursorMoved`.
579    MouseMotion {
580        /// (x, y) change in position in unspecified units.
581        ///
582        /// Different devices may use different units.
583        delta: (f64, f64),
584    },
585
586    /// Physical scroll event
587    MouseWheel {
588        delta: MouseScrollDelta,
589    },
590
591    /// Motion on some analog axis.  This event will be reported for all arbitrary input devices
592    /// that winit supports on this platform, including mouse devices.  If the device is a mouse
593    /// device then this will be reported alongside the MouseMotion event.
594    Motion {
595        axis: AxisId,
596        value: f64,
597    },
598
599    Button {
600        button: ButtonId,
601        state: ElementState,
602    },
603
604    Key(KeyboardInput),
605
606    Text {
607        codepoint: char,
608    },
609}
610
611/// Describes a keyboard input event.
612#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
613#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
614pub struct KeyboardInput {
615    /// Identifies the physical key pressed
616    ///
617    /// This should not change if the user adjusts the host's keyboard map. Use when the physical location of the
618    /// key is more important than the key's host GUI semantics, such as for movement controls in a first-person
619    /// game.
620    pub scancode: ScanCode,
621
622    pub state: ElementState,
623
624    /// Identifies the semantic meaning of the key
625    ///
626    /// Use when the semantics of the key are more important than the physical location of the key, such as when
627    /// implementing appropriate behavior for "page up."
628    pub virtual_keycode: Option<VirtualKeyCode>,
629
630    /// Modifier keys active at the time of this input.
631    ///
632    /// This is tracked internally to avoid tracking errors arising from modifier key state changes when events from
633    /// this device are not being delivered to the application, e.g. due to keyboard focus being elsewhere.
634    #[deprecated = "Deprecated in favor of WindowEvent::ModifiersChanged"]
635    pub modifiers: ModifiersState,
636}
637
638/// Describes touch-screen input state.
639#[derive(Debug, Hash, PartialEq, Eq, Clone, Copy)]
640#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
641pub enum TouchPhase {
642    Started,
643    Moved,
644    Ended,
645    Cancelled,
646}
647
648/// Represents a touch event
649///
650/// Every time the user touches the screen, a new `Start` event with an unique
651/// identifier for the finger is generated. When the finger is lifted, an `End`
652/// event is generated with the same finger id.
653///
654/// After a `Start` event has been emitted, there may be zero or more `Move`
655/// events when the finger is moved or the touch pressure changes.
656///
657/// The finger id may be reused by the system after an `End` event. The user
658/// should assume that a new `Start` event received with the same id has nothing
659/// to do with the old finger and is a new finger.
660///
661/// A `Cancelled` event is emitted when the system has canceled tracking this
662/// touch, such as when the window loses focus, or on iOS if the user moves the
663/// device against their face.
664#[derive(Debug, Clone, Copy, PartialEq)]
665pub struct Touch {
666    pub device_id: DeviceId,
667    pub phase: TouchPhase,
668    pub location: PhysicalPosition<f64>,
669    /// Describes how hard the screen was pressed. May be `None` if the platform
670    /// does not support pressure sensitivity.
671    ///
672    /// ## Platform-specific
673    ///
674    /// - Only available on **iOS** 9.0+ and **Windows** 8+.
675    pub force: Option<Force>,
676    /// Unique identifier of a finger.
677    pub id: u64,
678}
679
680/// Describes the force of a touch event
681#[derive(Debug, Clone, Copy, PartialEq)]
682pub enum Force {
683    /// On iOS, the force is calibrated so that the same number corresponds to
684    /// roughly the same amount of pressure on the screen regardless of the
685    /// device.
686    Calibrated {
687        /// The force of the touch, where a value of 1.0 represents the force of
688        /// an average touch (predetermined by the system, not user-specific).
689        ///
690        /// The force reported by Apple Pencil is measured along the axis of the
691        /// pencil. If you want a force perpendicular to the device, you need to
692        /// calculate this value using the `altitude_angle` value.
693        force: f64,
694        /// The maximum possible force for a touch.
695        ///
696        /// The value of this field is sufficiently high to provide a wide
697        /// dynamic range for values of the `force` field.
698        max_possible_force: f64,
699        /// The altitude (in radians) of the stylus.
700        ///
701        /// A value of 0 radians indicates that the stylus is parallel to the
702        /// surface. The value of this property is Pi/2 when the stylus is
703        /// perpendicular to the surface.
704        altitude_angle: Option<f64>,
705    },
706    /// If the platform reports the force as normalized, we have no way of
707    /// knowing how much pressure 1.0 corresponds to – we know it's the maximum
708    /// amount of force, but as to how much force, you might either have to
709    /// press really really hard, or not hard at all, depending on the device.
710    Normalized(f64),
711}
712
713impl Force {
714    /// Returns the force normalized to the range between 0.0 and 1.0 inclusive.
715    /// Instead of normalizing the force, you should prefer to handle
716    /// `Force::Calibrated` so that the amount of force the user has to apply is
717    /// consistent across devices.
718    pub fn normalized(&self) -> f64 {
719        match self {
720            Force::Calibrated {
721                force,
722                max_possible_force,
723                altitude_angle,
724            } => {
725                let force = match altitude_angle {
726                    Some(altitude_angle) => force / altitude_angle.sin(),
727                    None => *force,
728                };
729                force / max_possible_force
730            }
731            Force::Normalized(force) => *force,
732        }
733    }
734}
735
736/// Hardware-dependent keyboard scan code.
737pub type ScanCode = u32;
738
739/// Identifier for a specific analog axis on some device.
740pub type AxisId = u32;
741
742/// Identifier for a specific button on some device.
743pub type ButtonId = u32;
744
745/// Describes the input state of a key.
746#[derive(Debug, Hash, PartialEq, Eq, Clone, Copy)]
747#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
748pub enum ElementState {
749    Pressed,
750    Released,
751}
752
753/// Describes a button of a mouse controller.
754#[derive(Debug, Hash, PartialEq, Eq, Clone, Copy)]
755#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
756pub enum MouseButton {
757    Left,
758    Right,
759    Middle,
760    Other(u16),
761}
762
763/// Describes a difference in the mouse scroll wheel state.
764#[derive(Debug, Clone, Copy, PartialEq)]
765#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
766pub enum MouseScrollDelta {
767    /// Amount in lines or rows to scroll in the horizontal
768    /// and vertical directions.
769    ///
770    /// Positive values indicate movement forward
771    /// (away from the user) or rightwards.
772    LineDelta(f32, f32),
773    /// Amount in pixels to scroll in the horizontal and
774    /// vertical direction.
775    ///
776    /// Scroll events are expressed as a PixelDelta if
777    /// supported by the device (eg. a touchpad) and
778    /// platform.
779    PixelDelta(PhysicalPosition<f64>),
780}
781
782/// Symbolic name for a keyboard key.
783#[derive(Debug, Hash, Ord, PartialOrd, PartialEq, Eq, Clone, Copy)]
784#[repr(u32)]
785#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
786pub enum VirtualKeyCode {
787    /// The '1' key over the letters.
788    Key1,
789    /// The '2' key over the letters.
790    Key2,
791    /// The '3' key over the letters.
792    Key3,
793    /// The '4' key over the letters.
794    Key4,
795    /// The '5' key over the letters.
796    Key5,
797    /// The '6' key over the letters.
798    Key6,
799    /// The '7' key over the letters.
800    Key7,
801    /// The '8' key over the letters.
802    Key8,
803    /// The '9' key over the letters.
804    Key9,
805    /// The '0' key over the 'O' and 'P' keys.
806    Key0,
807
808    A,
809    B,
810    C,
811    D,
812    E,
813    F,
814    G,
815    H,
816    I,
817    J,
818    K,
819    L,
820    M,
821    N,
822    O,
823    P,
824    Q,
825    R,
826    S,
827    T,
828    U,
829    V,
830    W,
831    X,
832    Y,
833    Z,
834
835    /// The Escape key, next to F1.
836    Escape,
837
838    F1,
839    F2,
840    F3,
841    F4,
842    F5,
843    F6,
844    F7,
845    F8,
846    F9,
847    F10,
848    F11,
849    F12,
850    F13,
851    F14,
852    F15,
853    F16,
854    F17,
855    F18,
856    F19,
857    F20,
858    F21,
859    F22,
860    F23,
861    F24,
862
863    /// Print Screen/SysRq.
864    Snapshot,
865    /// Scroll Lock.
866    Scroll,
867    /// Pause/Break key, next to Scroll lock.
868    Pause,
869
870    /// `Insert`, next to Backspace.
871    Insert,
872    Home,
873    Delete,
874    End,
875    PageDown,
876    PageUp,
877
878    Left,
879    Up,
880    Right,
881    Down,
882
883    /// The Backspace key, right over Enter.
884    // TODO: rename
885    Back,
886    /// The Enter key.
887    Return,
888    /// The space bar.
889    Space,
890
891    /// The "Compose" key on Linux.
892    Compose,
893
894    Caret,
895
896    Numlock,
897    Numpad0,
898    Numpad1,
899    Numpad2,
900    Numpad3,
901    Numpad4,
902    Numpad5,
903    Numpad6,
904    Numpad7,
905    Numpad8,
906    Numpad9,
907    NumpadAdd,
908    NumpadDivide,
909    NumpadDecimal,
910    NumpadComma,
911    NumpadEnter,
912    NumpadEquals,
913    NumpadMultiply,
914    NumpadSubtract,
915
916    AbntC1,
917    AbntC2,
918    Apostrophe,
919    Apps,
920    Asterisk,
921    At,
922    Ax,
923    Backslash,
924    Calculator,
925    Capital,
926    Colon,
927    Comma,
928    Convert,
929    Equals,
930    Grave,
931    Kana,
932    Kanji,
933    LAlt,
934    LBracket,
935    LControl,
936    LShift,
937    LWin,
938    Mail,
939    MediaSelect,
940    MediaStop,
941    Minus,
942    Mute,
943    MyComputer,
944    // also called "Next"
945    NavigateForward,
946    // also called "Prior"
947    NavigateBackward,
948    NextTrack,
949    NoConvert,
950    OEM102,
951    Period,
952    PlayPause,
953    Plus,
954    Power,
955    PrevTrack,
956    RAlt,
957    RBracket,
958    RControl,
959    RShift,
960    RWin,
961    Semicolon,
962    Slash,
963    Sleep,
964    Stop,
965    Sysrq,
966    Tab,
967    Underline,
968    Unlabeled,
969    VolumeDown,
970    VolumeUp,
971    Wake,
972    WebBack,
973    WebFavorites,
974    WebForward,
975    WebHome,
976    WebRefresh,
977    WebSearch,
978    WebStop,
979    Yen,
980    Copy,
981    Paste,
982    Cut,
983}
984
985impl ModifiersState {
986    /// Returns `true` if the shift key is pressed.
987    pub fn shift(&self) -> bool {
988        self.intersects(Self::SHIFT)
989    }
990    /// Returns `true` if the control key is pressed.
991    pub fn ctrl(&self) -> bool {
992        self.intersects(Self::CTRL)
993    }
994    /// Returns `true` if the alt key is pressed.
995    pub fn alt(&self) -> bool {
996        self.intersects(Self::ALT)
997    }
998    /// Returns `true` if the logo key is pressed.
999    pub fn logo(&self) -> bool {
1000        self.intersects(Self::LOGO)
1001    }
1002}
1003
1004bitflags! {
1005    /// Represents the current state of the keyboard modifiers
1006    ///
1007    /// Each flag represents a modifier and is set if this modifier is active.
1008    #[derive(Default)]
1009    pub struct ModifiersState: u32 {
1010        // left and right modifiers are currently commented out, but we should be able to support
1011        // them in a future release
1012        /// The "shift" key.
1013        const SHIFT = 0b100 << 0;
1014        // const LSHIFT = 0b010 << 0;
1015        // const RSHIFT = 0b001 << 0;
1016        /// The "control" key.
1017        const CTRL = 0b100 << 3;
1018        // const LCTRL = 0b010 << 3;
1019        // const RCTRL = 0b001 << 3;
1020        /// The "alt" key.
1021        const ALT = 0b100 << 6;
1022        // const LALT = 0b010 << 6;
1023        // const RALT = 0b001 << 6;
1024        /// This is the "windows" key on PC and "command" key on Mac.
1025        const LOGO = 0b100 << 9;
1026        // const LLOGO = 0b010 << 9;
1027        // const RLOGO = 0b001 << 9;
1028    }
1029}
1030
1031#[cfg(feature = "serde")]
1032mod modifiers_serde {
1033    use super::ModifiersState;
1034    use serde::{Deserialize, Deserializer, Serialize, Serializer};
1035
1036    #[derive(Default, Serialize, Deserialize)]
1037    #[serde(default)]
1038    #[serde(rename = "ModifiersState")]
1039    pub struct ModifiersStateSerialize {
1040        pub shift: bool,
1041        pub ctrl: bool,
1042        pub alt: bool,
1043        pub logo: bool,
1044    }
1045
1046    impl Serialize for ModifiersState {
1047        fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
1048        where
1049            S: Serializer,
1050        {
1051            let s = ModifiersStateSerialize {
1052                shift: self.shift(),
1053                ctrl: self.ctrl(),
1054                alt: self.alt(),
1055                logo: self.logo(),
1056            };
1057            s.serialize(serializer)
1058        }
1059    }
1060
1061    impl<'de> Deserialize<'de> for ModifiersState {
1062        fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
1063        where
1064            D: Deserializer<'de>,
1065        {
1066            let ModifiersStateSerialize {
1067                shift,
1068                ctrl,
1069                alt,
1070                logo,
1071            } = ModifiersStateSerialize::deserialize(deserializer)?;
1072            let mut m = ModifiersState::empty();
1073            m.set(ModifiersState::SHIFT, shift);
1074            m.set(ModifiersState::CTRL, ctrl);
1075            m.set(ModifiersState::ALT, alt);
1076            m.set(ModifiersState::LOGO, logo);
1077            Ok(m)
1078        }
1079    }
1080}