aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordakkar <dakkar@thenautilus.net>2019-02-15 16:30:30 +0000
committerdakkar <dakkar@thenautilus.net>2019-02-15 16:30:30 +0000
commitb86f79d805e73fc08ab478455da59c47436f7105 (patch)
tree62b69c409d9c75c43f16079fe01fa0268c196418
parentprobably simpler: use LEDMode (diff)
downloadkeyboardio-model01-b86f79d805e73fc08ab478455da59c47436f7105.tar.gz
keyboardio-model01-b86f79d805e73fc08ab478455da59c47436f7105.tar.bz2
keyboardio-model01-b86f79d805e73fc08ab478455da59c47436f7105.zip
it works!!
-rw-r--r--color-picker.h271
1 files 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 <Kaleidoscope-LEDControl.h>
+#include <kaleidoscope/plugin/LEDControl.h>
+#include <kaleidoscope/plugin/LEDControl/LEDUtils.h>
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;