1use std::str::FromStr;
4
5use bitflags::bitflags;
6use keyboard_types::{Code, Key, Location, Modifiers};
7use smol_str::SmolStr;
8
9#[derive(Default)]
10pub struct EventState {
11 cancelled: bool,
12 propagation_stopped: bool,
13 redraw_requested: bool,
14}
15impl EventState {
16 #[inline(always)]
17 pub fn prevent_default(&mut self) {
18 self.cancelled = true;
19 }
20
21 #[inline(always)]
22 pub fn stop_propagation(&mut self) {
23 self.propagation_stopped = true;
24 }
25
26 #[inline(always)]
27 pub fn request_redraw(&mut self) {
28 self.redraw_requested = true;
29 }
30
31 #[inline(always)]
32 pub fn is_cancelled(&self) -> bool {
33 self.cancelled
34 }
35
36 #[inline(always)]
37 pub fn propagation_is_stopped(&self) -> bool {
38 self.propagation_stopped
39 }
40
41 #[inline(always)]
42 pub fn redraw_is_requested(&self) -> bool {
43 self.redraw_requested
44 }
45}
46
47#[derive(Debug, Clone)]
48#[repr(u8)]
49pub enum UiEvent {
50 MouseMove(BlitzMouseButtonEvent),
51 MouseUp(BlitzMouseButtonEvent),
52 MouseDown(BlitzMouseButtonEvent),
53 KeyUp(BlitzKeyEvent),
54 KeyDown(BlitzKeyEvent),
55 Ime(BlitzImeEvent),
56}
57impl UiEvent {
58 pub fn discriminant(&self) -> u8 {
59 unsafe { *<*const _>::from(self).cast::<u8>() }
64 }
65}
66
67#[derive(Debug, Clone)]
68pub struct DomEvent {
69 pub target: usize,
70 pub bubbles: bool,
72 pub cancelable: bool,
74
75 pub data: DomEventData,
76 pub request_redraw: bool,
77}
78
79impl DomEvent {
80 pub fn new(target: usize, data: DomEventData) -> Self {
81 Self {
82 target,
83 bubbles: data.bubbles(),
84 cancelable: data.cancelable(),
85 data,
86 request_redraw: false,
87 }
88 }
89
90 pub fn name(&self) -> &'static str {
92 self.data.name()
93 }
94}
95
96#[derive(Copy, Clone, Debug, PartialEq)]
97#[repr(u8)]
98pub enum DomEventKind {
99 MouseMove,
100 MouseDown,
101 MouseUp,
102 Click,
103 KeyPress,
104 KeyDown,
105 KeyUp,
106 Input,
107 Ime,
108}
109impl DomEventKind {
110 pub fn discriminant(self) -> u8 {
111 self as u8
112 }
113}
114impl FromStr for DomEventKind {
115 type Err = ();
116 fn from_str(s: &str) -> Result<Self, ()> {
117 match s.trim_start_matches("on") {
118 "mousemove" => Ok(Self::MouseMove),
119 "mousedown" => Ok(Self::MouseDown),
120 "mouseup" => Ok(Self::MouseUp),
121 "click" => Ok(Self::Click),
122 "keypress" => Ok(Self::KeyPress),
123 "keydown" => Ok(Self::KeyDown),
124 "keyup" => Ok(Self::KeyUp),
125 "input" => Ok(Self::Input),
126 "composition" => Ok(Self::Ime),
127 _ => Err(()),
128 }
129 }
130}
131
132#[derive(Debug, Clone)]
133#[repr(u8)]
134pub enum DomEventData {
135 MouseMove(BlitzMouseButtonEvent),
136 MouseDown(BlitzMouseButtonEvent),
137 MouseUp(BlitzMouseButtonEvent),
138 Click(BlitzMouseButtonEvent),
139 KeyPress(BlitzKeyEvent),
140 KeyDown(BlitzKeyEvent),
141 KeyUp(BlitzKeyEvent),
142 Input(BlitzInputEvent),
143 Ime(BlitzImeEvent),
144}
145impl DomEventData {
146 pub fn discriminant(&self) -> u8 {
147 unsafe { *<*const _>::from(self).cast::<u8>() }
152 }
153}
154
155impl DomEventData {
156 pub fn name(&self) -> &'static str {
157 match self {
158 Self::MouseMove { .. } => "mousemove",
159 Self::MouseDown { .. } => "mousedown",
160 Self::MouseUp { .. } => "mouseup",
161 Self::Click { .. } => "click",
162 Self::KeyPress { .. } => "keypress",
163 Self::KeyDown { .. } => "keydown",
164 Self::KeyUp { .. } => "keyup",
165 Self::Input { .. } => "input",
166 Self::Ime { .. } => "composition",
167 }
168 }
169
170 pub fn kind(&self) -> DomEventKind {
171 match self {
172 Self::MouseMove { .. } => DomEventKind::MouseMove,
173 Self::MouseDown { .. } => DomEventKind::MouseDown,
174 Self::MouseUp { .. } => DomEventKind::MouseUp,
175 Self::Click { .. } => DomEventKind::Click,
176 Self::KeyPress { .. } => DomEventKind::KeyPress,
177 Self::KeyDown { .. } => DomEventKind::KeyDown,
178 Self::KeyUp { .. } => DomEventKind::KeyUp,
179 Self::Input { .. } => DomEventKind::Input,
180 Self::Ime { .. } => DomEventKind::Ime,
181 }
182 }
183
184 pub fn cancelable(&self) -> bool {
185 match self {
186 Self::MouseMove { .. } => true,
187 Self::MouseDown { .. } => true,
188 Self::MouseUp { .. } => true,
189 Self::Click { .. } => true,
190 Self::KeyDown { .. } => true,
191 Self::KeyUp { .. } => true,
192 Self::KeyPress { .. } => true,
193 Self::Ime { .. } => true,
194 Self::Input { .. } => false,
195 }
196 }
197
198 pub fn bubbles(&self) -> bool {
199 match self {
200 Self::MouseMove { .. } => true,
201 Self::MouseDown { .. } => true,
202 Self::MouseUp { .. } => true,
203 Self::Click { .. } => true,
204 Self::KeyDown { .. } => true,
205 Self::KeyUp { .. } => true,
206 Self::KeyPress { .. } => true,
207 Self::Ime { .. } => true,
208 Self::Input { .. } => true,
209 }
210 }
211}
212
213#[derive(Debug, Clone, Copy)]
214pub struct HitResult {
215 pub node_id: usize,
217 pub x: f32,
219 pub y: f32,
221}
222
223#[derive(Clone, Debug)]
224pub struct BlitzMouseButtonEvent {
225 pub x: f32,
226 pub y: f32,
227 pub button: MouseEventButton,
228 pub buttons: MouseEventButtons,
229 pub mods: Modifiers,
230}
231
232bitflags! {
233 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
238 pub struct MouseEventButtons: u8 {
239 const None = 0b0000_0000;
241 const Primary = 0b0000_0001;
243 const Secondary = 0b0000_0010;
245 const Auxiliary = 0b0000_0100;
247 const Fourth = 0b0000_1000;
249 const Fifth = 0b0001_0000;
251 }
252}
253
254impl Default for MouseEventButtons {
255 fn default() -> Self {
256 Self::None
257 }
258}
259
260impl From<MouseEventButton> for MouseEventButtons {
261 fn from(value: MouseEventButton) -> Self {
262 match value {
263 MouseEventButton::Main => Self::Primary,
264 MouseEventButton::Auxiliary => Self::Auxiliary,
265 MouseEventButton::Secondary => Self::Secondary,
266 MouseEventButton::Fourth => Self::Fourth,
267 MouseEventButton::Fifth => Self::Fifth,
268 }
269 }
270}
271
272#[derive(Copy, Clone, Debug, Default, PartialEq, Eq)]
277pub enum MouseEventButton {
278 #[default]
280 Main = 0,
281 Auxiliary = 1,
283 Secondary = 2,
285 Fourth = 3,
287 Fifth = 4,
289}
290
291#[derive(Copy, Clone, Debug, PartialEq, Eq)]
292pub enum KeyState {
293 Pressed,
294 Released,
295}
296
297impl KeyState {
298 pub fn is_pressed(self) -> bool {
299 matches!(self, Self::Pressed)
300 }
301}
302
303#[derive(Clone, Debug)]
304pub struct BlitzKeyEvent {
305 pub key: Key,
306 pub code: Code,
307 pub modifiers: Modifiers,
308 pub location: Location,
309 pub is_auto_repeating: bool,
310 pub is_composing: bool,
311 pub state: KeyState,
312 pub text: Option<SmolStr>,
313}
314
315#[derive(Clone, Debug)]
316pub struct BlitzInputEvent {
317 pub value: String,
318}
319
320#[derive(Debug, Clone, PartialEq, Eq, Hash)]
322pub enum BlitzImeEvent {
323 Enabled,
328
329 Preedit(String, Option<(usize, usize)>),
337
338 Commit(String),
342
343 Disabled,
348}