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