1use std::rc::Rc;
2
3use dioxus::core::Event;
4use dioxus::html::PointerData;
5
6use crate::state::{
7 events::PointerEventReceiver,
8 gestures::{
9 drag::{Drag, DragCancelData, DragEndData, DragStartData, DragUpdateData},
10 pinch::{
11 Pinch, PinchCancelData, PinchEndData, PinchStartData, PinchUpdateData,
12 PinchUpdatedPointer,
13 },
14 pointer::{IncrementalOffsetPointer, InitialPointer, OffsetPointer, PointerId},
15 },
16};
17
18#[derive(Clone)]
19pub struct DownPointerGestureState {
20 drag: Drag,
21 pinch: Pinch,
22 pointers: Vec<DownPointerState>,
23 gesture_state: GestureState,
24}
25
26#[derive(Clone, Default)]
27enum GestureState {
28 #[default]
29 Pending,
30 Started,
31}
32
33#[derive(Clone)]
34struct DownPointerState {
35 id: PointerId,
36 initial: Rc<PointerData>,
37 current: Rc<PointerData>,
38}
39
40impl DownPointerGestureState {
41 pub fn new(drag: Drag, pinch: Pinch) -> Self {
42 Self {
43 drag,
44 pinch,
45 pointers: Vec::new(),
46 gesture_state: GestureState::default(),
47 }
48 }
49
50 fn add_down_pointer_event(&mut self, pointer_data: Rc<PointerData>) {
51 self.pointers.push(DownPointerState {
52 id: PointerId::from(pointer_data.pointer_id()),
53 initial: Rc::clone(&pointer_data),
54 current: Rc::clone(&pointer_data),
55 });
56
57 match self.pointers.len() {
58 1 => {
59 self.gesture_state = match (self.drag.has_started)([&pointer_data, &pointer_data]) {
60 false => GestureState::Pending,
61 true => GestureState::Started,
62 };
63
64 match self.gesture_state {
65 GestureState::Started => {
66 if let Some(handler) = &self.drag.on_start {
67 handler.borrow_mut()(DragStartData {
68 pointer: InitialPointer { data: pointer_data },
69 })
70 }
71 }
72 _ => (),
73 }
74 }
75 2 => {
76 if let Some(handler) = &self.drag.on_end {
77 let existing_pointer = &self.pointers[0];
78 handler.borrow_mut()(DragEndData {
79 pointer: OffsetPointer {
80 initial_data: Rc::clone(&existing_pointer.initial),
81 final_data: Rc::clone(&pointer_data),
82 },
83 });
84 }
85
86 self.pointers[0].initial = Rc::clone(&self.pointers[0].current);
87
88 self.gesture_state = match (self.pinch.has_started)(
89 [&self.pointers[0].initial, &self.pointers[0].initial],
90 [&pointer_data, &pointer_data],
91 ) {
92 false => GestureState::Pending,
93 true => GestureState::Started,
94 };
95
96 match self.gesture_state {
97 GestureState::Started => {
98 if let Some(handler) = &self.pinch.on_start {
99 handler.borrow_mut()(PinchStartData {
100 pointers: [
101 InitialPointer {
102 data: Rc::clone(&self.pointers[0].initial),
103 },
104 InitialPointer { data: pointer_data },
105 ],
106 });
107 }
108 }
109 _ => (),
110 }
111 }
112 3 => {
113 if let Some(handler) = &self.pinch.on_end {
114 let [first, second]: &[DownPointerState; 2] =
115 self.pointers[0..=1].try_into().unwrap();
116 handler.borrow_mut()(PinchEndData {
117 pointers: [
118 {
119 OffsetPointer {
120 initial_data: Rc::clone(&first.initial),
121 final_data: Rc::clone(&first.current),
122 }
123 },
124 {
125 OffsetPointer {
126 initial_data: Rc::clone(&second.initial),
127 final_data: Rc::clone(&second.current),
128 }
129 },
130 ],
131 });
132 }
133 }
134 _ => {}
135 }
136 }
137
138 fn update_known_down_pointer_event(&mut self, index: usize, pointer_data: Rc<PointerData>) {
139 let initial_data = Rc::clone(&self.pointers[index].initial);
140 let preceding_data = Rc::clone(&self.pointers[index].current);
141 self.pointers[index].current = Rc::clone(&pointer_data);
142
143 match self.pointers.len() {
144 1 => {
145 match self.gesture_state {
146 GestureState::Pending => {
147 match (self.drag.has_started)([&initial_data, &pointer_data]) {
148 false => (),
149 true => {
150 self.gesture_state = GestureState::Started;
151 if let Some(handler) = &self.drag.on_start {
152 handler.borrow_mut()(DragStartData {
153 pointer: InitialPointer {
154 data: Rc::clone(&initial_data),
155 },
156 });
157 }
158 }
159 }
160 }
161 GestureState::Started => match &self.drag.on_update {
162 Some(handler) => {
163 (handler.borrow_mut())(DragUpdateData {
164 pointer: IncrementalOffsetPointer {
165 initial_data,
166 preceding_data,
167 current_data: Rc::clone(&pointer_data),
168 },
169 });
170 }
171 None => (),
172 },
173 };
174 }
175 2 => {
176 let [first, second]: &[DownPointerState; 2] =
177 self.pointers[0..=1].try_into().unwrap();
178 match self.gesture_state {
179 GestureState::Pending => match (self.pinch.has_started)(
180 [&first.initial, &first.current],
181 [&second.initial, &second.current],
182 ) {
183 false => (),
184 true => {
185 self.gesture_state = GestureState::Started;
186 if let Some(handler) = &self.pinch.on_start {
187 handler.borrow_mut()(PinchStartData {
188 pointers: [
189 InitialPointer {
190 data: Rc::clone(&first.initial),
191 },
192 InitialPointer {
193 data: Rc::clone(&second.initial),
194 },
195 ],
196 });
197 }
198 }
199 },
200 GestureState::Started => {
201 if let Some(handler) = &self.pinch.on_update {
202 let (pointers, updated_pointer) = if index == 0 {
203 (
204 [
205 IncrementalOffsetPointer {
206 initial_data: Rc::clone(&initial_data),
207 preceding_data,
208 current_data: pointer_data,
209 },
210 IncrementalOffsetPointer {
211 initial_data: Rc::clone(&second.initial),
212 preceding_data: Rc::clone(&second.current),
213 current_data: Rc::clone(&second.current),
214 },
215 ],
216 PinchUpdatedPointer::First,
217 )
218 } else {
219 (
220 [
221 IncrementalOffsetPointer {
222 initial_data: Rc::clone(&first.initial),
223 preceding_data: Rc::clone(&first.current),
224 current_data: Rc::clone(&first.current),
225 },
226 IncrementalOffsetPointer {
227 initial_data: Rc::clone(&initial_data),
228 preceding_data,
229 current_data: pointer_data,
230 },
231 ],
232 PinchUpdatedPointer::Second,
233 )
234 };
235 handler.borrow_mut()(PinchUpdateData {
236 pointers,
237 updated_pointer,
238 });
239 }
240 }
241 };
242 }
243 _ => {}
244 }
245 }
246
247 fn remove_known_down_pointer_event(&mut self, index: usize, pointer_data: Rc<PointerData>) {
248 let pointer = self.pointers.remove(index);
249 let initial_data = pointer.initial;
250
251 match self.pointers.len() {
252 0 => {
253 match self.gesture_state {
254 GestureState::Pending => (),
255 GestureState::Started => {
256 if let Some(handler) = &self.drag.on_end {
257 handler.borrow_mut()(DragEndData {
258 pointer: OffsetPointer {
259 initial_data,
260 final_data: pointer_data,
261 },
262 });
263 }
264 }
265 };
266 }
267 1 => {
268 match self.gesture_state {
269 GestureState::Pending => (),
270 GestureState::Started => {
271 if let Some(handler) = &self.pinch.on_end {
272 let removed = OffsetPointer {
273 initial_data,
274 final_data: pointer_data,
275 };
276 let pointer = &self.pointers[0];
277 let retained = OffsetPointer {
278 initial_data: Rc::clone(&pointer.initial),
279 final_data: Rc::clone(&pointer.current),
280 };
281 handler.borrow_mut()(PinchEndData {
282 pointers: if index == 0 {
283 [removed, retained]
284 } else {
285 [retained, removed]
286 },
287 });
288 }
289 }
290 };
291
292 self.pointers[0].initial = Rc::clone(&self.pointers[0].current);
293
294 self.gesture_state = match (self.drag.has_started)([
295 &self.pointers[0].current,
296 &self.pointers[0].current,
297 ]) {
298 false => GestureState::Pending,
299 true => GestureState::Started,
300 };
301
302 match self.gesture_state {
303 GestureState::Started => {
304 if let Some(handler) = &self.drag.on_start {
305 handler.borrow_mut()(DragStartData {
306 pointer: InitialPointer {
307 data: Rc::clone(&self.pointers[0].initial),
308 },
309 });
310 }
311 }
312 _ => (),
313 }
314 }
315 2 => {
316 self.pointers
317 .iter_mut()
318 .for_each(|pointer| pointer.initial = Rc::clone(&pointer.current));
319
320 let [first, second]: &[DownPointerState; 2] =
321 self.pointers[0..=1].try_into().unwrap();
322
323 self.gesture_state = match (self.pinch.has_started)(
324 [&first.initial, &first.current],
325 [&second.initial, &second.current],
326 ) {
327 false => GestureState::Pending,
328 true => GestureState::Started,
329 };
330
331 match self.gesture_state {
332 GestureState::Started => {
333 if let Some(handler) = &self.pinch.on_start {
334 handler.borrow_mut()(PinchStartData {
335 pointers: [
336 InitialPointer {
337 data: Rc::clone(&first.initial),
338 },
339 InitialPointer {
340 data: Rc::clone(&second.initial),
341 },
342 ],
343 });
344 }
345 }
346 _ => (),
347 }
348 }
349 _ => {}
350 }
351 }
352
353 fn cancel_known_down_pointer_event(&mut self, index: usize, pointer_data: Rc<PointerData>) {
354 let pointer = self.pointers.remove(index);
355 let initial_data = pointer.initial;
356
357 match self.pointers.len() {
358 0 => {
359 match self.gesture_state {
360 GestureState::Pending => (),
361 GestureState::Started => {
362 if let Some(handler) = &self.drag.on_cancel {
363 handler.borrow_mut()(DragCancelData {
364 pointer: OffsetPointer {
365 initial_data,
366 final_data: pointer_data,
367 },
368 });
369 }
370 }
371 };
372 }
373 1 => {
374 match self.gesture_state {
375 GestureState::Pending => (),
376 GestureState::Started => {
377 if let Some(handler) = &self.pinch.on_cancel {
378 let removed = OffsetPointer {
379 initial_data,
380 final_data: pointer_data,
381 };
382 let pointer = &self.pointers[0];
383 let retained = OffsetPointer {
384 initial_data: Rc::clone(&pointer.initial),
385 final_data: Rc::clone(&pointer.current),
386 };
387 handler.borrow_mut()(PinchCancelData {
388 pointers: if index == 0 {
389 [removed, retained]
390 } else {
391 [retained, removed]
392 },
393 });
394 }
395 }
396 };
397
398 self.pointers[0].initial = Rc::clone(&self.pointers[0].current);
399
400 self.gesture_state = match (self.drag.has_started)([
401 &self.pointers[0].current,
402 &self.pointers[0].current,
403 ]) {
404 false => GestureState::Pending,
405 true => GestureState::Started,
406 };
407
408 match self.gesture_state {
409 GestureState::Started => {
410 if let Some(handler) = &self.drag.on_start {
411 handler.borrow_mut()(DragStartData {
412 pointer: InitialPointer {
413 data: Rc::clone(&self.pointers[0].initial),
414 },
415 });
416 }
417 }
418 _ => (),
419 }
420 }
421 2 => {
422 self.pointers
423 .iter_mut()
424 .for_each(|pointer| pointer.initial = Rc::clone(&pointer.current));
425
426 let [first, second]: &[DownPointerState; 2] =
427 self.pointers[0..=1].try_into().unwrap();
428
429 self.gesture_state = match (self.pinch.has_started)(
430 [&first.initial, &first.current],
431 [&second.initial, &second.current],
432 ) {
433 false => GestureState::Pending,
434 true => GestureState::Started,
435 };
436
437 match self.gesture_state {
438 GestureState::Started => {
439 if let Some(handler) = &self.pinch.on_start {
440 handler.borrow_mut()(PinchStartData {
441 pointers: [
442 InitialPointer {
443 data: Rc::clone(&first.initial),
444 },
445 InitialPointer {
446 data: Rc::clone(&second.initial),
447 },
448 ],
449 });
450 }
451 }
452 _ => (),
453 }
454 }
455 _ => {}
456 }
457 }
458
459 fn add_or_update(&mut self, event: &Event<PointerData>) {
460 let pointer_data = event.data();
461 let pointer_id = pointer_data.pointer_id();
462 let associated_down_pointer_event = self
463 .pointers
464 .iter()
465 .position(|p| p.id.is_equal_i32(pointer_id));
466 match associated_down_pointer_event {
467 Some(position) => {
468 self.update_known_down_pointer_event(position, pointer_data);
469 }
470 None => {
471 self.add_down_pointer_event(pointer_data);
472 }
473 };
474 }
475
476 fn update(&mut self, event: &Event<PointerData>) {
477 let pointer_data = event.data();
478 let pointer_id = pointer_data.pointer_id();
479 let associated_down_pointer_event = self
480 .pointers
481 .iter()
482 .position(|p| p.id.is_equal_i32(pointer_id));
483 match associated_down_pointer_event {
484 Some(position) => {
485 self.update_known_down_pointer_event(position, pointer_data);
486 }
487 None => {}
488 };
489 }
490
491 fn remove(&mut self, event: &Event<PointerData>) {
492 let pointer_data = event.data();
493 let pointer_id = pointer_data.pointer_id();
494 let associated_down_pointer_event = self
495 .pointers
496 .iter()
497 .position(|p| p.id.is_equal_i32(pointer_id));
498 match associated_down_pointer_event {
499 Some(position) => {
500 self.remove_known_down_pointer_event(position, pointer_data);
501 }
502 None => {}
503 };
504 }
505
506 fn cancel(&mut self, event: &Event<PointerData>) {
507 let pointer_data = event.data();
508 let pointer_id = pointer_data.pointer_id();
509 let associacted_hover_event = self
510 .pointers
511 .iter()
512 .position(|p| p.id.is_equal_i32(pointer_id));
513 match associacted_hover_event {
514 Some(position) => {
515 self.cancel_known_down_pointer_event(position, pointer_data);
516 }
517 None => {}
518 };
519 }
520}
521
522impl PointerEventReceiver<&Event<PointerData>> for DownPointerGestureState {
523 fn pointer_over(&mut self, _: &Event<PointerData>) {}
524
525 fn pointer_enter(&mut self, _: &Event<PointerData>) {}
526
527 fn pointer_down(&mut self, event: &Event<PointerData>) {
528 self.add_or_update(event);
529 }
530
531 fn pointer_move(&mut self, event: &Event<PointerData>) {
532 self.update(event);
533 }
534
535 fn pointer_up(&mut self, event: &Event<PointerData>) {
536 self.remove(event);
537 }
538
539 fn pointer_cancel(&mut self, event: &Event<PointerData>) {
540 self.cancel(event);
541 }
542
543 fn pointer_out(&mut self, event: &Event<PointerData>) {
544 self.remove(event);
545 }
546
547 fn pointer_leave(&mut self, event: &Event<PointerData>) {
548 self.remove(event);
549 }
550}