Improve one-hand support by adding more actions and tap keys.

This commit is contained in:
Joe Wasson 2016-07-28 01:24:06 -07:00
parent dd37860160
commit 8090f6b499
3 changed files with 89 additions and 9 deletions

View file

@ -456,8 +456,9 @@ Turn the backlight on and off without changing level.
### 2.6 Swap-Hands Action ### 2.6 Swap-Hands Action
The swap-hands action allows support for one-handed keyboards without requiring a separate layer. Set `ONEHAND_ENABLE` in the Makefile and define a `hand_swap_config` entry in your keymap. Now whenever the `ACTION_SWAP_HANDS` command is executed the keyboard is mirrored. For instance, to type "Hello, World" on QWERTY you would type `^Ge^s^s^w^c W^wr^sd` The swap-hands action allows support for one-handed keyboards without requiring a separate layer. Set `ONEHAND_ENABLE` in the Makefile and define a `hand_swap_config` entry in your keymap. Now whenever the `ACTION_SWAP_HANDS` command key is pressed the keyboard is mirrored. For instance, to type "Hello, World" on QWERTY you would type `^Ge^s^s^w^c W^wr^sd`
### 2.6.1 Configuration
The configuration table is a simple 2-dimensional array to map from column/row to new column/row. Example `hand_swap_config` for Planck: The configuration table is a simple 2-dimensional array to map from column/row to new column/row. Example `hand_swap_config` for Planck:
``` ```
@ -471,6 +472,16 @@ const keypos_t hand_swap_config[MATRIX_ROWS][MATRIX_COLS] = {
Note that the array indices are reversed same as the matrix and the values are of type `keypos_t` which is `{col, row}` and all values are zero-based. In the example above, `hand_swap_config[2][4]` (third row, fifth column) would return {7, 2} (third row, eighth column). Note that the array indices are reversed same as the matrix and the values are of type `keypos_t` which is `{col, row}` and all values are zero-based. In the example above, `hand_swap_config[2][4]` (third row, fifth column) would return {7, 2} (third row, eighth column).
### 2.6.2 Advanced Swap Commands
- **`ACTION_SWAP_HANDS()`** Swaps hands when pressed, returns to normal when released (momentary).
- **`ACTION_SWAP_HANDS_TOGGLE()`** Toggles swap on and off with every keypress.
- **`ACTION_SWAP_HANDS_TAP_TOGGLE()`** Toggles with a tap; momentary when held.
- **`ACTION_SWAP_HANDS_TAP_KEY(key)`** Sends `key` with a tap; momentary swap when held.
- **`ACTION_SWAP_HANDS_ON_OFF()`** Alias for `ACTION_SWAP_HANDS()`
- **`ACTION_SWAP_HANDS_OFF_ON()`** Momentarily turns off swap.
- **`ACTION_SWAP_HANDS_ON()`** Turns on swapping and leaves it on.
- **`ACTION_SWAP_HANDS_OFF()`** Turn off swapping and leaves it off. Good for returning to a known state.
## 3. Layer switching Example ## 3. Layer switching Example

View file

@ -465,14 +465,55 @@ void process_action(keyrecord_t *record, action_t action)
break; break;
#endif #endif
case ACT_COMMAND: case ACT_COMMAND:
switch (action.command.id) { break;
#ifdef ONEHAND_ENABLE #ifdef ONEHAND_ENABLE
case CMD_SWAP_HANDS: case ACT_SWAP_HANDS:
switch (action.swap.code) {
case OP_SH_TOGGLE:
if (event.pressed) {
swap_hands = !swap_hands;
}
break;
case OP_SH_ON_OFF:
swap_hands = event.pressed; swap_hands = event.pressed;
break; break;
#endif case OP_SH_OFF_ON:
swap_hands = !event.pressed;
break;
case OP_SH_ON:
if (!event.pressed) {
swap_hands = true;
}
break;
case OP_SH_OFF:
if (!event.pressed) {
swap_hands = false;
}
break;
#ifndef NO_ACTION_TAPPING
case OP_SH_TAP_TOGGLE:
/* tap toggle */
if (tap_count > 0) {
if (!event.pressed) {
swap_hands = !swap_hands;
}
} else {
swap_hands = event.pressed;
}
break;
default:
if (tap_count > 0) {
if (event.pressed) {
register_code(action.swap.code);
} else {
unregister_code(action.swap.code);
}
} else {
swap_hands = event.pressed;
}
#endif
} }
break; #endif
#ifndef NO_ACTION_FUNCTION #ifndef NO_ACTION_FUNCTION
case ACT_FUNCTION: case ACT_FUNCTION:
action_function(record, action.func.id, action.func.opt); action_function(record, action.func.id, action.func.opt);
@ -685,6 +726,13 @@ bool is_tap_key(keypos_t key)
return true; return true;
} }
return false; return false;
case ACT_SWAP_HANDS:
switch (action.swap.code) {
case 0x00 ... 0xdf:
case OP_SH_TAP_TOGGLE:
return true;
}
return false;
case ACT_MACRO: case ACT_MACRO:
case ACT_FUNCTION: case ACT_FUNCTION:
if (action.func.opt & FUNC_TAP) { return true; } if (action.func.opt & FUNC_TAP) { return true; }
@ -725,6 +773,7 @@ void debug_action(action_t action)
case ACT_MACRO: dprint("ACT_MACRO"); break; case ACT_MACRO: dprint("ACT_MACRO"); break;
case ACT_COMMAND: dprint("ACT_COMMAND"); break; case ACT_COMMAND: dprint("ACT_COMMAND"); break;
case ACT_FUNCTION: dprint("ACT_FUNCTION"); break; case ACT_FUNCTION: dprint("ACT_FUNCTION"); break;
case ACT_SWAP_HANDS: dprint("ACT_SWAP_HANDS"); break;
default: dprint("UNKNOWN"); break; default: dprint("UNKNOWN"); break;
} }
dprintf("[%X:%02X]", action.kind.param>>8, action.kind.param&0xff); dprintf("[%X:%02X]", action.kind.param>>8, action.kind.param&0xff);

