aboutsummaryrefslogtreecommitdiff
path: root/users
diff options
context:
space:
mode:
authorBrandon Schlack <brandonschlack@gmail.com>2020-11-04 21:55:03 -0800
committerGitHub <noreply@github.com>2020-11-04 21:55:03 -0800
commitf12dcb0659918657d35dc599e69f1aec43a22e97 (patch)
tree50e98a01f9103a82574390879f9989ef27b47e98 /users
parent262a60733483a38ed998b6dc6495f748ba6b71b0 (diff)
downloadqmk_firmware-f12dcb0659918657d35dc599e69f1aec43a22e97.tar.gz
qmk_firmware-f12dcb0659918657d35dc599e69f1aec43a22e97.zip
[Keymap] add brandonschlack userspace and keymaps (#10411)
Diffstat (limited to 'users')
-rw-r--r--users/brandonschlack/brandonschlack.c214
-rw-r--r--users/brandonschlack/brandonschlack.h83
-rw-r--r--users/brandonschlack/config.h55
-rw-r--r--users/brandonschlack/process_records.c172
-rw-r--r--users/brandonschlack/process_records.h152
-rw-r--r--users/brandonschlack/readme.md48
-rw-r--r--users/brandonschlack/rgb_bs.c146
-rw-r--r--users/brandonschlack/rgb_bs.h35
-rw-r--r--users/brandonschlack/rgb_theme.h51
-rw-r--r--users/brandonschlack/rgb_theme_user.inc95
-rw-r--r--users/brandonschlack/rules.mk34
-rw-r--r--users/brandonschlack/tap_dances.c91
-rw-r--r--users/brandonschlack/tap_dances.h52
13 files changed, 1228 insertions, 0 deletions
diff --git a/users/brandonschlack/brandonschlack.c b/users/brandonschlack/brandonschlack.c
new file mode 100644
index 000000000..1e52bd645
--- /dev/null
+++ b/users/brandonschlack/brandonschlack.c
@@ -0,0 +1,214 @@
1/* Copyright 2020 Brandon Schlack
2 *
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16#include "brandonschlack.h"
17
18user_config_t user_config;
19#ifdef STOPLIGHT_LED
20static stoplight_led_t stoplight_led;
21#endif
22
23/**
24 * Resets user config in EEPROM
25 *
26 * Default is use rgb for layer indication
27 */
28void eeconfig_init_user(void) {
29 user_config.raw = 0;
30 user_config.rgb_layer_change = true;
31 user_config.rgb_theme = 0;
32 eeconfig_update_user(user_config.raw);
33}
34
35__attribute__((weak))
36void matrix_init_keymap(void){ }
37
38void matrix_init_user(void) {
39 matrix_init_keymap();
40}
41
42__attribute__((weak))
43void keyboard_post_init_keymap(void){ }
44
45/**
46 * Reads user config from EEPROM,
47 * calls RGB init if RGBs enabled
48 */
49void keyboard_post_init_user(void){
50 // Read the user config from EEPROM
51 user_config.raw = eeconfig_read_user();
52 // Do Stoplight Animation if enabled
53#ifdef STOPLIGHT_LED
54 led_stoplight_start();
55#endif
56 // Do RGB things if RGBs enabled
57#if defined(RGBLIGHT_ENABLE) || defined(RGB_MATRIX_ENABLE)
58 keyboard_post_init_rgb();
59#endif
60 keyboard_post_init_keymap();
61}
62
63__attribute__ ((weak))
64void shutdown_keymap(void) {}
65
66/**
67 * On shutdown,
68 * If RGBs enabled,
69 * then set RGB color to Red
70 */
71void shutdown_user (void) {
72#ifdef RGBLIGHT_ENABLE
73 rgblight_enable_noeeprom();
74 rgblight_mode_noeeprom(RGBLIGHT_MODE_STATIC_LIGHT);
75 rgblight_sethsv_noeeprom(0, 255, 127);
76#endif // RGBLIGHT_ENABLE
77#ifdef RGB_MATRIX_ENABLE
78 rgb_matrix_set_color_all( 0xFF, 0x00, 0x00 );
79#endif //RGB_MATRIX_ENABLE
80 shutdown_keymap();
81}
82
83__attribute__ ((weak))
84void suspend_power_down_keymap(void) {}
85
86/**
87 * Set rgb_matrix suspend state to true if not already
88 */
89void suspend_power_down_user(void) {
90#ifdef RGB_MATRIX_ENABLE
91 if (!g_suspend_state) {
92 rgb_matrix_set_suspend_state(true);
93 }
94#endif //RGB_MATRIX_ENABLE
95 suspend_power_down_keymap();
96}
97
98__attribute__ ((weak))
99void suspend_wakeup_init_keymap(void) {}
100
101/**
102 * Set rgb_matrix suspend state to false if not already
103 */
104void suspend_wakeup_init_user(void) {
105#ifdef RGB_MATRIX_ENABLE
106 if (g_suspend_state) {
107 rgb_matrix_set_suspend_state(false);
108 }
109#endif //RGB_MATRIX_ENABLE
110 suspend_wakeup_init_keymap();
111}
112
113__attribute__ ((weak))
114void matrix_scan_keymap(void) {}
115
116/**
117 * Checks for Super CMD↯TAB
118 */
119void matrix_scan_user(void) {
120 matrix_scan_cmd_tab();
121#ifdef STOPLIGHT_LED
122 matrix_scan_led_stoplight();
123#endif
124 matrix_scan_keymap();
125}
126
127__attribute__ ((weak))
128layer_state_t default_layer_state_set_keymap(layer_state_t state) {
129 return state;
130}
131
132/**
133 * For macropads, if a new default layer is set from DF()
134 * then automatically set that layer with layer_move()
135 */
136layer_state_t default_layer_state_set_user(layer_state_t state) {
137#if defined(IS_MACROPAD)
138 layer_move(get_highest_layer(state));
139#endif
140 return default_layer_state_set_keymap(state);
141}
142
143__attribute__ ((weak))
144layer_state_t layer_state_set_keymap(layer_state_t state) {
145 return state;
146}
147
148/**
149 * Do RGB things (like layer indication) on layer change
150 */
151layer_state_t layer_state_set_user(layer_state_t state) {
152#if defined(RGBLIGHT_ENABLE) || defined(RGB_MATRIX_ENABLE)
153 state = layer_state_set_rgb(state);
154#endif // RGBLIGHT_ENABLE
155 return layer_state_set_keymap(state);
156}
157
158__attribute__((weak)) bool led_update_keymap(led_t led_state) { return true; }
159
160bool led_update_user(led_t led_state) {
161#ifdef STOPLIGHT_LED
162 if (stoplight_led.is_active) {
163 return false;
164 }
165#endif
166 return led_update_keymap(led_state);
167}
168
169#ifdef STOPLIGHT_LED
170void led_stoplight_start(void) {
171 writePin(TOP_LED, LED_ON(false));
172 writePin(MIDDLE_LED, LED_ON(false));
173 writePin(BOTTOM_LED, LED_ON(false));
174
175 stoplight_led.is_active = true;
176 stoplight_led.timer = timer_read();
177};
178
179void led_stoplight_set(pin_t pin) {
180 writePin(pin, LED_ON(true));
181};
182
183void led_stoplight_end(void) {
184 // Reset timer and status variables
185 stoplight_led.is_active = false;
186 stoplight_led.index = 0;
187 stoplight_led.timer = 0;
188 led_update_kb(host_keyboard_led_state());
189};
190
191void matrix_scan_led_stoplight(void) {
192 if (stoplight_led.is_active) {
193 if (timer_elapsed(stoplight_led.timer) > (1000 * (stoplight_led.index + 1))) {
194 switch (stoplight_led.index){
195 case 0:
196 led_stoplight_set(TOP_LED);
197 stoplight_led.index++;
198 break;
199 case 1:
200 led_stoplight_set(MIDDLE_LED);
201 stoplight_led.index++;
202 break;
203 case 2:
204 led_stoplight_set(BOTTOM_LED);
205 stoplight_led.index++;
206 break;
207 default:
208 led_stoplight_end();
209 break;
210 }
211 }
212 }
213};
214#endif
diff --git a/users/brandonschlack/brandonschlack.h b/users/brandonschlack/brandonschlack.h
new file mode 100644
index 000000000..d7dbc0ea4
--- /dev/null
+++ b/users/brandonschlack/brandonschlack.h
@@ -0,0 +1,83 @@
1/* Copyright 2020 Brandon Schlack
2 *
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16#pragma once
17
18#include "quantum.h"
19#include "version.h"
20#include "eeprom.h"
21#include "process_records.h"
22#ifdef TAP_DANCE_ENABLE
23# include "tap_dances.h"
24#endif // TAP_DANCE_ENABLE
25#if defined(RGBLIGHT_ENABLE) || defined(RGB_MATRIX_ENABLE)
26# include "rgb_bs.h"
27#endif
28
29/* TODO Layer Names */
30enum bs_layers {
31 _BASE = 0,
32 _M1 = 1,
33 _M2 = 2,
34 _M3 = 3,
35 _M4 = 4,
36 _FN1 = 5,
37 _M1_FN1 = 6,
38 _M2_FN1 = 7,
39 _M3_FN1 = 8,
40 _M4_FN1 = 9,
41 _FN2 = 10,
42 _M1_FN2 = 11,
43 _M2_FN2 = 12,
44 _M3_FN2 = 13,
45 _M4_FN2 = 14,
46 _ADJUST = 15 // 15: Change keyboard settings
47};
48
49#define _LOWER _FN1
50#define _RAISE _FN2
51
52/* TODO User EECONFIG */
53typedef union {
54 uint32_t raw;
55 struct {
56 bool rgb_layer_change :1;
57 uint8_t rgb_theme :4;
58 };
59} user_config_t;
60extern user_config_t user_config;
61
62void matrix_init_keymap(void);
63void keyboard_post_init_keymap(void);
64void shutdown_keymap(void);
65void suspend_power_down_keymap(void);
66void suspend_wakeup_init_keymap(void);
67void matrix_scan_keymap(void);
68layer_state_t default_layer_state_set_keymap(layer_state_t state);
69layer_state_t layer_state_set_keymap(layer_state_t state);
70bool led_update_keymap(led_t led_state);
71
72#ifdef STOPLIGHT_LED
73typedef struct {
74 bool is_active :1;
75 uint8_t index :7;
76 uint16_t timer :16;
77} stoplight_led_t;
78
79void led_stoplight_start(void);
80void led_stoplight_set(pin_t pin);
81void led_stoplight_end(void);
82void matrix_scan_led_stoplight(void);
83#endif
diff --git a/users/brandonschlack/config.h b/users/brandonschlack/config.h
new file mode 100644
index 000000000..8f09adef3
--- /dev/null
+++ b/users/brandonschlack/config.h
@@ -0,0 +1,55 @@
1/* Copyright 2020 Brandon Schlack
2 *
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16#pragma once
17
18#define TAPPING_TOGGLE 2
19#define TAPPING_TERM 200
20#define PERMISSIVE_HOLD
21#define TAP_HOLD_CAPS_DELAY 200
22
23#ifdef RGBLIGHT_ENABLE
24# define RGBLIGHT_SLEEP
25#endif
26
27#if defined(RGBLIGHT_ENABLE) || defined(RGB_MATRIX_ENABLE) && !defined(RGBLIGHT_LAYERS)
28# define RGB_THEME_ENABLE
29#endif
30
31#ifdef RGB_THEME_ENABLE
32# define DISABLE_RGB_THEME_JAMON
33# define DISABLE_RGB_THEME_OBLIQUE
34#endif
35
36#ifdef ENCODER_ENABLE
37# define TAP_CODE_DELAY 10
38#else
39# define TAP_CODE_DELAY 5
40#endif
41
42/* Disable unused and unneeded features to reduce on firmware size */
43#ifndef NO_ACTION_MACRO
44# define NO_ACTION_MACRO
45#endif
46#ifndef NO_ACTION_FUNCTION
47# define NO_ACTION_FUNCTION
48#endif
49
50#ifdef LOCKING_SUPPORT_ENABLE
51# undef LOCKING_SUPPORT_ENABLE
52#endif
53#ifdef LOCKING_RESYNC_ENABLE
54# undef LOCKING_RESYNC_ENABLE
55#endif
diff --git a/users/brandonschlack/process_records.c b/users/brandonschlack/process_records.c
new file mode 100644
index 000000000..dfd427bdc
--- /dev/null
+++ b/users/brandonschlack/process_records.c
@@ -0,0 +1,172 @@
1/* Copyright 2020 Brandon Schlack
2 *
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16#include "brandonschlack.h"
17
18// Super CMD↯TAB
19bool is_cmd_tab_active = false;
20uint16_t cmd_tab_timer = 0;
21
22__attribute__ ((weak))
23bool process_record_keymap(uint16_t keycode, keyrecord_t *record) {
24 return true;
25}
26
27// Consolidated Macros
28bool process_record_user(uint16_t keycode, keyrecord_t *record) {
29 switch (keycode) {
30 case QM_MAKE: // Sends 'qmk compile' or 'qmk flash'
31 if (record->event.pressed) {
32 bool flash = false;
33 // If is a keyboard and auto-flash is not set in rules.mk,
34 // then Shift will trigger the flash command
35 #if !defined(FLASH_BOOTLOADER) && !defined(IS_MACROPAD)
36 uint8_t temp_mod = get_mods();
37 uint8_t temp_osm = get_oneshot_mods();
38 clear_mods();
39 clear_oneshot_mods();
40 if ( (temp_mod | temp_osm) & MOD_MASK_SHIFT )
41 #endif
42 {
43 flash = true;
44 }
45 send_make_command(flash);
46 }
47 break;
48 case QM_FLSH: // Sends flash command instead of compile
49 if (record->event.pressed) {
50 clear_mods();
51 clear_oneshot_mods();
52 send_make_command(true);
53 }
54 break;
55 case QM_VRSN: // Prints firmware version
56 if (record->event.pressed) {
57 SEND_STRING(QMK_KEYBOARD "/" QMK_KEYMAP " @ " QMK_VERSION ", Built on: " QMK_BUILDDATE);
58 }
59 break;
60 case QM_KYBD: // Prints keyboard path
61 if (record->event.pressed) {
62 SEND_STRING("keyboards/" QMK_KEYBOARD "/");
63 }
64 break;
65 case QM_KYMP: // Prints keymap path
66 if (record->event.pressed) {
67 SEND_STRING("keyboards/" QMK_KEYBOARD "/keymaps/" QMK_KEYMAP "/keymap.c");
68 }
69 break;
70 case CMD_TAB: // Super CMD↯TAB
71 if (record->event.pressed) {
72 if (!is_cmd_tab_active) {
73 is_cmd_tab_active = true;
74 register_code(KC_LGUI);
75 }
76 cmd_tab_timer = timer_read();
77 register_code(KC_TAB);
78 } else {
79 unregister_code(KC_TAB);
80 }
81 break;
82 #if defined(RGB_THEME_ENABLE)
83 case RGB_LYR:
84 if (record->event.pressed) {
85 user_config.rgb_layer_change ^= 1;
86 dprintf("rgb layer change [EEPROM]: %u\n", user_config.rgb_layer_change);
87 eeconfig_update_user(user_config.raw);
88 if (user_config.rgb_layer_change) {
89 layer_state_set(layer_state);
90 }
91 }
92 break;
93 case RGB_HUI ... RGB_SAD:
94 if (record->event.pressed) {
95 if (user_config.rgb_layer_change) {
96 user_config.rgb_layer_change = false;
97 dprintf("rgb layer change [EEPROM]: %u\n", user_config.rgb_layer_change);
98 eeconfig_update_user(user_config.raw);
99 }
100 }
101 break;
102 case RGB_THEME_FORWARD:
103 if (record->event.pressed) {
104 uint8_t shifted = get_mods() & (MOD_BIT(KC_LSHIFT)|MOD_BIT(KC_RSHIFT));
105 if(shifted) {
106 rgb_theme_step_reverse();
107 } else {
108 rgb_theme_step();
109 }
110 layer_state_set(layer_state);
111 }
112 break;
113 case RGB_THEME_REVERSE:
114 if (record->event.pressed) {
115 uint8_t shifted = get_mods() & (MOD_BIT(KC_LSHIFT)|MOD_BIT(KC_RSHIFT));
116 if(shifted) {
117 rgb_theme_step();
118 } else {
119 rgb_theme_step_reverse();
120 }
121 layer_state_set(layer_state);
122 }
123 break;
124 #endif
125 }
126 return process_record_keymap(keycode, record);
127}
128
129// Super CMD↯TAB
130void matrix_scan_cmd_tab(void) {
131 if (is_cmd_tab_active) {
132 if (timer_elapsed(cmd_tab_timer) > 500) {
133 unregister_code(KC_LGUI);
134 is_cmd_tab_active = false;
135 }
136 }
137}
138
139/**
140 * Send Make Command
141 *
142 * Sends 'qmk compile -kb keyboard -km keymap' command to compile firmware
143 * Uses 'qmk flash' and resets keyboard, if flash_bootloader set to true
144 * Sends CTPC and/or FORCE_LAYOUT parameters if built with those options
145 */
146void send_make_command(bool flash_bootloader) {
147#ifdef FORCE_LAYOUT // Add layout string if built with FORCE_LAYOUT
148 SEND_STRING("FORCE_LAYOUT=" FORCE_LAYOUT " ");
149#endif
150#ifdef CONVERT_TO_PROTON_C // Add CTPC if built with CONVERT_TO_PROTON_C
151 SEND_STRING("CTPC=yes ");
152#endif
153 SEND_STRING("qmk ");
154 if (flash_bootloader) {
155#ifndef KEYBOARD_massdrop // Don't run flash for Massdrop boards
156 SEND_STRING("flash ");
157 } else {
158#endif
159 SEND_STRING("compile ");
160 }
161 SEND_STRING("-kb " QMK_KEYBOARD " ");
162 SEND_STRING("-km " QMK_KEYMAP);
163 if (flash_bootloader) {
164#if defined(KEYBOARD_massdrop) // only run for Massdrop boards
165 SEND_STRING(" && mdlflash " QMK_KEYBOARD " " QMK_KEYMAP);
166#endif
167 }
168 SEND_STRING(SS_TAP(X_ENTER));
169 if (flash_bootloader) {
170 reset_keyboard();
171 }
172}
diff --git a/users/brandonschlack/process_records.h b/users/brandonschlack/process_records.h
new file mode 100644
index 000000000..057233fb0
--- /dev/null
+++ b/users/brandonschlack/process_records.h
@@ -0,0 +1,152 @@
1/* Copyright 2020 Brandon Schlack
2 *
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16#pragma once
17#include "brandonschlack.h"
18
19// Macros
20enum custom_keycodes {
21 QM_MAKE = SAFE_RANGE,
22 QM_FLSH,
23 QM_VRSN,
24 QM_KYBD,
25 QM_KYMP,
26 CMD_TAB,
27 RGB_LYR,
28 RGB_THEME_FORWARD,
29 RGB_THEME_REVERSE,
30 KEYMAP_SAFE_RANGE
31};
32
33bool process_record_keymap(uint16_t keycode, keyrecord_t *record);
34void matrix_scan_cmd_tab(void);
35
36/**
37 * QMK Defines
38 * Some meta aliases for QMK features such as Mod-Taps
39 * and for cleaner looking Layer Toggles
40 */
41/* Control Mod-Tap */
42#define CTL_ESC CTL_T(KC_ESC) // Hold Escape for Control
43#define CTL_TAB CTL_T(KC_TAB) // Hold Tab for Control
44#define CTL_CAP CTL_T(KC_CAPS) // Hold Caps Lock for Control
45/* Command Mod-Tap */
46#define CMD_ESC CMD_T(KC_ESC) // Hold Escape for Command
47#define CMD_CAP CMD_T(KC_CAPS) // Hold Caps Lock for Command
48#define CMD_SPC CMD_T(KC_SPC) // Hold Space for Command
49/* Hyper Mod-Tap */
50#define HY_ESC ALL_T(KC_ESC) // Hold Escape for Hyper (Shift-Control-Option-Command)
51#define HY_TAB ALL_T(KC_TAB) // Hold Tab for Hyper (Shift-Control-Option-Command)
52#define HY_CAPS ALL_T(KC_CAPS) // Hold Caps Lock for Hyper (Shift-Control-Option-Command)
53/* Shift Mod-Tap */
54#define SF_CAPS LSFT_T(KC_CAPS) // Hold Caps Lock for Left Shift
55#define SFT_ENT RSFT_T(KC_ENT) // Hold Enter for Right Shift
56#define SF_SLSH RSFT_T(KC_SLSH) // Tap Right Shift for Slash (/)
57#define SF_BSLS RSFT_T(KC_BSLS) // Tap Right Shift for Back Slash (\)
58/* Layer Aliases */
59#define FN_LYR MO(_FN1) // Hold for FN Layer
60#define FN2_LYR MO(_FN2) // Hold for FN2 Layer
61#define LOWER MO(_LOWER) // Hold for LOWER Layer
62#define RAISE MO(_RAISE) // Hold for RAISE Layer
63#define TT_FN TT(_FN1) // Hold for FN Layer, or Double-Tap to Toggle
64#define TT_FN2 TT(_FN2) // Hold for FN2 Layer, or Double-Tap to Toggle
65#define TT_LWR TT(_LOWER) // Hold for LOWER Layer, or Double-Tap to Toggle
66#define TT_RAI TT(_RAISE) // Hold for RAISE Layer, or Double-Tap to Toggle
67#define SPC_LWR LT(_LOWER, KC_SPC) // Tap for Space, Hold for LOWER Layer
68#define SPC_RAI LT(_RAISE, KC_SPC) // Tap for Space, Hold for RAISE Layer
69#define SLH_LWR LT(_LOWER, KC_SLSH) // Tap for /, Hold for LOWER Layer
70#define BSL_LWR LT(_LOWER, KC_BSLS) // Tap for \, Hold for LOWER Layer
71#define MCO_LYR MO(_MACRO) // Hold for MACRO Layer
72#define TG_ADJT TG(_ADJUST) // Toggle ADJUST Layer
73#define TG_LGHT TG(_LIGHT) // Toggle LIGHT Layer
74/**
75 * Media Mod-Tap
76 * Use the Mod-Tap feature for easy media controls
77 * Used with >=65% layouts
78 */
79#define RWD_CMD RCMD_T(KC_MPRV) // Tap Right Command for Prev Track
80#define PLY_CMD RCMD_T(KC_MPLY) // Tap Right Command for Play/Pause
81#define FFD_OPT ROPT_T(KC_MNXT) // Tap Right Option for Next Track
82#define PLY_FN1 LT(_FN1, KC_MPLY) // Tap Fn for Play/Pause
83#define PLY_FN2 LT(_FN2, KC_MPLY) // Tap Fn2 for Play/Pause
84#define MUT_SFT RSFT_T(KC_MUTE) // Tap Right Shift for Mute
85/**
86 * Arrow Mod-Tap
87 * Use the Mod-Tap feature for arrow keys
88 * Mostly used for 40-60% layouts
89 */
90#define UP_RSFT RSFT_T(KC_UP) // Tap Right Shift for Up
91#define LFT_OPT ROPT_T(KC_LEFT) // Tap Right Option for Left
92#define LFT_CMD RCMD_T(KC_LEFT) // Tap Right Command for Left
93#define DWN_FN1 LT(1, KC_DOWN) // Tap Fn for Down
94#define DWN_LWR DWN_FN1 // Tap Lower for Down
95#define DWN_FN2 LT(2, KC_DOWN) // Tap Fn2 for Down
96#define DWN_RAI DWN_FN2 // Tap Raise for Down
97#define DWN_OPT ROPT_T(KC_DOWN) // Tap Right Option for Down
98#define RGT_SFT RSFT_T(KC_RGHT) // Tap Right Shift for Right
99#define RGT_OPT ROPT_T(KC_RGHT) // Tap Right Option for Right
100#define RGT_CTL RCTL_T(KC_RGHT) // Tap Right Ctrl for Right
101/**
102 * Nav Mod-Tap
103 * Use the Mod-Tap feature for nav keys (Home/End, Page Up/Down)
104 * Mostly used for 40-60% layouts, on a function layer
105 */
106#define PGU_SFT RSFT_T(KC_PGUP) // Tap Right Shift for Page Up
107#define HOM_OPT ROPT_T(KC_HOME) // Tap Right Option for Home
108#define HOM_CMD RCMD_T(KC_HOME) // Tap Right Command for Home
109#define PGD_OPT ROPT_T(KC_PGDN) // Tap Right Option for Page Down
110#define PGD_FN1 LT(1, KC_PGDN) // Tap Fn for Page Down
111#define PGD_LWR PGD_FN1 // Tap Lower for Page Down
112#define PGD_FN2 LT(2, KC_PGDN) // Tap Fn2 for Page Down
113#define PGD_RAI PGD_FN2 // Tap Raise for Page Down
114#define END_OPT ROPT_T(KC_END) // Tap Right Option for End
115#define END_CTL RCTL_T(KC_END) // Tap Right Control for End
116
117/**
118 * MacOS
119 * Common shortcuts used in macOS
120 * Reference: https://support.apple.com/en-us/HT201236
121 */
122#define MC_POWR KC_POWER // Power (KC_POWER)
123#define MC_SLEP LOPT(LCMD(KC_POWER)) // Sleep (Option-Command-Power)
124#define MC_SLPD LCTL(LSFT(KC_POWER)) // Sleep Display (Control-Shift-Power)
125#define MC_LOCK LCTL(LCMD(KC_Q)) // Lock Screen (Control-Command-Q)
126#define MC_MSSN KC_FIND // Mission Control: Configure karabiner for find -> mission_control
127#define MC_LHPD KC_MENU // Launchpad: Configure karabiner for menu -> launchpad
128#define MC_CMTB LCMD(KC_TAB) // Command-Tab
129#define MC_BACK LCMD(KC_LBRC) // Back (Command–Left Bracket)
130#define MC_FWRD LCMD(KC_RBRC) // Forward (Command–Right Bracket)
131#define CLS_TAB LCMD(KC_W) // Close Tab (Command–W)
132#define REO_TAB LSFT(LCMD(KC_T)) // Reopen Last Tab (Shift-Command-T)
133#define NXT_TAB LCTL(KC_TAB) // Next Tab (Control-Tab)
134#define PRV_TAB LSFT(LCTL(KC_TAB)) // Previous Tab (Shift-Control-Tab)
135#define NXT_WIN LCMD(KC_GRV) // Next Window (Control-Grave)
136#define PRV_WIN LCMD(KC_TILD) // Previous Window (Shift-Control-Grave)
137#define MC_PLYR LCMD(KC_F8) // Focuses current Media Player
138#define MC_UNDO LCMD(KC_Z) // Undo (Command-Z)
139#define MC_REDO LSFT(LCMD(KC_Z)) // Redo (Shift-Command-Z)
140#define OP_AFLL HYPR(KC_BSLS) // 1Password Autofill (Shift-Control-Option-Command-\)
141#define PX_AFLL LSFT(LOPT(KC_X)) // 1PasswordX Autofill (Shift-Option-X)
142// Reverse scrolling for using with macOS Natural Scrolling.
143#define MC_WH_U KC_WH_D // Mouse Wheel Up
144#define MC_WH_D KC_WH_U // Mouse Wheel Down
145#define MC_WH_L KC_WH_R // Mouse Wheel Left
146#define MC_WH_R KC_WH_L // Mouse Wheel Right
147
148// RGB Theme
149#define RGB_THM RGB_THEME_FORWARD // Cycle next RGB_THEME
150#define RGB_RTHM RGB_THEME_REVERSE // Cycle previous RGB_THEME
151
152void send_make_command(bool flash_bootloader);
diff --git a/users/brandonschlack/readme.md b/users/brandonschlack/readme.md
new file mode 100644
index 000000000..84f216f9f
--- /dev/null
+++ b/users/brandonschlack/readme.md
@@ -0,0 +1,48 @@
1# Overview
2
3My QMK home. I feel as though I stand on the shoulders of giants, for a lot of my code here is borrowed and adapted from so many contributors here, and that I hope my code here can help or inspire others.
4
5## Layers, Handlers, and Macros
6### Layers
7
8I have some predefined layer names for keyboards:
9* **_BASE**: Default Layer, QWERTY layout.
10* **_FN1**: Function Layer for 60% and above, and additional macros and shortcuts on 50% and below.
11* **_LOWER** and **_RAISE**: Function layers for 40%
12
13and macropads:
14* **_REEDER**: Shortcuts for [Reeder.app](https://reederapp.com/), my RSS feed reader
15* **_MEDIA**: Media controls
16* **_NAVI**: Navigation macros, for changing tabs and scrolling
17* **_KARABINER**: Generic macro keys, meant to be customized per app with [Karabiner](https://pqrs.org/osx/karabiner/)
18
19#### Protected Layers
20I have some named "protected" layers, meant to be at the end of the layer list for changing keyboard settings and features.
21
22* **KEYMAP_LAYERS**: Add additional layers in keymap.
23* **_AUDIO**: Audio feature controls.
24* **_LIGHT**: RGB Light/Matrix feature controls.
25* **_ADJUST**: General keyboard settings and toggles. Can also contain RGB and Audio controls on larger boards that don't need and extra layer for those controls.
26
27### EEPROM User Config
28
29I have a custom userspace config implemented to save settings on the board to persist across shutdowns. I currently store:
30
31* rgb_layer_change - a toggle for using RGB themes for layer indication
32* rgb_theme - a pointer to the currently set RGB Theme
33
34### Process Handlers
35
36### Keycode Aliases
37
38I am a macOS user and so a lot of my aliases are
39
40### Macros
41
42
43## Tap Dances
44
45### Tap Dance Trigger Layer
46
47## RGB
48### RGB Theme
diff --git a/users/brandonschlack/rgb_bs.c b/users/brandonschlack/rgb_bs.c
new file mode 100644
index 000000000..1abf785b4
--- /dev/null
+++ b/users/brandonschlack/rgb_bs.c
@@ -0,0 +1,146 @@
1/* Copyright 2020 Brandon Schlack
2 *
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16#include "brandonschlack.h"
17#include "rgb_theme.h"
18#include "rgb_bs.h"
19
20#if defined(RGBLIGHT_ENABLE)
21extern rgblight_config_t rgblight_config;
22#elif defined(RGB_MATRIX_ENABLE)
23extern rgb_config_t rgb_matrix_config;
24extern bool g_suspend_state;
25extern led_config_t g_led_config;
26#endif
27
28#if defined(RGB_THEME_ENABLE)
29// Should be rgb_theme.c
30#define RGB_THEME(name) const rgb_theme_t RGB_##name
31#define RGB_THEME_IMPLS
32#include "rgb_theme_user.inc"
33#undef RGB_THEME_IMPLS
34#undef RGB_THEME
35
36#define RGB_THEME(name) [RGB_THEME_##name] = &RGB_##name,
37const rgb_theme_t *themes[] = {
38 #include "rgb_theme_user.inc"
39};
40#undef RGB_THEME
41
42// Userspace loose colors
43rgb_theme_color_t default_adjust = { HSV_SPRINGGREEN };
44#endif
45
46void keyboard_post_init_rgb(void) {
47 layer_state_set_user(layer_state);
48}
49
50#if defined(RGB_THEME_ENABLE)
51void set_rgb_theme(uint8_t index) {
52 if (!user_config.rgb_layer_change) {
53 user_config.rgb_layer_change = true;
54 }
55 user_config.rgb_theme = index;
56 dprintf("rgb theme [EEPROM]: %u\n", user_config.rgb_theme);
57 eeconfig_update_user(user_config.raw);
58}
59
60rgb_theme_t get_rgb_theme(void) {
61 return *themes[user_config.rgb_theme];
62}
63
64void rgb_theme_step(void) {
65 uint8_t current = user_config.rgb_theme;
66 current = (current + 1) % RGB_THEME_MAX;
67 set_rgb_theme(current);
68}
69
70void rgb_theme_step_reverse(void) {
71 uint8_t current = user_config.rgb_theme;
72 current = (current - 1) % RGB_THEME_MAX;
73 set_rgb_theme(current);
74}
75
76rgb_theme_color_t get_rgb_theme_color(uint8_t index) {
77 rgb_theme_t theme = get_rgb_theme();
78 size_t rgb_theme_color_max = sizeof theme.colors / sizeof *theme.colors;
79
80 if (index == _ADJUST) {
81 return default_adjust;
82 } else {
83 return **(theme.colors + (index % rgb_theme_color_max));
84 }
85};
86
87void rgb_theme_layer(layer_state_t state) {
88 uint8_t rgb_color_index = get_highest_layer(state);
89 HSV color = get_rgb_theme_color(rgb_color_index);
90#if defined(RGBLIGHT_ENABLE)
91 color.v = rgblight_config.val;
92#elif defined(RGB_MATRIX_ENABLE)
93 color.v = rgb_matrix_config.hsv.v;
94#endif
95 rgb_layer_helper( color.h, color.s, color.v );
96}
97#endif
98
99#ifdef RGB_MATRIX_ENABLE
100void rgb_matrix_layer_helper (uint8_t red, uint8_t green, uint8_t blue, uint8_t led_type) {
101 for (int i = 0; i < DRIVER_LED_TOTAL; i++) {
102 if (!HAS_ANY_FLAGS(g_led_config.flags[i], led_type)) {
103 rgb_matrix_set_color( i, red, green, blue );
104 }
105 }
106}
107
108void rgb_matrix_cycle_flag (void) {
109 switch (rgb_matrix_get_flags()) {
110 case LED_FLAG_ALL:
111 rgb_matrix_set_flags(LED_FLAG_KEYS);
112 rgb_matrix_set_color_all(0, 0, 0);
113 break;
114 case LED_FLAG_KEYS:
115 rgb_matrix_set_flags(LED_FLAG_UNDERGLOW);
116 rgb_matrix_set_color_all(0, 0, 0);
117 break;
118 case LED_FLAG_UNDERGLOW:
119 rgb_matrix_set_flags(LED_FLAG_NONE);
120 rgb_matrix_set_color_all(0, 0, 0);
121 break;
122 default:
123 rgb_matrix_set_flags(LED_FLAG_ALL);
124 rgb_matrix_enable();
125 break;
126 }
127}
128#endif
129
130void rgb_layer_helper(uint8_t hue, uint8_t sat, uint8_t val) {
131#if defined(RGBLIGHT_ENABLE) || defined(RGB_MATRIX_ENABLE)
132 rgblight_sethsv_noeeprom(hue, sat, val);
133#ifdef RGB_MATRIX_ENABLE
134 rgb_matrix_layer_helper(0, 0, 0, rgb_matrix_get_flags());
135#endif
136}
137#endif
138
139layer_state_t layer_state_set_rgb(layer_state_t state) {
140#if defined(RGB_THEME_ENABLE)
141 if (user_config.rgb_layer_change) {
142 rgb_theme_layer(state);
143 }
144#endif // RGBLIGHT_ENABLE
145 return state;
146}
diff --git a/users/brandonschlack/rgb_bs.h b/users/brandonschlack/rgb_bs.h
new file mode 100644
index 000000000..c5cbd5969
--- /dev/null
+++ b/users/brandonschlack/rgb_bs.h
@@ -0,0 +1,35 @@
1/* Copyright 2020 Brandon Schlack
2 *
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16#pragma once
17#include "quantum.h"
18#ifdef RGB_THEME_ENABLE
19# include "rgb_theme.h"
20#endif
21#ifdef RGB_MATRIX_ENABLE
22# include "rgb_matrix.h"
23#endif
24
25#ifdef RGB_MATRIX_ENABLE
26#define LED_FLAG_KEYS (LED_FLAG_KEYLIGHT | LED_FLAG_MODIFIER)
27
28void rgb_matrix_layer_helper(uint8_t red, uint8_t green, uint8_t blue, uint8_t led_type);
29void rgb_matrix_cycle_flag(void);
30#endif
31
32void keyboard_post_init_rgb(void);
33void rgb_layer_helper(uint8_t hue, uint8_t sat, uint8_t val);
34
35layer_state_t layer_state_set_rgb(layer_state_t state);
diff --git a/users/brandonschlack/rgb_theme.h b/users/brandonschlack/rgb_theme.h
new file mode 100644
index 000000000..7c8b2923f
--- /dev/null
+++ b/users/brandonschlack/rgb_theme.h
@@ -0,0 +1,51 @@
1/* Copyright 2020 Brandon Schlack
2 *
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16#pragma once
17
18#include "brandonschlack.h"
19#include "color.h"
20#include "rgblight_list.h"
21
22/*TODO Update as RGBLIGHT Mode */
23#ifndef RGB_THEME_COLORS_MAX
24#define RGB_THEME_COLORS_MAX 5
25#endif
26
27enum rgb_themes {
28#define RGB_THEME(name) RGB_THEME_##name,
29 #include "rgb_theme_user.inc"
30#undef RGB_THEME
31 RGB_THEME_MAX
32};
33
34// RGB Theme Color
35typedef const HSV rgb_theme_color_t;
36#define RGB_THEME_COLOR(tname, tcolor,...) rgb_theme_color_t tname ## _ ## tcolor = { __VA_ARGS__ }
37
38// RGB Theme
39typedef struct {
40 const HSV *colors[RGB_THEME_COLORS_MAX];
41} rgb_theme_t;
42extern const rgb_theme_t *themes[];
43
44void set_rgb_theme(uint8_t index);
45rgb_theme_t get_rgb_theme(void);
46
47void rgb_theme_step(void);
48void rgb_theme_step_reverse(void);
49
50rgb_theme_color_t get_rgb_theme_color(uint8_t index);
51void rgb_theme_layer(layer_state_t state);
diff --git a/users/brandonschlack/rgb_theme_user.inc b/users/brandonschlack/rgb_theme_user.inc
new file mode 100644
index 000000000..a07e62b78
--- /dev/null
+++ b/users/brandonschlack/rgb_theme_user.inc
@@ -0,0 +1,95 @@
1// Basic Theme
2#ifndef DISABLE_RGB_THEME_BASIC
3#ifndef RGB_THEME_IMPLS
4RGB_THEME(BASIC)
5#else
6RGB_THEME_COLOR(BASIC, WHITE, HSV_WHITE);
7RGB_THEME_COLOR(BASIC, BLUE, HSV_BLUE);
8RGB_THEME_COLOR(BASIC, RED, HSV_RED);
9RGB_THEME_COLOR(BASIC, GREEN, HSV_GREEN);
10RGB_THEME_COLOR(BASIC, YELLOW, HSV_YELLOW);
11RGB_THEME(BASIC) = { { &BASIC_WHITE, &BASIC_BLUE, &BASIC_RED, &BASIC_GREEN, &BASIC_YELLOW } };
12#endif // RGB_THEME_IMPLS
13#endif // DISABLE_RGB_THEME_BASIC
14
15// Laser Theme
16#ifndef DISABLE_RGB_THEME_LASER
17#ifndef RGB_THEME_IMPLS
18RGB_THEME(LASER)
19#else
20RGB_THEME_COLOR(LASER, PURPLE, 191, 255, 255);
21RGB_THEME_COLOR(LASER, PINK, 237, 255, 255);
22RGB_THEME_COLOR(LASER, BLUE, 165, 255, 255);
23RGB_THEME_COLOR(LASER, CYAN, 133, 255, 255);
24RGB_THEME_COLOR(LASER, MAGENTA, 213, 255, 255);
25RGB_THEME(LASER) = { { &LASER_PURPLE, &LASER_PINK, &LASER_BLUE, &LASER_CYAN, &LASER_MAGENTA } };
26#endif // RGB_THEME_IMPLS
27#endif // DISABLE_RGB_THEME_LASER
28
29// Metropolis Theme
30#ifndef DISABLE_RGB_THEME_METROPOLIS
31#ifndef RGB_THEME_IMPLS
32RGB_THEME(METROPOLIS)
33#else
34RGB_THEME_COLOR(METROPOLIS, TEAL, 96, 207, 255);
35RGB_THEME_COLOR(METROPOLIS, RED, HSV_RED);
36RGB_THEME_COLOR(METROPOLIS, YELLOW, 24, 255, 255);
37RGB_THEME_COLOR(METROPOLIS, BLUE, 168, 255, 255);
38RGB_THEME_COLOR(METROPOLIS, WHITE, HSV_WHITE);
39RGB_THEME(METROPOLIS) = { { &METROPOLIS_TEAL, &METROPOLIS_RED, &METROPOLIS_YELLOW, &METROPOLIS_BLUE, &METROPOLIS_WHITE } };
40#endif // RGB_THEME_IMPLS
41#endif // DISABLE_RGB_THEME_METROPOLIS
42
43// Canvas Theme
44#ifndef DISABLE_RGB_THEME_CANVAS
45#ifndef RGB_THEME_IMPLS
46RGB_THEME(CANVAS)
47#else
48RGB_THEME_COLOR(CANVAS, WHITE, HSV_WHITE);
49RGB_THEME_COLOR(CANVAS, ORANGE, 10, 255, 255);
50RGB_THEME_COLOR(CANVAS, RED, 0, 231, 255);
51RGB_THEME_COLOR(CANVAS, GREEN, 74, 207, 255);
52RGB_THEME_COLOR(CANVAS, BLUE, 170, 135, 255);
53RGB_THEME(CANVAS) = { { &CANVAS_WHITE, &CANVAS_ORANGE, &CANVAS_RED, &CANVAS_GREEN, &CANVAS_BLUE } };
54#endif // RGB_THEME_IMPLS
55#endif // DISABLE_RGB_THEME_CANVAS
56
57// Jamon Theme
58#ifndef DISABLE_RGB_THEME_JAMON
59#ifndef RGB_THEME_IMPLS
60RGB_THEME(JAMON)
61#else
62RGB_THEME_COLOR(JAMON, RED, HSV_RED);
63RGB_THEME_COLOR(JAMON, LIGHTRED, 4, 255, 255);
64RGB_THEME_COLOR(JAMON, WHITE, HSV_WHITE);
65RGB_THEME_COLOR(JAMON, YELLOW, HSV_GOLD);
66RGB_THEME(JAMON) = { { &JAMON_RED, &JAMON_LIGHTRED, &JAMON_WHITE, &JAMON_YELLOW } };
67#endif // RGB_THEME_IMPLS
68#endif // DISABLE_RGB_THEME_JAMON
69
70// Striker Theme
71#ifndef DISABLE_RGB_THEME_STRIKER
72#ifndef RGB_THEME_IMPLS
73RGB_THEME(STRIKER)
74#else
75RGB_THEME_COLOR(STRIKER, BLUE, HSV_BLUE);
76RGB_THEME_COLOR(STRIKER, AZURE, HSV_AZURE);
77RGB_THEME_COLOR(STRIKER, WHITE, HSV_WHITE);
78RGB_THEME_COLOR(STRIKER, RED, HSV_RED);
79RGB_THEME(STRIKER) = { { &STRIKER_BLUE, &STRIKER_AZURE, &STRIKER_WHITE, &STRIKER_RED } };
80#endif // RGB_THEME_IMPLS
81#endif // DISABLE_RGB_THEME_STRIKER
82
83// Oblique Theme
84#ifndef DISABLE_RGB_THEME_OBLIQUE
85#ifndef RGB_THEME_IMPLS
86RGB_THEME(OBLIQUE)
87#else
88RGB_THEME_COLOR(OBLIQUE, WHITE, HSV_WHITE);
89RGB_THEME_COLOR(OBLIQUE, PURPLE, 186, 143, 255);
90RGB_THEME_COLOR(OBLIQUE, RED, 10, 200, 255);
91RGB_THEME_COLOR(OBLIQUE, ORANGE, 26, 215, 255);
92RGB_THEME_COLOR(OBLIQUE, GREEN, 58, 199, 255);
93RGB_THEME(OBLIQUE) = { { &OBLIQUE_WHITE, &OBLIQUE_PURPLE, &OBLIQUE_RED, &OBLIQUE_ORANGE, &OBLIQUE_GREEN } };
94#endif // RGB_THEME_IMPLS
95#endif // DISABLE_RGB_THEME_OBLIQUE
diff --git a/users/brandonschlack/rules.mk b/users/brandonschlack/rules.mk
new file mode 100644
index 000000000..2dfc332ab
--- /dev/null
+++ b/users/brandonschlack/rules.mk
@@ -0,0 +1,34 @@
1SRC += brandonschlack.c \
2 process_records.c
3
4SPACE_CADET_ENABLE = no
5
6# Use LTO except for ChibiOS
7ifneq ($(PLATFORM),CHIBIOS)
8 LTO_ENABLE = yes
9endif
10
11ifeq ($(strip $(IS_MACROPAD)), yes)
12 OPT_DEFS += -DIS_MACROPAD
13endif
14
15ifeq ($(strip $(RGBLIGHT_ENABLE)), yes)
16 SRC += rgb_bs.c
17endif
18
19RGB_MATRIX_ENABLE ?= no
20ifneq ($(strip $(RGB_MATRIX_ENABLE)), no)
21 SRC += rgb_bs.c
22endif
23
24ifeq ($(strip $(TAP_DANCE_ENABLE)), yes)
25 SRC += tap_dances.c
26endif
27
28ifeq ($(strip $(FLASH_BOOTLOADER)), yes)
29 OPT_DEFS += -DFLASH_BOOTLOADER
30endif
31
32ifneq ($(FORCE_LAYOUT),)
33 OPT_DEFS += -DFORCE_LAYOUT=\"$(FORCE_LAYOUT)\"
34endif
diff --git a/users/brandonschlack/tap_dances.c b/users/brandonschlack/tap_dances.c
new file mode 100644
index 000000000..861b31805
--- /dev/null
+++ b/users/brandonschlack/tap_dances.c
@@ -0,0 +1,91 @@
1/* Copyright 2020 Brandon Schlack
2 *
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16#include "tap_dances.h"
17#include "process_keycode/process_tap_dance.h"
18
19int cur_dance (qk_tap_dance_state_t *state) {
20 if (state->count == 1) {
21 if (state->interrupted || !state->pressed) return SINGLE_TAP;
22 else return SINGLE_HOLD;
23 } else if (state->count == 2) {
24 if (state->interrupted) return DOUBLE_SINGLE_TAP;
25 else if (state->pressed) return DOUBLE_HOLD;
26 else return DOUBLE_TAP;
27 }
28 if (state->count == 3) {
29 if (state->interrupted || !state->pressed) return TRIPLE_TAP;
30 else return TRIPLE_HOLD;
31 }
32 else return 8;
33}
34
35__attribute__ ((weak))
36void process_tap_dance_keycode (bool reset, uint8_t toggle_layer) { };
37
38void td_trigger_layer_finished (qk_tap_dance_state_t *state, void *user_data) {
39 qk_tap_dance_trigger_layer_t *data = (qk_tap_dance_trigger_layer_t *)user_data;
40 data->state = cur_dance(state);
41
42 if (data->state == data->trigger) {
43 layer_on(data->layer);
44 } else {
45 process_tap_dance_keycode(false, data->layer);
46 }
47
48}
49void td_trigger_layer_reset (qk_tap_dance_state_t *state, void *user_data) {
50 qk_tap_dance_trigger_layer_t *data = (qk_tap_dance_trigger_layer_t *)user_data;
51 if (data->state == data->trigger) {
52 switch (data->trigger) {
53 case SINGLE_HOLD:
54 case DOUBLE_HOLD:
55 case TRIPLE_HOLD:
56 layer_off(data->layer);
57 break;
58 }
59 } else {
60 process_tap_dance_keycode(true, data->layer);
61 }
62 data->state = 0;
63}
64
65/* Tap Dance: Layer Mod. Toggles Layer when tapped, Mod when held. */
66void td_layer_mod_each(qk_tap_dance_state_t *state, void *user_data) {
67 qk_tap_dance_dual_role_t *data = (qk_tap_dance_dual_role_t *)user_data;
68
69 // Single tap → toggle layer, Single hold → mod
70 if (state->pressed) {
71 register_code(data->kc);
72 } else if (state->count == 1) {
73 state->finished = true;
74 }
75}
76
77void td_layer_mod_finished(qk_tap_dance_state_t *state, void *user_data) {
78 qk_tap_dance_dual_role_t *data = (qk_tap_dance_dual_role_t *)user_data;
79
80 if (state->count == 1 && !state->pressed) {
81 layer_invert(data->layer);
82 }
83}
84
85void td_layer_mod_reset(qk_tap_dance_state_t *state, void *user_data) {
86 qk_tap_dance_dual_role_t *data = (qk_tap_dance_dual_role_t *)user_data;
87
88 if (state->count == 1) {
89 unregister_code(data->kc);
90 }
91}
diff --git a/users/brandonschlack/tap_dances.h b/users/brandonschlack/tap_dances.h
new file mode 100644
index 000000000..3747619a5
--- /dev/null
+++ b/users/brandonschlack/tap_dances.h
@@ -0,0 +1,52 @@
1/* Copyright 2020 Brandon Schlack
2 *
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16#pragma once
17#include "brandonschlack.h"
18#ifdef TAP_DANCE_ENABLE
19# include "process_keycode/process_tap_dance.h"
20#endif
21
22enum tap_dance_states {
23 SINGLE_TAP = 1,
24 SINGLE_HOLD = 2,
25 DOUBLE_TAP = 3,
26 DOUBLE_HOLD = 4,
27 DOUBLE_SINGLE_TAP = 5,
28 TRIPLE_TAP = 6,
29 TRIPLE_HOLD = 7
30};
31
32int cur_dance (qk_tap_dance_state_t *state);
33void process_tap_dance_keycode (bool reset, uint8_t toggle_layer);
34
35/* Tap Dance: Trigger Layer
36 *
37 * Toggles Layer based on given trigger (Single Hold, Double Tap, Double Hold, etc).
38 * Uses process_tap_dance_keycode() to allow keycode defines based on layer
39 */
40typedef struct {
41 uint8_t trigger;
42 uint8_t layer;
43 uint8_t state;
44} qk_tap_dance_trigger_layer_t;
45
46#define ACTION_TAP_DANCE_TRIGGER_LAYER(trigger, layer) { \
47 .fn = { NULL, td_trigger_layer_finished, td_trigger_layer_reset }, \
48 .user_data = (void *)&((qk_tap_dance_trigger_layer_t) { trigger, layer, 0 }), \
49}
50
51void td_trigger_layer_finished (qk_tap_dance_state_t *state, void *user_data);
52void td_trigger_layer_reset (qk_tap_dance_state_t *state, void *user_data);