From da8a83b9254910b5b82e2bf27dc60ff7305a489b Mon Sep 17 00:00:00 2001 From: Beka Westberg Date: Fri, 29 Mar 2024 00:38:58 +0000 Subject: [PATCH] feat: have the gesture use a dragger for blocks (#7972) * feat: have block use drag strategy * fix: gesture to use dragger for blocks * chore: register dragger * chore: remove getInsertionMarkers and pull logic into workspace --- core/blockly.ts | 2 ++ core/dragging/dragger.ts | 3 ++ core/gesture.ts | 69 +++++++++++++++------------------------- core/registry.ts | 3 ++ core/workspace_svg.ts | 10 +++--- 5 files changed, 38 insertions(+), 49 deletions(-) diff --git a/core/blockly.ts b/core/blockly.ts index 233fa31a7..dfcc6a1cb 100644 --- a/core/blockly.ts +++ b/core/blockly.ts @@ -40,6 +40,7 @@ import * as comments from './comments.js'; import * as Css from './css.js'; import {DeleteArea} from './delete_area.js'; import * as dialog from './dialog.js'; +import {Dragger} from './dragging/dragger.js'; import {DragTarget} from './drag_target.js'; import * as dropDownDiv from './dropdowndiv.js'; import * as Events from './events/events.js'; @@ -466,6 +467,7 @@ export {ContextMenuRegistry}; export {comments}; export {Cursor}; export {DeleteArea}; +export {Dragger}; export {DragTarget}; export const DropDownDiv = dropDownDiv; export {Field, FieldConfig, FieldValidator, UnattachedFieldError}; diff --git a/core/dragging/dragger.ts b/core/dragging/dragger.ts index d435e02bb..ded1dda10 100644 --- a/core/dragging/dragger.ts +++ b/core/dragging/dragger.ts @@ -12,6 +12,7 @@ import {Coordinate} from '../utils/coordinate.js'; import {WorkspaceSvg} from '../workspace_svg.js'; import {ComponentManager} from '../component_manager.js'; import {IDeleteArea} from '../interfaces/i_delete_area.js'; +import * as registry from '../registry.js'; export class Dragger implements IDragger { private startLoc: Coordinate; @@ -137,3 +138,5 @@ export class Dragger implements IDragger { return result; } } + +registry.register(registry.Type.DRAGGER, registry.DEFAULT, Dragger); diff --git a/core/gesture.ts b/core/gesture.ts index 2aed48d79..3ac499b32 100644 --- a/core/gesture.ts +++ b/core/gesture.ts @@ -28,7 +28,6 @@ import type {IBlockDragger} from './interfaces/i_block_dragger.js'; import type {IBubble} from './interfaces/i_bubble.js'; import type {IFlyout} from './interfaces/i_flyout.js'; import * as internalConstants from './internal_constants.js'; -import * as registry from './registry.js'; import * as Tooltip from './tooltip.js'; import * as Touch from './touch.js'; import {Coordinate} from './utils/coordinate.js'; @@ -36,6 +35,8 @@ import {WorkspaceCommentSvg} from './workspace_comment_svg.js'; import {WorkspaceDragger} from './workspace_dragger.js'; import type {WorkspaceSvg} from './workspace_svg.js'; import type {IIcon} from './interfaces/i_icon.js'; +import {IDragger} from './interfaces/i_dragger.js'; +import * as registry from './registry.js'; /** * Note: In this file "start" refers to pointerdown @@ -116,8 +117,7 @@ export class Gesture { /** The object tracking a bubble drag, or null if none is in progress. */ private bubbleDragger: BubbleDragger | null = null; - /** The object tracking a block drag, or null if none is in progress. */ - private blockDragger: IBlockDragger | null = null; + private dragger: IDragger | null = null; /** * The object tracking a workspace or flyout workspace drag, or null if none @@ -212,9 +212,6 @@ export class Gesture { } this.boundEvents.length = 0; - if (this.blockDragger) { - this.blockDragger.dispose(); - } if (this.workspaceDragger) { this.workspaceDragger.dispose(); } @@ -230,7 +227,7 @@ export class Gesture { const changed = this.updateDragDelta(currentXY); // Exceeded the drag radius for the first time. if (changed) { - this.updateIsDragging(); + this.updateIsDragging(e); Touch.longStop(); } this.mostRecentEvent = e; @@ -334,17 +331,17 @@ export class Gesture { * * @returns True if a block is being dragged. */ - private updateIsDraggingBlock(): boolean { + private updateIsDraggingBlock(e: PointerEvent): boolean { if (!this.targetBlock) { return false; } if (this.flyout) { if (this.updateIsDraggingFromFlyout()) { - this.startDraggingBlock(); + this.startDraggingBlock(e); return true; } } else if (this.targetBlock.isMovable()) { - this.startDraggingBlock(); + this.startDraggingBlock(e); return true; } return false; @@ -384,7 +381,7 @@ export class Gesture { * the drag radius is exceeded. It should be called no more than once per * gesture. */ - private updateIsDragging() { + private updateIsDragging(e: PointerEvent) { // Sanity check. if (this.calledUpdateIsDragging) { throw Error('updateIsDragging_ should only be called once per gesture.'); @@ -397,7 +394,7 @@ export class Gesture { return; } // Then check if it was a block drag. - if (this.updateIsDraggingBlock()) { + if (this.updateIsDraggingBlock(e)) { return; } // Then check if it's a workspace drag. @@ -405,20 +402,18 @@ export class Gesture { } /** Create a block dragger and start dragging the selected block. */ - private startDraggingBlock() { - const BlockDraggerClass = registry.getClassFromOptions( - registry.Type.BLOCK_DRAGGER, + private startDraggingBlock(e: PointerEvent) { + this.dragging = true; + + const DraggerClass = registry.getClassFromOptions( + registry.Type.DRAGGER, this.creatorWorkspace.options, true, ); - this.dragging = true; - this.blockDragger = new BlockDraggerClass!( - this.targetBlock, - this.startWorkspace_, - ); - this.blockDragger!.startDrag(this.currentDragDeltaXY, this.healStack); - this.blockDragger!.drag(this.mostRecentEvent, this.currentDragDeltaXY); + this.dragger = new DraggerClass!(this.targetBlock!, this.startWorkspace_!); + this.dragger.onDragStart(e); + this.dragger.onDrag(e, this.currentDragDeltaXY); } /** Create a bubble dragger and start dragging the selected bubble. */ @@ -587,8 +582,8 @@ export class Gesture { this.updateFromEvent(e); if (this.workspaceDragger) { this.workspaceDragger.drag(this.currentDragDeltaXY); - } else if (this.blockDragger) { - this.blockDragger.drag(this.mostRecentEvent, this.currentDragDeltaXY); + } else if (this.dragger) { + this.dragger.onDrag(this.mostRecentEvent, this.currentDragDeltaXY); } else if (this.bubbleDragger) { this.bubbleDragger.dragBubble( this.mostRecentEvent, @@ -631,8 +626,8 @@ export class Gesture { // not matter, because the three types of dragging are exclusive. if (this.bubbleDragger) { this.bubbleDragger.endBubbleDrag(e, this.currentDragDeltaXY); - } else if (this.blockDragger) { - this.blockDragger.endDrag(e, this.currentDragDeltaXY); + } else if (this.dragger) { + this.dragger.onDragEnd(e, this.currentDragDeltaXY); } else if (this.workspaceDragger) { this.workspaceDragger.endDrag(this.currentDragDeltaXY); } else if (this.isBubbleClick()) { @@ -797,8 +792,8 @@ export class Gesture { this.mostRecentEvent, this.currentDragDeltaXY, ); - } else if (this.blockDragger) { - this.blockDragger.endDrag(this.mostRecentEvent, this.currentDragDeltaXY); + } else if (this.dragger) { + this.dragger.onDragEnd(this.mostRecentEvent, this.currentDragDeltaXY); } else if (this.workspaceDragger) { this.workspaceDragger.endDrag(this.currentDragDeltaXY); } @@ -1227,20 +1222,6 @@ export class Gesture { return this.gestureHasStarted; } - /** - * Get a list of the insertion markers that currently exist. Block drags have - * 0, 1, or 2 insertion markers. - * - * @returns A possibly empty list of insertion marker blocks. - * @internal - */ - getInsertionMarkers(): BlockSvg[] { - if (this.blockDragger) { - return this.blockDragger.getInsertionMarkers(); - } - return []; - } - /** * Gets the current dragger if an item is being dragged. Null if nothing is * being dragged. @@ -1249,7 +1230,9 @@ export class Gesture { * progress. */ getCurrentDragger(): WorkspaceDragger | BubbleDragger | IBlockDragger | null { - return this.blockDragger ?? this.workspaceDragger ?? this.bubbleDragger; + // TODO: Change this to return the `dragger`, when we get rid of the last + // other dragger. + return this.workspaceDragger ?? this.bubbleDragger; } /** diff --git a/core/registry.ts b/core/registry.ts index 3645a6fdf..69b800504 100644 --- a/core/registry.ts +++ b/core/registry.ts @@ -24,6 +24,7 @@ import type {ToolboxItem} from './toolbox/toolbox_item.js'; import type {IPaster} from './interfaces/i_paster.js'; import type {ICopyData, ICopyable} from './interfaces/i_copyable.js'; import type {IConnectionPreviewer} from './interfaces/i_connection_previewer.js'; +import type {IDragger} from './interfaces/i_dragger.js'; /** * A map of maps. With the keys being the type and name of the class we are @@ -97,6 +98,8 @@ export class Type<_T> { static BLOCK_DRAGGER = new Type('blockDragger'); + static DRAGGER = new Type('dragger'); + /** @internal */ static SERIALIZER = new Type('serializer'); diff --git a/core/workspace_svg.ts b/core/workspace_svg.ts index 2d49485dd..c26aa61c5 100644 --- a/core/workspace_svg.ts +++ b/core/workspace_svg.ts @@ -1264,12 +1264,10 @@ export class WorkspaceSvg extends Workspace implements IASTNodeLocationSvg { blocks[i].queueRender(); } - if (this.currentGesture_) { - const imList = this.currentGesture_.getInsertionMarkers(); - for (let i = 0; i < imList.length; i++) { - imList[i].queueRender(); - } - } + this.getTopBlocks() + .flatMap((block) => block.getDescendants(false)) + .filter((block) => block.isInsertionMarker()) + .forEach((block) => block.queueRender()); renderManagement .finishQueuedRenders()