Colormap: Add a new (optional) plugin: DefaultColormap

This new plugin lets us store a default palette and colormap in PROGMEM.

Rather than teaching Colormap to pull from either EEPROM or PROGMEM, this
implements an entirely separate plugin, `DefaultColormap`, which is able
to *push* a palette and colormaps into Colormap.

When `DefaultColormap.setup()` is called, it checks if Colormap's storage area
is empty (both palette and the map must be empty), and if so, copies the
built-in palette and colormap over, and forces a refresh, and it has done its
job.

It does provide an additional Focus command too, `colormap.install`, which will
forcibly copy both palette and colormaps over. Useful for resetting back to a
factory setting.

Signed-off-by: Gergely Nagy <algernon@keyboard.io>
pull/1188/head
Gergely Nagy 3 years ago
parent 0c6f608704
commit e59a09e19e
No known key found for this signature in database
GPG Key ID: AC1E90BAC433F68F

@ -11,30 +11,60 @@ plugin, which also provides palette editing capabilities.
[plugin:focusserial]: Kaleidoscope-FocusSerial.md [plugin:focusserial]: Kaleidoscope-FocusSerial.md
[plugin:l-p-t]: Kaleidoscope-LED-Palette-Theme.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 ## Using the extension
To use the extension, include the header, tell it the number of layers you have, 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++ ```c++
#include <Kaleidoscope.h> #include <Kaleidoscope.h>
#include <Kaleidoscope-EEPROM-Settings.h> #include <Kaleidoscope-EEPROM-Settings.h>
#include <Kaleidoscope-LEDControl.h>
#include <Kaleidoscope-Colormap.h> #include <Kaleidoscope-Colormap.h>
#include <Kaleidoscope-FocusSerial.h> #include <Kaleidoscope-FocusSerial.h>
#include <Kaleidoscope-LED-Palette-Theme.h> #include <Kaleidoscope-LED-Palette-Theme.h>
KALEIDOSCOPE_INIT_PLUGINS(EEPROMSettings, KALEIDOSCOPE_INIT_PLUGINS(EEPROMSettings,
LEDControl,
LEDPaletteTheme, LEDPaletteTheme,
ColormapEffect, ColormapEffect,
DefaultColormap,
Focus); 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() { void setup() {
Kaleidoscope.setup(); Kaleidoscope.setup();
ColormapEffect.max_layers(1); 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 ## Plugin methods
The extension provides an `ColormapEffect` singleton object, with a single method: 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 > 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. > 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 ## Focus commands
### `colormap.map` ### `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 > ignore anything past the last key on the last layer (as set by the
> `.max_layers()` method). > `.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 ## Dependencies
* [Kaleidoscope-EEPROM-Settings](Kaleidoscope-EEPROM-Settings.md) * [Kaleidoscope-EEPROM-Settings](Kaleidoscope-EEPROM-Settings.md)

@ -1,6 +1,6 @@
/* -*- mode: c++ -*- /* -*- mode: c++ -*-
* Kaleidoscope-Colormap -- Per-layer colormap effect * 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 * 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 * the terms of the GNU General Public License as published by the Free Software
@ -18,3 +18,4 @@
#pragma once #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

@ -1,6 +1,6 @@
/* -*- mode: c++ -*- /* -*- mode: c++ -*-
* Kaleidoscope-Colormap -- Per-layer colormap effect * 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 * 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 * 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")); 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() { void ColormapEffect::TransientLEDMode::onActivate() {
if (!Runtime.has_leds) if (!Runtime.has_leds)
return; return;

@ -1,6 +1,6 @@
/* -*- mode: c++ -*- /* -*- mode: c++ -*-
* Kaleidoscope-Colormap -- Per-layer colormap effect * 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 * 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 * 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 onNameQuery();
EventHandlerResult onFocusEvent(const char *command); 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 // This class' instance has dynamic lifetime
// //
class TransientLEDMode : public LEDMode { class TransientLEDMode : public LEDMode {

@ -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 <http://www.gnu.org/licenses/>.
*/
#include "kaleidoscope/plugin/Colormap.h" // for Colormap
#include "kaleidoscope/plugin/DefaultColormap.h"
#include <Arduino.h> // for F, PSTR, __FlashStringHelper
#include <Kaleidoscope-FocusSerial.h> // for Focus, FocusSerial
#include <Kaleidoscope-LEDControl.h> // for LEDControl
#include <Kaleidoscope-LED-Palette-Theme.h> // for LEDPaletteTheme
#include <stdint.h> // 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;

@ -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 <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <Arduino.h> // for PROGMEM
#include <stdint.h> // 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;
Loading…
Cancel
Save