Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Colormap-Overlay plugin #1359

Merged
merged 10 commits into from
Jan 8, 2024
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 60 additions & 0 deletions plugins/Kaleidoscope-Colormap-Overlay/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# Colormap-Overlay

The `Colormap-Overlay` extension provides an easier way to apply color to
specific keys and layers, regardless of the active LED mode. Colors are picked
from a 16-color palette, provided by the [LED-Palette-Theme][plugin:l-p-t]
plugin. The color map is stored in `EEPROM`, and can be easily changed via the
[FocusSerial][plugin:focusserial] 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, provided by the [Colormap][plugin:colormap] package.

[plugin:colormap]: Kaleidoscope-Colormap.md

## 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. We'll also set up a default
for both the palette, and the colormap.

```c++
#include <Kaleidoscope.h>
#include <Kaleidoscope-LEDControl.h>
#include <Kaleidoscope-LED-Palette-Theme.h>
#include <Kaleidoscope-Colormap.h> // DefaultColorMap
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't really like that I need to include this, just to have DefaultColormap.

#include <Kaleidoscope-Colormap-Overlay.h>

PALETTE(
/* A list of 16 cRGB colors... */
)

KALEIDOSCOPE_INIT_PLUGINS(EEPROMSettings,
LEDControl,
ColormapOverlay,
DefaultColormap);

void setup() {
Kaleidoscope.setup();

COLORMAP_OVERLAYS(
// List of overlays, using kaleidoscope::plugin::Overlay
// kaleidoscope::plugin::Overlay({layer}, {key address}, {palette index})
)

ColormapOverlay.setup();
DefaultColormap.setup();
}
```

## Plugin methods

The extension only has a single method:

### `.setup()`

> Intended to be called from the `setup()` method of the sketch, it reserves the
> required space in EEPROM.
Comment on lines +72 to +77
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel this shouldn't be needed at all. I tries moving the contents to ColormapOverlay::onSetup(), but that resulted in the overlays briefly flashing in their assigned color, before being turned off again.

Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
// -*- mode: c++ -*-
/* Kaleidoscope - Firmware for computer input devices
* Copyright (C) 2017-2020 Bart Nagel
*
* 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 <http://www.gnu.org/licenses/>.
*/

#include <Kaleidoscope.h>
#include <Kaleidoscope-LEDControl.h>
#include <Kaleidoscope-LED-Palette-Theme.h>
#include <Kaleidoscope-Colormap.h> // DefaultColorMap
#include <Kaleidoscope-Colormap-Overlay.h>

// clang-format off

KEYMAPS(
[0] = KEYMAP_STACKED
(XXX, 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,
XXX,

XXX, Key_6, Key_7, Key_8, Key_9, Key_0, XXX,
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_RightAlt, Key_N, Key_M, Key_Comma, Key_Period, Key_Slash, Key_Minus,

Key_RightShift, Key_LeftAlt, Key_Spacebar, Key_RightControl,
XXX)
) // KEYMAPS(

// clang-format on

enum {
PALETTE_RED,
PALETTE_GREEN,
PALETTE_BLUE,
PALETTE_BLACK,
PALETTE_UNUSED_1,
PALETTE_UNUSED_2,
PALETTE_UNUSED_3,
PALETTE_UNUSED_4,
PALETTE_UNUSED_5,
PALETTE_UNUSED_6,
PALETTE_UNUSED_7,
PALETTE_UNUSED_8,
PALETTE_UNUSED_9,
PALETTE_UNUSED_10,
PALETTE_UNUSED_11,
PALETTE_UNUSED_12,
};

PALETTE(
[PALETTE_RED] = CRGB(0xff, 0x00, 0x00),
[PALETTE_GREEN] = CRGB(0x00, 0xff, 0x00),
[PALETTE_YELLOW] = CRGB(0x00, 0x00, 0xff),
[PALETTE_BLACK] = CRGB(0x00, 0x00, 0x00),
// unused
[PALETTE_UNUSED_1] = CRGB(0x00, 0x00, 0x00),
[PALETTE_UNUSED_2] = CRGB(0x00, 0x00, 0x00),
[PALETTE_UNUSED_3] = CRGB(0x00, 0x00, 0x00),
[PALETTE_UNUSED_4] = CRGB(0x00, 0x00, 0x00),
[PALETTE_UNUSED_5] = CRGB(0x00, 0x00, 0x00),
[PALETTE_UNUSED_6] = CRGB(0x00, 0x00, 0x00),
[PALETTE_UNUSED_7] = CRGB(0x00, 0x00, 0x00),
[PALETTE_UNUSED_8] = CRGB(0x00, 0x00, 0x00),
[PALETTE_UNUSED_9] = CRGB(0x00, 0x00, 0x00),
[PALETTE_UNUSED_10] = CRGB(0x00, 0x00, 0x00),
[PALETTE_UNUSED_11] = CRGB(0x00, 0x00, 0x00),
[PALETTE_UNUSED_12] = CRGB(0x00, 0x00, 0x00))

KALEIDOSCOPE_INIT_PLUGINS(EEPROMSettings,
LEDControl,
ColormapOverlay,
DefaultColormap);

void setup() {
Kaleidoscope.setup();

COLORMAP_OVERLAYS(
// Make the any key green
kaleidoscope::plugin::Overlay(0, KeyAddr(0, 9), PALETTE_GREEN),
// Make numlock red
kaleidoscope::plugin::Overlay(0, KeyAddr(0, 15), PALETTE_RED),
// Make escape yellow
kaleidoscope::plugin::Overlay(0, KeyAddr(2, 6), PALETTE_YELLOW),
// Disable leds on the palm keys
kaleidoscope::plugin::Overlay(0, KeyAddr(3, 6), PALETTE_BLACK),
kaleidoscope::plugin::Overlay(0, KeyAddr(3, 9), PALETTE_BLACK))

ColormapOverlay.setup();
DefaultColormap.setup();
}

