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/src/kaleidoscope/plugin/LED-Palette-Theme.cpp

179 lines
4.9 KiB

/* -*- mode: c++ -*-
* Kaleidoscope-LED-Palette-Theme -- Palette-based LED theme foundation
* 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-LED-Palette-Theme.h>
#include <Kaleidoscope-EEPROM-Settings.h>
#include <Kaleidoscope-FocusSerial.h>
#include <EEPROM.h>
namespace kaleidoscope {
namespace plugin {
uint16_t LEDPaletteTheme::palette_base_;
EventHandlerResult LEDPaletteTheme::onSetup(void) {
if (!palette_base_)
palette_base_ = ::EEPROMSettings.requestSlice(16 * sizeof(cRGB));
return EventHandlerResult::OK;
}
uint16_t LEDPaletteTheme::reserveThemes(uint8_t max_themes) {
return ::EEPROMSettings.requestSlice(max_themes * ROWS * COLS / 2);
}
void LEDPaletteTheme::updateHandler(uint16_t theme_base, uint8_t theme) {
uint16_t map_base = theme_base + (theme * ROWS * COLS / 2);
for (uint16_t pos = 0; pos < ROWS * COLS; pos++) {
cRGB color = lookupColorAtPosition(map_base, pos);
::LEDControl.setCrgbAt(pos, color);
8 years ago
}
}
void LEDPaletteTheme::refreshAt(uint16_t theme_base, uint8_t theme, byte row, byte col) {
uint16_t map_base = theme_base + (theme * ROWS * COLS / 2);
uint16_t pos = KeyboardHardware.getLedIndex(row, col);
cRGB color = lookupColorAtPosition(map_base, pos);
::LEDControl.setCrgbAt(pos, color);
}
const uint8_t LEDPaletteTheme::lookupColorIndexAtPosition(uint16_t map_base, uint16_t position) {
uint8_t color_index;
color_index = EEPROM.read(map_base + position / 2);
if (position % 2)
color_index &= ~0xf0;
8 years ago
else
color_index >>= 4;
return color_index;
}
const cRGB LEDPaletteTheme::lookupColorAtPosition(uint16_t map_base, uint16_t position) {
uint8_t color_index = lookupColorIndexAtPosition(map_base, position);
return lookupPaletteColor(color_index);
}
const cRGB LEDPaletteTheme::lookupPaletteColor(uint8_t color_index) {
8 years ago
cRGB color;
EEPROM.get(palette_base_ + color_index * sizeof(cRGB), color);
8 years ago
return color;
}
void LEDPaletteTheme::updateColorIndexAtPosition(uint16_t map_base, uint16_t position, uint8_t color_index) {
8 years ago
uint8_t indexes;
indexes = EEPROM.read(map_base + position / 2);
if (position % 2) {
8 years ago
uint8_t other = indexes >> 4;
indexes = (other << 4) + color_index;
8 years ago
} else {
uint8_t other = indexes & ~0xf0;
indexes = (color_index << 4) + other;
8 years ago
}
EEPROM.update(map_base + position / 2, indexes);
}
EventHandlerResult LEDPaletteTheme::onFocusEvent(const char *command) {
const char *cmd = PSTR("palette");
if (::Focus.handleHelp(command, cmd))
return EventHandlerResult::OK;
if (strcmp_P(command, cmd) != 0)
return EventHandlerResult::OK;
8 years ago
if (Serial.peek() == '\n') {
for (uint8_t i = 0; i < 16; i++) {
cRGB color;
EEPROM.get(palette_base_ + i * sizeof(color), color);
8 years ago
::Focus.printColor(color.r, color.g, color.b);
::Focus.printSpace();
}
8 years ago
Serial.println();
return EventHandlerResult::EVENT_CONSUMED;
8 years ago
}
8 years ago
uint8_t i = 0;
while (i < 16 && Serial.peek() != '\n') {
cRGB color;
8 years ago
color.r = Serial.parseInt();
color.g = Serial.parseInt();
color.b = Serial.parseInt();
EEPROM.put(palette_base_ + i * sizeof(color), color);
8 years ago
i++;
}
::LEDControl.refreshAll();
return EventHandlerResult::EVENT_CONSUMED;
}
EventHandlerResult LEDPaletteTheme::themeFocusEvent(const char *command,
6 years ago
const char *expected_command,
uint16_t theme_base,
uint8_t max_themes) {
if (::Focus.handleHelp(command, expected_command))
return EventHandlerResult::OK;
if (strcmp_P(command, expected_command) != 0)
return EventHandlerResult::OK;
uint16_t max_index = (max_themes * ROWS * COLS) / 2;
8 years ago
if (Serial.peek() == '\n') {
for (uint16_t pos = 0; pos < max_index; pos++) {
uint8_t indexes = EEPROM.read(theme_base + pos);
8 years ago
::Focus.printNumber(indexes >> 4);
::Focus.printSpace();
::Focus.printNumber(indexes & ~0xf0);
::Focus.printSpace();
}
8 years ago
Serial.println();
return EventHandlerResult::EVENT_CONSUMED;
8 years ago
}
uint16_t pos = 0;
8 years ago
while ((Serial.peek() != '\n') && (pos < max_index)) {
8 years ago
uint8_t idx1 = Serial.parseInt();
uint8_t idx2 = Serial.parseInt();
uint8_t indexes = (idx1 << 4) + idx2;
EEPROM.update(theme_base + pos, indexes);
pos++;
8 years ago
}
::LEDControl.refreshAll();
return EventHandlerResult::EVENT_CONSUMED;
}
}
}
kaleidoscope::plugin::LEDPaletteTheme LEDPaletteTheme;