use super::event::Event;
#[derive(Debug, Clone, Default)]
pub struct Key {
pub up_arrow: bool,
pub down_arrow: bool,
pub left_arrow: bool,
pub right_arrow: bool,
pub page_down: bool,
pub page_up: bool,
pub wheel_up: bool,
pub wheel_down: bool,
pub home: bool,
pub end: bool,
pub return_key: bool,
pub escape: bool,
pub ctrl: bool,
pub shift: bool,
pub fn_key: bool,
pub tab: bool,
pub backspace: bool,
pub delete: bool,
pub meta: bool,
pub super_key: bool,
}
impl Key {
pub fn new() -> Self {
Self::default()
}
pub fn is_navigation(&self) -> bool {
self.up_arrow
|| self.down_arrow
|| self.left_arrow
|| self.right_arrow
|| self.page_down
|| self.page_up
|| self.home
|| self.end
}
pub fn has_modifier(&self) -> bool {
self.ctrl || self.shift || self.meta || self.super_key
}
}
#[derive(Debug, Clone)]
pub struct InputEvent {
pub keypress: ParsedKey,
pub key: Key,
pub input: String,
base: Event,
}
impl InputEvent {
pub fn new(keypress: ParsedKey) -> Self {
let key = parse_key(&keypress);
let input = compute_input(&keypress);
Self {
keypress,
key,
input,
base: Event::new(),
}
}
pub fn did_stop_immediate_propagation(&self) -> bool {
self.base.did_stop_immediate_propagation()
}
pub fn stop_immediate_propagation(&self) {
self.base.stop_immediate_propagation();
}
}
#[derive(Debug, Clone)]
pub struct ParsedKey {
pub kind: &'static str,
pub name: Option<String>,
pub fn_key: bool,
pub ctrl: bool,
pub meta: bool,
pub shift: bool,
pub option: bool,
pub super_key: bool,
pub sequence: Option<String>,
pub raw: Option<String>,
pub code: Option<String>,
pub is_pasted: bool,
}
impl ParsedKey {
pub fn new() -> Self {
Self {
kind: "key",
name: None,
fn_key: false,
ctrl: false,
meta: false,
shift: false,
option: false,
super_key: false,
sequence: None,
raw: None,
code: None,
is_pasted: false,
}
}
}
impl Default for ParsedKey {
fn default() -> Self {
Self::new()
}
}
const NON_ALPHANUMERIC_KEYS: &[&str] = &[
"f1",
"f2",
"f3",
"f4",
"f5",
"f6",
"f7",
"f8",
"f9",
"f10",
"f11",
"f12",
"up",
"down",
"left",
"right",
"clear",
"end",
"home",
"insert",
"delete",
"pageup",
"pagedown",
"escape",
"backspace",
"wheelup",
"wheeldown",
"mouse",
];
fn parse_key(keypress: &ParsedKey) -> Key {
let mut key = Key::new();
if let Some(ref name) = keypress.name {
key.up_arrow = name == "up";
key.down_arrow = name == "down";
key.left_arrow = name == "left";
key.right_arrow = name == "right";
key.page_down = name == "pagedown";
key.page_up = name == "pageup";
key.wheel_up = name == "wheelup";
key.wheel_down = name == "wheeldown";
key.home = name == "home";
key.end = name == "end";
key.return_key = name == "return";
key.escape = name == "escape";
key.fn_key = keypress.fn_key;
key.ctrl = keypress.ctrl;
key.shift = keypress.shift;
key.tab = name == "tab";
key.backspace = name == "backspace";
key.delete = name == "delete";
key.meta = keypress.meta || name == "escape" || keypress.option;
key.super_key = keypress.super_key;
}
key
}
fn compute_input(keypress: &ParsedKey) -> String {
if keypress.ctrl {
if let Some(ref name) = keypress.name {
if name == "space" {
return " ".to_string();
}
if name.len() == 1 {
let c = name.chars().next().unwrap();
if c.is_ascii_lowercase() {
return ((c as u8 - b'a' + 1) as char).to_string();
}
}
}
}
if let Some(ref seq) = keypress.sequence {
if seq.starts_with('\u{1b}') {
return seq[1..].to_string();
}
return seq.clone();
}
String::new()
}