diff --git a/doc/plugin/FingerPainter.md b/doc/plugin/FingerPainter.md new file mode 100644 index 00000000..c2b512ec --- /dev/null +++ b/doc/plugin/FingerPainter.md @@ -0,0 +1,62 @@ +# Kaleidoscope-FingerPainter + +The `FingerPainter` plugin provides an elaborate `LED` mode, in which one's able +to paint with their fingers: when edit mode is toggled on, keys will - instead +of performing their normal function - cycle through the global palette - as +provided by the [LED-Palette-Theme][plugin:l-p-t] plugin -, one by one for each tap. + +This allows us to edit the theme with the keyboard only, without any special +software (except to toggle edit mode on and off). + +## Using the plugin + +To use the plugin, just include the header, add it to the list of used plugins. + +```c++ +#include +#include +#include +#include +#include +#include + +KALEIDOSCOPE_INIT_PLUGINS(LEDControl, + EEPromSettings, + LEDPaletteTheme, + FingerPainter, + Focus); + +void setup() { + Kaleidoscope.setup(); +} +``` + +## Plugin methods + +The plugin provides the `FingerPainter` object, which provides no public methods. + +## Focus commands + +### `fingerpainter.clear` + +> Clears the canvas, so that one can start a new painting. + +### `fingerpainter.toggle` + +> Toggles the painting mode on and off. + +## Dependencies + +* [Kaleidoscope-EEPROM-Settings](EEPROM-Settings.md) +* [Kaleidoscope-FocusSerial](FocusSerial.md) +* [Kaleidoscope-LED-Palette-Theme][plugin:l-p-t] +* [Kaleidoscope-LEDControl](LEDControl.md) + + [plugin:l-p-t]: LED-Palette-Theme.md + +## Further reading + +Starting from the [example][plugin:example] is the recommended way of getting +started with the plugin. + + [plugin:example]: ../../examples/FingerPainter/FingerPainter.ino diff --git a/examples/FingerPainter/FingerPainter.ino b/examples/FingerPainter/FingerPainter.ino new file mode 100644 index 00000000..455832c7 --- /dev/null +++ b/examples/FingerPainter/FingerPainter.ino @@ -0,0 +1,65 @@ +/* -*- mode: c++ -*- + * Kaleidoscope-FingerPainter -- On-the-fly keyboard painting. + * Copyright (C) 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 +#include +#include +#include +#include + +#include "LED-Off.h" + +// *INDENT-OFF* +const Key keymaps[][ROWS][COLS] PROGMEM = { + [0] = KEYMAP_STACKED + (Key_NoKey, Key_1, Key_2, Key_3, Key_4, Key_5, Key_LEDEffectNext, + 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_skip, 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, + LEDOff, + EEPROMSettings, + LEDPaletteTheme, + FingerPainter, + Focus); + +void setup() { + Kaleidoscope.setup(); + + EEPROMSettings.seal(); + + FingerPainter.activate(); +} + +void loop() { + Kaleidoscope.loop(); +} diff --git a/src/Kaleidoscope-FingerPainter.h b/src/Kaleidoscope-FingerPainter.h new file mode 100644 index 00000000..441fd275 --- /dev/null +++ b/src/Kaleidoscope-FingerPainter.h @@ -0,0 +1,20 @@ +/* -*- mode: c++ -*- + * Kaleidoscope-FingerPainter -- On-the-fly keyboard painting. + * Copyright (C) 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/FingerPainter.cpp b/src/kaleidoscope/plugin/FingerPainter.cpp new file mode 100644 index 00000000..40d0d27d --- /dev/null +++ b/src/kaleidoscope/plugin/FingerPainter.cpp @@ -0,0 +1,117 @@ +/* -*- mode: c++ -*- + * Kaleidoscope-FingerPainter -- On-the-fly keyboard painting. + * Copyright (C) 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 +#include +#include +#include + +namespace kaleidoscope { +namespace plugin { + +uint16_t FingerPainter::color_base_; +bool FingerPainter::edit_mode_; + +EventHandlerResult FingerPainter::onSetup() { + color_base_ = ::LEDPaletteTheme.reserveThemes(1); + ::LEDControl.mode_add(this); + return EventHandlerResult::OK; +} + +void FingerPainter::update(void) { + ::LEDPaletteTheme.updateHandler(color_base_, 0); +} + +void FingerPainter::refreshAt(byte row, byte col) { + ::LEDPaletteTheme.refreshAt(color_base_, 0, row, col); +} + +void FingerPainter::toggle(void) { + edit_mode_ = !edit_mode_; +} + +EventHandlerResult FingerPainter::onKeyswitchEvent(Key &mapped_key, byte row, byte col, uint8_t key_state) { + if (!edit_mode_) + return EventHandlerResult::OK; + + if (!keyToggledOn(key_state)) { + return EventHandlerResult::EVENT_CONSUMED; + } + + if (row >= ROWS || col >= COLS) + return EventHandlerResult::EVENT_CONSUMED; + + uint8_t color_index = ::LEDPaletteTheme.lookupColorIndexAtPosition(color_base_, KeyboardHardware.getLedIndex(row, col)); + + // Find the next color in the palette that is different. + // But do not loop forever! + bool turn_around = false; + cRGB old_color = ::LEDPaletteTheme.lookupPaletteColor(color_index), new_color = old_color; + while (memcmp(&old_color, &new_color, sizeof(cRGB)) == 0) { + color_index++; + if (color_index > 15) { + color_index = 0; + if (turn_around) + break; + turn_around = true; + } + new_color = ::LEDPaletteTheme.lookupPaletteColor(color_index); + } + + ::LEDPaletteTheme.updateColorIndexAtPosition(color_base_, KeyboardHardware.getLedIndex(row, col), color_index); + + return EventHandlerResult::EVENT_CONSUMED; +} + +EventHandlerResult FingerPainter::onFocusEvent(const char *command) { + enum { + TOGGLE, + CLEAR, + } sub_command; + + if (::Focus.handleHelp(command, PSTR("fingerpainter.toggle\nfingerpainter.clear"))) + return EventHandlerResult::OK; + + if (strncmp_P(command, PSTR("fingerpainter."), 14) != 0) + return EventHandlerResult::OK; + + if (strcmp_P(command + 14, PSTR("toggle")) == 0) + sub_command = TOGGLE; + else if (strcmp_P(command + 14, PSTR("clear")) == 0) + sub_command = CLEAR; + else + return EventHandlerResult::OK; + + if (sub_command == CLEAR) { + for (uint16_t i = 0; i < ROWS * COLS / 2; i++) { + EEPROM.update(color_base_ + i, 0); + } + return EventHandlerResult::OK; + } + + ::FingerPainter.activate(); + toggle(); + + return EventHandlerResult::OK; +} + +} +} + +kaleidoscope::plugin::FingerPainter FingerPainter; diff --git a/src/kaleidoscope/plugin/FingerPainter.h b/src/kaleidoscope/plugin/FingerPainter.h new file mode 100644 index 00000000..e13e58b3 --- /dev/null +++ b/src/kaleidoscope/plugin/FingerPainter.h @@ -0,0 +1,45 @@ +/* -*- mode: c++ -*- + * Kaleidoscope-FingerPainter -- On-the-fly keyboard painting. + * Copyright (C) 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 . + */ + +#pragma once + +#include + +namespace kaleidoscope { +namespace plugin { +class FingerPainter : public LEDMode { + public: + FingerPainter(void) {} + + static void toggle(void); + + EventHandlerResult onKeyswitchEvent(Key &mapped_key, byte row, byte col, uint8_t key_state); + EventHandlerResult onFocusEvent(const char *command); + EventHandlerResult onSetup(); + + protected: + void update(void) final; + void refreshAt(byte row, byte col) final; + + private: + static uint16_t color_base_; + static bool edit_mode_; +}; +} +} + +extern kaleidoscope::plugin::FingerPainter FingerPainter;