1515
1616import * as Blockly from 'blockly/core' ;
1717import { ASTNode , Marker } from 'blockly/core' ;
18- import { scrollBoundsIntoView } from './workspace_utilities' ;
18+ import { getWorkspaceElement , scrollBoundsIntoView } from './workspace_utilities' ;
1919
2020/** Options object for LineCursor instances. */
2121export type CursorOptions = {
@@ -474,47 +474,6 @@ export class LineCursor extends Marker {
474474 throw new Error ( 'no valid nodes in this.potentialNodes' ) ;
475475 }
476476
477- /**
478- * Get the current location of the cursor.
479- *
480- * Overrides superclass implementation to add a hack that attempts
481- * to detect if the user has moved focus by selecting a block and,
482- * if so, update the cursor location (and any highlighting) to
483- * match.
484- *
485- * Doing this only when getCurNode would naturally be called works
486- * reasonably well but has some glitches, most notably that if the
487- * cursor was not on a block (e.g. it was on a connection or the
488- * workspace) when the user selected a block then it will remain
489- * visible in its previous location until some keyboard navigation occurs.
490- *
491- * To ameliorate this, the LineCursor constructor adds an event
492- * listener that calls getCurNode in response to SELECTED events.
493- *
494- * Remove this hack once Blockly is modified to update the
495- * cursor/focus itself.
496- *
497- * @returns The current field, connection, or block the cursor is on.
498- */
499- override getCurNode ( ) : ASTNode {
500- const curNode = super . getCurNode ( ) ;
501- const selected = Blockly . common . getSelected ( ) ;
502- if ( selected ?. workspace !== this . workspace ) return curNode ;
503-
504- // Selected item is on workspace that this cursor belongs to.
505- const curLocation = curNode ?. getLocation ( ) ;
506- if ( curLocation === selected ) return curNode ;
507-
508- // Selected item is not where cursor is. Try to move cursor.
509- if ( ! ( selected instanceof Blockly . Block ) ) {
510- console . error ( 'Selected item is not a block. Ignoring' ) ;
511- return curNode ;
512- }
513- const newNode = new ASTNode ( ASTNode . types . BLOCK , selected ) ;
514- this . setCurNode ( newNode ) ;
515- return newNode ;
516- }
517-
518477 /**
519478 * Set the location of the cursor and draw it.
520479 *
@@ -523,7 +482,25 @@ export class LineCursor extends Marker {
523482 *
524483 * @param newNode The new location of the cursor.
525484 */
526- override setCurNode ( newNode : ASTNode ) {
485+ override setCurNode ( newNode : ASTNode , selectionInSync = false ) {
486+ if ( newNode ?. getLocation ( ) === this . getCurNode ( ) ?. getLocation ( ) ) {
487+ return ;
488+ }
489+ if ( ! selectionInSync ) {
490+ if (
491+ newNode ?. getType ( ) === ASTNode . types . BLOCK &&
492+ ! ( newNode . getLocation ( ) as Blockly . BlockSvg ) . isShadow ( )
493+ ) {
494+ if ( Blockly . common . getSelected ( ) !== newNode . getLocation ( ) ) {
495+ Blockly . common . setSelected ( newNode . getLocation ( ) as Blockly . BlockSvg ) ;
496+ }
497+ } else {
498+ if ( Blockly . common . getSelected ( ) ) {
499+ Blockly . common . setSelected ( null ) ;
500+ }
501+ }
502+ }
503+
527504 const oldNode = super . getCurNode ( ) ;
528505 // Kludge: we can't set this.curNode directly, so we have to call
529506 // super.setCurNode(...) to do it for us - but that would call
@@ -533,6 +510,7 @@ export class LineCursor extends Marker {
533510 this . setDrawer ( null as any ) ; // Cast required since param is not nullable.
534511 super . setCurNode ( newNode ) ;
535512 this . setDrawer ( drawer ) ;
513+
536514 // Draw this marker the way we want to.
537515 this . drawMarker ( oldNode , newNode ) ;
538516 // Try to scroll cursor into view.
@@ -545,22 +523,6 @@ export class LineCursor extends Marker {
545523 }
546524 }
547525
548- override hide ( ) : void {
549- super . hide ( ) ;
550-
551- // If there's a block currently selected, remove the selection since the
552- // cursor should now be hidden.
553- const curNode = this . getCurNode ( ) ;
554- if ( curNode && curNode . getType ( ) === ASTNode . types . BLOCK ) {
555- const block = curNode . getLocation ( ) as Blockly . BlockSvg ;
556- if ( ! block . isShadow ( ) ) {
557- Blockly . common . setSelected ( null ) ;
558- } else {
559- block . removeSelect ( ) ;
560- }
561- }
562- }
563-
564526 /**
565527 * Redraw the current marker.
566528 *
@@ -605,7 +567,7 @@ export class LineCursor extends Marker {
605567 if ( oldNode ?. getType ( ) === ASTNode . types . BLOCK ) {
606568 const block = oldNode . getLocation ( ) as Blockly . BlockSvg ;
607569 if ( ! block . isShadow ( ) ) {
608- Blockly . common . setSelected ( null ) ;
570+ // Selection should already be in sync.
609571 } else {
610572 block . removeSelect ( ) ;
611573 }
@@ -633,7 +595,7 @@ export class LineCursor extends Marker {
633595 } else if ( curNodeType === ASTNode . types . BLOCK ) {
634596 const block = curNode . getLocation ( ) as Blockly . BlockSvg ;
635597 if ( ! block . isShadow ( ) ) {
636- Blockly . common . setSelected ( block ) ;
598+ // Selection should already be in sync.
637599 } else {
638600 block . addSelect ( ) ;
639601 }
@@ -698,7 +660,22 @@ export class LineCursor extends Marker {
698660 if ( event . type !== Blockly . Events . SELECTED ) return ;
699661 const selectedEvent = event as Blockly . Events . Selected ;
700662 if ( selectedEvent . workspaceId !== this . workspace . id ) return ;
701- this . getCurNode ( ) ;
663+ if ( selectedEvent . newElementId ) {
664+ const block = this . workspace . getBlockById ( selectedEvent . newElementId ) ;
665+ if ( block ) {
666+ const node = ASTNode . createBlockNode ( block ) ;
667+ if ( node ) {
668+ this . setCurNode ( node , true ) ;
669+ }
670+ }
671+ } else if (
672+ this . getCurNode ( ) ?. getType ( ) === ASTNode . types . BLOCK &&
673+ ! ( this . getCurNode ( ) . getLocation ( ) as Blockly . BlockSvg ) . isShadow ( )
674+ ) {
675+ // This does mean other cursor types remain if you click on the workspace
676+ // background. Ideally gesture would be handling this with more context.
677+ this . setCurNode ( null as never , true ) ;
678+ }
702679 }
703680}
704681
0 commit comments