From b86f79d805e73fc08ab478455da59c47436f7105 Mon Sep 17 00:00:00 2001 From: dakkar Date: Fri, 15 Feb 2019 16:30:30 +0000 Subject: it works!! --- color-picker.h | 271 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 269 insertions(+), 2 deletions(-) diff --git a/color-picker.h b/color-picker.h index 9aa9f1f..b72df97 100644 --- a/color-picker.h +++ b/color-picker.h @@ -1,27 +1,294 @@ // -*- mode: c++ -*- #pragma once -#include +#include +#include class ColorPicker : public kaleidoscope::plugin::LEDMode { public: - ColorPicker(void) : current_index(0), colors{}, map{} { } + ColorPicker(void) : current_index(0), which_half(BOTH_HALVES), + colors{}, map{}, + hsv_colors{ + { .h=0, .s=150, .v=128 }, + { .h=32, .s=150, .v=128 }, + { .h=64, .s=150, .v=128 }, + { .h=96, .s=150, .v=128 }, + { .h=128, .s=150, .v=128 }, + { .h=160, .s=150, .v=128 }, + { .h=192, .s=150, .v=128 }, + { .h=224, .s=150, .v=128 }, + } + { + for (uint8_t i=0;i<16;++i) { + hsv& col = hsv_colors[i]; + colors[i] = hsvToRgb(col.h,col.s,col.v); + } + } kaleidoscope::EventHandlerResult onKeyswitchEvent(Key &mapped_key, byte row, byte col, uint8_t key_state) { if (!Kaleidoscope.has_leds || !is_active()) return kaleidoscope::EventHandlerResult::OK; + // only care at press time + if (!keyToggledOn(key_state)) + return kaleidoscope::EventHandlerResult::EVENT_CONSUMED; + + // uh? + if (row >= ROWS || col >= COLS) + return kaleidoscope::EventHandlerResult::EVENT_CONSUMED; + + // pressing a Fn makes that half the "editing" half; pressing it + // again disables editing + + picker_key key = whichKey(row,col); + switch (key) { + case OFF: + break; + case SHOW: + map[row][col] = current_index; break; + case SWITCH_LEFT: + which_half = which_half == RIGHT_HALF ? BOTH_HALVES : RIGHT_HALF; break; + case SWITCH_RIGHT: + which_half = which_half == LEFT_HALF ? BOTH_HALVES : LEFT_HALF; break; + case COLOR_1 ... COLOR_8: + current_index = key - COLOR_1; break; + case HUE_M10: + updateCurrentColor(-10,0,0); break; + case HUE_M1: + updateCurrentColor(-1,0,0); break; + case HUE_P1: + updateCurrentColor(+1,0,0); break; + case HUE_P10: + updateCurrentColor(+10,0,0); break; + case SAT_M10: + updateCurrentColor(0,-10,0); break; + case SAT_M1: + updateCurrentColor(0,-1,0); break; + case SAT_P1: + updateCurrentColor(0,+1,0); break; + case SAT_P10: + updateCurrentColor(0,+10,0); break; + case VAL_M10: + updateCurrentColor(0,0,-10); break; + case VAL_M1: + updateCurrentColor(0,0,-1); break; + case VAL_P1: + updateCurrentColor(0,0,+1); break; + case VAL_P10: + updateCurrentColor(0,0,+10); break; + }; + return kaleidoscope::EventHandlerResult::EVENT_CONSUMED; } +protected: + void update(void) { + for (uint8_t r = 0; r < ROWS; r++) { + for (uint8_t c = 0; c < COLS; c++) { + LEDControl.setCrgbAt(r, c, getColor(r,c)); + } + } + } + void refreshAt(byte r, byte c) final { + LEDControl.setCrgbAt(r, c, getColor(r,c)); + } + private: uint8_t current_index; + enum { BOTH_HALVES, LEFT_HALF, RIGHT_HALF } which_half; cRGB colors[16]; uint8_t map[ROWS][COLS]; + struct hsv { uint8_t h; uint8_t s; uint8_t v; } + hsv_colors[16]; + + static inline uint8_t add_and_clamp(uint8_t value, int8_t delta) { + int16_t result = ((int16_t)value) + delta; + if (result < 0) return 0; + if (result > 255) return 255; + return result; + } + static inline uint8_t add_and_wrap(uint8_t value, int8_t delta) { + int16_t result = ((int16_t)value) + delta; + if (result < 0) return result+255; + if (result > 255) return result-255; + return result; + } + + void updateCurrentColor(int8_t delta_h, int8_t delta_s, int8_t delta_v) { + hsv& color = hsv_colors[current_index]; + color.h = add_and_wrap(color.h,delta_h); + color.s = add_and_clamp(color.s,delta_s); + color.v = add_and_clamp(color.v,delta_v); + colors[current_index] = hsvToRgb(color.h,color.s,color.v); + } + bool is_active() { return LEDControl.get_mode() == this; } + + typedef enum { OFF, SHOW, + SWITCH_LEFT, SWITCH_RIGHT, + COLOR_1, COLOR_2, COLOR_3, COLOR_4, + COLOR_5, COLOR_6, COLOR_7, COLOR_8, + HUE_M10, HUE_M1, HUE_P1, HUE_P10, + SAT_M10, SAT_M1, SAT_P1, SAT_P10, + VAL_M10, VAL_M1, VAL_P1, VAL_P10 } + picker_key; + + picker_key whichKey(byte row, byte col) { + if (row == 3 && col == 6) { + return SWITCH_LEFT; + } + else if (row == 3 && col == 9) { + return SWITCH_RIGHT; + } + else if (row == 0 && col == 6) { + return OFF; // LED key, always off + } + + // non-editing half? show it + if (which_half == BOTH_HALVES || + (col < 8 && which_half == LEFT_HALF) || + (col >= 8 && which_half == RIGHT_HALF)) { + return SHOW; + } + + // pretend we're always showing the right half, by changing col if we're not + if (which_half == LEFT_HALF) { + switch (col) { + case 8: col=6; break; + case 9: col=7; break; + case 10: col=2; break; + case 11: col=3; break; + case 12: col=4; break; + case 13: col=5; break; + case 14: col=0; break; + case 15: col=1; break; + } + } + + switch (col) { + case 0: + switch (row) { + case 0: + return COLOR_1; + case 1: + return COLOR_2; + case 2: + return COLOR_3; + case 3: + return COLOR_4; + default: + return OFF; + }; + case 1: + switch (row) { + case 0: + return COLOR_5; + case 1: + return COLOR_6; + case 2: + return COLOR_7; + case 3: + return COLOR_8; + default: + return OFF; + }; + case 2: + switch (row) { + case 1: + return HUE_M10; + case 2: + return SAT_M10; + case 3: + return VAL_M10; + default: + return OFF; + }; + case 3: + switch (row) { + case 1: + return HUE_M1; + case 2: + return SAT_M1; + case 3: + return VAL_M1; + default: + return OFF; + }; + case 4: + switch (row) { + case 1: + return HUE_P1; + case 2: + return SAT_P1; + case 3: + return VAL_P1; + default: + return OFF; + }; + case 5: + switch (row) { + case 1: + return HUE_P10; + case 2: + return SAT_P10; + case 3: + return VAL_P10; + default: + return OFF; + }; + default: + return OFF; + }; + + // won't be reached + return SHOW; + } + + cRGB getColor(byte row, byte col) { + picker_key key = whichKey(row,col); + switch (key) { + case SHOW: + return colors[map[row][col]]; + case OFF: + case SWITCH_LEFT: + case SWITCH_RIGHT: + return CRGB(0,0,0); + case COLOR_1...COLOR_8: + return colors[key - COLOR_1]; + + case HUE_M10: + return hsvToRgb(add_and_wrap(hsv_colors[current_index].h,-10),255,128); + case HUE_M1: + return hsvToRgb(add_and_wrap(hsv_colors[current_index].h,-1),255,128); + case HUE_P1: + return hsvToRgb(add_and_wrap(hsv_colors[current_index].h,+1),255,128); + case HUE_P10: + return hsvToRgb(add_and_wrap(hsv_colors[current_index].h,+10),255,128); + case SAT_M10: + return hsvToRgb(hsv_colors[current_index].h,50,128); + case SAT_M1: + return hsvToRgb(hsv_colors[current_index].h,100,128); + case SAT_P1: + return hsvToRgb(hsv_colors[current_index].h,150,128); + case SAT_P10: + return hsvToRgb(hsv_colors[current_index].h,200,128); + + case VAL_M10: + return hsvToRgb(hsv_colors[current_index].h,128,50); + case VAL_M1: + return hsvToRgb(hsv_colors[current_index].h,128,100); + case VAL_P1: + return hsvToRgb(hsv_colors[current_index].h,128,150); + case VAL_P10: + return hsvToRgb(hsv_colors[current_index].h,128,200); + }; + + // won't be reached + return colors[map[row][col]]; + } }; ColorPicker theColorPicker; -- cgit v1.2.3