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