zng_app/view_process/
raw_device_events.rs1use std::{collections::HashMap, fmt};
10
11use crate::event::*;
12
13use zng_layout::unit::euclid;
14use zng_var::{Var, var};
15use zng_view_api::{
16 keyboard::{KeyCode, KeyState},
17 mouse::{ButtonId, ButtonState, MouseScrollDelta},
18};
19
20pub use zng_view_api::AxisId;
21pub use zng_view_api::raw_input::{InputDeviceCapability, InputDeviceInfo};
22
23use once_cell::sync::Lazy;
24
25zng_unique_id::unique_id_64! {
26 pub struct InputDeviceId;
28}
29zng_unique_id::impl_unique_id_bytemuck!(InputDeviceId);
30impl InputDeviceId {
31 pub fn virtual_keyboard() -> InputDeviceId {
33 static ID: Lazy<InputDeviceId> = Lazy::new(InputDeviceId::new_unique);
34 *ID
35 }
36
37 pub fn virtual_mouse() -> InputDeviceId {
39 static ID: Lazy<InputDeviceId> = Lazy::new(InputDeviceId::new_unique);
40 *ID
41 }
42
43 pub fn virtual_generic() -> InputDeviceId {
45 static ID: Lazy<InputDeviceId> = Lazy::new(InputDeviceId::new_unique);
46 *ID
47 }
48}
49impl fmt::Debug for InputDeviceId {
50 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
51 if f.alternate() {
52 f.debug_struct("InputDeviceId")
53 .field("id", &self.get())
54 .field("sequential", &self.sequential())
55 .finish()
56 } else {
57 write!(f, "InputDeviceId({})", self.sequential())
58 }
59 }
60}
61impl fmt::Display for InputDeviceId {
62 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
63 write!(f, "InputDeviceId({})", self.get())
64 }
65}
66
67event_args! {
68 pub struct InputDevicesChangedArgs {
70 pub devices: HashMap<InputDeviceId, InputDeviceInfo>,
72
73 ..
74
75 fn delivery_list(&self, list: &mut UpdateDeliveryList) {
77 list.search_all()
78 }
79 }
80
81 pub struct PointerMotionArgs {
83 pub device_id: InputDeviceId,
85
86 pub delta: euclid::Vector2D<f64, ()>,
88
89 ..
90
91 fn delivery_list(&self, list: &mut UpdateDeliveryList) {
93 list.search_all()
94 }
95 }
96
97 pub struct ScrollMotionArgs {
99 pub device_id: InputDeviceId,
101
102 pub delta: MouseScrollDelta,
104
105 ..
106
107 fn delivery_list(&self, list: &mut UpdateDeliveryList) {
109 list.search_all()
110 }
111 }
112
113 pub struct AxisMotionArgs {
115 pub device_id: InputDeviceId,
117
118 pub axis: AxisId,
120
121 pub value: f64,
123
124 ..
125
126 fn delivery_list(&self, list: &mut UpdateDeliveryList) {
128 list.search_all()
129 }
130 }
131
132 pub struct ButtonArgs {
134 pub device_id: InputDeviceId,
136
137 pub button: ButtonId,
139
140 pub state: ButtonState,
142
143 ..
144
145 fn delivery_list(&self, list: &mut UpdateDeliveryList) {
147 list.search_all()
148 }
149 }
150
151 pub struct KeyArgs {
153 pub device_id: InputDeviceId,
155
156 pub key_code: KeyCode,
158
159 pub state: KeyState,
161
162 ..
163
164 fn delivery_list(&self, list: &mut UpdateDeliveryList) {
166 list.search_all()
167 }
168 }
169}
170
171event! {
172 pub static INPUT_DEVICES_CHANGED_EVENT: InputDevicesChangedArgs;
174
175 pub static POINTER_MOTION_EVENT: PointerMotionArgs;
177
178 pub static SCROLL_MOTION_EVENT: ScrollMotionArgs;
180
181 pub static AXIS_MOTION_EVENT: AxisMotionArgs;
186
187 pub static BUTTON_EVENT: ButtonArgs;
189
190 pub static KEY_EVENT: KeyArgs;
192}
193
194#[allow(non_camel_case_types)]
200pub struct INPUT_DEVICES;
201
202impl INPUT_DEVICES {
203 pub fn available_devices(&self) -> Var<HashMap<InputDeviceId, InputDeviceInfo>> {
205 INPUT_DEVICES_SV.read().devices.read_only()
206 }
207
208 pub fn device(&self, id: InputDeviceId) -> Var<InputDeviceInfo> {
212 INPUT_DEVICES_SV.read().devices.map(move |m| {
213 m.get(&id)
214 .cloned()
215 .unwrap_or_else(|| InputDeviceInfo::new("Unknown Input Device", InputDeviceCapability::empty()))
216 })
217 }
218
219 pub(crate) fn update(&self, devices: HashMap<InputDeviceId, InputDeviceInfo>) {
220 INPUT_DEVICES_SV.read().devices.set(devices);
221 }
222}
223
224struct InputDevicesSv {
225 devices: Var<HashMap<InputDeviceId, InputDeviceInfo>>,
226}
227app_local! {
228 static INPUT_DEVICES_SV: InputDevicesSv = InputDevicesSv {
229 devices: var(HashMap::new()),
230 };
231}