diff options
Diffstat (limited to 'keyboards/thevankeyboards/minivan/keymaps/josjoha/unicode_macros.c')
-rw-r--r-- | keyboards/thevankeyboards/minivan/keymaps/josjoha/unicode_macros.c | 2671 |
1 files changed, 2671 insertions, 0 deletions
diff --git a/keyboards/thevankeyboards/minivan/keymaps/josjoha/unicode_macros.c b/keyboards/thevankeyboards/minivan/keymaps/josjoha/unicode_macros.c new file mode 100644 index 0000000000..8372ae4cd1 --- /dev/null +++ b/keyboards/thevankeyboards/minivan/keymaps/josjoha/unicode_macros.c @@ -0,0 +1,2671 @@ +/* + * License (GPL): + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see <http://www.gnu.org/licenses/>. + + * Author: © 2019, 2020 by Jos Boersema + * + */ + +/* This file contains mostly the Unicode and special macros. + It contains the function: process_record_user(...) + */ + +#include "./unicode_macros.h" +#include "./unicode_weurope.h" +#include "./unicode_hebrew.h" + +// Definition of ƒ (Dutch currency symbol). +// Best changed in user_config.h, if you like a Euro symbol instead. +// +# ifndef UNICODE_CURRENCY // Prior optional definition in user_config.h +# define UNICODE_CURRENCY 0x0192 // Hex number. The unicode hex number for position ƒ in the default keymap. +# endif + +// +// 🛠 +#define CS_USER_DEFINED 0x1F6E0 // Hammer & wrench (place holder). + +#define DIV10POINT TRUE // suggest to function write_number, to divide by 10 and print as a fraction: N.N + +// Gives Unicode code points to the relevant QMK functions. +// Handles Dvorak 'descramble' Unicode mode, if compiled (only tested on Linux). +void unicode_hex2output (long unsigned int unshifted, long unsigned int shifted) { + + long unsigned int input; // which argument to work on + +# ifdef DVORAK_DESCRAMBLE // Do the letter descramble if needed. + + char output[10]; // will hold the ascii for output + int index; // count backwards 'to left' in the string + long unsigned int bitmove; // move computation to next digit. + long unsigned int work; // temporary value for computation + +# endif + + // What to work on + if(shift_ison) input = shifted; // Trying to get everything possible here in this function, to reduce firmware size. + else input = unshifted; + +# ifndef DVORAK_DESCRAMBLE // Only normal mode + + register_unicode ( (uint32_t) input ) ; + +# else + + if(_FULL_ != alternate){ + + register_unicode ( (uint32_t) input ) ; // normal Unicode mode + + }else{ // Special Dvorak-descramble mode: 0-9=0-9, a=a, b=n, c=i, d=h, e=d, f=y + + // Take the hex value 4 bits at a time, starting with the least significant, convert to ascii, store + index = 9; + output[index] = '\0'; // terminator + bitmove = 0x1; + while ((work = (input / bitmove)) && (index >= 0)) { + index --; + work &= 0xF; + if (work < 0xA){ // numbers + output[index] = work + 0x30; // pad to ASCII + }else{ // alphas + if (0xA == work) output[index] = 'a'; + if (0xB == work) output[index] = 'n'; + if (0xC == work) output[index] = 'i'; + if (0xD == work) output[index] = 'h'; + if (0xE == work) output[index] = 'd'; + if (0xF == work) output[index] = 'y'; + } + bitmove *= 0x10; // next digit + } + + SEND_STRING ( SS_DOWN(X_LCTL) SS_DOWN(X_LSFT) "f" SS_UP(X_LSFT) SS_UP(X_LCTL) ); // lead-in for Unicode on Linux, 'descramble' mode + send_string (output + index); // pointer to argument with formatted string + SEND_STRING ( " " ); // Ends the Unicode numerical input mode + } + +# endif // DVORAK_DESCRAMBLE mode for that Base layer & mode setting is compiled in + +} + + +// Wrapper for unicode keys that do have the same on shift. +void unicode_hex2output_single (long unsigned int either) { + unicode_hex2output (either, either); +} + + +// Required by QMK Unicode +const uint32_t PROGMEM unicode_map[] = { + +}; + +// Macro name definitions. The Unicode layers _ACC, _DRA and _BON are defined here, +// because the Unicode map system does not have enough space (at time of this programming, year 2020). +enum custom_keycodes { + + // Macro, allowing the upper left button to switch to either _DEF_BASE base layer, or the _ALT_BASE base layer. + // Alternate is set on/half/off in the _RAR layer. The word "base" is used to avoid "default," because the default + // layer system call DF() is not being used. + CTO_BASE = SAFE_RANGE, // 'C' for costum, "TO" for to, "BASE" for chosen base layer + + OTHER_BASE, // cycles modes: use _DEF_BASE, _ALT_BASE. For “dvorak²” layout (descramble) compile option, there is a third mode. + +# if defined(BASE_NUMPAD__ALT_BASE) + OTHER_BASE_GO, // Like OTHER_BASE, but also immediately switches to the other BASE layer. +# endif + + CTO_NUMS, // activates number-symbols layer, taking into account the dual layout mode + CTO_ACCE, // accented '' + CTO_DRAW, // drawings '' + +# ifndef CHOLTAP_ACCE_NOP + CHOLTAP_ACCE, // Go to accented layer, or others in combination with other keys. +# endif + +// Keys can be pressed together for a separate layer (like 'adjust layer' on the Planck). + DUO_HOLD, + + CHOLTAP_RSHFT, // Go to _FUN layer, or shift modifier. + CHOLTAP_LSHFT, // Go to <configurable> layer, or shift modifier. + CHOLTAP_LAYR, // Go to _RAR layer, or right arrow + +// Shifts which on tap produce a key + + RSFT_TILDE, + LSFT_DASH, + +// Special macro to make F-keys one-shot or not. + _FUN_STAY, + +// Layer toggle to be guaranteed on up-key, therefore macro definition here. + _MOV_UP, + +// These macros protect the critical keys like 'Power' from accidental press, by needing Shift to be pressed. + C_KC_PWR, // Powers computer off. + C_KC_WAKE, + C_KC_SLEP, // sleep computer + C_KC_PAUS, // pauze computer + +// Toggles side leds on/off. + LEDS_ON, + RGBTOG_, + +// Typing speed measuring + SPEED_TOG, + SPEED_REPORT, + +// Word/character counting + COUNT_TOG, // starts word counting + COUNT_REPORT, // writes to the computer as if typing, gives count report + COUNT_WORDMIN, // reduces the word count + COUNT_NULL, // resets count to zero + LT__MOV__KC_ENT, // move to layer _MOV, or <enter> + +// The _ACC layer, additional Unicode. +# ifndef REMOVE_ACC // This cuts out the whole _ACC layer. + XP_ACC_AA, + XP_ACC_AB, + XP_ACC_AC, + XP_ACC_AD, + XP_ACC_AE, + XP_ACC_AF, + XP_ACC_AG, + XP_ACC_AH, + XP_ACC_AI, + XP_ACC_AJ, + XP_ACC_BA, + XP_ACC_BB, + XP_ACC_BC, + XP_ACC_BD, + XP_ACC_BE, + XP_ACC_BF, + XP_ACC_BG, + XP_ACC_BH, + XP_ACC_BI, + XP_ACC_BJ, + XP_ACC_BK, + XP_ACC_CA, + XP_ACC_CB, + XP_ACC_CC, + XP_ACC_CD, + XP_ACC_CE, + XP_ACC_CF, + XP_ACC_CG, + XP_ACC_CH, + XP_ACC_CI, + XP_ACC_CJ, +# endif // REMOVE_ACC + +# ifndef REMOVE_DRA // This cuts out the whole _DRA layer +// The _DRA layer, additional Unicode. + XP_DRA_AA, + XP_DRA_AB, + XP_DRA_AC, + XP_DRA_AD, + XP_DRA_AE, + XP_DRA_AF, + XP_DRA_AG, + XP_DRA_AH, + XP_DRA_AI, + XP_DRA_AJ, + XP_DRA_BA, + XP_DRA_BB, + XP_DRA_BC, + XP_DRA_BD, + XP_DRA_BE, + XP_DRA_BF, + XP_DRA_BG, + XP_DRA_BH, + XP_DRA_BI, + XP_DRA_BJ,// XP_DRA_BK , // no 'BK' key definition on this layer + XP_DRA_CA, + XP_DRA_CB, + XP_DRA_CC, + XP_DRA_CD, + XP_DRA_CE, + XP_DRA_CF, +# endif // REMOVE_DRA + XP_DRA_CG, // Needed for ☑ on Unicode tester key in _RAR +# ifndef REMOVE_DRA // This cuts out the whole _DRA layer + XP_DRA_CH, + XP_DRA_CI, + XP_DRA_CJ, +# endif // REMOVE_DRA + +// The _BON layer, additional Unicode. +# ifndef REMOVE_BON // Removes this layer entirely, if set. + XP_BON_AA, + XP_BON_AB, + XP_BON_AC, + XP_BON_AD, + XP_BON_AE, + XP_BON_AF, + XP_BON_AG, + XP_BON_AH, + XP_BON_AI, + XP_BON_AJ, + XP_BON_BA, + XP_BON_BB, + XP_BON_BC, + XP_BON_BD, + XP_BON_BE, + XP_BON_BF, + XP_BON_BG, + XP_BON_BH, + XP_BON_BI, + XP_BON_BJ, + XP_BON_BK, + XP_BON_CA, + XP_BON_CB, + XP_BON_CC, + XP_BON_CD, + XP_BON_CE, + XP_BON_CF, + XP_BON_CG, + XP_BON_CH, + XP_BON_CI, + XP_BON_CJ, +# endif // REMOVE_BON + +// Hebrew +# if defined(BASE_HEBREW__DEF_BASE) || defined(BASE_HEBREW__ALT_BASE) + XP_HEB_AA, + XP_HEB_AB, + XP_HEB_AC, + XP_HEB_AD, + XP_HEB_AE, + XP_HEB_AF, + XP_HEB_AG, + XP_HEB_AH, + XP_HEB_AI, + XP_HEB_AJ, + XP_HEB_BA, + XP_HEB_BB, + XP_HEB_BC, + XP_HEB_BD, + XP_HEB_BE, + XP_HEB_BF, + XP_HEB_BG, + XP_HEB_BH, + XP_HEB_BI, + XP_HEB_BJ, +# if defined(HEBREW_ISRAEL) + XP_HEB_BK, // +# endif + XP_HEB_CA, + XP_HEB_CB, + XP_HEB_CC, + XP_HEB_CD, + XP_HEB_CE, + XP_HEB_CF, + XP_HEB_CG, +# if defined(HEBREW_ISRAEL) || defined(HEBREW_DVORAK) + XP_HEB_CH, + XP_HEB_CI, + XP_HEB_CJ, +# endif + XP_HEB_MQF, // ־ +# endif //BASE_HEBREW__* + +}; + +// Pre-existing function, called for every key up and down. +// This function is sortof the hub of the whole thing. +bool process_record_user(uint16_t keycode, keyrecord_t *record) { + + // User input for the word count menu + if (sizecount_menu) { + if (record->event.pressed) { // key down + + switch (keycode) { + case KC_0: // read in how many is maximum + sizecount_max = (sizecount_max * 10); + break; + + case KC_1: + sizecount_max = (sizecount_max * 10) + 1; + break; + + case KC_2: + sizecount_max = (sizecount_max * 10) + 2; + break; + + case KC_3: + sizecount_max = (sizecount_max * 10) + 3; + break; + + case KC_4: + sizecount_max = (sizecount_max * 10) + 4; + break; + + case KC_5: + sizecount_max = (sizecount_max * 10) + 5; + break; + + case KC_6: + sizecount_max = (sizecount_max * 10) + 6; + break; + + case KC_7: + sizecount_max = (sizecount_max * 10) + 7; + break; + + case KC_8: + sizecount_max = (sizecount_max * 10) + 8; + break; + + case KC_9: + sizecount_max = (sizecount_max * 10) + 9; + break; + + case KC_C: // count characters + sizecount_max_type = SIZECOUNT_CHAR; + sizecount_menu = FALSE; + break; + + case KC_W: // count words + sizecount_max_type = SIZECOUNT_WORD; + sizecount_menu = FALSE; + break; + + // Anything else ends menu input. + case KC_DOT: + case KC_ESC: + sizecount_menu = FALSE; // break out + break; + + } + if (!sizecount_menu) { // end + send_string ("->"); + write_number (sizecount_max, FALSE); // just indicate something + } + } + } + + // Go back to base-layer after pressing an F-key, on key-up to avoid BASE key activation + if ((_fun_stay == FALSE) && // + (((keycode >= KC_F1) && (keycode <= KC_F12)) + || + ((keycode >= KC_F13) && (keycode <= KC_F24)))) { // assumes keycodes 1-12 and 13-24 are consequtive, which seems likely, although using 1-24 failed (probably not consequtive) + // Go back to base layer + if (!(record->event.pressed)) { // key up + if (alternate) { // + layer_move (_ALT_BASE); + }else{ + layer_move (_DEF_BASE); + } + } + } + + // Detect if Shift was pressed in isolation, by seeing if another key was pressed during the time + // the right shift key was held down. + // This system is also used by CHOLTAP_ACCE + // This helps make sure a tapped use of these keys is correctly differentiated from their use as a + // modifier/layer-hold key. The Shift and CHOLTAP_ACCE should not normally interfere with each other. + if (isolate_trigger) { // speed: hoping this statement to execute a little quicker overall, than the next + if ((keycode != CHOLTAP_RSHFT) // not right shift up + && + (keycode != CHOLTAP_LSHFT) // not left shift up + && + (keycode != CHOLTAP_ACCE) // _ACC layer (and others) + && + (keycode != RSFT_TILDE) // Shift on _NSY + && + (keycode != LSFT_DASH) // Shift on _NSY + && + (keycode != CHOLTAP_LAYR)) + { // _RAR layer, or RAlt/Alt-Gr + isolate_trigger = FALSE; // another key was pressed + } + } + + // This block contains the complex macros, which should not count in speed counting or word/character counting, + // because they aren't typed characters. + switch (keycode) { + + // Typing speed measuring + case SPEED_TOG: // Toggle speed measuring on/off + if (record->event.pressed) { // key down + if (speed_measure) { + speed_measure = FALSE; + +# ifdef RGBLIGHT_ENABLE + rgblight_sethsv_noeeprom (HSV_PURPLE); // indicates stop (_RAR color) +# endif + + }else{ + // initialization of measurements + speed_measure = TRUE; // activates + speed = 0; // start at 0 k/s + speed_countdown = SPEED_COUNTDOWN; // reset, speed is measured in batches of keypresses + speed_counttime = timer_read32 ();// get current time + speed_add = 0;// speed average accumulator, it keeps adding the *speed* of each batch to this total + speed_batches = 0; // divider for speed_add to get the average + +# ifdef RGBLIGHT_ENABLE + // set middle led + rgblight_sethsv_noeeprom (HSV_WHITE); // indicates start +# endif + + } + +# ifdef RGBLIGHT_ENABLE + isolate_rgblight_set (); +# endif + + } + break; + + case SPEED_REPORT: // Report the current typing speed by writing it, as if typing + if (record->event.pressed) { // down + short added = 5; // This counts how many characters the report itself is adding into the current text, + // to later delete it from the character count for text-size counting. + + if (speed_measure) { + +# ifdef WORDS_PER_MINUTE + + // The speed is recorded as an accumulation of keystrokes-per-second, times 10 for added precision. + // This will be converted into words-per-minute by dividing by 5 characters for a word including + // blank space and punctuation, and multiplied by 60 for seconds per minute. ⁶⁰/₅ = 12. Multiplied + // by 12 is the simple conversion. + send_string ("<"); // +1 character written // analogue to '<POWER>' + added += write_number ((long int)((speed*12)/10), FALSE); // writes the speed + send_string ("wpm"); // +3 character written + if (0 != speed_batches) { + long int average_times_ten; + average_times_ten =(long int) ((speed_add * 12) / speed_batches); // *12 converts k/s to wpm + + send_string (";"); // +① '' + added += write_number (average_times_ten / 10, FALSE); // writes the average speed, cannot use decimal because precision is not there + send_string ("wpm"); // +③ + added += write_number ((long int) speed_batches, FALSE); // amount of batches + send_string ("x"); // +① + added += 9 + write_number ((long int) SPEED_COUNTDOWN, FALSE); // amount of batches + send_string ("keys"); // +④ = ⑨ + + speed_led ( (int) (average_times_ten / 12));// on report, show the average + // we need to convert back to k/s now + } + +# else // keystrokes per second, k/s + + send_string ("<"); // +1 character written // analogue to '<POWER>' + added += write_number ((long int)(speed/10), FALSE); // writes the speed + send_string ("k/s"); // +3 character written + if (0 != speed_batches) { + long int average_times_ten; + average_times_ten =(long int) (speed_add / speed_batches); + + send_string (";"); // +① '' + added += write_number (average_times_ten, DIV10POINT); // writes the average speed + send_string ("k/s"); // +③ + added += write_number ((long int) speed_batches, FALSE); // amount of batches + send_string ("x"); // +① + added += 9 + write_number ((long int) SPEED_COUNTDOWN, FALSE); // amount of batches + send_string ("keys"); // +④ = ⑨ + + speed_led ( (int) average_times_ten );// on report, show the average. speed_led divides by 10 + } + +# endif + + send_string (">"); // +1 = 5 + if (sizecount_measure) sizecount_chars += added; // the user is expected to hit <backspace> + }else{ + send_string ("<Soff>"); // indicates off + if (sizecount_measure) sizecount_chars += 5; // user: <backspace>, to take it down again + } + + key_timer = timer_read (); + + }else{ // key up + // This use of the key is for callibrating your colors; it is difficult otherwise to see. + // This is not part of normal usage, therefore it is kept bare bones to reduce firmware size + if (timer_elapsed (key_timer) > 999) { // held for one second + speed += 10; + write_number ((long int)(speed/10), FALSE); // writes the speed + speed_led (speed); // update led + } + } + break; + + case COUNT_TOG: // Toggle start/stop text size measuring + if (record->event.pressed) { // key down + + key_timer = timer_read (); + + }else{ // up + if (timer_elapsed (key_timer) < 500) { // held for less than half a second (tapped) + if (sizecount_measure) { + + sizecount_measure = FALSE; + +# ifdef RGBLIGHT_ENABLE + rgblight_sethsv_noeeprom (HSV_PURPLE); // indicates stop (color of _RAR) + isolate_rgblight_set (); +# endif + + }else{ + + sizecount_measure = TRUE; // start counting + sizecount_word = FALSE; // detect double blanks. leading blanks are not a word + +# ifdef RGBLIGHT_ENABLE + if (0 == sizecount_max) { + rgblight_sethsv_noeeprom (HSV_BLUE); // indicates start/activated, but only without maximum set + isolate_rgblight_set (); // .. if maximum set, led goes green to red. + }else{ + rgblight_sethsv_noeeprom (HSV_GREEN); // indicates start/activated, but only without maximum set + isolate_rgblight_set (); // .. if maximum set, led goes green to red. + } +# endif + + } + }else{ // held longer + sizecount_menu = TRUE; + send_string ("<Nc|w>"); // Menu: N amount, c|w character|word counting. Input is a number then ‛c’ or ‛w’ + sizecount_max = 0; + } + } + break; + + case COUNT_NULL: // Sets the count to zero, which allows on/off to have a suspend/resume + if (record->event.pressed) { // key up + sizecount_blanks = 0; // + sizecount_chars = 0; + +# ifdef RGBLIGHT_ENABLE + rgblight_sethsv_noeeprom (HSV_CYAN); // indicates reset + isolate_rgblight_set (); +# endif + + } + break; + + case COUNT_REPORT: // Report the current typing speed + if (record->event.pressed) { + // We assume the user is writing a report in its active document, and then likely deleting it. + short added = 0; // This counts how much characters the report adds into the user document. + + if (sizecount_measure) { + send_string ("<"); // + 1 and ① characters (1 is one logical stream, ① another) + if (0 == sizecount_max) { // no size counting maximum, print both characters and words + + added += write_number (sizecount_chars, FALSE); // returns how many characters where printed + send_string ("c;"); // + 2 + added += write_number (sizecount_blanks, FALSE) + 5; // adds here + send_string ("w>"); // + 2 = 5 + + }else{ // Only show the one for which the maximum is set, don't throw off that mental focus + if (SIZECOUNT_WORD == sizecount_max_type ) { + + added += write_number (sizecount_blanks, FALSE) + 3; + send_string ("w>"); // + ② = ③ + + }else{ // characters + + added += write_number (sizecount_chars, FALSE) + 3; // returns how many characters where printed + send_string ("c>"); // + ② = ③ + + } + // add current maximum setting + send_string ("["); // + 1 + added += write_number (sizecount_max, FALSE) + 3; + if (SIZECOUNT_WORD == sizecount_max_type) send_string ("w]"); // + 2 + else send_string ("c]"); // + 2 + } + sizecount_chars += added; // Account for the written characters in the report itself. + + }else{ // no size counting, also here: keep the report terse + send_string ("<Coff>"); // indicates off (no need to add to count, since counting is off) + } + } + break; + + // This allows the user to manually remove word counts, when he has deleted a word. + // This is not needed for character count, because <backspace> counts as minus. + case COUNT_WORDMIN: // Take down one word in the word-count. + if (record->event.pressed) { // down + key_timer = timer_read (); + }else{ // up + if (timer_elapsed (key_timer) < 500) { // held for less than half a second (tapped) + sizecount_blanks--; + }else{ + sizecount_blanks -= 10; + } + } + break; + + // Shift detection system. + // Disused because it turned out 'one shot' like Unicode input. Shift detection copied from. + // https://github.com/kyleterry/qmk_firmware/blob/master/quantum/quantum.c + //uint8_t shifted = get_mods() & (MOD_BIT(KC_LSFT)|MOD_BIT(KC_RSFT)); + + // Crude but self contained in this source file shift detection. + // ... right shift + case KC_RSFT: + // + ... left shift + case KC_LSFT: + if (record->event.pressed) { // key down + shift_ison = 1; // shift depressed + }else{ // key up + shift_ison = 0; // shift released + } + // There are macros on Shift who also alter this variable. + break; + + case OTHER_BASE: // Switching through the default/alternate BASE modes, and Descramble for that Dvorak compile + if (record->event.pressed) { + ; + }else{ // key up + + // Cycles through the modes +# ifdef DVORAK_DESCRAMBLE // version Dvorak+Dvorak-descramble has 3 modes + if (_NORMAL_ == alternate) { + alternate = _FULL_;// alternate layers + default_layer_set (_ALT_BASE_MASK); // This is needed only for a rare case, + // where _DEF_BASE and _ALT_BASE their layer switching keys don't line up, + // such as with Qwerty Base Arrow + } else if (_HALF_ == alternate) { + alternate = _NORMAL_;// normal layers + default_layer_set (_DEF_BASE_MASK); + }else{ // _FULL_ == alternate + alternate = _HALF_;// alternate layers, without 'descramble' recomputing Unicode + //default_layer_set (_ALT_BASE_MASK); + // it cycles, and this comes always after it was set _FULL_ + } +# else // Only switching the BASE layers between alternate and default + + if (_NORMAL_ == alternate) { + alternate = _FULL_;// alternate base layers + default_layer_set (_ALT_BASE_MASK); + }else{ + alternate = _NORMAL_;// default base layers + default_layer_set (_DEF_BASE_MASK); + } +# endif + + indicate_base (); // activate led change + } + break; + +# if defined(BASE_NUMPAD__ALT_BASE) + + case OTHER_BASE_GO: // Switching through the default/alternate BASE modes, and Descramble for that Dvorak compile + if (record->event.pressed) { + ; + }else{ // key up + + // Cycles through the modes +# ifdef DVORAK_DESCRAMBLE // version Dvorak+Dvorak-descramble has 3 modes + if (_NORMAL_ == alternate) { + alternate = _FULL_;// alternate layers + default_layer_set (_ALT_BASE_MASK); + } else if (_HALF_ == alternate) { + alternate = _NORMAL_;// normal layers + default_layer_set (_DEF_BASE_MASK); + }else{ // _FULL_ == alternate + alternate = _HALF_;// alternate layers, without 'descramble' recomputing Unicode + //default_layer_set (_ALT_BASE_MASK); + // it cycles, and this comes always after it was set _FULL_ + } +# else // Only switching the BASE layers between alternate and default + + if (_NORMAL_ == alternate) { + alternate = _FULL_;// alternate base layers + default_layer_set (_ALT_BASE_MASK); + }else{ + alternate = _NORMAL_;// default base layers + default_layer_set (_DEF_BASE_MASK); + } +# endif + // make the switch to the other Base layer + if (alternate) { // + layer_move (_ALT_BASE); + }else{ + layer_move (_DEF_BASE); + } + } + break; +# endif + + // Switching to layers: + + case CTO_BASE: + // User pressed upper/left button, while not on BASE layer: ‛escape’ from a layer to BASE layer. + // On BASE itself, that key is <Escape>. + if (record->event.pressed) { // key down + ; + }else{ // key up + if (alternate) { // go to the alternate version (bit of a hack maybe, but all alternate + // ... modes are non-zero) + layer_move (_ALT_BASE); + }else{ + layer_move (_DEF_BASE); + } + } + break; + + case CTO_NUMS: // activates number-symbols layer + if (record->event.pressed) { // key down + ; + }else{ // key up, so that upon key down the target layer isn't already activated, triggering that key on up + if (alternate) { // go to the alternate version + layer_move (_ALT_NSY); + }else{ + layer_move (_DEF_NSY); + } + } + break; + + case CTO_ACCE: // Unicode layer + if (record->event.pressed) { // key down + ; + }else{ // key up + +# ifndef REMOVE_ACC // This cuts out the whole _ACC layer. + layer_move (_ACC); // activates normal accented layer +# else +# ifdef _ACC_KEY_ALT_LAYER + layer_move (_ACC_KEY_ALT_LAYER); // Alternative layer user configuration +# endif +# endif + + } + break; + + case CTO_DRAW: // Unicode layer + if (record->event.pressed) { // key down + ; + }else{ // key up + +# ifndef REMOVE_DRA // This cuts out the whole _DRA layer. + layer_move (_DRA); // activates normal accented layer +# else +# ifdef _DRA_KEY_ALT_LAYER + layer_move (_DRA_KEY_ALT_LAYER); // Alternative layer user configuration +# endif +# endif + } + break; + + // The below are a simulated LT(layer,kc), layer-tap. + // Double-tap-hold repeater functionality: not done. + // They switch what layer to use depending on 'alternate' variable + // Basically it starts the right layer on key down, goes back to base layer on key up, + // and throws in a keypress as well if tapped. + // It also integrates with DUO_HOLD, to reach the _BON layer. + +# ifndef CHOLTAP_ACCE_NOP // When this key has been eviscerated, this macro becomes useless + case CHOLTAP_ACCE: // Works with DUO_HOLD macro to activate one of several layers. + if (record->event.pressed) { // key down + key_timer = timer_read (); + isolate_trigger = TRUE; // keep track of whether another key gets pressed. + + duo_press_acc_bon ++; // This signals to the two DUO_HOLD keys, whether a move to _BON is desired. + + if (duo_press_nsy_dra) { // One or more of the DUO_HOLD layer keys was already pressed; move to _BON + +# ifndef REMOVE_BON // Removes this layer entirely, if set. + layer_move (_BON); // Bonus Unicode layer +# else +# ifdef _BON_KEY_ALT_LAYER + layer_move (_BON_KEY_ALT_LAYER); // Alternative layer user configuration +# endif +# endif + + }else{ // pressed in isolation + +# ifndef REMOVE_ACC // This cuts out the whole _ACC layer. + layer_move (_ACC); // Accented layer +# else +# ifdef _ACC_KEY_ALT_LAYER + layer_move (_ACC_KEY_ALT_LAYER); // Alternative layer user configuration +# endif +# endif + + } + }else{ // key up + + duo_press_acc_bon --; + + if (1 == duo_press_nsy_dra) { // One DUO_HOLD layer keys is still pressed; move to numbers/symbols + + if (_FULL_ == alternate) { + layer_move (_ALT_NSY); + }else{ + layer_move (_DEF_NSY); + } + }else if (2 == duo_press_nsy_dra) { // Two of the DUO_HOLD layer keys are still pressed: move to _DRA + +# ifndef REMOVE_DRA // This cuts out the whole _DRA layer. + layer_move (_DRA); // activates normal accented layer +# else +# ifdef _DRA_KEY_ALT_LAYER + layer_move (_DRA_KEY_ALT_LAYER); // Alternative layer user configuration +# endif +# endif + + }else{ + if (alternate) { // No _DEF_NSY layer keys remain pressed; Go back to base layer + layer_move (_ALT_BASE); + }else{ + layer_move (_DEF_BASE); + } + } + + // Pressed in isolation + if (isolate_trigger) + { + if (timer_elapsed (key_timer) <= TAPPING_TERM_HOLTAP) { // tapped + SEND_STRING (SS_TAP (X_DEL)); + } + } + } + break; +# endif // CHOLTAP_ACCE_NOP + + case CHOLTAP_LAYR: //to _RAR on hold, otherwise a keycode + if (record->event.pressed) { // key down + key_timer = timer_read (); + isolate_trigger = TRUE; // keep track of whether another key gets pressed. + +# ifdef BASE_RIGHT_ALT + SEND_STRING (SS_DOWN (X_RALT)); +# else + layer_move (_RAR); // activates descrambled drawings layer +# endif + + }else{ // key up + // Go back to base layer + if (speed_measure) speed_led (speed); // The _RAR layer overwrites the middle led, + //.. for use with alternate _HALF_ led colors (middle); thus needs to be set back to speed + // led color upon leaving. + +# ifdef BASE_RIGHT_ALT + SEND_STRING (SS_UP (X_RALT)); +# else + if (alternate) { + layer_move (_ALT_BASE); + }else{ + layer_move (_DEF_BASE); + } +# endif + + // Pressed in isolation + if (isolate_trigger) + { + if (timer_elapsed (key_timer) <= TAPPING_TERM_HOLTAP) { // tapped + SEND_STRING (SS_TAP (X_RIGHT)); + } + } + } + break; + +# ifndef DUO_HOLD_BASIC + // This is the normal 'big' version, dealing with switching between _DEF_NSY/_ALT_NSY, _ACC, _DRA and _BON, in + // .. conjunction with the CHOLTAP_ACCE macro. + case DUO_HOLD: // The macro around the split space-bar. Both keys come to this macro. + if (record->event.pressed) { // key down + + duo_press_nsy_dra ++; // simple way to keep track of how many are pressed + + if (duo_press_acc_bon){ // Preceded by holding the _ACC/_BON layer switch key: move to _BON + +# ifndef REMOVE_BON // Removes this layer entirely, if set. + layer_move (_BON); // Bonus Unicode layer +# else +# ifdef _BON_KEY_ALT_LAYER + layer_move (_BON_KEY_ALT_LAYER); // Alternative layer user configuration +# endif +# endif + + }else if (1 == duo_press_nsy_dra) { // This is the first press of either of the DUO_HOLD keys on BASE + + if (_NORMAL_ == alternate) { + layer_move (_DEF_NSY); + }else{ + layer_move (_ALT_NSY); + } + } + else if (2 == duo_press_nsy_dra) { // both are pressed + +# ifndef REMOVE_DRA // This cuts out the whole _DRA layer. + layer_move (_DRA); // activates normal accented layer +# else +# ifdef _DRA_KEY_ALT_LAYER + layer_move (_DRA_KEY_ALT_LAYER); // Alternative layer user configuration +# endif +# endif + } + + }else{ // key up + + duo_press_nsy_dra --; + + if (1 == duo_press_nsy_dra) { + if (duo_press_acc_bon){ // Still holding the _ACC/_BON layer switch key, and one DUO_HOLD keys + +# ifndef REMOVE_BON // Removes this layer entirely, if set. + layer_move (_BON); // Bonus Unicode layer +# else +# ifdef _BON_KEY_ALT_LAYER + layer_move (_BON_KEY_ALT_LAYER); // Alternative layer user configuration +# endif +# endif |