diff --git a/NEWS.md b/NEWS.md index 1bb61082..9d96084f 100644 --- a/NEWS.md +++ b/NEWS.md @@ -129,6 +129,10 @@ We integrated the [LEDWavepool](doc/plugin/LED-Wavepool.md) plugin by [ToyKeeper [wavepool:origin]: https://github.com/ToyKeeper/Kaleidoscope-LED-Wavepool +### Turbo + +The [Turbo](doc/plugin/Turbo.md) plugin provides a way to send keystrokes in very quick succession while holding down a key. + ### WinKeyToggle The [WinKeyToggle](doc/plugin/WinKeyToggle.md) plugin assists with toggling the Windows key on and off - a little something for those of us who game under Windows and are tired of accidentally popping up the start menu. diff --git a/doc/plugin/Turbo.md b/doc/plugin/Turbo.md new file mode 100644 index 00000000..dba42fb2 --- /dev/null +++ b/doc/plugin/Turbo.md @@ -0,0 +1,83 @@ +# Kaleidoscope-Turbo + +The `Turbo` plugin provides an extra key one can place on their keymap. While the +key is pressed or toggled, pressing other keys will generate quick repeated +inputs independent of the OS key repeation mechanics. + +## Using the plugin + +To use the plugin, simply include the header and enable the plugin and place +`Key_Turbo` somewhere on your keymap. You may add additionally configure +specific behaviors of the plugin as shown: + +```c++ +#include +#include +#include + +// somewhere in the keymap... +Key_Turbo + +KALEIDOSCOPE_INIT_PLUGINS(LEDControl, Turbo); + +void setup() { + Kaleidoscope.setup(); + + Turbo.interval(30); + Turbo.toggle(true); + Turbo.flash(true); + Turbo.flashInterval(80); + Turbo.activeColor(CRGB(0x64, 0x96, 0xed)); +} +``` + +## Plugin properties + +The `Turbo` object has the following user-configurable properties: + +### `.interval([uint16_t])` + +> This property adjusts the timing between simulated keypresses. If you set this +> too low, some programs might not like it. The default repeat rate for X11 is 25. +> +> Defaults to 10 + +### `.flashInterval([uint16_t])` + +> This property adjusts the timing between the on/off states of the key LED. +> +> Defaults to 69 + +### `.sticky([bool])` +> This method makes the Turbo functionality sticky, so it remains in effect not only while +> +> it is held, but after it is released too, until it is toggled off with another tap. Without +> arguments, the method enables the sticky functionality. Passing a boolean argument +> sets stickiness to the given value. +> +> Defaults to `false`. + +### `.flash([bool])` + +> This property indicates whether the key should flash when enabled or remain a solid +> color. +> +> Defaults to true. + + +### `.activeColor([cRGB])` + +> This property indicates the color the key should become when enabled. +> +> Defaults to `CRGB(160, 0, 0)` (same as solidRed in default firmware). + +## Dependencies + +* [Kaleidoscope-LEDControl](LEDControl.md) + +## Further reading + +Starting from the [example][plugin:example] is the recommended way of getting +started with the plugin. + + [plugin:example]: ../../examples/Keystrokes/Turbo/Turbo.ino diff --git a/examples/Keystrokes/Turbo/Turbo.ino b/examples/Keystrokes/Turbo/Turbo.ino new file mode 100644 index 00000000..5827c5b1 --- /dev/null +++ b/examples/Keystrokes/Turbo/Turbo.ino @@ -0,0 +1,57 @@ +/* -*- mode: c++ -*- + * Kaleidoscope-Turbo + * Copyright (C) 2018 + * + * This program is free software: you can redistribute it and/or modify it under + * the terms of the GNU General Public License as published by the Free Software + * Foundation, version 3. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see . + */ + +#include +#include +#include + +// *INDENT-OFF* +KEYMAPS( + [0] = KEYMAP_STACKED + (Key_NoKey, Key_1, Key_2, Key_3, Key_4, Key_5, Key_NoKey, + Key_Backtick, Key_Q, Key_W, Key_E, Key_R, Key_T, Key_Tab, + Key_PageUp, Key_A, Key_S, Key_D, Key_F, Key_G, + Key_PageDown, Key_Z, Key_X, Key_C, Key_V, Key_B, Key_Escape, + + Key_LeftControl, Key_Backspace, Key_LeftGui, Key_LeftShift, + Key_skip, + + Key_skip, Key_6, Key_7, Key_8, Key_9, Key_0, Key_skip, + Key_Enter, Key_Y, Key_U, Key_I, Key_O, Key_P, Key_Equals, + Key_H, Key_J, Key_K, Key_L, Key_Semicolon, Key_Quote, + Key_Turbo, Key_N, Key_M, Key_Comma, Key_Period, Key_Slash, Key_Minus, + + Key_RightShift, Key_RightAlt, Key_Spacebar, Key_RightControl, + Key_skip), +) +// *INDENT-ON* + +KALEIDOSCOPE_INIT_PLUGINS(LEDControl, Turbo); + +void setup() { + Kaleidoscope.setup(); + + Turbo.interval(30); + Turbo.sticky(true); + Turbo.flash(true); + Turbo.flashInterval(80); + Turbo.activeColor(CRGB(0x64, 0x96, 0xed)); +} + +void loop() { + Kaleidoscope.loop(); +} diff --git a/src/Kaleidoscope-Ranges.h b/src/Kaleidoscope-Ranges.h index 091a4589..9c12111d 100644 --- a/src/Kaleidoscope-Ranges.h +++ b/src/Kaleidoscope-Ranges.h @@ -48,6 +48,7 @@ enum : uint16_t { SC_FIRST, SC_LAST, REDIAL, + TURBO, SAFE_START, KALEIDOSCOPE_SAFE_START = SAFE_START diff --git a/src/Kaleidoscope-Turbo.h b/src/Kaleidoscope-Turbo.h new file mode 100644 index 00000000..6c419692 --- /dev/null +++ b/src/Kaleidoscope-Turbo.h @@ -0,0 +1,20 @@ +/* -*- mode: c++ -*- + * Kaleidoscope-Turbo + * Copyright (C) 2018 ash lea + * + * This program is free software: you can redistribute it and/or modify it under + * the terms of the GNU General Public License as published by the Free Software + * Foundation, version 3. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see . + */ + +#pragma once + +#include diff --git a/src/kaleidoscope/plugin/Turbo.cpp b/src/kaleidoscope/plugin/Turbo.cpp new file mode 100644 index 00000000..cf50f4d8 --- /dev/null +++ b/src/kaleidoscope/plugin/Turbo.cpp @@ -0,0 +1,134 @@ +/* -*- mode: c++ -*- + * Kaleidoscope-Turbo + * Copyright (C) 2018 ash lea + * + * This program is free software: you can redistribute it and/or modify it under + * the terms of the GNU General Public License as published by the Free Software + * Foundation, version 3. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see . + */ + +#include +#include + +namespace kaleidoscope { +namespace plugin { + +uint16_t Turbo::interval_ = 10; +uint16_t Turbo::flashInterval_ = 69; +bool Turbo::sticky_ = false; +bool Turbo::flash_ = true; +cRGB Turbo::activeColor_ = CRGB(160, 0, 0); + +bool Turbo::enable = false; +uint32_t Turbo::startTime = 0; +uint32_t Turbo::flashStartTime = 0; +byte Turbo::keyPositions[4]; +uint16_t Turbo::numKeys = 0; + +uint16_t Turbo::interval() { + return interval_; +} +void Turbo::interval(uint16_t newVal) { + interval_ = newVal; +} + +uint16_t Turbo::flashInterval() { + return flashInterval_; +} +void Turbo::flashInterval(uint16_t newVal) { + flashInterval_ = newVal; +} + +bool Turbo::sticky() { + return sticky_; +} +void Turbo::sticky(bool newVal) { + sticky_ = newVal; +} + +bool Turbo::flash() { + return flash_; +} +void Turbo::flash(bool newVal) { + flash_ = newVal; +} + +cRGB Turbo::activeColor() { + return activeColor_; +} +void Turbo::activeColor(cRGB newVal) { + activeColor_ = newVal; +} + +void Turbo::findKeyPositions() { + numKeys = 0; + for (byte r = 0; r < ROWS; r++) { + for (byte c = 0; c < COLS; c++) { + if (Layer.lookupOnActiveLayer(r, c) == Key_Turbo) { + keyPositions[numKeys++] = r * COLS + c; + } + } + } +} + +EventHandlerResult Turbo::onSetup() { + Turbo::findKeyPositions(); + return EventHandlerResult::OK; +} + +EventHandlerResult Turbo::onLayerChange() { + Turbo::findKeyPositions(); + return EventHandlerResult::OK; +} + +EventHandlerResult Turbo::onKeyswitchEvent(Key &key, byte row, byte col, uint8_t key_state) { + if (key != Key_Turbo) return EventHandlerResult::OK; + enable = sticky_ ? (keyIsPressed(key_state) ? enable : !enable) : keyIsPressed(key_state); + if (!enable) { + for (uint16_t i = 0; i < numKeys; i++) { + LEDControl::refreshAt(keyPositions[i] / COLS, keyPositions[i] % COLS); + } + } + return EventHandlerResult::EVENT_CONSUMED; +} + +EventHandlerResult Turbo::afterEachCycle() { + if (enable) { + if (Kaleidoscope.millisAtCycleStart() - startTime > interval_) { + kaleidoscope::hid::sendKeyboardReport(); + startTime = Kaleidoscope.millisAtCycleStart(); + } + + if (flash_) { + if (Kaleidoscope.millisAtCycleStart() - flashStartTime > flashInterval_ * 2) { + for (uint16_t i = 0; i < numKeys; i++) { + LEDControl::setCrgbAt(keyPositions[i] / COLS, keyPositions[i] % COLS, activeColor_); + } + flashStartTime = Kaleidoscope.millisAtCycleStart(); + } else if (Kaleidoscope.millisAtCycleStart() - flashStartTime > flashInterval_) { + for (uint16_t i = 0; i < numKeys; i++) { + LEDControl::setCrgbAt(keyPositions[i] / COLS, keyPositions[i] % COLS, {0, 0, 0}); + } + } + LEDControl::syncLeds(); + } else { + for (uint16_t i = 0; i < numKeys; i++) { + LEDControl::setCrgbAt(keyPositions[i] / COLS, keyPositions[i] % COLS, activeColor_); + } + } + } + return EventHandlerResult::OK; +} + +} +} + +kaleidoscope::plugin::Turbo Turbo; diff --git a/src/kaleidoscope/plugin/Turbo.h b/src/kaleidoscope/plugin/Turbo.h new file mode 100644 index 00000000..0e534d12 --- /dev/null +++ b/src/kaleidoscope/plugin/Turbo.h @@ -0,0 +1,67 @@ +/* -*- mode: c++ -*- + * Kaleidoscope-Turbo + * Copyright (C) 2018 ash lea + * + * This program is free software: you can redistribute it and/or modify it under + * the terms of the GNU General Public License as published by the Free Software + * Foundation, version 3. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see . + */ + +#include +#include +#include + +#define Key_Turbo ((Key) { .raw = kaleidoscope::ranges::TURBO }) + +namespace kaleidoscope { +namespace plugin { +class Turbo : public kaleidoscope::Plugin { + public: + Turbo() {} + + uint16_t interval(); + void interval(uint16_t newVal); + + uint16_t flashInterval(); + void flashInterval(uint16_t newVal); + + bool sticky(); + void sticky(bool newVal); + + bool flash(); + void flash(bool newVal); + + cRGB activeColor(); + void activeColor(cRGB newVal); + + EventHandlerResult onSetup(); + EventHandlerResult onLayerChange(); + EventHandlerResult onKeyswitchEvent(Key &key, byte row, byte col, uint8_t key_state); + EventHandlerResult afterEachCycle(); + private: + void findKeyPositions(); + + static uint16_t interval_; + static uint16_t flashInterval_; + static bool sticky_; + static bool flash_; + static cRGB activeColor_; + + static bool enable; + static uint32_t startTime; + static uint32_t flashStartTime; + static byte keyPositions[4]; + static uint16_t numKeys; +}; +} +} + +extern kaleidoscope::plugin::Turbo Turbo;