From fe02abc47921428fe6eb59ca817bfd082f0de4bf Mon Sep 17 00:00:00 2001 From: Drashna Jaelre Date: Sat, 11 Feb 2023 15:23:07 -0800 Subject: [Core] Tri Layer Keys (#19795) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: wilba Co-authored-by: Pablo Martínez <58857054+elpekenin@users.noreply.github.com> Co-authored-by: Joel Challis Co-authored-by: Nick Brassel --- quantum/action_layer.c | 10 +++++ quantum/action_layer.h | 21 ++++++++++ quantum/keycodes.h | 6 ++- quantum/process_keycode/process_tri_layer.c | 30 +++++++++++++++ quantum/process_keycode/process_tri_layer.h | 16 ++++++++ quantum/quantum.c | 13 ++----- quantum/quantum.h | 7 ++-- quantum/tri_layer.c | 39 +++++++++++++++++++ quantum/tri_layer.h | 59 +++++++++++++++++++++++++++++ 9 files changed, 187 insertions(+), 14 deletions(-) create mode 100644 quantum/process_keycode/process_tri_layer.c create mode 100644 quantum/process_keycode/process_tri_layer.h create mode 100644 quantum/tri_layer.c create mode 100644 quantum/tri_layer.h (limited to 'quantum') diff --git a/quantum/action_layer.c b/quantum/action_layer.c index 74e8137920..35f494df8f 100644 --- a/quantum/action_layer.c +++ b/quantum/action_layer.c @@ -349,3 +349,13 @@ uint8_t layer_switch_get_layer(keypos_t key) { action_t layer_switch_get_action(keypos_t key) { return action_for_key(layer_switch_get_layer(key), key); } + +layer_state_t update_tri_layer_state(layer_state_t state, uint8_t layer1, uint8_t layer2, uint8_t layer3) { + layer_state_t mask12 = ((layer_state_t)1 << layer1) | ((layer_state_t)1 << layer2); + layer_state_t mask3 = (layer_state_t)1 << layer3; + return (state & mask12) == mask12 ? (state | mask3) : (state & ~mask3); +} + +void update_tri_layer(uint8_t layer1, uint8_t layer2, uint8_t layer3) { + layer_state_set(update_tri_layer_state(layer_state, layer1, layer2, layer3)); +} diff --git a/quantum/action_layer.h b/quantum/action_layer.h index 3fe2726529..ff783bb3e7 100644 --- a/quantum/action_layer.h +++ b/quantum/action_layer.h @@ -113,6 +113,25 @@ void layer_and(layer_state_t state); void layer_xor(layer_state_t state); layer_state_t layer_state_set_user(layer_state_t state); layer_state_t layer_state_set_kb(layer_state_t state); + +/** + * @brief Applies the tri layer to global layer state. Not be used in layer_state_set_(kb|user) functions. + * + * @param layer1 First layer to check for tri layer + * @param layer2 Second layer to check for tri layer + * @param layer3 Layer to activate if both other layers are enabled + */ +void update_tri_layer(uint8_t layer1, uint8_t layer2, uint8_t layer3); +/** + * @brief Applies the tri layer behavior to supplied layer bitmask, without using layer functions. + * + * @param state Original layer bitmask to check and modify + * @param layer1 First layer to check for tri layer + * @param layer2 Second layer to check for tri layer + * @param layer3 Layer to activate if both other layers are enabled + * @return layer_state_t returns a modified layer bitmask with tri layer modifications applied + */ +layer_state_t update_tri_layer_state(layer_state_t state, uint8_t layer1, uint8_t layer2, uint8_t layer3); #else # define layer_state 0 @@ -131,6 +150,8 @@ layer_state_t layer_state_set_kb(layer_state_t state); # define layer_xor(state) (void)state # define layer_state_set_kb(state) (void)state # define layer_state_set_user(state) (void)state +# define update_tri_layer(layer1, layer2, layer3) +# define update_tri_layer_state(state, layer1, layer2, layer3) (void)state #endif /* pressed actions cache */ diff --git a/quantum/keycodes.h b/quantum/keycodes.h index f24ccf01b8..4fa4306ed6 100644 --- a/quantum/keycodes.h +++ b/quantum/keycodes.h @@ -717,6 +717,8 @@ enum qk_keycode_defines { QK_AUTOCORRECT_ON = 0x7C74, QK_AUTOCORRECT_OFF = 0x7C75, QK_AUTOCORRECT_TOGGLE = 0x7C76, + QK_TRI_LAYER_LOWER = 0x7C77, + QK_TRI_LAYER_UPPER = 0x7C78, SAFE_RANGE = 0x7E00, // Alias @@ -1282,6 +1284,8 @@ enum qk_keycode_defines { AC_ON = QK_AUTOCORRECT_ON, AC_OFF = QK_AUTOCORRECT_OFF, AC_TOGG = QK_AUTOCORRECT_TOGGLE, + TL_LOWR = QK_TRI_LAYER_LOWER, + TL_UPPR = QK_TRI_LAYER_UPPER, }; // Range Helpers @@ -1333,4 +1337,4 @@ enum qk_keycode_defines { #define IS_MACRO_KEYCODE(code) ((code) >= QK_MACRO_0 && (code) <= QK_MACRO_31) #define IS_BACKLIGHT_KEYCODE(code) ((code) >= QK_BACKLIGHT_ON && (code) <= QK_BACKLIGHT_TOGGLE_BREATHING) #define IS_RGB_KEYCODE(code) ((code) >= RGB_TOG && (code) <= RGB_MODE_TWINKLE) -#define IS_QUANTUM_KEYCODE(code) ((code) >= QK_BOOTLOADER && (code) <= QK_AUTOCORRECT_TOGGLE) +#define IS_QUANTUM_KEYCODE(code) ((code) >= QK_BOOTLOADER && (code) <= QK_TRI_LAYER_UPPER) diff --git a/quantum/process_keycode/process_tri_layer.c b/quantum/process_keycode/process_tri_layer.c new file mode 100644 index 0000000000..1e681b9a1c --- /dev/null +++ b/quantum/process_keycode/process_tri_layer.c @@ -0,0 +1,30 @@ +// Copyright 2023 QMK +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "process_tri_layer.h" +#include "tri_layer.h" +#include "action_layer.h" + +bool process_tri_layer(uint16_t keycode, keyrecord_t *record) { + switch (keycode) { + case QK_TRI_LAYER_LOWER: + if (record->event.pressed) { + layer_on(get_tri_layer_lower_layer()); + update_tri_layer(get_tri_layer_lower_layer(), get_tri_layer_upper_layer(), get_tri_layer_adjust_layer()); + } else { + layer_off(get_tri_layer_lower_layer()); + update_tri_layer(get_tri_layer_lower_layer(), get_tri_layer_upper_layer(), get_tri_layer_adjust_layer()); + } + return false; + case QK_TRI_LAYER_UPPER: + if (record->event.pressed) { + layer_on(get_tri_layer_upper_layer()); + update_tri_layer(get_tri_layer_lower_layer(), get_tri_layer_upper_layer(), get_tri_layer_adjust_layer()); + } else { + layer_off(get_tri_layer_upper_layer()); + update_tri_layer(get_tri_layer_lower_layer(), get_tri_layer_upper_layer(), get_tri_layer_adjust_layer()); + } + return false; + } + return true; +} diff --git a/quantum/process_keycode/process_tri_layer.h b/quantum/process_keycode/process_tri_layer.h new file mode 100644 index 0000000000..9c4e3df1c2 --- /dev/null +++ b/quantum/process_keycode/process_tri_layer.h @@ -0,0 +1,16 @@ +// Copyright 2023 QMK +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "action.h" + +/** + * @brief Handles tri layer behavior + * + * @param keycode the keycode + * @param record the key record structure + * @return true continue handling keycodes + * @return false stop handling keycodes + */ +bool process_tri_layer(uint16_t keycode, keyrecord_t *record); diff --git a/quantum/quantum.c b/quantum/quantum.c index 5554ecab32..0587f215fe 100644 --- a/quantum/quantum.c +++ b/quantum/quantum.c @@ -342,6 +342,9 @@ bool process_record_quantum(keyrecord_t *record) { #endif #ifdef AUTOCORRECT_ENABLE process_autocorrect(keycode, record) && +#endif +#ifdef TRI_LAYER_ENABLE + process_tri_layer(keycode, record) && #endif true)) { return false; @@ -443,16 +446,6 @@ void set_single_persistent_default_layer(uint8_t default_layer) { default_layer_set((layer_state_t)1 << default_layer); } -layer_state_t update_tri_layer_state(layer_state_t state, uint8_t layer1, uint8_t layer2, uint8_t layer3) { - layer_state_t mask12 = ((layer_state_t)1 << layer1) | ((layer_state_t)1 << layer2); - layer_state_t mask3 = (layer_state_t)1 << layer3; - return (state & mask12) == mask12 ? (state | mask3) : (state & ~mask3); -} - -void update_tri_layer(uint8_t layer1, uint8_t layer2, uint8_t layer3) { - layer_state_set(update_tri_layer_state(layer_state, layer1, layer2, layer3)); -} - //------------------------------------------------------------------------------ // Override these functions in your keymap file to play different tunes on // different events such as startup and bootloader jump diff --git a/quantum/quantum.h b/quantum/quantum.h index 615ec2382c..708d325a32 100644 --- a/quantum/quantum.h +++ b/quantum/quantum.h @@ -240,9 +240,10 @@ extern layer_state_t layer_state; # include "process_autocorrect.h" #endif -// For tri-layer -void update_tri_layer(uint8_t layer1, uint8_t layer2, uint8_t layer3); -layer_state_t update_tri_layer_state(layer_state_t state, uint8_t layer1, uint8_t layer2, uint8_t layer3); +#ifdef TRI_LAYER_ENABLE +# include "tri_layer.h" +# include "process_tri_layer.h" +#endif void set_single_persistent_default_layer(uint8_t default_layer); diff --git a/quantum/tri_layer.c b/quantum/tri_layer.c new file mode 100644 index 0000000000..a5e3f8cb47 --- /dev/null +++ b/quantum/tri_layer.c @@ -0,0 +1,39 @@ +// Copyright 2023 QMK +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "tri_layer.h" +#include + +static uint8_t tri_layer_lower_layer = TRI_LAYER_LOWER_LAYER; +static uint8_t tri_layer_upper_layer = TRI_LAYER_UPPER_LAYER; +static uint8_t tri_layer_adjust_layer = TRI_LAYER_ADJUST_LAYER; + +void set_tri_layer_lower_layer(uint8_t layer) { + tri_layer_lower_layer = layer; +} + +void set_tri_layer_upper_layer(uint8_t layer) { + tri_layer_upper_layer = layer; +} + +void set_tri_layer_adjust_layer(uint8_t layer) { + tri_layer_adjust_layer = layer; +} + +void set_tri_layer_layers(uint8_t lower, uint8_t raise, uint8_t adjust) { + tri_layer_lower_layer = lower; + tri_layer_upper_layer = raise; + tri_layer_adjust_layer = adjust; +} + +uint8_t get_tri_layer_lower_layer(void) { + return tri_layer_lower_layer; +} + +uint8_t get_tri_layer_upper_layer(void) { + return tri_layer_upper_layer; +} + +uint8_t get_tri_layer_adjust_layer(void) { + return tri_layer_adjust_layer; +} diff --git a/quantum/tri_layer.h b/quantum/tri_layer.h new file mode 100644 index 0000000000..3341ebffb2 --- /dev/null +++ b/quantum/tri_layer.h @@ -0,0 +1,59 @@ +// Copyright 2023 QMK +// SPDX-License-Identifier: GPL-2.0-or-later + +#include + +#ifndef TRI_LAYER_LOWER_LAYER +# define TRI_LAYER_LOWER_LAYER 1 +#endif +#ifndef TRI_LAYER_UPPER_LAYER +# define TRI_LAYER_UPPER_LAYER 2 +#endif +#ifndef TRI_LAYER_ADJUST_LAYER +# define TRI_LAYER_ADJUST_LAYER 3 +#endif + +/** + * @brief Set the tri layer lower layer index + * + * @param layer + */ +void set_tri_layer_lower_layer(uint8_t layer); +/** + * @brief Set the tri layer upper layer index + * + * @param layer + */ +void set_tri_layer_upper_layer(uint8_t layer); +/** + * @brief Set the tri layer adjust layer index + * + * @param layer + */ +void set_tri_layer_adjust_layer(uint8_t layer); +/** + * @brief Set the tri layer indices + * + * @param lower + * @param upper + * @param adjust + */ +void set_tri_layer_layers(uint8_t lower, uint8_t upper, uint8_t adjust); +/** + * @brief Get the tri layer lower layer index + * + * @return uint8_t + */ +uint8_t get_tri_layer_lower_layer(void); +/** + * @brief Get the tri layer upper layer index + * + * @return uint8_t + */ +uint8_t get_tri_layer_upper_layer(void); +/** + * @brief Get the tri layer adjust layer index + * + * @return uint8_t + */ +uint8_t get_tri_layer_adjust_layer(void); -- cgit v1.2.3