dioxus_html/
geometry.rs

1//! Geometry primitives for representing e.g. mouse events
2
3/// A re-export of euclid, which we use for geometry primitives
4pub use euclid;
5
6use euclid::*;
7
8/// Coordinate space relative to the screen
9pub struct ScreenSpace;
10/// A point in ScreenSpace
11pub type ScreenPoint = Point2D<f64, ScreenSpace>;
12
13/// Coordinate space relative to the viewport
14pub struct ClientSpace;
15/// A point in ClientSpace
16pub type ClientPoint = Point2D<f64, ClientSpace>;
17
18/// Coordinate space relative to an element
19pub struct ElementSpace;
20/// A point in ElementSpace
21pub type ElementPoint = Point2D<f64, ElementSpace>;
22
23/// Coordinate space relative to the page
24pub struct PageSpace;
25/// A point in PageSpace
26pub type PagePoint = Point2D<f64, PageSpace>;
27
28/// A pixel unit: one unit corresponds to 1 pixel
29pub struct Pixels;
30/// A size expressed in Pixels
31pub type PixelsSize = Size2D<f64, Pixels>;
32/// A rectangle expressed in Pixels
33pub type PixelsRect = Rect<f64, Pixels>;
34/// A 2D vector expressed in Pixels
35pub type PixelsVector2D = Vector2D<f64, Pixels>;
36/// A 3D vector expressed in Pixels
37pub type PixelsVector3D = Vector3D<f64, Pixels>;
38
39/// A unit in terms of Lines
40///
41/// One unit is relative to the size of one line
42pub struct Lines;
43/// A vector expressed in Lines
44pub type LinesVector = Vector3D<f64, Lines>;
45
46/// A unit in terms of Screens:
47///
48/// One unit is relative to the size of a page
49pub struct Pages;
50/// A vector expressed in Pages
51pub type PagesVector = Vector3D<f64, Pages>;
52
53/// A vector representing the amount the mouse wheel was moved
54///
55/// This may be expressed in Pixels, Lines or Pages
56#[derive(Copy, Clone, Debug, PartialEq)]
57#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
58pub enum WheelDelta {
59    /// Movement in Pixels
60    Pixels(PixelsVector3D),
61    /// Movement in Lines
62    Lines(LinesVector),
63    /// Movement in Pages
64    Pages(PagesVector),
65}
66
67impl WheelDelta {
68    /// Construct from the attributes of the web wheel event
69    pub fn from_web_attributes(delta_mode: u32, delta_x: f64, delta_y: f64, delta_z: f64) -> Self {
70        match delta_mode {
71            0 => WheelDelta::Pixels(PixelsVector3D::new(delta_x, delta_y, delta_z)),
72            1 => WheelDelta::Lines(LinesVector::new(delta_x, delta_y, delta_z)),
73            2 => WheelDelta::Pages(PagesVector::new(delta_x, delta_y, delta_z)),
74            _ => panic!("Invalid delta mode, {:?}", delta_mode),
75        }
76    }
77
78    /// Convenience function for constructing a WheelDelta with pixel units
79    pub fn pixels(x: f64, y: f64, z: f64) -> Self {
80        WheelDelta::Pixels(PixelsVector3D::new(x, y, z))
81    }
82
83    /// Convenience function for constructing a WheelDelta with line units
84    pub fn lines(x: f64, y: f64, z: f64) -> Self {
85        WheelDelta::Lines(LinesVector::new(x, y, z))
86    }
87
88    /// Convenience function for constructing a WheelDelta with page units
89    pub fn pages(x: f64, y: f64, z: f64) -> Self {
90        WheelDelta::Pages(PagesVector::new(x, y, z))
91    }
92
93    /// Returns true iff there is no wheel movement
94    ///
95    /// i.e. the x, y and z delta is zero (disregards units)
96    pub fn is_zero(&self) -> bool {
97        self.strip_units() == Vector3D::new(0., 0., 0.)
98    }
99
100    /// A Vector3D proportional to the amount scrolled
101    ///
102    /// Note that this disregards the 3 possible units: this could be expressed in terms of pixels, lines, or pages.
103    ///
104    /// In most cases, to properly handle scrolling, you should handle all 3 possible enum variants instead of stripping units. Otherwise, if you assume that the units will always be pixels, the user may experience some unexpectedly slow scrolling if their mouse/OS sends values expressed in lines or pages.
105    pub fn strip_units(&self) -> Vector3D<f64, UnknownUnit> {
106        match self {
107            WheelDelta::Pixels(v) => v.cast_unit(),
108            WheelDelta::Lines(v) => v.cast_unit(),
109            WheelDelta::Pages(v) => v.cast_unit(),
110        }
111    }
112}
113
114/// Coordinates of a point in the app's interface
115#[derive(Debug, PartialEq)]
116pub struct Coordinates {
117    screen: ScreenPoint,
118    client: ClientPoint,
119    element: ElementPoint,
120    page: PagePoint,
121}
122
123impl Coordinates {
124    /// Construct new coordinates with the specified screen-, client-, element- and page-relative points
125    pub fn new(
126        screen: ScreenPoint,
127        client: ClientPoint,
128        element: ElementPoint,
129        page: PagePoint,
130    ) -> Self {
131        Self {
132            screen,
133            client,
134            element,
135            page,
136        }
137    }
138    /// Coordinates relative to the entire screen. This takes into account the window's offset.
139    pub fn screen(&self) -> ScreenPoint {
140        self.screen
141    }
142    /// Coordinates relative to the application's viewport (as opposed to the coordinate within the page).
143    ///
144    /// For example, clicking in the top left corner of the viewport will always result in a mouse event with client coordinates (0., 0.), regardless of whether the page is scrolled horizontally.
145    pub fn client(&self) -> ClientPoint {
146        self.client
147    }
148    /// Coordinates relative to the padding edge of the target element
149    ///
150    /// For example, clicking in the top left corner of an element will result in element coordinates (0., 0.)
151    pub fn element(&self) -> ElementPoint {
152        self.element
153    }
154    /// Coordinates relative to the entire document. This includes any portion of the document not currently visible.
155    ///
156    /// For example, if the page is scrolled 200 pixels to the right and 300 pixels down, clicking in the top left corner of the viewport would result in page coordinates (200., 300.)
157    pub fn page(&self) -> PagePoint {
158        self.page
159    }
160}