zng_view_api/raw_input.rs
1//! Types for "input" devices.
2//!
3//! This represents the more basic subset of HIDs, keyboard, mouse, game controllers, it does not include media devices.
4
5use bitflags::bitflags;
6use serde::{Deserialize, Serialize};
7use zng_txt::Txt;
8
9use crate::{
10 AxisId,
11 keyboard::{KeyCode, KeyState},
12 mouse::{ButtonId, ButtonState, MouseScrollDelta},
13};
14
15crate::declare_id! {
16 /// Input device ID in channel.
17 ///
18 /// In the View Process this is mapped to a system id.
19 ///
20 /// In the App Process this is mapped to an unique id, but does not survived View crashes.
21 ///
22 /// The View Process defines the ID.
23 pub struct InputDeviceId(_);
24}
25
26/// Info about an human input device.
27#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
28#[non_exhaustive]
29pub struct InputDeviceInfo {
30 /// Display name.
31 pub name: Txt,
32 /// Device capabilities.
33 pub capabilities: InputDeviceCapability,
34}
35
36impl InputDeviceInfo {
37 /// New info.
38 pub fn new(name: impl Into<Txt>, capabilities: InputDeviceCapability) -> Self {
39 Self {
40 name: name.into(),
41 capabilities,
42 }
43 }
44}
45
46bitflags! {
47 /// Capabilities of an input device.
48 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
49 pub struct InputDeviceCapability: u8 {
50 /// Device can produce keyboard key presses.
51 const KEY = 0b0000_0001;
52 /// Device can produce button presses.
53 const BUTTON = 0b0000_0010;
54 /// Device provides scrolling wheel deltas, vertical or horizontal.
55 const SCROLL_MOTION = 0b0001_0000;
56 /// Device provides axis aligned 1D motion.
57 const AXIS_MOTION = 0b0010_0000;
58 /// Device provides 2D pointer motion.
59 const POINTER_MOTION = 0b0100_0000;
60 }
61}
62
63/// Raw input device event.
64#[derive(Debug, Clone, Serialize, Deserialize)]
65#[non_exhaustive]
66pub enum InputDeviceEvent {
67 /// 2D pointer motion.
68 ///
69 /// The values if the delta of movement (x, y), not position.
70 PointerMotion {
71 /// Delta of change in the cursor position.
72 delta: euclid::Vector2D<f64, ()>,
73 },
74 /// Scroll wheel motion.
75 ScrollMotion {
76 /// Delta of change in the mouse scroll wheel state.
77 delta: MouseScrollDelta,
78 },
79 /// Motion on some analog axis.
80 ///
81 /// This includes the mouse device and any other that fits.
82 AxisMotion {
83 /// Device dependent axis of the motion.
84 axis: AxisId,
85 /// Device dependent value.
86 value: f64,
87 },
88 /// Device button press or release.
89 Button {
90 /// Device dependent button that was used.
91 button: ButtonId,
92 /// If the button was pressed or released.
93 state: ButtonState,
94 },
95 /// Device key press or release.
96 Key {
97 /// Physical key.
98 key_code: KeyCode,
99 /// If the key was pressed or released.
100 state: KeyState,
101 },
102}
103impl InputDeviceEvent {
104 /// Change `self` to incorporate `other` or returns `other` if both events cannot be coalesced.
105 pub fn coalesce(&mut self, other: Self) -> Result<(), Self> {
106 use InputDeviceEvent::*;
107 match (self, other) {
108 (PointerMotion { delta }, PointerMotion { delta: n_delta }) => {
109 *delta += n_delta;
110 }
111 (
112 ScrollMotion {
113 delta: MouseScrollDelta::LineDelta(delta_x, delta_y),
114 },
115 ScrollMotion {
116 delta: MouseScrollDelta::LineDelta(n_delta_x, n_delta_y),
117 },
118 ) => {
119 *delta_x += n_delta_x;
120 *delta_y += n_delta_y;
121 }
122
123 (
124 ScrollMotion {
125 delta: MouseScrollDelta::PixelDelta(delta_x, delta_y),
126 },
127 ScrollMotion {
128 delta: MouseScrollDelta::PixelDelta(n_delta_x, n_delta_y),
129 },
130 ) => {
131 *delta_x += n_delta_x;
132 *delta_y += n_delta_y;
133 }
134 (_, e) => return Err(e),
135 }
136 Ok(())
137 }
138}