smart_keymap/key/
caps_word.rs1#![doc = include_str!("doc_de_caps_word.md")]
2
3use serde::Deserialize;
4
5use crate::input;
6use crate::key;
7use crate::keymap;
8
9#[derive(Debug, Clone, Copy)]
11pub struct Context {
12 is_active: bool,
13}
14
15pub const DEFAULT_CONTEXT: Context = Context { is_active: false };
17
18impl Context {
19 pub fn handle_event<E>(&mut self, event: key::Event<E>) -> key::KeyEvents<E>
21 where
22 Event: TryFrom<E>,
23 E: core::fmt::Debug + core::marker::Copy,
24 {
25 match event {
26 key::Event::Keymap(keymap::KeymapEvent::ResolvedKeyOutput {
27 key_output:
28 key::KeyOutput {
29 key_code: key::KeyUsage::Keyboard(key_code),
30 key_modifiers,
31 },
32 ..
33 }) if self.is_active => {
34 let is_shifted = key_modifiers.has_modifiers(
40 &key::KeyboardModifiers::LEFT_SHIFT.union(&key::KeyboardModifiers::RIGHT_SHIFT),
41 );
42 let exit_caps_word = match key_code {
43 0x04..=0x1D => false, 0x1E..=0x27 if !is_shifted => false, 0x2A => false, 0x2D => false, 0x4C => false, 0xE1 => false, 0xE5 => false, 0x00 => false, _ => true,
52 };
53
54 if exit_caps_word {
55 self.is_active = false;
56
57 let key_code = 0xE1;
58 let vk_ev = input::Event::VirtualKeyRelease {
59 key_output: key::KeyOutput::from_key_code(key_code),
60 };
61 key::KeyEvents::event(key::Event::Input(vk_ev))
62 } else {
63 key::KeyEvents::no_events()
64 }
65 }
66 key::Event::Key { key_event, .. } => {
67 if let Ok(ev) = key_event.try_into() {
68 match ev {
69 Event::EnableCapsWord => {
70 self.is_active = true;
71
72 let key_code = 0xE1;
73 let vk_ev = input::Event::VirtualKeyPress {
74 key_output: key::KeyOutput::from_key_code(key_code),
75 };
76 key::KeyEvents::event(key::Event::Input(vk_ev))
77 }
78 Event::DisableCapsWord => {
79 self.is_active = false;
80
81 let key_code = 0xE1;
82 let vk_ev = input::Event::VirtualKeyRelease {
83 key_output: key::KeyOutput::from_key_code(key_code),
84 };
85 key::KeyEvents::event(key::Event::Input(vk_ev))
86 }
87 }
88 } else {
89 key::KeyEvents::no_events()
90 }
91 }
92 _ => key::KeyEvents::no_events(),
93 }
94 }
95}
96
97#[derive(Debug, Clone, Copy, PartialEq)]
99pub enum Event {
100 EnableCapsWord,
102 DisableCapsWord,
104}
105
106#[derive(Deserialize, Debug, Clone, Copy, PartialEq)]
108pub enum Key {
109 ToggleCapsWord,
111}
112
113impl Key {
114 pub const fn new() -> Self {
116 Key::ToggleCapsWord
117 }
118
119 pub fn new_pressed_key(&self, context: &Context, keymap_index: u16) -> key::KeyEvents<Event> {
121 let key_event = match self {
122 Key::ToggleCapsWord => {
123 if context.is_active {
124 Event::DisableCapsWord
125 } else {
126 Event::EnableCapsWord
127 }
128 }
129 };
130 key::KeyEvents::event(key::Event::key_event(keymap_index, key_event))
131 }
132}
133
134impl key::Key for Key {
135 type Context = crate::init::Context;
136 type Event = crate::init::Event;
137 type PendingKeyState = crate::init::PendingKeyState;
138 type KeyState = crate::init::KeyState;
139
140 fn new_pressed_key(
141 &self,
142 context: &Self::Context,
143 key_path: key::KeyPath,
144 ) -> (
145 key::PressedKeyResult<Self::PendingKeyState, Self::KeyState>,
146 key::KeyEvents<Self::Event>,
147 ) {
148 let caps_word_context = context.into();
149 let keymap_index: u16 = key_path[0];
150 let pke = self.new_pressed_key(caps_word_context, keymap_index);
151 let pks = key::PressedKeyResult::Resolved(key::NoOpKeyState::new().into());
152 (pks, pke.into_events())
153 }
154
155 fn handle_event(
156 &self,
157 _pending_state: &mut Self::PendingKeyState,
158 _context: &Self::Context,
159 _key_path: key::KeyPath,
160 _event: key::Event<Self::Event>,
161 ) -> (
162 Option<key::PressedKeyResult<Self::PendingKeyState, Self::KeyState>>,
163 key::KeyEvents<Self::Event>,
164 ) {
165 panic!()
166 }
167
168 fn lookup(
169 &self,
170 _path: &[u16],
171 ) -> &dyn key::Key<
172 Context = Self::Context,
173 Event = Self::Event,
174 PendingKeyState = Self::PendingKeyState,
175 KeyState = Self::KeyState,
176 > {
177 self
178 }
179}