use std::default::Default;
use std::cmp::Ordering;
use GenericEvent;
use Button;
bitflags!(
#[allow(missing_docs)]
#[derive(Deserialize, Serialize)]
pub struct ModifierKey: u8 {
const NO_MODIFIER = 0b00000000;
const CTRL = 0b00000001;
const SHIFT = 0b00000010;
const ALT = 0b00000100;
const GUI = 0b00001000;
const CTRL_SHIFT = ModifierKey::CTRL.bits
| ModifierKey::SHIFT.bits;
const CTRL_ALT = ModifierKey::CTRL.bits
| ModifierKey::ALT.bits;
const CTRL_GUI = ModifierKey::CTRL.bits
| ModifierKey::GUI.bits;
const CTRL_SHIFT_ALT = ModifierKey::CTRL.bits
| ModifierKey::SHIFT.bits
| ModifierKey::ALT.bits;
const CTRL_SHIFT_GUI = ModifierKey::CTRL.bits
| ModifierKey::SHIFT.bits
| ModifierKey::GUI.bits;
const CTRL_SHIFT_ALT_GUI = ModifierKey::CTRL.bits
| ModifierKey::SHIFT.bits
| ModifierKey::ALT.bits
| ModifierKey::GUI.bits;
const SHIFT_ALT = ModifierKey::SHIFT.bits
| ModifierKey::ALT.bits;
const SHIFT_GUI = ModifierKey::SHIFT.bits
| ModifierKey::GUI.bits;
const SHIFT_ALT_GUI = ModifierKey::SHIFT.bits
| ModifierKey::ALT.bits
| ModifierKey::GUI.bits;
const ALT_GUI = ModifierKey::ALT.bits
| ModifierKey::GUI.bits;
}
);
impl ModifierKey {
pub fn event<E: GenericEvent>(&mut self, e: &E) {
if let Some(button) = e.press_args() {
match button {
Button::Keyboard(Key::LCtrl) |
Button::Keyboard(Key::RCtrl) => self.insert(ModifierKey::CTRL),
Button::Keyboard(Key::LShift) |
Button::Keyboard(Key::RShift) => self.insert(ModifierKey::SHIFT),
Button::Keyboard(Key::LAlt) |
Button::Keyboard(Key::RAlt) => self.insert(ModifierKey::ALT),
Button::Keyboard(Key::LGui) |
Button::Keyboard(Key::RGui) => self.insert(ModifierKey::GUI),
_ => {}
}
}
if let Some(button) = e.release_args() {
match button {
Button::Keyboard(Key::LCtrl) |
Button::Keyboard(Key::RCtrl) => self.remove(ModifierKey::CTRL),
Button::Keyboard(Key::LShift) |
Button::Keyboard(Key::RShift) => self.remove(ModifierKey::SHIFT),
Button::Keyboard(Key::LAlt) |
Button::Keyboard(Key::RAlt) => self.remove(ModifierKey::ALT),
Button::Keyboard(Key::LGui) |
Button::Keyboard(Key::RGui) => self.remove(ModifierKey::GUI),
_ => {}
}
}
if let Some(false) = e.focus_args() {
*self = ModifierKey::NO_MODIFIER;
}
}
}
impl Default for ModifierKey {
fn default() -> ModifierKey {
ModifierKey::NO_MODIFIER
}
}
#[allow(missing_docs)]
#[derive(Copy, Clone, Deserialize, Serialize, Debug, Hash)]
pub enum Key {
Unknown = 0x00,
Backspace = 0x08,
Tab = 0x09,
Return = 0x0D,
Escape = 0x1B,
Space = 0x20,
Exclaim = 0x21,
Quotedbl = 0x22,
Hash = 0x23,
Dollar = 0x24,
Percent = 0x25,
Ampersand = 0x26,
Quote = 0x27,
LeftParen = 0x28,
RightParen = 0x29,
Asterisk = 0x2A,
Plus = 0x2B,
Comma = 0x2C,
Minus = 0x2D,
Period = 0x2E,
Slash = 0x2F,
D0 = 0x30,
D1 = 0x31,
D2 = 0x32,
D3 = 0x33,
D4 = 0x34,
D5 = 0x35,
D6 = 0x36,
D7 = 0x37,
D8 = 0x38,
D9 = 0x39,
Colon = 0x3A,
Semicolon = 0x3B,
Less = 0x3C,
Equals = 0x3D,
Greater = 0x3E,
Question = 0x3F,
At = 0x40,
LeftBracket = 0x5B,
Backslash = 0x5C,
RightBracket = 0x5D,
Caret = 0x5E,
Underscore = 0x5F,
Backquote = 0x60,
A = 0x61,
B = 0x62,
C = 0x63,
D = 0x64,
E = 0x65,
F = 0x66,
G = 0x67,
H = 0x68,
I = 0x69,
J = 0x6A,
K = 0x6B,
L = 0x6C,
M = 0x6D,
N = 0x6E,
O = 0x6F,
P = 0x70,
Q = 0x71,
R = 0x72,
S = 0x73,
T = 0x74,
U = 0x75,
V = 0x76,
W = 0x77,
X = 0x78,
Y = 0x79,
Z = 0x7A,
Delete = 0x7F,
CapsLock = 0x40000039,
F1 = 0x4000003A,
F2 = 0x4000003B,
F3 = 0x4000003C,
F4 = 0x4000003D,
F5 = 0x4000003E,
F6 = 0x4000003F,
F7 = 0x40000040,
F8 = 0x40000041,
F9 = 0x40000042,
F10 = 0x40000043,
F11 = 0x40000044,
F12 = 0x40000045,
PrintScreen = 0x40000046,
ScrollLock = 0x40000047,
Pause = 0x40000048,
Insert = 0x40000049,
Home = 0x4000004A,
PageUp = 0x4000004B,
End = 0x4000004D,
PageDown = 0x4000004E,
Right = 0x4000004F,
Left = 0x40000050,
Down = 0x40000051,
Up = 0x40000052,
NumLockClear = 0x40000053,
NumPadDivide = 0x40000054,
NumPadMultiply = 0x40000055,
NumPadMinus = 0x40000056,
NumPadPlus = 0x40000057,
NumPadEnter = 0x40000058,
NumPad1 = 0x40000059,
NumPad2 = 0x4000005A,
NumPad3 = 0x4000005B,
NumPad4 = 0x4000005C,
NumPad5 = 0x4000005D,
NumPad6 = 0x4000005E,
NumPad7 = 0x4000005F,
NumPad8 = 0x40000060,
NumPad9 = 0x40000061,
NumPad0 = 0x40000062,
NumPadPeriod = 0x40000063,
Application = 0x40000065,
Power = 0x40000066,
NumPadEquals = 0x40000067,
F13 = 0x40000068,
F14 = 0x40000069,
F15 = 0x4000006A,
F16 = 0x4000006B,
F17 = 0x4000006C,
F18 = 0x4000006D,
F19 = 0x4000006E,
F20 = 0x4000006F,
F21 = 0x40000070,
F22 = 0x40000071,
F23 = 0x40000072,
F24 = 0x40000073,
Execute = 0x40000074,
Help = 0x40000075,
Menu = 0x40000076,
Select = 0x40000077,
Stop = 0x40000078,
Again = 0x40000079,
Undo = 0x4000007A,
Cut = 0x4000007B,
Copy = 0x4000007C,
Paste = 0x4000007D,
Find = 0x4000007E,
Mute = 0x4000007F,
VolumeUp = 0x40000080,
VolumeDown = 0x40000081,
NumPadComma = 0x40000085,
NumPadEqualsAS400 = 0x40000086,
AltErase = 0x40000099,
Sysreq = 0x4000009A,
Cancel = 0x4000009B,
Clear = 0x4000009C,
Prior = 0x4000009D,
Return2 = 0x4000009E,
Separator = 0x4000009F,
Out = 0x400000A0,
Oper = 0x400000A1,
ClearAgain = 0x400000A2,
CrSel = 0x400000A3,
ExSel = 0x400000A4,
NumPad00 = 0x400000B0,
NumPad000 = 0x400000B1,
ThousandsSeparator = 0x400000B2,
DecimalSeparator = 0x400000B3,
CurrencyUnit = 0x400000B4,
CurrencySubUnit = 0x400000B5,
NumPadLeftParen = 0x400000B6,
NumPadRightParen = 0x400000B7,
NumPadLeftBrace = 0x400000B8,
NumPadRightBrace = 0x400000B9,
NumPadTab = 0x400000BA,
NumPadBackspace = 0x400000BB,
NumPadA = 0x400000BC,
NumPadB = 0x400000BD,
NumPadC = 0x400000BE,
NumPadD = 0x400000BF,
NumPadE = 0x400000C0,
NumPadF = 0x400000C1,
NumPadXor = 0x400000C2,
NumPadPower = 0x400000C3,
NumPadPercent = 0x400000C4,
NumPadLess = 0x400000C5,
NumPadGreater = 0x400000C6,
NumPadAmpersand = 0x400000C7,
NumPadDblAmpersand = 0x400000C8,
NumPadVerticalBar = 0x400000C9,
NumPadDblVerticalBar = 0x400000CA,
NumPadColon = 0x400000CB,
NumPadHash = 0x400000CC,
NumPadSpace = 0x400000CD,
NumPadAt = 0x400000CE,
NumPadExclam = 0x400000CF,
NumPadMemStore = 0x400000D0,
NumPadMemRecall = 0x400000D1,
NumPadMemClear = 0x400000D2,
NumPadMemAdd = 0x400000D3,
NumPadMemSubtract = 0x400000D4,
NumPadMemMultiply = 0x400000D5,
NumPadMemDivide = 0x400000D6,
NumPadPlusMinus = 0x400000D7,
NumPadClear = 0x400000D8,
NumPadClearEntry = 0x400000D9,
NumPadBinary = 0x400000DA,
NumPadOctal = 0x400000DB,
NumPadDecimal = 0x400000DC,
NumPadHexadecimal = 0x400000DD,
LCtrl = 0x400000E0,
LShift = 0x400000E1,
LAlt = 0x400000E2,
LGui = 0x400000E3,
RCtrl = 0x400000E4,
RShift = 0x400000E5,
RAlt = 0x400000E6,
RGui = 0x400000E7,
Mode = 0x40000101,
AudioNext = 0x40000102,
AudioPrev = 0x40000103,
AudioStop = 0x40000104,
AudioPlay = 0x40000105,
AudioMute = 0x40000106,
MediaSelect = 0x40000107,
Www = 0x40000108,
Mail = 0x40000109,
Calculator = 0x4000010A,
Computer = 0x4000010B,
AcSearch = 0x4000010C,
AcHome = 0x4000010D,
AcBack = 0x4000010E,
AcForward = 0x4000010F,
AcStop = 0x40000110,
AcRefresh = 0x40000111,
AcBookmarks = 0x40000112,
BrightnessDown = 0x40000113,
BrightnessUp = 0x40000114,
DisplaySwitch = 0x40000115,
KbdIllumToggle = 0x40000116,
KbdIllumDown = 0x40000117,
KbdIllumUp = 0x40000118,
Eject = 0x40000119,
Sleep = 0x4000011A,
}
impl From<u32> for Key {
fn from(val: u32) -> Key {
match val {
0x00 => Key::Unknown,
0x08 => Key::Backspace,
0x09 => Key::Tab,
0x0D => Key::Return,
0x1B => Key::Escape,
0x20 => Key::Space,
0x21 => Key::Exclaim,
0x22 => Key::Quotedbl,
0x23 => Key::Hash,
0x24 => Key::Dollar,
0x25 => Key::Percent,
0x26 => Key::Ampersand,
0x27 => Key::Quote,
0x28 => Key::LeftParen,
0x29 => Key::RightParen,
0x2A => Key::Asterisk,
0x2B => Key::Plus,
0x2C => Key::Comma,
0x2D => Key::Minus,
0x2E => Key::Period,
0x2F => Key::Slash,
0x30 => Key::D0,
0x31 => Key::D1,
0x32 => Key::D2,
0x33 => Key::D3,
0x34 => Key::D4,
0x35 => Key::D5,
0x36 => Key::D6,
0x37 => Key::D7,
0x38 => Key::D8,
0x39 => Key::D9,
0x3A => Key::Colon,
0x3B => Key::Semicolon,
0x3C => Key::Less,
0x3D => Key::Equals,
0x3E => Key::Greater,
0x3F => Key::Question,
0x40 => Key::At,
0x5B => Key::LeftBracket,
0x5C => Key::Backslash,
0x5D => Key::RightBracket,
0x5E => Key::Caret,
0x5F => Key::Underscore,
0x60 => Key::Backquote,
0x61 => Key::A,
0x62 => Key::B,
0x63 => Key::C,
0x64 => Key::D,
0x65 => Key::E,
0x66 => Key::F,
0x67 => Key::G,
0x68 => Key::H,
0x69 => Key::I,
0x6A => Key::J,
0x6B => Key::K,
0x6C => Key::L,
0x6D => Key::M,
0x6E => Key::N,
0x6F => Key::O,
0x70 => Key::P,
0x71 => Key::Q,
0x72 => Key::R,
0x73 => Key::S,
0x74 => Key::T,
0x75 => Key::U,
0x76 => Key::V,
0x77 => Key::W,
0x78 => Key::X,
0x79 => Key::Y,
0x7A => Key::Z,
0x7F => Key::Delete,
0x40000039 => Key::CapsLock,
0x4000003A => Key::F1,
0x4000003B => Key::F2,
0x4000003C => Key::F3,
0x4000003D => Key::F4,
0x4000003E => Key::F5,
0x4000003F => Key::F6,
0x40000040 => Key::F7,
0x40000041 => Key::F8,
0x40000042 => Key::F9,
0x40000043 => Key::F10,
0x40000044 => Key::F11,
0x40000045 => Key::F12,
0x40000046 => Key::PrintScreen,
0x40000047 => Key::ScrollLock,
0x40000048 => Key::Pause,
0x40000049 => Key::Insert,
0x4000004A => Key::Home,
0x4000004B => Key::PageUp,
0x4000004D => Key::End,
0x4000004E => Key::PageDown,
0x4000004F => Key::Right,
0x40000050 => Key::Left,
0x40000051 => Key::Down,
0x40000052 => Key::Up,
0x40000053 => Key::NumLockClear,
0x40000054 => Key::NumPadDivide,
0x40000055 => Key::NumPadMultiply,
0x40000056 => Key::NumPadMinus,
0x40000057 => Key::NumPadPlus,
0x40000058 => Key::NumPadEnter,
0x40000059 => Key::NumPad1,
0x4000005A => Key::NumPad2,
0x4000005B => Key::NumPad3,
0x4000005C => Key::NumPad4,
0x4000005D => Key::NumPad5,
0x4000005E => Key::NumPad6,
0x4000005F => Key::NumPad7,
0x40000060 => Key::NumPad8,
0x40000061 => Key::NumPad9,
0x40000062 => Key::NumPad0,
0x40000063 => Key::NumPadPeriod,
0x40000065 => Key::Application,
0x40000066 => Key::Power,
0x40000067 => Key::NumPadEquals,
0x40000068 => Key::F13,
0x40000069 => Key::F14,
0x4000006A => Key::F15,
0x4000006B => Key::F16,
0x4000006C => Key::F17,
0x4000006D => Key::F18,
0x4000006E => Key::F19,
0x4000006F => Key::F20,
0x40000070 => Key::F21,
0x40000071 => Key::F22,
0x40000072 => Key::F23,
0x40000073 => Key::F24,
0x40000074 => Key::Execute,
0x40000075 => Key::Help,
0x40000076 => Key::Menu,
0x40000077 => Key::Select,
0x40000078 => Key::Stop,
0x40000079 => Key::Again,
0x4000007A => Key::Undo,
0x4000007B => Key::Cut,
0x4000007C => Key::Copy,
0x4000007D => Key::Paste,
0x4000007E => Key::Find,
0x4000007F => Key::Mute,
0x40000080 => Key::VolumeUp,
0x40000081 => Key::VolumeDown,
0x40000085 => Key::NumPadComma,
0x40000086 => Key::NumPadEqualsAS400,
0x40000099 => Key::AltErase,
0x4000009A => Key::Sysreq,
0x4000009B => Key::Cancel,
0x4000009C => Key::Clear,
0x4000009D => Key::Prior,
0x4000009E => Key::Return2,
0x4000009F => Key::Separator,
0x400000A0 => Key::Out,
0x400000A1 => Key::Oper,
0x400000A2 => Key::ClearAgain,
0x400000A3 => Key::CrSel,
0x400000A4 => Key::ExSel,
0x400000B0 => Key::NumPad00,
0x400000B1 => Key::NumPad000,
0x400000B2 => Key::ThousandsSeparator,
0x400000B3 => Key::DecimalSeparator,
0x400000B4 => Key::CurrencyUnit,
0x400000B5 => Key::CurrencySubUnit,
0x400000B6 => Key::NumPadLeftParen,
0x400000B7 => Key::NumPadRightParen,
0x400000B8 => Key::NumPadLeftBrace,
0x400000B9 => Key::NumPadRightBrace,
0x400000BA => Key::NumPadTab,
0x400000BB => Key::NumPadBackspace,
0x400000BC => Key::NumPadA,
0x400000BD => Key::NumPadB,
0x400000BE => Key::NumPadC,
0x400000BF => Key::NumPadD,
0x400000C0 => Key::NumPadE,
0x400000C1 => Key::NumPadF,
0x400000C2 => Key::NumPadXor,
0x400000C3 => Key::NumPadPower,
0x400000C4 => Key::NumPadPercent,
0x400000C5 => Key::NumPadLess,
0x400000C6 => Key::NumPadGreater,
0x400000C7 => Key::NumPadAmpersand,
0x400000C8 => Key::NumPadDblAmpersand,
0x400000C9 => Key::NumPadVerticalBar,
0x400000CA => Key::NumPadDblVerticalBar,
0x400000CB => Key::NumPadColon,
0x400000CC => Key::NumPadHash,
0x400000CD => Key::NumPadSpace,
0x400000CE => Key::NumPadAt,
0x400000CF => Key::NumPadExclam,
0x400000D0 => Key::NumPadMemStore,
0x400000D1 => Key::NumPadMemRecall,
0x400000D2 => Key::NumPadMemClear,
0x400000D3 => Key::NumPadMemAdd,
0x400000D4 => Key::NumPadMemSubtract,
0x400000D5 => Key::NumPadMemMultiply,
0x400000D6 => Key::NumPadMemDivide,
0x400000D7 => Key::NumPadPlusMinus,
0x400000D8 => Key::NumPadClear,
0x400000D9 => Key::NumPadClearEntry,
0x400000DA => Key::NumPadBinary,
0x400000DB => Key::NumPadOctal,
0x400000DC => Key::NumPadDecimal,
0x400000DD => Key::NumPadHexadecimal,
0x400000E0 => Key::LCtrl,
0x400000E1 => Key::LShift,
0x400000E2 => Key::LAlt,
0x400000E3 => Key::LGui,
0x400000E4 => Key::RCtrl,
0x400000E5 => Key::RShift,
0x400000E6 => Key::RAlt,
0x400000E7 => Key::RGui,
0x40000101 => Key::Mode,
0x40000102 => Key::AudioNext,
0x40000103 => Key::AudioPrev,
0x40000104 => Key::AudioStop,
0x40000105 => Key::AudioPlay,
0x40000106 => Key::AudioMute,
0x40000107 => Key::MediaSelect,
0x40000108 => Key::Www,
0x40000109 => Key::Mail,
0x4000010A => Key::Calculator,
0x4000010B => Key::Computer,
0x4000010C => Key::AcSearch,
0x4000010D => Key::AcHome,
0x4000010E => Key::AcBack,
0x4000010F => Key::AcForward,
0x40000110 => Key::AcStop,
0x40000111 => Key::AcRefresh,
0x40000112 => Key::AcBookmarks,
0x40000113 => Key::BrightnessDown,
0x40000114 => Key::BrightnessUp,
0x40000115 => Key::DisplaySwitch,
0x40000116 => Key::KbdIllumToggle,
0x40000117 => Key::KbdIllumDown,
0x40000118 => Key::KbdIllumUp,
0x40000119 => Key::Eject,
0x4000011A => Key::Sleep,
_ => Key::Unknown,
}
}
}
impl PartialEq for Key {
fn eq(&self, other: &Key) -> bool {
return (*self as i32) == (*other as i32);
}
}
impl Eq for Key {}
impl PartialOrd for Key {
fn partial_cmp(&self, other: &Key) -> Option<Ordering> {
let (s_id, o_id) = (*self as i32, *other as i32);
s_id.partial_cmp(&o_id)
}
}
impl Ord for Key {
fn cmp(&self, other: &Key) -> Ordering {
let (s_id, o_id) = (*self as i32, *other as i32);
s_id.cmp(&o_id)
}
}
impl Key {
#[inline(always)]
pub fn code(&self) -> i32 {
*self as i32
}
}
impl From<Key> for u32 {
#[inline(always)]
fn from(key: Key) -> u32 {
key as u32
}
}
#[cfg(test)]
mod tests {
#[test]
fn keycode() {
use super::Key;
use super::Key::*;
let keys = vec![Unknown,
Backspace,
Tab,
Return,
Escape,
Space,
Exclaim,
Quotedbl,
Hash,
Dollar,
Percent,
Ampersand,
Quote,
LeftParen,
RightParen,
Asterisk,
Plus,
Comma,
Minus,
Period,
Slash,
D0,
D1,
D2,
D3,
D4,
D5,
D6,
D7,
D8,
D9,
Colon,
Semicolon,
Less,
Equals,
Greater,
Question,
At,
LeftBracket,
Backslash,
RightBracket,
Caret,
Underscore,
Backquote,
A,
B,
C,
D,
E,
F,
G,
H,
I,
J,
K,
L,
M,
N,
O,
P,
Q,
R,
S,
T,
U,
V,
W,
X,
Y,
Z,
Delete,
CapsLock,
F1,
F2,
F3,
F4,
F5,
F6,
F7,
F8,
F9,
F10,
F11,
F12,
PrintScreen,
ScrollLock,
Pause,
Insert,
Home,
PageUp,
End,
PageDown,
Right,
Left,
Down,
Up,
NumLockClear,
NumPadDivide,
NumPadMultiply,
NumPadMinus,
NumPadPlus,
NumPadEnter,
NumPad1,
NumPad2,
NumPad3,
NumPad4,
NumPad5,
NumPad6,
NumPad7,
NumPad8,
NumPad9,
NumPad0,
NumPadPeriod,
Application,
Power,
NumPadEquals,
F13,
F14,
F15,
F16,
F17,
F18,
F19,
F20,
F21,
F22,
F23,
F24,
Execute,
Help,
Menu,
Select,
Stop,
Again,
Undo,
Cut,
Copy,
Paste,
Find,
Mute,
VolumeUp,
VolumeDown,
NumPadComma,
NumPadEqualsAS400,
AltErase,
Sysreq,
Cancel,
Clear,
Prior,
Return2,
Separator,
Out,
Oper,
ClearAgain,
CrSel,
ExSel,
NumPad00,
NumPad000,
ThousandsSeparator,
DecimalSeparator,
CurrencyUnit,
CurrencySubUnit,
NumPadLeftParen,
NumPadRightParen,
NumPadLeftBrace,
NumPadRightBrace,
NumPadTab,
NumPadBackspace,
NumPadA,
NumPadB,
NumPadC,
NumPadD,
NumPadE,
NumPadF,
NumPadXor,
NumPadPower,
NumPadPercent,
NumPadLess,
NumPadGreater,
NumPadAmpersand,
NumPadDblAmpersand,
NumPadVerticalBar,
NumPadDblVerticalBar,
NumPadColon,
NumPadHash,
NumPadSpace,
NumPadAt,
NumPadExclam,
NumPadMemStore,
NumPadMemRecall,
NumPadMemClear,
NumPadMemAdd,
NumPadMemSubtract,
NumPadMemMultiply,
NumPadMemDivide,
NumPadPlusMinus,
NumPadClear,
NumPadClearEntry,
NumPadBinary,
NumPadOctal,
NumPadDecimal,
NumPadHexadecimal,
LCtrl,
LShift,
LAlt,
LGui,
RCtrl,
RShift,
RAlt,
RGui,
Mode,
AudioNext,
AudioPrev,
AudioStop,
AudioPlay,
AudioMute,
MediaSelect,
Www,
Mail,
Calculator,
Computer,
AcSearch,
AcHome,
AcBack,
AcForward,
AcStop,
AcRefresh,
AcBookmarks,
BrightnessDown,
BrightnessUp,
DisplaySwitch,
KbdIllumToggle,
KbdIllumDown,
KbdIllumUp,
Eject,
Sleep];
for &key in &keys {
let val: u32 = key.into();
let key2: Key = val.into();
assert_eq!(key, key2);
}
}
}