dioxus_gestures/state/gestures/
down_pointer.rs

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}