Skip to main content

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