create users/datagrok (#7653)
* users/datagrok: add shared functions * users/datagrok: improve base-layer selection feature * users/datagrok: add README.md
This commit is contained in:
		
							parent
							
								
									05d6e6ca78
								
							
						
					
					
						commit
						5fb95c5f94
					
				
					 5 changed files with 227 additions and 0 deletions
				
			
		
							
								
								
									
										63
									
								
								users/datagrok/README.md
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										63
									
								
								users/datagrok/README.md
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -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
 | 
			
		||||
							
								
								
									
										47
									
								
								users/datagrok/feature_cdeq.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								users/datagrok/feature_cdeq.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -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;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										2
									
								
								users/datagrok/feature_cdeq.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								users/datagrok/feature_cdeq.h
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,2 @@
 | 
			
		|||
#include QMK_KEYBOARD_H
 | 
			
		||||
bool process_record_cdeq(uint16_t keycode, keyrecord_t *record);
 | 
			
		||||
							
								
								
									
										46
									
								
								users/datagrok/feature_default_layers_selector.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								users/datagrok/feature_default_layers_selector.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -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;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										69
									
								
								users/datagrok/feature_default_layers_selector.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										69
									
								
								users/datagrok/feature_default_layers_selector.h
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -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…
	
	Add table
		Add a link
		
	
		Reference in a new issue