core: button: add support for layout switching keys
This commit is contained in:
parent
71ca235a09
commit
e5d0716c0f
2 changed files with 99 additions and 28 deletions
|
|
@ -488,6 +488,11 @@ impl<D: Display, K: Keyboard> Button<D, K> {
|
||||||
let meta_pressed = modifiers[MOD_META - 1] != ModState::Released;
|
let meta_pressed = modifiers[MOD_META - 1] != ModState::Released;
|
||||||
let mods_pressed = ctrl_pressed || alt_pressed || meta_pressed;
|
let mods_pressed = ctrl_pressed || alt_pressed || meta_pressed;
|
||||||
|
|
||||||
|
if part.sym() == Keysym::Num_Lock
|
||||||
|
|| part.sym() == Keysym::Caps_Lock {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if part.key_available() && mods_pressed {
|
if part.key_available() && mods_pressed {
|
||||||
kbd.press(part.sym());
|
kbd.press(part.sym());
|
||||||
kbd.release(part.sym());
|
kbd.release(part.sym());
|
||||||
|
|
@ -499,6 +504,30 @@ impl<D: Display, K: Keyboard> Button<D, K> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn release_layout_switcher(&mut self, sym: Keysym) -> DrawOperation
|
||||||
|
{
|
||||||
|
let old_width = self.layout.width();
|
||||||
|
let old_height = self.layout.height();
|
||||||
|
|
||||||
|
match sym {
|
||||||
|
Keysym::Num_Lock => {
|
||||||
|
self.layout.switch_numeric();
|
||||||
|
},
|
||||||
|
Keysym::Caps_Lock => {
|
||||||
|
self.layout.switch_text();
|
||||||
|
},
|
||||||
|
_ => return DrawOperation::Key,
|
||||||
|
}
|
||||||
|
|
||||||
|
self.layout.update_keys_supported(&self.kbd);
|
||||||
|
self.kbd.change_layout(&self.layout);
|
||||||
|
|
||||||
|
self.x_scale *= self.layout.width() / old_width;
|
||||||
|
self.y_scale *= self.layout.height() / old_height;
|
||||||
|
|
||||||
|
DrawOperation::Labels
|
||||||
|
}
|
||||||
|
|
||||||
fn is_normal_key_pressed(&self) -> bool
|
fn is_normal_key_pressed(&self) -> bool
|
||||||
{
|
{
|
||||||
for id in &self.timers {
|
for id in &self.timers {
|
||||||
|
|
@ -586,12 +615,14 @@ impl<D: Display, K: Keyboard> Button<D, K> {
|
||||||
|
|
||||||
key.parts[press.part].release();
|
key.parts[press.part].release();
|
||||||
|
|
||||||
|
let keysym = key.parts[press.part].sym();
|
||||||
let modifier = key.parts[press.part].modifier_id();
|
let modifier = key.parts[press.part].modifier_id();
|
||||||
if modifier == 0 {
|
if modifier == 0 {
|
||||||
Self::emit(&mut self.kbd, &key.parts[press.part], &self.modifiers);
|
Self::emit(&mut self.kbd, &key.parts[press.part], &self.modifiers);
|
||||||
}
|
}
|
||||||
|
|
||||||
let draw = self.release_mod(modifier);
|
let draw = self.release_mod(modifier);
|
||||||
|
let draw = draw + self.release_layout_switcher(keysym);
|
||||||
|
|
||||||
let press = self.presses[id].as_ref().unwrap();
|
let press = self.presses[id].as_ref().unwrap();
|
||||||
let key = self.layout.locate_key(press.x1, press.y1).unwrap();
|
let key = self.layout.locate_key(press.x1, press.y1).unwrap();
|
||||||
|
|
|
||||||
|
|
@ -69,6 +69,7 @@ impl KeyValue {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
pub struct Part {
|
pub struct Part {
|
||||||
orig: KeyValue,
|
orig: KeyValue,
|
||||||
val: KeyValue,
|
val: KeyValue,
|
||||||
|
|
@ -404,6 +405,7 @@ impl Part {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
pub struct Key {
|
pub struct Key {
|
||||||
pub parts: [Part; 9],
|
pub parts: [Part; 9],
|
||||||
pub x1: f64,
|
pub x1: f64,
|
||||||
|
|
@ -441,7 +443,7 @@ impl Key {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const KEYSYMS: [(&str, Keysym, &str); 21] = [
|
const KEYSYMS: [(&str, Keysym, &str); 23] = [
|
||||||
("\\#", Keysym::numbersign, "#"),
|
("\\#", Keysym::numbersign, "#"),
|
||||||
("\\?", Keysym::question, "?"),
|
("\\?", Keysym::question, "?"),
|
||||||
("\\@", Keysym::at, "@"),
|
("\\@", Keysym::at, "@"),
|
||||||
|
|
@ -461,10 +463,13 @@ const KEYSYMS: [(&str, Keysym, &str); 21] = [
|
||||||
("right", Keysym::Right, "→"),
|
("right", Keysym::Right, "→"),
|
||||||
("shift", Keysym::Shift_L, "⇧"),
|
("shift", Keysym::Shift_L, "⇧"),
|
||||||
("space", Keysym::space, " "),
|
("space", Keysym::space, " "),
|
||||||
|
("switch_numeric", Keysym::Num_Lock, "123+"),
|
||||||
|
("switch_text", Keysym::Caps_Lock, "ABC"),
|
||||||
("tab", Keysym::Tab, "⭾"),
|
("tab", Keysym::Tab, "⭾"),
|
||||||
("up", Keysym::Up, "↑"),
|
("up", Keysym::Up, "↑"),
|
||||||
];
|
];
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
struct LayoutFile {
|
struct LayoutFile {
|
||||||
rows: Vec<Vec<Key>>,
|
rows: Vec<Vec<Key>>,
|
||||||
has_bottom_row: bool,
|
has_bottom_row: bool,
|
||||||
|
|
@ -604,6 +609,10 @@ impl LayoutFile {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Layout {
|
pub struct Layout {
|
||||||
|
main_layout: LayoutFile,
|
||||||
|
numeric: LayoutFile,
|
||||||
|
bottom_row: LayoutFile,
|
||||||
|
|
||||||
rows: Vec<Vec<Key>>,
|
rows: Vec<Vec<Key>>,
|
||||||
width: f64,
|
width: f64,
|
||||||
height: f64,
|
height: f64,
|
||||||
|
|
@ -652,6 +661,35 @@ impl Layout {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn open_layout(&mut self, data: LayoutFile)
|
||||||
|
{
|
||||||
|
self.rows = data.rows;
|
||||||
|
self.width = data.width;
|
||||||
|
self.height = data.height;
|
||||||
|
|
||||||
|
if data.has_bottom_row {
|
||||||
|
let old_height = self.height;
|
||||||
|
self.height += self.bottom_row.height;
|
||||||
|
|
||||||
|
self.rows.reserve(self.bottom_row.rows.len());
|
||||||
|
for row in &self.bottom_row.rows {
|
||||||
|
let mut new_row = Vec::with_capacity(row.len());
|
||||||
|
|
||||||
|
for key in row {
|
||||||
|
new_row.push(Key {
|
||||||
|
parts: key.parts.clone(),
|
||||||
|
x1: key.x1 * self.width / self.bottom_row.width,
|
||||||
|
y1: old_height + key.y1,
|
||||||
|
x2: key.x2 * self.width / self.bottom_row.width,
|
||||||
|
y2: old_height + key.y2,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
self.rows.push(new_row);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn load(cfg: &Configuration) -> Result<Self, Error>
|
pub fn load(cfg: &Configuration) -> Result<Self, Error>
|
||||||
{
|
{
|
||||||
let dir = Path::new("/usr/share/unfettered-keyboard/layouts");
|
let dir = Path::new("/usr/share/unfettered-keyboard/layouts");
|
||||||
|
|
@ -659,37 +697,25 @@ impl Layout {
|
||||||
let path = dir.join(cfg.layout());
|
let path = dir.join(cfg.layout());
|
||||||
let main_layout = LayoutFile::load(path)?;
|
let main_layout = LayoutFile::load(path)?;
|
||||||
|
|
||||||
|
let path = dir.join("numeric.xml");
|
||||||
|
let numeric = LayoutFile::load(path)?;
|
||||||
|
|
||||||
|
let path = dir.join("bottom_row.xml");
|
||||||
|
let bottom_row = LayoutFile::load(path)?;
|
||||||
|
|
||||||
let mut layout = Layout {
|
let mut layout = Layout {
|
||||||
rows: main_layout.rows,
|
main_layout,
|
||||||
width: main_layout.width,
|
numeric,
|
||||||
height: main_layout.height,
|
bottom_row,
|
||||||
|
|
||||||
|
rows: Vec::new(),
|
||||||
|
width: 0.0,
|
||||||
|
height: 0.0,
|
||||||
text_supp: false,
|
text_supp: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
if main_layout.has_bottom_row {
|
let data = layout.main_layout.clone();
|
||||||
let path = dir.join("bottom_row.xml");
|
layout.open_layout(data);
|
||||||
let bottom_row = LayoutFile::load(path)?;
|
|
||||||
|
|
||||||
let old_height = layout.height;
|
|
||||||
layout.height += bottom_row.height;
|
|
||||||
|
|
||||||
layout.rows.reserve(bottom_row.rows.len());
|
|
||||||
for row in bottom_row.rows {
|
|
||||||
let mut new_row = Vec::with_capacity(row.len());
|
|
||||||
|
|
||||||
for key in row {
|
|
||||||
new_row.push(Key {
|
|
||||||
parts: key.parts,
|
|
||||||
x1: key.x1 * layout.width / bottom_row.width,
|
|
||||||
y1: old_height + key.y1,
|
|
||||||
x2: key.x2 * layout.width / bottom_row.width,
|
|
||||||
y2: old_height + key.y2,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
layout.rows.push(new_row);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(layout)
|
Ok(layout)
|
||||||
}
|
}
|
||||||
|
|
@ -784,4 +810,18 @@ impl Layout {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn switch_numeric(&mut self)
|
||||||
|
{
|
||||||
|
let data = self.numeric.clone();
|
||||||
|
self.open_layout(data);
|
||||||
|
self.set_text_supported(self.text_supp);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn switch_text(&mut self)
|
||||||
|
{
|
||||||
|
let data = self.main_layout.clone();
|
||||||
|
self.open_layout(data);
|
||||||
|
self.set_text_supported(self.text_supp);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue