freya_core/events/
name.rs

1#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)]
2pub enum EventName {
3    // Platform Mouse
4    MouseUp,
5    MouseDown,
6    MouseMove,
7
8    // Platform Mouse or Touch
9    PointerPress,
10    PointerDown,
11    PointerEnter,
12    PointerLeave,
13    PointerOver,
14    PointerOut,
15
16    // Platform Keyboard
17    KeyDown,
18    KeyUp,
19
20    // Platform Touch
21    TouchCancel,
22    TouchStart,
23    TouchMove,
24    TouchEnd,
25
26    GlobalPointerMove,
27    GlobalPointerPress,
28    GlobalPointerDown,
29
30    GlobalKeyDown,
31    GlobalKeyUp,
32
33    GlobalFileHover,
34    GlobalFileHoverCancelled,
35
36    CaptureGlobalPointerMove,
37    CaptureGlobalPointerPress,
38
39    Wheel,
40
41    Sized,
42
43    FileDrop,
44
45    ImePreedit,
46}
47
48use std::collections::HashSet;
49
50impl PartialOrd for EventName {
51    fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
52        Some(self.cmp(other))
53    }
54}
55
56impl Ord for EventName {
57    fn cmp(&self, other: &Self) -> std::cmp::Ordering {
58        match self {
59            // Capture events have max priority
60            e if e.is_capture() => std::cmp::Ordering::Less,
61            // Left events have more priority over non-left
62            e if e.is_left() => std::cmp::Ordering::Less,
63            // Exclusive left events have more priority over non-exclusive-left
64            e if e.is_exclusive_left() => std::cmp::Ordering::Less,
65            e => {
66                if e == other {
67                    std::cmp::Ordering::Equal
68                } else {
69                    std::cmp::Ordering::Greater
70                }
71            }
72        }
73    }
74}
75
76impl EventName {
77    /// Check if this even captures others or not
78    pub fn is_capture(&self) -> bool {
79        matches!(
80            &self,
81            Self::CaptureGlobalPointerMove | Self::CaptureGlobalPointerPress
82        )
83    }
84
85    /// Check if this is a global pointer event
86    pub fn is_global_pointer(&self) -> bool {
87        matches!(
88            self,
89            Self::GlobalPointerMove
90                | Self::GlobalPointerPress
91                | Self::GlobalPointerDown
92                | Self::CaptureGlobalPointerMove
93                | Self::CaptureGlobalPointerPress
94        )
95    }
96
97    pub fn is_left(&self) -> bool {
98        matches!(&self, Self::PointerLeave | Self::PointerOut)
99    }
100
101    pub fn is_exclusive_left(&self) -> bool {
102        matches!(&self, Self::PointerLeave)
103    }
104
105    pub fn is_down(&self) -> bool {
106        matches!(self, Self::PointerDown)
107    }
108
109    pub fn is_press(&self) -> bool {
110        matches!(self, Self::PointerPress)
111    }
112}
113
114impl ragnarok::NameOfEvent for EventName {
115    fn get_global_events(&self) -> HashSet<Self> {
116        match self {
117            Self::MouseUp | Self::TouchEnd => {
118                HashSet::from([Self::GlobalPointerPress, Self::CaptureGlobalPointerPress])
119            }
120            Self::MouseDown | Self::TouchStart => HashSet::from([Self::GlobalPointerDown]),
121            Self::MouseMove | Self::TouchMove => {
122                HashSet::from([Self::GlobalPointerMove, Self::CaptureGlobalPointerMove])
123            }
124
125            Self::KeyDown => HashSet::from([Self::GlobalKeyDown]),
126            Self::KeyUp => HashSet::from([Self::GlobalKeyUp]),
127
128            Self::GlobalFileHover => HashSet::from([Self::GlobalFileHover]),
129            Self::GlobalFileHoverCancelled => HashSet::from([Self::GlobalFileHoverCancelled]),
130            _ => HashSet::new(),
131        }
132    }
133
134    fn get_derived_events(&self) -> HashSet<Self> {
135        let mut events = HashSet::new();
136
137        events.insert(*self);
138
139        match self {
140            Self::MouseMove | Self::TouchMove => {
141                events.insert(Self::PointerEnter);
142                events.insert(Self::PointerOver);
143            }
144            Self::MouseDown | Self::TouchStart => {
145                events.insert(Self::PointerDown);
146            }
147            Self::MouseUp | Self::TouchEnd => {
148                events.insert(Self::PointerPress);
149            }
150            // PointerOut is synthesized as the leave event; it also derives PointerLeave
151            // so that both events are emitted when a node stops being hovered.
152            Self::PointerOut => {
153                events.insert(Self::PointerLeave);
154            }
155            _ => {}
156        }
157
158        events
159    }
160
161    fn get_cancellable_events(&self) -> HashSet<Self> {
162        let mut events = HashSet::new();
163
164        events.insert(*self);
165
166        match self {
167            Self::KeyDown => {
168                events.insert(Self::GlobalKeyDown);
169            }
170            Self::KeyUp => {
171                events.insert(Self::GlobalKeyUp);
172            }
173            Self::MouseUp | Self::TouchEnd => {
174                events.extend([Self::PointerPress, Self::GlobalPointerPress])
175            }
176            Self::PointerPress => events.extend([Self::MouseUp, Self::GlobalPointerPress]),
177            Self::MouseDown | Self::TouchStart => {
178                events.extend([Self::PointerDown, Self::GlobalPointerDown])
179            }
180            Self::PointerDown => events.extend([Self::MouseDown, Self::GlobalPointerDown]),
181            Self::CaptureGlobalPointerMove => {
182                events.extend([
183                    Self::MouseMove,
184                    Self::TouchMove,
185                    Self::PointerEnter,
186                    Self::PointerOver,
187                    Self::GlobalPointerMove,
188                ]);
189            }
190            Self::CaptureGlobalPointerPress => {
191                events.extend([
192                    Self::MouseUp,
193                    Self::TouchEnd,
194                    Self::PointerPress,
195                    Self::GlobalPointerPress,
196                ]);
197            }
198
199            _ => {}
200        }
201
202        events
203    }
204
205    fn is_global(&self) -> bool {
206        matches!(
207            self,
208            Self::GlobalKeyDown
209                | Self::GlobalKeyUp
210                | Self::GlobalPointerPress
211                | Self::GlobalPointerDown
212                | Self::GlobalPointerMove
213                | Self::GlobalFileHover
214                | Self::GlobalFileHoverCancelled
215        )
216    }
217
218    fn is_moved(&self) -> bool {
219        matches!(
220            &self,
221            Self::MouseMove
222                | Self::TouchMove
223                | Self::CaptureGlobalPointerMove
224                | Self::GlobalPointerMove
225        )
226    }
227
228    fn does_bubble(&self) -> bool {
229        (!self.is_moved()
230            && !self.is_enter()
231            && !self.is_left()
232            && !self.is_global()
233            && !self.is_capture())
234            || self.is_exclusive_enter()
235            || self.is_exclusive_leave()
236    }
237
238    fn does_go_through_solid(&self) -> bool {
239        // TODO
240        false
241    }
242
243    fn is_enter(&self) -> bool {
244        matches!(&self, Self::PointerEnter | Self::PointerOver)
245    }
246
247    fn is_pressed(&self) -> bool {
248        matches!(self, Self::MouseDown | Self::PointerDown)
249    }
250
251    fn is_released(&self) -> bool {
252        matches!(&self, Self::PointerPress)
253    }
254
255    fn is_exclusive_enter(&self) -> bool {
256        matches!(&self, Self::PointerEnter)
257    }
258
259    fn is_exclusive_leave(&self) -> bool {
260        matches!(&self, Self::PointerLeave)
261    }
262
263    fn new_leave() -> Self {
264        Self::PointerOut
265    }
266
267    fn new_exclusive_leave() -> Self {
268        Self::PointerLeave
269    }
270
271    fn new_exclusive_enter() -> Self {
272        Self::PointerEnter
273    }
274}