+
+### 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)`