diff --git a/plugins/Kaleidoscope-Colormap-Overlay/examples/Colormap-Overlay/Colormap-Overlay.ino b/plugins/Kaleidoscope-Colormap-Overlay/examples/Colormap-Overlay/Colormap-Overlay.ino index e62a7f2df7..2fec95572c 100644 --- a/plugins/Kaleidoscope-Colormap-Overlay/examples/Colormap-Overlay/Colormap-Overlay.ino +++ b/plugins/Kaleidoscope-Colormap-Overlay/examples/Colormap-Overlay/Colormap-Overlay.ino @@ -19,8 +19,10 @@ * You should have received a copy of the GNU General Public License along with * this program. If not, see . */ + #include #include +#include #include #include diff --git a/plugins/Kaleidoscope-Colormap-Overlay/examples/Colormap-Overlay/sketch.json b/plugins/Kaleidoscope-Colormap-Overlay/examples/Colormap-Overlay/sketch.json new file mode 100644 index 0000000000..e00344e932 --- /dev/null +++ b/plugins/Kaleidoscope-Colormap-Overlay/examples/Colormap-Overlay/sketch.json @@ -0,0 +1,6 @@ +{ + "cpu": { + "fqbn": "keyboardio:gd32:keyboardio_model_100", + "port": "" + } +} diff --git a/plugins/Kaleidoscope-Colormap-Overlay/examples/Colormap-Overlay/sketch.yaml b/plugins/Kaleidoscope-Colormap-Overlay/examples/Colormap-Overlay/sketch.yaml new file mode 100644 index 0000000000..6065348e4d --- /dev/null +++ b/plugins/Kaleidoscope-Colormap-Overlay/examples/Colormap-Overlay/sketch.yaml @@ -0,0 +1 @@ +default_fqbn: keyboardio:gd32:keyboardio_model_100 diff --git a/plugins/Kaleidoscope-Colormap-Overlay/src/kaleidoscope/plugin/Colormap-Overlay.cpp b/plugins/Kaleidoscope-Colormap-Overlay/src/kaleidoscope/plugin/Colormap-Overlay.cpp index 1e0de40cdd..32ef5073ab 100644 --- a/plugins/Kaleidoscope-Colormap-Overlay/src/kaleidoscope/plugin/Colormap-Overlay.cpp +++ b/plugins/Kaleidoscope-Colormap-Overlay/src/kaleidoscope/plugin/Colormap-Overlay.cpp @@ -30,12 +30,31 @@ #include "kaleidoscope/key_defs.h" // for Key, KEY_FLAGS, Key_NoKey, LockLayer #include "kaleidoscope/layers.h" // for Layer, Layer_ #include "kaleidoscope/plugin/LEDControl.h" // for LEDControl +#include // for Kaleidoscope +#include // for Focus #include // for LEDPaletteTheme +#include // for EEPROMSettings namespace kaleidoscope { namespace plugin { +uint16_t ColormapOverlay::overlays_base_; +Overlay *ColormapOverlay::overlays_; +uint8_t ColormapOverlay::overlay_count_; + void ColormapOverlay::setup() { ::LEDPaletteTheme.reservePalette(); + + overlays_base_ = ::EEPROMSettings.requestSlice(max_overlays_ * sizeof(Overlay)); + + ::EEPROMSettings.seal(); + + if (!::EEPROMSettings.isValid()) { + // When settings are invalid, better to clean it all up to prevent unwanted things from happening + ::EEPROMSettings.invalidate(); + return; + } + + Kaleidoscope.storage().get(overlays_base_, overlays_); } bool ColormapOverlay::hasOverlay(KeyAddr k) { @@ -43,7 +62,7 @@ bool ColormapOverlay::hasOverlay(KeyAddr k) { uint8_t layer_index = Layer.lookupActiveLayer(k); bool found_match_on_lower_layer = false; - for (uint8_t i{0}; i < overlay_count_; ++i) { + for (uint8_t i{0}; i < overlay_count_; i++) { Overlay overlay = overlays_[i]; if (overlay.addr == k) { if ((overlay.layer == top_layer) || (overlay.layer == layer_wildcard)) { @@ -82,6 +101,75 @@ EventHandlerResult ColormapOverlay::beforeSyncingLeds() { return EventHandlerResult::OK; } +EventHandlerResult ColormapOverlay::onFocusEvent(const char *input) { + if (!Runtime.has_leds) + return EventHandlerResult::OK; + + const char *cmd = PSTR("colormap.overlay"); + + if (::Focus.inputMatchesHelp(input)) + return ::Focus.printHelp(cmd); + + if (!::Focus.inputMatchesCommand(input, cmd)) + return EventHandlerResult::OK; + + if (::Focus.isEOL()) { + for (uint8_t layer = 0; layer < layer_count; layer++) { + for (uint8_t key_index_ = 0; key_index_ < Runtime.device().numKeys(); key_index_++) { + KeyAddr k = KeyAddr(key_index_); + for (uint8_t overlay_index{0}; overlay_index < overlay_count_; overlay_index++) { + Overlay overlay = overlays_[overlay_index]; + if ((overlay.addr == k) && (overlay.layer == layer)) { + ::Focus.send(overlay.palette_index); + } + } + ::Focus.send(-1); + } + } + return EventHandlerResult::EVENT_CONSUMED; + } + + overlays_ = nullptr; + overlay_count_ = 0; + uint16_t i = 0; + while (!::Focus.isEOL() && (i < (uint16_t)Runtime.device().numKeys() * layer_count)) { + int8_t color_index_; + + // Ref: plugins/Kaleidoscope-FocusSerial/src/kaleidoscope/plugin/FocusSerial.h + // -> No overload for signed integers + // Ref: src/kaleidoscope/device/Base.h + // -> parseInt() seems to support signed values? + ::Focus.read(color_index_); + if (color_index_ >= 0) { + uint8_t key_index_ = i % Runtime.device().numKeys(); + uint8_t layer_ = (i - key_index_) / Runtime.device().numKeys(); + + overlays_[overlay_count_] = Overlay(layer_, KeyAddr(key_index_), color_index_); + overlay_count_++; + + if (overlay_count_ >= max_overlays_) { + // TODO(anyone): For now we just break the loop. Once focus implements + // support for reporting back errors, this should report why we break + // the loop + break; + } + } + + i++; + } + Runtime.storage().commit(); + + ::LEDControl.refreshAll(); + + return EventHandlerResult::EVENT_CONSUMED; +} + +EventHandlerResult ColormapOverlay::onLayerChange() { + // Ensure that any LEDs previously controlled by this plugin get reset + ::LEDControl.refreshAll(); + return EventHandlerResult::OK; +} + } // namespace plugin } // namespace kaleidoscope diff --git a/plugins/Kaleidoscope-Colormap-Overlay/src/kaleidoscope/plugin/Colormap-Overlay.h b/plugins/Kaleidoscope-Colormap-Overlay/src/kaleidoscope/plugin/Colormap-Overlay.h index 51921a0dd9..e4a410f933 100644 --- a/plugins/Kaleidoscope-Colormap-Overlay/src/kaleidoscope/plugin/Colormap-Overlay.h +++ b/plugins/Kaleidoscope-Colormap-Overlay/src/kaleidoscope/plugin/Colormap-Overlay.h @@ -22,7 +22,8 @@ #pragma once -#include // for uint8_t +#include // for PROGMEM +#include // for uint8_t #include "kaleidoscope/KeyAddr.h" // for KeyAddr #include "kaleidoscope/device/device.h" // for cRGB @@ -35,7 +36,7 @@ namespace kaleidoscope { namespace plugin { -// Data structure for an individual qukey +// Data structure for an individual color overlay struct Overlay { uint8_t layer; KeyAddr addr; @@ -60,6 +61,7 @@ class ColormapOverlay : public kaleidoscope::Plugin { // as a separate parameter. template void configureOverlays(Overlay const (&overlays)[_overlay_count]) { + static_assert(_overlay_count <= max_overlays_); // Delete old overlays if they exist if (overlays_ != nullptr) { delete[] overlays_; @@ -79,12 +81,12 @@ class ColormapOverlay : public kaleidoscope::Plugin { void configureOverlays(uint8_t **overlays) { // First count how many overlays we'll need uint8_t count = 0; - for (int layer_ = 0; layer_ < _layer_count; layer_++) { - for (int key_index_ = 0; key_index_ < kaleidoscope_internal::device.matrix_rows * kaleidoscope_internal::device.matrix_columns; key_index_++) { + for (uint8_t layer_ = 0; layer_ < _layer_count; layer_++) { + for (uint8_t key_index_ = 0; key_index_ < kaleidoscope_internal::device.matrix_rows * kaleidoscope_internal::device.matrix_columns; key_index_++) { int8_t color_index_ = overlays[layer_][key_index_]; if (color_index_ >= 0 && color_index_ < ::LEDPaletteTheme.getPaletteSize() && color_index_ != no_color_overlay) { - count++; + count++; // TODO(EvyBongers): how to make sure that we don't exceed max_overlays_ } } } @@ -113,12 +115,15 @@ class ColormapOverlay : public kaleidoscope::Plugin { overlays_ = new_overlays; overlay_count_ = count; } + // A wildcard value for an overlay that applies on every layer. static constexpr int8_t layer_wildcard{-1}; static constexpr int8_t no_color_overlay{-1}; EventHandlerResult onSetup(); EventHandlerResult beforeSyncingLeds(); + EventHandlerResult onFocusEvent(const char *input); + EventHandlerResult onLayerChange(); ~ColormapOverlay() { if (overlays_ != nullptr) { @@ -127,8 +132,10 @@ class ColormapOverlay : public kaleidoscope::Plugin { } private: - Overlay *overlays_; - uint8_t overlay_count_; + static uint16_t overlays_base_; + static const uint8_t max_overlays_ = 64; // TODO(EvyBongers): figure this out. How determine a good maximum? + static Overlay *overlays_; + static uint8_t overlay_count_; cRGB selectedColor; bool hasOverlay(KeyAddr k);