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 ..
179 } => Self {
180 node_id,
181 name,
182 source_event: platform_event_name.into(),
183 data: EventType::Wheel(WheelEventData::new(scroll.x, scroll.y, source)),
184 bubbles,
185 },
186 PlatformEvent::Touch {
187 name: platform_event_name,
188 location,
189 finger_id,
190 phase,
191 force,
192 ..
193 } => {
194 let global_location = location / scale_factor;
195 let element_x =
196 (location.x - node_area.unwrap_or_default().min_x() as f64) / scale_factor;
197 let element_y =
198 (location.y - node_area.unwrap_or_default().min_y() as f64) / scale_factor;
199
200 let event_data = EventType::Touch(TouchEventData::new(
201 global_location,
202 CursorPoint::new(element_x, element_y),
203 finger_id,
204 phase,
205 force,
206 ));
207
208 Self {
209 node_id,
210 name,
211 source_event: platform_event_name.into(),
212 data: event_data,
213 bubbles,
214 }
215 }
216 PlatformEvent::ImePreedit {
217 name: platform_event_name,
218 cursor,
219 text,
220 } => Self {
221 node_id,
222 name,
223
224 source_event: platform_event_name.into(),
225 data: EventType::ImePreedit(ImePreeditEventData::new(text, cursor)),
226 bubbles,
227 },
228 PlatformEvent::File {
229 name: platform_event_name,
230 cursor,
231 file_path,
232 } => Self {
233 node_id,
234 name,
235
236 source_event: platform_event_name.into(),
237 data: EventType::File(FileEventData::new(cursor, file_path)),
238 bubbles,
239 },
240 }
241 }
242}