1use std::str::FromStr;
2
3use smallvec::SmallVec;
4
5#[derive(Clone, Copy, PartialEq, Debug, Hash)]
6pub enum EventName {
7 Click,
8 MiddleClick,
9 RightClick,
10
11 MouseUp,
12 MouseDown,
13 MouseMove,
14 MouseEnter,
15 MouseLeave,
16
17 Wheel,
18
19 PointerOver,
20 PointerDown,
21 PointerEnter,
22 PointerLeave,
23 PointerUp,
24
25 KeyDown,
26 KeyUp,
27 GlobalKeyDown,
28 GlobalKeyUp,
29
30 TouchCancel,
31 TouchStart,
32 TouchMove,
33 TouchEnd,
34
35 GlobalClick,
36 GlobalPointerUp,
37 GlobalMouseDown,
38 GlobalMouseMove,
39 GlobalFileHover,
40 GlobalFileHoverCancelled,
41
42 FileDrop,
43}
44
45impl FromStr for EventName {
46 type Err = ();
47
48 fn from_str(txt: &str) -> Result<Self, Self::Err> {
49 match txt {
50 "click" => Ok(EventName::Click),
51 "rightclick" => Ok(EventName::RightClick),
52 "middleclick" => Ok(EventName::MiddleClick),
53 "mouseup" => Ok(EventName::MouseUp),
54 "mousedown" => Ok(EventName::MouseDown),
55 "mousemove" => Ok(EventName::MouseMove),
56 "mouseenter" => Ok(EventName::MouseEnter),
57 "mouseleave" => Ok(EventName::MouseLeave),
58 "wheel" => Ok(EventName::Wheel),
59 "pointermove" => Ok(EventName::PointerOver),
60 "pointerdown" => Ok(EventName::PointerDown),
61 "pointerenter" => Ok(EventName::PointerEnter),
62 "pointerleave" => Ok(EventName::PointerLeave),
63 "pointerup" => Ok(EventName::PointerUp),
64 "keydown" => Ok(EventName::KeyDown),
65 "keyup" => Ok(EventName::KeyUp),
66 "globalkeydown" => Ok(EventName::GlobalKeyDown),
67 "globalkeyup" => Ok(EventName::GlobalKeyUp),
68 "touchcancel" => Ok(EventName::TouchCancel),
69 "touchstart" => Ok(EventName::TouchStart),
70 "touchmove" => Ok(EventName::TouchMove),
71 "touchend" => Ok(EventName::TouchEnd),
72 "globalclick" => Ok(EventName::GlobalClick),
73 "globalpointerup" => Ok(EventName::GlobalPointerUp),
74 "globalmousedown" => Ok(EventName::GlobalMouseDown),
75 "globalmousemove" => Ok(EventName::GlobalMouseMove),
76 "filedrop" => Ok(EventName::FileDrop),
77 "globalfilehover" => Ok(EventName::GlobalFileHover),
78 "globalfilehovercancelled" => Ok(EventName::GlobalFileHoverCancelled),
79 _ => Err(()),
80 }
81 }
82}
83
84impl From<EventName> for &str {
85 fn from(event: EventName) -> Self {
86 match event {
87 EventName::Click => "click",
88 EventName::MiddleClick => "middleclick",
89 EventName::RightClick => "rightclick",
90 EventName::MouseUp => "mouseup",
91 EventName::MouseDown => "mousedown",
92 EventName::MouseMove => "mousemove",
93 EventName::MouseEnter => "mouseenter",
94 EventName::MouseLeave => "mouseleave",
95 EventName::Wheel => "wheel",
96 EventName::PointerOver => "pointermove",
97 EventName::PointerDown => "pointerdown",
98 EventName::PointerEnter => "pointerenter",
99 EventName::PointerLeave => "pointerleave",
100 EventName::PointerUp => "pointerup",
101 EventName::KeyUp => "keyup",
102 EventName::KeyDown => "keydown",
103 EventName::GlobalKeyDown => "globalkeydown",
104 EventName::GlobalKeyUp => "globalkeyup",
105 EventName::TouchCancel => "touchcancel",
106 EventName::TouchStart => "touchstart",
107 EventName::TouchMove => "touchmove",
108 EventName::TouchEnd => "touchend",
109 EventName::GlobalClick => "globalclick",
110 EventName::GlobalPointerUp => "globalpointerup",
111 EventName::GlobalMouseDown => "globalmousedown",
112 EventName::GlobalMouseMove => "globalmousemove",
113 EventName::FileDrop => "filedrop",
114 EventName::GlobalFileHover => "globalfilehover",
115 EventName::GlobalFileHoverCancelled => "globalfilehovercancelled",
116 }
117 }
118}
119
120impl Eq for EventName {}
121
122impl PartialOrd for EventName {
123 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
124 Some(self.cmp(other))
125 }
126}
127
128impl Ord for EventName {
129 fn cmp(&self, other: &Self) -> std::cmp::Ordering {
130 match self {
131 Self::MouseLeave | Self::PointerLeave => {
133 if self == other {
134 std::cmp::Ordering::Equal
135 } else {
136 std::cmp::Ordering::Less
137 }
138 }
139
140 _ => std::cmp::Ordering::Greater,
141 }
142 }
143}
144
145impl EventName {
146 pub fn get_global_event(&self) -> Option<Self> {
148 match self {
149 Self::MouseUp => Some(Self::GlobalClick),
150 Self::PointerUp => Some(Self::GlobalPointerUp),
151 Self::MouseDown => Some(Self::GlobalMouseDown),
152 Self::MouseMove => Some(Self::GlobalMouseMove),
153 Self::GlobalFileHover => Some(Self::GlobalFileHover),
154 Self::GlobalFileHoverCancelled => Some(Self::GlobalFileHoverCancelled),
155 Self::KeyDown => Some(EventName::GlobalKeyDown),
156 Self::KeyUp => Some(EventName::GlobalKeyUp),
157 _ => None,
158 }
159 }
160
161 pub fn get_derived_events(&self) -> SmallVec<[Self; 4]> {
165 let mut events = SmallVec::new();
166
167 events.push(*self);
168
169 match self {
170 Self::MouseMove => {
171 events.extend([Self::MouseEnter, Self::PointerEnter, Self::PointerOver])
172 }
173 Self::TouchMove => events.extend([Self::PointerEnter, Self::PointerOver]),
174 Self::MouseDown | Self::TouchStart => events.push(Self::PointerDown),
175 Self::MouseUp | Self::MiddleClick | Self::RightClick | Self::TouchEnd => {
176 events.extend([Self::Click, Self::PointerUp])
177 }
178 Self::MouseLeave => events.push(Self::PointerLeave),
179 _ => {}
180 }
181
182 events
183 }
184
185 pub fn is_enter(&self) -> bool {
187 matches!(&self, Self::MouseEnter | Self::PointerEnter)
188 }
189
190 pub fn is_global(&self) -> bool {
191 matches!(
192 &self,
193 Self::GlobalKeyDown
194 | Self::GlobalKeyUp
195 | Self::GlobalClick
196 | Self::GlobalPointerUp
197 | Self::GlobalMouseDown
198 | Self::GlobalMouseMove
199 | Self::GlobalFileHover
200 | Self::GlobalFileHoverCancelled
201 )
202 }
203
204 pub fn is_pointer(&self) -> bool {
206 matches!(
207 &self,
208 Self::PointerEnter
209 | Self::PointerLeave
210 | Self::PointerOver
211 | Self::PointerDown
212 | Self::PointerUp
213 | Self::GlobalPointerUp
214 )
215 }
216
217 pub fn is_moved(&self) -> bool {
219 matches!(
220 &self,
221 Self::MouseMove | Self::MouseEnter | Self::PointerEnter | Self::PointerOver
222 )
223 }
224
225 pub fn is_left(&self) -> bool {
227 matches!(&self, Self::MouseLeave | Self::PointerLeave)
228 }
229
230 pub fn does_bubble(&self) -> bool {
234 !self.is_moved() && !self.is_left() && !self.is_global()
235 }
236
237 pub fn does_go_through_solid(&self) -> bool {
239 matches!(self, Self::GlobalKeyDown | Self::GlobalKeyUp)
240 }
241
242 pub fn is_hovered(&self) -> bool {
244 matches!(
245 self,
246 Self::MouseMove | Self::MouseEnter | Self::PointerOver | Self::PointerEnter
247 )
248 }
249
250 pub fn is_pressed(&self) -> bool {
252 matches!(self, Self::MouseDown | Self::TouchStart | Self::PointerDown)
253 }
254
255 pub fn is_released(&self) -> bool {
257 matches!(&self, Self::Click | Self::PointerUp)
258 }
259}