1
0

geometry.rs 5.4 KB

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