Add duplicate selection functionality

This commit is contained in:
2026-04-05 04:23:19 +02:00
parent e7605511a3
commit fa440f2e33

View File

@@ -12,6 +12,7 @@ import {
import { createCreateBoxBrushCommand } from "../commands/create-box-brush-command";
import { createDeleteBoxBrushCommand } from "../commands/delete-box-brush-command";
import { createDeleteEntityCommand } from "../commands/delete-entity-command";
import { createDuplicateSelectionCommand } from "../commands/duplicate-selection-command";
import { createImportAudioAssetCommand } from "../commands/import-audio-asset-command";
import { createImportBackgroundImageAssetCommand } from "../commands/import-background-image-asset-command";
import { createImportModelAssetCommand } from "../commands/import-model-asset-command";
@@ -748,6 +749,21 @@ function isTextEntryTarget(target: EventTarget | null): boolean {
);
}
function selectionCanBeDuplicated(selection: EditorSelection): boolean {
switch (selection.kind) {
case "brushes":
case "entities":
case "modelInstances":
return selection.ids.length > 0;
case "brushFace":
case "brushEdge":
case "brushVertex":
return true;
case "none":
return false;
}
}
function isCommitIncrementKey(key: string): boolean {
return key === "ArrowUp" || key === "ArrowDown" || key === "PageUp" || key === "PageDown";
}
@@ -1589,6 +1605,7 @@ export function App({ store, initialStatusMessage }: AppProps) {
const isDeletionKey = event.key === "Delete" || event.key === "Backspace";
const isDeleteShortcut = !event.altKey && !event.ctrlKey && !event.metaKey && (event.code === "KeyX" || isDeletionKey);
const isDuplicateShortcut = event.shiftKey && !event.altKey && !event.ctrlKey && !event.metaKey && event.code === "KeyD";
if (addMenuPosition !== null) {
if (isDeletionKey) {
@@ -1597,6 +1614,16 @@ export function App({ store, initialStatusMessage }: AppProps) {
return;
}
if (isDuplicateShortcut) {
const duplicated = handleDuplicateSelection();
if (duplicated) {
event.preventDefault();
}
return;
}
if (isDeleteShortcut) {
if (editorState.toolMode !== "create") {
const deleted = handleDeleteSelectedSceneItem();
@@ -2776,6 +2803,21 @@ export function App({ store, initialStatusMessage }: AppProps) {
return false;
};
const handleDuplicateSelection = () => {
if (!selectionCanBeDuplicated(editorState.selection)) {
return false;
}
try {
store.executeCommand(createDuplicateSelectionCommand());
setStatusMessage("Duplicated selection.");
return true;
} catch (error) {
setStatusMessage(getErrorMessage(error));
return false;
}
};
const updateInteractionLinkTrigger = (link: InteractionLink, trigger: InteractionTriggerKind) => {
const sourceEntity = getInteractionSourceEntityForLink(link);