Skip to main content
RKTK API Docs RKTK Home Repo

kmsm/
keymap.rs

1//! Keymap related types
2
3use macro_rules_attribute::apply;
4
5use crate::{
6    interface::state::input_event::EncoderDirection,
7    keycode::{KeyAction, KeyCode},
8    macros::common_derive,
9};
10
11/// Root keymap type
12///
13/// This structure holds all information about keymap.
14#[derive(Clone)]
15pub struct Keymap<
16    const LAYER: usize,
17    const ROW: usize,
18    const COL: usize,
19    const ENCODER_COUNT: usize,
20    const TAP_DANCE_MAX_DEFINITIONS: usize,
21    const TAP_DANCE_MAX_REPEATS: usize,
22    const COMBO_KEY_MAX_DEFINITIONS: usize,
23    const COMBO_KEY_MAX_SOURCES: usize,
24> {
25    pub layers: [Layer<ROW, COL, ENCODER_COUNT>; LAYER],
26    pub tap_dance: TapDanceDefinitions<TAP_DANCE_MAX_DEFINITIONS, TAP_DANCE_MAX_REPEATS>,
27    pub combo: ComboDefinitions<COMBO_KEY_MAX_DEFINITIONS, COMBO_KEY_MAX_SOURCES>,
28}
29
30impl<
31    const LAYER: usize,
32    const ROW: usize,
33    const COL: usize,
34    const ENCODER_COUNT: usize,
35    const TAP_DANCE_MAX_DEFINITIONS: usize,
36    const TAP_DANCE_MAX_REPEATS: usize,
37    const COMBO_KEY_MAX_DEFINITIONS: usize,
38    const COMBO_KEY_MAX_SOURCES: usize,
39>
40    Keymap<
41        LAYER,
42        ROW,
43        COL,
44        ENCODER_COUNT,
45        TAP_DANCE_MAX_DEFINITIONS,
46        TAP_DANCE_MAX_REPEATS,
47        COMBO_KEY_MAX_DEFINITIONS,
48        COMBO_KEY_MAX_SOURCES,
49    >
50{
51    pub const fn const_default() -> Self {
52        Self {
53            layers: [const { Layer::const_default() }; LAYER],
54            tap_dance: [const { None }; TAP_DANCE_MAX_DEFINITIONS],
55            combo: [const { None }; COMBO_KEY_MAX_DEFINITIONS],
56        }
57    }
58
59    pub fn get_keyaction(&self, layer: usize, row: usize, col: usize) -> Option<&KeyAction> {
60        if let Some(layer) = self.layers.get(layer)
61            && let Some(row) = layer.keymap.get(row)
62            && let Some(key) = row.get(col)
63        {
64            return Some(key);
65        }
66        None
67    }
68
69    pub fn get_encoder_key(
70        &self,
71        mut layer_state: [bool; LAYER],
72        encoder: usize,
73        direction: EncoderDirection,
74    ) -> Option<&KeyCode> {
75        layer_state[0] = true;
76        self.layers
77            .iter()
78            .zip(layer_state.iter())
79            .rev()
80            .filter_map(|(l, s)| if *s { Some(l) } else { None })
81            .find_map(|l| match direction {
82                EncoderDirection::Clockwise => l.encoder_keys[encoder].1.as_ref(),
83                EncoderDirection::CounterClockwise => l.encoder_keys[encoder].0.as_ref(),
84            })
85    }
86}
87
88/// Layer definition
89///
90/// This structure holds information about layer. This contains keymap and arrowmouse flag.
91#[apply(common_derive)]
92pub struct Layer<const ROW: usize, const COL: usize, const ENCODER_COUNT: usize> {
93    // NOTE: This is workaround for issue that serde_as cannot be used with cfg-attr.
94    // ref: https://github.com/jonasbb/serde_with/issues/355
95    #[cfg_attr(
96        feature = "serde",
97        serde(with = "serde_with::As::<[[serde_with::Same; COL]; ROW]>")
98    )]
99    pub keymap: LayerKeymap<ROW, COL>,
100    /// Keycode assigned to each encoder.
101    ///
102    /// Left of tuple is for counter clockwise, right of tuple is for clockwise.
103    /// None has special meaning that it is not assigned and inherits keycode from previous layer.
104    #[cfg_attr(
105        feature = "serde",
106        serde(with = "serde_with::As::<[serde_with::Same; ENCODER_COUNT]>")
107    )]
108    pub encoder_keys: [(Option<KeyCode>, Option<KeyCode>); ENCODER_COUNT],
109    pub arrow_mouse: bool,
110}
111
112impl<const ROW: usize, const COL: usize, const ENCODER_COUNT: usize>
113    Layer<ROW, COL, ENCODER_COUNT>
114{
115    pub const fn const_default() -> Self {
116        Self {
117            keymap: [[KeyAction::const_default(); COL]; ROW],
118            encoder_keys: [(None, None); ENCODER_COUNT],
119            arrow_mouse: false,
120        }
121    }
122}
123
124impl<const ROW: usize, const COL: usize, const ENCODER_COUNT: usize> Default
125    for Layer<ROW, COL, ENCODER_COUNT>
126{
127    fn default() -> Self {
128        Self::const_default()
129    }
130}
131
132/// Keymap of single layer
133///
134/// Type that represents keymap for each layer.
135pub type LayerKeymap<const ROW: usize, const COL: usize> = [[KeyAction; COL]; ROW];
136
137/// Tap dance definition
138#[apply(common_derive)]
139pub struct TapDanceDefinition<const MAX_REPEATS: usize> {
140    #[cfg_attr(
141        feature = "serde",
142        serde(with = "serde_with::As::<[serde_with::Same; MAX_REPEATS]>")
143    )]
144    pub tap: [Option<KeyCode>; MAX_REPEATS],
145
146    #[cfg_attr(
147        feature = "serde",
148        serde(with = "serde_with::As::<[serde_with::Same; MAX_REPEATS]>")
149    )]
150    pub hold: [Option<KeyCode>; MAX_REPEATS],
151}
152
153pub type TapDanceDefinitions<const MAX_DEFINITIONS: usize, const MAX_REPEATS: usize> =
154    [Option<TapDanceDefinition<MAX_REPEATS>>; MAX_DEFINITIONS];
155
156#[apply(common_derive)]
157pub struct ComboDefinition<const MAX_SOURCES: usize> {
158    #[cfg_attr(
159        feature = "serde",
160        serde(with = "serde_with::As::<[serde_with::Same; MAX_SOURCES]>")
161    )]
162    pub src: [Option<KeyCode>; MAX_SOURCES],
163    pub dst: KeyCode,
164}
165pub type ComboDefinitions<const MAX_DEFINITIONS: usize, const MAX_SOURCES: usize> =
166    [Option<ComboDefinition<MAX_SOURCES>>; MAX_DEFINITIONS];