jlj-qmk/keyboards/planck/keymaps/corvec/tapdance.c
2018-03-07 16:58:51 -05:00

157 lines
4.6 KiB
C

/**
* Tap Dance config and functions
**/
/* Copyright 2018 Corey Kump
*
* 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 <http://www.gnu.org/licenses/>.
*/
enum {
SINGLE_TAP = 1,
SINGLE_HOLD = 2,
DOUBLE_TAP = 3,
DOUBLE_SINGLE_TAP = 4,
UNKNOWN_TAPS = 5
};
typedef struct {
bool is_press_action;
int state;
} tap;
int cur_dance (qk_tap_dance_state_t *state) {
if (state->count == 1) {
if (state->interrupted || !state->pressed) {
return SINGLE_TAP;
} else {
return SINGLE_HOLD;
}
}
if (state->count == 2) {
if (state->interrupted) {
return DOUBLE_SINGLE_TAP;
} else if (!state->pressed) {
return DOUBLE_TAP;
}
}
return UNKNOWN_TAPS;
}
/**
* quote
**/
static tap quote_state = {
.is_press_action = true,
.state = 0
};
void quote_finished(qk_tap_dance_state_t *state, void *user_data) {
quote_state.state = cur_dance(state);
switch(quote_state.state) {
case SINGLE_TAP: register_code(KC_QUOT); break;
case SINGLE_HOLD: layer_on(_LEANDOWN); break;
case DOUBLE_TAP: register_code(KC_MINS); break;
case DOUBLE_SINGLE_TAP: register_code(KC_QUOT); unregister_code(KC_QUOT); register_code(KC_QUOT); break;
}
}
void quote_reset(qk_tap_dance_state_t *state, void *user_data) {
switch(quote_state.state) {
case SINGLE_TAP: unregister_code(KC_QUOT); break;
case SINGLE_HOLD: layer_off(_LEANDOWN); break;
case DOUBLE_TAP: unregister_code(KC_MINS); break;
case DOUBLE_SINGLE_TAP: unregister_code(KC_QUOT); break;
}
quote_state.state = 0;
}
/**
* ralt / left bracket / left curly brace
**/
static tap ralt_state = {
.is_press_action = true,
.state = 0
};
void ralt_finished(qk_tap_dance_state_t *state, void *user_data) {
ralt_state.state = cur_dance(state);
switch(ralt_state.state) {
case SINGLE_TAP: register_code(KC_LBRC); break;
case SINGLE_HOLD: register_code(KC_RALT); break;
case DOUBLE_TAP: register_code(KC_LSFT); register_code(KC_LBRC); break;
// fallback to alt because it's the primary purpose of this key
case DOUBLE_SINGLE_TAP: register_code(KC_RALT); break;
}
}
void ralt_reset(qk_tap_dance_state_t *state, void *user_data) {
switch(ralt_state.state) {
case SINGLE_TAP: unregister_code(KC_LBRC); break;
case SINGLE_HOLD: unregister_code(KC_RALT); break;
case DOUBLE_TAP: unregister_code(KC_LBRC); unregister_code(KC_LSFT); break;
case DOUBLE_SINGLE_TAP: unregister_code(KC_RALT); break;
}
ralt_state.state = 0;
}
/**
* rgui / right bracket / right curly brace
**/
static tap rgui_state = {
.is_press_action = true,
.state = 0
};
void rgui_finished(qk_tap_dance_state_t *state, void *user_data) {
rgui_state.state = cur_dance(state);
switch(rgui_state.state) {
case SINGLE_TAP: register_code(KC_RBRC); break;
case SINGLE_HOLD: register_code(KC_RGUI); break;
case DOUBLE_TAP: register_code(KC_LSFT); register_code(KC_RBRC); break;
// fallback to alt because it's the primary purpose of this key
case DOUBLE_SINGLE_TAP: register_code(KC_RGUI); break;
}
}
void rgui_reset(qk_tap_dance_state_t *state, void *user_data) {
switch(rgui_state.state) {
case SINGLE_TAP: unregister_code(KC_RBRC); break;
case SINGLE_HOLD: unregister_code(KC_RGUI); break;
case DOUBLE_TAP: unregister_code(KC_RBRC); unregister_code(KC_LSFT); break;
case DOUBLE_SINGLE_TAP: unregister_code(KC_RGUI); break;
}
rgui_state.state = 0;
}
/**
* Define the available tap dance keys
**/
enum {
TD_ALT_SHIFT = 0,
TD_LQUT_MINS,
TD_QUOT_LEAN_MINS,
TD_LBRC_RALT_LCBR,
TD_RBRC_RGUI_RCBR
};
qk_tap_dance_action_t tap_dance_actions[] = {
// Tap once for Alt, twice for Shift
[TD_ALT_SHIFT] = ACTION_TAP_DANCE_DOUBLE(KC_RALT, KC_RSFT),
[TD_QUOT_LEAN_MINS] = ACTION_TAP_DANCE_FN_ADVANCED(NULL, quote_finished, quote_reset),
[TD_LBRC_RALT_LCBR] = ACTION_TAP_DANCE_FN_ADVANCED(NULL, ralt_finished, ralt_reset),
[TD_RBRC_RGUI_RCBR] = ACTION_TAP_DANCE_FN_ADVANCED(NULL, rgui_finished, rgui_reset)
};