Browse Source

Add generic handling to cycle LED/RGB Matrix flags (#24649)

Joel Challis 11 months ago
parent
commit
883465d9fb

+ 0 - 0
data/constants/keycodes/keycodes_0.0.8.hjson


+ 37 - 0
data/constants/keycodes/keycodes_0.0.8_lighting.hjson

@@ -0,0 +1,37 @@
+{
+    "keycodes": {
+        "0x7819": {
+            "group": "led_matrix",
+            "key": "QK_LED_MATRIX_FLAG_NEXT",
+            "label": "LED Matrix Flag Next",
+            "aliases": [
+                "LM_FLGN"
+            ]
+        },
+        "0x781A": {
+            "group": "led_matrix",
+            "key": "QK_LED_MATRIX_FLAG_PREVIOUS",
+            "label": "LED Matrix Flag Previous",
+            "aliases": [
+                "LM_FLGP"
+            ]
+        },
+
+        "0x784D": {
+            "group": "rgb_matrix",
+            "key": "QK_RGB_MATRIX_FLAG_NEXT",
+            "label": "RGB Matrix Flag Next",
+            "aliases": [
+                "RM_FLGN"
+            ]
+        },
+        "0x784E": {
+            "group": "rgb_matrix",
+            "key": "QK_RGB_MATRIX_FLAG_PREVIOUS",
+            "label": "RGB Matrix Flag Previous",
+            "aliases": [
+                "RM_FLGP"
+            ]
+        }
+    }
+}

+ 2 - 0
data/mappings/info_config.hjson

@@ -98,6 +98,7 @@
 
     // LED Matrix
     "LED_MATRIX_CENTER": {"info_key": "led_matrix.center_point", "value_type": "array.int"},
+    "LED_MATRIX_FLAG_STEPS": {"info_key": "led_matrix.flag_steps", "value_type": "array.int"},
     "LED_MATRIX_KEYRELEASES": {"info_key": "led_matrix.react_on_keyup", "value_type": "flag"},
     "LED_MATRIX_LED_FLUSH_LIMIT": {"info_key": "led_matrix.led_flush_limit", "value_type": "int"},
     "LED_MATRIX_LED_PROCESS_LIMIT": {"info_key": "led_matrix.led_process_limit", "value_type": "int", "to_json": false},
@@ -147,6 +148,7 @@
 
     // RGB Matrix
     "RGB_MATRIX_CENTER": {"info_key": "rgb_matrix.center_point", "value_type": "array.int"},
+    "RGB_MATRIX_FLAG_STEPS": {"info_key": "rgb_matrix.flag_steps", "value_type": "array.int"},
     "RGB_MATRIX_HUE_STEP": {"info_key": "rgb_matrix.hue_steps", "value_type": "int"},
     "RGB_MATRIX_KEYRELEASES": {"info_key": "rgb_matrix.react_on_keyup", "value_type": "flag"},
     "RGB_MATRIX_LED_FLUSH_LIMIT": {"info_key": "rgb_matrix.led_flush_limit", "value_type": "int"},

+ 10 - 0
data/schemas/keyboard.jsonschema

@@ -571,6 +571,11 @@
                     "maxItems": 2,
                     "items": {"$ref": "./definitions.jsonschema#/unsigned_int_8"}
                 },
+                "flag_steps": {
+                    "type": "array",
+                    "minItems": 1,
+                    "items": {"$ref": "./definitions.jsonschema#/unsigned_int_8"}
+                },
                 "max_brightness": {"$ref": "./definitions.jsonschema#/unsigned_int_8"},
                 "timeout": {"$ref": "./definitions.jsonschema#/unsigned_int"},
                 "val_steps": {"$ref": "./definitions.jsonschema#/unsigned_int"},
@@ -656,6 +661,11 @@
                     "maxItems": 2,
                     "items": {"$ref": "./definitions.jsonschema#/unsigned_int_8"}
                 },
+                "flag_steps": {
+                    "type": "array",
+                    "minItems": 1,
+                    "items": {"$ref": "./definitions.jsonschema#/unsigned_int_8"}
+                },
                 "max_brightness": {"$ref": "./definitions.jsonschema#/unsigned_int_8"},
                 "timeout": {"$ref": "./definitions.jsonschema#/unsigned_int"},
                 "hue_steps": {"$ref": "./definitions.jsonschema#/unsigned_int"},

+ 6 - 0
docs/reference_info_json.md

@@ -415,6 +415,9 @@ Configures the [LED Matrix](features/led_matrix) feature.
     * `center_point` <Badge type="info">Array: Number</Badge>
         * The centroid (geometric center) of the LEDs. Used for certain effects.
         * Default: `[112, 32]`
