use glib::translate::*;
use crate::{ffi, prelude::*, Event, EventType};
impl Event {
#[inline]
pub fn is<T: EventKind>(&self) -> bool {
T::event_types().contains(&self.event_type())
}
#[inline]
pub fn type_(&self) -> glib::Type {
unsafe {
let ptr = self.as_ptr();
from_glib((*(*(ptr as *mut glib::gobject_ffi::GTypeInstance)).g_class).g_type)
}
}
#[inline]
pub fn downcast<T: EventKind>(self) -> Result<T, Event> {
unsafe {
if self.is::<T>() {
Ok(from_glib_full(self.into_glib_ptr()))
} else {
Err(self)
}
}
}
#[inline]
pub fn downcast_ref<T: EventKind>(&self) -> Option<&T> {
unsafe {
if self.is::<T>() {
Some(&*(self as *const Event as *const T))
} else {
None
}
}
}
#[doc(alias = "gdk_events_get_angle")]
#[doc(alias = "get_angle")]
pub fn angle(&self, event: impl AsRef<Event>) -> Option<f64> {
skip_assert_initialized!();
unsafe {
let mut angle = std::mem::MaybeUninit::uninit();
let ret = from_glib(ffi::gdk_events_get_angle(
self.to_glib_none().0,
event.as_ref().to_glib_none().0,
angle.as_mut_ptr(),
));
if ret {
let angle = angle.assume_init();
Some(angle)
} else {
None
}
}
}
#[doc(alias = "gdk_events_get_center")]
#[doc(alias = "get_center")]
pub fn center(&self, event: impl AsRef<Event>) -> Option<(f64, f64)> {
skip_assert_initialized!();
unsafe {
let mut x = std::mem::MaybeUninit::uninit();
let mut y = std::mem::MaybeUninit::uninit();
let ret = from_glib(ffi::gdk_events_get_center(
self.to_glib_none().0,
event.as_ref().to_glib_none().0,
x.as_mut_ptr(),
y.as_mut_ptr(),
));
if ret {
let x = x.assume_init();
let y = y.assume_init();
Some((x, y))
} else {
None
}
}
}
#[doc(alias = "gdk_events_get_distance")]
#[doc(alias = "get_distance")]
pub fn distance(&self, event: impl AsRef<Event>) -> Option<f64> {
skip_assert_initialized!();
unsafe {
let mut distance = std::mem::MaybeUninit::uninit();
let ret = from_glib(ffi::gdk_events_get_distance(
self.to_glib_none().0,
event.as_ref().to_glib_none().0,
distance.as_mut_ptr(),
));
if ret {
let distance = distance.assume_init();
Some(distance)
} else {
None
}
}
}
}
impl std::fmt::Debug for Event {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
f.debug_struct("Event")
.field("event_type", &self.event_type())
.field("history", &self.history())
.field("modifier_state", &self.modifier_state())
.field("pointer_emulated", &self.is_pointer_emulated())
.field("position", &self.position())
.field("time", &self.time())
.field("triggers_context_menu", &self.triggers_context_menu())
.finish()
}
}
#[doc(hidden)]
impl AsRef<Event> for Event {
#[inline]
fn as_ref(&self) -> &Self {
self
}
}
pub unsafe trait EventKind:
StaticType + FromGlibPtrFull<*mut ffi::GdkEvent> + 'static
{
fn event_types() -> &'static [EventType];
}
macro_rules! define_event {
($rust_type:ident, $ffi_type:path,$event_event_types:expr) => {
unsafe impl crate::event::EventKind for $rust_type {
#[inline]
fn event_types() -> &'static [crate::EventType] {
$event_event_types
}
}
impl std::ops::Deref for $rust_type {
type Target = crate::Event;
#[inline]
fn deref(&self) -> &Self::Target {
unsafe { &*(self as *const $rust_type as *const crate::Event) }
}
}
impl AsRef<crate::Event> for $rust_type {
#[inline]
fn as_ref(&self) -> &crate::Event {
self.upcast_ref()
}
}
#[doc(hidden)]
impl glib::translate::FromGlibPtrFull<*mut crate::ffi::GdkEvent> for $rust_type {
#[inline]
unsafe fn from_glib_full(ptr: *mut crate::ffi::GdkEvent) -> Self {
glib::translate::FromGlibPtrFull::from_glib_full(ptr as *mut $ffi_type)
}
}
impl $rust_type {
#[inline]
pub fn upcast(self) -> crate::Event {
unsafe { std::mem::transmute(self) }
}
#[inline]
pub fn upcast_ref(&self) -> &crate::Event {
self
}
}
};
}