Skip to content

Commit 6ee4938

Browse files
authored
fix: Move cursor when user selects a block with mouse (#178)
Hack to temporarily address #97. Overrides Marker.prototype.getCurNode in LineCursor to add a hack that attempts to detect if the user has moved focus by selecting a block and, if so, update the cursor location (and any highlighting) to match. This works reasonably well but has some glitches, most notably that if the cursor is not on a block (e.g. it is on a connection or the workspace) then it will remain visible in its previous location until a cursor key is pressed.
1 parent d961db1 commit 6ee4938

File tree

1 file changed

+56
-2
lines changed

1 file changed

+56
-2
lines changed

src/line_cursor.ts

Lines changed: 56 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -403,7 +403,50 @@ export class LineCursor extends Marker {
403403
}
404404

405405
/**
406-
* Set the location of the marker and draw it.
406+
* Get the current location of the cursor.
407+
*
408+
* Overrides superclass implementation to add a hack that attempts
409+
* to detect if the user has moved focus by selecting a block and,
410+
* if so, update the cursor location (and any highlighting) to
411+
* match.
412+
*
413+
* This works reasonably well but has some glitches, most notably
414+
* that if the cursor is not on a block (e.g. it is on a connection
415+
* or the workspace) then it will remain visible in its previous
416+
* location until a cursor key is pressed.
417+
*
418+
* TODO(#97): Remove this hack once Blockly is modified to update
419+
* the cursor/focus itself.
420+
*
421+
* @returns The current field, connection, or block the cursor is on.
422+
*/
423+
override getCurNode(): ASTNode {
424+
const curNode = super.getCurNode();
425+
const selected = Blockly.common.getSelected();
426+
if (
427+
(selected?.workspace as Blockly.WorkspaceSvg)
428+
?.getMarkerManager()
429+
.getCursor() !== this
430+
)
431+
return curNode;
432+
433+
// Selected item is on workspace that this cursor belongs to.
434+
const curLocation = curNode?.getLocation();
435+
if (curLocation === selected) return curNode;
436+
437+
// Selected item is not where cursor is. Try to move cursor.
438+
if (!(selected instanceof Blockly.Block)) {
439+
console.error('Selected item is not a block. Ignoring');
440+
return curNode;
441+
}
442+
const newNode = new ASTNode(ASTNode.types.BLOCK, selected);
443+
super.setCurNode(newNode);
444+
this.updateFocusIndication(curNode, newNode);
445+
return newNode;
446+
}
447+
448+
/**
449+
* Set the location of the cursor and draw it.
407450
*
408451
* Overrides drawing logic to call `setSelected` if the location is
409452
* a block, or `addSelect` if it's a shadow block (since shadow
@@ -421,11 +464,22 @@ export class LineCursor extends Marker {
421464
* this selection hack with non-hacky changing of focus once that's
422465
* possible.
423466
*
424-
* @param newNode The new location of the marker.
467+
* @param newNode The new location of the cursor.
425468
*/
426469
override setCurNode(newNode: ASTNode) {
427470
const oldNode = this.getCurNode();
428471
super.setCurNode(newNode);
472+
this.updateFocusIndication(oldNode, newNode);
473+
}
474+
475+
/**
476+
* Implements fake selection of shadow blocks as described in
477+
* documentation for setCurNode.
478+
*
479+
* @param oldNode The previous node.
480+
* @param newNode The newly-selected node.
481+
*/
482+
private updateFocusIndication(oldNode: ASTNode, newNode: ASTNode) {
429483
const drawer = this.getDrawer();
430484

431485
if (!drawer) {

0 commit comments

Comments
 (0)