+    * `flag_steps` <Badge type="info">Array: Number</Badge>
+        * A list of flag bitfields that can be cycled through.
+        * Default: `[255, 5, 0]`
     * `default`
         * `animation` <Badge type="info">String</Badge>
             * The default effect. Must be one of `led_matrix.animations`
@@ -660,6 +663,9 @@ Configures the [RGB Matrix](features/rgb_matrix) feature.
     * `center_point` <Badge type="info">Array: Number</Badge>
         * The centroid (geometric center) of the LEDs. Used for certain effects.
         * Default: `[112, 32]`
+    * `flag_steps` <Badge type="info">Array: Number</Badge>
+        * A list of flag bitfields that can be cycled through.
+        * Default: `[255, 5, 2, 0]`
     * `default`
         * `animation` <Badge type="info">String</Badge>
             * The default effect. Must be one of `rgb_matrix.animations`

+ 8 - 0
lib/python/qmk/info.py

@@ -800,6 +800,14 @@ def _extract_led_config(info_data, keyboard):
             if info_data[feature].get('layout', None) and not info_data[feature].get('led_count', None):
                 info_data[feature]['led_count'] = len(info_data[feature]['layout'])
 
+            if info_data[feature].get('layout', None) and not info_data[feature].get('flag_steps', None):
+                flags = {0xFF, 0}
+                # if only a single flag is used, assume only all+none flags
+                unique_flags = set(x.get('flags', 0) for x in info_data[feature]['layout'])
+                if len(unique_flags) > 1:
+                    flags.update(unique_flags)
+                info_data[feature]['flag_steps'] = sorted(list(flags), reverse=True)
+
     return info_data
 
 

+ 15 - 7
quantum/keycodes.h

@@ -26,11 +26,11 @@
 #pragma once
 // clang-format off
 
-#define QMK_KEYCODES_VERSION "0.0.7"
-#define QMK_KEYCODES_VERSION_BCD 0x00000007
+#define QMK_KEYCODES_VERSION "0.0.8"
+#define QMK_KEYCODES_VERSION_BCD 0x00000008
 #define QMK_KEYCODES_VERSION_MAJOR 0
 #define QMK_KEYCODES_VERSION_MINOR 0
