You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

269 lines
8.5 KiB

  1. /*
  2. Copyright 2018 Eric Gebhart <e.a.gebhart@gmail.com>
  3. This program is free software: you can redistribute it and/or modify
  4. it under the terms of the GNU General Public License as published by
  5. the Free Software Foundation, either version 2 of the License, or
  6. (at your option) any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with this program. If not, see <http://www.gnu.org/licenses/>.
  13. */
  14. #ifdef TAP_DANCES_ENABLE
  15. #include "tap_dances.h"
  16. #include "action.h"
  17. #include "action_layer.h"
  18. #include "process_keycode/process_tap_dance.h"
  19. void tap_dance_mouse_btns (qk_tap_dance_state_t *state, void *user_data) {
  20. switch(state->count){
  21. case 1:
  22. register_code(KC_BTN1);
  23. break;
  24. case 2:
  25. register_code(KC_BTN2);
  26. break;
  27. case 3:
  28. register_code(KC_BTN3);
  29. break;
  30. case 4:
  31. register_code(KC_BTN4);
  32. break;
  33. case 5:
  34. register_code(KC_BTN5);
  35. break;
  36. default:
  37. break;
  38. }
  39. reset_tap_dance(state);
  40. }
  41. // counting on all the qwerty layers to be less than dvorak_on_bepo
  42. int on_qwerty(){
  43. uint8_t deflayer = (biton32(default_layer_state));
  44. return (deflayer < _DVORAK_BP);
  45. }
  46. static void switch_default_layer(uint8_t layer) {
  47. default_layer_set(1UL<<layer);
  48. clear_keyboard();
  49. }
  50. // so the keyboard remembers which layer it's in after power disconnect.
  51. /*
  52. uint32_t default_layer_state_set_kb(uint32_t state) {
  53. eeconfig_update_default_layer(state);
  54. return state;
  55. }
  56. */
  57. void tap_dance_df_bepo_layers_switch (qk_tap_dance_state_t *state, void *user_data) {
  58. switch(state->count){
  59. case 1:
  60. switch_default_layer(_DVORAK_BP);
  61. break;
  62. case 2:
  63. switch_default_layer(_BEPO);
  64. break;
  65. case 3:
  66. layer_invert(_LAYERS);
  67. break;
  68. default:
  69. break;
  70. }
  71. reset_tap_dance(state);
  72. }
  73. void tap_dance_layer_switch (qk_tap_dance_state_t *state, void *user_data) {
  74. switch(state->count){
  75. case 1:
  76. if(on_qwerty())
  77. layer_invert(_SYMB);
  78. else
  79. layer_invert(_SYMB_BP);
  80. break;
  81. case 2:
  82. layer_invert(_NAV);
  83. break;
  84. case 3:
  85. layer_invert(_LAYERS);
  86. break;
  87. case 4:
  88. if(on_qwerty())
  89. layer_invert(_KEYPAD);
  90. else
  91. layer_invert(_KEYPAD_BP);
  92. break;
  93. default:
  94. break;
  95. }
  96. reset_tap_dance(state);
  97. }
  98. void tap_dance_default_layer_switch (qk_tap_dance_state_t *state, void *user_data) {
  99. switch(state->count){
  100. case 1:
  101. switch_default_layer(_DVORAK);
  102. break;
  103. case 2:
  104. switch_default_layer(_DVORAK_BP);
  105. break;
  106. case 3:
  107. switch_default_layer(_BEPO);
  108. break;
  109. default:
  110. break;
  111. }
  112. reset_tap_dance(state);
  113. }
  114. // switch the default layer to another qwerty based layer.
  115. void switch_default_layer_on_qwerty(int count) {
  116. switch(count){
  117. case 1:
  118. switch_default_layer(_DVORAK);
  119. break;
  120. case 2:
  121. switch_default_layer(_QWERTY);
  122. break;
  123. case 3:
  124. switch_default_layer(_COLEMAK);
  125. break;
  126. /* case 4: */
  127. /* switch_default_layer(_WORKMAN); */
  128. /* break; */
  129. /* case 5: */
  130. /* switch_default_layer(_NORMAN); */
  131. /* break; */
  132. default:
  133. switch_default_layer(_DVORAK);
  134. break;
  135. }
  136. }
  137. // switch the default layer to another bepo based layer.
  138. void switch_default_layer_on_bepo(int count) {
  139. switch(count){
  140. case 1:
  141. switch_default_layer(_DVORAK_BP);
  142. break;
  143. case 2:
  144. switch_default_layer(_BEPO);
  145. break;
  146. default:
  147. switch_default_layer(_DVORAK_BP);
  148. break;
  149. }
  150. }
  151. // tap to change the default layer. Distinguishes between layers that are based on
  152. // a qwerty software keyboard and a bepo software keyboard.
  153. // if shifted, choose layers based on the other software keyboard, otherwise choose only
  154. // layers that work on the current software keyboard.
  155. void tap_dance_default_os_layer_switch (qk_tap_dance_state_t *state, void *user_data) {
  156. //uint8_t shifted = (get_mods() & MOD_BIT(KC_LSFT|KC_RSFT));
  157. bool shifted = ( keyboard_report->mods & (MOD_BIT(KC_LSFT)|MOD_BIT(KC_RSFT)) );
  158. int qwerty = on_qwerty();
  159. // shifted, choose between layers on the other software keyboard
  160. if(shifted){
  161. if (qwerty)
  162. switch_default_layer_on_bepo(state->count);
  163. else
  164. switch_default_layer_on_qwerty(state->count);
  165. // not shifted, choose between layers on the same software keyboard
  166. } else {
  167. if (qwerty)
  168. switch_default_layer_on_qwerty(state->count);
  169. else
  170. switch_default_layer_on_bepo(state->count);
  171. }
  172. reset_tap_dance(state);
  173. }
  174. /* Return an integer that corresponds to what kind of tap dance should be executed.
  175. *
  176. * How to figure out tap dance state: interrupted and pressed.
  177. *
  178. * Interrupted: If the state of a dance dance is "interrupted", that means that another key has been hit
  179. * under the tapping term. This is typically indicitive that you are trying to "tap" the key.
  180. *
  181. * Pressed: Whether or not the key is still being pressed. If this value is true, that means the tapping term
  182. * has ended, but the key is still being pressed down. This generally means the key is being "held".
  183. *
  184. * One thing that is currenlty not possible with qmk software in regards to tap dance is to mimic the "permissive hold"
  185. * feature. In general, advanced tap dances do not work well if they are used with commonly typed letters.
  186. * For example "A". Tap dances are best used on non-letter keys that are not hit while typing letters.
  187. *
  188. * Good places to put an advanced tap dance:
  189. * z,q,x,j,k,v,b, any function key, home/end, comma, semi-colon
  190. *
  191. * Criteria for "good placement" of a tap dance key:
  192. * Not a key that is hit frequently in a sentence
  193. * Not a key that is used frequently to double tap, for example 'tab' is often double tapped in a terminal, or
  194. * in a web form. So 'tab' would be a poor choice for a tap dance.
  195. * Letters used in common words as a double. For example 'p' in 'pepper'. If a tap dance function existed on the
  196. * letter 'p', the word 'pepper' would be quite frustating to type.
  197. *
  198. * For the third point, there does exist the 'DOUBLE_SINGLE_TAP', however this is not fully tested
  199. *
  200. */
  201. int cur_dance (qk_tap_dance_state_t *state) {
  202. if (state->count == 1) {
  203. if (state->interrupted || !state->pressed) return SINGLE_TAP;
  204. //key has not been interrupted, but they key is still held. Means you want to send a 'HOLD'.
  205. else return SINGLE_HOLD;
  206. }
  207. else if (state->count == 2) {
  208. /*
  209. * DOUBLE_SINGLE_TAP is to distinguish between typing "pepper", and actually wanting a double tap
  210. * action when hitting 'pp'. Suggested use case for this return value is when you want to send two
  211. * keystrokes of the key, and not the 'double tap' action/macro.
  212. */
  213. if (state->interrupted) return DOUBLE_SINGLE_TAP;
  214. else if (state->pressed) return DOUBLE_HOLD;
  215. else return DOUBLE_TAP;
  216. }
  217. //Assumes no one is trying to type the same letter three times (at least not quickly).
  218. //If your tap dance key is 'KC_W', and you want to type "www." quickly - then you will need to add
  219. //an exception here to return a 'TRIPLE_SINGLE_TAP', and define that enum just like 'DOUBLE_SINGLE_TAP'
  220. if (state->count == 3) {
  221. if (state->interrupted || !state->pressed) return TRIPLE_TAP;
  222. else return TRIPLE_HOLD;
  223. }
  224. else return 8; //magic number. At some point this method will expand to work for more presses
  225. }
  226. //Tap Dance Definitions
  227. qk_tap_dance_action_t tap_dance_actions[] = {
  228. //Tap once for Esc, twice for Caps Lock
  229. [TD_ESC_CAPS] = ACTION_TAP_DANCE_DOUBLE(KC_ESC, KC_CAPS),
  230. [TD_TAB_BKTAB] = ACTION_TAP_DANCE_DOUBLE(KC_TAB, LSFT(KC_TAB)),
  231. [TD_RIGHT_TAB] = ACTION_TAP_DANCE_DOUBLE(KC_RIGHT, KC_TAB),
  232. [TD_LEFT_BACKTAB] = ACTION_TAP_DANCE_DOUBLE(KC_LEFT, LSFT(KC_TAB)),
  233. [TD_UP_HOME] = ACTION_TAP_DANCE_DOUBLE(KC_UP, KC_HOME),
  234. [TD_DOWN_END] = ACTION_TAP_DANCE_DOUBLE(KC_DOWN, KC_END),
  235. [TD_MDIA_SYMB] = ACTION_TAP_DANCE_FN(tap_dance_layer_switch),
  236. [TD_DVORAK_BEPO] = ACTION_TAP_DANCE_FN(tap_dance_df_bepo_layers_switch),
  237. [TD_DEF_LAYER_SW] = ACTION_TAP_DANCE_FN(tap_dance_default_layer_switch),
  238. [TD_DEF_OS_LAYER_SW] = ACTION_TAP_DANCE_FN(tap_dance_default_os_layer_switch),
  239. [TD_HOME_END] = ACTION_TAP_DANCE_DOUBLE(KC_HOME, KC_END),
  240. [TD_MOUSE_BTNS] = ACTION_TAP_DANCE_FN(tap_dance_mouse_btns)
  241. };
  242. #endif