diff options
| author | Joe Wasson <jwasson+github@gmail.com> | 2018-09-19 16:13:58 -0700 |
|---|---|---|
| committer | Drashna Jaelre <drashna@live.com> | 2018-09-19 16:13:58 -0700 |
| commit | c23233f41ab9221577fc83bbae0a230452a38231 (patch) | |
| tree | 659d89fab1b5d8e27642a3de50ac66e33205df83 /users/talljoe/tapdance.c | |
| parent | 71fe973190610bf155d864c71b8b326bc1b74eab (diff) | |
| download | qmk_firmware-c23233f41ab9221577fc83bbae0a230452a38231.tar.gz qmk_firmware-c23233f41ab9221577fc83bbae0a230452a38231.zip | |
Keymap: Talljoe's keymap for oddball keyboards (#3910)
* Create layout for JD45
* Tweak layout to better support JD45 and add more tap dancing.
* Add Maltron and tweak layout for 40% enter compatibility.
* Switch back to `BL_TOGGLE` for backlight.
* More tweaks
* Rename talljoe_gherkin to talljoe-gherkin
* Make NAV layer tab C_S_T also.
* Add missing RESET key.
* Add Talljoe layout for minivan.
* MTI is not for me
* Tweak keymap.
* Add talljoe keymap to Atreus.
* Minor tweaks.
* Fix talljoe keymaps to work with new Zeal60 commit.
Diffstat (limited to 'users/talljoe/tapdance.c')
| -rw-r--r-- | users/talljoe/tapdance.c | 148 |
1 files changed, 130 insertions, 18 deletions
diff --git a/users/talljoe/tapdance.c b/users/talljoe/tapdance.c index 3198fc67f..c4d6025f0 100644 --- a/users/talljoe/tapdance.c +++ b/users/talljoe/tapdance.c | |||
| @@ -1,34 +1,146 @@ | |||
| 1 | //Tap Dance | 1 | //Tap Dance |
| 2 | #include "talljoe.h" | 2 | #include "talljoe.h" |
| 3 | 3 | ||
| 4 | // Send semin-colon + enter on two taps | 4 | enum { |
| 5 | void tap_dance_semicolon(qk_tap_dance_state_t *state, void *user_data) { | 5 | SINGLE_TAP = 1, |
| 6 | SINGLE_HOLD = 2, | ||
| 7 | DOUBLE_TAP = 3, | ||
| 8 | DOUBLE_HOLD = 4, | ||
| 9 | DOUBLE_SINGLE_TAP = 5, //send two single taps | ||
| 10 | TRIPLE_TAP = 6, | ||
| 11 | TRIPLE_HOLD = 7, | ||
| 12 | SPECIAL = 8 | ||
| 13 | }; | ||
| 14 | |||
| 15 | static struct { | ||
| 16 | int quote; | ||
| 17 | int semicolon; | ||
| 18 | } tap_state = {0}; | ||
| 19 | |||
| 20 | int cur_dance (qk_tap_dance_state_t *state) { | ||
| 21 | if (state->count == 1) { | ||
| 22 | //If count = 1, and it has been interrupted - it doesn't matter if it is pressed or not: Send SINGLE_TAP | ||
| 23 | if (state->interrupted) { | ||
| 24 | // if (!state->pressed) return SINGLE_TAP; | ||
| 25 | //need "permissive hold" here. | ||
| 26 | // else return SINGLE_HOLD; | ||
| 27 | //If the interrupting key is released before the tap-dance key, then it is a single HOLD | ||
| 28 | //However, if the tap-dance key is released first, then it is a single TAP | ||
| 29 | //But how to get access to the state of the interrupting key???? | ||
| 30 | return SINGLE_TAP; | ||
| 31 | } | ||
| 32 | else { | ||
| 33 | if (!state->pressed) return SINGLE_TAP; | ||
| 34 | else return SINGLE_HOLD; | ||
| 35 | } | ||
| 36 | } | ||
| 37 | //If count = 2, and it has been interrupted - assume that user is trying to type the letter associated | ||
| 38 | //with single tap. | ||
| 39 | else if (state->count == 2) { | ||
| 40 | if (state->interrupted) return DOUBLE_SINGLE_TAP; | ||
| 41 | else if (state->pressed) return DOUBLE_HOLD; | ||
| 42 | else return DOUBLE_TAP; | ||
| 43 | } | ||
| 44 | else if ((state->count == 3) && ((state->interrupted) || (!state->pressed))) return TRIPLE_TAP; | ||
| 45 | else if (state->count == 3) return TRIPLE_HOLD; | ||
| 46 | else return SPECIAL; | ||
| 47 | } | ||
| 48 | |||
| 49 | int hold_cur_dance (qk_tap_dance_state_t *state) { | ||
| 50 | if (state->count == 1) { | ||
| 51 | if (state->interrupted) { | ||
| 52 | if (!state->pressed) return SINGLE_TAP; | ||
| 53 | else return SINGLE_HOLD; | ||
| 54 | } | ||
| 55 | else { | ||
| 56 | if (!state->pressed) return SINGLE_TAP; | ||
| 57 | else return SINGLE_HOLD; | ||
| 58 | } | ||
| 59 | } | ||
| 60 | //If count = 2, and it has been interrupted - assume that user is trying to type the letter associated | ||
| 61 | //with single tap. | ||
| 62 | else if (state->count == 2) { | ||
| 63 | if (state->pressed) return DOUBLE_HOLD; | ||
| 64 | else return DOUBLE_TAP; | ||
| 65 | } | ||
| 66 | else if (state->count == 3) { | ||
| 67 | if (!state->pressed) return TRIPLE_TAP; | ||
| 68 | else return TRIPLE_HOLD; | ||
| 69 | } | ||
| 70 | else return SPECIAL; | ||
| 71 | } | ||
| 72 | |||
| 73 | // Send semi-colon + enter on two taps | ||
| 74 | void tap_dance_semicolon_finished(qk_tap_dance_state_t *state, void *user_data) { | ||
| 75 | tap_state.semicolon = hold_cur_dance(state); | ||
| 76 | switch (tap_state.semicolon) { | ||
| 77 | case SINGLE_TAP: case DOUBLE_HOLD: register_code(KC_SCLN); break; | ||
| 78 | case SINGLE_HOLD: layer_on(_NUM); break; | ||
| 79 | } | ||
| 80 | } | ||
| 81 | |||
| 82 | void tap_dance_semicolon_reset(qk_tap_dance_state_t *state, void *user_data) { | ||
| 83 | switch (tap_state.semicolon) { | ||
| 84 | case SINGLE_TAP: case DOUBLE_HOLD: unregister_code(KC_SCLN); break; | ||
| 85 | case DOUBLE_TAP: { | ||
| 86 | if (get_mods()) { | ||
| 87 | SEND_STRING(";;"); // send normal when mods are pressed | ||
| 88 | } | ||
| 89 | else { | ||
| 90 | SEND_STRING(";\n"); | ||
| 91 | } | ||
| 92 | break; | ||
| 93 | } | ||
| 94 | case TRIPLE_TAP: { | ||
| 95 | SEND_STRING(";\n\n"); | ||
| 96 | } | ||
| 97 | case SPECIAL: layer_invert(_NUM); break; | ||
| 98 | case SINGLE_HOLD: layer_off(_NUM); break; | ||
| 99 | } | ||
| 100 | tap_state.semicolon = 0; | ||
| 101 | } | ||
| 102 | |||
| 103 | // Send `. ~. ``` | ||
| 104 | void tap_dance_grave_finished(qk_tap_dance_state_t *state, void *user_data) { | ||
| 6 | switch(state->count) { | 105 | switch(state->count) { |
| 7 | case 1: | 106 | case 1: |
| 8 | register_code(KC_SCLN); | 107 | SEND_STRING("`"); |
| 9 | unregister_code(KC_SCLN); | ||
| 10 | break; | 108 | break; |
| 11 | case 2: | 109 | case 2: |
| 12 | register_code(KC_SCLN); | 110 | SEND_STRING("~"); |
| 13 | unregister_code(KC_SCLN); | 111 | break; |
| 112 | } | ||
| 113 | } | ||
| 14 | 114 | ||
| 15 | uint8_t mods = get_mods(); | 115 | void tap_dance_grave_each(qk_tap_dance_state_t *state, void *user_data) { |
| 16 | if (mods) { | 116 | if(state->count == 3) { |
| 17 | clear_mods(); | 117 | SEND_STRING("```"); |
| 18 | } | 118 | } else if (state->count > 3) { |
| 119 | SEND_STRING("`"); | ||
| 120 | } | ||
| 121 | } | ||
| 19 | 122 | ||
| 20 | register_code(KC_ENT); | ||
| 21 | unregister_code(KC_ENT); | ||
| 22 | 123 | ||
| 23 | if (mods) { | 124 | void tap_dance_quote_finished(qk_tap_dance_state_t *state, void *user_data) { |
| 24 | set_mods(mods); | 125 | tap_state.quote = hold_cur_dance(state); |
| 25 | } | 126 | switch (tap_state.quote) { |
| 127 | case SINGLE_TAP: case DOUBLE_HOLD: register_code(KC_QUOT); break; | ||
| 128 | case SINGLE_HOLD: layer_on(_NAV); break; | ||
| 129 | } | ||
| 130 | } | ||
| 26 | 131 | ||
| 27 | reset_tap_dance(state); | 132 | void tap_dance_quote_reset(qk_tap_dance_state_t *state, void *user_data) { |
| 28 | break; | 133 | switch (tap_state.quote) { |
| 134 | case SINGLE_TAP: case DOUBLE_HOLD: unregister_code(KC_QUOTE); break; | ||
| 135 | case DOUBLE_TAP: SEND_STRING("\""); break; | ||
| 136 | case TRIPLE_TAP: layer_invert(_NAV); break; | ||
| 137 | case SINGLE_HOLD: layer_off(_NAV); break; | ||
| 29 | } | 138 | } |
| 139 | tap_state.quote = 0; | ||
| 30 | } | 140 | } |
| 31 | 141 | ||
| 32 | qk_tap_dance_action_t tap_dance_actions[] = { | 142 | qk_tap_dance_action_t tap_dance_actions[] = { |
| 33 | [TD_SEMICOLON] = ACTION_TAP_DANCE_FN(tap_dance_semicolon), | 143 | [TD_SEMICOLON] = ACTION_TAP_DANCE_FN_ADVANCED(NULL, tap_dance_semicolon_finished, tap_dance_semicolon_reset), |
| 144 | [TD_GRAVE] = ACTION_TAP_DANCE_FN_ADVANCED(tap_dance_grave_each, tap_dance_grave_finished, NULL), | ||
| 145 | [TD_QUOTE] = ACTION_TAP_DANCE_FN_ADVANCED(NULL, tap_dance_quote_finished, tap_dance_quote_reset), | ||
| 34 | }; | 146 | }; |
