Skip to main content

ferroui_base/input/raw/
raw_input_event_args.rs

1use crate::input::{IInputDevice, IInputRoot};
2use std::any::{Any, TypeId};
3use std::cell::Cell;
4use std::ops::Deref;
5use std::rc::Rc;
6
7/// Implemented by every raw input event args type.
8///
9/// Raw event args form a small class hierarchy rooted at
10/// [`RawInputEventArgs`]; a derived type embeds its base as its `base`
11/// field and derefs to it. This trait gives the runtime view of that
12/// hierarchy.
13pub trait IRawInputEventArgs: Any {
14    /// The base raw input event args.
15    fn as_raw_input_event_args(&self) -> &RawInputEventArgs;
16
17    /// Returns the args viewed as the args type identified by `type_id`, if
18    /// the args are of that type or of a type derived from it.
19    fn query_args(&self, type_id: TypeId) -> Option<&dyn Any>;
20}
21
22impl dyn IRawInputEventArgs {
23    /// Returns the args as `T` if they are of type `T` or of a type derived
24    /// from it (C# `e as T`).
25    #[inline]
26    pub fn downcast_ref<T: IRawInputEventArgs>(&self) -> Option<&T> {
27        self.query_args(TypeId::of::<T>()).and_then(<dyn Any>::downcast_ref::<T>)
28    }
29}
30
31impl Deref for dyn IRawInputEventArgs {
32    type Target = RawInputEventArgs;
33
34    #[inline]
35    fn deref(&self) -> &RawInputEventArgs {
36        self.as_raw_input_event_args()
37    }
38}
39
40/// Declares a raw input event args type derived from another one.
41macro_rules! raw_input_event_args {
42    ($name:ident : $base:ty) => {
43        impl ::std::ops::Deref for $name {
44            type Target = $base;
45
46            #[inline]
47            fn deref(&self) -> &$base {
48                &self.base
49            }
50        }
51
52        impl $crate::input::raw::IRawInputEventArgs for $name {
53            #[inline]
54            fn as_raw_input_event_args(&self) -> &$crate::input::raw::RawInputEventArgs {
55                $crate::input::raw::IRawInputEventArgs::as_raw_input_event_args(&self.base)
56            }
57
58            #[inline]
59            fn query_args(&self, type_id: ::std::any::TypeId) -> ::std::option::Option<&dyn ::std::any::Any> {
60                if type_id == ::std::any::TypeId::of::<$name>() {
61                    ::std::option::Option::Some(self)
62                } else {
63                    $crate::input::raw::IRawInputEventArgs::query_args(&self.base, type_id)
64                }
65            }
66        }
67    };
68}
69
70pub(crate) use raw_input_event_args;
71
72/// A raw input event.
73///
74/// Raw input events are sent from the windowing subsystem to the input
75/// manager for processing: this gives an application the opportunity to
76/// pre-process the event. After pre-processing they are consumed by the
77/// relevant input device and turned into standard events.
78pub struct RawInputEventArgs {
79    device: Rc<dyn IInputDevice>,
80    root: Rc<dyn IInputRoot>,
81    handled: Cell<bool>,
82    timestamp: Cell<u64>,
83}
84
85impl RawInputEventArgs {
86    /// Creates raw input event args.
87    ///
88    /// `timestamp` is the time stamp of the input as reported by the
89    /// platform; `root` is the root from which the event originates.
90    pub fn new(device: Rc<dyn IInputDevice>, timestamp: u64, root: Rc<dyn IInputRoot>) -> Self {
91        Self { device, root, handled: Cell::new(false), timestamp: Cell::new(timestamp) }
92    }
93
94    /// The associated device.
95    #[inline]
96    pub fn device(&self) -> &Rc<dyn IInputDevice> {
97        &self.device
98    }
99
100    /// The root from which the event originates.
101    #[inline]
102    pub fn root(&self) -> &Rc<dyn IInputRoot> {
103        &self.root
104    }
105
106    /// Whether the event was handled.
107    ///
108    /// If an event is not marked handled after processing, this event will
109    /// be returned to the windowing subsystem for further processing.
110    #[inline]
111    pub fn handled(&self) -> bool {
112        self.handled.get()
113    }
114
115    /// Marks the event as handled or unhandled.
116    #[inline]
117    pub fn set_handled(&self, value: bool) {
118        self.handled.set(value)
119    }
120
121    /// The timestamp associated with the event.
122    #[inline]
123    pub fn timestamp(&self) -> u64 {
124        self.timestamp.get()
125    }
126
127    /// Sets the timestamp associated with the event.
128    #[inline]
129    pub fn set_timestamp(&self, value: u64) {
130        self.timestamp.set(value)
131    }
132}
133
134impl IRawInputEventArgs for RawInputEventArgs {
135    #[inline]
136    fn as_raw_input_event_args(&self) -> &RawInputEventArgs {
137        self
138    }
139
140    #[inline]
141    fn query_args(&self, type_id: TypeId) -> Option<&dyn Any> {
142        if type_id == TypeId::of::<RawInputEventArgs>() {
143            Some(self)
144        } else {
145            None
146        }
147    }
148}