Add an optional 9-sector-grid warp size

This warp mode is similar to the navigation provided by some speech
recognition software. A 9-cell grid may provide more precision and
efficiency than the existing 4-cell warp mode. This adds some extra
key definitions to support the additional sectors and enables a user
to switch the grid size:

  MouseKeys.setWarpGridSize(MOUSE_WARP_GRID_3X3);

Signed-off-by: Cy Rossignol <cy@rossignols.me>
pull/365/head
Cy Rossignol 7 years ago
parent 468c2443a5
commit a407aa29b0

@ -88,19 +88,65 @@ acceleration involved. One just presses them.
* `Key_mouseBtnL`, `Key_mouseBtnM`, `Key_mouseBtnR`: The left, middle, and right * `Key_mouseBtnL`, `Key_mouseBtnM`, `Key_mouseBtnR`: The left, middle, and right
mouse buttons, respectively. mouse buttons, respectively.
### Warping ## Warping
Warping is one of the most interesting features of the plugin, and is a feature Warping is one of the most interesting features of the plugin, and is a feature
unique to Kaleidoscope, as far as we can tell. The warping keys position the unique to Kaleidoscope, as far as we can tell. The warping keys position the
mouse cursor within a quadrant of the screen on first press, and any subsequent mouse cursor within a sector of the screen on first press, and any subsequent
taps will warp within the previously selected quadrant. For example, pressing taps will warp within the previously selected sector. For example, pressing the
the north-west warp key twice will first jump to the middle of the north-west north-west warp key twice will first jump to the middle of the north-west
quadrant of your screen, then select the north-west quadrant of that, and jump sector of your screen, then select the north-west sector of that, and jump to
to the middle of it. the middle of it.
To stop warping, use any other mouse key, or hit the "warp end" key. To stop warping, use any other mouse key, or hit the "warp end" key.
The warping keys are the following: ### Warp grid size
The warp grid size determines how MouseKeys partitions the screen to select the
next position to jump to when pressing a warp key. The plugin provides two grid
sizes to choose from: a *2x2* grid that splits the screen into quadrants, and a
*3x3* grid with nine cells similar to a navigation feature included with some
speech recognition software. By default, the plugin splits the screen into the
2x2 grid.
To change the warp grid size, call the plugin's `setWarpGridSize()` method:
```c++
MouseKeys.setWarpGridSize(MOUSE_WARP_GRID_3X3);
```
#### 2x2 grid
As described above, MouseKeys warps the pointer using a grid model that reflects
locations on the screen. By default, the plugin uses a 2x2 grid. To understand
how warping works, examine this diagram of a screen split into that 2x2 grid:
+-----------------------+-----------------------+
| | | |
| G | tab | |
| | | |
|-----------+-----------| tab |
| | | |
| B | esc | |
| | | |
+-----------------------+-----------------------+
| | |
| | |
| | |
| B | esc |
| | |
| | |
| | |
+-----------------------+-----------------------+
Each quadrant is labed with a key that, when pressed, moves the mouse pointer
to the center of that quadrant. With this layout, pressing <kbd>G</kbd> warps
the pointer to the top-left quadant. Then, the plugin "zooms" into that sector
with a smaller grid so that the next warp key pressed jumps the pointer more
precisely within the sector. In this case, if we press <kbd>esc</kbd> next,
the pointer warps to the bottom-right corner within that quadrant.
The warping keys for the 2x2 grid are the following:
* `Key_mouseWarpNW`, `Key_mouseWarpNE`, `Key_mouseWarpSW`, `Key_mouseWarpSE`: * `Key_mouseWarpNW`, `Key_mouseWarpNE`, `Key_mouseWarpSW`, `Key_mouseWarpSE`:
Warp towards the north-west, north-east, south-west, or south-east quadrants, Warp towards the north-west, north-east, south-west, or south-east quadrants,
@ -109,6 +155,64 @@ The warping keys are the following:
state. Using any of the warping keys after this will start from the whole state. Using any of the warping keys after this will start from the whole
screen again. screen again.
#### 3x3 grid
A 3x3 warp grid assigns a key to each of nine sectors of the screen. The next
diagram shows a screen with a key label that warps to each sector. As we can
see, pressing <kbd>W</kbd> warps the pointer into the top-left sector, and
pressing <kbd>V</kbd> warps to the bottom-right corner within that sector:
+-----------------+-----------------+-----------------+
| W | E | R | | |
|-----+-----+-----| | |
| S | D | F | E | R |
|-----+-----+-----| | |
| X | C | V | | |
+-----------------+-----------------+-----------------+
| | | |
| | | |
| S | D | F |
| | | |
| | | |
+-----------------+-----------------+-----------------+
| | | |
| | | |
| X | C | V |
| | | |
| | | |
+-----------------+-----------------+-----------------+
To use a 3x3 warp grid, we may need to remap some keys. A suggested warp key
mapping is shown below on the left side of a keyboard with a QWERTY layout:
W | E | R T A - End Warping (Key_mouseWarpEnd)
---+---+--- W - Warp NW Sector (Key_mouseWarpNW)
A S | D | F G E - Warp N Sector (Key_mouseWarpN)
---+---+--- R - Warp NE Sector (Key_mouseWarpNE)
X | C | V B S - Warp E Sector (Key_mouseWarpE)
D - Warp/Zoom Center (Key_mouseWarpIn)
F - Warp W Sector (Key_mouseWarpW)
K - Warp SE Sector (Key_mouseWarpSE)
C - Warp S Sector (Key_mouseWarpS)
V - Warp SW Sector (Key_mouseWarpSW)
T - Right Click (Key_mouseBtnR)
G - Left Click (Key_mouseBtnL)
B - Middle Click (Key_mouseBtnM)
This example layout replaces the default directional mouse keys and sets the
warp keys in a comfortable position for a warp-only configuration. Of course,
a Kaleidoscope user may retain the directional keys and map the warp keys
elsewhere according to his or her liking.
A 3x3 warp grid layout contains all of the keys from the 2x2 grid layout with
the following additions:
* `Key_mouseWarpN`, `Key_mouseWarpE`, `Key_mouseWarpS`, `Key_mouseWarpW`:
Warp towards the north, east, south, and west sectors, respectively.
* `Key_mouseWarpIn`: Warp to the center sector of the grid. The plugin will
continue to "zoom" into center of the current cell with each consecutive
press of this key.
## Plugin methods ## Plugin methods
The plugin provides a `MouseKeys` object, with the following methods and The plugin provides a `MouseKeys` object, with the following methods and
@ -137,3 +241,8 @@ properties available:
> scrolling speed. The former, `.wheelSpeed`, controls the amount of ticks the > scrolling speed. The former, `.wheelSpeed`, controls the amount of ticks the
> wheel shall scroll, and defaults to 1. The second, `.wheelDelay`, controls the > wheel shall scroll, and defaults to 1. The second, `.wheelDelay`, controls the
> delay between two scroll events, and defaults to 50 milliseconds. > delay between two scroll events, and defaults to 50 milliseconds.
### `.setWarpGridSize`
> This method changes the size of the grid used for [warping](#warping). The
> following are valid sizes: `MOUSE_WARP_GRID_2X2`, `MOUSE_WARP_GRID_3X3`

@ -19,6 +19,10 @@ uint32_t MouseKeys_::accelEndTime;
uint32_t MouseKeys_::endTime; uint32_t MouseKeys_::endTime;
uint32_t MouseKeys_::wheelEndTime; uint32_t MouseKeys_::wheelEndTime;
void MouseKeys_::setWarpGridSize(uint8_t grid_size) {
MouseWrapper.warp_grid_size = grid_size;
}
void MouseKeys_::scrollWheel(uint8_t keyCode) { void MouseKeys_::scrollWheel(uint8_t keyCode) {
if (millis() < wheelEndTime) if (millis() < wheelEndTime)
return; return;
@ -102,10 +106,10 @@ Key MouseKeys_::eventHandlerHook(Key mappedKey, byte row, byte col, uint8_t keyS
} }
} else if (keyToggledOn(keyState)) { } else if (keyToggledOn(keyState)) {
if (mappedKey.keyCode & KEY_MOUSE_WARP && mappedKey.flags & IS_MOUSE_KEY) { if (mappedKey.keyCode & KEY_MOUSE_WARP && mappedKey.flags & IS_MOUSE_KEY) {
// we don't pass in the left and up values because those are the
// default, "no-op" conditionals
MouseWrapper.warp(((mappedKey.keyCode & KEY_MOUSE_WARP_END) ? WARP_END : 0x00) | MouseWrapper.warp(((mappedKey.keyCode & KEY_MOUSE_WARP_END) ? WARP_END : 0x00) |
((mappedKey.keyCode & KEY_MOUSE_UP) ? WARP_UP : 0x00) |
((mappedKey.keyCode & KEY_MOUSE_DOWN) ? WARP_DOWN : 0x00) | ((mappedKey.keyCode & KEY_MOUSE_DOWN) ? WARP_DOWN : 0x00) |
((mappedKey.keyCode & KEY_MOUSE_LEFT) ? WARP_LEFT : 0x00) |
((mappedKey.keyCode & KEY_MOUSE_RIGHT) ? WARP_RIGHT : 0x00)); ((mappedKey.keyCode & KEY_MOUSE_RIGHT) ? WARP_RIGHT : 0x00));
} }
} }

