1use macro_rules_attribute::apply;
4
5use crate::{
6 interface::state::input_event::EncoderDirection,
7 keycode::{KeyAction, KeyCode},
8 macros::common_derive,
9};
10
11#[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#[apply(common_derive)]
92pub struct Layer<const ROW: usize, const COL: usize, const ENCODER_COUNT: usize> {
93 #[cfg_attr(
96 feature = "serde",
97 serde(with = "serde_with::As::<[[serde_with::Same; COL]; ROW]>")
98 )]
99 pub keymap: LayerKeymap<ROW, COL>,
100 #[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
132pub type LayerKeymap<const ROW: usize, const COL: usize> = [[KeyAction; COL]; ROW];
136
137#[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];