#[derive(Debug, Clone, Copy)] pub struct KeyPos { pub row: usize, pub col: f32, pub width: f32, } fn ansi_row0(name: &str) -> Option { let keys: &[(&str, f32, f32)] = &[ ("ESC", 0.0, 1.0), ("TLDE", 1.0, 1.0), ("AE01", 2.0, 1.0), ("AE02", 3.0, 1.0), ("AE03", 4.0, 1.0), ("AE04", 5.0, 1.0), ("AE05", 6.0, 1.0), ("AE06", 7.0, 1.0), ("AE07", 8.0, 1.0), ("AE08", 9.0, 1.0), ("AE09", 10.0, 1.0), ("AE10", 11.0, 1.0), ("AE11", 12.0, 1.0), ("AE12", 13.0, 1.0), ("BKSP", 14.0, 1.5), ]; keys.iter().find(|(n, _, _)| *n == name).map(|(_, c, w)| KeyPos { row: 0, col: *c, width: *w }) } fn ansi_row1(name: &str) -> Option { let keys: &[(&str, f32, f32)] = &[ ("TAB", 0.0, 1.5), ("AD01", 1.5, 1.0), ("AD02", 2.5, 1.0), ("AD03", 3.5, 1.0), ("AD04", 4.5, 1.0), ("AD05", 5.5, 1.0), ("AD06", 6.5, 1.0), ("AD07", 7.5, 1.0), ("AD08", 8.5, 1.0), ("AD09", 9.5, 1.0), ("AD10", 10.5, 1.0), ("AD11", 11.5, 1.0), ("AD12", 12.5, 1.0), ("BKSL", 13.5, 1.5), ]; keys.iter().find(|(n, _, _)| *n == name).map(|(_, c, w)| KeyPos { row: 1, col: *c, width: *w }) } fn ansi_row2(name: &str) -> Option { let keys: &[(&str, f32, f32)] = &[ ("CAPS", 0.0, 1.75), ("AC01", 1.75, 1.0), ("AC02", 2.75, 1.0), ("AC03", 3.75, 1.0), ("AC04", 4.75, 1.0), ("AC05", 5.75, 1.0), ("AC06", 6.75, 1.0), ("AC07", 7.75, 1.0), ("AC08", 8.75, 1.0), ("AC09", 9.75, 1.0), ("AC10", 10.75, 1.0), ("AC11", 11.75, 1.0), ("RET", 12.75, 2.25), ]; keys.iter().find(|(n, _, _)| *n == name).map(|(_, c, w)| KeyPos { row: 2, col: *c, width: *w }) } fn ansi_row3(name: &str) -> Option { let keys: &[(&str, f32, f32)] = &[ ("LFSH", 0.0, 2.25), ("AB01", 2.25, 1.0), ("AB02", 3.25, 1.0), ("AB03", 4.25, 1.0), ("AB04", 5.25, 1.0), ("AB05", 6.25, 1.0), ("AB06", 7.25, 1.0), ("AB07", 8.25, 1.0), ("AB08", 9.25, 1.0), ("AB09", 10.25, 1.0), ("AB10", 11.25, 1.0), ("RTSH", 12.25, 2.75), ]; keys.iter().find(|(n, _, _)| *n == name).map(|(_, c, w)| KeyPos { row: 3, col: *c, width: *w }) } fn ansi_row4(name: &str) -> Option { let keys: &[(&str, f32, f32)] = &[ ("LCTL", 0.0, 1.25), ("LWIN", 1.25, 1.25), ("LALT", 2.50, 1.25), ("SPCE", 3.75, 6.25), ("RALT", 10.0, 1.25), ("RWIN", 11.25, 1.25), ("MENU", 12.50, 1.25), ("RCTL", 13.75, 1.25), ]; keys.iter().find(|(n, _, _)| *n == name).map(|(_, c, w)| KeyPos { row: 4, col: *c, width: *w }) } fn iso_row3(name: &str, _has_lsgt: bool) -> Option { let keys: &[(&str, f32, f32)] = &[ ("LFSH", 0.0, 1.25), ("LSGT", 1.25, 1.0), ("AB01", 2.25, 1.0), ("AB02", 3.25, 1.0), ("AB03", 4.25, 1.0), ("AB04", 5.25, 1.0), ("AB05", 6.25, 1.0), ("AB06", 7.25, 1.0), ("AB07", 8.25, 1.0), ("AB08", 9.25, 1.0), ("AB09", 10.25, 1.0), ("AB10", 11.25, 1.0), ("RTSH", 12.25, 2.75), ]; keys.iter().find(|(n, _, _)| *n == name).map(|(_, c, w)| KeyPos { row: 3, col: *c, width: *w }) } fn iso_row2(name: &str) -> Option { let keys: &[(&str, f32, f32)] = &[ ("CAPS", 0.0, 1.75), ("AC01", 1.75, 1.0), ("AC02", 2.75, 1.0), ("AC03", 3.75, 1.0), ("AC04", 4.75, 1.0), ("AC05", 5.75, 1.0), ("AC06", 6.75, 1.0), ("AC07", 7.75, 1.0), ("AC08", 8.75, 1.0), ("AC09", 9.75, 1.0), ("AC10", 10.75, 1.0), ("AC11", 11.75, 1.0), ("RET", 12.75, 2.25), ]; keys.iter().find(|(n, _, _)| *n == name).map(|(_, c, w)| KeyPos { row: 2, col: *c, width: *w }) } pub fn resolve_position(name: &str, is_iso: bool) -> KeyPos { if is_iso { if let Some(pos) = iso_row3(name, true).or_else(|| ansi_row0(name)) .or_else(|| ansi_row1(name)) .or_else(|| iso_row2(name)) .or_else(|| ansi_row4(name)) { return pos; } } else { if let Some(pos) = ansi_row0(name) .or_else(|| ansi_row1(name)) .or_else(|| ansi_row2(name)) .or_else(|| ansi_row3(name)) .or_else(|| ansi_row4(name)) { return pos; } } let extra = DEFAULT_POS.fetch_add(1, std::sync::atomic::Ordering::Relaxed); KeyPos { row: 5, col: (extra % 16) as f32, width: 1.0, } } use std::sync::atomic::AtomicU32; static DEFAULT_POS: AtomicU32 = AtomicU32::new(0); pub fn reset_default_pos() { DEFAULT_POS.store(0, std::sync::atomic::Ordering::Relaxed); }