diff --git a/doc/plugin/ShapeShifter.md b/doc/plugin/ShapeShifter.md new file mode 100644 index 00000000..2dd55c97 --- /dev/null +++ b/doc/plugin/ShapeShifter.md @@ -0,0 +1,69 @@ +# Kaleidoscope-ShapeShifter + +`ShapeShifter` is a plugin that makes it considerably easier to change what +symbol is input when a key is pressed together with `Shift`. If one wants to +rearrange the symbols on the number row for example, without modifying the +layout on the operating system side, this plugin is where one can turn to. + +What it does, is very simple: if any key in its dictionary is found pressed +while `Shift` is held, it will press another key instead of the one triggering +the event. For example, if it sees `Shift + 1` pressed together, which normally +results in a `!`, it will press `4` instead of `1`, inputting `$`. + +## Using the plugin + +To use the plugin, one needs to include the header, create a dictionary, and +configure the provided `ShapeShifter` object to use the dictionary: + +```c++ +#include +#include + +static const kaleidoscope::plugin::ShapeShifter::dictionary_t shape_shift_dictionary[] PROGMEM = { + {Key_1, Key_4}, + {Key_4, Key_1}, + {Key_NoKey, Key_NoKey}, +}; + +KALEIDOSCOPE_INIT_PLUGINS(ShapeShifter); + +void setup() { + Kaleidoscope.setup(); + + ShapeShifter.dictionary = shape_shift_dictionary; +} +``` + +The dictionary is made up of `Key` pairs: the first one is to replace, the +second is the replacement. The dictionary must be closed with a `{Key_NoKey, +Key_NoKey}` pair, and **must** reside in `PROGMEM`. + +## Plugin methods + +The plugin provides the `ShapeShifter` object, with the following methods and +properties: + +### `.dictionary` + +> Set this property to the dictionary `ShapeShifter` should use. The dictionary +> is an array of `kaleidoscope::ShapeShifter::dictionary_t` elements, which is +> just a very verbose way of saying that its a pair of keys. The first one is +> the one to replace, and the other is to replace it with. +> +> Be aware that the replacement key will be pressed with `Shift` held, so do +> keep that in mind! + +## Further reading + +Starting from the [example][plugin:example] is the recommended way of getting +started with the plugin. + + [plugin:example]: ../../examples/ShapeShifter/ShapeShifter.ino + +## Upgrading + +Previous versions of `ShapeShifter` used +`kaleidoscope::ShapeShifter::dictionary_t` as a type for defining the +dictionary. In newer versions, this is +`kaleidoscope::plugin::ShapeShifter::dictionary_t`. The old name still works, +but will be removed by 2019-01-14. diff --git a/examples/ShapeShifter/ShapeShifter.ino b/examples/ShapeShifter/ShapeShifter.ino new file mode 100644 index 00000000..14631dee --- /dev/null +++ b/examples/ShapeShifter/ShapeShifter.ino @@ -0,0 +1,59 @@ +/* -*- mode: c++ -*- + * Kaleidoscope-ShapeShifter -- Change the shifted symbols on any key of your choice + * Copyright (C) 2016, 2017, 2018 Keyboard.io, Inc + * + * 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 + +// *INDENT-OFF* +const Key keymaps[][ROWS][COLS] PROGMEM = { + [0] = KEYMAP_STACKED + ( + Key_skip, Key_1, Key_2, Key_3, Key_4, Key_5, Key_skip, + 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_NoKey, + + 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_skip, Key_N, Key_M, Key_Comma, Key_Period, Key_Slash, Key_Minus, + + Key_RightShift, Key_RightAlt, Key_Spacebar, Key_RightControl, + Key_NoKey), +}; +// *INDENT-ON* + +static const kaleidoscope::plugin::ShapeShifter::dictionary_t shape_shift_dictionary[] PROGMEM = { + {Key_1, Key_2}, + {Key_2, Key_1}, + {Key_NoKey, Key_NoKey}, +}; + +KALEIDOSCOPE_INIT_PLUGINS(ShapeShifter); + +void setup() { + Kaleidoscope.setup(); + + ShapeShifter.dictionary = shape_shift_dictionary; +} + +void loop() { + Kaleidoscope.loop(); +} diff --git a/src/Kaleidoscope-ShapeShifter.h b/src/Kaleidoscope-ShapeShifter.h new file mode 100644 index 00000000..b08d872f --- /dev/null +++ b/src/Kaleidoscope-ShapeShifter.h @@ -0,0 +1,20 @@ +/* -*- mode: c++ -*- + * Kaleidoscope-ShapeShifter -- Change the shifted symbols on any key of your choice + * Copyright (C) 2016, 2017 Keyboard.io, Inc + * + * 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/ShapeShifter.cpp b/src/kaleidoscope/plugin/ShapeShifter.cpp new file mode 100644 index 00000000..f97cefbf --- /dev/null +++ b/src/kaleidoscope/plugin/ShapeShifter.cpp @@ -0,0 +1,66 @@ +/* -*- mode: c++ -*- + * Kaleidoscope-ShapeShifter -- Change the shifted symbols on any key of your choice + * Copyright (C) 2016, 2017 Keyboard.io, Inc + * + * 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 { + +const ShapeShifter::dictionary_t *ShapeShifter::dictionary = NULL; +bool ShapeShifter::mod_active_; + +EventHandlerResult ShapeShifter::beforeReportingState() { + mod_active_ = hid::isModifierKeyActive(Key_LeftShift) || + hid::isModifierKeyActive(Key_RightShift); + return EventHandlerResult::OK; +} + +EventHandlerResult ShapeShifter::onKeyswitchEvent(Key &mapped_key, byte row, byte col, uint8_t key_state) { + if (!dictionary) + return EventHandlerResult::OK; + + // If Shift is not active, bail out early. + if (!mod_active_) + return EventHandlerResult::OK; + + Key orig, repl; + + // Try to find the current key in the dictionary + uint8_t i = 0; + do { + orig.raw = pgm_read_word(&(dictionary[i].original.raw)); + i++; + } while (orig.raw != Key_NoKey.raw && + orig.raw != mapped_key.raw); + i--; + + // If not found, bail out. + if (orig.raw == Key_NoKey.raw) + return EventHandlerResult::OK; + + repl.raw = pgm_read_word(&(dictionary[i].replacement.raw)); + + // If found, handle the alternate key instead + mapped_key = repl; + return EventHandlerResult::OK; +} + +} +} + +kaleidoscope::plugin::ShapeShifter ShapeShifter; diff --git a/src/kaleidoscope/plugin/ShapeShifter.h b/src/kaleidoscope/plugin/ShapeShifter.h new file mode 100644 index 00000000..59344fb5 --- /dev/null +++ b/src/kaleidoscope/plugin/ShapeShifter.h @@ -0,0 +1,47 @@ +/* -*- mode: c++ -*- + * Kaleidoscope-ShapeShifter -- Change the shifted symbols on any key of your choice + * Copyright (C) 2016, 2017 Keyboard.io, Inc + * + * 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 + +namespace kaleidoscope { +namespace plugin { + +class ShapeShifter : public kaleidoscope::Plugin { + public: + typedef struct { + Key original, replacement; + } dictionary_t; + + ShapeShifter(void) {} + + static const dictionary_t *dictionary; + + EventHandlerResult onKeyswitchEvent(Key &mapped_key, byte row, byte col, uint8_t key_state); + EventHandlerResult beforeReportingState(); + + private: + static bool mod_active_; +}; +} + +// Backwards compatibility +typedef plugin::ShapeShifter ShapeShifter; +} + +extern kaleidoscope::plugin::ShapeShifter ShapeShifter;