Skip to content

Commit

Permalink
chore: merge develop into v11.0.0
Browse files Browse the repository at this point in the history
Merge pull request #7929 from BeksOmega/merge-dev-v11
  • Loading branch information
BeksOmega authored Mar 12, 2024
2 parents 30127db + cac6b64 commit 5d4e120
Show file tree
Hide file tree
Showing 6 changed files with 138 additions and 62 deletions.
2 changes: 2 additions & 0 deletions blocks/blocks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import type {BlockDefinition} from '../core/blocks.js';
export {
colour,
lists,
logic,
loops,
math,
procedures,
Expand All @@ -40,6 +41,7 @@ export const blocks: {[key: string]: BlockDefinition} = Object.assign(
loops.blocks,
math.blocks,
procedures.blocks,
texts.blocks,
variables.blocks,
variablesDynamic.blocks,
);
56 changes: 46 additions & 10 deletions core/block_dragger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,18 @@ export class BlockDragger implements IBlockDragger {

/** Whether the block would be deleted if dropped immediately. */
protected wouldDeleteBlock_ = false;

protected startXY_: Coordinate;

/** The parent block at the start of the drag. */
private startParentConn: RenderedConnection | null = null;

/**
* The child block at the start of the drag. Only gets set if
* `healStack` is true.
*/
private startChildConn: RenderedConnection | null = null;

/**
* @param block The block to drag.
* @param workspace The workspace to drag on.
Expand Down Expand Up @@ -126,6 +136,13 @@ export class BlockDragger implements IBlockDragger {
blockAnimation.disconnectUiStop();

if (this.shouldDisconnect_(healStack)) {
this.startParentConn =
this.draggingBlock_.outputConnection?.targetConnection ??
this.draggingBlock_.previousConnection?.targetConnection;
if (healStack) {
this.startChildConn =
this.draggingBlock_.nextConnection?.targetConnection;
}
this.disconnectBlock_(healStack, currentDragDeltaXY);
}
this.draggingBlock_.setDragging(true);
Expand Down Expand Up @@ -413,17 +430,10 @@ export class BlockDragger implements IBlockDragger {
.getLayerManager()
?.moveOffDragLayer(this.draggingBlock_, layers.BLOCK);
this.draggingBlock_.setDragging(false);
if (delta) {
// !preventMove
if (preventMove) {
this.moveToOriginalPosition();
} else if (delta) {
this.updateBlockAfterMove_();
} else {
// Blocks dragged directly from a flyout may need to be bumped into
// bounds.
bumpObjects.bumpIntoBounds(
this.draggingBlock_.workspace,
this.workspace_.getMetricsManager().getScrollMetrics(true),
this.draggingBlock_,
);
}
}
// Must dispose after `updateBlockAfterMove_` is called to not break the
Expand All @@ -434,6 +444,32 @@ export class BlockDragger implements IBlockDragger {
eventUtils.setGroup(false);
}

/**
* Moves the dragged block back to its original position before the start of
* the drag. Reconnects any parent and child blocks.
*/
private moveToOriginalPosition() {
this.startChildConn?.connect(this.draggingBlock_.nextConnection);
if (this.startParentConn) {
switch (this.startParentConn.type) {
case ConnectionType.INPUT_VALUE:
this.startParentConn.connect(this.draggingBlock_.outputConnection);
break;
case ConnectionType.NEXT_STATEMENT:
this.startParentConn.connect(this.draggingBlock_.previousConnection);
}
} else {
this.draggingBlock_.moveTo(this.startXY_, ['drag']);
// Blocks dragged directly from a flyout may need to be bumped into
// bounds.
bumpObjects.bumpIntoBounds(
this.draggingBlock_.workspace,
this.workspace_.getMetricsManager().getScrollMetrics(true),
this.draggingBlock_,
);
}
}

/**
* Calculates the drag delta and new location values after a block is dragged.
*
Expand Down
4 changes: 3 additions & 1 deletion core/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -282,7 +282,9 @@ export function defineBlocks(blocks: {[key: string]: BlockDefinition}) {
for (const type of Object.keys(blocks)) {
const definition = blocks[type];
if (type in Blocks) {
console.warn(`Block definiton "${type}" overwrites previous definition.`);
console.warn(
`Block definition "${type}" overwrites previous definition.`,
);
}
Blocks[type] = definition;
}
Expand Down
27 changes: 15 additions & 12 deletions core/grid.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,12 +66,26 @@ export class Grid {
this.update(this.scale);
}

/**
* Get the spacing of the grid points (in px).
*
* @returns The spacing of the grid points.
*/
getSpacing(): number {
return this.spacing;
}

/** Sets the length of the grid lines. */
setLength(length: number) {
this.length = length;
this.update(this.scale);
}

/** Get the length of the grid lines (in px). */
getLength(): number {
return this.length;
}

/**
* Sets whether blocks should snap to the grid or not.
*
Expand All @@ -85,25 +99,14 @@ export class Grid {
}

/**
* Whether blocks should snap to the grid, based on the initial configuration.
* Whether blocks should snap to the grid.
*
* @returns True if blocks should snap, false otherwise.
* @internal
*/
shouldSnap(): boolean {
return this.snapToGrid;
}

/**
* Get the spacing of the grid points (in px).
*
* @returns The spacing of the grid points.
* @internal
*/
getSpacing(): number {
return this.spacing;
}

/**
* Get the ID of the pattern element, which should be randomized to avoid
* conflicts with other Blockly instances on the page.
Expand Down
79 changes: 56 additions & 23 deletions core/insertion_marker_previewer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import * as blocks from './serialization/blocks.js';
import * as eventUtils from './events/utils.js';
import * as renderManagement from './render_management.js';
import * as registry from './registry.js';
import {Renderer as ZelosRenderer} from './renderers/zelos/renderer.js';
import {ConnectionType} from './connection_type.js';

/**
* An error message to throw if the block created by createMarkerBlock_ is
Expand Down Expand Up @@ -97,41 +99,72 @@ export class InsertionMarkerPreviewer implements IConnectionPreviewer {
throw Error(DUPLICATE_BLOCK_ERROR);
}

// Render disconnected from everything else so that we have a valid
// connection location.
marker.queueRender();
renderManagement.triggerQueuedRenders();

// Connect() also renders the insertion marker.
markerConn.connect(staticConn);

const originalOffsetToTarget = {
x: staticConn.x - markerConn.x,
y: staticConn.y - markerConn.y,
};
const originalOffsetInBlock = markerConn.getOffsetInBlock().clone();
renderManagement.finishQueuedRenders().then(() => {
// Position so that the existing block doesn't move.
marker?.positionNearConnection(
markerConn,
originalOffsetToTarget,
originalOffsetInBlock,
);
marker?.getSvgRoot().setAttribute('visibility', 'visible');
});
// TODO(7898): Instead of special casing, we should change the dragger to
// track the change in distance between the dragged connection and the
// static connection, so that it doesn't disconnect unless that
// (+ a bit) has been exceeded.
if (this.shouldUseMarkerPreview(draggedConn, staticConn)) {
this.markerConn = this.previewMarker(draggedConn, staticConn);
}

if (this.workspace.getRenderer().shouldHighlightConnection(staticConn)) {
staticConn.highlight();
}

this.markerConn = markerConn;
this.draggedConn = draggedConn;
this.staticConn = staticConn;
} finally {
eventUtils.enable();
}
}

private shouldUseMarkerPreview(
_draggedConn: RenderedConnection,
staticConn: RenderedConnection,
): boolean {
return (
staticConn.type === ConnectionType.PREVIOUS_STATEMENT ||
staticConn.type === ConnectionType.NEXT_STATEMENT ||
!(this.workspace.getRenderer() instanceof ZelosRenderer)
);
}

private previewMarker(
draggedConn: RenderedConnection,
staticConn: RenderedConnection,
): RenderedConnection {
const dragged = draggedConn.getSourceBlock();
const marker = this.createInsertionMarker(dragged);
const markerConn = this.getMatchingConnection(dragged, marker, draggedConn);
if (!markerConn) {
throw Error('Could not create insertion marker to preview connection');
}

// Render disconnected from everything else so that we have a valid
// connection location.
marker.queueRender();
renderManagement.triggerQueuedRenders();

// Connect() also renders the insertion marker.
markerConn.connect(staticConn);

const originalOffsetToTarget = {
x: staticConn.x - markerConn.x,
y: staticConn.y - markerConn.y,
};
const originalOffsetInBlock = markerConn.getOffsetInBlock().clone();
renderManagement.finishQueuedRenders().then(() => {
// Position so that the existing block doesn't move.
marker?.positionNearConnection(
markerConn,
originalOffsetToTarget,
originalOffsetInBlock,
);
marker?.getSvgRoot().setAttribute('visibility', 'visible');
});
return markerConn;
}

private createInsertionMarker(origBlock: BlockSvg) {
const blockJson = blocks.save(origBlock, {
addCoordinates: false,
Expand Down
32 changes: 16 additions & 16 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 5d4e120

Please sign in to comment.