diff --git a/examples/LEDs/Colormap/Colormap.ino b/examples/LEDs/Colormap/Colormap.ino index 4699b093..a11699c5 100644 --- a/examples/LEDs/Colormap/Colormap.ino +++ b/examples/LEDs/Colormap/Colormap.ino @@ -1,6 +1,6 @@ /* -*- mode: c++ -*- * Kaleidoscope-EEPROM-Colormap -- Per-layer colormap effect - * Copyright (C) 2017, 2018 Keyboard.io, Inc + * Copyright (C) 2017-2022 Keyboard.io, Inc * * This program is free software: you can redistribute it and/or modify it under it under * the terms of the GNU General Public License as published by the Free Software @@ -17,6 +17,7 @@ #include #include +#include #include #include #include @@ -25,10 +26,10 @@ // clang-format off KEYMAPS( [0] = KEYMAP_STACKED - (Key_LEDEffectNext, 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_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_NoKey, @@ -42,17 +43,90 @@ KEYMAPS( Key_NoKey), ) +// Colors names of the EGA palette, for convenient use in colormaps. Should +// match the palette definition below. Optional, one can just use the indexes +// directly, too. +enum { + BLACK, + BLUE, + GREEN, + CYAN, + RED, + MAGENTA, + BROWN, + LIGHT_GRAY, + DARK_GRAY, + BRIGHT_BLUE, + BRIGHT_GREEN, + BRIGHT_CYAN, + BRIGHT_RED, + BRIGHT_MAGENTA, + YELLOW, + WHITE +}; + +// Define an EGA palette. Conveniently, that's exactly 16 colors, just like the +// limit of LEDPaletteTheme. +PALETTE( + CRGB(0x00, 0x00, 0x00), // [0x0] black + CRGB(0x00, 0x00, 0xaa), // [0x1] blue + CRGB(0x00, 0xaa, 0x00), // [0x2] green + CRGB(0x00, 0xaa, 0xaa), // [0x3] cyan + CRGB(0xaa, 0x00, 0x00), // [0x4] red + CRGB(0xaa, 0x00, 0xaa), // [0x5] magenta + CRGB(0xaa, 0x55, 0x00), // [0x6] brown + CRGB(0xaa, 0xaa, 0xaa), // [0x7] light gray + CRGB(0x55, 0x55, 0x55), // [0x8] dark gray + CRGB(0x55, 0x55, 0xff), // [0x9] bright blue + CRGB(0x55, 0xff, 0x55), // [0xa] bright green + CRGB(0x55, 0xff, 0xff), // [0xb] bright cyan + CRGB(0xff, 0x55, 0x55), // [0xc] bright red + CRGB(0xff, 0x55, 0xff), // [0xd] bright magenta + CRGB(0xff, 0xff, 0x55), // [0xe] yellow + CRGB(0xff, 0xff, 0xff) // [0xf] white +) + +COLORMAPS( + [0] = COLORMAP_STACKED + (BLACK, GREEN, GREEN, GREEN, GREEN, GREEN, BLUE, + MAGENTA, CYAN, CYAN, CYAN, CYAN, CYAN, RED, + BROWN, CYAN, CYAN, CYAN, CYAN, CYAN, + BROWN, CYAN, CYAN, CYAN, CYAN, CYAN, RED, + + LIGHT_GRAY, RED, LIGHT_GRAY, LIGHT_GRAY, + BLACK, + + BLACK, BRIGHT_GREEN, BRIGHT_GREEN, BRIGHT_GREEN, BRIGHT_GREEN, BRIGHT_GREEN, BLACK, + BRIGHT_RED, BRIGHT_CYAN, BRIGHT_CYAN, BRIGHT_CYAN, BRIGHT_CYAN, BRIGHT_CYAN, YELLOW, + BRIGHT_CYAN, BRIGHT_CYAN, BRIGHT_CYAN, BRIGHT_CYAN, BRIGHT_RED, BRIGHT_RED, + BLACK, BRIGHT_CYAN, BRIGHT_CYAN, BRIGHT_RED, BRIGHT_RED, BRIGHT_RED, BRIGHT_RED, + + DARK_GRAY, BRIGHT_RED, DARK_GRAY, DARK_GRAY, + BLACK) +) + // clang-format on KALEIDOSCOPE_INIT_PLUGINS(EEPROMSettings, + EEPROMKeymap, + LEDControl, LEDPaletteTheme, + LEDOff, ColormapEffect, - Focus); + DefaultColormap, + Focus, + FocusEEPROMCommand, + FocusSettingsCommand); void setup() { Kaleidoscope.setup(); + + EEPROMKeymap.setup(1); + ColormapEffect.max_layers(1); ColormapEffect.activate(); + + DefaultColormap.setup(); } void loop() { diff --git a/plugins/Kaleidoscope-Colormap/README.md b/plugins/Kaleidoscope-Colormap/README.md index f5a438f9..30ea3605 100644 --- a/plugins/Kaleidoscope-Colormap/README.md +++ b/plugins/Kaleidoscope-Colormap/README.md @@ -11,30 +11,60 @@ plugin, which also provides palette editing capabilities. [plugin:focusserial]: Kaleidoscope-FocusSerial.md [plugin:l-p-t]: Kaleidoscope-LED-Palette-Theme.md +It is also possible to set up a default palette and colormap, using the +`DefaultColormap` plugin, also provided by this package. See below for its +documentation. + ## Using the extension To use the extension, include the header, tell it the number of layers you have, -register the `Focus` hooks, and it will do the rest. +register the `Focus` hooks, and it will do the rest. We'll also set up a default +for both the palette, and the colormap. ```c++ #include #include +#include #include #include #include KALEIDOSCOPE_INIT_PLUGINS(EEPROMSettings, + LEDControl, LEDPaletteTheme, ColormapEffect, + DefaultColormap, Focus); +PALETTE( + /* A list of 16 cRGB colors... */ +) + +COLORMAPS( + [0] = COLORMAP( + // List of palette indexes for each key, using the same layout + // as the `KEYMAP` macro does for keys. + ), + [1] = COLORMAP_STACKED( + // List of palette indexes for each key, using the same layout + // as the `KEYMAP_STACKED` macro does for keys. + ) +) + void setup() { Kaleidoscope.setup(); ColormapEffect.max_layers(1); + DefaultColormap.setup(); } ``` +The `PALETTE` and `COLORMAPS` macros are only used for the `DefaultColormap` +plugin, `ColormapEffect` itself makes no use of them. The `PALETTE` must always +contain a full 16-color palette. `COLORMAPS` can define colormaps for as many +layers as one wishes, but the `DefaultColormap` plugin will only copy over as +many as `ColormapEffect` is configured to support. + ## Plugin methods The extension provides an `ColormapEffect` singleton object, with a single method: @@ -44,6 +74,19 @@ The extension provides an `ColormapEffect` singleton object, with a single metho > Tells the extension to reserve space in EEPROM for up to `max` layers. Can > only be called once, any subsequent call will be a no-op. +Also provided is an optional `DefaultColormap` plugin, with two methods: + +### `.setup()` + +> Intended to be called from the `setup()` method of the sketch, it checks if +> the `ColormapEffect` plugin is initialized, and if not, then copies the +> palette and the colormap over from the firmware to EEPROM. + +### `.install()` + +> Same as `.setup()` above, but without the initialized check. Intended to be +> used when one wants to restore the colormap to factory settings. + ## Focus commands ### `colormap.map` @@ -55,6 +98,14 @@ The extension provides an `ColormapEffect` singleton object, with a single metho > ignore anything past the last key on the last layer (as set by the > `.max_layers()` method). +If the `DefaultColormap` plugin is also in use, an additional focus command is +made available: + +### `colormap.install` + +> Copies the default colormap and palette built into the firmware into EEPROM, +> effectively performing a factory reset for both. + ## Dependencies * [Kaleidoscope-EEPROM-Settings](Kaleidoscope-EEPROM-Settings.md) diff --git a/plugins/Kaleidoscope-Colormap/src/Kaleidoscope-Colormap.h b/plugins/Kaleidoscope-Colormap/src/Kaleidoscope-Colormap.h index 994d288d..b06e1e43 100644 --- a/plugins/Kaleidoscope-Colormap/src/Kaleidoscope-Colormap.h +++ b/plugins/Kaleidoscope-Colormap/src/Kaleidoscope-Colormap.h @@ -1,6 +1,6 @@ /* -*- mode: c++ -*- * Kaleidoscope-Colormap -- Per-layer colormap effect - * Copyright (C) 2016, 2017 Keyboard.io, Inc + * Copyright (C) 2016-2022 Keyboard.io, Inc * * This program is free software: you can redistribute it and/or modify it under it under * the terms of the GNU General Public License as published by the Free Software @@ -17,4 +17,5 @@ #pragma once -#include "kaleidoscope/plugin/Colormap.h" // IWYU pragma: export +#include "kaleidoscope/plugin/Colormap.h" // IWYU pragma: export +#include "kaleidoscope/plugin/DefaultColormap.h" // IWYU pragma: export diff --git a/plugins/Kaleidoscope-Colormap/src/kaleidoscope/plugin/Colormap.cpp b/plugins/Kaleidoscope-Colormap/src/kaleidoscope/plugin/Colormap.cpp index 371614d7..ad20194e 100644 --- a/plugins/Kaleidoscope-Colormap/src/kaleidoscope/plugin/Colormap.cpp +++ b/plugins/Kaleidoscope-Colormap/src/kaleidoscope/plugin/Colormap.cpp @@ -1,6 +1,6 @@ /* -*- mode: c++ -*- * Kaleidoscope-Colormap -- Per-layer colormap effect - * Copyright (C) 2016, 2017, 2018, 2021 Keyboard.io, Inc + * Copyright (C) 2016-2022 Keyboard.io, Inc * * This program is free software: you can redistribute it and/or modify it under it under * the terms of the GNU General Public License as published by the Free Software @@ -47,6 +47,17 @@ EventHandlerResult ColormapEffect::onNameQuery() { return ::Focus.sendName(F("ColormapEffect")); } +bool ColormapEffect::isUninitialized() { + return ::LEDPaletteTheme.isThemeUninitialized(map_base_, max_layers_); +} + +void ColormapEffect::updateColorIndexAtPosition(uint8_t layer, uint16_t position, uint8_t palette_index) { + if (layer >= max_layers_) return; + + uint16_t index = Runtime.device().led_count * layer + position; + ::LEDPaletteTheme.updateColorIndexAtPosition(map_base_, index, palette_index); +} + void ColormapEffect::TransientLEDMode::onActivate() { if (!Runtime.has_leds) return; diff --git a/plugins/Kaleidoscope-Colormap/src/kaleidoscope/plugin/Colormap.h b/plugins/Kaleidoscope-Colormap/src/kaleidoscope/plugin/Colormap.h index 76583519..3a9403ed 100644 --- a/plugins/Kaleidoscope-Colormap/src/kaleidoscope/plugin/Colormap.h +++ b/plugins/Kaleidoscope-Colormap/src/kaleidoscope/plugin/Colormap.h @@ -1,6 +1,6 @@ /* -*- mode: c++ -*- * Kaleidoscope-Colormap -- Per-layer colormap effect - * Copyright (C) 2016, 2017, 2018, 2021 Keyboard.io, Inc + * Copyright (C) 2016-2022 Keyboard.io, Inc * * This program is free software: you can redistribute it and/or modify it under it under * the terms of the GNU General Public License as published by the Free Software @@ -38,6 +38,9 @@ class ColormapEffect : public Plugin, EventHandlerResult onNameQuery(); EventHandlerResult onFocusEvent(const char *command); + static bool isUninitialized(); + static void updateColorIndexAtPosition(uint8_t layer, uint16_t position, uint8_t palette_index); + // This class' instance has dynamic lifetime // class TransientLEDMode : public LEDMode { diff --git a/plugins/Kaleidoscope-Colormap/src/kaleidoscope/plugin/DefaultColormap.cpp b/plugins/Kaleidoscope-Colormap/src/kaleidoscope/plugin/DefaultColormap.cpp new file mode 100644 index 00000000..e0eb7f35 --- /dev/null +++ b/plugins/Kaleidoscope-Colormap/src/kaleidoscope/plugin/DefaultColormap.cpp @@ -0,0 +1,94 @@ +/* -*- mode: c++ -*- + * Kaleidoscope-Colormap -- Per-layer colormap effect + * Copyright (C) 2022 Keyboard.io, Inc + * + * This program is free software: you can redistribute it and/or modify it under 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 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 along with + * this program. If not, see . + */ + +#include "kaleidoscope/plugin/Colormap.h" // for Colormap +#include "kaleidoscope/plugin/DefaultColormap.h" + +#include // for F, PSTR, __FlashStringHelper +#include // for Focus, FocusSerial +#include // for LEDControl +#include // for LEDPaletteTheme +#include // for uint8_t, uint16_t + +#include "kaleidoscope/KeyAddr.h" // for KeyAddr +#include "kaleidoscope/Runtime.h" // for Runtime, Runtime_ + +namespace kaleidoscope { +namespace plugin { + +namespace defaultcolormap { +__attribute__((weak)) extern const cRGB palette[] = {}; +__attribute__((weak)) extern bool palette_defined = false; +__attribute__((weak)) extern const uint8_t colormaps[][kaleidoscope_internal::device.matrix_rows * kaleidoscope_internal::device.matrix_columns] = {}; +__attribute__((weak)) extern uint8_t colormap_layers = 0; +} // namespace defaultcolormap + +void DefaultColormap::setup() { + // If the colormap is already initialized, return early. + if (!::ColormapEffect.isUninitialized()) + return; + + install(); +} + +void DefaultColormap::install() { + if (!defaultcolormap::palette_defined) return; + + for (uint8_t i = 0; i < 16; i++) { + cRGB color; + + color.r = pgm_read_byte(&(defaultcolormap::palette[i].r)); + color.g = pgm_read_byte(&(defaultcolormap::palette[i].g)); + color.b = pgm_read_byte(&(defaultcolormap::palette[i].b)); + + ::LEDPaletteTheme.updatePaletteColor(i, color); + } + + if (defaultcolormap::colormap_layers == 0) return; + + for (uint8_t layer = 0; layer < defaultcolormap::colormap_layers; layer++) { + for (int8_t i = 0; i < Runtime.device().numKeys(); i++) { + const int8_t post = Runtime.device().ledDriver().getLedIndex(i); + const uint8_t idx = pgm_read_byte(&(defaultcolormap::colormaps[layer][i])); + ::ColormapEffect.updateColorIndexAtPosition(layer, post, idx); + } + } + Runtime.storage().commit(); + + ::LEDControl.refreshAll(); +} + +EventHandlerResult DefaultColormap::onFocusEvent(const char *command) { + if (!Runtime.has_leds) + return EventHandlerResult::OK; + + const char *cmd = PSTR("colormap.install"); + + if (::Focus.handleHelp(command, cmd)) + return EventHandlerResult::OK; + + if (strcmp_P(command, cmd) != 0) + return EventHandlerResult::OK; + + install(); + return EventHandlerResult::EVENT_CONSUMED; +} + +} // namespace plugin +} // namespace kaleidoscope + +kaleidoscope::plugin::DefaultColormap DefaultColormap; diff --git a/plugins/Kaleidoscope-Colormap/src/kaleidoscope/plugin/DefaultColormap.h b/plugins/Kaleidoscope-Colormap/src/kaleidoscope/plugin/DefaultColormap.h new file mode 100644 index 00000000..315224ce --- /dev/null +++ b/plugins/Kaleidoscope-Colormap/src/kaleidoscope/plugin/DefaultColormap.h @@ -0,0 +1,98 @@ +/* -*- mode: c++ -*- + * Kaleidoscope-Colormap -- Per-layer colormap effect + * Copyright (C) 2022 Keyboard.io, Inc + * + * This program is free software: you can redistribute it and/or modify it under 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 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 along with + * this program. If not, see . + */ + +#pragma once + +#include // for PROGMEM +#include // for uint8_t + +#include "kaleidoscope_internal/device.h" // for device +#include "kaleidoscope/device/device.h" // for cRGB +#include "kaleidoscope/event_handler_result.h" // for EventHandlerResult +#include "kaleidoscope/plugin.h" // for Plugin + +namespace kaleidoscope { +namespace plugin { + +// clang-format off + +#define COLORMAPS(layers...) \ + namespace kaleidoscope { \ + namespace plugin { \ + namespace defaultcolormap { \ + const uint8_t colormaps[][kaleidoscope_internal::device.matrix_rows * kaleidoscope_internal::device.matrix_columns] PROGMEM = { \ + layers \ + }; \ + uint8_t colormap_layers = \ + sizeof(colormaps) / sizeof(*colormaps); \ + } /* defaultcolormap */ \ + } /* plugin */ \ + } /* kaleidoscope */ + +#define __IDENTITY__(X) X + +#ifdef PER_KEY_DATA_STACKED +#define COLORMAP_STACKED(...) \ + { \ + MAP_LIST(__IDENTITY__, PER_KEY_DATA_STACKED(0, __VA_ARGS__)) \ + } +#endif + +#ifdef PER_KEY_DATA +#define COLORMAP(...) \ + { \ + MAP_LIST(__IDENTITY__, PER_KEY_DATA(0, __VA_ARGS__)) \ + } +#endif + +#define PALETTE(p0, p1, p2, p3, p4, p5, p6, p7, \ + p8, p9, pa, pb, pc, pd, pe, pf) \ + namespace kaleidoscope { \ + namespace plugin { \ + namespace defaultcolormap { \ + const cRGB palette[] PROGMEM = { \ + p0, p1, p2, p3, p4, p5, p6, p7, \ + p8, p9, pa, pb, pc, pd, pe, pf \ + }; \ + bool palette_defined = true; \ + } /* defaultcolormap */ \ + } /* plugin */ \ + } /* kaleidoscope */ + +// clang-format on + +namespace defaultcolormap { +extern bool palette_defined; +extern const cRGB palette[]; +extern const uint8_t colormaps[][kaleidoscope_internal::device.matrix_rows * kaleidoscope_internal::device.matrix_columns]; +extern uint8_t colormap_layers; +} // namespace defaultcolormap + +class DefaultColormap : public Plugin { + public: + static void setup(); + + EventHandlerResult onFocusEvent(const char *command); + + private: + static void install(); +}; + +} // namespace plugin +} // namespace kaleidoscope + +extern kaleidoscope::plugin::DefaultColormap DefaultColormap; diff --git a/plugins/Kaleidoscope-FingerPainter/src/kaleidoscope/plugin/FingerPainter.cpp b/plugins/Kaleidoscope-FingerPainter/src/kaleidoscope/plugin/FingerPainter.cpp index 2ed60776..015f5eb1 100644 --- a/plugins/Kaleidoscope-FingerPainter/src/kaleidoscope/plugin/FingerPainter.cpp +++ b/plugins/Kaleidoscope-FingerPainter/src/kaleidoscope/plugin/FingerPainter.cpp @@ -1,6 +1,6 @@ /* -*- mode: c++ -*- * Kaleidoscope-FingerPainter -- On-the-fly keyboard painting. - * Copyright (C) 2017-2021 Keyboard.io, Inc + * Copyright (C) 2017-2022 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 @@ -89,6 +89,7 @@ EventHandlerResult FingerPainter::onKeyEvent(KeyEvent &event) { ::LEDPaletteTheme.updateColorIndexAtPosition(color_base_, Runtime.device().getLedIndex(event.addr), color_index); + Runtime.storage().commit(); return EventHandlerResult::EVENT_CONSUMED; } diff --git a/plugins/Kaleidoscope-LED-Palette-Theme/src/kaleidoscope/plugin/LED-Palette-Theme.cpp b/plugins/Kaleidoscope-LED-Palette-Theme/src/kaleidoscope/plugin/LED-Palette-Theme.cpp index 13cbd3b1..4d43d06e 100644 --- a/plugins/Kaleidoscope-LED-Palette-Theme/src/kaleidoscope/plugin/LED-Palette-Theme.cpp +++ b/plugins/Kaleidoscope-LED-Palette-Theme/src/kaleidoscope/plugin/LED-Palette-Theme.cpp @@ -1,6 +1,6 @@ /* -*- mode: c++ -*- * Kaleidoscope-LED-Palette-Theme -- Palette-based LED theme foundation - * Copyright (C) 2017, 2018, 2019 Keyboard.io, Inc + * Copyright (C) 2017-2022 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 @@ -105,7 +105,21 @@ void LEDPaletteTheme::updateColorIndexAtPosition(uint16_t map_base, uint16_t pos indexes = (color_index << 4) + other; } Runtime.storage().update(map_base + position / 2, indexes); - Runtime.storage().commit(); +} + +void LEDPaletteTheme::updatePaletteColor(uint8_t palette_index, cRGB color) { + color.r ^= 0xff; + color.g ^= 0xff; + color.b ^= 0xff; + + Runtime.storage().put(palette_base_ + palette_index * sizeof(color), color); +} + +bool LEDPaletteTheme::isThemeUninitialized(uint16_t theme_base, uint8_t max_themes) { + bool paletteEmpty = Runtime.storage().isSliceUninitialized(palette_base_, 16 * sizeof(cRGB)); + bool themeEmpty = Runtime.storage().isSliceUninitialized(theme_base, max_themes * Runtime.device().led_count / 2); + + return paletteEmpty && themeEmpty; } EventHandlerResult LEDPaletteTheme::onFocusEvent(const char *command) { @@ -135,11 +149,7 @@ EventHandlerResult LEDPaletteTheme::onFocusEvent(const char *command) { cRGB color; ::Focus.read(color); - color.r ^= 0xff; - color.g ^= 0xff; - color.b ^= 0xff; - - Runtime.storage().put(palette_base_ + i * sizeof(color), color); + updatePaletteColor(i, color); i++; } Runtime.storage().commit(); diff --git a/plugins/Kaleidoscope-LED-Palette-Theme/src/kaleidoscope/plugin/LED-Palette-Theme.h b/plugins/Kaleidoscope-LED-Palette-Theme/src/kaleidoscope/plugin/LED-Palette-Theme.h index 44711dcd..715dc9a5 100644 --- a/plugins/Kaleidoscope-LED-Palette-Theme/src/kaleidoscope/plugin/LED-Palette-Theme.h +++ b/plugins/Kaleidoscope-LED-Palette-Theme/src/kaleidoscope/plugin/LED-Palette-Theme.h @@ -1,6 +1,6 @@ /* -*- mode: c++ -*- * Kaleidoscope-LED-Palette-Theme -- Palette-based LED theme foundation - * Copyright (C) 2017, 2018 Keyboard.io, Inc + * Copyright (C) 2017-2022 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 @@ -37,6 +37,7 @@ class LEDPaletteTheme : public kaleidoscope::Plugin { static const cRGB lookupColorAtPosition(uint16_t theme_base, uint16_t position); static void updateColorIndexAtPosition(uint16_t theme_base, uint16_t position, uint8_t color_index); + static void updatePaletteColor(uint8_t palette_index, cRGB color); static const cRGB lookupPaletteColor(uint8_t palette_index); EventHandlerResult onFocusEvent(const char *command); @@ -44,6 +45,7 @@ class LEDPaletteTheme : public kaleidoscope::Plugin { const char *expected_command, uint16_t theme_base, uint8_t max_themes); + static bool isThemeUninitialized(uint16_t theme_base, uint8_t max_themes); private: static uint16_t palette_base_;