|
|
@ -40,191 +40,191 @@ byte TapDance::lastTapDanceCol;
|
|
|
|
// --- actions ---
|
|
|
|
// --- actions ---
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
void
|
|
|
|
TapDance::interrupt (void) {
|
|
|
|
TapDance::interrupt(void) {
|
|
|
|
uint8_t idx = lastTapDanceKey.raw - Ranges::TD_FIRST;
|
|
|
|
uint8_t idx = lastTapDanceKey.raw - Ranges::TD_FIRST;
|
|
|
|
|
|
|
|
|
|
|
|
tapDanceAction (idx, lastTapDanceRow, lastTapDanceCol, tapCount[idx], Interrupt);
|
|
|
|
tapDanceAction(idx, lastTapDanceRow, lastTapDanceCol, tapCount[idx], Interrupt);
|
|
|
|
bitWrite (triggeredState, idx, 1);
|
|
|
|
bitWrite(triggeredState, idx, 1);
|
|
|
|
|
|
|
|
|
|
|
|
endTime = 0;
|
|
|
|
endTime = 0;
|
|
|
|
|
|
|
|
|
|
|
|
if (bitRead (pressedState, idx))
|
|
|
|
if (bitRead(pressedState, idx))
|
|
|
|
return;
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
release (idx);
|
|
|
|
release(idx);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
void
|
|
|
|
TapDance::timeout (void) {
|
|
|
|
TapDance::timeout(void) {
|
|
|
|
uint8_t idx = lastTapDanceKey.raw - Ranges::TD_FIRST;
|
|
|
|
uint8_t idx = lastTapDanceKey.raw - Ranges::TD_FIRST;
|
|
|
|
|
|
|
|
|
|
|
|
tapDanceAction (idx, lastTapDanceRow, lastTapDanceCol, tapCount[idx], Timeout);
|
|
|
|
tapDanceAction(idx, lastTapDanceRow, lastTapDanceCol, tapCount[idx], Timeout);
|
|
|
|
bitWrite (triggeredState, idx, 1);
|
|
|
|
bitWrite(triggeredState, idx, 1);
|
|
|
|
|
|
|
|
|
|
|
|
if (bitRead (pressedState, idx))
|
|
|
|
if (bitRead(pressedState, idx))
|
|
|
|
return;
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
lastTapDanceKey.raw = Key_NoKey.raw;
|
|
|
|
lastTapDanceKey.raw = Key_NoKey.raw;
|
|
|
|
|
|
|
|
|
|
|
|
release (idx);
|
|
|
|
release(idx);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Key
|
|
|
|
Key
|
|
|
|
TapDance::release (uint8_t tapDanceIndex) {
|
|
|
|
TapDance::release(uint8_t tapDanceIndex) {
|
|
|
|
endTime = 0;
|
|
|
|
endTime = 0;
|
|
|
|
lastTapDanceKey.raw = Key_NoKey.raw;
|
|
|
|
lastTapDanceKey.raw = Key_NoKey.raw;
|
|
|
|
|
|
|
|
|
|
|
|
bitClear (pressedState, tapDanceIndex);
|
|
|
|
bitClear(pressedState, tapDanceIndex);
|
|
|
|
bitClear (triggeredState, tapDanceIndex);
|
|
|
|
bitClear(triggeredState, tapDanceIndex);
|
|
|
|
bitWrite (releaseNextState, tapDanceIndex, 1);
|
|
|
|
bitWrite(releaseNextState, tapDanceIndex, 1);
|
|
|
|
return Key_NoKey;
|
|
|
|
return Key_NoKey;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Key
|
|
|
|
Key
|
|
|
|
TapDance::tap (void) {
|
|
|
|
TapDance::tap(void) {
|
|
|
|
uint8_t idx = lastTapDanceKey.raw - Ranges::TD_FIRST;
|
|
|
|
uint8_t idx = lastTapDanceKey.raw - Ranges::TD_FIRST;
|
|
|
|
|
|
|
|
|
|
|
|
tapCount[idx]++;
|
|
|
|
tapCount[idx]++;
|
|
|
|
endTime = millis () + timeOut;
|
|
|
|
endTime = millis() + timeOut;
|
|
|
|
|
|
|
|
|
|
|
|
tapDanceAction (idx, lastTapDanceRow, lastTapDanceCol, tapCount[idx], Tap);
|
|
|
|
tapDanceAction(idx, lastTapDanceRow, lastTapDanceCol, tapCount[idx], Tap);
|
|
|
|
|
|
|
|
|
|
|
|
return Key_NoKey;
|
|
|
|
return Key_NoKey;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// --- api ---
|
|
|
|
// --- api ---
|
|
|
|
|
|
|
|
|
|
|
|
TapDance::TapDance (void) {
|
|
|
|
TapDance::TapDance(void) {
|
|
|
|
lastTapDanceKey.raw = Key_NoKey.raw;
|
|
|
|
lastTapDanceKey.raw = Key_NoKey.raw;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
void
|
|
|
|
TapDance::begin (void) {
|
|
|
|
TapDance::begin(void) {
|
|
|
|
event_handler_hook_use (this->eventHandlerHook);
|
|
|
|
event_handler_hook_use(this->eventHandlerHook);
|
|
|
|
loop_hook_use (this->loopHook);
|
|
|
|
loop_hook_use(this->loopHook);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
void
|
|
|
|
TapDance::actionKeys (uint8_t tapCount, ActionType tapDanceAction, uint8_t maxKeys, const Key tapKeys[]) {
|
|
|
|
TapDance::actionKeys(uint8_t tapCount, ActionType tapDanceAction, uint8_t maxKeys, const Key tapKeys[]) {
|
|
|
|
if (tapCount > maxKeys)
|
|
|
|
if (tapCount > maxKeys)
|
|
|
|
tapCount = maxKeys;
|
|
|
|
tapCount = maxKeys;
|
|
|
|
|
|
|
|
|
|
|
|
Key key;
|
|
|
|
Key key;
|
|
|
|
key.raw = pgm_read_word (&(tapKeys[tapCount - 1].raw));
|
|
|
|
key.raw = pgm_read_word(&(tapKeys[tapCount - 1].raw));
|
|
|
|
|
|
|
|
|
|
|
|
switch (tapDanceAction) {
|
|
|
|
switch (tapDanceAction) {
|
|
|
|
case Tap:
|
|
|
|
case Tap:
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
case Interrupt:
|
|
|
|
case Interrupt:
|
|
|
|
case Timeout:
|
|
|
|
case Timeout:
|
|
|
|
handle_keyswitch_event (key, lastTapDanceRow, lastTapDanceCol, IS_PRESSED | INJECTED);
|
|
|
|
handle_keyswitch_event(key, lastTapDanceRow, lastTapDanceCol, IS_PRESSED | INJECTED);
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
case Hold:
|
|
|
|
case Hold:
|
|
|
|
handle_keyswitch_event (key, lastTapDanceRow, lastTapDanceCol, IS_PRESSED | WAS_PRESSED | INJECTED);
|
|
|
|
handle_keyswitch_event(key, lastTapDanceRow, lastTapDanceCol, IS_PRESSED | WAS_PRESSED | INJECTED);
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
case Release:
|
|
|
|
case Release:
|
|
|
|
Keyboard.sendReport ();
|
|
|
|
Keyboard.sendReport();
|
|
|
|
handle_keyswitch_event (key, lastTapDanceRow, lastTapDanceCol, WAS_PRESSED | INJECTED);
|
|
|
|
handle_keyswitch_event(key, lastTapDanceRow, lastTapDanceCol, WAS_PRESSED | INJECTED);
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// --- hooks ---
|
|
|
|
// --- hooks ---
|
|
|
|
|
|
|
|
|
|
|
|
Key
|
|
|
|
Key
|
|
|
|
TapDance::eventHandlerHook (Key mappedKey, byte row, byte col, uint8_t keyState) {
|
|
|
|
TapDance::eventHandlerHook(Key mappedKey, byte row, byte col, uint8_t keyState) {
|
|
|
|
if (keyState & INJECTED)
|
|
|
|
if (keyState & INJECTED)
|
|
|
|
return mappedKey;
|
|
|
|
return mappedKey;
|
|
|
|
|
|
|
|
|
|
|
|
if (!key_is_pressed (keyState) && !key_was_pressed (keyState)) {
|
|
|
|
|
|
|
|
if (isTapDance (mappedKey))
|
|
|
|
|
|
|
|
return Key_NoKey;
|
|
|
|
|
|
|
|
return mappedKey;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!isTapDance (mappedKey)) {
|
|
|
|
if (!key_is_pressed(keyState) && !key_was_pressed(keyState)) {
|
|
|
|
if (!isActive ())
|
|
|
|
if (isTapDance(mappedKey))
|
|
|
|
return mappedKey;
|
|
|
|
return Key_NoKey;
|
|
|
|
|
|
|
|
return mappedKey;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (key_toggled_on (keyState))
|
|
|
|
if (!isTapDance(mappedKey)) {
|
|
|
|
interrupt ();
|
|
|
|
if (!isActive())
|
|
|
|
|
|
|
|
return mappedKey;
|
|
|
|
|
|
|
|
|
|
|
|
return mappedKey;
|
|
|
|
if (key_toggled_on(keyState))
|
|
|
|
}
|
|
|
|
interrupt();
|
|
|
|
|
|
|
|
|
|
|
|
uint8_t tapDanceIndex = mappedKey.raw - Ranges::TD_FIRST;
|
|
|
|
return mappedKey;
|
|
|
|
|
|
|
|
}
|
|
|
|
if (key_toggled_off (keyState))
|
|
|
|
|
|
|
|
bitClear (pressedState, tapDanceIndex);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!isInSeq (mappedKey)) {
|
|
|
|
|
|
|
|
if (!isActive ()) {
|
|
|
|
|
|
|
|
if (bitRead (triggeredState, tapDanceIndex)) {
|
|
|
|
|
|
|
|
if (key_toggled_off (keyState))
|
|
|
|
|
|
|
|
return release (tapDanceIndex);
|
|
|
|
|
|
|
|
return Key_NoKey;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lastTapDanceKey.raw = mappedKey.raw;
|
|
|
|
|
|
|
|
lastTapDanceRow = row;
|
|
|
|
|
|
|
|
lastTapDanceCol = col;
|
|
|
|
|
|
|
|
return tap ();
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
if (key_toggled_off (keyState) && stillHeld (tapDanceIndex)) {
|
|
|
|
|
|
|
|
return release (tapDanceIndex);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!key_toggled_on (keyState))
|
|
|
|
|
|
|
|
return Key_NoKey;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
interrupt ();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// in sequence
|
|
|
|
uint8_t tapDanceIndex = mappedKey.raw - Ranges::TD_FIRST;
|
|
|
|
|
|
|
|
|
|
|
|
if (key_toggled_off (keyState))
|
|
|
|
if (key_toggled_off(keyState))
|
|
|
|
return Key_NoKey;
|
|
|
|
bitClear(pressedState, tapDanceIndex);
|
|
|
|
|
|
|
|
|
|
|
|
lastTapDanceKey.raw = mappedKey.raw;
|
|
|
|
if (!isInSeq(mappedKey)) {
|
|
|
|
lastTapDanceRow = row;
|
|
|
|
if (!isActive()) {
|
|
|
|
lastTapDanceCol = col;
|
|
|
|
if (bitRead(triggeredState, tapDanceIndex)) {
|
|
|
|
bitSet (pressedState, tapDanceIndex);
|
|
|
|
if (key_toggled_off(keyState))
|
|
|
|
|
|
|
|
return release(tapDanceIndex);
|
|
|
|
|
|
|
|
return Key_NoKey;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lastTapDanceKey.raw = mappedKey.raw;
|
|
|
|
|
|
|
|
lastTapDanceRow = row;
|
|
|
|
|
|
|
|
lastTapDanceCol = col;
|
|
|
|
|
|
|
|
return tap();
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
if (key_toggled_off(keyState) && stillHeld(tapDanceIndex)) {
|
|
|
|
|
|
|
|
return release(tapDanceIndex);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!key_toggled_on(keyState))
|
|
|
|
|
|
|
|
return Key_NoKey;
|
|
|
|
|
|
|
|
|
|
|
|
if (key_toggled_on (keyState))
|
|
|
|
interrupt();
|
|
|
|
return tap ();
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (bitRead (triggeredState, tapDanceIndex))
|
|
|
|
// in sequence
|
|
|
|
tapDanceAction (tapDanceIndex, row, col, tapCount[tapDanceIndex], Hold);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (key_toggled_off(keyState))
|
|
|
|
return Key_NoKey;
|
|
|
|
return Key_NoKey;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lastTapDanceKey.raw = mappedKey.raw;
|
|
|
|
|
|
|
|
lastTapDanceRow = row;
|
|
|
|
|
|
|
|
lastTapDanceCol = col;
|
|
|
|
|
|
|
|
bitSet(pressedState, tapDanceIndex);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (key_toggled_on(keyState))
|
|
|
|
|
|
|
|
return tap();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (bitRead(triggeredState, tapDanceIndex))
|
|
|
|
|
|
|
|
tapDanceAction(tapDanceIndex, row, col, tapCount[tapDanceIndex], Hold);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return Key_NoKey;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
void
|
|
|
|
TapDance::loopHook (bool postClear) {
|
|
|
|
TapDance::loopHook(bool postClear) {
|
|
|
|
if (!postClear)
|
|
|
|
if (!postClear)
|
|
|
|
return;
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
for (uint8_t i = 0; i < 16; i++) {
|
|
|
|
for (uint8_t i = 0; i < 16; i++) {
|
|
|
|
if (!bitRead (releaseNextState, i))
|
|
|
|
if (!bitRead(releaseNextState, i))
|
|
|
|
continue;
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
|
|
tapDanceAction (i, lastTapDanceRow, lastTapDanceCol, tapCount[i], Release);
|
|
|
|
tapDanceAction(i, lastTapDanceRow, lastTapDanceCol, tapCount[i], Release);
|
|
|
|
tapCount[i] = 0;
|
|
|
|
tapCount[i] = 0;
|
|
|
|
bitClear (releaseNextState, i);
|
|
|
|
bitClear(releaseNextState, i);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (!isActive ())
|
|
|
|
if (!isActive())
|
|
|
|
return;
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
if (endTime && millis () > endTime)
|
|
|
|
if (endTime && millis() > endTime)
|
|
|
|
timeout();
|
|
|
|
timeout();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} // namespace KaleidoscopePlugins
|
|
|
|
} // namespace KaleidoscopePlugins
|
|
|
|
|
|
|
|
|
|
|
|
__attribute__((weak))
|
|
|
|
__attribute__((weak))
|
|
|
|
void
|
|
|
|
void
|
|
|
|
tapDanceAction (uint8_t tapDanceIndex, byte row, byte col, uint8_t tapCount, KaleidoscopePlugins::TapDance::ActionType tapDanceAction) {
|
|
|
|
tapDanceAction(uint8_t tapDanceIndex, byte row, byte col, uint8_t tapCount, KaleidoscopePlugins::TapDance::ActionType tapDanceAction) {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
KaleidoscopePlugins::TapDance TapDance;
|
|
|
|
KaleidoscopePlugins::TapDance TapDance;
|
|
|
|