You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Kaleidoscope/plugins/Kaleidoscope-FingerPainter/src/kaleidoscope/plugin/FingerPainter.cpp

129 lines
3.7 KiB

/* -*- mode: c++ -*-
* Kaleidoscope-FingerPainter -- On-the-fly keyboard painting.
* Copyright (C) 2017-2021 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-FingerPainter.h>
#include <Kaleidoscope-EEPROM-Settings.h>
#include <Kaleidoscope-FocusSerial.h>
#include <Kaleidoscope-LEDControl.h>
#include <Kaleidoscope-LED-Palette-Theme.h>
#include "kaleidoscope/keyswitch_state.h"
namespace kaleidoscope {
namespace plugin {
uint16_t FingerPainter::color_base_;
bool FingerPainter::edit_mode_;
EventHandlerResult FingerPainter::onNameQuery() {
return ::Focus.sendName(F("FingerPainter"));
}
EventHandlerResult FingerPainter::onSetup() {
color_base_ = ::LEDPaletteTheme.reserveThemes(1);
return EventHandlerResult::OK;
}
void FingerPainter::update(void) {
::LEDPaletteTheme.updateHandler(color_base_, 0);
}
void FingerPainter::refreshAt(KeyAddr key_addr) {
::LEDPaletteTheme.refreshAt(color_base_, 0, key_addr);
}
void FingerPainter::toggle(void) {
edit_mode_ = !edit_mode_;
}
EventHandlerResult FingerPainter::onKeyEvent(KeyEvent &event) {
if (!Runtime.has_leds || !edit_mode_)
return EventHandlerResult::OK;
if (keyToggledOff(event.state)) {
return EventHandlerResult::OK;
}
if (!event.addr.isValid())
return EventHandlerResult::OK;
// TODO(anyone): The following works only for keyboards with LEDs for each key.
uint8_t color_index = ::LEDPaletteTheme
.lookupColorIndexAtPosition(color_base_,
Runtime.device().getLedIndex(event.addr));
// 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_,
Runtime.device().getLedIndex(event.addr),
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 < Runtime.device().numKeys() / 2; i++) {
Runtime.storage().update(color_base_ + i, 0);
}
Runtime.storage().commit();
return EventHandlerResult::OK;
}
::FingerPainter.activate();
toggle();
return EventHandlerResult::OK;
}
}
}
kaleidoscope::plugin::FingerPainter FingerPainter;