Skip to content

Commit

Permalink
Configurable modifier keys, re issue d3#20
Browse files Browse the repository at this point in the history
d3#20

Added modifier behavior "constants" that also hold
the default key modifier.

d3.brushForceNew (Meta key) <-- unsure on naming
d3.brushFixSize (Space key)
d3.brushFixCenter (Alt key)
d3.brushFixSecondary (Shift key)

Default modifier key code can be changed, or the behavior disabled,
by calling
```
d3.brushFixSecondary.keyCode(newKeyCode);  //change
d3.brushFixCenter.keyCode(null); //disable
```
Default modifier key code can be retrieved by calling `.keyCode()`
without arguments.

Added `brush.keyModifier(behavior, keyCode)` method

Modifier keys for an individual brush can be changed or disabled
by calling
```
brush.keyModifier(d3.brushFixSecondary, keyCode); //change
brush.keyModifier(d3.brushFixCenter, null); //disable
```

The current modifier key code can be retrieved by passing the behavior
without an argument for key code.
```
const keyCode = brush.keyModifier(d3.brushFixSecondary); // keyCode === 16
```

Note: Non-modifier keys can be set as the key code for brushFixCenter,
but the behavior will only be applied/stopped for keydown/keyup while
brushing is active, since the key code can't be mapped to one of the
`modifierKey` properties on MouseEvent.
  • Loading branch information
krisdages committed Mar 29, 2019
1 parent 8aed2b3 commit d54a40a
Show file tree
Hide file tree
Showing 2 changed files with 86 additions and 11 deletions.
91 changes: 81 additions & 10 deletions src/brush.js
Expand Up @@ -7,6 +7,43 @@ import constant from "./constant";
import BrushEvent from "./event";
import noevent, {nopropagation} from "./noevent";

var ALT_KEY = 18,
CTRL_KEY = 17,
META_KEY = 91,
SHIFT_KEY = 16,
SPACE_KEY = 32;

var EVENT_MOD_KEYS = { };
EVENT_MOD_KEYS[ALT_KEY] = "altKey";
EVENT_MOD_KEYS[CTRL_KEY] = "ctrlKey";
EVENT_MOD_KEYS[SHIFT_KEY] = "shiftKey";
EVENT_MOD_KEYS[META_KEY] = "metaKey";

function KeyModifier(keyCode) {
this._keyCode = keyCode;
}

KeyModifier.prototype = {
keyCode: function(keyCode) {
if (keyCode === undefined) {
return this._keyCode;
}
if (keyCode === null) {
this._keyCode = null;
}
else {
this._keyCode = +keyCode;
}
return this;
},
};
var brushForceNew = new KeyModifier(META_KEY);
var brushFixSize = new KeyModifier(SPACE_KEY);
var brushFixCenter = new KeyModifier(ALT_KEY);
var brushFixSecondary = new KeyModifier(SHIFT_KEY);

export { brushForceNew, brushFixSize, brushFixCenter, brushFixSecondary };

