Kaleidoscope Style Guide conformance

...and an update to use the newest Ranges APIs.

Signed-off-by: Gergely Nagy <algernon@madhouse-project.org>
pull/389/head
Gergely Nagy 8 years ago
parent a6983c5c4d
commit 8be191fe9b

@ -5,9 +5,9 @@
[travis:image]: https://travis-ci.org/keyboardio/Kaleidoscope-TapDance.svg?branch=master
[travis:status]: https://travis-ci.org/keyboardio/Kaleidoscope-TapDance
[st:stable]: https://img.shields.io/badge/stable-✔-black.png?style=flat&colorA=44cc11&colorB=494e52
[st:broken]: https://img.shields.io/badge/broken-X-black.png?style=flat&colorA=e05d44&colorB=494e52
[st:experimental]: https://img.shields.io/badge/experimental----black.png?style=flat&colorA=dfb317&colorB=494e52
[st:stable]: https://img.shields.io/badge/stable-✔-black.svg?style=flat&colorA=44cc11&colorB=494e52
[st:broken]: https://img.shields.io/badge/broken-X-black.svg?style=flat&colorA=e05d44&colorB=494e52
[st:experimental]: https://img.shields.io/badge/experimental----black.svg?style=flat&colorA=dfb317&colorB=494e52
Tap-dance keys are general purpose, multi-use keys, which trigger a different
action based on the number of times they were tapped in sequence. As an example
@ -44,21 +44,20 @@ This is to preserve the order of keys pressed.
In both of these cases, the [`tapDanceAction`][tdaction] will be called, with
`tapDanceIndex` set to the index of the tap-dance action (as set in the keymap),
the `tapCount`, and `tapDanceAction` set to either
`KaleidoscopePlugins::TapDance::Interrupt`, or
`KaleidoscopePlugins::TapDance::Timeout`. If we continue holding the key, then
as long as it is held, the same function will be called with `tapDanceAction`
set to `KaleidoscopePlugins::TapDance::Hold`. When the key is released, after
either an `Interrupt` or `Timeout` action was triggered, the function will be
called with `tapDanceAction` set to `KaleidoscopePlugins::TapDance::Release`.
`kaleidoscope::TapDance::Interrupt`, or `kaleidoscope::TapDance::Timeout`. If we
continue holding the key, then as long as it is held, the same function will be
called with `tapDanceAction` set to `kaleidoscope::TapDance::Hold`. When the key
is released, after either an `Interrupt` or `Timeout` action was triggered, the
function will be called with `tapDanceAction` set to
`kaleidoscope::TapDance::Release`.
These actions allow us to create sophisticated tap-dance setups, where one can
tap a key twice and hold it, and have it repeat, for example.
There is one additional value the `tapDanceAction` parameter can take:
`KaleidoscopePlugins::TapDance::Tap`. It is called with this argument for each
and every tap, even if no action is to be triggered yet. This is so that we can
have a way to do some side-effects, like light up LEDs to show progress, and so
on.
`kaleidoscope::TapDance::Tap`. It is called with this argument for each and
every tap, even if no action is to be triggered yet. This is so that we can have
a way to do some side-effects, like light up LEDs to show progress, and so on.
## Using the plugin
@ -75,18 +74,19 @@ time an action is to be performed.
TD(0)
// later in the Sketch:
void tapDanceAction (uint8_t tapDanceIndex, uint8_t tapCount,
KaleidoscopePlugins::TapDance::ActionType tapDanceAction) {
switch (tapDanceIndex) {
void tapDanceAction(uint8_t tap_dance_index, uint8_t tap_count,
kaleidoscope::TapDance::ActionType tap_dance_action) {
switch (tap_dance_index) {
case 0:
return tapDanceActionKeys (tapCount, tapDanceAction,
Key_nextTrack, Key_prevTrack);
return tapDanceActionKeys(tap_count, tap_dance_action,
Consumer_ScanNextTrack, Consumer_ScanPreviousTrack);
}
}
void setup (void) {
Kaleidoscope.setup (KEYMAP_SIZE);
Kaleidoscope.use (&TapDance, NULL);
void setup() {
USE_PLUGINS(&TapDance);
Kaleidoscope.setup ();
}
```
@ -98,8 +98,8 @@ void setup (void) {
> implementation for the `id` index within the [`tapDanceActions`][tdactions]
> function.
>
> The `id` parameter here is what will be used as `tapDanceIndex` in the handler
> function.
> The `id` parameter here is what will be used as `tap_dance_index` in the
> handler function.
[tdaction]: #tapdanceactiontapdanceindex-tapcount-tapdanceaction
@ -109,17 +109,15 @@ The plugin provides a `TapDance` object, but to implement the actions, we need
to define a function ([`tapDanceAction`][tdaction]) outside of the object. A
handler, of sorts. Nevertheless, the plugin provides one macro that is
particularly useful: `tapDanceActionKeys`. Apart from that, it provides one
method only:
property only:
### `.timeOut`
### `.time_out`
> The number of loop iterations to wait before a tap-dance sequence times out.
> Once the sequence timed out, the action for it will trigger, even without an
> interruptor. Defaults to 5, and the timer resets with every tap of the same
> Not strictly a method, it is a variable one can assign a new value to.
### `tapDanceActionKeys(tapCount, tapDanceAction, keys...)`
### `tapDanceActionKeys(tap_count, tap_dance_action, keys...)`
> Sets up an action where for each subsequent tap, a different key will be
> chosen from the list of keys supplied in the `keys...` argument.
@ -130,19 +128,19 @@ method only:
> When all our actions are just different keys, this is a very handy macro to
> use.
>
> The `tapCount` and `tapDanceActions` parameters should be the same as the
> The `tap_count` and `tap_dance_actions` parameters should be the same as the
> similarly named parameters of the `tapDanceAction` function.
### `tapDanceAction(tapDanceIndex, row, col, tapCount, tapDanceAction)`
### `tapDanceAction(tap_dance_index, row, col, tap_count, tap_dance_action)`
> The heart of the tap-dance plugin is the handler method. This is called every
> time any kind of tap-dance action is to be performed. See the
> *[How does it work?](#how-does-it-work)* section for details about when and
> how this function is called.
>
> The `tapDanceIndex` and `tapCount` parameters help us choose which action to
> perform. The `row` and `col` parameters tell us where the tap-dance key is on
> the keyboard.
> The `tap_dance_index` and `tap_count` parameters help us choose which action
> to perform. The `row` and `col` parameters tell us where the tap-dance key is
> on the keyboard.
## Dependencies

@ -36,26 +36,26 @@ const Key keymaps[][ROWS][COLS] PROGMEM = {
Key_skip, Key_N, Key_M, Key_Comma, Key_Period, Key_Slash, Key_Minus,
Key_RightShift, Key_RightAlt, Key_Spacebar, Key_RightControl,
TD(1)
),
TD(1)),
};
static void tapDanceEsc(uint8_t tapDanceIndex, uint8_t tapCount, KaleidoscopePlugins::TapDance::ActionType tapDanceAction) {
tapDanceActionKeys(tapCount, tapDanceAction, Key_Escape, Key_Tab);
static void tapDanceEsc(uint8_t tap_dance_index, uint8_t tap_count, kaleidoscope::TapDance::ActionType tap_dance_action) {
tap_dance_actionKeys(tap_count, tap_dance_action, Key_Escape, Key_Tab);
}
void tapDanceAction(uint8_t tapDanceIndex, byte row, byte col, uint8_t tapCount, KaleidoscopePlugins::TapDance::ActionType tapDanceAction) {
switch (tapDanceIndex) {
void tap_dance_action(uint8_t tap_dance_index, byte row, byte col, uint8_t tap_count, kaleidoscope::TapDance::ActionType tap_dance_action) {
switch (tap_dance_index) {
case 0:
return tapDanceActionKeys(tapCount, tapDanceAction, Key_Tab, Key_Escape);
return tap_dance_actionKeys(tap_count, tap_dance_action, Key_Tab, Key_Escape);
case 1:
return tapDanceEsc(tapDanceIndex, tapCount, tapDanceAction);
return tapDanceEsc(tap_dance_index, tap_count, tap_dance_action);
}
}
void setup() {
Kaleidoscope.setup(KEYMAP_SIZE);
Kaleidoscope.use(&TapDance, NULL);
USE_PLUGINS(&TapDance);
Kaleidoscope.setup();
}
void loop() {

@ -18,76 +18,73 @@
#include <Kaleidoscope-TapDance.h>
namespace KaleidoscopePlugins {
namespace kaleidoscope {
// --- state ---
uint32_t TapDance::endTime;
uint16_t TapDance::timeOut = 200;
uint8_t TapDance::tapCount[16];
uint16_t TapDance::pressedState;
uint16_t TapDance::triggeredState;
uint16_t TapDance::releaseNextState;
Key TapDance::lastTapDanceKey;
byte TapDance::lastTapDanceRow;
byte TapDance::lastTapDanceCol;
uint32_t TapDance::end_time_;
uint16_t TapDance::time_out = 200;
uint8_t TapDance::tap_count_[16];
uint16_t TapDance::pressed_state_;
uint16_t TapDance::triggered_state_;
uint16_t TapDance::release_next_state_;
Key TapDance::last_tap_dance_key_;
byte TapDance::last_tap_dance_row_;
byte TapDance::last_tap_dance_col_;
// --- helpers ---
#define isTapDance(k) (k.raw >= Ranges::TD_FIRST && k.raw <= Ranges::TD_LAST)
#define isInSeq(k) (lastTapDanceKey.raw == k.raw)
#define stillHeld(idx) (tapCount[idx])
#define isActive() (lastTapDanceKey.raw != Key_NoKey.raw)
#define isTapDance(k) (k.raw >= ranges::TD_FIRST && k.raw <= ranges::TD_LAST)
#define isInSeq(k) (last_tap_dance_key_.raw == k.raw)
#define stillHeld(idx) (tap_count_[idx])
#define isActive() (last_tap_dance_key_.raw != Key_NoKey.raw)
// --- actions ---
void
TapDance::interrupt(void) {
uint8_t idx = lastTapDanceKey.raw - Ranges::TD_FIRST;
void TapDance::interrupt(void) {
uint8_t idx = last_tap_dance_key_.raw - ranges::TD_FIRST;
tapDanceAction(idx, lastTapDanceRow, lastTapDanceCol, tapCount[idx], Interrupt);
bitWrite(triggeredState, idx, 1);
tapDanceAction(idx, last_tap_dance_row_, last_tap_dance_col_, tap_count_[idx], Interrupt);
bitWrite(triggered_state_, idx, 1);
endTime = 0;
end_time_ = 0;
if (bitRead(pressedState, idx))
if (bitRead(pressed_state_, idx))
return;
release(idx);
}
void
TapDance::timeout(void) {
uint8_t idx = lastTapDanceKey.raw - Ranges::TD_FIRST;
void TapDance::timeout(void) {
uint8_t idx = last_tap_dance_key_.raw - ranges::TD_FIRST;
tapDanceAction(idx, lastTapDanceRow, lastTapDanceCol, tapCount[idx], Timeout);
bitWrite(triggeredState, idx, 1);
tapDanceAction(idx, last_tap_dance_row_, last_tap_dance_col_, tap_count_[idx], Timeout);
bitWrite(triggered_state_, idx, 1);
if (bitRead(pressedState, idx))
if (bitRead(pressed_state_, idx))
return;
lastTapDanceKey.raw = Key_NoKey.raw;
last_tap_dance_key_.raw = Key_NoKey.raw;
release(idx);
}
Key
TapDance::release(uint8_t tapDanceIndex) {
endTime = 0;
lastTapDanceKey.raw = Key_NoKey.raw;
Key TapDance::release(uint8_t tap_dance_index) {
end_time_ = 0;
last_tap_dance_key_.raw = Key_NoKey.raw;
bitClear(pressedState, tapDanceIndex);
bitClear(triggeredState, tapDanceIndex);
bitWrite(releaseNextState, tapDanceIndex, 1);
bitClear(pressed_state_, tap_dance_index);
bitClear(triggered_state_, tap_dance_index);
bitWrite(release_next_state_, tap_dance_index, 1);
return Key_NoKey;
}
Key
TapDance::tap(void) {
uint8_t idx = lastTapDanceKey.raw - Ranges::TD_FIRST;
Key TapDance::tap(void) {
uint8_t idx = last_tap_dance_key_.raw - ranges::TD_FIRST;
tapCount[idx]++;
endTime = millis() + timeOut;
tap_count_[idx]++;
end_time_ = millis() + time_out;
tapDanceAction(idx, lastTapDanceRow, lastTapDanceCol, tapCount[idx], Tap);
tapDanceAction(idx, last_tap_dance_row_, last_tap_dance_col_, tap_count_[idx], Tap);
return Key_NoKey;
}
@ -95,86 +92,82 @@ TapDance::tap(void) {
// --- api ---
TapDance::TapDance(void) {
lastTapDanceKey.raw = Key_NoKey.raw;
}
void
TapDance::begin(void) {
event_handler_hook_use(this->eventHandlerHook);
loop_hook_use(this->loopHook);
void TapDance::begin(void) {
event_handler_hook_use(eventHandlerHook);
loop_hook_use(loopHook);
}
void
TapDance::actionKeys(uint8_t tapCount, ActionType tapDanceAction, uint8_t maxKeys, const Key tapKeys[]) {
if (tapCount > maxKeys)
tapCount = maxKeys;
void TapDance::actionKeys(uint8_t tap_count, ActionType tap_dance_action, uint8_t max_keys, const Key tap_keys[]) {
if (tap_count > max_keys)
tap_count = max_keys;
Key key;
key.raw = pgm_read_word(&(tapKeys[tapCount - 1].raw));
key.raw = pgm_read_word(&(tap_keys[tap_count - 1].raw));
switch (tapDanceAction) {
switch (tap_dance_action) {
case Tap:
break;
case Interrupt:
case Timeout:
handle_keyswitch_event(key, lastTapDanceRow, lastTapDanceCol, IS_PRESSED | INJECTED);
handle_keyswitch_event(key, last_tap_dance_row_, last_tap_dance_col_, IS_PRESSED | INJECTED);
break;
case Hold:
handle_keyswitch_event(key, lastTapDanceRow, lastTapDanceCol, IS_PRESSED | WAS_PRESSED | INJECTED);
handle_keyswitch_event(key, last_tap_dance_row_, last_tap_dance_col_, IS_PRESSED | WAS_PRESSED | INJECTED);
break;
case Release:
Keyboard.sendReport();
handle_keyswitch_event(key, lastTapDanceRow, lastTapDanceCol, WAS_PRESSED | INJECTED);
handle_keyswitch_event(key, last_tap_dance_row_, last_tap_dance_col_, WAS_PRESSED | INJECTED);
break;
}
}
// --- hooks ---
Key
TapDance::eventHandlerHook(Key mappedKey, byte row, byte col, uint8_t keyState) {
if (keyState & INJECTED)
return mappedKey;
Key TapDance::eventHandlerHook(Key mapped_key, byte row, byte col, uint8_t key_state) {
if (key_state & INJECTED)
return mapped_key;
if (!key_is_pressed(keyState) && !key_was_pressed(keyState)) {
if (isTapDance(mappedKey))
if (!key_is_pressed(key_state) && !key_was_pressed(key_state)) {
if (isTapDance(mapped_key))
return Key_NoKey;
return mappedKey;
return mapped_key;
}
if (!isTapDance(mappedKey)) {
if (!isTapDance(mapped_key)) {
if (!isActive())
return mappedKey;
return mapped_key;
if (key_toggled_on(keyState))
if (key_toggled_on(key_state))
interrupt();
return mappedKey;
return mapped_key;
}
uint8_t tapDanceIndex = mappedKey.raw - Ranges::TD_FIRST;
uint8_t tap_dance_index = mapped_key.raw - ranges::TD_FIRST;
if (key_toggled_off(keyState))
bitClear(pressedState, tapDanceIndex);
if (key_toggled_off(key_state))
bitClear(pressed_state_, tap_dance_index);
if (!isInSeq(mappedKey)) {
if (!isInSeq(mapped_key)) {
if (!isActive()) {
if (bitRead(triggeredState, tapDanceIndex)) {
if (key_toggled_off(keyState))
return release(tapDanceIndex);
if (bitRead(triggered_state_, tap_dance_index)) {
if (key_toggled_off(key_state))
return release(tap_dance_index);
return Key_NoKey;
}
lastTapDanceKey.raw = mappedKey.raw;
lastTapDanceRow = row;
lastTapDanceCol = col;
last_tap_dance_key_.raw = mapped_key.raw;
last_tap_dance_row_ = row;
last_tap_dance_col_ = col;
return tap();
} else {
if (key_toggled_off(keyState) && stillHeld(tapDanceIndex)) {
return release(tapDanceIndex);
if (key_toggled_off(key_state) && stillHeld(tap_dance_index)) {
return release(tap_dance_index);
}
if (!key_toggled_on(keyState))
if (!key_toggled_on(key_state))
return Key_NoKey;
interrupt();
@ -183,48 +176,48 @@ TapDance::eventHandlerHook(Key mappedKey, byte row, byte col, uint8_t keyState)
// in sequence
if (key_toggled_off(keyState))
if (key_toggled_off(key_state))
return Key_NoKey;
lastTapDanceKey.raw = mappedKey.raw;
lastTapDanceRow = row;
lastTapDanceCol = col;
bitSet(pressedState, tapDanceIndex);
last_tap_dance_key_.raw = mapped_key.raw;
last_tap_dance_row_ = row;
last_tap_dance_col_ = col;
bitSet(pressed_state_, tap_dance_index);
if (key_toggled_on(keyState))
if (key_toggled_on(key_state))
return tap();
if (bitRead(triggeredState, tapDanceIndex))
tapDanceAction(tapDanceIndex, row, col, tapCount[tapDanceIndex], Hold);
if (bitRead(triggered_state_, tap_dance_index))
tapDanceAction(tap_dance_index, row, col, tap_count_[tap_dance_index], Hold);
return Key_NoKey;
}
void
TapDance::loopHook(bool postClear) {
if (!postClear)
TapDance::loopHook(bool is_post_clear) {
if (!is_post_clear)
return;
for (uint8_t i = 0; i < 16; i++) {
if (!bitRead(releaseNextState, i))
if (!bitRead(release_next_state_, i))
continue;
tapDanceAction(i, lastTapDanceRow, lastTapDanceCol, tapCount[i], Release);
tapCount[i] = 0;
bitClear(releaseNextState, i);
tapDanceAction(i, last_tap_dance_row_, last_tap_dance_col_, tap_count_[i], Release);
tap_count_[i] = 0;
bitClear(release_next_state_, i);
}
if (!isActive())
return;
if (endTime && millis() > endTime)
if (end_time_ && millis() > end_time_)
timeout();
}
} // namespace KaleidoscopePlugins
__attribute__((weak))
void
tapDanceAction(uint8_t tapDanceIndex, byte row, byte col, uint8_t tapCount, KaleidoscopePlugins::TapDance::ActionType tapDanceAction) {
}
KaleidoscopePlugins::TapDance TapDance;
__attribute__((weak)) void tapDanceAction(uint8_t tap_dance_index, byte row, byte col, uint8_t tap_count,
kaleidoscope::TapDance::ActionType tap_dance_action) {
}
kaleidoscope::TapDance TapDance;

@ -21,15 +21,15 @@
#include <Kaleidoscope.h>
#include <Kaleidoscope-Ranges.h>
#define TD(n) (Key){.raw = KaleidoscopePlugins::Ranges::TD_FIRST + n }
#define TD(n) (Key) {.raw = kaleidoscope::ranges::TD_FIRST + n }
#define tapDanceActionKeys(tapCount, tapDanceAction, ...) ({ \
#define tap_dance_actionKeys(tap_count, tap_dance_action, ...) ({ \
static const Key __k[] PROGMEM = { __VA_ARGS__ }; \
TapDance.actionKeys (tapCount, tapDanceAction, \
TapDance.actionKeys(tap_count, tap_dance_action, \
sizeof (__k) / sizeof (Key), &__k[0]); \
})
namespace KaleidoscopePlugins {
namespace kaleidoscope {
class TapDance : public KaleidoscopePlugin {
public:
typedef enum {
@ -43,30 +43,32 @@ class TapDance : public KaleidoscopePlugin {
TapDance(void);
void begin(void) final;
static uint16_t timeOut;
static uint16_t time_out;
void actionKeys(uint8_t tapCount, ActionType tapDanceAction, uint8_t maxKeys, const Key tapKeys[]);
void actionKeys(uint8_t tap_count, ActionType tap_dance_action, uint8_t max_keys, const Key tap_keys[]);
private:
static uint32_t endTime;
static uint8_t tapCount[16];
static uint16_t pressedState;
static uint16_t triggeredState;
static uint16_t releaseNextState;
static Key lastTapDanceKey;
static byte lastTapDanceRow;
static byte lastTapDanceCol;
static uint32_t end_time_;
static uint8_t tap_count_[16];
static uint16_t pressed_state_;
static uint16_t triggered_state_;
static uint16_t release_next_state_;
static Key last_tap_dance_key_;
static byte last_tap_dance_row_;
static byte last_tap_dance_col_;
static Key eventHandlerHook(Key mappedKey, byte row, byte col, uint8_t keyState);
static void loopHook(bool postClear);
static Key eventHandlerHook(Key mapped_key, byte row, byte col, uint8_t key_state);
static void loopHook(bool is_post_clear);
static Key tap(void);
static void interrupt(void);
static void timeout(void);
static Key release(uint8_t tapDanceIndex);
static Key release(uint8_t tap_dance_index);
};
} // namespace KaleidoscopePlugins
void tapDanceAction(uint8_t tapDanceIndex, byte row, byte col, uint8_t tapCount, KaleidoscopePlugins::TapDance::ActionType tapDanceAction);
}
extern KaleidoscopePlugins::TapDance TapDance;
void tapDanceAction(uint8_t tap_dance_index, byte row, byte col, uint8_t tap_count,
kaleidoscope::TapDance::ActionType tap_dance_action);
extern kaleidoscope::TapDance TapDance;

Loading…
Cancel
Save