From a407aa29b0a381e9ced9c3aa1afa9515c9e56c11 Mon Sep 17 00:00:00 2001 From: Cy Rossignol Date: Sun, 1 Apr 2018 00:58:48 +0100 Subject: [PATCH] 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 --- README.md | 123 +++++++++++++++++++++++++++++++-- src/Kaleidoscope-MouseKeys.cpp | 8 ++- src/Kaleidoscope-MouseKeys.h | 3 + src/MouseKeyDefs.h | 5 ++ src/MouseWarpModes.h | 10 +++ src/MouseWrapper.cpp | 33 +++++---- src/MouseWrapper.h | 2 + 7 files changed, 163 insertions(+), 21 deletions(-) create mode 100644 src/MouseWarpModes.h diff --git a/README.md b/README.md index 379813cb..d4ee37a4 100644 --- a/README.md +++ b/README.md @@ -88,19 +88,65 @@ acceleration involved. One just presses them. * `Key_mouseBtnL`, `Key_mouseBtnM`, `Key_mouseBtnR`: The left, middle, and right mouse buttons, respectively. -### Warping +## Warping 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 -mouse cursor within a quadrant of the screen on first press, and any subsequent -taps will warp within the previously selected quadrant. For example, pressing -the 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 -to the middle of it. +mouse cursor within a sector of the screen on first press, and any subsequent +taps will warp within the previously selected sector. For example, pressing the +north-west warp key twice will first jump to the middle of the north-west +sector of your screen, then select the north-west sector of that, and jump to +the middle of it. 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 G 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 esc 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`: 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 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 W warps the pointer into the top-left sector, and +pressing V 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 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 > wheel shall scroll, and defaults to 1. The second, `.wheelDelay`, controls the > 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` diff --git a/src/Kaleidoscope-MouseKeys.cpp b/src/Kaleidoscope-MouseKeys.cpp index 4455dde4..6da6090b 100644 --- a/src/Kaleidoscope-MouseKeys.cpp +++ b/src/Kaleidoscope-MouseKeys.cpp @@ -19,6 +19,10 @@ uint32_t MouseKeys_::accelEndTime; uint32_t MouseKeys_::endTime; uint32_t MouseKeys_::wheelEndTime; +void MouseKeys_::setWarpGridSize(uint8_t grid_size) { + MouseWrapper.warp_grid_size = grid_size; +} + void MouseKeys_::scrollWheel(uint8_t keyCode) { if (millis() < wheelEndTime) return; @@ -102,10 +106,10 @@ Key MouseKeys_::eventHandlerHook(Key mappedKey, byte row, byte col, uint8_t keyS } } else if (keyToggledOn(keyState)) { 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) | + ((mappedKey.keyCode & KEY_MOUSE_UP) ? WARP_UP : 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)); } } diff --git a/src/Kaleidoscope-MouseKeys.h b/src/Kaleidoscope-MouseKeys.h index 255a0888..78dbabe2 100644 --- a/src/Kaleidoscope-MouseKeys.h +++ b/src/Kaleidoscope-MouseKeys.h @@ -2,6 +2,7 @@ #include "Kaleidoscope.h" #include "MouseKeyDefs.h" +#include "MouseWarpModes.h" class MouseKeys_ : public KaleidoscopePlugin { public: @@ -16,6 +17,8 @@ class MouseKeys_ : public KaleidoscopePlugin { static uint8_t wheelSpeed; static uint16_t wheelDelay; + static void setWarpGridSize(uint8_t grid_size); + private: static uint8_t mouseMoveIntent; static uint32_t endTime; diff --git a/src/MouseKeyDefs.h b/src/MouseKeyDefs.h index 2a10af25..5f66a5d4 100644 --- a/src/MouseKeyDefs.h +++ b/src/MouseKeyDefs.h @@ -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_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_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_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_mouseWarpEnd (Key) { KEY_MOUSE_WARP| KEY_MOUSE_WARP_END, KEY_FLAGS|SYNTHETIC|IS_MOUSE_KEY } diff --git a/src/MouseWarpModes.h b/src/MouseWarpModes.h new file mode 100644 index 00000000..6f2b28a4 --- /dev/null +++ b/src/MouseWarpModes.h @@ -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 diff --git a/src/MouseWrapper.cpp b/src/MouseWrapper.cpp index 9476a237..100367bb 100644 --- a/src/MouseWrapper.cpp +++ b/src/MouseWrapper.cpp @@ -5,6 +5,7 @@ #include "MouseWrapper.h" #include "kaleidoscope/hid.h" +uint8_t MouseWrapper_::warp_grid_size = MOUSE_WARP_GRID_2X2; uint16_t MouseWrapper_::next_width; uint16_t MouseWrapper_::next_height; uint16_t MouseWrapper_::section_top; @@ -59,21 +60,29 @@ void MouseWrapper_::warp(uint8_t warp_cmd) { return; } - next_width = next_width / 2; - next_height = next_height / 2; + next_width /= warp_grid_size; + next_height /= warp_grid_size; - if (warp_cmd & WARP_UP) { -// Serial.print(" - up "); - } else if (warp_cmd & WARP_DOWN) { -// Serial.print(" - down "); - section_top = section_top + next_height; + // WARP_UP + WARP_DOWN means "zoom in" to center sector + if (warp_cmd & WARP_UP && warp_cmd & WARP_DOWN) { + section_left += next_width; + 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) { - // Serial.print(" - left "); - } else if (warp_cmd & WARP_RIGHT) { - // Serial.print(" - right "); - section_left = section_left + next_width; + if (warp_cmd & WARP_RIGHT) { + section_left += next_width * (warp_grid_size - 1); + } else if (!(warp_cmd & WARP_LEFT)) { + section_left += next_width; } warp_jump(section_left, section_top, next_height, next_width); diff --git a/src/MouseWrapper.h b/src/MouseWrapper.h index 732d2af7..8c6ee04f 100644 --- a/src/MouseWrapper.h +++ b/src/MouseWrapper.h @@ -1,6 +1,7 @@ #pragma once #include "Arduino.h" +#include "MouseWarpModes.h" // Warping commands @@ -32,6 +33,7 @@ class MouseWrapper_ { static void release_button(uint8_t button); static uint8_t accelStep; static uint8_t speedLimit; + static uint8_t warp_grid_size; private: static uint16_t next_width;