Skip to content

Commit

Permalink
feat(combo): add option to enable a combo only for a specific layer
Browse files Browse the repository at this point in the history
  • Loading branch information
pcasotti committed Dec 18, 2024
1 parent f057b5c commit a7a6d51
Show file tree
Hide file tree
Showing 8 changed files with 50 additions and 9 deletions.
6 changes: 5 additions & 1 deletion rmk-macro/src/behavior.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,11 @@ fn expand_combos(combos: &Option<CombosConfig>) -> proc_macro2::TokenStream {
let combos = combos.combos.iter().map(|combo| {
let actions = combo.actions.iter().map(|a| parse_key(a.to_owned()));
let output = parse_key(combo.output.to_owned());
quote! { ::rmk::combo::Combo::new([#(#actions),*], #output) }
let layer = match combo.layer {
Some(layer) => quote! { ::core::option::Option::Some(#layer) },
None => quote! { ::core::option::Option::None },
};
quote! { ::rmk::combo::Combo::new([#(#actions),*], #output, #layer) }
});

quote! { ::heapless::Vec::from_iter([#(#combos),*]) }
Expand Down
1 change: 1 addition & 0 deletions rmk-macro/src/config/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,7 @@ pub struct CombosConfig {
pub struct ComboConfig {
pub actions: Vec<String>,
pub output: String,
pub layer: Option<u8>,
}

/// Configurations for split keyboards
Expand Down
6 changes: 6 additions & 0 deletions rmk-macro/src/keyboard_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -455,6 +455,12 @@ impl KeyboardConfig {
if c.actions.len() > COMBO_MAX_LENGTH {
return rmk_compile_error!(format!("keyboard.toml: number of keys in combo #{i} is greater than [behavior.combo.max_length]"));
}

if let Some(layer) = c.layer {
if layer >= layout.layers {
return rmk_compile_error!(format!("keyboard.toml: layer in combo #{i} is greater than [layout.layers]"));
}
}
}
}

Expand Down
27 changes: 24 additions & 3 deletions rmk/src/combo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ pub(crate) const COMBO_MAX_LENGTH: usize = 4;
pub struct Combo {
pub(crate) actions: Vec<KeyAction, COMBO_MAX_LENGTH>,
pub(crate) output: KeyAction,
pub(crate) layer: Option<u8>,
state: u8,
}

Expand All @@ -21,23 +22,43 @@ impl Default for Combo {
}

impl Combo {
pub fn new<I: IntoIterator<Item = KeyAction>>(actions: I, output: KeyAction) -> Self {
pub fn new<I: IntoIterator<Item = KeyAction>>(
actions: I,
output: KeyAction,
layer: Option<u8>,
) -> Self {
Self {
actions: Vec::from_iter(actions),
output,
layer,
state: 0,
}
}

pub fn empty() -> Self {
Self::new(Vec::<KeyAction, COMBO_MAX_LENGTH>::new(), KeyAction::No)
Self::new(
Vec::<KeyAction, COMBO_MAX_LENGTH>::new(),
KeyAction::No,
None,
)
}

pub(crate) fn update(&mut self, key_action: KeyAction, key_event: KeyEvent) -> bool {
pub(crate) fn update(
&mut self,
key_action: KeyAction,
key_event: KeyEvent,
active_layer: u8,
) -> bool {
if !key_event.pressed || key_action == KeyAction::No {
return false;
}

if let Some(layer) = self.layer {
if layer != active_layer {
return false;
}
}

let action_idx = self.actions.iter().position(|&a| a == key_action);
if let Some(i) = action_idx {
self.state |= 1 << i;
Expand Down
3 changes: 2 additions & 1 deletion rmk/src/keyboard.rs
Original file line number Diff line number Diff line change
Expand Up @@ -322,8 +322,9 @@ impl<'a, const ROW: usize, const COL: usize, const NUM_LAYER: usize>
key_event: KeyEvent,
) -> Option<KeyAction> {
let mut is_combo_action = false;
let current_layer = self.keymap.borrow().get_activated_layer();
for combo in self.keymap.borrow_mut().combos.iter_mut() {
is_combo_action |= combo.update(key_action, key_event);
is_combo_action |= combo.update(key_action, key_event, current_layer);
}

if key_event.pressed && is_combo_action {
Expand Down
2 changes: 1 addition & 1 deletion rmk/src/keymap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,7 @@ impl<'a, const ROW: usize, const COL: usize, const NUM_LAYER: usize>
KeyAction::No
}

fn get_activated_layer(&self) -> u8 {
pub(crate) fn get_activated_layer(&self) -> u8 {
for (layer_idx, _) in self.layers.iter().enumerate().rev() {
if self.layer_state[layer_idx] || layer_idx as u8 == self.default_layer {
return layer_idx as u8;
Expand Down
13 changes: 10 additions & 3 deletions rmk/src/storage/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,11 @@ impl Value<'_> for StorageData {
);
}
BigEndian::write_u16(&mut buffer[9..11], to_via_keycode(combo.output));
Ok(11)
buffer[11] = match combo.layer {
Some(layer) => layer.to_be(),
None => u8::MAX,
};
Ok(12)
}
StorageData::ConnectionType(ty) => {
buffer[0] = StorageKeys::ConnectionType as u8;
Expand Down Expand Up @@ -273,7 +277,7 @@ impl Value<'_> for StorageData {
Ok(StorageData::MacroData(buf))
}
StorageKeys::ComboData => {
if buffer.len() < 11 {
if buffer.len() < 12 {
return Err(SerializationError::InvalidData);
}
let mut actions = [KeyAction::No; 4];
Expand All @@ -282,10 +286,12 @@ impl Value<'_> for StorageData {
from_via_keycode(BigEndian::read_u16(&buffer[1 + i * 2..3 + i * 2]));
}
let output = from_via_keycode(BigEndian::read_u16(&buffer[9..11]));
let layer = u8::from_be(buffer[11]);
Ok(StorageData::ComboData(ComboData {
idx: 0,
actions,
output,
layer: (layer != u8::MAX).then_some(layer),
}))
}
StorageKeys::ConnectionType => Ok(StorageData::ConnectionType(buffer[1])),
Expand Down Expand Up @@ -353,6 +359,7 @@ pub(crate) struct ComboData {
pub(crate) idx: usize,
pub(crate) actions: [KeyAction; COMBO_MAX_LENGTH],
pub(crate) output: KeyAction,
pub(crate) layer: Option<u8>,
}

pub(crate) struct Storage<
Expand Down Expand Up @@ -707,7 +714,7 @@ impl<F: AsyncNorFlash, const ROW: usize, const COL: usize, const NUM_LAYER: usiz
for &action in combo.actions.iter().filter(|&&a| a != KeyAction::No) {
let _ = actions.push(action);
}
combos[i] = Combo::new(actions, combo.output);
combos[i] = Combo::new(actions, combo.output, combo.layer);
}
}

Expand Down
1 change: 1 addition & 0 deletions rmk/src/via/process.rs
Original file line number Diff line number Diff line change
Expand Up @@ -453,6 +453,7 @@ impl<'a, const ROW: usize, const COL: usize, const NUM_LAYER: usize>
idx: real_idx,
actions,
output,
layer: combos[real_idx].layer,
}))
.await;
}
Expand Down

0 comments on commit a7a6d51

Please sign in to comment.