keymap.c (5817B)
1 /* Copyright 2021 Hydrogen BD <support@hgenbd.com> 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 17 #include QMK_KEYBOARD_H 18 19 typedef enum { 20 TD_NONE, 21 TD_UNKNOWN, 22 TD_SINGLE_TAP, 23 TD_SINGLE_HOLD, 24 TD_DOUBLE_TAP, 25 TD_DOUBLE_HOLD, 26 TD_DOUBLE_SINGLE_TAP, // Send two single taps 27 } td_state_t; 28 29 typedef struct { 30 bool is_press_action; 31 td_state_t state; 32 } td_tap_t; 33 34 enum custom_keycodes { 35 TD_CUT_REDO, 36 TD_PLAY_PAUSE_MUTE, 37 TD_MNXT_RIGHT, 38 TD_MPRV_LEFT, 39 TD_SEARCH_REFRESH, 40 QUAD_LAYER_SWITCH, 41 QUAD_CVXA, 42 YOUTUBE = SAFE_RANGE, 43 FACEBOOK, 44 DISCORD, 45 VALORANT, 46 VSCODE, 47 }; 48 49 td_state_t cur_dance(tap_dance_state_t *state); 50 51 /* Quad layer switching */ 52 void layer_finished(tap_dance_state_t *state, void *user_data); 53 void layer_reset(tap_dance_state_t *state, void *user_data); 54 55 /* Copy, paste, select all, cut */ 56 void cvxa_finished(tap_dance_state_t *state, void *user_data); 57 void cvxa_reset(tap_dance_state_t *state, void *user_data); 58 59 static td_tap_t layerTap_state = { 60 .is_press_action = true, 61 .state = TD_NONE 62 }; 63 64 static td_tap_t cvxa_state = { 65 .is_press_action = true, 66 .state = TD_NONE 67 }; 68 69 // Determine the current tap dance state 70 td_state_t cur_dance(tap_dance_state_t *state) { 71 if (state->count == 1) { 72 if (state->interrupted || !state->pressed) return TD_SINGLE_TAP; 73 // Key has not been interrupted, but the key is still held. Means you want to send a 'HOLD'. 74 else return TD_SINGLE_HOLD; 75 } else if (state->count == 2) { 76 if (state->interrupted) return TD_DOUBLE_SINGLE_TAP; 77 else if (state->pressed) return TD_DOUBLE_HOLD; 78 else return TD_DOUBLE_TAP; 79 } else return TD_UNKNOWN; 80 } 81 82 void layer_finished(tap_dance_state_t *state, void *user_data) { 83 layerTap_state.state = cur_dance(state); 84 layer_off(get_highest_layer(layer_state)); 85 switch (layerTap_state.state) { 86 case TD_SINGLE_TAP: layer_on(0); break; 87 case TD_SINGLE_HOLD: layer_on(1); break; 88 case TD_DOUBLE_TAP: layer_on(2); break; 89 case TD_DOUBLE_HOLD: layer_on(3); break; 90 default: layer_on(0); 91 } 92 } 93 94 void layer_reset(tap_dance_state_t *state, void *user_data) { 95 layerTap_state.state = TD_NONE; 96 } 97 98 void cvxa_finished(tap_dance_state_t *state, void *user_data) { 99 cvxa_state.state = cur_dance(state); 100 register_mods(MOD_BIT(KC_LCTL)); 101 switch (cvxa_state.state) { 102 case TD_SINGLE_TAP: tap_code(KC_V); break; 103 case TD_SINGLE_HOLD: tap_code(KC_A); break; 104 case TD_DOUBLE_TAP: tap_code(KC_C); break; 105 case TD_DOUBLE_HOLD: tap_code(KC_X); break; 106 default: tap_code(KC_V); 107 } 108 unregister_mods(MOD_BIT(KC_LCTL)); 109 } 110 111 void cvxa_reset(tap_dance_state_t *state, void *user_data) { 112 cvxa_state.state = TD_NONE; 113 } 114 115 // Tap Dance definitions 116 tap_dance_action_t tap_dance_actions[] = { 117 [TD_CUT_REDO] = ACTION_TAP_DANCE_DOUBLE(C(KC_Z), S(C(KC_Z))), 118 [TD_PLAY_PAUSE_MUTE] = ACTION_TAP_DANCE_DOUBLE(KC_MPLY, KC_MUTE), 119 [TD_MNXT_RIGHT] = ACTION_TAP_DANCE_DOUBLE(KC_MNXT, KC_RIGHT), 120 [TD_MPRV_LEFT] = ACTION_TAP_DANCE_DOUBLE(KC_MPRV, KC_LEFT), 121 [TD_SEARCH_REFRESH] = ACTION_TAP_DANCE_DOUBLE(KC_WREF, KC_WSCH), 122 [QUAD_LAYER_SWITCH] = ACTION_TAP_DANCE_FN_ADVANCED(NULL, layer_finished, layer_reset), 123 [QUAD_CVXA] = ACTION_TAP_DANCE_FN_ADVANCED(NULL, cvxa_finished, cvxa_reset) 124 }; 125 126 bool process_record_user(uint16_t keycode, keyrecord_t *record) { 127 switch(keycode) { 128 case YOUTUBE: 129 if (record->event.pressed) { 130 tap_code16(C(KC_L)); 131 SEND_STRING("https://www.youtube.com/"); 132 } else { 133 tap_code(KC_ENT); 134 } 135 break; 136 case FACEBOOK: 137 if (record->event.pressed) { 138 tap_code16(C(KC_L)); 139 SEND_STRING("https://www.facebook.com/"); 140 } else { 141 tap_code(KC_ENT); 142 } 143 break; 144 case VALORANT: 145 if (record->event.pressed) { 146 tap_code16(G(KC_S)); 147 SEND_STRING("valorant"); 148 } else { 149 tap_code(KC_ENT); 150 } 151 break; 152 case DISCORD: 153 if (record->event.pressed) { 154 tap_code16(G(KC_S)); 155 SEND_STRING("discord"); 156 } else { 157 tap_code(KC_ENT); 158 } 159 break; 160 case VSCODE: 161 if (record->event.pressed) { 162 tap_code16(G(KC_S)); 163 SEND_STRING("vscode"); 164 } else { 165 tap_code(KC_ENT); 166 } 167 break; 168 } 169 return true; 170 }; 171 172 const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { 173 174 [0] = LAYOUT( 175 TD(TD_CUT_REDO), TD(TD_MPRV_LEFT), TD(TD_PLAY_PAUSE_MUTE), TD(TD_MNXT_RIGHT), TD(QUAD_CVXA), TD(QUAD_LAYER_SWITCH) 176 ), 177 178 [1] = LAYOUT( 179 YOUTUBE, KC_WBAK, TD(TD_SEARCH_REFRESH), KC_WFWD, FACEBOOK, TD(QUAD_LAYER_SWITCH) 180 ), 181 182 [2] = LAYOUT( 183 A(KC_F4), LSG(KC_S), KC_MYCM, LCA(KC_DEL), KC_CALC, TD(QUAD_LAYER_SWITCH) 184 ), 185 186 [3] = LAYOUT( 187 C(KC_SLSH), VALORANT, VSCODE, DISCORD, LSA(KC_A), TD(QUAD_LAYER_SWITCH) 188 ), 189 };