Skip to main content

ferroui_base/input/raw/
raw_pointer_event_args.rs

1use super::raw_input_event_args::raw_input_event_args;
2use super::RawInputEventArgs;
3use crate::input::{IInputDevice, IInputRoot, InputElement, IntermediatePoints, RawInputModifiers};
4use crate::{Point, Rect, Ref, Size};
5use std::any::Any;
6use std::cell::{Cell, RefCell};
7use std::rc::Rc;
8
9/// The kinds of raw pointer events.
10#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
11pub enum RawPointerEventType {
12    LeaveWindow,
13    LeftButtonDown,
14    LeftButtonUp,
15    RightButtonDown,
16    RightButtonUp,
17    MiddleButtonDown,
18    MiddleButtonUp,
19    XButton1Down,
20    XButton1Up,
21    XButton2Down,
22    XButton2Up,
23    Move,
24    Wheel,
25    NonClientLeftButtonDown,
26    TouchBegin,
27    TouchUpdate,
28    TouchEnd,
29    TouchCancel,
30    Magnify,
31    Rotate,
32    Swipe,
33    CancelCapture,
34}
35
36/// The result of input hit testing a raw pointer event: the element under
37/// the pointer and its first enabled ancestor (or itself).
38type InputHitTestResult = (Option<Ref<InputElement>>, Option<Ref<InputElement>>);
39
40/// A raw mouse (or other pointer) event.
41pub struct RawPointerEventArgs {
42    base: RawInputEventArgs,
43    point: Cell<RawPointerPoint>,
44    raw_pointer_id: Cell<i64>,
45    type_: Cell<RawPointerEventType>,
46    input_modifiers: Cell<RawInputModifiers>,
47    intermediate_points: RefCell<Option<IntermediatePoints>>,
48    platform_input_event_cookie: RefCell<Option<Rc<dyn Any>>>,
49    input_hit_test_result: RefCell<InputHitTestResult>,
50}
51
52raw_input_event_args!(RawPointerEventArgs: RawInputEventArgs);
53
54impl RawPointerEventArgs {
55    /// Creates raw pointer event args for a position in client coordinates.
56    pub fn new(
57        device: Rc<dyn IInputDevice>,
58        timestamp: u64,
59        root: Rc<dyn IInputRoot>,
60        type_: RawPointerEventType,
61        position: Point,
62        input_modifiers: RawInputModifiers,
63    ) -> Self {
64        let point = RawPointerPoint { position, ..RawPointerPoint::new() };
65        Self::with_point(device, timestamp, root, type_, point, input_modifiers)
66    }
67
68    /// Creates raw pointer event args for a raw pointer point.
69    pub fn with_point(
70        device: Rc<dyn IInputDevice>,
71        timestamp: u64,
72        root: Rc<dyn IInputRoot>,
73        type_: RawPointerEventType,
74        point: RawPointerPoint,
75        input_modifiers: RawInputModifiers,
76    ) -> Self {
77        Self {
78            base: RawInputEventArgs::new(device, timestamp, root),
79            point: Cell::new(point),
80            raw_pointer_id: Cell::new(0),
81            type_: Cell::new(type_),
82            input_modifiers: Cell::new(input_modifiers),
83            intermediate_points: RefCell::new(None),
84            platform_input_event_cookie: RefCell::new(None),
85            input_hit_test_result: RefCell::new((None, None)),
86        }
87    }
88
89    /// The raw pointer identifier.
90    #[inline]
91    pub fn raw_pointer_id(&self) -> i64 {
92        self.raw_pointer_id.get()
93    }
94
95    pub fn set_raw_pointer_id(&self, value: i64) {
96        self.raw_pointer_id.set(value)
97    }
98
99    /// The pointer properties and position, in client DIPs.
100    #[inline]
101    pub fn point(&self) -> RawPointerPoint {
102        self.point.get()
103    }
104
105    pub fn set_point(&self, value: RawPointerPoint) {
106        self.point.set(value)
107    }
108
109    /// The mouse position, in client DIPs.
110    #[inline]
111    pub fn position(&self) -> Point {
112        self.point.get().position
113    }
114
115    pub fn set_position(&self, value: Point) {
116        let mut point = self.point.get();
117        point.position = value;
118        self.point.set(point);
119    }
120
121    /// The type of the event.
122    #[inline]
123    pub fn type_(&self) -> RawPointerEventType {
124        self.type_.get()
125    }
126
127    pub fn set_type(&self, value: RawPointerEventType) {
128        self.type_.set(value)
129    }
130
131    /// The input modifiers.
132    #[inline]
133    pub fn input_modifiers(&self) -> RawInputModifiers {
134        self.input_modifiers.get()
135    }
136
137    pub fn set_input_modifiers(&self, value: RawInputModifiers) {
138        self.input_modifiers.set(value)
139    }
140
141    /// Points that were traversed by a pointer since the previous relevant
142    /// event, only valid for Move and TouchUpdate.
143    pub fn intermediate_points(&self) -> Option<IntermediatePoints> {
144        self.intermediate_points.borrow().clone()
145    }
146
147    pub fn set_intermediate_points(&self, value: Option<IntermediatePoints>) {
148        let old = self.intermediate_points.replace(value);
149        drop(old);
150    }
151
152    /// The platform's opaque cookie for the input event.
153    pub fn platform_input_event_cookie(&self) -> Option<Rc<dyn Any>> {
154        self.platform_input_event_cookie.borrow().clone()
155    }
156
157    pub fn set_platform_input_event_cookie(&self, value: Option<Rc<dyn Any>>) {
158        let old = self.platform_input_event_cookie.replace(value);
159        drop(old);
160    }
161
162    /// The result of input hit testing the event: the element under the
163    /// pointer and its first enabled ancestor. Set by the presentation
164    /// source before the event is processed.
165    pub fn input_hit_test_result(&self) -> (Option<Ref<InputElement>>, Option<Ref<InputElement>>) {
166        self.input_hit_test_result.borrow().clone()
167    }
168
169    pub fn set_input_hit_test_result(
170        &self,
171        element: Option<Ref<InputElement>>,
172        first_enabled_ancestor: Option<Ref<InputElement>>,
173    ) {
174        let old = self.input_hit_test_result.replace((element, first_enabled_ancestor));
175        drop(old);
176    }
177}
178
179/// The position and pen state of a raw pointer event.
180#[derive(Clone, Copy, Debug, PartialEq)]
181pub struct RawPointerPoint {
182    /// Pointer position, in client DIPs.
183    pub position: Point,
184    pub twist: f32,
185    pub pressure: f32,
186    pub x_tilt: f32,
187    pub y_tilt: f32,
188    contact_rect: Option<Rect>,
189}
190
191impl Default for RawPointerPoint {
192    fn default() -> Self {
193        Self::new()
194    }
195}
196
197impl RawPointerPoint {
198    /// Creates a raw pointer point at the origin with default pressure.
199    pub fn new() -> Self {
200        Self { position: Point::default(), twist: 0.0, pressure: 0.5, x_tilt: 0.0, y_tilt: 0.0, contact_rect: None }
201    }
202
203    /// The contact rectangle of the pointer; an empty rectangle at the
204    /// pointer position unless set.
205    pub fn contact_rect(&self) -> Rect {
206        self.contact_rect.unwrap_or_else(|| Rect::from_position_size(self.position, Size::default()))
207    }
208
209    pub fn set_contact_rect(&mut self, value: Rect) {
210        self.contact_rect = Some(value);
211    }
212}