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