X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=docs%2Ftap_dance.md;h=473725414a246c15d34cf284b2af560a6069aa8e;hb=a860d9d628ae5b99e8c676af4e8226640b53e7d4;hp=38b2ee99938774481e5b385b7c80b92d83c5b516;hpb=ea3df7466aa29312b3e781f29532e10fa8a08a1f;p=qmk_firmware.git diff --git a/docs/tap_dance.md b/docs/tap_dance.md index 38b2ee999..473725414 100644 --- a/docs/tap_dance.md +++ b/docs/tap_dance.md @@ -14,7 +14,7 @@ The implementation hooks into two parts of the system, to achieve this: into `pr But lets start with how to use it, first! -First, you will need `TAP_DANCE_ENABLE=yes` in your `Makefile`, because the feature is disabled by default. This adds a little less than 1k to the firmware size. Next, you will want to define some tap-dance keys, which is easiest to do with the `TD()` macro, that - similar to `F()`, takes a number, which will later be used as an index into the `tap_dance_actions` array. +First, you will need `TAP_DANCE_ENABLE=yes` in your `rules.mk`, because the feature is disabled by default. This adds a little less than 1k to the firmware size. Next, you will want to define some tap-dance keys, which is easiest to do with the `TD()` macro, that - similar to `F()`, takes a number, which will later be used as an index into the `tap_dance_actions` array. This array specifies what actions shall be taken when a tap-dance key is in action. Currently, there are three possible options: @@ -42,7 +42,7 @@ For the sake of flexibility, tap-dance actions can be either a pair of keycodes, Here's a simple example for a single definition: -1. In your `makefile`, add `TAP_DANCE_ENABLE = yes` +1. In your `rules.mk`, add `TAP_DANCE_ENABLE = yes` 2. In your `config.h` (which you can copy from `qmk_firmware/keyboards/planck/config.h` to your keymap directory), add `#define TAPPING_TERM 200` 3. In your `keymap.c` file, define the variables and definitions, then add to your keymap: @@ -63,20 +63,23 @@ qk_tap_dance_action_t tap_dance_actions[] = { TD(TD_ESC_CAPS) ``` -## Complex Example +## Complex Examples -Here's a more complex example involving custom actions: +This section details several complex tap dance examples. +All the enums used in the examples are declared like this: ```c +// Enums defined for all examples: enum { CT_SE = 0, CT_CLN, CT_EGG, CT_FLSH, + X_TAP_DANCE }; - -/* Have the above three on the keymap, TD(CT_SE), etc... */ - +``` +### Example 1: Send `:` on single tap, `;` on double tap +```c void dance_cln_finished (qk_tap_dance_state_t *state, void *user_data) { if (state->count == 1) { register_code (KC_RSFT); @@ -95,6 +98,13 @@ void dance_cln_reset (qk_tap_dance_state_t *state, void *user_data) { } } +//All tap dance functions would go here. Only showing this one. +qk_tap_dance_action_t tap_dance_actions[] = { + [CT_CLN] = ACTION_TAP_DANCE_FN_ADVANCED (NULL, dance_cln_finished, dance_cln_reset) +}; +``` +### Example 2: Send "Safety Dance!" after 100 taps +```c void dance_egg (qk_tap_dance_state_t *state, void *user_data) { if (state->count >= 100) { SEND_STRING ("Safety dance!"); @@ -102,6 +112,14 @@ void dance_egg (qk_tap_dance_state_t *state, void *user_data) { } } +qk_tap_dance_action_t tap_dance_actions[] = { + [CT_EGG] = ACTION_TAP_DANCE_FN (dance_egg) +}; +``` + +### Example 3: Turn LED lights on then off, one at a time + +```c // on each tap, light up one led, from right to left // on the forth tap, turn them off from right to left 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) { ergodox_right_led_3_off(); } +//All tap dances now put together. Example 3 is "CT_FLASH" qk_tap_dance_action_t tap_dance_actions[] = { [CT_SE] = ACTION_TAP_DANCE_DOUBLE (KC_SPC, KC_ENT) ,[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[] = { ,[CT_FLSH] = ACTION_TAP_DANCE_FN_ADVANCED (dance_flsh_each, dance_flsh_finished, dance_flsh_reset) }; ``` + +### Example 4: 'Quad Function Tap-Dance' + +By @DanielGGordon + +Allow one key to have 4 (or more) functions, depending on number of presses, and if the key is held or tapped. +Below is a specific example: +* Tap = Send `x` +* Hold = Send `Control` +* Double Tap = Send `Escape` +* Double Tap and Hold = Send `Alt` + +The following example can be easily expanded to more than 4 quite easily: +```c +//**************** Definitions needed for quad function to work *********************// +//Enums used to clearly convey the state of the tap dance +enum { + SINGLE_TAP = 1, + SINGLE_HOLD = 2, + DOUBLE_TAP = 3, + DOUBLE_HOLD = 4 + // Add more enums here if you want for triple, quadruple, etc. +}; + +typedef struct { + bool is_press_action; + int state; +} tap; + +int cur_dance (qk_tap_dance_state_t *state) { + if ((state->count == 1) && (!state->pressed)) return SINGLE_TAP; + else if ((state->count == 1) && (state->pressed)) return SINGLE_HOLD; + else if ((state->count == 2) && (!state->pressed)) return DOUBLE_TAP; + else if ((state->count == 2) && (state->pressed)) return DOUBLE_HOLD; + else return 5; //magic number. At some point this method will expand to work for more presses +} +//**************** Definitions needed for quad function to work *********************// + +//instanalize an instance of 'tap' for the 'x' tap dance. +static tap xtap_state = { + .is_press_action = true, + .state = 0 +}; + +void x_finished (qk_tap_dance_state_t *state, void *user_data) { + xtap_state.state = cur_dance(state); + switch (xtap_state.state) { + case SINGLE_TAP: register_code(KC_X); break; + case SINGLE_HOLD: register_code(KC_LCTRL); break; + case DOUBLE_TAP: register_code(KC_ESC); break; + case DOUBLE_HOLD: register_code(KC_LALT); + } +} + +void x_reset (qk_tap_dance_state_t *state, void *user_data) { + switch (xtap_state.state) { + case SINGLE_TAP: unregister_code(KC_X); break; + case SINGLE_HOLD: unregister_code(KC_LCTRL); break; + case DOUBLE_TAP: unregister_code(KC_ESC); break; + case DOUBLE_HOLD: unregister_code(KC_LALT); + } + xtap_state.state = 0; +} +``` +And then simply add this to your list of tap dance functions: +`[X_TAP_DANCE] = ACTION_TAP_DANCE_FN_ADVANCED(NULL, x_finished, x_reset)`