input_data.rs 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. //! Data structures representing user input, such as modifier keys and mouse buttons
  2. use enumset::{EnumSet, EnumSetType};
  3. /// A re-export of keyboard_types
  4. pub use keyboard_types;
  5. use keyboard_types::Location;
  6. /// A mouse button type (such as Primary/Secondary)
  7. // note: EnumSetType also derives Copy and Clone for some reason
  8. #[allow(clippy::unused_unit)]
  9. #[derive(EnumSetType, Debug, Default)]
  10. #[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
  11. pub enum MouseButton {
  12. #[default]
  13. /// Primary button (typically the left button)
  14. Primary,
  15. /// Secondary button (typically the right button)
  16. Secondary,
  17. /// Auxiliary button (typically the middle button)
  18. Auxiliary,
  19. /// Fourth button (typically the "Browser Back" button)
  20. Fourth,
  21. /// Fifth button (typically the "Browser Forward" button)
  22. Fifth,
  23. /// A button with an unknown code
  24. Unknown,
  25. }
  26. impl MouseButton {
  27. /// Constructs a MouseButton for the specified button code
  28. ///
  29. /// E.g. 0 => Primary; 1 => Auxiliary
  30. ///
  31. /// Unknown codes get mapped to MouseButton::Unknown.
  32. pub fn from_web_code(code: i16) -> Self {
  33. match code {
  34. 0 => MouseButton::Primary,
  35. // not a typo; auxiliary and secondary are swapped unlike in the `buttons` field.
  36. // https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/button
  37. 1 => MouseButton::Auxiliary,
  38. 2 => MouseButton::Secondary,
  39. 3 => MouseButton::Fourth,
  40. 4 => MouseButton::Fifth,
  41. _ => MouseButton::Unknown,
  42. }
  43. }
  44. /// Converts MouseButton into the corresponding button code
  45. ///
  46. /// MouseButton::Unknown will get mapped to -1
  47. pub fn into_web_code(self) -> i16 {
  48. match self {
  49. MouseButton::Primary => 0,
  50. // not a typo; auxiliary and secondary are swapped unlike in the `buttons` field.
  51. // https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/button
  52. MouseButton::Auxiliary => 1,
  53. MouseButton::Secondary => 2,
  54. MouseButton::Fourth => 3,
  55. MouseButton::Fifth => 4,
  56. MouseButton::Unknown => -1,
  57. }
  58. }
  59. }
  60. /// A set of mouse buttons
  61. pub type MouseButtonSet = EnumSet<MouseButton>;
  62. pub fn decode_mouse_button_set(code: u16) -> MouseButtonSet {
  63. let mut set = EnumSet::empty();
  64. // https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/buttons
  65. #[allow(deprecated)]
  66. {
  67. if code & 0b1 != 0 {
  68. set |= MouseButton::Primary;
  69. }
  70. if code & 0b10 != 0 {
  71. set |= MouseButton::Secondary;
  72. }
  73. if code & 0b100 != 0 {
  74. set |= MouseButton::Auxiliary;
  75. }
  76. if code & 0b1000 != 0 {
  77. set |= MouseButton::Fourth;
  78. }
  79. if code & 0b10000 != 0 {
  80. set |= MouseButton::Fifth;
  81. }
  82. if code & (!0b11111) != 0 {
  83. set |= MouseButton::Unknown;
  84. }
  85. }
  86. set
  87. }
  88. pub fn encode_mouse_button_set(set: MouseButtonSet) -> u16 {
  89. let mut code = 0;
  90. // https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/buttons
  91. {
  92. if set.contains(MouseButton::Primary) {
  93. code |= 0b1;
  94. }
  95. if set.contains(MouseButton::Secondary) {
  96. code |= 0b10;
  97. }
  98. if set.contains(MouseButton::Auxiliary) {
  99. code |= 0b100;
  100. }
  101. if set.contains(MouseButton::Fourth) {
  102. code |= 0b1000;
  103. }
  104. if set.contains(MouseButton::Fifth) {
  105. code |= 0b10000;
  106. }
  107. if set.contains(MouseButton::Unknown) {
  108. code |= 0b100000;
  109. }
  110. }
  111. code
  112. }
  113. pub fn decode_key_location(code: usize) -> Location {
  114. match code {
  115. 0 => Location::Standard,
  116. 1 => Location::Left,
  117. 2 => Location::Right,
  118. 3 => Location::Numpad,
  119. // keyboard_types doesn't yet support mobile/joystick locations
  120. 4 | 5 => Location::Standard,
  121. // unknown location; Standard seems better than panicking
  122. _ => Location::Standard,
  123. }
  124. }
  125. pub fn encode_key_location(location: Location) -> usize {
  126. match location {
  127. Location::Standard => 0,
  128. Location::Left => 1,
  129. Location::Right => 2,
  130. Location::Numpad => 3,
  131. }
  132. }