mirror of
https://github.com/google/blockly.git
synced 2026-01-07 00:50:27 +01:00
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:
@@ -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};
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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<IBlockDragger>('blockDragger');
|
||||
|
||||
static DRAGGER = new Type<IDragger>('dragger');
|
||||
|
||||
/** @internal */
|
||||
static SERIALIZER = new Type<ISerializer>('serializer');
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
Reference in New Issue
Block a user