freya_elements/events/
pointer.rs

1use torin::geometry::CursorPoint;
2pub use winit::event::MouseButton;
3use winit::event::{
4    Force,
5    TouchPhase,
6};
7
8use crate::{
9    events::ErasedEventData,
10    impl_event,
11};
12impl_event! [
13    PointerData;
14
15    /// The `pointerdown` event fires when the user clicks/starts touching an element.
16    ///
17    /// Event Data: [`PointerData`](crate::events::PointerData)
18    ///
19    /// ### Example
20    ///
21    /// ```rust, no_run
22    /// # use freya::prelude::*;
23    /// fn app() -> Element {
24    ///     rsx!(
25    ///         rect {
26    ///             width: "100",
27    ///             height: "100",
28    ///             background: "red",
29    ///             onpointerdown: |_| println!("Clicked/started pressing!")
30    ///         }
31    ///     )
32    /// }
33    /// ```
34    onpointerdown
35
36    /// The `pointerup` event fires when the user releases their mouse button or stops touching the element.
37    ///
38    /// Event Data: [`PointerData`](crate::events::PointerData)
39    ///
40    /// ### Example
41    ///
42    /// ```rust, no_run
43    /// # use freya::prelude::*;
44    /// fn app() -> Element {
45    ///     rsx!(
46    ///         rect {
47    ///             width: "100",
48    ///             height: "100",
49    ///             background: "red",
50    ///             onpointerup: |_| println!("Released mouse button, or no longer touching!")
51    ///         }
52    ///     )
53    /// }
54    /// ```
55    onpointerup
56
57    /// The `globalpointerup` event fires when the user releases the point anywhere in the app.
58    ///
59    /// Event Data: [`PointerData`](crate::events::PointerData)
60    ///
61    /// ### Example
62    ///
63    /// ```rust, no_run
64    /// # use freya::prelude::*;
65    /// fn app() -> Element {
66    ///     rsx!(
67    ///         rect {
68    ///             onglobalpointerup: |_| println!("Pointer released somewhere else!")
69    ///         }
70    ///         rect {
71    ///             width: "100",
72    ///             height: "100",
73    ///             background: "red",
74    ///             onclick: |_| println!("Clicked!")
75    ///         }
76    ///     )
77    /// }
78    /// ```
79    onglobalpointerup
80
81    /// The `pointermove` event fires when the user moves the cursor or touches over an element.
82    /// Unlike [`onpointerenter`](crate::events::onpointerenter()), this fires even if the user was already hovering over
83    /// the element.
84    ///
85    /// Event Data: [`PointerData`](crate::events::PointerData)
86    ///
87    /// ### Example
88    ///
89    /// ```rust, no_run
90    /// # use freya::prelude::*;
91    /// fn app() -> Element {
92    ///     rsx!(
93    ///         rect {
94    ///             width: "100",
95    ///             height: "100",
96    ///             background: "red",
97    ///             onpointermove: |_| println!("Moving or touching!")
98    ///         }
99    ///     )
100    /// }
101    /// ```
102    onpointermove
103
104    /// The `pointerenter` event fires when the user starts hovering/touching an element.
105    ///
106    /// Event Data: [`PointerData`](crate::events::PointerData)
107    ///
108    /// ### Example
109    ///
110    /// ```rust, no_run
111    /// # use freya::prelude::*;
112    /// fn app() -> Element {
113    ///     rsx!(
114    ///         rect {
115    ///             width: "100",
116    ///             height: "100",
117    ///             background: "red",
118    ///             onpointerenter: |_| println!("Started hovering or touching!")
119    ///         }
120    ///     )
121    /// }
122    /// ```
123    onpointerenter
124
125    /// The `pointerleave` event fires when the user stops hovering/touching an element.
126    ///
127    /// Event Data: [`PointerData`](crate::events::PointerData)
128    ///
129    /// ### Example
130    ///
131    /// ```rust, no_run
132    /// # use freya::prelude::*;
133    /// fn app() -> Element {
134    ///     rsx!(
135    ///         rect {
136    ///             width: "100",
137    ///             height: "100",
138    ///             background: "red",
139    ///             onpointerleave: |_| println!("Started hovering or touching!")
140    ///         }
141    ///     )
142    /// }
143    /// ```
144    onpointerleave
145];
146
147/// The type of device that triggered a Pointer event.
148#[derive(Debug, Clone, PartialEq, Copy)]
149pub enum PointerType {
150    Mouse {
151        trigger_button: Option<MouseButton>,
152    },
153    Touch {
154        finger_id: u64,
155        phase: TouchPhase,
156        force: Option<Force>,
157    },
158}
159
160/// Data of a Mouse event.
161#[derive(Debug, Clone, PartialEq)]
162pub struct PointerData {
163    pub screen_coordinates: CursorPoint,
164    pub element_coordinates: CursorPoint,
165    pub pointer_type: PointerType,
166}
167
168impl PointerData {
169    pub fn new(
170        screen_coordinates: CursorPoint,
171        element_coordinates: CursorPoint,
172        point_type: PointerType,
173    ) -> Self {
174        Self {
175            screen_coordinates,
176            element_coordinates,
177            pointer_type: point_type,
178        }
179    }
180}
181
182impl PointerData {
183    /// Get the mouse coordinates relative to the window bounds.
184    pub fn get_screen_coordinates(&self) -> CursorPoint {
185        self.screen_coordinates
186    }
187
188    /// Get the mouse coordinates relatives to the element bounds.
189    pub fn get_element_coordinates(&self) -> CursorPoint {
190        self.element_coordinates
191    }
192
193    /// Get the pointer type that triggered this event.
194    pub fn get_pointer_type(&self) -> PointerType {
195        self.pointer_type
196    }
197}
198
199impl From<&ErasedEventData> for PointerData {
200    fn from(val: &ErasedEventData) -> Self {
201        val.downcast::<PointerData>().cloned().unwrap()
202    }
203}