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
This commit is contained in:
Beka Westberg
2024-03-29 00:38:58 +00:00
committed by GitHub
parent 75fc4704da
commit da8a83b925
5 changed files with 38 additions and 49 deletions

View File

@@ -40,6 +40,7 @@ import * as comments from './comments.js';
import * as Css from './css.js'; import * as Css from './css.js';
import {DeleteArea} from './delete_area.js'; import {DeleteArea} from './delete_area.js';
import * as dialog from './dialog.js'; import * as dialog from './dialog.js';
import {Dragger} from './dragging/dragger.js';
import {DragTarget} from './drag_target.js'; import {DragTarget} from './drag_target.js';
import * as dropDownDiv from './dropdowndiv.js'; import * as dropDownDiv from './dropdowndiv.js';
import * as Events from './events/events.js'; import * as Events from './events/events.js';
@@ -466,6 +467,7 @@ export {ContextMenuRegistry};
export {comments}; export {comments};
export {Cursor}; export {Cursor};
export {DeleteArea}; export {DeleteArea};
export {Dragger};
export {DragTarget}; export {DragTarget};
export const DropDownDiv = dropDownDiv; export const DropDownDiv = dropDownDiv;
export {Field, FieldConfig, FieldValidator, UnattachedFieldError}; export {Field, FieldConfig, FieldValidator, UnattachedFieldError};

View File

@@ -12,6 +12,7 @@ import {Coordinate} from '../utils/coordinate.js';
import {WorkspaceSvg} from '../workspace_svg.js'; import {WorkspaceSvg} from '../workspace_svg.js';
import {ComponentManager} from '../component_manager.js'; import {ComponentManager} from '../component_manager.js';
import {IDeleteArea} from '../interfaces/i_delete_area.js'; import {IDeleteArea} from '../interfaces/i_delete_area.js';
import * as registry from '../registry.js';
export class Dragger implements IDragger { export class Dragger implements IDragger {
private startLoc: Coordinate; private startLoc: Coordinate;
@@ -137,3 +138,5 @@ export class Dragger implements IDragger {
return result; return result;
} }
} }
registry.register(registry.Type.DRAGGER, registry.DEFAULT, Dragger);

View File

