/* Copyright 2022 @ Keychron (https://www.keychron.com) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include QMK_KEYBOARD_H enum layers{ BASE, FN, COLEMAK, NAVIGATION }; enum tap_dance_keys { TD_CAPS_NAV = 0 }; enum tap_dance_state { TD_NONE, TD_UNKNOWN, TD_SINGLE_TAP, TD_SINGLE_HOLD, TD_DOUBLE_TAP, TD_TAP_HOLD }; typedef struct { bool is_press_action; enum tap_dance_state state; } td_tap_t; enum tap_dance_state cur_dance(tap_dance_state_t *state) { if (state->count == 1) { if (state->interrupted || !state->pressed) return TD_SINGLE_TAP; else return TD_SINGLE_HOLD; } else if (state->count == 2) { if (state->interrupted) return TD_DOUBLE_TAP; else if (state->pressed) return TD_TAP_HOLD; else return TD_DOUBLE_TAP; } return TD_UNKNOWN; } static td_tap_t caps_tap_state = {.is_press_action = true, .state = TD_NONE}; void caps_finished(tap_dance_state_t *state, void *user_data) { caps_tap_state.state = cur_dance(state); switch (caps_tap_state.state) { case TD_SINGLE_TAP: case TD_SINGLE_HOLD: register_code(KC_LCTL); break; case TD_TAP_HOLD: layer_on(NAVIGATION); break; default: break; } } void caps_reset(tap_dance_state_t *state, void *user_data) { switch (caps_tap_state.state) { case TD_SINGLE_TAP: case TD_SINGLE_HOLD: unregister_code(KC_LCTL); break; case TD_TAP_HOLD: layer_off(NAVIGATION); break; default: break; } caps_tap_state.state = TD_NONE; } tap_dance_action_t tap_dance_actions[] = { [TD_CAPS_NAV] = ACTION_TAP_DANCE_FN_ADVANCED(NULL, caps_finished, caps_reset) }; const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { [BASE] = LAYOUT_tkl_f13_ansi( KC_ESC, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_MUTE, KC_F13, KC_F14, RM_NEXT, KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSPC, KC_INS, KC_HOME, KC_PGUP, KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSLS, KC_DEL, KC_END, KC_PGDN, TD(TD_CAPS_NAV), KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_ENT, KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, KC_UP, KC_LCTL, KC_LOPT, KC_LCMD, KC_SPC, KC_RCMD, KC_ROPT, MO(FN), KC_RCTL, KC_LEFT, KC_DOWN, KC_RGHT), [FN] = LAYOUT_tkl_f13_ansi( _______, KC_BRID, KC_BRIU, KC_MISSION_CONTROL, KC_LAUNCHPAD, RM_VALD, RM_VALU, KC_MPRV, KC_MPLY, KC_MNXT, KC_MUTE, KC_VOLD, KC_VOLU, RM_TOGG, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, RM_TOGG, RM_NEXT, RM_VALU, RM_HUEU, RM_SATU, RM_SPDU, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, RM_PREV, RM_VALD, RM_HUED, RM_SATD, RM_SPDD, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, NK_TOGG, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______), [COLEMAK] = LAYOUT_tkl_f13_ansi( KC_ESC, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_MUTE, KC_F13, KC_F14, RM_NEXT, KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSPC, KC_INS, KC_HOME, KC_PGUP, KC_TAB, KC_Q, KC_W, KC_F, KC_P, KC_B, KC_J, KC_L, KC_U, KC_Y, KC_SCLN, KC_LBRC, KC_RBRC, KC_BSLS, KC_DEL, KC_END, KC_PGDN, TD(TD_CAPS_NAV), KC_A, KC_R, KC_S, KC_T, KC_G, KC_M, KC_N, KC_E, KC_I, KC_O, KC_QUOT, KC_ENT, MT(MOD_LSFT, KC_Z), KC_X, KC_C, KC_D, KC_V, KC_NUHS, KC_K, KC_H, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, KC_UP, KC_LCTL, KC_LOPT, KC_LCMD, KC_SPC, KC_RCMD, KC_ROPT, MO(FN), KC_RCTL, KC_LEFT, KC_DOWN, KC_RGHT), [NAVIGATION] = LAYOUT_tkl_f13_ansi( _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_LEFT, KC_DOWN, KC_UP, KC_RGHT, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______), }; #if defined(ENCODER_MAP_ENABLE) const uint16_t PROGMEM encoder_map[][NUM_ENCODERS][NUM_DIRECTIONS] = { [BASE] = {ENCODER_CCW_CW(KC_VOLD, KC_VOLU) }, [FN] = {ENCODER_CCW_CW(RM_VALD, RM_VALU) }, [COLEMAK] = {ENCODER_CCW_CW(KC_VOLD, KC_VOLU) }, [NAVIGATION] = {ENCODER_CCW_CW(KC_VOLD, KC_VOLU) } }; #endif // ENCODER_MAP_ENABLE #ifdef RGB_MATRIX_ENABLE bool rgb_matrix_indicators_advanced_user(uint8_t led_min, uint8_t led_max) { // Check if COLEMAK is the default layer (set by DIP switch) // The DIP switch uses default_layer_set(), not layer_on() if (get_highest_layer(default_layer_state) == COLEMAK) { // Create a breathing effect for the pause key uint16_t time = timer_read(); uint8_t val = ((time >> 3) & 0xFF); // Convert to triangle wave for breathing if (val > 127) { val = 255 - val; } val = val << 1; // Double brightness // Set pause key to pulse red RGB_MATRIX_INDICATOR_SET_COLOR(15, val, 0, 0); } // Check if NAVIGATION layer is active if (IS_LAYER_ON(NAVIGATION)) { // Light up the HJKL keys (navigation arrow positions) in solid green // H = LED 56, J = LED 57, K = LED 58, L = LED 59 RGB_MATRIX_INDICATOR_SET_COLOR(56, 0, 255, 0); // H (Left) RGB_MATRIX_INDICATOR_SET_COLOR(57, 0, 255, 0); // J (Down) RGB_MATRIX_INDICATOR_SET_COLOR(58, 0, 255, 0); // K (Up) RGB_MATRIX_INDICATOR_SET_COLOR(59, 0, 255, 0); // L (Right) } return true; } #endif