diff options
| author | Daniel Gordon <daniel.gordon@here.com> | 2017-10-18 12:41:28 -0500 |
|---|---|---|
| committer | Jack Humbert <jack.humb@gmail.com> | 2017-10-18 17:14:12 -1000 |
| commit | 383e508bc56870aa971c4a881ed43dfe2f44f2ce (patch) | |
| tree | cd37798adedb6cf290a38af7416ae683e87640bf /docs | |
| parent | 3f3fa0791895f14370b4bb3e8512597688c45122 (diff) | |
| download | qmk_firmware-383e508bc56870aa971c4a881ed43dfe2f44f2ce.tar.gz qmk_firmware-383e508bc56870aa971c4a881ed43dfe2f44f2ce.zip | |
Quad Function Tap Dance added to TD Doc
* Added section to example, detailing how to accomplish the
'quad-function' tap dance.
* Refactored TD documentation to clearly separate different complex
examples
Change-Id: Ifc1495d1142849c771418fdabc458c04c48311e6
Diffstat (limited to 'docs')
| -rw-r--r-- | docs/tap_dance.md | 95 |
1 files changed, 90 insertions, 5 deletions
diff --git a/docs/tap_dance.md b/docs/tap_dance.md index 442162765..473725414 100644 --- a/docs/tap_dance.md +++ b/docs/tap_dance.md | |||
| @@ -63,20 +63,23 @@ qk_tap_dance_action_t tap_dance_actions[] = { | |||
| 63 | TD(TD_ESC_CAPS) | 63 | TD(TD_ESC_CAPS) |
| 64 | ``` | 64 | ``` |
| 65 | 65 | ||
| 66 | ## Complex Example | 66 | ## Complex Examples |
| 67 | 67 | ||
| 68 | Here's a more complex example involving custom actions: | 68 | This section details several complex tap dance examples. |
| 69 | All the enums used in the examples are declared like this: | ||
| 69 | 70 | ||
| 70 | ```c | 71 | ```c |
| 72 | // Enums defined for all examples: | ||
| 71 | enum { | 73 | enum { |
| 72 | CT_SE = 0, | 74 | CT_SE = 0, |
| 73 | CT_CLN, | 75 | CT_CLN, |
| 74 | CT_EGG, | 76 | CT_EGG, |
| 75 | CT_FLSH, | 77 | CT_FLSH, |
| 78 | X_TAP_DANCE | ||
| 76 | }; | 79 | }; |
| 77 | 80 | ``` | |
| 78 | /* Have the above three on the keymap, TD(CT_SE), etc... */ | 81 | ### Example 1: Send `:` on single tap, `;` on double tap |
| 79 | 82 | ```c | |
| 80 | void dance_cln_finished (qk_tap_dance_state_t *state, void *user_data) { | 83 | void dance_cln_finished (qk_tap_dance_state_t *state, void *user_data) { |
| 81 | if (state->count == 1) { | 84 | if (state->count == 1) { |
| 82 | register_code (KC_RSFT); | 85 | register_code (KC_RSFT); |
| @@ -95,6 +98,13 @@ void dance_cln_reset (qk_tap_dance_state_t *state, void *user_data) { | |||
| 95 | } | 98 | } |
| 96 | } | 99 | } |
| 97 | 100 | ||
| 101 | //All tap dance functions would go here. Only showing this one. | ||
| 102 | qk_tap_dance_action_t tap_dance_actions[] = { | ||
| 103 | [CT_CLN] = ACTION_TAP_DANCE_FN_ADVANCED (NULL, dance_cln_finished, dance_cln_reset) | ||
| 104 | }; | ||
| 105 | ``` | ||
| 106 | ### Example 2: Send "Safety Dance!" after 100 taps | ||
| 107 | ```c | ||
| 98 | void dance_egg (qk_tap_dance_state_t *state, void *user_data) { | 108 | void dance_egg (qk_tap_dance_state_t *state, void *user_data) { |
| 99 | if (state->count >= 100) { | 109 | if (state->count >= 100) { |
| 100 | SEND_STRING ("Safety dance!"); | 110 | SEND_STRING ("Safety dance!"); |
| @@ -102,6 +112,14 @@ void dance_egg (qk_tap_dance_state_t *state, void *user_data) { | |||
| 102 | } | 112 | } |
| 103 | } | 113 | } |
| 104 | 114 | ||
| 115 | qk_tap_dance_action_t tap_dance_actions[] = { | ||
| 116 | [CT_EGG] = ACTION_TAP_DANCE_FN (dance_egg) | ||
| 117 | }; | ||
| 118 | ``` | ||
| 119 | |||
| 120 | ### Example 3: Turn LED lights on then off, one at a time | ||
| 121 | |||
| 122 | ```c | ||
| 105 | // on each tap, light up one led, from right to left | 123 | // on each tap, light up one led, from right to left |
| 106 | // on the forth tap, turn them off from right to left | 124 | // on the forth tap, turn them off from right to left |
| 107 | void dance_flsh_each(qk_tap_dance_state_t *state, void *user_data) { | 125 | void dance_flsh_each(qk_tap_dance_state_t *state, void *user_data) { |
| @@ -141,6 +159,7 @@ void dance_flsh_reset(qk_tap_dance_state_t *state, void *user_data) { | |||
| 141 | ergodox_right_led_3_off(); | 159 | ergodox_right_led_3_off(); |
| 142 | } | 160 | } |
| 143 | 161 | ||
| 162 | //All tap dances now put together. Example 3 is "CT_FLASH" | ||
| 144 | qk_tap_dance_action_t tap_dance_actions[] = { | 163 | qk_tap_dance_action_t tap_dance_actions[] = { |
| 145 | [CT_SE] = ACTION_TAP_DANCE_DOUBLE (KC_SPC, KC_ENT) | 164 | [CT_SE] = ACTION_TAP_DANCE_DOUBLE (KC_SPC, KC_ENT) |
| 146 | ,[CT_CLN] = ACTION_TAP_DANCE_FN_ADVANCED (NULL, dance_cln_finished, dance_cln_reset) | 165 | ,[CT_CLN] = ACTION_TAP_DANCE_FN_ADVANCED (NULL, dance_cln_finished, dance_cln_reset) |
| @@ -148,3 +167,69 @@ qk_tap_dance_action_t tap_dance_actions[] = { | |||
| 148 | ,[CT_FLSH] = ACTION_TAP_DANCE_FN_ADVANCED (dance_flsh_each, dance_flsh_finished, dance_flsh_reset) | 167 | ,[CT_FLSH] = ACTION_TAP_DANCE_FN_ADVANCED (dance_flsh_each, dance_flsh_finished, dance_flsh_reset) |
| 149 | }; | 168 | }; |
| 150 | ``` | 169 | ``` |
| 170 | |||
| 171 | ### Example 4: 'Quad Function Tap-Dance' | ||
| 172 | |||
| 173 | By @DanielGGordon | ||
| 174 | |||
| 175 | Allow one key to have 4 (or more) functions, depending on number of presses, and if the key is held or tapped. | ||
| 176 | Below is a specific example: | ||
| 177 | * Tap = Send `x` | ||
| 178 | * Hold = Send `Control` | ||
| 179 | * Double Tap = Send `Escape` | ||
| 180 | * Double Tap and Hold = Send `Alt` | ||
| 181 | |||
| 182 | The following example can be easily expanded to more than 4 quite easily: | ||
| 183 | ```c | ||
| 184 | //**************** Definitions needed for quad function to work *********************// | ||
| 185 | //Enums used to clearly convey the state of the tap dance | ||
| 186 | enum { | ||
| 187 | SINGLE_TAP = 1, | ||
| 188 | SINGLE_HOLD = 2, | ||
| 189 | DOUBLE_TAP = 3, | ||
| 190 | DOUBLE_HOLD = 4 | ||
| 191 | // Add more enums here if you want for triple, quadruple, etc. | ||
| 192 | }; | ||
| 193 | |||
| 194 | typedef struct { | ||
| 195 | bool is_press_action; | ||
| 196 | int state; | ||
| 197 | } tap; | ||
| 198 | |||
| 199 | int cur_dance (qk_tap_dance_state_t *state) { | ||
| 200 | if ((state->count == 1) && (!state->pressed)) return SINGLE_TAP; | ||
| 201 | else if ((state->count == 1) && (state->pressed)) return SINGLE_HOLD; | ||
| 202 | else if ((state->count == 2) && (!state->pressed)) return DOUBLE_TAP; | ||
| 203 | else if ((state->count == 2) && (state->pressed)) return DOUBLE_HOLD; | ||
| 204 | else return 5; //magic number. At some point this method will expand to work for more presses | ||
| 205 | } | ||
| 206 | //**************** Definitions needed for quad function to work *********************// | ||
| 207 | |||
| 208 | //instanalize an instance of 'tap' for the 'x' tap dance. | ||
| 209 | static tap xtap_state = { | ||
| 210 | .is_press_action = true, | ||
| 211 | .state = 0 | ||
| 212 | }; | ||
| 213 | |||
| 214 | void x_finished (qk_tap_dance_state_t *state, void *user_data) { | ||
| 215 | xtap_state.state = cur_dance(state); | ||
| 216 | switch (xtap_state.state) { | ||
| 217 | case SINGLE_TAP: register_code(KC_X); break; | ||
| 218 | case SINGLE_HOLD: register_code(KC_LCTRL); break; | ||
| 219 | case DOUBLE_TAP: register_code(KC_ESC); break; | ||
| 220 | case DOUBLE_HOLD: register_code(KC_LALT); | ||
| 221 | } | ||
| 222 | } | ||
| 223 | |||
| 224 | void x_reset (qk_tap_dance_state_t *state, void *user_data) { | ||
| 225 | switch (xtap_state.state) { | ||
| 226 | case SINGLE_TAP: unregister_code(KC_X); break; | ||
| 227 | case SINGLE_HOLD: unregister_code(KC_LCTRL); break; | ||
| 228 | case DOUBLE_TAP: unregister_code(KC_ESC); break; | ||
| 229 | case DOUBLE_HOLD: unregister_code(KC_LALT); | ||
| 230 | } | ||
| 231 | xtap_state.state = 0; | ||
| 232 | } | ||
| 233 | ``` | ||
| 234 | And then simply add this to your list of tap dance functions: | ||
| 235 | `[X_TAP_DANCE] = ACTION_TAP_DANCE_FN_ADVANCED(NULL, x_finished, x_reset)` | ||
