1use crate::{Closure, Node, StateKV};
3use std::{collections::HashMap, sync::Arc};
4
5macro_rules! construct_gesture {
8 ($(($name:tt, $doc:expr),)*) => {
9 #[derive(Debug, Hash, PartialEq, Eq, Clone)]
11 pub enum Gesture {
12 $(
13 #[doc=$doc]
14 $name,
15 )*
16 }
17 };
18}
19
20construct_gesture! {
21 (Tap, "Trigger when tap widget"),
22 (LongTap, "Trigger when long tap widget"),
23}
24
25pub type GestureKV = HashMap<Gesture, Closure<StateKV>>;
27
28#[derive(Clone)]
30pub struct GestureDetector<W> {
31 child: W,
32 gesture: GestureKV,
33}
34
35impl<W> GestureDetector<W>
36where
37 W: Into<Node>,
38{
39 pub fn new(n: W) -> GestureDetector<W> {
41 GestureDetector {
42 child: n,
43 gesture: HashMap::new(),
44 }
45 }
46
47 pub fn register(mut self, gesture: Gesture, callback: fn(StateKV) -> ()) -> Self {
49 self.gesture
50 .entry(gesture)
51 .or_insert_with(|| Arc::new(callback));
52
53 self
54 }
55
56 pub fn get(&mut self, name: Gesture) -> Option<&Closure<StateKV>> {
58 if let Some(f) = self.gesture.get(&Box::new(name)) {
59 Some(f)
60 } else {
61 None
62 }
63 }
64
65 pub fn remove(&mut self, name: Gesture) -> Option<Closure<StateKV>> {
67 self.gesture.remove(&Box::new(name))
68 }
69
70 pub fn list(&self) -> Vec<(&Gesture, &Closure<StateKV>)> {
72 self.gesture
73 .iter()
74 .map(|(m, c)| (m, c))
75 .collect::<Vec<(&Gesture, &Closure<StateKV>)>>()
76 }
77}
78
79impl<W> Into<Node> for GestureDetector<W>
80where
81 W: Into<Node>,
82{
83 fn into(self) -> Node {
84 let mut n = self.child.into();
85 n.gesture = Some(self.gesture);
86 n
87 }
88}