smart_keymap/key/composite/
tap_hold.rs

1use core::fmt::Debug;
2
3#[cfg(feature = "std")]
4use serde::Deserialize;
5
6use crate::key;
7
8use super::BaseKey;
9use super::{Context, Event, KeyState, PendingKeyState, PressedKeyResult};
10
11/// Trait for types which can be nested in [TapHoldKey] variants.
12pub trait TapHoldNestable:
13    key::Key<
14        Context = Context,
15        Event = Event,
16        KeyState = KeyState,
17        PendingKeyState = PendingKeyState,
18    > + Copy
19    + PartialEq
20{
21}
22
23impl TapHoldNestable for key::layered::ModifierKey {}
24impl TapHoldNestable for key::callback::Key {}
25impl TapHoldNestable for key::caps_word::Key {}
26impl TapHoldNestable for key::custom::Key {}
27impl TapHoldNestable for key::sticky::Key {}
28impl TapHoldNestable for key::keyboard::Key {}
29impl TapHoldNestable for BaseKey {}
30
31/// An aggregate of [key::Key] types.
32#[derive(Debug, Clone, Copy, PartialEq)]
33#[cfg_attr(feature = "std", derive(Deserialize))]
34#[cfg_attr(feature = "std", serde(untagged))]
35pub enum TapHoldKey<K: TapHoldNestable> {
36    /// A tap-dance key.
37    TapDance(key::tap_dance::Key<K>),
38    /// A tap-hold key.
39    TapHold(key::tap_hold::Key<K>),
40    /// A non-tap-hold key.
41    Pass(K),
42}
43
44/// Newtype for [TapHoldNestable] keys so they can implement [key::Key].
45#[derive(Debug, Clone, Copy, PartialEq)]
46pub struct TapHold<K: TapHoldNestable>(pub K);
47
48impl<K: TapHoldNestable> key::Key for TapHoldKey<K> {
49    type Context = Context;
50    type Event = Event;
51    type PendingKeyState = PendingKeyState;
52    type KeyState = KeyState;
53
54    fn new_pressed_key(
55        &self,
56        context: &Self::Context,
57        key_path: key::KeyPath,
58    ) -> (PressedKeyResult, key::KeyEvents<Self::Event>) {
59        match self {
60            TapHoldKey::TapDance(key) => key.new_pressed_key(context, key_path),
61            TapHoldKey::TapHold(key) => key.new_pressed_key(context, key_path),
62            TapHoldKey::Pass(key) => key.new_pressed_key(context, key_path),
63        }
64    }
65
66    fn handle_event(
67        &self,
68        pending_state: &mut Self::PendingKeyState,
69        context: &Self::Context,
70        key_path: key::KeyPath,
71        event: key::Event<Self::Event>,
72    ) -> (Option<key::NewPressedKey>, key::KeyEvents<Self::Event>) {
73        match self {
74            TapHoldKey::TapDance(key) => key.handle_event(pending_state, context, key_path, event),
75            TapHoldKey::TapHold(key) => key.handle_event(pending_state, context, key_path, event),
76            TapHoldKey::Pass(key) => key.handle_event(pending_state, context, key_path, event),
77        }
78    }
79
80    fn lookup(
81        &self,
82        path: &[u16],
83    ) -> &dyn key::Key<
84        Context = Self::Context,
85        Event = Self::Event,
86        PendingKeyState = Self::PendingKeyState,
87        KeyState = Self::KeyState,
88    > {
89        match self {
90            TapHoldKey::TapDance(key) => key.lookup(path),
91            TapHoldKey::TapHold(key) => key.lookup(path),
92            TapHoldKey::Pass(key) => key.lookup(path),
93        }
94    }
95}
96
97impl<K: TapHoldNestable> key::Key for TapHold<K> {
98    type Context = Context;
99    type Event = Event;
100    type PendingKeyState = PendingKeyState;
101    type KeyState = KeyState;
102
103    fn new_pressed_key(
104        &self,
105        context: &Self::Context,
106        key_path: key::KeyPath,
107    ) -> (PressedKeyResult, key::KeyEvents<Self::Event>) {
108        let TapHold(key) = self;
109        key.new_pressed_key(context, key_path)
110    }
111
112    fn handle_event(
113        &self,
114        pending_state: &mut Self::PendingKeyState,
115        context: &Self::Context,
116        key_path: key::KeyPath,
117        event: key::Event<Self::Event>,
118    ) -> (Option<key::NewPressedKey>, key::KeyEvents<Self::Event>) {
119        let TapHold(key) = self;
120        key.handle_event(pending_state, context, key_path, event)
121    }
122
123    fn lookup(
124        &self,
125        path: &[u16],
126    ) -> &dyn key::Key<
127        Context = Self::Context,
128        Event = Self::Event,
129        PendingKeyState = Self::PendingKeyState,
130        KeyState = Self::KeyState,
131    > {
132        let TapHold(key) = self;
133        key.lookup(path)
134    }
135}
136
137impl<K: TapHoldNestable> From<key::tap_hold::Key<K>> for TapHoldKey<K> {
138    fn from(key: key::tap_hold::Key<K>) -> Self {
139        TapHoldKey::TapHold(key)
140    }
141}
142
143impl<K: Into<BaseKey>> From<K> for TapHoldKey<BaseKey> {
144    fn from(key: K) -> Self {
145        TapHoldKey::Pass(key.into())
146    }
147}
148
149impl TapHoldKey<BaseKey> {
150    /// Constructs a [TapHoldKey] from the given [key::keyboard::Key].
151    pub const fn keyboard(key: key::keyboard::Key) -> Self {
152        Self::Pass(BaseKey::Keyboard(key))
153    }
154
155    /// Constructs a [TapHoldKey] from the given [key::tap_hold::Key].
156    pub const fn tap_hold(key: key::tap_hold::Key<BaseKey>) -> Self {
157        Self::TapHold(key)
158    }
159
160    /// Constructs a [TapHoldKey] from the given [key::layered::ModifierKey].
161    pub const fn layer_modifier(key: key::layered::ModifierKey) -> Self {
162        Self::Pass(BaseKey::LayerModifier(key))
163    }
164}
165
166impl TapHold<key::keyboard::Key> {
167    /// Constructs a [TapHold] newtype from the given key.
168    pub const fn keyboard(key: key::keyboard::Key) -> Self {
169        Self(key)
170    }
171}
172
173impl TapHold<key::layered::ModifierKey> {
174    /// Constructs a [TapHold] newtypefrom the given key.
175    pub const fn layer_modifier(key: key::layered::ModifierKey) -> Self {
176        Self(key)
177    }
178}
179
180impl TapHold<BaseKey> {
181    /// Constructs a [TapHold] newtype from the given key.
182    pub const fn base_key(key: BaseKey) -> Self {
183        Self(key)
184    }
185}