use macro_rules_attribute::apply;
use crate::{
interface::state::input_event::EncoderDirection,
keycode::{KeyAction, KeyCode},
macros::common_derive,
};
#[derive(Clone)]
pub struct Keymap<
const LAYER: usize,
const ROW: usize,
const COL: usize,
const ENCODER_COUNT: usize,
const TAP_DANCE_MAX_DEFINITIONS: usize,
const TAP_DANCE_MAX_REPEATS: usize,
const COMBO_KEY_MAX_DEFINITIONS: usize,
const COMBO_KEY_MAX_SOURCES: usize,
> {
pub layers: [Layer<ROW, COL, ENCODER_COUNT>; LAYER],
pub tap_dance: TapDanceDefinitions<TAP_DANCE_MAX_DEFINITIONS, TAP_DANCE_MAX_REPEATS>,
pub combo: ComboDefinitions<COMBO_KEY_MAX_DEFINITIONS, COMBO_KEY_MAX_SOURCES>,
}
impl<
const LAYER: usize,
const ROW: usize,
const COL: usize,
const ENCODER_COUNT: usize,
const TAP_DANCE_MAX_DEFINITIONS: usize,
const TAP_DANCE_MAX_REPEATS: usize,
const COMBO_KEY_MAX_DEFINITIONS: usize,
const COMBO_KEY_MAX_SOURCES: usize,
>
Keymap<
LAYER,
ROW,
COL,
ENCODER_COUNT,
TAP_DANCE_MAX_DEFINITIONS,
TAP_DANCE_MAX_REPEATS,
COMBO_KEY_MAX_DEFINITIONS,
COMBO_KEY_MAX_SOURCES,
>
{
pub const fn const_default() -> Self {
Self {
layers: [const { Layer::const_default() }; LAYER],
tap_dance: [const { None }; TAP_DANCE_MAX_DEFINITIONS],
combo: [const { None }; COMBO_KEY_MAX_DEFINITIONS],
}
}
pub fn get_keyaction(&self, layer: usize, row: usize, col: usize) -> Option<&KeyAction> {
if let Some(layer) = self.layers.get(layer) {
if let Some(row) = layer.keymap.get(row) {
if let Some(key) = row.get(col) {
return Some(key);
}
}
}
None
}
pub fn get_encoder_key(
&self,
mut layer_state: [bool; LAYER],
encoder: usize,
direction: EncoderDirection,
) -> Option<&KeyCode> {
layer_state[0] = true;
self.layers
.iter()
.zip(layer_state.iter())
.rev()
.filter_map(|(l, s)| if *s { Some(l) } else { None })
.find_map(|l| match direction {
EncoderDirection::Clockwise => l.encoder_keys[encoder].1.as_ref(),
EncoderDirection::CounterClockwise => l.encoder_keys[encoder].0.as_ref(),
})
}
}
#[apply(common_derive)]
pub struct Layer<const ROW: usize, const COL: usize, const ENCODER_COUNT: usize> {
#[cfg_attr(
feature = "serde",
serde(with = "serde_with::As::<[[serde_with::Same; COL]; ROW]>")
)]
pub keymap: LayerKeymap<ROW, COL>,
#[cfg_attr(
feature = "serde",
serde(with = "serde_with::As::<[serde_with::Same; ENCODER_COUNT]>")
)]
pub encoder_keys: [(Option<KeyCode>, Option<KeyCode>); ENCODER_COUNT],
pub arrow_mouse: bool,
}
impl<const ROW: usize, const COL: usize, const ENCODER_COUNT: usize>
Layer<ROW, COL, ENCODER_COUNT>
{
pub const fn const_default() -> Self {
Self {
keymap: [[KeyAction::const_default(); COL]; ROW],
encoder_keys: [(None, None); ENCODER_COUNT],
arrow_mouse: false,
}
}
}
impl<const ROW: usize, const COL: usize, const ENCODER_COUNT: usize> Default
for Layer<ROW, COL, ENCODER_COUNT>
{
fn default() -> Self {
Self::const_default()
}
}
pub type LayerKeymap<const ROW: usize, const COL: usize> = [[KeyAction; COL]; ROW];
#[apply(common_derive)]
pub struct TapDanceDefinition<const MAX_REPEATS: usize> {
#[cfg_attr(
feature = "serde",
serde(with = "serde_with::As::<[serde_with::Same; MAX_REPEATS]>")
)]
pub tap: [Option<KeyCode>; MAX_REPEATS],
#[cfg_attr(
feature = "serde",
serde(with = "serde_with::As::<[serde_with::Same; MAX_REPEATS]>")
)]
pub hold: [Option<KeyCode>; MAX_REPEATS],
}
pub type TapDanceDefinitions<const MAX_DEFINITIONS: usize, const MAX_REPEATS: usize> =
[Option<TapDanceDefinition<MAX_REPEATS>>; MAX_DEFINITIONS];
#[apply(common_derive)]
pub struct ComboDefinition<const MAX_SOURCES: usize> {
#[cfg_attr(
feature = "serde",
serde(with = "serde_with::As::<[serde_with::Same; MAX_SOURCES]>")
)]
pub src: [Option<KeyCode>; MAX_SOURCES],
pub dst: KeyCode,
}
pub type ComboDefinitions<const MAX_DEFINITIONS: usize, const MAX_SOURCES: usize> =
[Option<ComboDefinition<MAX_SOURCES>>; MAX_DEFINITIONS];