Skip to main content

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