Add support for undoing duplication and deletion commands

This commit is contained in:
Ryan Huffman 2014-10-28 13:42:02 -07:00
parent 68f51d2484
commit 76c3e9f483
2 changed files with 92 additions and 17 deletions

View file

@ -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);

View file

@ -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,