RKTK API Docs RKTK Home Repo

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