1use std::{
2 cell::RefCell,
3 ops::{
4 Deref,
5 Div,
6 },
7 path::PathBuf,
8 rc::Rc,
9};
10
11pub use accesskit::{
12 Action as AccessibilityAction,
13 ActionRequest as AccessibilityActionEventData,
14};
15use torin::prelude::{
16 Area,
17 CursorPoint,
18 Size2D,
19};
20
21use crate::data::{
22 StyleState,
23 TextStyleState,
24};
25
26#[derive(Debug, Hash, PartialEq, Eq, PartialOrd, Ord, Clone, Copy)]
27pub enum MouseButton {
28 Left,
29 Right,
30 Middle,
31 Back,
32 Forward,
33 Other(u16),
34}
35
36#[derive(Debug, Clone, PartialEq, Default)]
37pub struct MouseEventData {
38 pub global_location: CursorPoint,
39 pub element_location: CursorPoint,
40 pub button: Option<MouseButton>,
41}
42
43#[derive(Debug, Clone, PartialEq)]
45pub struct KeyboardEventData {
46 pub key: keyboard_types::Key,
47 pub code: keyboard_types::Code,
48 pub modifiers: keyboard_types::Modifiers,
49}
50
51impl KeyboardEventData {
52 pub fn new(
53 key: keyboard_types::Key,
54 code: keyboard_types::Code,
55 modifiers: keyboard_types::Modifiers,
56 ) -> Self {
57 Self {
58 key,
59 code,
60 modifiers,
61 }
62 }
63}
64
65impl KeyboardEventData {
66 pub fn try_as_str(&self) -> Option<&str> {
68 if let keyboard_types::Key::Character(c) = &self.key {
69 Some(c)
70 } else {
71 None
72 }
73 }
74}
75
76pub struct Event<D> {
77 pub(crate) data: D,
78 pub(crate) propagate: Rc<RefCell<bool>>,
79 pub(crate) default: Rc<RefCell<bool>>,
80}
81
82impl<D> Deref for Event<D> {
83 type Target = D;
84
85 fn deref(&self) -> &Self::Target {
86 &self.data
87 }
88}
89
90impl<D> Event<D> {
91 pub fn map<NewD>(self, data: impl FnOnce(D) -> NewD) -> Event<NewD> {
92 Event {
93 data: data(self.data),
94 propagate: self.propagate,
95 default: self.default,
96 }
97 }
98
99 pub fn try_map<NewD>(self, data: impl FnOnce(D) -> Option<NewD>) -> Option<Event<NewD>> {
100 Some(Event {
101 data: data(self.data)?,
102 propagate: self.propagate,
103 default: self.default,
104 })
105 }
106
107 pub fn data(&self) -> &D {
108 &self.data
109 }
110
111 pub fn stop_propagation(&self) {
112 *self.propagate.borrow_mut() = false;
113 }
114
115 pub fn prevent_default(&self) {
116 *self.default.borrow_mut() = false;
117 }
118
119 #[must_use]
120 pub fn get_prevent_default(&self) -> Rc<RefCell<bool>> {
121 self.default.clone()
122 }
123}
124
125#[derive(Debug, Clone, PartialEq, Default)]
127pub struct SizedEventData {
128 pub area: Area,
129 pub visible_area: Area,
130 pub inner_sizes: Size2D,
131}
132
133impl SizedEventData {
134 pub fn div(&mut self, rhs: f32) {
135 self.area = self.area.div(rhs);
136 self.visible_area = self.visible_area.div(rhs);
137 self.inner_sizes = self.inner_sizes.div(rhs);
138 }
139}
140
141impl SizedEventData {
142 pub fn new(area: Area, visible_area: Area, inner_sizes: Size2D) -> Self {
143 Self {
144 area,
145 visible_area,
146 inner_sizes,
147 }
148 }
149}
150
151#[derive(Debug, Clone, PartialEq, Default)]
153pub struct VisibleEventData {
154 pub area: Area,
155}
156
157impl VisibleEventData {
158 pub fn new(area: Area) -> Self {
159 Self { area }
160 }
161
162 pub fn div(&mut self, rhs: f32) {
163 self.area = self.area.div(rhs);
164 }
165}
166
167#[derive(Debug, Clone, PartialEq)]
169pub struct StyledEventData {
170 pub style: StyleState,
171 pub text_style: TextStyleState,
172}
173
174#[derive(Debug, Clone, PartialEq, Copy)]
175pub enum WheelSource {
176 Line,
178 Pixel,
180 Custom,
181}
182
183impl WheelSource {
184 pub fn is_device(&self) -> bool {
186 matches!(self, Self::Line | Self::Pixel)
187 }
188}
189
190#[derive(Debug, Clone, PartialEq)]
192pub struct WheelEventData {
193 pub source: WheelSource,
194 pub phase: TouchPhase,
195 pub delta_x: f64,
196 pub delta_y: f64,
197 pub global_location: CursorPoint,
198 pub element_location: CursorPoint,
199}
200
201impl WheelEventData {
202 pub fn new(
203 delta_x: f64,
204 delta_y: f64,
205 source: WheelSource,
206 phase: TouchPhase,
207 global_location: CursorPoint,
208 element_location: CursorPoint,
209 ) -> Self {
210 Self {
211 delta_x,
212 delta_y,
213 source,
214 phase,
215 global_location,
216 element_location,
217 }
218 }
219}
220
221#[derive(Debug, Hash, PartialEq, Eq, Clone, Copy)]
222pub enum TouchPhase {
223 Started,
224 Moved,
225 Ended,
226 Cancelled,
227}
228
229#[derive(Debug, Clone, Copy, PartialEq)]
230pub enum Force {
231 Calibrated {
232 force: f64,
233 max_possible_force: f64,
234 altitude_angle: Option<f64>,
235 },
236 Normalized(f64),
237}
238
239#[derive(Debug, Clone, PartialEq)]
241pub struct TouchEventData {
242 pub global_location: CursorPoint,
243 pub element_location: CursorPoint,
244 pub finger_id: u64,
245 pub phase: TouchPhase,
246 pub force: Option<Force>,
247}
248
249impl TouchEventData {
250 pub fn new(
251 global_location: CursorPoint,
252 element_location: CursorPoint,
253 finger_id: u64,
254 phase: TouchPhase,
255 force: Option<Force>,
256 ) -> Self {
257 Self {
258 global_location,
259 element_location,
260 finger_id,
261 phase,
262 force,
263 }
264 }
265}
266
267#[derive(Debug, Clone, PartialEq)]
269pub enum PointerEventData {
270 Mouse(MouseEventData),
271 Touch(TouchEventData),
272}
273
274impl PointerEventData {
275 pub fn global_location(&self) -> CursorPoint {
276 match self {
277 Self::Mouse(m) => m.global_location,
278 Self::Touch(t) => t.global_location,
279 }
280 }
281
282 pub fn element_location(&self) -> CursorPoint {
283 match self {
284 Self::Mouse(m) => m.element_location,
285 Self::Touch(t) => t.element_location,
286 }
287 }
288
289 pub fn button(&self) -> Option<MouseButton> {
290 match self {
291 Self::Mouse(m) => m.button,
292 Self::Touch(_) => None,
293 }
294 }
295
296 pub fn is_primary(&self) -> bool {
298 match self {
299 Self::Mouse(m) => m.button == Some(MouseButton::Left),
300 Self::Touch(_) => true,
301 }
302 }
303}
304
305#[derive(Debug, Clone, PartialEq)]
306pub struct ImePreeditEventData {
307 pub text: String,
308 pub cursor: Option<(usize, usize)>,
309}
310
311impl ImePreeditEventData {
312 pub(crate) fn new(text: String, cursor: Option<(usize, usize)>) -> Self {
313 Self { text, cursor }
314 }
315}
316
317#[derive(Debug, Clone, PartialEq)]
318pub struct FileEventData {
319 pub cursor: CursorPoint,
320 pub file_paths: Vec<PathBuf>,
321}
322
323impl FileEventData {
324 pub(crate) fn new(cursor: CursorPoint, file_paths: Vec<PathBuf>) -> Self {
325 Self { cursor, file_paths }
326 }
327}
328
329#[derive(Debug, Clone, PartialEq)]
330pub enum EventType {
331 AccessibilityAction(AccessibilityActionEventData),
332 Mouse(MouseEventData),
333 Keyboard(KeyboardEventData),
334 Sized(SizedEventData),
335 Visible(VisibleEventData),
336 Styled(StyledEventData),
337 Wheel(WheelEventData),
338 Touch(TouchEventData),
339 Pointer(PointerEventData),
340 ImePreedit(ImePreeditEventData),
341 File(FileEventData),
342}