@@ -28,7 +28,6 @@ import type {IBlockDragger} from './interfaces/i_block_dragger.js';
import type {IBubble} from './interfaces/i_bubble.js'; import type {IBubble} from './interfaces/i_bubble.js';
import type {IFlyout} from './interfaces/i_flyout.js'; import type {IFlyout} from './interfaces/i_flyout.js';
import * as internalConstants from './internal_constants.js'; import * as internalConstants from './internal_constants.js';
import * as registry from './registry.js';
import * as Tooltip from './tooltip.js'; import * as Tooltip from './tooltip.js';
import * as Touch from './touch.js'; import * as Touch from './touch.js';
import {Coordinate} from './utils/coordinate.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 {WorkspaceDragger} from './workspace_dragger.js';
import type {WorkspaceSvg} from './workspace_svg.js'; import type {WorkspaceSvg} from './workspace_svg.js';
import type {IIcon} from './interfaces/i_icon.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 * 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. */ /** The object tracking a bubble drag, or null if none is in progress. */
private bubbleDragger: BubbleDragger | null = null; private bubbleDragger: BubbleDragger | null = null;
/** The object tracking a block drag, or null if none is in progress. */ private dragger: IDragger | null = null;
private blockDragger: IBlockDragger | null = null;
/** /**
* The object tracking a workspace or flyout workspace drag, or null if none * The object tracking a workspace or flyout workspace drag, or null if none
@@ -212,9 +212,6 @@ export class Gesture {
} }
this.boundEvents.length = 0; this.boundEvents.length = 0;
if (this.blockDragger) {
this.blockDragger.dispose();
}
if (this.workspaceDragger) { if (this.workspaceDragger) {
this.workspaceDragger.dispose(); this.workspaceDragger.dispose();
} }
@@ -230,7 +227,7 @@ export class Gesture {
const changed = this.updateDragDelta(currentXY); const changed = this.updateDragDelta(currentXY);
// Exceeded the drag radius for the first time. // Exceeded the drag radius for the first time.
if (changed) { if (changed) {
this.updateIsDragging(); this.updateIsDragging(e);
Touch.longStop(); Touch.longStop();
} }
this.mostRecentEvent = e; this.mostRecentEvent = e;
@@ -334,17 +331,17 @@ export class Gesture {
* *
* @returns True if a block is being dragged. * @returns True if a block is being dragged.
*/ */
private updateIsDraggingBlock(): boolean { private updateIsDraggingBlock(e: PointerEvent): boolean {
if (!this.targetBlock) { if (!this.targetBlock) {
return false; return false;
} }
if (this.flyout) { if (this.flyout) {
if (this.updateIsDraggingFromFlyout()) { if (this.updateIsDraggingFromFlyout()) {
this.startDraggingBlock(); this.startDraggingBlock(e);
return true; return true;
} }
} else if (this.targetBlock.isMovable()) { } else if (this.targetBlock.isMovable()) {
this.startDraggingBlock(); this.startDraggingBlock(e);
return true; return true;
} }
return false; return false;
@@ -384,7 +381,7 @@ export class Gesture {
* the drag radius is exceeded. It should be called no more than once per * the drag radius is exceeded. It should be called no more than once per
* gesture. * gesture.
*/ */
private updateIsDragging() { private updateIsDragging(e: PointerEvent) {
// Sanity check. // Sanity check.
if (this.calledUpdateIsDragging) { if (this.calledUpdateIsDragging) {
throw Error('updateIsDragging_ should only be called once per gesture.'); throw Error('updateIsDragging_ should only be called once per gesture.');
@@ -397,7 +394,7 @@ export class Gesture {
return; return;
} }
// Then check if it was a block drag. // Then check if it was a block drag.
if (this.updateIsDraggingBlock()) { if (this.updateIsDraggingBlock(e)) {
return; return;
} }
// Then check if it's a workspace drag. // 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. */ /** Create a block dragger and start dragging the selected block. */
private startDraggingBlock() { private startDraggingBlock(e: PointerEvent) {
const BlockDraggerClass = registry.getClassFromOptions( this.dragging = true;
registry.Type.BLOCK_DRAGGER,
const DraggerClass = registry.getClassFromOptions(
registry.Type.DRAGGER,
this.creatorWorkspace.options, this.creatorWorkspace.options,
true, true,
); );
this.dragging = true; this.dragger = new DraggerClass!(this.targetBlock!, this.startWorkspace_!);
this.blockDragger = new BlockDraggerClass!( this.dragger.onDragStart(e);
this.targetBlock, this.dragger.onDrag(e, this.currentDragDeltaXY);
this.startWorkspace_,
);
this.blockDragger!.startDrag(this.currentDragDeltaXY, this.healStack);
this.blockDragger!.drag(this.mostRecentEvent, this.currentDragDeltaXY);
} }
/** Create a bubble dragger and start dragging the selected bubble. */ /** Create a bubble dragger and start dragging the selected bubble. */
@@ -587,8 +582,8 @@ export class Gesture {
this.updateFromEvent(e); this.updateFromEvent(e);
if (this.workspaceDragger) { if (this.workspaceDragger) {
this.workspaceDragger.drag(this.currentDragDeltaXY); this.workspaceDragger.drag(this.currentDragDeltaXY);
} else if (this.blockDragger) { } else if (this.dragger) {
this.blockDragger.drag(this.mostRecentEvent, this.currentDragDeltaXY); this.dragger.onDrag(this.mostRecentEvent, this.currentDragDeltaXY);
} else if (this.bubbleDragger) { } else if (this.bubbleDragger) {
this.bubbleDragger.dragBubble( this.bubbleDragger.dragBubble(
this.mostRecentEvent, this.mostRecentEvent,
@@ -631,8 +626,8 @@ export class Gesture {
// not matter, because the three types of dragging are exclusive. // not matter, because the three types of dragging are exclusive.
if (this.bubbleDragger) { if (this.bubbleDragger) {
this.bubbleDragger.endBubbleDrag(e, this.currentDragDeltaXY); this.bubbleDragger.endBubbleDrag(e, this.currentDragDeltaXY);
} else if (this.blockDragger) { } else if (this.dragger) {
this.blockDragger.endDrag(e, this.currentDragDeltaXY); this.dragger.onDragEnd(e, this.currentDragDeltaXY);
} else if (this.workspaceDragger) { } else if (this.workspaceDragger) {
this.workspaceDragger.endDrag(this.currentDragDeltaXY); this.workspaceDragger.endDrag(this.currentDragDeltaXY);
} else if (this.isBubbleClick()) { } else if (this.isBubbleClick()) {
@@ -797,8 +792,8 @@ export class Gesture {
this.mostRecentEvent, this.mostRecentEvent,
this.currentDragDeltaXY, this.currentDragDeltaXY,
); );
} else if (this.blockDragger) { } else if (this.dragger) {
this.blockDragger.endDrag(this.mostRecentEvent, this.currentDragDeltaXY); this.dragger.onDragEnd(this.mostRecentEvent, this.currentDragDeltaXY);
} else if (this.workspaceDragger) { } else if (this.workspaceDragger) {
this.workspaceDragger.endDrag(this.currentDragDeltaXY); this.workspaceDragger.endDrag(this.currentDragDeltaXY);
} }
@@ -1227,20 +1222,6 @@ export class Gesture {
return this.gestureHasStarted; 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 * Gets the current dragger if an item is being dragged. Null if nothing is
* being dragged. * being dragged.
@@ -1249,7 +1230,9 @@ export class Gesture {
* progress. * progress.
*/ */
getCurrentDragger(): WorkspaceDragger | BubbleDragger | IBlockDragger | null { 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;
} }
/** /**

View File

@@ -24,6 +24,7 @@ import type {ToolboxItem} from './toolbox/toolbox_item.js';
import type {IPaster} from './interfaces/i_paster.js'; import type {IPaster} from './interfaces/i_paster.js';
import type {ICopyData, ICopyable} from './interfaces/i_copyable.js'; import type {ICopyData, ICopyable} from './interfaces/i_copyable.js';
import type {IConnectionPreviewer} from './interfaces/i_connection_previewer.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 * 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<IBlockDragger>('blockDragger'); static BLOCK_DRAGGER = new Type<IBlockDragger>('blockDragger');
static DRAGGER = new Type<IDragger>('dragger');
/** @internal */ /** @internal */
static SERIALIZER = new Type<ISerializer>('serializer'); static SERIALIZER = new Type<ISerializer>('serializer');

View File

@@ -1264,12 +1264,10 @@ export class WorkspaceSvg extends Workspace implements IASTNodeLocationSvg {
blocks[i].queueRender(); blocks[i].queueRender();
} }
if (this.currentGesture_) { this.getTopBlocks()
const imList = this.currentGesture_.getInsertionMarkers(); .flatMap((block) => block.getDescendants(false))
for (let i = 0; i < imList.length; i++) { .filter((block) => block.isInsertionMarker())
imList[i].queueRender(); .forEach((block) => block.queueRender());
}
}
renderManagement renderManagement
.finishQueuedRenders() .finishQueuedRenders()