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()
84                || name.is_left()
85                || name.is_press()
86                || name.is_down()
87                || name.is_global_pointer() =>
88            {
89                let global_location = cursor / scale_factor;
90                let element_x =
91                    (cursor.x - node_area.unwrap_or_default().min_x() as f64) / scale_factor;
92                let element_y =
93                    (cursor.y - node_area.unwrap_or_default().min_y() as f64) / scale_factor;
94
95                let event_data = EventType::Pointer(PointerEventData::Mouse(MouseEventData {
96                    global_location,
97                    element_location: CursorPoint::new(element_x, element_y),
98                    button,
99                }));
100
101                Self {
102                    node_id,
103                    name,
104                    source_event: platform_event_name.into(),
105                    data: event_data,
106                    bubbles,
107                }
108            }
109            PlatformEvent::Touch {
110                name: platform_event_name,
111                location,
112                finger_id,
113                phase,
114                force,
115                ..
116            } if name.is_enter()
117                || name.is_left()
118                || name.is_press()
119                || name.is_down()
120                || name.is_global_pointer() =>
121            {
122                let global_location = location / scale_factor;
123                let element_x =
124                    (location.x - node_area.unwrap_or_default().min_x() as f64) / scale_factor;
125                let element_y =
126                    (location.y - node_area.unwrap_or_default().min_y() as f64) / scale_factor;
127
128                let event_data = EventType::Pointer(PointerEventData::Touch(TouchEventData::new(
129                    global_location,
130                    CursorPoint::new(element_x, element_y),
131                    finger_id,
132                    phase,
133                    force,
134                )));
135
136                Self {
137                    node_id,
138                    name,
139                    source_event: platform_event_name.into(),
140                    data: event_data,
141                    bubbles,
142                }
143            }
144            PlatformEvent::Mouse {
145                name: platform_event_name,
146                cursor,
147                button,
148                ..
149            } => {
150                let global_location = cursor / scale_factor;
151                let element_x =
152                    (cursor.x - node_area.unwrap_or_default().min_x() as f64) / scale_factor;
153                let element_y =
154                    (cursor.y - node_area.unwrap_or_default().min_y() as f64) / scale_factor;
155
156                let event_data = EventType::Mouse(MouseEventData {
157                    global_location,
158                    element_location: CursorPoint::new(element_x, element_y),
159                    button,
160                });
161
162                Self {
163                    node_id,
164                    name,
165                    source_event: platform_event_name.into(),
166                    data: event_data,
167                    bubbles,
168                }
169            }
170            PlatformEvent::Keyboard {
171                name: platform_event_name,
172                ref key,
173                code,
174                modifiers,
175                ..
176            } => Self {
177                node_id,
178                name,
179
180                source_event: platform_event_name.into(),
181                data: EventType::Keyboard(KeyboardEventData::new(key.clone(), code, modifiers)),
182                bubbles,
183            },
184            PlatformEvent::Wheel {
185                name: platform_event_name,
186                scroll,
187                source,
188                cursor,
189                ..
190            } => {
191                let global_location = cursor / scale_factor;
192                let element_x =
193                    (cursor.x - node_area.unwrap_or_default().min_x() as f64) / scale_factor;
194                let element_y =
195                    (cursor.y - node_area.unwrap_or_default().min_y() as f64) / scale_factor;
196                let element_location = CursorPoint::new(element_x, element_y);
197
198                Self {
199                    node_id,
200                    name,
201                    source_event: platform_event_name.into(),
202                    data: EventType::Wheel(WheelEventData::new(
203                        scroll.x,
204                        scroll.y,
205                        source,
206                        global_location,
207                        element_location,
208                    )),
209                    bubbles,
210                }
211            }
212            PlatformEvent::Touch {
213                name: platform_event_name,
214                location,
215                finger_id,
216                phase,
217                force,
218                ..
219            } => {
220                let global_location = location / scale_factor;
221                let element_x =
222                    (location.x - node_area.unwrap_or_default().min_x() as f64) / scale_factor;
223                let element_y =
224                    (location.y - node_area.unwrap_or_default().min_y() as f64) / scale_factor;
225
226                let event_data = EventType::Touch(TouchEventData::new(
227                    global_location,
228                    CursorPoint::new(element_x, element_y),
229                    finger_id,
230                    phase,
231                    force,
232                ));
233
234                Self {
235                    node_id,
236                    name,
237                    source_event: platform_event_name.into(),
238                    data: event_data,
239                    bubbles,
240                }
241            }
242            PlatformEvent::ImePreedit {
243                name: platform_event_name,
244                cursor,
245                text,
246            } => Self {
247                node_id,
248                name,
249
250                source_event: platform_event_name.into(),
251                data: EventType::ImePreedit(ImePreeditEventData::new(text, cursor)),
252                bubbles,
253            },
254            PlatformEvent::File {
255                name: platform_event_name,
256                cursor,
257                file_path,
258            } => Self {
259                node_id,
260                name,
261
262                source_event: platform_event_name.into(),
263                data: EventType::File(FileEventData::new(cursor, file_path)),
264                bubbles,
265            },
266        }
267    }
268}