summaryrefslogtreecommitdiffstats
path: root/src/layout.rs
blob: 4dad3fb9dc598c5e61a0aab58ecbd3bd0bcafece (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
#[derive(Debug, Clone, Copy)]
pub struct KeyPos {
    pub row: usize,
    pub col: f32,
    pub width: f32,
}

fn ansi_row0(name: &str) -> Option<KeyPos> {
    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<KeyPos> {
    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<KeyPos> {
    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<KeyPos> {
    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<KeyPos> {
    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<KeyPos> {
    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<KeyPos> {
    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);
}