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")]
44 #[doc(alias = "get_angle")]
45 pub fn angle(&self, event: impl AsRef<Event>) -> Option<f64> {
46 skip_assert_initialized!();
47 unsafe {
48 let mut angle = std::mem::MaybeUninit::uninit();
49 let ret = from_glib(ffi::gdk_events_get_angle(
50 self.to_glib_none().0,
51 event.as_ref().to_glib_none().0,
52 angle.as_mut_ptr(),
53 ));
54 if ret {
55 let angle = angle.assume_init();
56 Some(angle)
57 } else {
58 None
59 }
60 }
61 }
62
63 #[doc(alias = "gdk_events_get_center")]
64 #[doc(alias = "get_center")]
65 pub fn center(&self, event: impl AsRef<Event>) -> Option<(f64, f64)> {
66 skip_assert_initialized!();
67 unsafe {
68 let mut x = std::mem::MaybeUninit::uninit();
69 let mut y = std::mem::MaybeUninit::uninit();
70 let ret = from_glib(ffi::gdk_events_get_center(
71 self.to_glib_none().0,
72 event.as_ref().to_glib_none().0,
73 x.as_mut_ptr(),
74 y.as_mut_ptr(),
75 ));
76 if ret {
77 let x = x.assume_init();
78 let y = y.assume_init();
79 Some((x, y))
80 } else {
81 None
82 }
83 }
84 }
85
86 #[doc(alias = "gdk_events_get_distance")]
87 #[doc(alias = "get_distance")]
88 pub fn distance(&self, event: impl AsRef<Event>) -> Option<f64> {
89 skip_assert_initialized!();
90 unsafe {
91 let mut distance = std::mem::MaybeUninit::uninit();
92 let ret = from_glib(ffi::gdk_events_get_distance(
93 self.to_glib_none().0,
94 event.as_ref().to_glib_none().0,
95 distance.as_mut_ptr(),
96 ));
97 if ret {
98 let distance = distance.assume_init();
99 Some(distance)
100 } else {
101 None
102 }
103 }
104 }
105}
106
107impl std::fmt::Debug for Event {
108 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
109 f.debug_struct("Event")
110 .field("event_type", &self.event_type())
111 .field("history", &self.history())
112 .field("modifier_state", &self.modifier_state())
113 .field("pointer_emulated", &self.is_pointer_emulated())
114 .field("position", &self.position())
115 .field("time", &self.time())
116 .field("triggers_context_menu", &self.triggers_context_menu())
117 .finish()
118 }
119}
120
121#[doc(hidden)]
122impl AsRef<Event> for Event {
123 #[inline]
124 fn as_ref(&self) -> &Self {
125 self
126 }
127}
128
129pub unsafe trait EventKind:
136 StaticType + FromGlibPtrFull<*mut ffi::GdkEvent> + 'static
137{
138 fn event_types() -> &'static [EventType];
139}
140
141macro_rules! define_event {
142 ($rust_type:ident, $ffi_type:path,$event_event_types:expr) => {
143 unsafe impl crate::event::EventKind for $rust_type {
144 #[inline]
145 fn event_types() -> &'static [crate::EventType] {
146 $event_event_types
147 }
148 }
149
150 impl std::ops::Deref for $rust_type {
151 type Target = crate::Event;
152
153 #[inline]
154 fn deref(&self) -> &Self::Target {
155 unsafe { &*(self as *const $rust_type as *const crate::Event) }
156 }
157 }
158
159 impl AsRef<crate::Event> for $rust_type {
160 #[inline]
161 fn as_ref(&self) -> &crate::Event {
162 self.upcast_ref()
163 }
164 }
165
166 #[doc(hidden)]
167 impl glib::translate::FromGlibPtrFull<*mut crate::ffi::GdkEvent> for $rust_type {
168 #[inline]
169 unsafe fn from_glib_full(ptr: *mut crate::ffi::GdkEvent) -> Self {
170 glib::translate::FromGlibPtrFull::from_glib_full(ptr as *mut $ffi_type)
171 }
172 }
173
174 impl $rust_type {
175 #[inline]
176 pub fn upcast(self) -> crate::Event {
177 unsafe { std::mem::transmute(self) }
178 }
179
180 #[inline]
181 pub fn upcast_ref(&self) -> &crate::Event {
182 self
183 }
184 }
185 };
186}