diff options
-rw-r--r-- | Model01-Firmware.ino | 2 | ||||
-rw-r--r-- | color-picker.h | 335 | ||||
-rw-r--r-- | color-themes.h | 48 | ||||
-rw-r--r-- | key-classes.h | 6 | ||||
-rw-r--r-- | keymaps.h | 42 |
5 files changed, 389 insertions, 44 deletions
diff --git a/Model01-Firmware.ino b/Model01-Firmware.ino index a3d6d95..2bfa9fc 100644 --- a/Model01-Firmware.ino +++ b/Model01-Firmware.ino @@ -10,6 +10,7 @@ #include "keymap-wrapper.h" #include "color-themes.h" +//#include "color-picker.h" /* plugins */ #include "kaleidoscope/plugin/EEPROM-Settings.h" @@ -31,6 +32,7 @@ KALEIDOSCOPE_INIT_PLUGINS( LEDControl, DakkarColorDark, DakkarColorBright, + //theColorPicker, Macros, MouseKeys, diff --git a/color-picker.h b/color-picker.h new file mode 100644 index 0000000..d442c79 --- /dev/null +++ b/color-picker.h @@ -0,0 +1,335 @@ +// -*- mode: c++ -*- +#pragma once + +/* + this class implements a color theme editor as a LED mode + + when this mode is active, nothing gets sent to the host + + the Fn keys switch into editing mode, with that half housing the controls + + the controls are: + + * 8 keys for the 8 colors we currently use + * 3 rows of 4 keys to change the active color in the HSV space + + pressing a key on the non-control half of the keyboard assigns the + current color to that key + */ + +#include <kaleidoscope/plugin/LEDControl.h> +#include <kaleidoscope/plugin/LEDControl/LEDUtils.h> +#include <kaleidoscope/plugin/FocusSerial.h> + +class ColorPicker : public kaleidoscope::plugin::LEDMode { +public: + 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; + } + + kaleidoscope::EventHandlerResult onFocusEvent(const char *command) { + if (Focus.handleHelp(command, PSTR("color-picker.dump"))) + return kaleidoscope::EventHandlerResult::OK; + + if (strncmp_P(command, PSTR("color-picker."), 13) != 0) + return kaleidoscope::EventHandlerResult::OK; + + if (strcmp_P(command + 13, PSTR("dump")) != 0) + return kaleidoscope::EventHandlerResult::OK; + + for (uint8_t i=0;i<16;++i) { + Focus.send(F("color"),i,colors[i],Focus.NEWLINE); + } + Focus.send(F("map\n")); + for (uint8_t r=0;r<ROWS;++r) { + for (uint8_t c=0;c<COLS;++c) { + Focus.send(map[r][c]); + } + Focus.send(Focus.NEWLINE); + } + + 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; diff --git a/color-themes.h b/color-themes.h index a6287ca..b612fd0 100644 --- a/color-themes.h +++ b/color-themes.h @@ -22,31 +22,39 @@ const cRGB num_breathe() { return breath_compute(170); } static constexpr DakkarColor::colorSrc dark_colors[COLOR_COUNT] = { - [Off] = D_C(0,0,0), - [Base] = D_C(0,0,0), - [Lnch] = D_C(0,0,150), - [Wind] = D_C(150,0,0), - [View] = D_C(0,150,0), - [Ms] = D_C(100,100,0), - [MsB] = D_C(50,0,50), - [MsW] = D_C(0,50,50), - [Func] = D_C(100,100,150), - [Num] = D_C(150,0,0), + [Off] = D_C(0,0,0), + [Base] = D_C(0,0,0), + [Base2] = D_C(89,89,89), + [Screen] = D_C(78,13,80), + [Lnch] = D_C(128,25,87), + [Wind] = D_C(65,128,52), + [View] = D_C(51,102,128), + [Media] = D_C(123,128,47), + [Ms] = D_C(128,126,21), + [MsB] = D_C(108,26,0), + [MsW] = D_C(110,128,27), + [Func] = D_C(115,0,128), + [Func2] = D_C(14,43,80), + [Num] = D_C(150,0,0), [NumBreathe] = D_F(num_breathe), }; static constexpr DakkarColor::colorSrc bright_colors[COLOR_COUNT] = { - [Off] = D_C(0,0,0), - [Base] = D_C(50,50,50), - [Lnch] = D_C(0,0,100), - [Wind] = D_C(100,0,0), - [View] = D_C(0,100,0), - [Ms] = D_C(50,50,0), - [MsB] = D_C(30,0,30), - [MsW] = D_C(0,30,30), - [Func] = D_C(50,50,80), - [Num] = D_C(100,0,0), + [Off] = D_C(0,0,0), + [Base] = D_C(50,50,50), + [Base2] = D_C(50,50,50), + [Screen] = D_C(78,13,80), + [Lnch] = D_C(128,25,87), + [Wind] = D_C(65,128,52), + [View] = D_C(51,102,128), + [Media] = D_C(123,128,47), + [Ms] = D_C(128,126,21), + [MsB] = D_C(108,26,0), + [MsW] = D_C(110,128,27), + [Func] = D_C(115,0,128), + [Func2] = D_C(14,43,80), + [Num] = D_C(150,0,0), [NumBreathe] = D_F(num_breathe), }; diff --git a/key-classes.h b/key-classes.h index 3ab6fa3..eb3a50b 100644 --- a/key-classes.h +++ b/key-classes.h @@ -3,10 +3,10 @@ typedef enum { Off, - Base, - Lnch, Wind, View, + Base,Base2, + Screen, Lnch, Wind, View, Media, Ms, MsB, MsW, - Func, + Func,Func2, Num, NumBreathe, COLOR_COUNT, @@ -54,38 +54,38 @@ ColorKeymaps( CK(M(MACRO_VERSION_INFO),Base), CK(XXX,Off), CK(Key_Keypad7,Num), CK(Key_Keypad8,Num), CK(Key_Keypad9,Num), CK(Key_KeypadSubtract,Num), CK(___,NumBreathe), CK(XXX,Off), CK(XXX,Off), CK(Key_Keypad4,Num), CK(Key_Keypad5,Num), CK(Key_Keypad6,Num), CK(Key_KeypadAdd,Num), CK(XXX,Off), - CK(XXX,Off), CK(Key_Keypad1,Num), CK(Key_Keypad2,Num), CK(Key_Keypad3,Num), CK(Key_Equals,Num), CK(XXX,Off), - CK(XXX,Off), CK(XXX,Off), CK(Key_Keypad0,Num), CK(Key_KeypadDot,Num), CK(Key_KeypadMultiply,Num), CK(Key_KeypadDivide,Num), CK(Key_Enter,Num), + CK(XXX,Off), CK(Key_Keypad1,Num), CK(Key_Keypad2,Num), CK(Key_Keypad3,Num), CK(Key_KeypadEquals,Num), CK(XXX,Off), + CK(XXX,Off), CK(XXX,Off), CK(Key_Keypad0,Num), CK(Key_KeypadDot,Num), CK(Key_KeypadMultiply,Num), CK(Key_KeypadDivide,Num), CK(Key_KeypadEnter,Num), CK(___,Off), CK(___,Off), CK(___,Off), CK(___,Off), CK(___,Off)), [FUNCTION] = KEYMAP_STACKED - (CK(XXX,Off), CK(Key_F1,Func), CK(Key_F2,Func), CK(Key_F3,Func), CK(Key_F4,Func), CK(Key_F5,Func), CK(Key_CapsLock,Func), - CK(Key_Tab,Func), CK(XXX,Off), CK(Key_mouseUp,Ms), CK(XXX,Off), CK(Key_mouseBtnR,MsB), CK(Key_mouseWarpEnd,MsW), CK(Key_mouseWarpNE,MsW), - CK(Key_Home,Func), CK(Key_mouseL,Ms), CK(Key_mouseDn,Ms), CK(Key_mouseR,Ms), CK(Key_mouseBtnL,MsB), CK(Key_mouseWarpNW,MsW), - CK(Key_End,Func), CK(Key_PrintScreen,Func), CK(Key_Insert,Func), CK(XXX,Off), CK(Key_mouseBtnM,MsB), CK(Key_mouseWarpSW,MsW), CK(Key_mouseWarpSE,MsW), - CK(___,Off), CK(Key_Delete,Func), CK(___,Off), CK(___,Off), + (CK(XXX,Off), CK(Key_F1,Func), CK(Key_F2,Func), CK(Key_F3,Func), CK(Key_F4,Func), CK(Key_F5,Func), CK(___,Off), + CK(Key_Tab,Func2), CK(XXX,Off), CK(Key_mouseUp,Ms), CK(XXX,Off), CK(Key_mouseBtnR,MsB), CK(Key_mouseWarpEnd,MsW), CK(Key_mouseWarpNE,MsW), + CK(Key_Home,Func2), CK(Key_mouseL,Ms), CK(Key_mouseDn,Ms), CK(Key_mouseR,Ms), CK(Key_mouseBtnL,MsB), CK(Key_mouseWarpNW,MsW), + CK(Key_End,Func2), CK(Key_PrintScreen,Func2), CK(Key_Insert,Func2), CK(XXX,Off), CK(Key_mouseBtnM,MsB), CK(Key_mouseWarpSW,MsW), CK(Key_mouseWarpSE,MsW), + CK(___,Off), CK(Key_Delete,Func2), CK(___,Off), CK(___,Off), CK(___,Off), - CK(XXX,Off), CK(Key_F6,Func), CK(Key_F7,Func), CK(Key_F8,Func), CK(Key_F9,Func), CK(Key_F10,Func), CK(Key_F11,Func), - CK(XXX,Off), CK(XXX,Off), CK(Key_LeftCurlyBracket,Func), CK(Key_RightCurlyBracket,Func), CK(Key_LeftBracket,Func), CK(Key_RightBracket,Func), CK(Key_F12,Func), - CK(Key_LeftArrow,Func), CK(Key_DownArrow,Func), CK(Key_UpArrow,Func), CK(Key_RightArrow,Func), CK(XXX,Off), CK(XXX,Off), - CK(Key_PcApplication,Func), CK(XXX,Off), CK(XXX,Off), CK(XXX,Off), CK(XXX,Off), CK(Key_Backslash,Func), CK(Key_Pipe,Func), - CK(___,Off), CK(___,Off), CK(Key_Enter,Func), CK(___,Off), + CK(XXX,Off), CK(Key_F6,Func), CK(Key_F7,Func), CK(Key_F8,Func), CK(Key_F9,Func), CK(Key_F10,Func), CK(Key_F11,Func), + CK(XXX,Off), CK(XXX,Off), CK(Key_LeftCurlyBracket,Base2), CK(Key_RightCurlyBracket,Base2), CK(Key_LeftBracket,Base2), CK(Key_RightBracket,Base2), CK(Key_F12,Func), + CK(Key_LeftArrow,Base2), CK(Key_DownArrow,Base2), CK(Key_UpArrow,Base2), CK(Key_RightArrow,Base2), CK(XXX,Off), CK(XXX,Off), + CK(Key_PcApplication,Func2), CK(XXX,Off), CK(XXX,Off), CK(XXX,Off), CK(XXX,Off), CK(Key_Backslash,Base2), CK(Key_Pipe,Base2), + CK(___,Off), CK(___,Off), CK(Key_Enter,Func2), CK(___,Off), CK(___,Off)), [FVWM] = KEYMAP_STACKED - (CK(XXX,Off), CK(Key_BacklightDown,Lnch), CK(Key_BacklightUp,Lnch), CK(LALT(Key_F1),Lnch), CK(LALT(Key_F2),Lnch), CK(XXX,Off), CK(___,Off), - CK(XXX,Off), CK(XXX,Off), CK(XXX,Off), CK(XXX,Off), CK(XXX,Off), CK(XXX,Off), CK(XXX,Off), - CK(XXX,Off), CK(XXX,Off), CK(LALT(Key_Keypad4),Wind), CK(LALT(Key_Keypad2),Wind), CK(LALT(Key_Keypad8),Wind), CK(LALT(Key_Keypad6),Wind), - CK(XXX,Off), CK(XXX,Off), CK(XXX,Off), CK(XXX,Off), CK(XXX,Off), CK(XXX,Off), CK(LALT(Key_KeypadMultiply),Wind), - CK(___,Off), CK(LALT(Key_Backtick),Lnch), CK(LSHIFT(LALT(Key_Backtick)),Lnch), CK(___,Off), + (CK(XXX,Off), CK(Key_BacklightDown,Screen), CK(Key_BacklightUp,Screen), CK(LALT(Key_F1),Lnch), CK(LALT(Key_F2),Lnch), CK(XXX,Off), CK(___,Off), + CK(XXX,Off), CK(XXX,Off), CK(XXX,Off), CK(XXX,Off), CK(XXX,Off), CK(XXX,Off), CK(XXX,Off), + CK(XXX,Off), CK(XXX,Off), CK(LALT(Key_Keypad4),Wind), CK(LALT(Key_Keypad2),Wind), CK(LALT(Key_Keypad8),Wind), CK(LALT(Key_Keypad6),Wind), + CK(LALT(Key_W),Wind), CK(XXX,Off), CK(XXX,Off), CK(XXX,Off), CK(XXX,Off), CK(XXX,Off), CK(LALT(Key_KeypadMultiply),Wind), + CK(___,Off), CK(LALT(Key_Backtick),Lnch), CK(LSHIFT(LALT(Key_Backtick)),Lnch), CK(___,Off), CK(___,Off), - CK(XXX,Off), CK(Consumer_Mute,Lnch), CK(Consumer_VolumeDecrement,Lnch), CK(Consumer_VolumeIncrement,Lnch), CK(XXX,Off), CK(Consumer_Eject,Lnch), CK(___,Off), - CK(XXX,Off), CK(XXX,Off), CK(XXX,Off), CK(XXX,Off), CK(XXX,Off), CK(XXX,Off), CK(LSHIFT(LALT(Key_KeypadDivide)),Wind), - CK(LALT(Key_LeftArrow),View), CK(LALT(Key_DownArrow),View), CK(LALT(Key_UpArrow),View), CK(LALT(Key_RightArrow),View), CK(XXX,Off), CK(LSHIFT(LALT(Key_KeypadEnter)),Wind), - CK(LALT(Key_Pause),Lnch), CK(XXX,Off), CK(XXX,Off), CK(XXX,Off), CK(XXX,Off), CK(LALT(Key_M),Wind), CK(LSHIFT(LALT(Key_KeypadDot)),Wind), + CK(XXX,Off), CK(Consumer_Mute,Media), CK(Consumer_VolumeDecrement,Media), CK(Consumer_VolumeIncrement,Media), CK(XXX,Off), CK(Consumer_Eject,Media), CK(___,Off), + CK(XXX,Off), CK(XXX,Off), CK(XXX,Off), CK(XXX,Off), CK(XXX,Off), CK(XXX,Off), CK(LSHIFT(LALT(Key_KeypadDivide)),Wind), + CK(LALT(Key_LeftArrow),View), CK(LALT(Key_DownArrow),View), CK(LALT(Key_UpArrow),View), CK(LALT(Key_RightArrow),View), CK(XXX,Off), CK(LSHIFT(LALT(Key_KeypadEnter)),Wind), + CK(LALT(Key_Pause),Lnch), CK(XXX,Off), CK(XXX,Off), CK(XXX,Off), CK(XXX,Off), CK(LALT(Key_M),Wind), CK(LSHIFT(LALT(Key_KeypadDot)),Wind), CK(___,Off), CK(___,Off), CK(___,Off), CK(___,Off), CK(___,Off)) ); |