Skip to main content

freya_core/events/
data.rs

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/// Data of a Keyboard event.
44#[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    /// Try to get the text of the key
67    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/// Data of a Sized event.
126#[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/// Data of a Visible event.
152#[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/// Data of a Styled event.
168#[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    /// Discrete line-based steps, usually from a mouse wheel.
177    Line,
178    /// Continuous pixel deltas, usually from a touchpad.
179    Pixel,
180    Custom,
181}
182
183impl WheelSource {
184    /// Whether the event came from a physical device rather than being synthesized from code.
185    pub fn is_device(&self) -> bool {
186        matches!(self, Self::Line | Self::Pixel)
187    }
188}
189
190/// Data of a Wheel event.
191#[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/// Data of a Touch event.
240#[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/// Data of a pointer event.
268#[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    /// Whether this is a touch event or a primary (left) mouse button event.
297    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}