1
0
mirror of https://github.com/tobspr/shapez.io.git synced 2025-06-13 13:04:03 +00:00

Added clipboard copy and paste

Added copy selection to system clipboard.
Added paste blueprint from system clipboard.
This commit is contained in:
FatCatX 2021-05-05 01:26:58 -07:00
parent 7dfe867de5
commit 177f50bce8
4 changed files with 107 additions and 11 deletions

View File

@ -14,6 +14,13 @@ export class Blueprint {
this.entities = entities;
}
/**
* Returns array of entities
*/
getEntities() {
return this.entities;
}
/**
* Returns the layer of this blueprint
* @returns {Layer}

View File

@ -1,16 +1,21 @@
import { DrawParameters } from "../../../core/draw_parameters";
import { createLogger } from "../../../core/logging";
import { STOP_PROPAGATION } from "../../../core/signal";
import { TrackedState } from "../../../core/tracked_state";
import { makeDiv } from "../../../core/utils";
import { Vector } from "../../../core/vector";
import { SOUNDS } from "../../../platform/sound";
import { SerializerInternal } from "../../../savegame/serializer_internal";
import { T } from "../../../translations";
import { Blueprint } from "../../blueprint";
import { enumMouseButton } from "../../camera";
import { KEYMAPPINGS } from "../../key_action_mapper";
import { BaseHUDPart } from "../base_hud_part";
import { Entity } from "../../entity";
import { DynamicDomAttach } from "../dynamic_dom_attach";
const logger = createLogger("blueprint_placer");
export class HUDBlueprintPlacer extends BaseHUDPart {
createElements(parent) {
const blueprintCostShape = this.root.shapeDefinitionMgr.getShapeFromShortKey(
@ -48,6 +53,11 @@ export class HUDBlueprintPlacer extends BaseHUDPart {
this.domAttach = new DynamicDomAttach(this.root, this.costDisplayParent);
this.trackedCanAfford = new TrackedState(this.onCanAffordChanged, this);
this.serializer = new SerializerInternal();
// TODO: This probably belongs at a higher level
document.addEventListener("paste", this.pasteFromClipboard.bind(this));
}
abortPlacement() {
@ -98,7 +108,7 @@ export class HUDBlueprintPlacer extends BaseHUDPart {
}
/**
* mouse down pre handler
* Mouse down pre handler
* @param {Vector} pos
* @param {enumMouseButton} button
*/
@ -183,7 +193,6 @@ export class HUDBlueprintPlacer extends BaseHUDPart {
}
/**
*
* @param {DrawParameters} parameters
*/
draw(parameters) {
@ -201,4 +210,58 @@ export class HUDBlueprintPlacer extends BaseHUDPart {
const tile = worldPos.toTileSpace();
blueprint.draw(parameters, tile);
}
/**
* @param {ClipboardEvent} event
*/
pasteFromClipboard(event) {
const data = event.clipboardData.getData("Text");
if (!data) {
return;
}
let json;
try {
json = JSON.parse(data);
} catch (error) {
logger.error("Unable to parse clipboard data:", error.message);
return;
}
if (!verifyBlueprintData(json)) {
logger.error("Invalid clipboard data");
return;
}
logger.log("Paste blueprint from clipboard");
const entityArray = [];
for (let i = 0; i < json.length; ++i) {
const serializedEntity = json[i];
const result = this.serializer.deserializeEntity(this.root, serializedEntity);
if (typeof result == "string") {
logger.error(result);
return;
}
entityArray.push(result);
}
const newBP = new Blueprint(entityArray);
this.currentBlueprint.set(newBP);
}
}
/**
* Verify data is a valid serialized blueprint
* @param {Array<Entity>} data
*/
function verifyBlueprintData(data) {
if (typeof data != "object") {
return false;
}
if (!Array.isArray(data)) {
return false;
}
for (let i = 0; i < data.length; ++i) {
const value = data[i];
if (value.components == undefined || value.components.StaticMapEntity == undefined) {
return false;
}
}
return true;
}

View File

@ -15,6 +15,7 @@ import { KEYMAPPINGS } from "../../key_action_mapper";
import { THEME } from "../../theme";
import { enumHubGoalRewards } from "../../tutorial_goals";
import { Blueprint } from "../../blueprint";
import { SerializerInternal } from "../../../savegame/serializer_internal";
const logger = createLogger("hud/mass_selector");
@ -42,6 +43,11 @@ export class HUDMassSelector extends BaseHUDPart {
this.root.hud.signals.selectedPlacementBuildingChanged.add(this.clearSelection, this);
this.root.signals.editModeChanged.add(this.clearSelection, this);
this.serializer = new SerializerInternal();
// TODO: This probably belongs at a higher level
document.addEventListener("copy", this.copyToClipboard.bind(this));
}
/**
@ -202,6 +208,24 @@ export class HUDMassSelector extends BaseHUDPart {
}
}
/**
* @param {ClipboardEvent} event
*/
copyToClipboard(event) {
if (this.selectedUids.size == 0) {
return;
}
const entityUids = Array.from(this.selectedUids);
const blueprint = Blueprint.fromUids(this.root, entityUids);
const serializedBP = this.serializer.serializeEntityArray(blueprint.getEntities());
const json = JSON.stringify(serializedBP);
event.clipboardData.setData("text/plain", json);
event.preventDefault();
logger.log("Copied selection to clipboard");
}
/**
* mouse down pre handler
* @param {Vector} pos

View File

@ -25,21 +25,26 @@ export class SerializerInternal {
}
/**
*
* @param {GameRoot} root
* @param {Array<Entity>} array
* @returns {string|void}
*/
deserializeEntityArray(root, array) {
for (let i = 0; i < array.length; ++i) {
this.deserializeEntity(root, array[i]);
const serializedEntity = array[i];
const result = this.deserializeEntity(root, serializedEntity);
if (typeof result == "string") {
return result;
}
root.entityMgr.registerEntity(result, serializedEntity.uid);
root.map.placeStaticEntity(result);
}
}
/**
*
* @param {GameRoot} root
* @param {Entity} payload
* @returns {string|Entity}
*/
deserializeEntity(root, payload) {
const staticData = payload.components.StaticMapEntity;
@ -61,10 +66,9 @@ export class SerializerInternal {
entity.uid = payload.uid;
this.deserializeComponents(root, entity, payload.components);
const errorStatus = this.deserializeComponents(root, entity, payload.components);
root.entityMgr.registerEntity(entity, payload.uid);
root.map.placeStaticEntity(entity);
return errorStatus || entity;
}
/////// COMPONENTS ////
@ -89,9 +93,7 @@ export class SerializerInternal {
}
const errorStatus = entity.components[componentId].deserialize(data[componentId], root);
if (errorStatus) {
return errorStatus;
}
return errorStatus;
}
}
}