View file

@ -108,6 +108,8 @@ enum action_kind_id {
/* Other Keys */ /* Other Keys */
ACT_USAGE = 0b0100, ACT_USAGE = 0b0100,
ACT_MOUSEKEY = 0b0101, ACT_MOUSEKEY = 0b0101,
/* One-hand Support */
ACT_SWAP_HANDS = 0b0110,
/* Layer Actions */ /* Layer Actions */
ACT_LAYER = 0b1000, ACT_LAYER = 0b1000,
ACT_LAYER_TAP = 0b1010, /* Layer 0-15 */ ACT_LAYER_TAP = 0b1010, /* Layer 0-15 */
@ -178,6 +180,11 @@ typedef union {
uint8_t opt :4; uint8_t opt :4;
uint8_t kind :4; uint8_t kind :4;
} func; } func;
struct action_swap {
uint8_t code :8;
uint8_t opt :4;
uint8_t kind :4;
} swap;
} action_t; } action_t;
@ -296,9 +303,6 @@ enum backlight_opt {
BACKLIGHT_LEVEL = 4, BACKLIGHT_LEVEL = 4,
}; };
enum command_id {
CMD_SWAP_HANDS = 0x14,
};
/* Macro */ /* Macro */
#define ACTION_MACRO(id) ACTION(ACT_MACRO, (id)) #define ACTION_MACRO(id) ACTION(ACT_MACRO, (id))
#define ACTION_MACRO_TAP(id) ACTION(ACT_MACRO, FUNC_TAP<<8 | (id)) #define ACTION_MACRO_TAP(id) ACTION(ACT_MACRO, FUNC_TAP<<8 | (id))
@ -319,6 +323,22 @@ enum function_opts {
#define ACTION_FUNCTION_TAP(id) ACTION(ACT_FUNCTION, FUNC_TAP<<8 | (id)) #define ACTION_FUNCTION_TAP(id) ACTION(ACT_FUNCTION, FUNC_TAP<<8 | (id))
#define ACTION_FUNCTION_OPT(id, opt) ACTION(ACT_FUNCTION, (opt)<<8 | (id)) #define ACTION_FUNCTION_OPT(id, opt) ACTION(ACT_FUNCTION, (opt)<<8 | (id))
/* OneHand Support */ /* OneHand Support */
#define ACTION_SWAP_HANDS() ACTION_COMMAND(CMD_SWAP_HANDS, 0) enum swap_hands_pram_tap_op {
OP_SH_TOGGLE = 0xF0,
OP_SH_TAP_TOGGLE,
OP_SH_ON_OFF,
OP_SH_OFF_ON,
OP_SH_OFF,
OP_SH_ON,
};
#define ACTION_SWAP_HANDS() ACTION_SWAP_HANDS_ON_OFF()
#define ACTION_SWAP_HANDS_TOGGLE() ACTION(ACT_SWAP_HANDS, OP_SH_TOGGLE)
#define ACTION_SWAP_HANDS_TAP_TOGGLE() ACTION(ACT_SWAP_HANDS, OP_SH_TAP_TOGGLE)
#define ACTION_SWAP_HANDS_TAP_KEY(key) ACTION(ACT_SWAP_HANDS, key)
#define ACTION_SWAP_HANDS_ON_OFF() ACTION(ACT_SWAP_HANDS, OP_SH_ON_OFF)
#define ACTION_SWAP_HANDS_OFF_ON() ACTION(ACT_SWAP_HANDS, OP_SH_OFF_ON)
#define ACTION_SWAP_HANDS_ON() ACTION(ACT_SWAP_HANDS, OP_SH_ON)
#define ACTION_SWAP_HANDS_OFF() ACTION(ACT_SWAP_HANDS, OP_SH_OFF)
#endif /* ACTION_CODE_H */ #endif /* ACTION_CODE_H */