From 76c3e9f483aedc329bc493f114e104ff52d35022 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Tue, 28 Oct 2014 13:42:02 -0700 Subject: [PATCH] Add support for undoing duplication and deletion commands --- examples/libraries/entitySelectionTool.js | 27 +++++++- examples/newEditEntities.js | 82 ++++++++++++++++++----- 2 files changed, 92 insertions(+), 17 deletions(-) diff --git a/examples/libraries/entitySelectionTool.js b/examples/libraries/entitySelectionTool.js index c7cf678bde..e9d65eff1d 100644 --- a/examples/libraries/entitySelectionTool.js +++ b/examples/libraries/entitySelectionTool.js @@ -1137,6 +1137,7 @@ SelectionDisplay = (function () { var initialXZPick = null; var isConstrained = false; var startPosition = null; + var duplicatedEntityIDs = null; var translateXZTool = { mode: 'TRANSLATE_XZ', onBegin: function(event) { @@ -1151,10 +1152,17 @@ SelectionDisplay = (function () { // copy of the selected entities and move the _original_ entities, not // the new ones. if (event.isAlt) { + duplicatedEntityIDs = []; for (var otherEntityID in SelectionManager.savedProperties) { var properties = SelectionManager.savedProperties[otherEntityID]; var entityID = Entities.addEntity(properties); + duplicatedEntityIDs.push({ + entityID: entityID, + properties: properties, + }); } + } else { + duplicatedEntityIDs = null; } isConstrained = false; @@ -1222,9 +1230,26 @@ SelectionDisplay = (function () { mode: "TRANSLATE_UP_DOWN", onBegin: function(event) { SelectionManager.saveProperties(); + + // Duplicate entities if alt is pressed. This will make a + // copy of the selected entities and move the _original_ entities, not + // the new ones. + if (event.isAlt) { + duplicatedEntityIDs = []; + for (var otherEntityID in SelectionManager.savedProperties) { + var properties = SelectionManager.savedProperties[otherEntityID]; + var entityID = Entities.addEntity(properties); + duplicatedEntityIDs.push({ + entityID: entityID, + properties: properties, + }); + } + } else { + duplicatedEntityIDs = null; + } }, onEnd: function(event, reason) { - pushCommandForSelections(); + pushCommandForSelections(duplicatedEntityIDs); }, onMove: function(event) { pickRay = Camera.computePickRay(event.x, event.y); diff --git a/examples/newEditEntities.js b/examples/newEditEntities.js index c53e2e9f2e..d9b2f95b3d 100644 --- a/examples/newEditEntities.js +++ b/examples/newEditEntities.js @@ -606,14 +606,24 @@ function handeMenuEvent(menuItem) { } else if (menuItem == "Allow Select Large Models") { allowLargeModels = Menu.isOptionChecked("Allow Select Large Models"); } else if (menuItem == "Delete") { - if (entitySelected) { + if (SelectionManager.hasSelection()) { print(" Delete Entity.... selectedEntityID="+ selectedEntityID); + SelectionManager.saveProperties(); + var savedProperties = []; for (var i = 0; i < selectionManager.selections.length; i++) { - Entities.deleteEntity(selectionManager.selections[i]); + var entityID = SelectionManager.selections[i]; + var initialProperties = SelectionManager.savedProperties[entityID.id]; + SelectionManager.savedProperties[entityID.id]; + savedProperties.push({ + entityID: entityID, + properties: initialProperties + }); + Entities.deleteEntity(entityID); } + SelectionManager.clearSelections(); + pushCommandForSelections([], savedProperties); selectionDisplay.unselect(selectedEntityID); entitySelected = false; - selectionManager.clearSelections(); } else { print(" Delete Entity.... not holding..."); } @@ -623,15 +633,16 @@ function handeMenuEvent(menuItem) { editModelID = -1; if (selectionManager.selections.length == 1) { print(" Edit Properties.... selectedEntityID="+ selectedEntityID); - editModelID = selectedEntityID; + editModelID = selectionManager.selections[0]; } else { print(" Edit Properties.... not holding..."); } if (editModelID != -1) { print(" Edit Properties.... about to edit properties..."); entityPropertyDialogBox.openDialog(editModelID); + selectionManager._update(); } - + } else if (menuItem == "Paste Models") { modelImporter.paste(); } else if (menuItem == "Export Models") { @@ -720,25 +731,64 @@ Controller.keyReleaseEvent.connect(function (event) { } }); +// When an entity has been deleted we need a way to "undo" this deletion. Because it's not currently +// possible to create an entity with a specific id, earlier undo commands to the deleted entity +// will fail if there isn't a way to find the new entity id. +DELETED_ENTITY_MAP = { +} + function applyEntityProperties(data) { - for (var i = 0; i < data.length; i++) { - var entityID = data[i].entityID; - var properties = data[i].properties; - Entities.editEntity(entityID, properties); + var properties = data.setProperties; + var selectedEntityIDs = []; + for (var i = 0; i < properties.length; i++) { + var entityID = properties[i].entityID; + if (DELETED_ENTITY_MAP[entityID.id] !== undefined) { + entityID = DELETED_ENTITY_MAP[entityID.id]; + } + Entities.editEntity(entityID, properties[i].properties); + selectedEntityIDs.push(entityID); } - selectionManager._update(); + for (var i = 0; i < data.createEntities.length; i++) { + var entityID = data.createEntities[i].entityID; + var properties = data.createEntities[i].properties; + var newEntityID = Entities.addEntity(properties); + DELETED_ENTITY_MAP[entityID.id] = newEntityID; + print(newEntityID.isKnownID); + if (data.selectCreated) { + selectedEntityIDs.push(newEntityID); + } + } + for (var i = 0; i < data.deleteEntities.length; i++) { + var entityID = data.deleteEntities[i].entityID; + if (DELETED_ENTITY_MAP[entityID.id] !== undefined) { + entityID = DELETED_ENTITY_MAP[entityID.id]; + } + Entities.deleteEntity(entityID); + } + + selectionManager.setSelections(selectedEntityIDs); }; // For currently selected entities, push a command to the UndoStack that uses the current entity properties for the -// redo command, and the saved properties for the undo command. -function pushCommandForSelections() { - var undoData = []; - var redoData = []; +// redo command, and the saved properties for the undo command. Also, include create and delete entity data. +function pushCommandForSelections(createdEntityData, deletedEntityData) { + var undoData = { + setProperties: [], + createEntities: deletedEntityData || [], + deleteEntities: createdEntityData || [], + selectCreated: true, + }; + var redoData = { + setProperties: [], + createEntities: createdEntityData || [], + deleteEntities: deletedEntityData || [], + selectCreated: false, + }; for (var i = 0; i < SelectionManager.selections.length; i++) { var entityID = SelectionManager.selections[i]; var initialProperties = SelectionManager.savedProperties[entityID.id]; var currentProperties = Entities.getEntityProperties(entityID); - undoData.push({ + undoData.setProperties.push({ entityID: entityID, properties: { position: initialProperties.position, @@ -746,7 +796,7 @@ function pushCommandForSelections() { dimensions: initialProperties.dimensions, }, }); - redoData.push({ + redoData.setProperties.push({ entityID: entityID, properties: { position: currentProperties.position,