-#define QMK_KEYCODES_VERSION_PATCH 7
+#define QMK_KEYCODES_VERSION_PATCH 8
 
 enum qk_keycode_ranges {
 // Ranges
@@ -663,6 +663,8 @@ enum qk_keycode_defines {
     QK_LED_MATRIX_BRIGHTNESS_DOWN = 0x7816,
     QK_LED_MATRIX_SPEED_UP = 0x7817,
     QK_LED_MATRIX_SPEED_DOWN = 0x7818,
+    QK_LED_MATRIX_FLAG_NEXT = 0x7819,
+    QK_LED_MATRIX_FLAG_PREVIOUS = 0x781A,
     QK_UNDERGLOW_TOGGLE = 0x7820,
     QK_UNDERGLOW_MODE_NEXT = 0x7821,
     QK_UNDERGLOW_MODE_PREVIOUS = 0x7822,
@@ -697,6 +699,8 @@ enum qk_keycode_defines {
     QK_RGB_MATRIX_VALUE_DOWN = 0x784A,
     QK_RGB_MATRIX_SPEED_UP = 0x784B,
     QK_RGB_MATRIX_SPEED_DOWN = 0x784C,
+    QK_RGB_MATRIX_FLAG_NEXT = 0x784D,
+    QK_RGB_MATRIX_FLAG_PREVIOUS = 0x784E,
     QK_BOOTLOADER = 0x7C00,
     QK_REBOOT = 0x7C01,
     QK_DEBUG_TOGGLE = 0x7C02,
@@ -1352,6 +1356,8 @@ enum qk_keycode_defines {
     LM_BRID    = QK_LED_MATRIX_BRIGHTNESS_DOWN,
     LM_SPDU    = QK_LED_MATRIX_SPEED_UP,
     LM_SPDD    = QK_LED_MATRIX_SPEED_DOWN,
+    LM_FLGN    = QK_LED_MATRIX_FLAG_NEXT,
+    LM_FLGP    = QK_LED_MATRIX_FLAG_PREVIOUS,
     UG_TOGG    = QK_UNDERGLOW_TOGGLE,
     UG_NEXT    = QK_UNDERGLOW_MODE_NEXT,
     UG_PREV    = QK_UNDERGLOW_MODE_PREVIOUS,
@@ -1386,6 +1392,8 @@ enum qk_keycode_defines {
     RM_VALD    = QK_RGB_MATRIX_VALUE_DOWN,
     RM_SPDU    = QK_RGB_MATRIX_SPEED_UP,
     RM_SPDD    = QK_RGB_MATRIX_SPEED_DOWN,
+    RM_FLGN    = QK_RGB_MATRIX_FLAG_NEXT,
+    RM_FLGP    = QK_RGB_MATRIX_FLAG_PREVIOUS,
     QK_BOOT    = QK_BOOTLOADER,
     QK_RBT     = QK_REBOOT,
     DB_TOGG    = QK_DEBUG_TOGGLE,
@@ -1511,10 +1519,10 @@ enum qk_keycode_defines {
 #define IS_MACRO_KEYCODE(code) ((code) >= QK_MACRO_0 && (code) <= QK_MACRO_31)
 #define IS_CONNECTION_KEYCODE(code) ((code) >= QK_OUTPUT_AUTO && (code) <= QK_BLUETOOTH_PROFILE5)
 #define IS_BACKLIGHT_KEYCODE(code) ((code) >= QK_BACKLIGHT_ON && (code) <= QK_BACKLIGHT_TOGGLE_BREATHING)
-#define IS_LED_MATRIX_KEYCODE(code) ((code) >= QK_LED_MATRIX_ON && (code) <= QK_LED_MATRIX_SPEED_DOWN)
+#define IS_LED_MATRIX_KEYCODE(code) ((code) >= QK_LED_MATRIX_ON && (code) <= QK_LED_MATRIX_FLAG_PREVIOUS)
 #define IS_UNDERGLOW_KEYCODE(code) ((code) >= QK_UNDERGLOW_TOGGLE && (code) <= QK_UNDERGLOW_SPEED_DOWN)
 #define IS_RGB_KEYCODE(code) ((code) >= RGB_MODE_PLAIN && (code) <= RGB_MODE_TWINKLE)
-#define IS_RGB_MATRIX_KEYCODE(code) ((code) >= QK_RGB_MATRIX_ON && (code) <= QK_RGB_MATRIX_SPEED_DOWN)
+#define IS_RGB_MATRIX_KEYCODE(code) ((code) >= QK_RGB_MATRIX_ON && (code) <= QK_RGB_MATRIX_FLAG_PREVIOUS)
 #define IS_QUANTUM_KEYCODE(code) ((code) >= QK_BOOTLOADER && (code) <= QK_LAYER_LOCK)
 #define IS_KB_KEYCODE(code) ((code) >= QK_KB_0 && (code) <= QK_KB_31)
 #define IS_USER_KEYCODE(code) ((code) >= QK_USER_0 && (code) <= QK_USER_31)
@@ -1537,10 +1545,10 @@ enum qk_keycode_defines {
 #define MACRO_KEYCODE_RANGE                 QK_MACRO_0 ... QK_MACRO_31
 #define CONNECTION_KEYCODE_RANGE            QK_OUTPUT_AUTO ... QK_BLUETOOTH_PROFILE5
 #define BACKLIGHT_KEYCODE_RANGE             QK_BACKLIGHT_ON ... QK_BACKLIGHT_TOGGLE_BREATHING
-#define LED_MATRIX_KEYCODE_RANGE            QK_LED_MATRIX_ON ... QK_LED_MATRIX_SPEED_DOWN
+#define LED_MATRIX_KEYCODE_RANGE            QK_LED_MATRIX_ON ... QK_LED_MATRIX_FLAG_PREVIOUS
 #define UNDERGLOW_KEYCODE_RANGE             QK_UNDERGLOW_TOGGLE ... QK_UNDERGLOW_SPEED_DOWN
 #define RGB_KEYCODE_RANGE                   RGB_MODE_PLAIN ... RGB_MODE_TWINKLE
-#define RGB_MATRIX_KEYCODE_RANGE            QK_RGB_MATRIX_ON ... QK_RGB_MATRIX_SPEED_DOWN
+#define RGB_MATRIX_KEYCODE_RANGE            QK_RGB_MATRIX_ON ... QK_RGB_MATRIX_FLAG_PREVIOUS
 #define QUANTUM_KEYCODE_RANGE               QK_BOOTLOADER ... QK_LAYER_LOCK
 #define KB_KEYCODE_RANGE                    QK_KB_0 ... QK_KB_31
 #define USER_KEYCODE_RANGE                  QK_USER_0 ... QK_USER_31

+ 51 - 0
quantum/led_matrix/led_matrix.c

@@ -70,6 +70,13 @@ uint8_t g_led_frame_buffer[MATRIX_ROWS][MATRIX_COLS] = {{0}};
 last_hit_t g_last_hit_tracker;
 #endif // LED_MATRIX_KEYREACTIVE_ENABLED
 
+#ifndef LED_MATRIX_FLAG_STEPS
+#    define LED_MATRIX_FLAG_STEPS \
+        { LED_FLAG_ALL, LED_FLAG_KEYLIGHT | LED_FLAG_MODIFIER, LED_FLAG_NONE }
+#endif
+static const uint8_t led_matrix_flag_steps[] = LED_MATRIX_FLAG_STEPS;
+#define LED_MATRIX_FLAG_STEPS_COUNT ARRAY_SIZE(led_matrix_flag_steps)
+
 // internals
 static bool            suspend_state     = false;
 static uint8_t         led_last_enable   = UINT8_MAX;
@@ -661,6 +668,50 @@ void led_matrix_set_flags_noeeprom(led_flags_t flags) {
     led_matrix_set_flags_eeprom_helper(flags, false);
 }
 
+void led_matrix_flags_step_helper(bool write_to_eeprom) {
+    led_flags_t flags = led_matrix_get_flags();
+
+    uint8_t next = 0;
+    for (uint8_t i = 0; i < LED_MATRIX_FLAG_STEPS_COUNT; i++) {
+        if (led_matrix_flag_steps[i] == flags) {
+            next = i == LED_MATRIX_FLAG_STEPS_COUNT - 1 ? 0 : i + 1;
+            break;
+        }
+    }
+
+    led_matrix_set_flags_eeprom_helper(led_matrix_flag_steps[next], write_to_eeprom);
+}
+
+void led_matrix_flags_step_noeeprom(void) {
+    led_matrix_flags_step_helper(false);
+}
+
+void led_matrix_flags_step(void) {
+    led_matrix_flags_step_helper(true);
+}
+
+void led_matrix_flags_step_reverse_helper(bool write_to_eeprom) {
+    led_flags_t flags = led_matrix_get_flags();
+
+    uint8_t next = 0;
+    for (uint8_t i = 0; i < LED_MATRIX_FLAG_STEPS_COUNT; i++) {
+        if (led_matrix_flag_steps[i] == flags) {
+            next = i == 0 ? LED_MATRIX_FLAG_STEPS_COUNT - 1 : i - 1;
+            break;
+        }
+    }
+
+    led_matrix_set_flags_eeprom_helper(led_matrix_flag_steps[next], write_to_eeprom);
+}
+
+void led_matrix_flags_step_reverse_noeeprom(void) {
+    led_matrix_flags_step_reverse_helper(false);
+}
+
+void led_matrix_flags_step_reverse(void) {
+    led_matrix_flags_step_reverse_helper(true);
+}
+
 // LED Matrix naming
 #undef LED_MATRIX_EFFECT
 #ifdef LED_MATRIX_MODE_NAME_ENABLE

+ 4 - 0
quantum/led_matrix/led_matrix.h

@@ -183,6 +183,10 @@ void        led_matrix_decrease_speed_noeeprom(void);
 led_flags_t led_matrix_get_flags(void);
 void        led_matrix_set_flags(led_flags_t flags);
 void        led_matrix_set_flags_noeeprom(led_flags_t flags);
+void        led_matrix_flags_step_noeeprom(void);
+void        led_matrix_flags_step(void);
+void        led_matrix_flags_step_reverse_noeeprom(void);
+void        led_matrix_flags_step_reverse(void);
 
 #ifdef LED_MATRIX_MODE_NAME_ENABLE
 const char *led_matrix_get_mode_name(uint8_t mode);

+ 6 - 0
quantum/process_keycode/process_led_matrix.c

@@ -40,6 +40,12 @@ bool process_led_matrix(uint16_t keycode, keyrecord_t *record) {
             case QK_LED_MATRIX_SPEED_DOWN:
                 led_matrix_decrease_speed();
                 return false;
+            case QK_LED_MATRIX_FLAG_NEXT:
+                led_matrix_flags_step();
+                return false;
+            case QK_LED_MATRIX_FLAG_PREVIOUS:
+                led_matrix_flags_step_reverse();
+                return false;
         }
     }
 

+ 14 - 0
quantum/process_keycode/process_rgb_matrix.c

@@ -94,6 +94,20 @@ bool process_rgb_matrix(uint16_t keycode, keyrecord_t *record) {
                     rgb_matrix_decrease_speed();
                 }
                 return false;
+            case QK_RGB_MATRIX_FLAG_NEXT:
+                if (shifted) {
+                    rgb_matrix_flags_step_reverse();
+                } else {
+                    rgb_matrix_flags_step();
+                }
+                return false;
+            case QK_RGB_MATRIX_FLAG_PREVIOUS:
+                if (shifted) {
+                    rgb_matrix_flags_step();
+                } else {
+                    rgb_matrix_flags_step_reverse();
+                }
+                return false;
         }
     }
 

+ 51 - 0
quantum/rgb_matrix/rgb_matrix.c

@@ -72,6 +72,13 @@ uint8_t g_rgb_frame_buffer[MATRIX_ROWS][MATRIX_COLS] = {{0}};
 last_hit_t g_last_hit_tracker;
 #endif // RGB_MATRIX_KEYREACTIVE_ENABLED
 
+#ifndef RGB_MATRIX_FLAG_STEPS
+#    define RGB_MATRIX_FLAG_STEPS \
+        { LED_FLAG_ALL, LED_FLAG_KEYLIGHT | LED_FLAG_MODIFIER, LED_FLAG_UNDERGLOW, LED_FLAG_NONE }
+#endif
+static const uint8_t rgb_matrix_flag_steps[] = RGB_MATRIX_FLAG_STEPS;
+#define RGB_MATRIX_FLAG_STEPS_COUNT ARRAY_SIZE(rgb_matrix_flag_steps)
+
 // internals
 static bool            suspend_state     = false;
 static uint8_t         rgb_last_enable   = UINT8_MAX;
@@ -747,6 +754,50 @@ void rgb_matrix_set_flags_noeeprom(led_flags_t flags) {
     rgb_matrix_set_flags_eeprom_helper(flags, false);
 }
 
+void rgb_matrix_flags_step_helper(bool write_to_eeprom) {
+    led_flags_t flags = rgb_matrix_get_flags();
+
+    uint8_t next = 0;
+    for (uint8_t i = 0; i < RGB_MATRIX_FLAG_STEPS_COUNT; i++) {
+        if (rgb_matrix_flag_steps[i] == flags) {
+            next = i == RGB_MATRIX_FLAG_STEPS_COUNT - 1 ? 0 : i + 1;
+            break;
+        }
+    }
+
+    rgb_matrix_set_flags_eeprom_helper(rgb_matrix_flag_steps[next], write_to_eeprom);
+}
+
+void rgb_matrix_flags_step_noeeprom(void) {
+    rgb_matrix_flags_step_helper(false);
+}
+
+void rgb_matrix_flags_step(void) {
+    rgb_matrix_flags_step_helper(true);
+}
+
+void rgb_matrix_flags_step_reverse_helper(bool write_to_eeprom) {
+    led_flags_t flags = rgb_matrix_get_flags();
+
+    uint8_t next = 0;
+    for (uint8_t i = 0; i < RGB_MATRIX_FLAG_STEPS_COUNT; i++) {
+        if (rgb_matrix_flag_steps[i] == flags) {
+            next = i == 0 ? RGB_MATRIX_FLAG_STEPS_COUNT - 1 : i - 1;
+            break;
+        }
+    }
+
+    rgb_matrix_set_flags_eeprom_helper(rgb_matrix_flag_steps[next], write_to_eeprom);
+}
+
+void rgb_matrix_flags_step_reverse_noeeprom(void) {
+    rgb_matrix_flags_step_reverse_helper(false);
+}
+
+void rgb_matrix_flags_step_reverse(void) {
+    rgb_matrix_flags_step_reverse_helper(true);
+}
+
 //----------------------------------------------------------
 // RGB Matrix naming
 #undef RGB_MATRIX_EFFECT

+ 4 - 0
quantum/rgb_matrix/rgb_matrix.h

@@ -218,6 +218,10 @@ void        rgb_matrix_decrease_speed_noeeprom(void);
 led_flags_t rgb_matrix_get_flags(void);
 void        rgb_matrix_set_flags(led_flags_t flags);
 void        rgb_matrix_set_flags_noeeprom(led_flags_t flags);
+void        rgb_matrix_flags_step_noeeprom(void);
+void        rgb_matrix_flags_step(void);
+void        rgb_matrix_flags_step_reverse_noeeprom(void);
+void        rgb_matrix_flags_step_reverse(void);
 void        rgb_matrix_update_pwm_buffers(void);
 
 #ifdef RGB_MATRIX_MODE_NAME_ENABLE