use crate::keycode::Keycode;
use crate::localizer::Platform;
use crate::named_key::NamedKey;
use crate::scancode::Scancode;
#[derive(Copy, Clone, Debug)]
pub struct LayoutKey {
pub scancode: Scancode,
pub base: Option<char>,
pub shift: Option<char>,
pub altgr: Option<char>,
pub shift_altgr: Option<char>,
pub named: Option<NamedKey>,
}
impl LayoutKey {
pub const fn named(sc: Scancode, nk: NamedKey) -> Self {
Self {
scancode: sc,
base: None,
shift: None,
altgr: None,
shift_altgr: None,
named: Some(nk),
}
}
pub const fn printable(sc: Scancode, base: char, shift: char) -> Self {
Self {
scancode: sc,
base: Some(base),
shift: Some(shift),
altgr: None,
shift_altgr: None,
named: None,
}
}
pub const fn printable4(
sc: Scancode,
base: char,
shift: char,
altgr: char,
shift_altgr: char,
) -> Self {
Self {
scancode: sc,
base: Some(base),
shift: Some(shift),
altgr: Some(altgr),
shift_altgr: Some(shift_altgr),
named: None,
}
}
}
#[derive(Copy, Clone, Debug)]
pub struct Layout {
pub id: &'static str,
pub display_name: &'static str,
pub platform: Platform,
pub language: &'static str,
pub named_keys: &'static [LayoutKey],
pub printable_keys: &'static [LayoutKey],
}
impl Layout {
pub fn key(&self, sc: Scancode) -> Option<&'static LayoutKey> {
self.printable_keys
.iter()
.find(|k| k.scancode == sc)
.or_else(|| self.named_keys.iter().find(|k| k.scancode == sc))
}
}
pub const STD_NAMED_KEYS: &[LayoutKey] = &[
LayoutKey::named(Scancode::ESCAPE, NamedKey::Escape),
LayoutKey::named(Scancode::RETURN, NamedKey::Return),
LayoutKey::named(Scancode::BACKSPACE, NamedKey::Backspace),
LayoutKey::named(Scancode::TAB, NamedKey::Tab),
LayoutKey::named(Scancode::CAPSLOCK, NamedKey::CapsLock),
LayoutKey::named(Scancode::F1, NamedKey::F1),
LayoutKey::named(Scancode::F2, NamedKey::F2),
LayoutKey::named(Scancode::F3, NamedKey::F3),
LayoutKey::named(Scancode::F4, NamedKey::F4),
LayoutKey::named(Scancode::F5, NamedKey::F5),
LayoutKey::named(Scancode::F6, NamedKey::F6),
LayoutKey::named(Scancode::F7, NamedKey::F7),
LayoutKey::named(Scancode::F8, NamedKey::F8),
LayoutKey::named(Scancode::F9, NamedKey::F9),
LayoutKey::named(Scancode::F10, NamedKey::F10),
LayoutKey::named(Scancode::F11, NamedKey::F11),
LayoutKey::named(Scancode::F12, NamedKey::F12),
LayoutKey::named(Scancode::F13, NamedKey::F13),
LayoutKey::named(Scancode::F14, NamedKey::F14),
LayoutKey::named(Scancode::F15, NamedKey::F15),
LayoutKey::named(Scancode::F16, NamedKey::F16),
LayoutKey::named(Scancode::F17, NamedKey::F17),
LayoutKey::named(Scancode::F18, NamedKey::F18),
LayoutKey::named(Scancode::F19, NamedKey::F19),
LayoutKey::named(Scancode::F20, NamedKey::F20),
LayoutKey::named(Scancode::F21, NamedKey::F21),
LayoutKey::named(Scancode::F22, NamedKey::F22),
LayoutKey::named(Scancode::F23, NamedKey::F23),
LayoutKey::named(Scancode::F24, NamedKey::F24),
LayoutKey::named(Scancode::PRINT_SCREEN, NamedKey::PrintScreen),
LayoutKey::named(Scancode::SCROLL_LOCK, NamedKey::ScrollLock),
LayoutKey::named(Scancode::PAUSE, NamedKey::Pause),
LayoutKey::named(Scancode::INSERT, NamedKey::Insert),
LayoutKey::named(Scancode::HOME, NamedKey::Home),
LayoutKey::named(Scancode::PAGE_UP, NamedKey::PageUp),
LayoutKey::named(Scancode::DELETE, NamedKey::Delete),
LayoutKey::named(Scancode::END, NamedKey::End),
LayoutKey::named(Scancode::PAGE_DOWN, NamedKey::PageDown),
LayoutKey::named(Scancode::RIGHT, NamedKey::ArrowRight),
LayoutKey::named(Scancode::LEFT, NamedKey::ArrowLeft),
LayoutKey::named(Scancode::DOWN, NamedKey::ArrowDown),
LayoutKey::named(Scancode::UP, NamedKey::ArrowUp),
LayoutKey::named(Scancode::NUM_LOCK_CLEAR, NamedKey::NumLock),
LayoutKey::named(Scancode::KP_DIVIDE, NamedKey::KeypadDivide),
LayoutKey::named(Scancode::KP_MULTIPLY, NamedKey::KeypadMultiply),
LayoutKey::named(Scancode::KP_MINUS, NamedKey::KeypadMinus),
LayoutKey::named(Scancode::KP_PLUS, NamedKey::KeypadPlus),
LayoutKey::named(Scancode::KP_ENTER, NamedKey::KeypadEnter),
LayoutKey::named(Scancode::KP_1, NamedKey::Keypad1),
LayoutKey::named(Scancode::KP_2, NamedKey::Keypad2),
LayoutKey::named(Scancode::KP_3, NamedKey::Keypad3),
LayoutKey::named(Scancode::KP_4, NamedKey::Keypad4),
LayoutKey::named(Scancode::KP_5, NamedKey::Keypad5),
LayoutKey::named(Scancode::KP_6, NamedKey::Keypad6),
LayoutKey::named(Scancode::KP_7, NamedKey::Keypad7),
LayoutKey::named(Scancode::KP_8, NamedKey::Keypad8),
LayoutKey::named(Scancode::KP_9, NamedKey::Keypad9),
LayoutKey::named(Scancode::KP_0, NamedKey::Keypad0),
LayoutKey::named(Scancode::KP_PERIOD, NamedKey::KeypadPeriod),
LayoutKey::named(Scancode::KP_EQUALS, NamedKey::KeypadEquals),
LayoutKey::named(Scancode::APPLICATION, NamedKey::Application),
LayoutKey::named(Scancode::MENU, NamedKey::Menu),
LayoutKey::named(Scancode::SPACE, NamedKey::Space),
LayoutKey::named(Scancode::LCTRL, NamedKey::ControlLeft),
LayoutKey::named(Scancode::LSHIFT, NamedKey::ShiftLeft),
LayoutKey::named(Scancode::LALT, NamedKey::AltLeft),
LayoutKey::named(Scancode::LGUI, NamedKey::GuiLeft),
LayoutKey::named(Scancode::RCTRL, NamedKey::ControlRight),
LayoutKey::named(Scancode::RSHIFT, NamedKey::ShiftRight),
LayoutKey::named(Scancode::RALT, NamedKey::AltRight),
LayoutKey::named(Scancode::RGUI, NamedKey::GuiRight),
];
include!(concat!(env!("OUT_DIR"), "/cldr_layouts.rs"));
pub fn get_layout(id: &str) -> Option<&'static Layout> {
CLDR_LAYOUTS
.iter()
.find(|l| l.id == id)
.or_else(|| CLDR3_LAYOUTS.iter().find(|l| l.id == id))
.copied()
}
pub fn all_layouts() -> &'static [&'static Layout] {
use std::sync::OnceLock;
static COMBINED: OnceLock<Vec<&'static Layout>> = OnceLock::new();
COMBINED
.get_or_init(|| {
let mut v: Vec<&'static Layout> = CLDR_LAYOUTS.to_vec();
v.extend(CLDR3_LAYOUTS.iter().copied());
v
})
.as_slice()
}
pub(crate) fn layout_key_base_keycode(k: &LayoutKey) -> Keycode {
if let Some(nk) = k.named {
named_key_keycode(nk)
} else if let Some(c) = k.base {
Keycode::from(c)
} else {
Keycode::UNKNOWN
}
}
pub(crate) fn named_key_keycode(nk: NamedKey) -> Keycode {
use NamedKey::*;
match nk {
Escape => Keycode::ESCAPE,
Return => Keycode::RETURN,
Tab => Keycode::TAB,
Space => Keycode::SPACE,
Backspace => Keycode::BACKSPACE,
Insert => Keycode::INSERT,
Delete => Keycode::DELETE,
Home => Keycode::HOME,
End => Keycode::END,
PageUp => Keycode::PAGE_UP,
PageDown => Keycode::PAGE_DOWN,
ArrowUp => Keycode::UP,
ArrowDown => Keycode::DOWN,
ArrowLeft => Keycode::LEFT,
ArrowRight => Keycode::RIGHT,
CapsLock => Keycode::CAPSLOCK,
NumLock => Keycode::NUM_LOCK_CLEAR,
ScrollLock => Keycode::SCROLL_LOCK,
PrintScreen => Keycode::PRINT_SCREEN,
Pause => Keycode::PAUSE,
Menu => Keycode::MENU,
Application => Keycode::APPLICATION,
ShiftLeft => Keycode::LSHIFT,
ShiftRight => Keycode::RSHIFT,
ControlLeft => Keycode::LCTRL,
ControlRight => Keycode::RCTRL,
AltLeft => Keycode::LALT,
AltRight => Keycode::RALT,
AltGr => Keycode::RALT,
GuiLeft => Keycode::LGUI,
GuiRight => Keycode::RGUI,
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,
F13 => Keycode::F13,
F14 => Keycode::F14,
F15 => Keycode::F15,
F16 => Keycode::F16,
F17 => Keycode::F17,
F18 => Keycode::F18,
F19 => Keycode::F19,
F20 => Keycode::F20,
F21 => Keycode::F21,
F22 => Keycode::F22,
F23 => Keycode::F23,
F24 => Keycode::F24,
KeypadEnter => Keycode::KP_ENTER,
KeypadDivide => Keycode::KP_DIVIDE,
KeypadMultiply => Keycode::KP_MULTIPLY,
KeypadMinus => Keycode::KP_MINUS,
KeypadPlus => Keycode::KP_PLUS,
KeypadPeriod => Keycode::KP_PERIOD,
KeypadEquals => Keycode::KP_EQUALS,
Keypad0 => Keycode::KP_0,
Keypad1 => Keycode::KP_1,
Keypad2 => Keycode::KP_2,
Keypad3 => Keycode::KP_3,
Keypad4 => Keycode::KP_4,
Keypad5 => Keycode::KP_5,
Keypad6 => Keycode::KP_6,
Keypad7 => Keycode::KP_7,
Keypad8 => Keycode::KP_8,
Keypad9 => Keycode::KP_9,
}
}