use serde::{Deserialize, Serialize};
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct KeyCombo {
pub modifiers: u8,
pub key_code: u16,
#[serde(default)]
pub display: String,
}
impl KeyCombo {
pub const MOD_CMD: u8 = 1 << 0;
pub const MOD_SHIFT: u8 = 1 << 1;
pub const MOD_CTRL: u8 = 1 << 2;
pub const MOD_OPTION: u8 = 1 << 3;
#[must_use]
pub fn rendered_label(&self) -> String {
if !self.display.is_empty() {
return self.display.clone();
}
let mut out = String::new();
if self.modifiers & Self::MOD_CTRL != 0 {
out.push('⌃');
}
if self.modifiers & Self::MOD_OPTION != 0 {
out.push('⌥');
}
if self.modifiers & Self::MOD_SHIFT != 0 {
out.push('⇧');
}
if self.modifiers & Self::MOD_CMD != 0 {
out.push('⌘');
}
match self.key_code {
0x00 => out.push('A'),
0x01 => out.push('S'),
0x02 => out.push('D'),
0x03 => out.push('F'),
0x06 => out.push('Z'),
0x07 => out.push('X'),
0x08 => out.push('C'),
0x09 => out.push('V'),
0x0B => out.push('B'),
0x0C => out.push('Q'),
0x0D => out.push('W'),
0x0E => out.push('E'),
0x0F => out.push('R'),
0x10 => out.push('Y'),
0x11 => out.push('T'),
0x20 => out.push('U'),
0x22 => out.push('I'),
0x1F => out.push('O'),
0x23 => out.push('P'),
_ => {
use std::fmt::Write as _;
let _ = write!(out, "key 0x{:02X}", self.key_code);
}
}
out
}
}