1use glib::translate::*;
4
5use crate::{ffi, prelude::*, Event, EventType};
6
7impl Event {
8 #[inline]
9 pub fn is<T: EventKind>(&self) -> bool {
10 T::event_types().contains(&self.event_type())
11 }
12
13 #[inline]
14 pub fn type_(&self) -> glib::Type {
15 unsafe {
16 let ptr = self.as_ptr();
17 from_glib((*(*(ptr as *mut glib::gobject_ffi::GTypeInstance)).g_class).g_type)
18 }
19 }
20
21 #[inline]
22 pub fn downcast<T: EventKind>(self) -> Result<T, Event> {
23 unsafe {
24 if self.is::<T>() {
25 Ok(from_glib_full(self.into_glib_ptr()))
26 } else {
27 Err(self)
28 }
29 }
30 }
31
32 #[inline]
33 pub fn downcast_ref<T: EventKind>(&self) -> Option<&T> {
34 unsafe {
35 if self.is::<T>() {
36 Some(&*(self as *const Event as *const T))
37 } else {
38 None
39 }
40 }
41 }
42
43 #[doc(alias = "gdk_events_get_angle")]
63 #[doc(alias = "get_angle")]
64 pub fn angle(&self, event: impl AsRef<Event>) -> Option<f64> {
65 skip_assert_initialized!();
66 unsafe {
67 let mut angle = std::mem::MaybeUninit::uninit();
68 let ret = from_glib(ffi::gdk_events_get_angle(
69 self.to_glib_none().0,
70 event.as_ref().to_glib_none().0,
71 angle.as_mut_ptr(),
72 ));
73 if ret {
74 let angle = angle.assume_init();
75 Some(angle)
76 } else {
77 None
78 }
79 }
80 }
81
82 #[doc(alias = "gdk_events_get_center")]
101 #[doc(alias = "get_center")]
102 pub fn center(&self, event: impl AsRef<Event>) -> Option<(f64, f64)> {
103 skip_assert_initialized!();
104 unsafe {
105 let mut x = std::mem::MaybeUninit::uninit();
106 let mut y = std::mem::MaybeUninit::uninit();
107 let ret = from_glib(ffi::gdk_events_get_center(
108 self.to_glib_none().0,
109 event.as_ref().to_glib_none().0,
110 x.as_mut_ptr(),
111 y.as_mut_ptr(),
112 ));
113 if ret {
114 let x = x.assume_init();
115 let y = y.assume_init();
116 Some((x, y))
117 } else {
118 None
119 }
120 }
121 }
122
123 #[doc(alias = "gdk_events_get_distance")]
139 #[doc(alias = "get_distance")]
140 pub fn distance(&self, event: impl AsRef<Event>) -> Option<f64> {
141 skip_assert_initialized!();
142 unsafe {
143 let mut distance = std::mem::MaybeUninit::uninit();
144 let ret = from_glib(ffi::gdk_events_get_distance(
145 self.to_glib_none().0,
146 event.as_ref().to_glib_none().0,
147 distance.as_mut_ptr(),
148 ));
149 if ret {
150 let distance = distance.assume_init();
151 Some(distance)
152 } else {
153 None
154 }
155 }
156 }
157}
158
159impl std::fmt::Debug for Event {
160 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
161 f.debug_struct("Event")
162 .field("event_type", &self.event_type())
163 .field("history", &self.history())
164 .field("modifier_state", &self.modifier_state())
165 .field("pointer_emulated", &self.is_pointer_emulated())
166 .field("position", &self.position())
167 .field("time", &self.time())
168 .field("triggers_context_menu", &self.triggers_context_menu())
169 .finish()
170 }
171}
172
173#[doc(hidden)]
174impl AsRef<Event> for Event {
175 #[inline]
176 fn as_ref(&self) -> &Self {
177 self
178 }
179}
180
181pub unsafe trait EventKind:
188 StaticType + FromGlibPtrFull<*mut ffi::GdkEvent> + 'static
189{
190 fn event_types() -> &'static [EventType];
191}
192
193macro_rules! define_event {
194 ($rust_type:ident, $ffi_type:path,$event_event_types:expr) => {
195 unsafe impl crate::event::EventKind for $rust_type {
196 #[inline]
197 fn event_types() -> &'static [crate::EventType] {
198 $event_event_types
199 }
200 }
201
202 impl std::ops::Deref for $rust_type {
203 type Target = crate::Event;
204
205 #[inline]
206 fn deref(&self) -> &Self::Target {
207 unsafe { &*(self as *const $rust_type as *const crate::Event) }
208 }
209 }
210
211 impl AsRef<crate::Event> for $rust_type {
212 #[inline]
213 fn as_ref(&self) -> &crate::Event {
214 self.upcast_ref()
215 }
216 }
217
218 #[doc(hidden)]
219 impl glib::translate::FromGlibPtrFull<*mut crate::ffi::GdkEvent> for $rust_type {
220 #[inline]
221 unsafe fn from_glib_full(ptr: *mut crate::ffi::GdkEvent) -> Self {
222 glib::translate::FromGlibPtrFull::from_glib_full(ptr as *mut $ffi_type)
223 }
224 }
225
226 impl $rust_type {
227 #[inline]
228 pub fn upcast(self) -> crate::Event {
229 unsafe { std::mem::transmute(self) }
230 }
231
232 #[inline]
233 pub fn upcast_ref(&self) -> &crate::Event {
234 self
235 }
236 }
237 };
238}