use std::fmt;
pub use cranpose_foundation::Modifiers;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum KeyEventType {
KeyDown,
KeyUp,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum KeyCode {
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,
Digit0,
Digit1,
Digit2,
Digit3,
Digit4,
Digit5,
Digit6,
Digit7,
Digit8,
Digit9,
F1,
F2,
F3,
F4,
F5,
F6,
F7,
F8,
F9,
F10,
F11,
F12,
ArrowUp,
ArrowDown,
ArrowLeft,
ArrowRight,
Home,
End,
PageUp,
PageDown,
Backspace,
Delete,
Enter,
Tab,
Space,
Escape,
ShiftLeft,
ShiftRight,
ControlLeft,
ControlRight,
AltLeft,
AltRight,
MetaLeft,
MetaRight,
Minus,
Equal,
BracketLeft,
BracketRight,
Backslash,
Semicolon,
Quote,
Comma,
Period,
Slash,
Backquote,
Unknown,
}
const DOM_KEY_CODES: [(&str, KeyCode); 82] = [
("KeyA", KeyCode::A),
("KeyB", KeyCode::B),
("KeyC", KeyCode::C),
("KeyD", KeyCode::D),
("KeyE", KeyCode::E),
("KeyF", KeyCode::F),
("KeyG", KeyCode::G),
("KeyH", KeyCode::H),
("KeyI", KeyCode::I),
("KeyJ", KeyCode::J),
("KeyK", KeyCode::K),
("KeyL", KeyCode::L),
("KeyM", KeyCode::M),
("KeyN", KeyCode::N),
("KeyO", KeyCode::O),
("KeyP", KeyCode::P),
("KeyQ", KeyCode::Q),
("KeyR", KeyCode::R),
("KeyS", KeyCode::S),
("KeyT", KeyCode::T),
("KeyU", KeyCode::U),
("KeyV", KeyCode::V),
("KeyW", KeyCode::W),
("KeyX", KeyCode::X),
("KeyY", KeyCode::Y),
("KeyZ", KeyCode::Z),
("Digit0", KeyCode::Digit0),
("Digit1", KeyCode::Digit1),
("Digit2", KeyCode::Digit2),
("Digit3", KeyCode::Digit3),
("Digit4", KeyCode::Digit4),
("Digit5", KeyCode::Digit5),
("Digit6", KeyCode::Digit6),
("Digit7", KeyCode::Digit7),
("Digit8", KeyCode::Digit8),
("Digit9", KeyCode::Digit9),
("F1", KeyCode::F1),
("F2", KeyCode::F2),
("F3", KeyCode::F3),
("F4", KeyCode::F4),
("F5", KeyCode::F5),
("F6", KeyCode::F6),
("F7", KeyCode::F7),
("F8", KeyCode::F8),
("F9", KeyCode::F9),
("F10", KeyCode::F10),
("F11", KeyCode::F11),
("F12", KeyCode::F12),
("ArrowUp", KeyCode::ArrowUp),
("ArrowDown", KeyCode::ArrowDown),
("ArrowLeft", KeyCode::ArrowLeft),
("ArrowRight", KeyCode::ArrowRight),
("Home", KeyCode::Home),
("End", KeyCode::End),
("PageUp", KeyCode::PageUp),
("PageDown", KeyCode::PageDown),
("Backspace", KeyCode::Backspace),
("Delete", KeyCode::Delete),
("Enter", KeyCode::Enter),
("NumpadEnter", KeyCode::Enter),
("Tab", KeyCode::Tab),
("Space", KeyCode::Space),
("Escape", KeyCode::Escape),
("ShiftLeft", KeyCode::ShiftLeft),
("ShiftRight", KeyCode::ShiftRight),
("ControlLeft", KeyCode::ControlLeft),
("ControlRight", KeyCode::ControlRight),
("AltLeft", KeyCode::AltLeft),
("AltRight", KeyCode::AltRight),
("MetaLeft", KeyCode::MetaLeft),
("MetaRight", KeyCode::MetaRight),
("Minus", KeyCode::Minus),
("Equal", KeyCode::Equal),
("BracketLeft", KeyCode::BracketLeft),
("BracketRight", KeyCode::BracketRight),
("Backslash", KeyCode::Backslash),
("Semicolon", KeyCode::Semicolon),
("Quote", KeyCode::Quote),
("Comma", KeyCode::Comma),
("Period", KeyCode::Period),
("Slash", KeyCode::Slash),
("Backquote", KeyCode::Backquote),
];
impl KeyCode {
pub fn from_dom_code(code: &str) -> Self {
DOM_KEY_CODES
.iter()
.find(|(name, _)| *name == code)
.map_or(Self::Unknown, |(_, key)| *key)
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct KeyEvent {
pub key_code: KeyCode,
pub text: String,
pub modifiers: Modifiers,
pub event_type: KeyEventType,
}
impl KeyEvent {
pub fn new(
key_code: KeyCode,
text: impl Into<String>,
modifiers: Modifiers,
event_type: KeyEventType,
) -> Self {
Self {
key_code,
text: text.into(),
modifiers,
event_type,
}
}
pub fn key_down(key_code: KeyCode, text: impl Into<String>) -> Self {
Self::new(key_code, text, Modifiers::NONE, KeyEventType::KeyDown)
}
pub fn key_down_with_modifiers(
key_code: KeyCode,
text: impl Into<String>,
modifiers: Modifiers,
) -> Self {
Self::new(key_code, text, modifiers, KeyEventType::KeyDown)
}
pub fn is_key_down(&self) -> bool {
self.event_type == KeyEventType::KeyDown
}
pub fn has_text(&self) -> bool {
!self.text.is_empty()
}
}
impl fmt::Display for KeyEvent {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
"KeyEvent({:?}, text=\"{}\", {:?})",
self.key_code, self.text, self.event_type
)
}
}
#[cfg(test)]
#[path = "tests/key_event_tests.rs"]
mod tests;