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() || 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}