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#[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}