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_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}