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