freya_core/events/
emittable.rs

1use ragnarok::{
2    Area,
3    NameOfEvent,
4};
5use torin::prelude::CursorPoint;
6
7use crate::{
8    events::{
9        data::{
10            EventType,
11            KeyboardEventData,
12            MouseEventData,
13            PointerEventData,
14            TouchEventData,
15            WheelEventData,
16        },
17        name::EventName,
18    },
19    integration::PlatformEvent,
20    node_id::NodeId,
21    prelude::{
22        FileEventData,
23        ImePreeditEventData,
24    },
25};
26/// Event emitted to the Tree.
27#[derive(Debug, Clone, PartialEq)]
28pub struct EmmitableEvent {
29    pub name: EventName,
30    pub source_event: EventName,
31    pub node_id: NodeId,
32    pub data: EventType,
33    pub bubbles: bool,
34}
35
36impl Eq for EmmitableEvent {}
37
38impl PartialOrd for EmmitableEvent {
39    fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
40        Some(self.cmp(other))
41    }
42}
43
44impl Ord for EmmitableEvent {
45    fn cmp(&self, other: &Self) -> std::cmp::Ordering {
46        self.name.cmp(&other.name)
47    }
48}
49
50impl ragnarok::EmmitableEvent for EmmitableEvent {
51    type Key = NodeId;
52    type Name = EventName;
53
54    fn key(&self) -> Self::Key {
55        self.node_id
56    }
57
58    fn name(&self) -> Self::Name {
59        self.name
60    }
61
62    fn source(&self) -> Self::Name {
63        self.source_event
64    }
65}
66
67impl EmmitableEvent {
68    pub fn new(
69        node_id: NodeId,
70        name: EventName,
71        platform_event: PlatformEvent,
72        node_area: Option<Area>,
73        scale_factor: f64,
74    ) -> Self {
75        let bubbles = name.does_bubble();
76
77        match platform_event {
78            PlatformEvent::Mouse {
79                name: platform_event_name,
80                cursor,
81                button,
82                ..
83            } if name.is_enter() || name.is_left() || name.is_press() || name.is_down() => {
84                let global_location = cursor / scale_factor;
85                let element_x =
86                    (cursor.x - node_area.unwrap_or_default().min_x() as f64) / scale_factor;
87                let element_y =
88                    (cursor.y - node_area.unwrap_or_default().min_y() as f64) / scale_factor;
89
90                let event_data = EventType::Pointer(PointerEventData::Mouse(MouseEventData {
91                    global_location,
92                    element_location: CursorPoint::new(element_x, element_y),
93                    button,
94                }));
95
96                Self {
97                    node_id,
98                    name,
99                    source_event: platform_event_name.into(),
100                    data: event_data,
101                    bubbles,
102                }
103            }
104            PlatformEvent::Touch {
105                name: platform_event_name,
106                location,
107                finger_id,
108                phase,
109                force,
110                ..
111            } if name.is_enter() || name.is_left() || name.is_press() || name.is_down() => {
112                let global_location = location / scale_factor;
113                let element_x =
114                    (location.x - node_area.unwrap_or_default().min_x() as f64) / scale_factor;
115                let element_y =
116                    (location.y - node_area.unwrap_or_default().min_y() as f64) / scale_factor;
117
118                let event_data = EventType::Pointer(PointerEventData::Touch(TouchEventData::new(
119                    global_location,
120                    CursorPoint::new(element_x, element_y),
121                    finger_id,
122                    phase,
123                    force,
124                )));
125
126                Self {
127                    node_id,
128                    name,
129                    source_event: platform_event_name.into(),
130                    data: event_data,
131                    bubbles,
132                }
133            }
134            PlatformEvent::Mouse {
135                name: platform_event_name,
136                cursor,
137                button,
138                ..
139            } => {
140                let global_location = cursor / scale_factor;
141                let element_x =
142                    (cursor.x - node_area.unwrap_or_default().min_x() as f64) / scale_factor;
143                let element_y =
144                    (cursor.y - node_area.unwrap_or_default().min_y() as f64) / scale_factor;
145
146                let event_data = EventType::Mouse(MouseEventData {
147                    global_location,
148                    element_location: CursorPoint::new(element_x, element_y),
149                    button,
150                });
151
152                Self {
153                    node_id,
154                    name,
155                    source_event: platform_event_name.into(),
156                    data: event_data,
157                    bubbles,
158                }
159            }
160            PlatformEvent::Keyboard {
161                name: platform_event_name,
162                ref key,
163                code,
164                modifiers,
165                ..
166            } => Self {
167                node_id,
168                name,
169
170                source_event: platform_event_name.into(),
171                data: EventType::Keyboard(KeyboardEventData::new(key.clone(), code, modifiers)),
172                bubbles,
173            },
174            PlatformEvent::Wheel {
175                name: platform_event_name,
176                scroll,
177                source,
178                cursor,
179                ..
180            } => {
181                let global_location = cursor / scale_factor;
182                let element_x =
183                    (cursor.x - node_area.unwrap_or_default().min_x() as f64) / scale_factor;
184                let element_y =
185                    (cursor.y - node_area.unwrap_or_default().min_y() as f64) / scale_factor;
186                let element_location = CursorPoint::new(element_x, element_y);
187
188                Self {
189                    node_id,
190                    name,
191                    source_event: platform_event_name.into(),
192                    data: EventType::Wheel(WheelEventData::new(
193                        scroll.x,
194                        scroll.y,
195                        source,
196                        global_location,
197                        element_location,
198                    )),
199                    bubbles,
200                }
201            }
202            PlatformEvent::Touch {
203                name: platform_event_name,
204                location,
205                finger_id,
206                phase,
207                force,
208                ..
209            } => {
210                let global_location = location / scale_factor;
211                let element_x =
212                    (location.x - node_area.unwrap_or_default().min_x() as f64) / scale_factor;
213                let element_y =
214                    (location.y - node_area.unwrap_or_default().min_y() as f64) / scale_factor;
215
216                let event_data = EventType::Touch(TouchEventData::new(
217                    global_location,
218                    CursorPoint::new(element_x, element_y),
219                    finger_id,
220                    phase,
221                    force,
222                ));
223
224                Self {
225                    node_id,
226                    name,
227                    source_event: platform_event_name.into(),
228                    data: event_data,
229                    bubbles,
230                }
231            }
232            PlatformEvent::ImePreedit {
233                name: platform_event_name,
234                cursor,
235                text,
236            } => Self {
237                node_id,
238                name,
239
240                source_event: platform_event_name.into(),
241                data: EventType::ImePreedit(ImePreeditEventData::new(text, cursor)),
242                bubbles,
243            },
244            PlatformEvent::File {
245                name: platform_event_name,
246                cursor,
247                file_path,
248            } => Self {
249                node_id,
250                name,
251
252                source_event: platform_event_name.into(),
253                data: EventType::File(FileEventData::new(cursor, file_path)),
254                bubbles,
255            },
256        }
257    }
258}