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:
parent
7dfe867de5
commit
177f50bce8
@ -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}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user