var MODE_DRAG = {name: "drag"},
MODE_SPACE = {name: "space"},
MODE_HANDLE = {name: "handle"},
Expand Down Expand Up @@ -137,7 +174,21 @@ function brush(dim) {
filter = defaultFilter,
listeners = dispatch(brush, "start", "brush", "end"),
handleSize = 6,
touchending;
touchending,
modForceNew = new KeyModifier(brushForceNew._keyCode),
modFixSize = new KeyModifier(brushFixSize._keyCode),
modFixCenter = new KeyModifier(brushFixCenter._keyCode),
modFixSecondary = new KeyModifier(brushFixSecondary._keyCode);

function eventModMatches(event, keyModifier) {
var keyCode = keyModifier._keyCode;
if (keyCode === null)
return false;

var modKey = EVENT_MOD_KEYS[keyCode];

return modKey !== undefined && event[modKey];
}

function brush(group) {
var overlay = group
Expand Down Expand Up @@ -294,7 +345,7 @@ function brush(dim) {

var that = this,
type = event.target.__data__.type,
mode = (event.metaKey ? type = "overlay" : type) === "selection" ? MODE_DRAG : (event.altKey ? MODE_CENTER : MODE_HANDLE),
mode = (eventModMatches(event, modForceNew) ? type = "overlay" : type) === "selection" ? MODE_DRAG : (eventModMatches(event, modFixCenter) ? MODE_CENTER : MODE_HANDLE),
signX = dim === Y ? null : signsX[type],
signY = dim === X ? null : signsY[type],
state = local(that),
Expand All @@ -307,7 +358,8 @@ function brush(dim) {
dx,
dy,
moving,
shifting = signX && signY && event.shiftKey,
shifting = signX && signY && eventModMatches(event, modFixSecondary),
alting = eventModMatches(event, modFixCenter),
lockX,
lockY,
point0 = mouse(that),
Expand Down Expand Up @@ -443,11 +495,12 @@ function brush(dim) {

function keydowned() {
switch (event.keyCode) {
case 16: { // SHIFT
case modFixSecondary._keyCode: { // SHIFT
shifting = signX && signY;
break;
}
case 18: { // ALT
case modFixCenter._keyCode: { // ALT
alting = true;
if (mode === MODE_HANDLE) {
if (signX) e0 = e1 - dx * signX, w0 = w1 + dx * signX;
if (signY) s0 = s1 - dy * signY, n0 = n1 + dy * signY;
Expand All @@ -456,7 +509,7 @@ function brush(dim) {
}
break;
}
case 32: { // SPACE; takes priority over ALT
case modFixSize._keyCode: { // SPACE; takes priority over ALT
if (mode === MODE_HANDLE || mode === MODE_CENTER) {
if (signX < 0) e0 = e1 - dx; else if (signX > 0) w0 = w1 - dx;
if (signY < 0) s0 = s1 - dy; else if (signY > 0) n0 = n1 - dy;
Expand All @@ -473,14 +526,15 @@ function brush(dim) {

function keyupped() {
switch (event.keyCode) {
case 16: { // SHIFT
case modFixSecondary._keyCode: { // SHIFT
if (shifting) {
lockX = lockY = shifting = false;
move();
}
break;
}
case 18: { // ALT
case modFixCenter._keyCode: { // ALT
alting = false;
if (mode === MODE_CENTER) {
if (signX < 0) e0 = e1; else if (signX > 0) w0 = w1;
if (signY < 0) s0 = s1; else if (signY > 0) n0 = n1;
Expand All @@ -489,9 +543,9 @@ function brush(dim) {
}
break;
}
case 32: { // SPACE
case modFixSize._keyCode: { // SPACE
if (mode === MODE_SPACE) {
if (event.altKey) {
if (eventModMatches(event, modFixCenter) || alting) {
if (signX) e0 = e1 - dx * signX, w0 = w1 + dx * signX;
if (signY) s0 = s1 - dy * signY, n0 = n1 + dy * signY;
mode = MODE_CENTER;
Expand Down Expand Up @@ -535,5 +589,22 @@ function brush(dim) {
return value === listeners ? brush : value;
};

function applyModifier(mod, keyCode) {
if (keyCode === undefined) {
return mod.keyCode();
}
mod.keyCode(keyCode);
return brush;
}

brush.keyModifier = function(brushModifier, keyCode) {
switch (brushModifier) {
case brushFixSize: return applyModifier(modFixSize, keyCode);
case brushFixCenter: return applyModifier(modFixCenter, keyCode);
case brushFixSecondary: return applyModifier(modFixSecondary, keyCode);
default: return brush;
}
};

return brush;
}
6 changes: 5 additions & 1 deletion src/index.js
Expand Up @@ -2,5 +2,9 @@ export {
default as brush,
brushX,
brushY,
brushSelection
brushSelection,
brushForceNew,
brushFixSize,
brushFixCenter,
brushFixSecondary
} from "./brush";

0 comments on commit d54a40a

Please sign in to comment.