Skip to content

Commit 3c0ca08

Browse files
ids1024jackpot51
authored andcommitted
improv: Refactor application code with a Layout type
1 parent fdfe93c commit 3c0ca08

File tree

5 files changed

+242
-183
lines changed

5 files changed

+242
-183
lines changed

.github/workflows/ci.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,9 @@ jobs:
1212
run-tests:
1313
runs-on: ubuntu-latest
1414
steps:
15-
- run: sudo apt-get install cargo libgtk-3-dev libhidapi-dev libusb-1.0-0-dev xvfb
15+
- run: sudo apt-get install cargo libgtk-3-dev libhidapi-dev libusb-1.0-0-dev
1616
- uses: actions/checkout@v2
17-
- run: xvfb-run cargo test
17+
- run: cargo test
1818

1919
linux-x86_64:
2020
runs-on: ubuntu-latest

src/application/keyboard.rs

Lines changed: 34 additions & 179 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ use std::{
66
Cell,
77
RefCell,
88
},
9-
char,
109
collections::HashMap,
1110
fs,
1211
path::{
@@ -20,10 +19,9 @@ use crate::daemon::Daemon;
2019
use crate::keyboard::Keyboard as ColorKeyboard;
2120
use crate::keyboard_color_button::KeyboardColorButton;
2221
use super::key::Key;
22+
use super::layout::Layout;
2323
use super::page::Page;
2424
use super::picker::Picker;
25-
use super::physical_layout::{PhysicalLayout, PhysicalLayoutEntry, PhysicalKeyEnum};
26-
use super::rect::Rect;
2725

2826
pub struct Keyboard {
2927
pub(crate) daemon_opt: Option<Rc<dyn Daemon>>,
@@ -48,174 +46,56 @@ impl Keyboard {
4846
Self::new_data(&keymap_csv, &layout_csv, &physical_json, daemon_opt, daemon_board)
4947
}
5048

51-
pub fn new_board(board: &str, daemon_opt: Option<Rc<dyn Daemon>>, daemon_board: usize) -> Option<Rc<Self>> {
52-
macro_rules! keyboard {
53-
($board:expr) => (if board == $board {
54-
let keymap_csv = include_str!(concat!("../../layouts/", $board, "/keymap.csv"));
55-
let layout_csv = include_str!(concat!("../../layouts/", $board, "/layout.csv"));
56-
let physical_json = include_str!(concat!("../../layouts/", $board, "/physical.json"));
57-
return Some(Keyboard::new_data(keymap_csv, layout_csv, physical_json, daemon_opt, daemon_board));
58-
});
59-
}
60-
61-
keyboard!("system76/addw1");
62-
keyboard!("system76/addw2");
63-
keyboard!("system76/bonw14");
64-
keyboard!("system76/darp5");
65-
keyboard!("system76/darp6");
66-
keyboard!("system76/gaze15");
67-
keyboard!("system76/launch_alpha_1");
68-
keyboard!("system76/launch_alpha_2");
69-
keyboard!("system76/launch_beta_1");
70-
keyboard!("system76/lemp9");
71-
keyboard!("system76/oryp5");
72-
keyboard!("system76/oryp6");
73-
None
74-
}
75-
76-
fn new_data(keymap_csv: &str, layout_csv: &str, physical_json: &str, daemon_opt: Option<Rc<dyn Daemon>>, daemon_board: usize) -> Rc<Self> {
77-
let mut keymap = HashMap::new();
78-
let mut scancode_names = HashMap::new();
79-
scancode_names.insert(0, "NONE");
80-
for line in keymap_csv.lines() {
81-
let mut parts = line.split(',');
82-
let scancode_name = parts.next().expect("Failed to read scancode name");
83-
let scancode_str = parts.next().expect("Failed to read scancode");
84-
let scancode_trim = scancode_str.trim_start_matches("0x");
85-
let scancode = u16::from_str_radix(scancode_trim, 16).expect("Failed to parse scancode");
86-
keymap.insert(scancode_name.to_string(), scancode);
87-
scancode_names.insert(scancode, scancode_name);
88-
}
89-
90-
let mut layout = HashMap::new();
91-
for line in layout_csv.lines() {
92-
let mut parts = line.split(',');
93-
let logical_name = parts.next().expect("Failed to read logical name");
94-
let output_str = parts.next().expect("Failed to read electrical output");
95-
let output = output_str.parse().expect("Failed to parse electrical output");
96-
let input_str = parts.next().expect("Failed to read electrical input");
97-
let input = input_str.parse().expect("Failed to parse electrical input");
98-
layout.insert(logical_name, (output, input));
99-
}
100-
101-
let physical_layout: PhysicalLayout = serde_json::from_str(&physical_json).unwrap();
102-
//println!("{:#?}", v);
103-
104-
let mut keys = Vec::new();
105-
106-
let mut row_i = 0;
107-
let mut col_i = 0;
108-
let mut x = 0.0;
109-
let mut y = 0.0;
110-
let mut w = 1.0;
111-
let mut h = 1.0;
112-
let mut background_color = "#cccccc".to_string();
113-
let mut foreground_color = "#000000".to_string();
114-
115-
for entry in physical_layout.0 {
116-
if let PhysicalLayoutEntry::Row(row) = entry {
117-
for i in row.0 {
118-
match i {
119-
PhysicalKeyEnum::Meta(meta) => {
120-
println!("Key metadata {:?}", meta);
121-
x += meta.x;
122-
y -= meta.y;
123-
w = meta.w.unwrap_or(w);
124-
h = meta.h.unwrap_or(h);
125-
background_color = meta.c.unwrap_or(background_color);
126-
if let Some(t) = meta.t {
127-
//TODO: support using different color per line?
128-
//Is this even possible in GTK?
129-
if let Some(t_l) = t.lines().next() {
130-
foreground_color = t_l.to_string();
131-
}
132-
}
133-
}
134-
PhysicalKeyEnum::Name(name) => {
135-
println!("Key {}, {} = {:?}", x, y, name);
136-
137-
let logical = (row_i as u8, col_i as u8);
138-
println!(" Logical: {:?}", logical);
139-
140-
let row_char = char::from_digit(logical.0 as u32, 36)
141-
.expect("Failed to convert row to char");
142-
let col_char = char::from_digit(logical.1 as u32, 36)
143-
.expect("Failed to convert col to char");
144-
let logical_name = format!("K{}{}", row_char, col_char).to_uppercase();
145-
println!(" Logical Name: {}", logical_name);
146-
147-
let electrical = layout.get(logical_name.as_str())
148-
//.expect("Failed to find electrical mapping");
149-
.unwrap_or(&(0, 0));
150-
println!(" Electrical: {:?}", electrical);
151-
152-
let mut scancodes = Vec::new();
153-
for layer in 0..2 {
154-
println!(" Layer {}", layer);
155-
let scancode = if let Some(ref daemon) = daemon_opt {
156-
match daemon.keymap_get(daemon_board, layer, electrical.0, electrical.1) {
157-
Ok(value) => value,
158-
Err(err) => {
159-
eprintln!("Failed to read scancode: {:?}", err);
160-
0
161-
}
162-
}
163-
} else {
164-
0
165-
};
166-
println!(" Scancode: {:04X}", scancode);
167-
168-
let scancode_name = match scancode_names.get(&scancode) {
169-
Some(some) => some.to_string(),
170-
None => String::new(),
171-
};
172-
println!(" Scancode Name: {}", scancode_name);
173-
174-
scancodes.push((scancode, scancode_name));
175-
}
176-
177-
keys.push(Key {
178-
logical,
179-
logical_name,
180-
physical: Rect::new(x, y, w, h),
181-
physical_name: name,
182-
electrical: electrical.clone(),
183-
electrical_name: format!("{}, {}", electrical.0, electrical.1),
184-
scancodes,
185-
background_color: background_color.clone(),
186-
foreground_color: foreground_color.clone(),
187-
gtk: HashMap::new(),
188-
});
189-
190-
x += w;
191-
192-
w = 1.0;
193-
h = 1.0;
194-
195-
col_i += 1;
49+
fn new_layout(layout: Layout, daemon_opt: Option<Rc<dyn Daemon>>, daemon_board: usize) -> Rc<Self> {
50+
let mut keys = layout.keys();
51+
for key in keys.iter_mut() {
52+
for layer in 0..2 {
53+
println!(" Layer {}", layer);
54+
let scancode = if let Some(ref daemon) = daemon_opt {
55+
match daemon.keymap_get(daemon_board, layer, key.electrical.0, key.electrical.1) {
56+
Ok(value) => value,
57+
Err(err) => {
58+
eprintln!("Failed to read scancode: {:?}", err);
59+
0
19660
}
19761
}
198-
}
62+
} else {
63+
0
64+
};
65+
println!(" Scancode: {:04X}", scancode);
19966

200-
x = 0.0;
201-
y -= 1.0;
67+
let scancode_name = match layout.scancode_names.get(&scancode) {
68+
Some(some) => some.to_string(),
69+
None => String::new(),
70+
};
71+
println!(" Scancode Name: {}", scancode_name);
20272

203-
col_i = 0;
204-
row_i += 1;
73+
key.scancodes.push((scancode, scancode_name));
20574
}
20675
}
20776

20877
Rc::new(Self {
20978
daemon_opt,
21079
daemon_board,
211-
keymap,
80+
keymap: layout.keymap,
21281
keys: RefCell::new(keys),
21382
page: Cell::new(Page::Layer1),
21483
picker: RefCell::new(WeakRef::new()),
21584
selected: RefCell::new(None),
21685
})
21786
}
21887

88+
pub fn new_board(board: &str, daemon_opt: Option<Rc<dyn Daemon>>, daemon_board: usize) -> Option<Rc<Self>> {
89+
Layout::from_board(board).map(|layout|
90+
Self::new_layout(layout, daemon_opt, daemon_board)
91+
)
92+
}
93+
94+
fn new_data(keymap_csv: &str, layout_csv: &str, physical_json: &str, daemon_opt: Option<Rc<dyn Daemon>>, daemon_board: usize) -> Rc<Self> {
95+
let layout = Layout::from_data(keymap_csv, layout_csv, physical_json);
96+
Self::new_layout(layout, daemon_opt, daemon_board)
97+
}
98+
21999
pub fn layer(&self) -> usize {
220100
//TODO: make this more robust
221101
match self.page.get() {
@@ -424,28 +304,3 @@ impl Keyboard {
424304
};
425305
}
426306
}
427-
428-
#[cfg(test)]
429-
mod tests {
430-
use super::*;
431-
432-
#[test]
433-
fn test_new_board() {
434-
gtk::init().unwrap();
435-
for i in &[
436-
"system76/addw1",
437-
"system76/addw2",
438-
"system76/bonw14",
439-
"system76/darp5",
440-
"system76/darp6",
441-
"system76/gaze15",
442-
"system76/launch_alpha_1",
443-
"system76/launch_alpha_2",
444-
"system76/lemp9",
445-
"system76/oryp5",
446-
"system76/oryp6",
447-
] {
448-
Keyboard::new_board(i, None, 0).unwrap();
449-
}
450-
}
451-
}

0 commit comments

Comments
 (0)