void loop() {
Kaleidoscope.loop();
}
7 changes: 7 additions & 0 deletions plugins/Kaleidoscope-Colormap-Overlay/library.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
name=Kaleidoscope-Colormap-Overlay
version=0.0.0
sentence=Per key colors overlaying active LED effect
maintainer=Kaleidoscope's Developers <[email protected]>
url=https://github.com/keyboardio/Kaleidoscope
author=Keyboardio
paragraph=
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/* Kaleidoscope-Colormap-Overlay -- A LED plugin for Kaleidoscope.
* 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 <http://www.gnu.org/licenses/>.
*/

#pragma once

#include "kaleidoscope/plugin/Colormap-Overlay.h" // IWYU pragma: export
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
/* Kaleidoscope-Colormap-Overlay - A LED plugin for Kaleidoscope.
* 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 <http://www.gnu.org/licenses/>.
*/

#include "kaleidoscope/plugin/Colormap-Overlay.h"

#include <stdint.h> // for uint8_t

#include "kaleidoscope/KeyAddr.h" // for KeyAddr, MatrixAddr, MatrixAddr<>::...
#include "kaleidoscope/device/device.h" // for cRGB, CRGB
#include "kaleidoscope/event_handler_result.h" // for EventHandlerResult, EventHandlerRes...
#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 <Kaleidoscope-LED-Palette-Theme.h> // for LEDPaletteTheme

namespace kaleidoscope {
namespace plugin {
uint16_t ColormapOverlay::map_base_;

void ColormapOverlay::setup() {
map_base_ = ::LEDPaletteTheme.reserveThemes(1);
}
Comment on lines +33 to +35
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As stated above, I would prefer to remove this and move that single line to ColormapOverlay::onSetup(), but that doesn't work as I expect it to.

I'd appreciate some help


bool ColormapOverlay::hasOverlay(KeyAddr k) {
uint8_t layer_index = Layer.lookupActiveLayer(k);
for (uint8_t i{0}; i < overlay_count_; ++i) {
Overlay overlay = overlays_[i];
if (overlay.addr == k) {
if ((overlay.layer == layer_index) ||
(overlay.layer == layer_wildcard)) {
selectedColor = ::LEDPaletteTheme.lookupPaletteColor(overlay.palette_index);
return true;
}
}
}

return false;
}

EventHandlerResult ColormapOverlay::onSetup() {
return EventHandlerResult::OK;
}

void ColormapOverlay::setKeyboardLEDColors() {
if (!Runtime.has_leds)
return;

for (auto key_addr : KeyAddr::all()) {
if (ColormapOverlay::hasOverlay(key_addr)) {
::LEDControl.setCrgbAt(KeyAddr(key_addr), selectedColor);
} else {
::LEDControl.refreshAt(KeyAddr(key_addr));
}
}
}

EventHandlerResult ColormapOverlay::afterEachCycle() {
setKeyboardLEDColors();

return EventHandlerResult::OK;
}

} // namespace plugin
} // namespace kaleidoscope

kaleidoscope::plugin::ColormapOverlay ColormapOverlay;
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
/* Kaleidoscope-Colormap-Overlay - A LED plugin for Kaleidoscope.
* 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 <http://www.gnu.org/licenses/>.
*/

#pragma once

#include <stdint.h> // for uint8_t

#include "kaleidoscope/KeyAddr.h" // for KeyAddr
#include "kaleidoscope/device/device.h" // for cRGB
#include "kaleidoscope/event_handler_result.h" // for EventHandlerResult
#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

namespace kaleidoscope {
namespace plugin {

// Data structure for an individual qukey
struct Overlay {
int8_t layer;
KeyAddr addr;
uint8_t palette_index;

// This is the constructor that should be used when creating a Overlay that
// will be used by ColormapOverlay
constexpr Overlay(int8_t layer, KeyAddr k, uint8_t palette_index)
: layer(layer), addr(k), palette_index(palette_index) {}
};

class ColormapOverlay : public kaleidoscope::Plugin {
public:
static void setup();
// Function for defining the array of overlays. It's a template function that
// takes as its sole argument an array reference of size `_overlay_count`, so
// there's no need to use `sizeof` to calculate the correct size, and pass it
// as a separate parameter.
template<uint8_t _overlay_count>
void configureOverlays(Overlay const (&overlays)[_overlay_count]) {
overlays_ = overlays;
overlay_count_ = _overlay_count;
}

// A wildcard value for a qukey that exists on every layer.
static constexpr int8_t layer_wildcard{-1};

EventHandlerResult onSetup();
EventHandlerResult afterEachCycle();

private:
static uint16_t map_base_;
Overlay const *overlays_;
uint8_t overlay_count_;
cRGB selectedColor;

bool hasOverlay(KeyAddr k);
void setKeyboardLEDColors();
};

} // namespace plugin
} // namespace kaleidoscope

extern kaleidoscope::plugin::ColormapOverlay ColormapOverlay;

#define COLORMAP_OVERLAYS(overlays...) \
{ \
static kaleidoscope::plugin::Overlay const overlays_[] = {overlays}; \
ColormapOverlay.configureOverlays(overlays_); \
}
Loading