feat: Paste block in viewport / near cursor (#7521)

* fix: Paste block in viewport / near cursor

* Fix: formatting fix with prettier

* fix import path for Coordinate

* fix import path for coordinate

* paste so that the block's center is at the viewport center
This commit is contained in:
Sampada Bhujel
2023-09-22 18:32:00 -04:00
committed by GitHub
parent 4437fdb089
commit c37f4b8749
2 changed files with 41 additions and 2 deletions

View File

@@ -4,6 +4,8 @@
* SPDX-License-Identifier: Apache-2.0
*/
import {Coordinate} from '../utils/coordinate.js';
// Former goog.module ID: Blockly.IMovable
/**
@@ -16,4 +18,12 @@ export interface IMovable {
* @returns True if movable.
*/
isMovable(): boolean;
/**
* Return the coordinates of the top-left corner of this movable object
* relative to the drawing surface's origin (0,0), in workspace units.
*
* @returns Object with .x and .y properties.
*/
getRelativeToSurfaceXY(): Coordinate;
}

View File

@@ -12,6 +12,7 @@ import * as common from './common.js';
import {Gesture} from './gesture.js';
import {ICopyData, isCopyable} from './interfaces/i_copyable.js';
import {KeyboardShortcut, ShortcutRegistry} from './shortcut_registry.js';
import {Coordinate} from './utils/coordinate.js';
import {KeyCodes} from './utils/keycodes.js';
import type {WorkspaceSvg} from './workspace_svg.js';
@@ -79,6 +80,7 @@ export function registerDelete() {
let copyData: ICopyData | null = null;
let copyWorkspace: WorkspaceSvg | null = null;
let copyCoords: Coordinate | null = null;
/**
* Keyboard shortcut to copy a block on ctrl+c, cmd+c, or alt+c.
@@ -115,6 +117,7 @@ export function registerCopy() {
const selected = common.getSelected();
if (!selected || !isCopyable(selected)) return false;
copyData = selected.toCopyData();
copyCoords = selected.getRelativeToSurfaceXY();
copyWorkspace = workspace;
return !!copyData;
},
@@ -155,6 +158,7 @@ export function registerCut() {
const selected = common.getSelected();
if (!selected || !isCopyable(selected)) return false;
copyData = selected.toCopyData();
copyCoords = selected.getRelativeToSurfaceXY();
copyWorkspace = workspace;
(selected as BlockSvg).checkAndDelete();
return true;
@@ -185,8 +189,33 @@ export function registerPaste() {
return !workspace.options.readOnly && !Gesture.inProgress();
},
callback() {
if (!copyData || !copyWorkspace) return false;
return !!clipboard.paste(copyData, copyWorkspace);
if (!copyData || !copyCoords || !copyWorkspace) return false;
const {
left: viewportLeft,
top: viewportTop,
width: viewportWidth,
height: viewportHeight,
} = copyWorkspace.getMetricsManager().getViewMetrics(true);
const selected = common.getSelected() as BlockSvg;
// Pass the default copy coordinates when
// default location is inside viewport.
if (
copyCoords.x >= viewportLeft &&
copyCoords.x + selected.width <= viewportLeft + viewportWidth &&
copyCoords.y >= viewportTop &&
copyCoords.y + selected.height <= viewportTop + viewportHeight
) {
return !!clipboard.paste(copyData, copyWorkspace, copyCoords);
} else {
// Pass the center of the new viewport
// to paste the copied block
const centerCoords = new Coordinate(
viewportLeft + Math.trunc(viewportWidth / 2 - selected.width / 2),
viewportTop + Math.trunc(viewportHeight / 2 - selected.height / 2),
);
return !!clipboard.paste(copyData, copyWorkspace, centerCoords);
}
},
keyCodes: [ctrlV, altV, metaV],
};