aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJack Humbert <jack.humb@gmail.com>2016-07-21 20:56:24 -0400
committerGitHub <noreply@github.com>2016-07-21 20:56:24 -0400
commit62a6d3a6f57fa55a016497d88b725cc82c395194 (patch)
tree5074f65a0cf9029a456d473120d2f42d8f702dae
parent9ecf9073b96799e52a1f1c0d35b57177382902ce (diff)
parent4e6a8627d8ebd7af942f68142d1a959d60361d90 (diff)
downloadqmk_firmware-62a6d3a6f57fa55a016497d88b725cc82c395194.tar.gz
qmk_firmware-62a6d3a6f57fa55a016497d88b725cc82c395194.zip
Merge pull request #516 from pvinis/tap-dance-anyway
Tap dance anyway
-rw-r--r--quantum/process_keycode/process_tap_dance.c52
-rw-r--r--quantum/process_keycode/process_tap_dance.h19
-rw-r--r--readme.md48
3 files changed, 103 insertions, 16 deletions
diff --git a/quantum/process_keycode/process_tap_dance.c b/quantum/process_keycode/process_tap_dance.c
index 9b172e1b6..b9b836df2 100644
--- a/quantum/process_keycode/process_tap_dance.c
+++ b/quantum/process_keycode/process_tap_dance.c
@@ -22,10 +22,29 @@ static void _process_tap_dance_action_pair (qk_tap_dance_state_t *state,
22static void _process_tap_dance_action_fn (qk_tap_dance_state_t *state, 22static void _process_tap_dance_action_fn (qk_tap_dance_state_t *state,
23 qk_tap_dance_user_fn_t fn) 23 qk_tap_dance_user_fn_t fn)
24{ 24{
25 fn(state); 25 if (fn) {
26 fn(state);
27 }
28}
29
30void process_tap_dance_action_on_each_tap (uint16_t keycode)
31{
32 uint16_t idx = keycode - QK_TAP_DANCE;
33 qk_tap_dance_action_t action;
34
35 action = tap_dance_actions[idx];
36
37 switch (action.type) {
38 case QK_TAP_DANCE_TYPE_FN:
39 _process_tap_dance_action_fn (&qk_tap_dance_state, action.fn.on_each_tap);
40 break;
41
42 default:
43 break;
44 }
26} 45}
27 46
28void process_tap_dance_action (uint16_t keycode) 47void process_tap_dance_action_on_dance_finished (uint16_t keycode)
29{ 48{
30 uint16_t idx = keycode - QK_TAP_DANCE; 49 uint16_t idx = keycode - QK_TAP_DANCE;
31 qk_tap_dance_action_t action; 50 qk_tap_dance_action_t action;
@@ -38,7 +57,7 @@ void process_tap_dance_action (uint16_t keycode)
38 action.pair.kc1, action.pair.kc2); 57 action.pair.kc1, action.pair.kc2);
39 break; 58 break;
40 case QK_TAP_DANCE_TYPE_FN: 59 case QK_TAP_DANCE_TYPE_FN:
41 _process_tap_dance_action_fn (&qk_tap_dance_state, action.fn); 60 _process_tap_dance_action_fn (&qk_tap_dance_state, action.fn.on_dance_finished);
42 break; 61 break;
43 62
44 default: 63 default:
@@ -51,8 +70,9 @@ bool process_tap_dance(uint16_t keycode, keyrecord_t *record) {
51 70
52 switch(keycode) { 71 switch(keycode) {
53 case QK_TAP_DANCE ... QK_TAP_DANCE_MAX: 72 case QK_TAP_DANCE ... QK_TAP_DANCE_MAX:
73 process_tap_dance_action_on_each_tap (qk_tap_dance_state.keycode);
54 if (qk_tap_dance_state.keycode && qk_tap_dance_state.keycode != keycode) { 74 if (qk_tap_dance_state.keycode && qk_tap_dance_state.keycode != keycode) {
55 process_tap_dance_action (qk_tap_dance_state.keycode); 75 process_tap_dance_action_on_dance_finished (qk_tap_dance_state.keycode);
56 } else { 76 } else {
57 r = false; 77 r = false;
58 } 78 }
@@ -66,8 +86,9 @@ bool process_tap_dance(uint16_t keycode, keyrecord_t *record) {
66 86
67 default: 87 default:
68 if (qk_tap_dance_state.keycode) { 88 if (qk_tap_dance_state.keycode) {
69 process_tap_dance_action (qk_tap_dance_state.keycode); 89 // if we are here, the tap dance was interrupted by a different key
70 90 process_tap_dance_action_on_each_tap (qk_tap_dance_state.keycode);
91 process_tap_dance_action_on_dance_finished (qk_tap_dance_state.keycode);
71 reset_tap_dance (&qk_tap_dance_state); 92 reset_tap_dance (&qk_tap_dance_state);
72 } 93 }
73 break; 94 break;
@@ -78,13 +99,28 @@ bool process_tap_dance(uint16_t keycode, keyrecord_t *record) {
78 99
79void matrix_scan_tap_dance () { 100void matrix_scan_tap_dance () {
80 if (qk_tap_dance_state.keycode && timer_elapsed (qk_tap_dance_state.timer) > TAPPING_TERM) { 101 if (qk_tap_dance_state.keycode && timer_elapsed (qk_tap_dance_state.timer) > TAPPING_TERM) {
81 process_tap_dance_action (qk_tap_dance_state.keycode); 102 // if we are here, the tap dance was timed out
82 103 process_tap_dance_action_on_dance_finished (qk_tap_dance_state.keycode);
83 reset_tap_dance (&qk_tap_dance_state); 104 reset_tap_dance (&qk_tap_dance_state);
84 } 105 }
85} 106}
86 107
87void reset_tap_dance (qk_tap_dance_state_t *state) { 108void reset_tap_dance (qk_tap_dance_state_t *state) {
109 uint16_t idx = state->keycode - QK_TAP_DANCE;
110 qk_tap_dance_action_t action;
111
112 action = tap_dance_actions[idx];
113 switch (action.type) {
114 case QK_TAP_DANCE_TYPE_FN:
115 if (action.fn.on_reset) {
116 action.fn.on_reset(state);
117 }
118 break;
119
120 default:
121 break;
122 }
123
88 state->keycode = 0; 124 state->keycode = 0;
89 state->count = 0; 125 state->count = 0;
90} 126}
diff --git a/quantum/process_keycode/process_tap_dance.h b/quantum/process_keycode/process_tap_dance.h
index b9d7c7fcf..7b820584a 100644
--- a/quantum/process_keycode/process_tap_dance.h
+++ b/quantum/process_keycode/process_tap_dance.h
@@ -31,18 +31,27 @@ typedef struct
31 uint16_t kc1; 31 uint16_t kc1;
32 uint16_t kc2; 32 uint16_t kc2;
33 } pair; 33 } pair;
34 qk_tap_dance_user_fn_t fn; 34 struct {
35 qk_tap_dance_user_fn_t on_each_tap;
36 qk_tap_dance_user_fn_t on_dance_finished;
37 qk_tap_dance_user_fn_t on_reset;
38 } fn;
35 }; 39 };
36} qk_tap_dance_action_t; 40} qk_tap_dance_action_t;
37 41
38#define ACTION_TAP_DANCE_DOUBLE(kc1, kc2) { \ 42#define ACTION_TAP_DANCE_DOUBLE(kc1, kc2) { \
39 .type = QK_TAP_DANCE_TYPE_PAIR, \ 43 .type = QK_TAP_DANCE_TYPE_PAIR, \
40 .pair = { kc1, kc2 } \ 44 .pair = { kc1, kc2 } \
41 } 45 }
42 46
43#define ACTION_TAP_DANCE_FN(user_fn) { \ 47#define ACTION_TAP_DANCE_FN(user_fn) { \
44 .type = QK_TAP_DANCE_TYPE_FN, \ 48 .type = QK_TAP_DANCE_TYPE_FN, \
45 .fn = user_fn \ 49 .fn = { NULL, user_fn, NULL } \
50 }
51
52#define ACTION_TAP_DANCE_FN_ADVANCED(user_fn_on_each_tap, user_fn_on_dance_finished, user_fn_on_reset) { \
53 .type = QK_TAP_DANCE_TYPE_FN, \
54 .fn = { user_fn_on_each_tap, user_fn_on_dance_finished, user_fn_on_reset } \
46 } 55 }
47 56
48extern const qk_tap_dance_action_t tap_dance_actions[]; 57extern const qk_tap_dance_action_t tap_dance_actions[];
diff --git a/readme.md b/readme.md
index e0dcd5608..b5f7f6945 100644
--- a/readme.md
+++ b/readme.md
@@ -372,10 +372,11 @@ But lets start with how to use it, first!
372 372
373First, 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. 373First, 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.
374 374
375This array specifies what actions shall be taken when a tap-dance key is in action. Currently, there are two possible options: 375This array specifies what actions shall be taken when a tap-dance key is in action. Currently, there are three possible options:
376 376
377* `ACTION_TAP_DANCE_DOUBLE(kc1, kc2)`: Sends the `kc1` keycode when tapped once, `kc2` otherwise. 377* `ACTION_TAP_DANCE_DOUBLE(kc1, kc2)`: Sends the `kc1` keycode when tapped once, `kc2` otherwise.
378* `ACTION_TAP_DANCE_FN(fn)`: Calls the specified function - defined in the user keymap - with the current state of the tap-dance action. 378* `ACTION_TAP_DANCE_FN(fn)`: Calls the specified function - defined in the user keymap - with the final tap count of the tap dance action.
379* `ACTION_TAP_DANCE_FN_ADVANCED(on_each_tap_fn, on_dance_finished_fn, on_reset_fn)`: Calls the first specified function - defined in the user keymap - on every tap, the second function on when the dance action finishes (like the previous option), and the last function when the tap dance action resets.
379 380
380The first option is enough for a lot of cases, that just want dual roles. For example, `ACTION_TAP_DANCE(KC_SPC, KC_ENT)` will result in `Space` being sent on single-tap, `Enter` otherwise. 381The first option is enough for a lot of cases, that just want dual roles. For example, `ACTION_TAP_DANCE(KC_SPC, KC_ENT)` will result in `Space` being sent on single-tap, `Enter` otherwise.
381 382
@@ -399,7 +400,8 @@ In the end, let's see a full example!
399enum { 400enum {
400 CT_SE = 0, 401 CT_SE = 0,
401 CT_CLN, 402 CT_CLN,
402 CT_EGG 403 CT_EGG,
404 CT_FLSH,
403}; 405};
404 406
405/* Have the above three on the keymap, TD(CT_SE), etc... */ 407/* Have the above three on the keymap, TD(CT_SE), etc... */
@@ -424,10 +426,50 @@ void dance_egg (qk_tap_dance_state_t *state) {
424 } 426 }
425} 427}
426 428
429// on each tap, light up one led, from right to left
430// on the forth tap, turn them off from right to left
431void dance_flsh_each(qk_tap_dance_state_t *state) {
432 switch (state->count) {
433 case 1:
434 ergodox_right_led_3_on();
435 break;
436 case 2:
437 ergodox_right_led_2_on();
438 break;
439 case 3:
440 ergodox_right_led_1_on();
441 break;
442 case 4:
443 ergodox_right_led_3_off();
444 _delay_ms(50);
445 ergodox_right_led_2_off();
446 _delay_ms(50);
447 ergodox_right_led_1_off();
448 }
449}
450
451// on the fourth tap, set the keyboard on flash state
452void dance_flsh_finished(qk_tap_dance_state_t *state) {
453 if (state->count >= 4) {
454 reset_keyboard();
455 reset_tap_dance(state);
456 }
457}
458
459// if the flash state didnt happen, then turn off leds, left to right
460void dance_flsh_reset(qk_tap_dance_state_t *state) {
461 ergodox_right_led_1_off();
462 _delay_ms(50);
463 ergodox_right_led_2_off();
464 _delay_ms(50);
465 ergodox_right_led_3_off();
466}
467
427const qk_tap_dance_action_t tap_dance_actions[] = { 468const qk_tap_dance_action_t tap_dance_actions[] = {
428 [CT_SE] = ACTION_TAP_DANCE_DOUBLE (KC_SPC, KC_ENT) 469 [CT_SE] = ACTION_TAP_DANCE_DOUBLE (KC_SPC, KC_ENT)
429 ,[CT_CLN] = ACTION_TAP_DANCE_FN (dance_cln) 470 ,[CT_CLN] = ACTION_TAP_DANCE_FN (dance_cln)
430 ,[CT_EGG] = ACTION_TAP_DANCE_FN (dance_egg) 471 ,[CT_EGG] = ACTION_TAP_DANCE_FN (dance_egg)
472 ,[CT_FLSH] = ACTION_TAP_DANCE_FN_ADVANCED (dance_flsh_each, dance_flsh_finished, dance_flsh_reset)
431}; 473};
432``` 474```
433 475