Created
August 31, 2019 16:05
-
-
Save optozorax/770d188b7a4ca22b2118092aa82782c7 to your computer and use it in GitHub Desktop.
Каждая клавиша - функция. Идея паттерна для программируемых клавиатур
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** Идея для программируемых клавиатур, когда каждая клавиша - функция. | |
В чатике много шутили, типо: давайте сделаем каждую клавишу - процессом)))000)), а давайте http-сервером)))00)). Так вот, эта идея является серьезной реализацией этих шуток, причём это даже может быть удобно. | |
*/ | |
typedef std::function<void()> Key; | |
//---------------------------------------------------------------------------- | |
// Стандартные клавиши | |
Key KC_NULL = [](){}; | |
Key KC_0 = [](){ | |
register_code(48); | |
unregister_code(48); | |
}; | |
Key KC_1 = //... | |
//... | |
//---------------------------------------------------------------------------- | |
// Модификаторы | |
Key SHIFT = [](const Key& K) -> Key { | |
return [&K](){ | |
register_code(/* shift */); | |
K(); | |
unregister_code(/* shift */); | |
}; | |
}; | |
Key CTRL = // ... | |
// ... | |
//---------------------------------------------------------------------------- | |
// Макросы | |
Key LANG = [](){ | |
CTRL(ALT(KC_NULL))(); | |
}; | |
Key THREE_DOT = [](){ | |
KC_DOT(); | |
KC_DOT(); | |
KC_DOT(); | |
}; | |
Key KLAVOGONKI_NEXT = [](){ | |
KC_TAB(); | |
KC_TAB(); | |
CTRL(KC_RIGHT)(); | |
}; | |
// ... | |
//---------------------------------------------------------------------------- | |
// Русские клавиши (даже если сейчас английский язык!) | |
int currentLayer; | |
Key PRESS_RUSSIAN = [¤tLayer](Key K){ | |
return [](){ | |
if (currentLayer != RUSSIAN) { | |
layer_on(RUSSIAN); | |
LANG(); | |
K(); | |
LANG(); | |
layer_off(RUSSIAN); | |
} else { | |
K(); | |
} | |
}; | |
}; | |
Key RU_A = PRESS_RUSSIAN(KC_F) | |
Key RU_V = [](){ | |
PRESS_RUSSIAN(KC_D)(); // или можно так | |
}; | |
// ... | |
//---------------------------------------------------------------------------- | |
const std::vector<std::vector<Key>> keymap = { | |
{KC_A, KC_B, LANG, RU_A, PRESS_RUSSIAN(SHIFT(KC_3)), RU_B} | |
}; | |
//---------------------------------------------------------------------------- | |
// Как нажать клавишу, зная её позицию? Так: | |
keymap[x][y](); | |
//---------------------------------------------------------------------------- | |
/** Плюсы и минусы: | |
+ То, как себя поведёт клавиша, определяется в месте её объявления. | |
+ Можно выражать куда более сложные вещи, чем те, что в QMK, которые используют выставление бита, например, как: PRESS_RUSSIAN. | |
- Требует много памяти и выполняется дольше, однозначно на микроконтроллере в 32кб не хватит места. | |
*/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Я забыл также, что у каждую клавишу можно не только нажать, но ещё и зажать, а от этого логика всего этого значительно меняется. Каждая клавиша теперь должна стать двумя лямбдами:
DOWN
,UP
.А вообще можно ввести ещё промежуточное состояние, когда клавиша нажата достаточно долго, и начинает отправляться автоповтор:
HOLDED
.Задавать три лямбды для одной клавиши можно через какой-нибудь конструктор, типо: