8000 feat: have the gesture use a dragger for blocks by BeksOmega · Pull Request #7972 · google/blockly · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

feat: have the gesture use a dragger for blocks #7972

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Mar 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 34 additions & 1 deletion core/block_svg.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ import type {Input} from './inputs/input.js';
import type {IASTNodeLocationSvg} from './interfaces/i_ast_node_location_svg.js';
import type {IBoundedElement} from './interfaces/i_bounded_element.js';
import type {ICopyable} from './interfaces/i_copyable.js';
import type {IDraggable} from './interfaces/i_draggable.old.js';
import type {IDragStrategy, IDraggable} from './interfaces/i_draggable.js';
import {IIcon} from './interfaces/i_icon.js';
import * as internalConstants from './internal_constants.js';
import {ASTNode} from './keyboard_nav/ast_node.js';
Expand All @@ -60,6 +60,7 @@ import type {WorkspaceSvg} from './workspace_svg.js';
import * as renderManagement from './render_management.js';
import {IconType} from './icons/icon_types.js';
import {BlockCopyData, BlockPaster} from './clipboard/block_paster.js';
import {BlockDragStrategy} from './dragging/block_drag_strategy.js';

/**
* Class for a block's SVG representation.
Expand Down Expand Up @@ -154,6 +155,8 @@ export class BlockSvg
*/
relativeCoords = new Coordinate(0, 0);

private dragStrategy: IDragStrategy = new BlockDragStrategy(this);

/**
* @param workspace The block's workspace.
* @param prototypeName Name of the language object containing type-specific
Expand Down Expand Up @@ -1622,4 +1625,34 @@ export class BlockSvg
add,
);
}

/** Sets the drag strategy for this block. */
setDragStrategy(dragStrategy: IDragStrategy) {
this.dragStrategy = dragStrategy;
}

/** Returns whether this block is movable or not. */
override isMovable(): boolean {
return this.dragStrategy.isMovable();
}

/** Starts a drag on the block. */
startDrag(e?: PointerEvent): void {
this.dragStrategy.startDrag(e);
}

/** Drags the block to the given location. */
drag(newLoc: Coordinate, e?: PointerEvent): void {
this.dragStrategy.drag(newLoc, e);
}

/** Ends the drag on the block. */
endDrag(e?: PointerEvent): void {
this.dragStrategy.endDrag(e);
}

/** Moves the block back to where it was at the start of a drag. */
revertDrag(): void {
this.dragStrategy.revertDrag();
}
}
2 changes: 2 additions & 0 deletions core/blockly.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -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};
Expand Down
3 changes: 3 additions & 0 deletions core/dragging/block_drag_strategy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -390,6 +390,9 @@ export class BlockDragStrategy implements IDragStrategy {
);
}

this.startChildConn = null;
this.startParentConn = null;

this.connectionPreviewer!.hidePreview();
this.connectionCandidate = null;

Expand Down
3 changes: 3 additions & 0 deletions 10000 core/dragging/dragger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -137,3 +138,5 @@ export class Dragger implements IDragger {
return result;
}
}

registry.register(registry.Type.DRAGGER, registry.DEFAULT, Dragger);
69 changes: 26 additions & 43 deletions core/gesture.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,15 @@ 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';
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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -212,9 +212,6 @@ export class Gesture {
}
this.boundEvents.length = 0;

if (this.blockDragger) {
this.blockDragger.dispose();
}
if (this.workspaceDragger) {
this.workspaceDragger.dispose();
}
Expand All @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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.');
Expand All @@ -397,28 +394,26 @@ 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.
this.updateIsDraggingWorkspace();
}

/** 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. */
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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()) {
Expand Down Expand Up @@ -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);
}
Expand Down Expand Up @@ -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.
Expand All @@ -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;
}

/**
Expand Down
3 changes: 3 additions & 0 deletions core/registry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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');

Expand Down
10 changes: 4 additions & 6 deletions core/workspace_svg.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down
0