create users/datagrok (#7653)
* users/datagrok: add shared functions * users/datagrok: improve base-layer selection feature * users/datagrok: add README.mdrefactor_process_record_kb_user
parent
05d6e6ca78
commit
5fb95c5f94
@ -0,0 +1,63 @@ |
||||
# datagrok's QMK user-space code |
||||
|
||||
## cdeq "comma dot exclamation question" |
||||
|
||||
This is a hack to place `question mark` on `shift-comma` and `exclamation mark` on `shift-period`. |
||||
|
||||
When using an operating system configured for a US/qwerty layout this replaces the angle brackets `<` `>` with `?` `!`. This helps on small keyboards to keep symbols for prose co-located in one layer, and symbols for programming in another. |
||||
|
||||
It's a "hack" because the "proper" way to accomplish this would be to edit the operating system's keymap. |
||||
|
||||
### setup |
||||
|
||||
in your `keymap.c`: |
||||
|
||||
#include "feature_cdeq.h" |
||||
|
||||
bool process_record_user(uint16_t keycode, keyrecord_t *record) { |
||||
return process_record_cdeq(keycode, record); |
||||
} |
||||
|
||||
in your `rules.mk`, |
||||
|
||||
SRC += feature_cdeq.c |
||||
|
||||
### examples |
||||
|
||||
- atreus:datagrok |
||||
- bm43a:datagrok |
||||
- mitosis:datagrok |
||||
|
||||
## base layer selector |
||||
|
||||
Defines a keycode `KF_LAYO` to rotate between available default layers. |
||||
|
||||
`Shift`+`KF_LAYO` makes the currently selected one persistent across reboots. |
||||
|
||||
This is useful if you'd like your keyboard to support and toggle between QWERTY, Dvorak, Colemak, Workman, and other layouts while keeping a common arrangement of modifier and function keys. |
||||
|
||||
Since toggling layouts seems like something one does infrequently, I wanted to be able to operate this feature with a single key, instead of one for each layer like planck:default or bootmagic. |
||||
|
||||
### setup |
||||
|
||||
in your `keymap.c`: |
||||
|
||||
#define KF_LAYO SAFE_RANGE |
||||
#include "feature_default_layers_selector.h" |
||||
const uint8_t highest_base_layer = 4; |
||||
|
||||
bool process_record_user(uint16_t keycode, keyrecord_t *record) { |
||||
return \ |
||||
process_record_save_default_layer(keycode, record) && \ |
||||
process_record_select_default_layer(keycode, record); |
||||
} |
||||
|
||||
in your `rules.mk`, |
||||
|
||||
SRC += feature_default_layers_selector.c |
||||
|
||||
### examples |
||||
|
||||
- atreus:datagrok |
||||
- bm43a:datagrok |
||||
- mitosis:datagrok |
@ -0,0 +1,47 @@ |
||||
// This is a hack to place <question mark> on <shift-comma> and <exclamation
|
||||
// mark> on <shift-period>, when using an operating system configured for a
|
||||
// US/qwerty layout.
|
||||
//
|
||||
// cdeq = "comma dot exclamation question"
|
||||
|
||||
#include QMK_KEYBOARD_H |
||||
|
||||
bool comm_shifted = false; |
||||
bool ques_shifted = false; |
||||
|
||||
bool process_record_cdeq(uint16_t keycode, keyrecord_t *record) { |
||||
uint8_t shifted; |
||||
uint16_t s_keycode; |
||||
bool *k_shifted; |
||||
|
||||
switch (keycode) { |
||||
case KC_COMM: |
||||
s_keycode = KC_SLSH; |
||||
k_shifted = &comm_shifted; |
||||
break; |
||||
case KC_DOT: |
||||
s_keycode = KC_1; |
||||
k_shifted = &ques_shifted; |
||||
break; |
||||
default: |
||||
return true; |
||||
} |
||||
|
||||
shifted = get_mods() & (MOD_BIT(KC_LSHIFT)|MOD_BIT(KC_RSHIFT)); |
||||
|
||||
// Keydown. If shift is currently pressed, register its alternate keycode.
|
||||
if (record->event.pressed && shifted) { |
||||
*k_shifted = true; |
||||
register_code(s_keycode); |
||||
return false; |
||||
// Keyup. If shift was pressed back when the key was pressed, unregister
|
||||
// its alternate keycode.
|
||||
} else if (!(record->event.pressed) && *k_shifted) { |
||||
*k_shifted = false; |
||||
unregister_code(s_keycode); |
||||
return false; |
||||
// Otherwise, behave as normal.
|
||||
} else { |
||||
return true; |
||||
} |
||||
} |
@ -0,0 +1,2 @@ |
||||
#include QMK_KEYBOARD_H |
||||
bool process_record_cdeq(uint16_t keycode, keyrecord_t *record); |
@ -0,0 +1,46 @@ |
||||
#include "feature_default_layers_selector.h" |
||||
|
||||
#ifdef AUDIO_ENABLE |
||||
#include "audio.h" |
||||
#ifdef DEFAULT_LAYER_SONGS |
||||
extern float default_layer_songs[][16][2]; |
||||
#endif |
||||
#endif |
||||
|
||||
bool process_record_save_default_layer(uint16_t keycode, keyrecord_t *record) { |
||||
|
||||
#if defined(AUDIO_ENABLE) |
||||
float saved_song[][2] = SONG(COIN_SOUND); |
||||
#endif |
||||
|
||||
if (!(keycode == KF_LAYO |
||||
&& record->event.pressed |
||||
&& get_mods() & (MOD_BIT(KC_LSHIFT)|MOD_BIT(KC_RSHIFT)))) { |
||||
return true; |
||||
} |
||||
|
||||
eeconfig_update_default_layer(default_layer_state); |
||||
#if defined(AUDIO_ENABLE) |
||||
PLAY_SONG(saved_song); |
||||
#endif |
||||
return false; |
||||
} |
||||
|
||||
bool process_record_select_default_layer(uint16_t keycode, keyrecord_t *record) { |
||||
if (!(keycode == KF_LAYO |
||||
&& record->event.pressed)) { |
||||
return true; |
||||
} |
||||
if (!default_layer_state) { |
||||
default_layer_set(2); |
||||
} else { |
||||
default_layer_set( |
||||
(((1U<<(highest_base_layer+1))-1) & (default_layer_state<<1)) |
||||
| (default_layer_state>>highest_base_layer)); |
||||
} |
||||
led_set(host_keyboard_leds()); |
||||
#if defined(AUDIO_ENABLE) && defined(DEFAULT_LAYER_SONGS) |
||||
PLAY_SONG(default_layer_songs[get_highest_layer(default_layer_state)]); |
||||
#endif |
||||
return false; |
||||
} |
@ -0,0 +1,69 @@ |
||||
#include QMK_KEYBOARD_H |
||||
|
||||
/*
|
||||
Define a keycode KF_LAYO to rotate between available default layers. |
||||
Shift+KF_LAYO makes the current one persistent. |
||||
|
||||
To use: |
||||
|
||||
in your keymap.c, define KF_LAYO so it does not conflict with anything else. |
||||
then include this header and set highest_base_layer. |
||||
|
||||
#define KF_LAYO SAFE_RANGE |
||||
#include "feature_default_layers_selector.h" |
||||
|
||||
const uint8_t highest_base_layer = 4; // the index
|
||||
|
||||
and in your rules.mk, |
||||
|
||||
SRC += feature_default_layers_selector.c |
||||
*/ |
||||
|
||||
/*
|
||||
See https://docs.qmk.fm/#/keymap for docs about layers including the concept
|
||||
of "base" or "default" layers. |
||||
|
||||
This is broken into two functions so that: |
||||
|
||||
- If you don't want to store the default layer state in eeprom, don't call |
||||
process_record_save_default_layer. |
||||
|
||||
- If you have your own mechanism for setting the default layer state (to one |
||||
or multiple layers), do that instead of process_record_select_default_layer. |
||||
|
||||
If you call both functions, call process_record_save_default_layer first. |
||||
|
||||
The QMK docs seem to assume that you will have only one layer as your |
||||
default layer at any time, but the source code actually supports an arbitrary |
||||
default_layer_state (composition of layers) |
||||
|
||||
quantum has "set_single_persistent_default_layer" but that writes to eeprom |
||||
every time you change your default layer preference. i wanted a behavior |
||||
instead which lets you switch default layers all you want, then store the |
||||
current configuration once you're happy with it. that way if you get into an |
||||
unusable state you can just unplug and replug your keyboard to escape from it. |
||||
|
||||
this code assumes: |
||||
|
||||
1. each default layer state that you would select among consists of a single |
||||
layer, which we will call a "base" layer. |
||||
|
||||
2. all your "base" layers are stored contiguously at the bottom of your |
||||
keymaps[] stack, and there are no non-"base" layers mixed in. |
||||
|
||||
3. you have a maximum of 8 "base" layers. that is, the highest base layer is |
||||
index 7. |
||||
|
||||
while 16 and 32 bit platforms might allow default_layer_state to include more |
||||
and higher-numbered layers, eeconfig_update_default_layer saves only the first |
||||
8 bits of default_layer_state to eeprom. |
||||
|
||||
*/ |
||||
|
||||
#ifndef KF_LAYO |
||||
#define KF_LAYO SAFE_RANGE |
||||
#endif |
||||
|
||||
const uint8_t highest_base_layer; |
||||
bool process_record_save_default_layer(uint16_t keycode, keyrecord_t *record); |
||||
bool process_record_select_default_layer(uint16_t keycode, keyrecord_t *record); |
Loading…
Reference in new issue