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                    return Some(key);
64                }
65        None
66    }
67
68    pub fn get_encoder_key(
69        &self,
70        mut layer_state: [bool; LAYER],
71        encoder: usize,
72        direction: EncoderDirection,
73    ) -> Option<&KeyCode> {
74        layer_state[0] = true;
75        self.layers
76            .iter()
77            .zip(layer_state.iter())
78            .rev()
79            .filter_map(|(l, s)| if *s { Some(l) } else { None })
80            .find_map(|l| match direction {
81                EncoderDirection::Clockwise => l.encoder_keys[encoder].1.as_ref(),
82                EncoderDirection::CounterClockwise => l.encoder_keys[encoder].0.as_ref(),
83            })
84    }
85}
86
87/// Layer definition
88///
89/// This structure holds information about layer. This contains keymap and arrowmouse flag.
90#[apply(common_derive)]
91pub struct Layer<const ROW: usize, const COL: usize, const ENCODER_COUNT: usize> {
92    // NOTE: This is workaround for issue that serde_as cannot be used with cfg-attr.
93    // ref: https://github.com/jonasbb/serde_with/issues/355
94    #[cfg_attr(
95        feature = "serde",
96        serde(with = "serde_with::As::<[[serde_with::Same; COL]; ROW]>")
97    )]
98    pub keymap: LayerKeymap<ROW, COL>,
99    /// Keycode assigned to each encoder.
100    ///
101    /// Left of tuple is for counter clockwise, right of tuple is for clockwise.
102    /// None has special meaning that it is not assigned and inherits keycode from previous layer.
103    #[cfg_attr(
104        feature = "serde",
105        serde(with = "serde_with::As::<[serde_with::Same; ENCODER_COUNT]>")
106    )]
107    pub encoder_keys: [(Option<KeyCode>, Option<KeyCode>); ENCODER_COUNT],
108    pub arrow_mouse: bool,
109}
110
111impl<const ROW: usize, const COL: usize, const ENCODER_COUNT: usize>
112    Layer<ROW, COL, ENCODER_COUNT>
113{
114    pub const fn const_default() -> Self {
115        Self {
116            keymap: [[KeyAction::const_default(); COL]; ROW],
117            encoder_keys: [(None, None); ENCODER_COUNT],
118            arrow_mouse: false,
119        }
120    }
121}
122
123impl<const ROW: usize, const COL: usize, const ENCODER_COUNT: usize> Default
124    for Layer<ROW, COL, ENCODER_COUNT>
125{
126    fn default() -> Self {
127        Self::const_default()
128    }
129}
130
131/// Keymap of single layer
132///
133/// Type that represents keymap for each layer.
134pub type LayerKeymap<const ROW: usize, const COL: usize> = [[KeyAction; COL]; ROW];
135
136/// Tap dance definition
137#[apply(common_derive)]
138pub struct TapDanceDefinition<const MAX_REPEATS: usize> {
139    #[cfg_attr(
140        feature = "serde",
141        serde(with = "serde_with::As::<[serde_with::Same; MAX_REPEATS]>")
142    )]
143    pub tap: [Option<KeyCode>; MAX_REPEATS],
144
145    #[cfg_attr(
146        feature = "serde",
147        serde(with = "serde_with::As::<[serde_with::Same; MAX_REPEATS]>")
148    )]
149    pub hold: [Option<KeyCode>; MAX_REPEATS],
150}
151
152pub type TapDanceDefinitions<const MAX_DEFINITIONS: usize, const MAX_REPEATS: usize> =
153    [Option<TapDanceDefinition<MAX_REPEATS>>; MAX_DEFINITIONS];
154
155#[apply(common_derive)]
156pub struct ComboDefinition<const MAX_SOURCES: usize> {
157    #[cfg_attr(
158        feature = "serde",
159        serde(with = "serde_with::As::<[serde_with::Same; MAX_SOURCES]>")
160    )]
161    pub src: [Option<KeyCode>; MAX_SOURCES],
162    pub dst: KeyCode,
163}
164pub type ComboDefinitions<const MAX_DEFINITIONS: usize, const MAX_SOURCES: usize> =
165    [Option<ComboDefinition<MAX_SOURCES>>; MAX_DEFINITIONS];