@ -2,6 +2,7 @@
#include "Kaleidoscope.h" #include "Kaleidoscope.h"
#include "MouseKeyDefs.h" #include "MouseKeyDefs.h"
#include "MouseWarpModes.h"
class MouseKeys_ : public KaleidoscopePlugin { class MouseKeys_ : public KaleidoscopePlugin {
public: public:
@ -16,6 +17,8 @@ class MouseKeys_ : public KaleidoscopePlugin {
static uint8_t wheelSpeed; static uint8_t wheelSpeed;
static uint16_t wheelDelay; static uint16_t wheelDelay;
static void setWarpGridSize(uint8_t grid_size);
private: private:
static uint8_t mouseMoveIntent; static uint8_t mouseMoveIntent;
static uint32_t endTime; static uint32_t endTime;

@ -20,8 +20,13 @@
#define Key_mouseWarpNW (Key) { KEY_MOUSE_WARP| KEY_MOUSE_UP | KEY_MOUSE_LEFT, KEY_FLAGS|SYNTHETIC|IS_MOUSE_KEY } #define Key_mouseWarpNW (Key) { KEY_MOUSE_WARP| KEY_MOUSE_UP | KEY_MOUSE_LEFT, KEY_FLAGS|SYNTHETIC|IS_MOUSE_KEY }
#define Key_mouseWarpN (Key) { KEY_MOUSE_WARP| KEY_MOUSE_UP, KEY_FLAGS|SYNTHETIC|IS_MOUSE_KEY }
#define Key_mouseWarpNE (Key) { KEY_MOUSE_WARP| KEY_MOUSE_UP | KEY_MOUSE_RIGHT, KEY_FLAGS|SYNTHETIC|IS_MOUSE_KEY } #define Key_mouseWarpNE (Key) { KEY_MOUSE_WARP| KEY_MOUSE_UP | KEY_MOUSE_RIGHT, KEY_FLAGS|SYNTHETIC|IS_MOUSE_KEY }
#define Key_mouseWarpW (Key) { KEY_MOUSE_WARP| KEY_MOUSE_LEFT, KEY_FLAGS|SYNTHETIC|IS_MOUSE_KEY }
#define Key_mouseWarpIn (Key) { KEY_MOUSE_WARP| KEY_MOUSE_UP | KEY_MOUSE_DOWN, KEY_FLAGS|SYNTHETIC|IS_MOUSE_KEY }
#define Key_mouseWarpE (Key) { KEY_MOUSE_WARP| KEY_MOUSE_RIGHT, KEY_FLAGS|SYNTHETIC|IS_MOUSE_KEY }
#define Key_mouseWarpSW (Key) { KEY_MOUSE_WARP| KEY_MOUSE_DOWN | KEY_MOUSE_LEFT, KEY_FLAGS|SYNTHETIC|IS_MOUSE_KEY } #define Key_mouseWarpSW (Key) { KEY_MOUSE_WARP| KEY_MOUSE_DOWN | KEY_MOUSE_LEFT, KEY_FLAGS|SYNTHETIC|IS_MOUSE_KEY }
#define Key_mouseWarpS (Key) { KEY_MOUSE_WARP| KEY_MOUSE_DOWN, KEY_FLAGS|SYNTHETIC|IS_MOUSE_KEY }
#define Key_mouseWarpSE (Key) { KEY_MOUSE_WARP| KEY_MOUSE_DOWN | KEY_MOUSE_RIGHT, KEY_FLAGS|SYNTHETIC|IS_MOUSE_KEY } #define Key_mouseWarpSE (Key) { KEY_MOUSE_WARP| KEY_MOUSE_DOWN | KEY_MOUSE_RIGHT, KEY_FLAGS|SYNTHETIC|IS_MOUSE_KEY }
#define Key_mouseWarpEnd (Key) { KEY_MOUSE_WARP| KEY_MOUSE_WARP_END, KEY_FLAGS|SYNTHETIC|IS_MOUSE_KEY } #define Key_mouseWarpEnd (Key) { KEY_MOUSE_WARP| KEY_MOUSE_WARP_END, KEY_FLAGS|SYNTHETIC|IS_MOUSE_KEY }

@ -0,0 +1,10 @@
#pragma once
// Warp modes determine how the plugin jumps the mouse pointer to a screen
// location when pressing a warp key.
// Grid Based - the constant represents the number of cells in a row or column:
#define MOUSE_WARP_GRID_2X2 2
#define MOUSE_WARP_GRID_3X3 3

@ -5,6 +5,7 @@
#include "MouseWrapper.h" #include "MouseWrapper.h"
#include "kaleidoscope/hid.h" #include "kaleidoscope/hid.h"
uint8_t MouseWrapper_::warp_grid_size = MOUSE_WARP_GRID_2X2;
uint16_t MouseWrapper_::next_width; uint16_t MouseWrapper_::next_width;
uint16_t MouseWrapper_::next_height; uint16_t MouseWrapper_::next_height;
uint16_t MouseWrapper_::section_top; uint16_t MouseWrapper_::section_top;
@ -59,21 +60,29 @@ void MouseWrapper_::warp(uint8_t warp_cmd) {
return; return;
} }
next_width = next_width / 2; next_width /= warp_grid_size;
next_height = next_height / 2; next_height /= warp_grid_size;
if (warp_cmd & WARP_UP) { // WARP_UP + WARP_DOWN means "zoom in" to center sector
// Serial.print(" - up "); if (warp_cmd & WARP_UP && warp_cmd & WARP_DOWN) {
} else if (warp_cmd & WARP_DOWN) { section_left += next_width;
// Serial.print(" - down "); section_top += next_height;
section_top = section_top + next_height;
warp_jump(section_left, section_top, next_height, next_width);
return;
}
if (warp_cmd & WARP_DOWN) {
section_top += next_height * (warp_grid_size - 1);
} else if (!(warp_cmd & WARP_UP)) {
section_top += next_height;
} }
if (warp_cmd & WARP_LEFT) { if (warp_cmd & WARP_RIGHT) {
// Serial.print(" - left "); section_left += next_width * (warp_grid_size - 1);
} else if (warp_cmd & WARP_RIGHT) { } else if (!(warp_cmd & WARP_LEFT)) {
// Serial.print(" - right "); section_left += next_width;
section_left = section_left + next_width;
} }
warp_jump(section_left, section_top, next_height, next_width); warp_jump(section_left, section_top, next_height, next_width);

@ -1,6 +1,7 @@
#pragma once #pragma once
#include "Arduino.h" #include "Arduino.h"
#include "MouseWarpModes.h"
// Warping commands // Warping commands
@ -32,6 +33,7 @@ class MouseWrapper_ {
static void release_button(uint8_t button); static void release_button(uint8_t button);
static uint8_t accelStep; static uint8_t accelStep;
static uint8_t speedLimit; static uint8_t speedLimit;
static uint8_t warp_grid_size;
private: private:
static uint16_t next_width; static uint16_t next_width;

Loading…
Cancel
Save