Skip to content

Commit a60e07c

Browse files
feat: use drag direction enum and helpers (#383)
* feat: add drag direction to constrained events * feat: use direction for unconstrained moves * feat: unpack direction info in keyboard drag strategy
1 parent 6f1cf40 commit a60e07c

File tree

2 files changed

+51
-29
lines changed

2 files changed

+51
-29
lines changed

src/actions/mover.ts

Lines changed: 31 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import {
1818
import type {BlockSvg, IDragger, IDragStrategy} from 'blockly';
1919
import {Navigation} from '../navigation';
2020
import {KeyboardDragStrategy} from '../keyboard_drag_strategy';
21+
import {Direction, getXYFromDirection} from '../drag_direction';
2122

2223
const KeyCodes = utils.KeyCodes;
2324
const createSerializedKey = ShortcutRegistry.registry.createSerializedKey.bind(
@@ -87,28 +88,28 @@ export class Mover {
8788
{
8889
name: 'Move left, constrained',
8990
preconditionFn: (workspace) => this.isMoving(workspace),
90-
callback: (workspace) => this.moveConstrained(workspace /* , ...*/),
91+
callback: (workspace) => this.moveConstrained(workspace, Direction.Left),
9192
keyCodes: [KeyCodes.LEFT],
9293
allowCollision: true,
9394
},
9495
{
9596
name: 'Move right unconstrained',
9697
preconditionFn: (workspace) => this.isMoving(workspace),
97-
callback: (workspace) => this.moveConstrained(workspace /* , ... */),
98+
callback: (workspace) => this.moveConstrained(workspace, Direction.Right),
9899
keyCodes: [KeyCodes.RIGHT],
99100
allowCollision: true,
100101
},
101102
{
102103
name: 'Move up, constrained',
103104
preconditionFn: (workspace) => this.isMoving(workspace),
104-
callback: (workspace) => this.moveConstrained(workspace /* , ... */),
105+
callback: (workspace) => this.moveConstrained(workspace, Direction.Up),
105106
keyCodes: [KeyCodes.UP],
106107
allowCollision: true,
107108
},
108109
{
109110
name: 'Move down constrained',
110111
preconditionFn: (workspace) => this.isMoving(workspace),
111-
callback: (workspace) => this.moveConstrained(workspace /* , ... */),
112+
callback: (workspace) => this.moveConstrained(workspace, Direction.Down),
112113
keyCodes: [KeyCodes.DOWN],
113114
allowCollision: true,
114115
},
@@ -117,7 +118,8 @@ export class Mover {
117118
{
118119
name: 'Move left, unconstrained',
119120
preconditionFn: (workspace) => this.isMoving(workspace),
120-
callback: (workspace) => this.moveUnconstrained(workspace, -1, 0),
121+
callback: (workspace) =>
122+
this.moveUnconstrained(workspace, Direction.Left),
121123
keyCodes: [
122124
createSerializedKey(KeyCodes.LEFT, [KeyCodes.ALT]),
123125
createSerializedKey(KeyCodes.LEFT, [KeyCodes.CTRL]),
@@ -126,7 +128,8 @@ export class Mover {
126128
{
127129
name: 'Move right, unconstrained',
128130
preconditionFn: (workspace) => this.isMoving(workspace),
129-
callback: (workspace) => this.moveUnconstrained(workspace, 1, 0),
131+
callback: (workspace) =>
132+
this.moveUnconstrained(workspace, Direction.Right),
130133
keyCodes: [
131134
createSerializedKey(KeyCodes.RIGHT, [KeyCodes.ALT]),
132135
createSerializedKey(KeyCodes.RIGHT, [KeyCodes.CTRL]),
@@ -135,7 +138,7 @@ export class Mover {
135138
{
136139
name: 'Move up unconstrained',
137140
preconditionFn: (workspace) => this.isMoving(workspace),
138-
callback: (workspace) => this.moveUnconstrained(workspace, 0, -1),
141+
callback: (workspace) => this.moveUnconstrained(workspace, Direction.Up),
139142
keyCodes: [
140143
createSerializedKey(KeyCodes.UP, [KeyCodes.ALT]),
141144
createSerializedKey(KeyCodes.UP, [KeyCodes.CTRL]),
@@ -144,7 +147,8 @@ export class Mover {
144147
{
145148
name: 'Move down, unconstrained',
146149
preconditionFn: (workspace) => this.isMoving(workspace),
147-
callback: (workspace) => this.moveUnconstrained(workspace, 0, 1),
150+
callback: (workspace) =>
151+
this.moveUnconstrained(workspace, Direction.Down),
148152
keyCodes: [
149153
createSerializedKey(KeyCodes.DOWN, [KeyCodes.ALT]),
150154
createSerializedKey(KeyCodes.DOWN, [KeyCodes.CTRL]),
@@ -320,17 +324,18 @@ export class Mover {
320324
* constrained to valid attachment points (if any).
321325
*
322326
* @param workspace The workspace to move on.
327+
* @param direction The direction to move the dragged item.
323328
* @returns True iff this action applies and has been performed.
324329
*/
325-
moveConstrained(
326-
workspace: WorkspaceSvg,
327-
/* ... */
328-
) {
329-
// Not yet implemented. Absorb keystroke to avoid moving cursor.
330-
alert(`Constrained movement not implemented.
330+
moveConstrained(workspace: WorkspaceSvg, direction: Direction) {
331+
if (!workspace) return false;
332+
const info = this.moves.get(workspace);
333+
if (!info) throw new Error('no move info for workspace');
331334

332-
Use ctrl+arrow or alt+arrow (option+arrow on macOS) for unconstrained move.
333-
Use enter to complete the move, or escape to abort.`);
335+
info.dragger.onDrag(
336+
info.fakePointerEvent('pointermove', direction),
337+
info.totalDelta,
338+
);
334339
return true;
335340
}
336341

@@ -339,23 +344,17 @@ Use enter to complete the move, or escape to abort.`);
339344
* without constraint.
340345
*
341346
* @param workspace The workspace to move on.
342-
* @param xDirection -1 to move left. 1 to move right.
343-
* @param yDirection -1 to move up. 1 to move down.
347+
* @param direction The direction to move the dragged item.
344348
* @returns True iff this action applies and has been performed.
345349
*/
346-
moveUnconstrained(
347-
workspace: WorkspaceSvg,
348-
xDirection: number,
349-
yDirection: number,
350-
): boolean {
350+
moveUnconstrained(workspace: WorkspaceSvg, direction: Direction): boolean {
351351
if (!workspace) return false;
352352
const info = this.moves.get(workspace);
353353
if (!info) throw new Error('no move info for workspace');
354354

355-
info.totalDelta.x +=
356-
xDirection * UNCONSTRAINED_MOVE_DISTANCE * workspace.scale;
357-
info.totalDelta.y +=
358-
yDirection * UNCONSTRAINED_MOVE_DISTANCE * workspace.scale;
355+
const {x, y} = getXYFromDirection(direction);
356+
info.totalDelta.x += x * UNCONSTRAINED_MOVE_DISTANCE * workspace.scale;
357+
info.totalDelta.y += y * UNCONSTRAINED_MOVE_DISTANCE * workspace.scale;
359358

360359
info.dragger.onDrag(info.fakePointerEvent('pointermove'), info.totalDelta);
361360
return true;
@@ -446,10 +445,11 @@ export class MoveInfo {
446445
* Create a fake pointer event for dragging.
447446
*
448447
* @param type Which type of pointer event to create.
448+
* @param direction The direction if this movement is a constrained drag.
449449
* @returns A synthetic PointerEvent that can be consumed by Blockly's
450450
* dragging code.
451451
*/
452-
fakePointerEvent(type: string): PointerEvent {
452+
fakePointerEvent(type: string, direction?: Direction): PointerEvent {
453453
const workspace = this.block.workspace;
454454
if (!(workspace instanceof WorkspaceSvg)) throw new TypeError();
455455

@@ -460,9 +460,12 @@ export class MoveInfo {
460460
this.startLocation.y + this.totalDelta.y,
461461
),
462462
);
463+
const tilts = getXYFromDirection(direction);
463464
return new PointerEvent(type, {
464465
clientX: blockCoords.x,
465466
clientY: blockCoords.y,
467+
tiltX: tilts.x,
468+
tiltY: tilts.y,
466469
});
467470
}
468471
}

src/keyboard_drag_strategy.ts

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,33 @@
44
* SPDX-License-Identifier: Apache-2.0
55
*/
66

7-
import {dragging} from 'blockly';
7+
import {dragging, utils} from 'blockly';
8+
import {Direction, getDirectionFromXY} from './drag_direction';
89

910
export class KeyboardDragStrategy extends dragging.BlockDragStrategy {
11+
private currentDragDirection: Direction | null = null;
12+
1013
override startDrag(e?: PointerEvent) {
1114
super.startDrag(e);
1215
// Set position of the dragging block, so that it doesn't pop
1316
// to the top left of the workspace.
1417
// @ts-expect-error block and startLoc are private.
1518
this.block.moveDuringDrag(this.startLoc);
1619
}
20+
21+
override drag(newLoc: utils.Coordinate, e?: PointerEvent): void {
22+
if (!e) return;
23+
this.currentDragDirection = getDirectionFromXY({x: e.tiltX, y: e.tiltY});
24+
super.drag(newLoc);
25+
}
26+
27+
/**
28+
* Get whether the most recent drag event represents a constrained
29+
* keyboard drag.
30+
*
31+
* @returns true if the current movement is constrained, otherwise false.
32+
*/
33+
private isConstrainedMovement(): boolean {
34+
return !!this.currentDragDirection;
35+
}
1736
}

0 commit comments

Comments
 (0)