dioxus_html/events/
pointer.rs1use dioxus_core::Event;
2use keyboard_types::Modifiers;
3
4use crate::{geometry::*, input_data::*, *};
5
6pub type PointerEvent = Event<PointerData>;
8
9pub struct PointerData {
10 inner: Box<dyn HasPointerData>,
11}
12
13impl PointerData {
14 pub fn new(data: impl HasPointerData + 'static) -> Self {
16 Self::from(data)
17 }
18
19 #[inline(always)]
21 pub fn downcast<T: 'static>(&self) -> Option<&T> {
22 self.inner.as_any().downcast_ref::<T>()
23 }
24}
25
26impl<E: HasPointerData + 'static> From<E> for PointerData {
27 fn from(e: E) -> Self {
28 Self { inner: Box::new(e) }
29 }
30}
31
32impl std::fmt::Debug for PointerData {
33 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
34 f.debug_struct("PointerData")
35 .field("pointer_id", &self.pointer_id())
36 .field("width", &self.width())
37 .field("height", &self.height())
38 .field("pressure", &self.pressure())
39 .field("tangential_pressure", &self.tangential_pressure())
40 .field("tilt_x", &self.tilt_x())
41 .field("tilt_y", &self.tilt_y())
42 .field("twist", &self.twist())
43 .field("pointer_type", &self.pointer_type())
44 .field("is_primary", &self.is_primary())
45 .field("coordinates", &self.coordinates())
46 .field("modifiers", &self.modifiers())
47 .field("held_buttons", &self.held_buttons())
48 .field("trigger_button", &self.trigger_button())
49 .finish()
50 }
51}
52
53impl PartialEq for PointerData {
54 fn eq(&self, other: &Self) -> bool {
55 self.pointer_id() == other.pointer_id()
56 && self.width() == other.width()
57 && self.height() == other.height()
58 && self.pressure() == other.pressure()
59 && self.tangential_pressure() == other.tangential_pressure()
60 && self.tilt_x() == other.tilt_x()
61 && self.tilt_y() == other.tilt_y()
62 && self.twist() == other.twist()
63 && self.pointer_type() == other.pointer_type()
64 && self.is_primary() == other.is_primary()
65 && self.coordinates() == other.coordinates()
66 && self.modifiers() == other.modifiers()
67 && self.held_buttons() == other.held_buttons()
68 && self.trigger_button() == other.trigger_button()
69 }
70}
71
72pub trait HasPointerData: PointerInteraction {
74 fn pointer_id(&self) -> i32;
76
77 fn width(&self) -> f64;
79
80 fn height(&self) -> f64;
82
83 fn pressure(&self) -> f32;
85
86 fn tangential_pressure(&self) -> f32;
88
89 fn tilt_x(&self) -> i32;
91
92 fn tilt_y(&self) -> i32;
94
95 fn twist(&self) -> i32;
97
98 fn pointer_type(&self) -> String;
100
101 fn is_primary(&self) -> bool;
103
104 fn as_any(&self) -> &dyn std::any::Any;
106}
107
108impl PointerData {
109 pub fn pointer_id(&self) -> i32 {
111 self.inner.pointer_id()
112 }
113
114 pub fn width(&self) -> f64 {
116 self.inner.width()
117 }
118
119 pub fn height(&self) -> f64 {
121 self.inner.height()
122 }
123
124 pub fn pressure(&self) -> f32 {
126 self.inner.pressure()
127 }
128
129 pub fn tangential_pressure(&self) -> f32 {
131 self.inner.tangential_pressure()
132 }
133
134 pub fn tilt_x(&self) -> i32 {
136 self.inner.tilt_x()
137 }
138
139 pub fn tilt_y(&self) -> i32 {
141 self.inner.tilt_y()
142 }
143
144 pub fn twist(&self) -> i32 {
146 self.inner.twist()
147 }
148
149 pub fn pointer_type(&self) -> String {
151 self.inner.pointer_type()
152 }
153
154 pub fn is_primary(&self) -> bool {
156 self.inner.is_primary()
157 }
158}
159
160impl InteractionLocation for PointerData {
161 fn client_coordinates(&self) -> ClientPoint {
162 self.inner.client_coordinates()
163 }
164
165 fn screen_coordinates(&self) -> ScreenPoint {
166 self.inner.screen_coordinates()
167 }
168
169 fn page_coordinates(&self) -> PagePoint {
170 self.inner.page_coordinates()
171 }
172}
173
174impl InteractionElementOffset for PointerData {
175 fn element_coordinates(&self) -> ElementPoint {
176 self.inner.element_coordinates()
177 }
178}
179
180impl ModifiersInteraction for PointerData {
181 fn modifiers(&self) -> Modifiers {
182 self.inner.modifiers()
183 }
184}
185
186impl PointerInteraction for PointerData {
187 fn held_buttons(&self) -> MouseButtonSet {
188 self.inner.held_buttons()
189 }
190
191 fn trigger_button(&self) -> Option<MouseButton> {
192 self.inner.trigger_button()
193 }
194}
195
196#[cfg(feature = "serialize")]
197#[derive(serde::Serialize, serde::Deserialize, Debug, PartialEq, Clone)]
199pub struct SerializedPointerData {
200 #[serde(flatten)]
202 point_data: crate::point_interaction::SerializedPointInteraction,
203
204 pointer_id: i32,
206
207 width: f64,
209
210 height: f64,
212
213 pressure: f32,
215
216 tangential_pressure: f32,
218
219 tilt_x: i32,
221
222 tilt_y: i32,
224
225 twist: i32,
227
228 pointer_type: String,
230
231 is_primary: bool,
233}
234
235#[cfg(feature = "serialize")]
236impl HasPointerData for SerializedPointerData {
237 fn pointer_id(&self) -> i32 {
238 self.pointer_id
239 }
240
241 fn width(&self) -> f64 {
242 self.width
243 }
244
245 fn height(&self) -> f64 {
246 self.height
247 }
248
249 fn pressure(&self) -> f32 {
250 self.pressure
251 }
252
253 fn tangential_pressure(&self) -> f32 {
254 self.tangential_pressure
255 }
256
257 fn tilt_x(&self) -> i32 {
258 self.tilt_x
259 }
260
261 fn tilt_y(&self) -> i32 {
262 self.tilt_y
263 }
264
265 fn twist(&self) -> i32 {
266 self.twist
267 }
268
269 fn pointer_type(&self) -> String {
270 self.pointer_type.clone()
271 }
272
273 fn is_primary(&self) -> bool {
274 self.is_primary
275 }
276
277 fn as_any(&self) -> &dyn std::any::Any {
278 self
279 }
280}
281
282#[cfg(feature = "serialize")]
283impl InteractionLocation for SerializedPointerData {
284 fn client_coordinates(&self) -> ClientPoint {
285 self.point_data.client_coordinates()
286 }
287
288 fn screen_coordinates(&self) -> ScreenPoint {
289 self.point_data.screen_coordinates()
290 }
291
292 fn page_coordinates(&self) -> PagePoint {
293 self.point_data.page_coordinates()
294 }
295}
296
297#[cfg(feature = "serialize")]
298impl InteractionElementOffset for SerializedPointerData {
299 fn element_coordinates(&self) -> ElementPoint {
300 self.point_data.element_coordinates()
301 }
302}
303
304#[cfg(feature = "serialize")]
305impl ModifiersInteraction for SerializedPointerData {
306 fn modifiers(&self) -> Modifiers {
307 self.point_data.modifiers()
308 }
309}
310
311#[cfg(feature = "serialize")]
312impl PointerInteraction for SerializedPointerData {
313 fn held_buttons(&self) -> MouseButtonSet {
314 self.point_data.held_buttons()
315 }
316
317 fn trigger_button(&self) -> Option<MouseButton> {
318 self.point_data.trigger_button()
319 }
320}
321
322#[cfg(feature = "serialize")]
323impl From<&PointerData> for SerializedPointerData {
324 fn from(data: &PointerData) -> Self {
325 Self {
326 point_data: data.into(),
327 pointer_id: data.pointer_id(),
328 width: data.width(),
329 height: data.height(),
330 pressure: data.pressure(),
331 tangential_pressure: data.tangential_pressure(),
332 tilt_x: data.tilt_x(),
333 tilt_y: data.tilt_y(),
334 twist: data.twist(),
335 pointer_type: data.pointer_type().to_string(),
336 is_primary: data.is_primary(),
337 }
338 }
339}
340
341#[cfg(feature = "serialize")]
342impl serde::Serialize for PointerData {
343 fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
344 SerializedPointerData::from(self).serialize(serializer)
345 }
346}
347
348#[cfg(feature = "serialize")]
349impl<'de> serde::Deserialize<'de> for PointerData {
350 fn deserialize<D: serde::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
351 let data = SerializedPointerData::deserialize(deserializer)?;
352 Ok(Self {
353 inner: Box::new(data),
354 })
355 }
356}