ableos/ableos/src/keyboard/abstractions/custom_layout.rs

445 lines
13 KiB
Rust

use crate::{
DecodedKey, HandleControl, KeyCode, KeyboardLayout, LayoutEntry, LayoutEntryKind, Modifiers,
};
pub struct CustomLayout {
mapping: [LayoutEntry; 256],
}
impl Default for CustomLayout {
fn default() -> Self {
Self::new_us104key()
}
}
impl CustomLayout {
pub fn new_us104key() -> Self {
let mut mapping = Self {
mapping: [LayoutEntry::default(); 256],
};
mapping.set(
KeyCode::BackTick,
LayoutEntry::regular().unshifted('`').shifted('`'),
);
mapping.set(KeyCode::Escape, LayoutEntry::regular().unshifted('\x1B'));
mapping.set(
KeyCode::Key0,
LayoutEntry::regular().unshifted('0').shifted(')'),
);
mapping.set(
KeyCode::Key1,
LayoutEntry::regular().unshifted('1').shifted('!'),
);
mapping.set(
KeyCode::Key2,
LayoutEntry::regular().unshifted('2').shifted('@'),
);
mapping.set(
KeyCode::Key3,
LayoutEntry::regular().unshifted('3').shifted('#'),
);
mapping.set(
KeyCode::Key4,
LayoutEntry::regular().unshifted('4').shifted('$'),
);
mapping.set(
KeyCode::Key5,
LayoutEntry::regular().unshifted('5').shifted('%'),
);
mapping.set(
KeyCode::Key6,
LayoutEntry::regular().unshifted('6').shifted('^'),
);
mapping.set(
KeyCode::Key7,
LayoutEntry::regular().unshifted('7').shifted('&'),
);
mapping.set(
KeyCode::Key8,
LayoutEntry::regular().unshifted('8').shifted('*'),
);
mapping.set(
KeyCode::Key9,
LayoutEntry::regular().unshifted('9').shifted('('),
);
mapping.set(
KeyCode::Minus,
LayoutEntry::regular().unshifted('-').shifted('_'),
);
mapping.set(
KeyCode::Equals,
LayoutEntry::regular().unshifted('=').shifted('+'),
);
mapping.set(KeyCode::Backspace, LayoutEntry::regular().all('\x08'));
mapping.set(KeyCode::Tab, LayoutEntry::regular().all('\x09'));
mapping.set(
KeyCode::Q,
LayoutEntry::alphabet()
.low('q')
.high('Q')
.raw_unicode('\u{0011}'),
);
mapping.set(
KeyCode::W,
LayoutEntry::alphabet()
.low('w')
.high('W')
.raw_unicode('\u{0017}'),
);
mapping.set(
KeyCode::E,
LayoutEntry::alphabet()
.low('e')
.high('E')
.raw_unicode('\u{0005}'),
);
mapping.set(
KeyCode::R,
LayoutEntry::alphabet()
.low('r')
.high('R')
.raw_unicode('\u{0012}'),
);
mapping.set(
KeyCode::T,
LayoutEntry::alphabet()
.low('t')
.high('T')
.raw_unicode('\u{0014}'),
);
mapping.set(
KeyCode::Y,
LayoutEntry::alphabet()
.low('y')
.high('Y')
.raw_unicode('\u{0019}'),
);
mapping.set(
KeyCode::U,
LayoutEntry::alphabet()
.low('u')
.high('U')
.raw_unicode('\u{0015}'),
);
mapping.set(
KeyCode::I,
LayoutEntry::alphabet()
.low('i')
.high('I')
.raw_unicode('\u{0009}'),
);
mapping.set(
KeyCode::O,
LayoutEntry::alphabet()
.low('o')
.high('O')
.raw_unicode('\u{000F}'),
);
mapping.set(
KeyCode::P,
LayoutEntry::alphabet()
.low('p')
.high('P')
.raw_unicode('\u{0010}'),
);
mapping.set(
KeyCode::A,
LayoutEntry::alphabet()
.low('a')
.high('A')
.raw_unicode('\u{0001}'),
);
mapping.set(
KeyCode::S,
LayoutEntry::alphabet()
.low('s')
.high('S')
.raw_unicode('\u{0013}'),
);
mapping.set(
KeyCode::D,
LayoutEntry::alphabet()
.low('d')
.high('D')
.raw_unicode('\u{0004}'),
);
mapping.set(
KeyCode::F,
LayoutEntry::alphabet()
.low('f')
.high('F')
.raw_unicode('\u{0006}'),
);
mapping.set(
KeyCode::G,
LayoutEntry::alphabet()
.low('g')
.high('G')
.raw_unicode('\u{0007}'),
);
mapping.set(
KeyCode::H,
LayoutEntry::alphabet()
.low('h')
.high('H')
.raw_unicode('\u{0008}'),
);
mapping.set(
KeyCode::J,
LayoutEntry::alphabet()
.low('j')
.high('J')
.raw_unicode('\u{000A}'),
);
mapping.set(
KeyCode::K,
LayoutEntry::alphabet()
.low('k')
.high('K')
.raw_unicode('\u{000B}'),
);
mapping.set(
KeyCode::L,
LayoutEntry::alphabet()
.low('l')
.high('L')
.raw_unicode('\u{000C}'),
);
mapping.set(
KeyCode::Z,
LayoutEntry::alphabet()
.low('z')
.high('Z')
.raw_unicode('\u{001A}'),
);
mapping.set(
KeyCode::X,
LayoutEntry::alphabet()
.low('x')
.high('X')
.raw_unicode('\u{0018}'),
);
mapping.set(
KeyCode::C,
LayoutEntry::alphabet()
.low('c')
.high('C')
.raw_unicode('\u{0003}'),
);
mapping.set(
KeyCode::V,
LayoutEntry::alphabet()
.low('v')
.high('V')
.raw_unicode('\u{0016}'),
);
mapping.set(
KeyCode::B,
LayoutEntry::alphabet()
.low('b')
.high('B')
.raw_unicode('\u{0002}'),
);
mapping.set(
KeyCode::N,
LayoutEntry::alphabet()
.low('n')
.high('N')
.raw_unicode('\u{000E}'),
);
mapping.set(
KeyCode::M,
LayoutEntry::alphabet()
.low('m')
.high('M')
.raw_unicode('\u{000D}'),
);
mapping.set(
KeyCode::BracketSquareLeft,
LayoutEntry::regular().unshifted('{').shifted('['),
);
mapping.set(
KeyCode::BracketSquareRight,
LayoutEntry::regular().unshifted('}').shifted(']'),
);
mapping.set(
KeyCode::BackSlash,
LayoutEntry::regular().unshifted('|').shifted('\\'),
);
mapping.set(
KeyCode::SemiColon,
LayoutEntry::regular().unshifted(';').shifted(':'),
);
mapping.set(
KeyCode::Quote,
LayoutEntry::regular().unshifted('\'').shifted('"'),
);
mapping.set(KeyCode::Enter, LayoutEntry::regular().all('\x0A'));
mapping.set(
KeyCode::Comma,
LayoutEntry::regular().unshifted(',').shifted('<'),
);
mapping.set(
KeyCode::Fullstop,
LayoutEntry::regular().unshifted('.').shifted('>'),
);
mapping.set(
KeyCode::Slash,
LayoutEntry::regular().unshifted('/').shifted('?'),
);
mapping.set(KeyCode::Spacebar, LayoutEntry::regular().all(' '));
mapping.set(KeyCode::Delete, LayoutEntry::regular().all('\x7F'));
mapping.set(KeyCode::NumpadSlash, LayoutEntry::numpad().all('/'));
mapping.set(KeyCode::NumpadStar, LayoutEntry::numpad().all('*'));
mapping.set(KeyCode::NumpadMinus, LayoutEntry::numpad().all('-'));
mapping.set(
KeyCode::Numpad7,
LayoutEntry::numpad().low('7').high(KeyCode::Home),
);
mapping.set(
KeyCode::Numpad8,
LayoutEntry::numpad().low('8').high(KeyCode::ArrowUp),
);
mapping.set(
KeyCode::Numpad9,
LayoutEntry::numpad().low('9').high(KeyCode::PageUp),
);
mapping.set(KeyCode::NumpadPlus, LayoutEntry::numpad().all('+'));
mapping.set(
KeyCode::Numpad4,
LayoutEntry::numpad().low('4').high(KeyCode::ArrowLeft),
);
mapping.set(KeyCode::Numpad5, LayoutEntry::numpad().all('5'));
mapping.set(
KeyCode::Numpad6,
LayoutEntry::numpad().low('6').high(KeyCode::ArrowRight),
);
mapping.set(
KeyCode::Numpad1,
LayoutEntry::numpad().low('1').high(KeyCode::End),
);
mapping.set(
KeyCode::Numpad2,
LayoutEntry::numpad().low('2').high(KeyCode::ArrowDown),
);
mapping.set(
KeyCode::Numpad3,
LayoutEntry::numpad().low('3').high(KeyCode::PageDown),
);
mapping.set(
KeyCode::Numpad0,
LayoutEntry::numpad().low('0').high(KeyCode::Insert),
);
mapping.set(
KeyCode::NumpadPeriod,
LayoutEntry::numpad().low('.').high('\x7F'),
);
mapping.set(KeyCode::NumpadEnter, LayoutEntry::numpad().all('\x0A'));
mapping
}
pub fn new_us105key() -> Self {
let mut mapping = Self::new_us104key();
mapping.set(
KeyCode::BackTick,
LayoutEntry::regular()
.unshifted('`')
.shifted('¬')
.altgr('|'),
);
mapping.set(
KeyCode::Key2,
LayoutEntry::regular().unshifted('2').shifted('"'),
);
mapping.set(
KeyCode::Quote,
LayoutEntry::regular().unshifted('\'').shifted('@'),
);
mapping.set(
KeyCode::Key3,
LayoutEntry::regular().unshifted('3').shifted('£'),
);
mapping.set(
KeyCode::BackTick,
LayoutEntry::regular()
.unshifted('4')
.shifted('$')
.altgr('€'),
);
mapping.set(
KeyCode::HashTilde,
LayoutEntry::regular().unshifted('#').shifted('~'),
);
mapping
}
pub fn set(&mut self, pos: KeyCode, entry: LayoutEntry) {
self.mapping[pos as usize] = entry;
}
}
impl KeyboardLayout for CustomLayout {
fn map_keycode(
&self,
keycode: KeyCode,
modifiers: &Modifiers,
handle_ctrl: HandleControl,
) -> DecodedKey {
let map_to_unicode = handle_ctrl == HandleControl::MapLettersToUnicode;
let spot = &self.mapping[keycode as usize];
if let Some(k) = if map_to_unicode && modifiers.is_ctrl() {
match spot.kind {
LayoutEntryKind::Regular => spot.raw_unicode,
LayoutEntryKind::Numlockable => None,
LayoutEntryKind::Capslockable => spot.raw_unicode,
}
} else if modifiers.alt_gr {
match spot.kind {
LayoutEntryKind::Regular => spot.altgr,
LayoutEntryKind::Numlockable => None,
LayoutEntryKind::Capslockable => spot.altgr,
}
} else if modifiers.is_shifted() {
match spot.kind {
LayoutEntryKind::Regular => spot.shifted,
LayoutEntryKind::Numlockable => {
if modifiers.numlock {
spot.locked_shifted
} else {
spot.shifted
}
}
LayoutEntryKind::Capslockable => {
if modifiers.is_caps() {
spot.locked_shifted
} else {
spot.shifted
}
}
}
} else {
match spot.kind {
LayoutEntryKind::Regular => spot.unshifted,
LayoutEntryKind::Numlockable => {
if modifiers.numlock {
spot.locked
} else {
spot.unshifted
}
}
LayoutEntryKind::Capslockable => {
if modifiers.is_caps() {
spot.locked
} else {
spot.unshifted
}
}
}
} {
k
} else {
DecodedKey::RawKey(keycode as u8)
}
}
}