[go: up one dir, main page]

gdk4/
event.rs

1// Take a look at the license at the top of the repository in the LICENSE file.
2
3use 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
129// rustdoc-stripper-ignore-next
130/// A common trait implemented by the various [`Event`](crate::Event) types.
131///
132/// # Safety
133///
134/// The user is not supposed to implement this trait.
135pub 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}