mirror of
https://github.com/lubosz/overte.git
synced 2025-04-10 04:52:17 +02:00
Merge pull request #14027 from huffman/feat/deprecate-undo-stack
Remove UndoStack API
This commit is contained in:
commit
7c9464572a
6 changed files with 102 additions and 143 deletions
|
@ -976,7 +976,6 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
|
|||
_window(new MainWindow(desktop())),
|
||||
_sessionRunTimer(startupTimer),
|
||||
_previousSessionCrashed(setupEssentials(argc, argv, runningMarkerExisted)),
|
||||
_undoStackScriptingInterface(&_undoStack),
|
||||
_entitySimulation(new PhysicalEntitySimulation()),
|
||||
_physicsEngine(new PhysicsEngine(Vectors::ZERO)),
|
||||
_entityClipboard(new EntityTree()),
|
||||
|
@ -3095,7 +3094,6 @@ void Application::onDesktopRootContextCreated(QQmlContext* surfaceContext) {
|
|||
surfaceContext->setContextProperty("DialogsManager", _dialogsManagerScriptingInterface);
|
||||
surfaceContext->setContextProperty("FaceTracker", DependencyManager::get<DdeFaceTracker>().data());
|
||||
surfaceContext->setContextProperty("AvatarManager", DependencyManager::get<AvatarManager>().data());
|
||||
surfaceContext->setContextProperty("UndoStack", &_undoStackScriptingInterface);
|
||||
surfaceContext->setContextProperty("LODManager", DependencyManager::get<LODManager>().data());
|
||||
surfaceContext->setContextProperty("HMD", DependencyManager::get<HMDScriptingInterface>().data());
|
||||
surfaceContext->setContextProperty("Scene", DependencyManager::get<SceneScriptingInterface>().data());
|
||||
|
@ -6767,8 +6765,6 @@ void Application::registerScriptEngineWithApplicationServices(ScriptEnginePointe
|
|||
|
||||
scriptEngine->registerGlobalObject("AvatarManager", DependencyManager::get<AvatarManager>().data());
|
||||
|
||||
scriptEngine->registerGlobalObject("UndoStack", &_undoStackScriptingInterface);
|
||||
|
||||
scriptEngine->registerGlobalObject("LODManager", DependencyManager::get<LODManager>().data());
|
||||
|
||||
scriptEngine->registerGlobalObject("Paths", DependencyManager::get<PathUtils>().data());
|
||||
|
|
|
@ -23,7 +23,6 @@
|
|||
#include <QtGui/QImage>
|
||||
|
||||
#include <QtWidgets/QApplication>
|
||||
#include <QtWidgets/QUndoStack>
|
||||
|
||||
#include <ThreadHelpers.h>
|
||||
#include <AbstractScriptingServicesInterface.h>
|
||||
|
@ -70,7 +69,6 @@
|
|||
#include "ui/OctreeStatsDialog.h"
|
||||
#include "ui/OverlayConductor.h"
|
||||
#include "ui/overlays/Overlays.h"
|
||||
#include "UndoStackScriptingInterface.h"
|
||||
|
||||
#include "workload/GameWorkload.h"
|
||||
|
||||
|
@ -189,7 +187,6 @@ public:
|
|||
|
||||
const OctreePacketProcessor& getOctreePacketProcessor() const { return _octreeProcessor; }
|
||||
QSharedPointer<EntityTreeRenderer> getEntities() const { return DependencyManager::get<EntityTreeRenderer>(); }
|
||||
QUndoStack* getUndoStack() { return &_undoStack; }
|
||||
MainWindow* getWindow() const { return _window; }
|
||||
EntityTreePointer getEntityClipboard() const { return _entityClipboard; }
|
||||
EntityEditPacketSender* getEntityEditPacketSender() { return &_entityEditSender; }
|
||||
|
@ -571,9 +568,6 @@ private:
|
|||
|
||||
bool _activatingDisplayPlugin { false };
|
||||
|
||||
QUndoStack _undoStack;
|
||||
UndoStackScriptingInterface _undoStackScriptingInterface;
|
||||
|
||||
uint32_t _renderFrameCount { 0 };
|
||||
|
||||
// Frame Rate Measurement
|
||||
|
|
|
@ -90,19 +90,6 @@ Menu::Menu() {
|
|||
// Edit menu ----------------------------------
|
||||
MenuWrapper* editMenu = addMenu("Edit");
|
||||
|
||||
// Edit > Undo
|
||||
QUndoStack* undoStack = qApp->getUndoStack();
|
||||
QAction* undoAction = undoStack->createUndoAction(editMenu);
|
||||
undoAction->setShortcut(Qt::CTRL | Qt::Key_Z);
|
||||
addActionToQMenuAndActionHash(editMenu, undoAction);
|
||||
|
||||
// Edit > Redo
|
||||
QAction* redoAction = undoStack->createRedoAction(editMenu);
|
||||
redoAction->setShortcut(Qt::CTRL | Qt::SHIFT | Qt::Key_Z);
|
||||
addActionToQMenuAndActionHash(editMenu, redoAction);
|
||||
|
||||
editMenu->addSeparator();
|
||||
|
||||
// Edit > Cut
|
||||
auto cutAction = addActionToQMenuAndActionHash(editMenu, "Cut", QKeySequence::Cut);
|
||||
connect(cutAction, &QAction::triggered, [] {
|
||||
|
|
|
@ -1,66 +0,0 @@
|
|||
//
|
||||
// UndoStackScriptingInterface.cpp
|
||||
// libraries/script-engine/src
|
||||
//
|
||||
// Created by Ryan Huffman on 10/22/14.
|
||||
// Copyright 2014 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#include "UndoStackScriptingInterface.h"
|
||||
|
||||
#include <QDebug>
|
||||
#include <QScriptValue>
|
||||
#include <QScriptValueList>
|
||||
#include <QScriptEngine>
|
||||
|
||||
UndoStackScriptingInterface::UndoStackScriptingInterface(QUndoStack* undoStack) : _undoStack(undoStack) {
|
||||
}
|
||||
|
||||
void UndoStackScriptingInterface::pushCommand(QScriptValue undoFunction, QScriptValue undoData,
|
||||
QScriptValue redoFunction, QScriptValue redoData) {
|
||||
if (undoFunction.engine()) {
|
||||
ScriptUndoCommand* undoCommand = new ScriptUndoCommand(undoFunction, undoData, redoFunction, redoData);
|
||||
undoCommand->moveToThread(undoFunction.engine()->thread());
|
||||
_undoStack->push(undoCommand);
|
||||
}
|
||||
}
|
||||
|
||||
ScriptUndoCommand::ScriptUndoCommand(QScriptValue undoFunction, QScriptValue undoData,
|
||||
QScriptValue redoFunction, QScriptValue redoData) :
|
||||
_hasRedone(false),
|
||||
_undoFunction(undoFunction),
|
||||
_undoData(undoData),
|
||||
_redoFunction(redoFunction),
|
||||
_redoData(redoData) {
|
||||
}
|
||||
|
||||
void ScriptUndoCommand::undo() {
|
||||
QMetaObject::invokeMethod(this, "doUndo");
|
||||
}
|
||||
|
||||
void ScriptUndoCommand::redo() {
|
||||
// QUndoStack will call `redo()` when adding a command to the stack. This
|
||||
// makes it difficult to work with commands that span a period of time - for instance,
|
||||
// the entity duplicate + move command that duplicates an entity and then moves it.
|
||||
// A better implementation might be to properly implement `mergeWith()` and `id()`
|
||||
// so that the two actions in the example would be merged.
|
||||
if (_hasRedone) {
|
||||
QMetaObject::invokeMethod(this, "doRedo");
|
||||
}
|
||||
_hasRedone = true;
|
||||
}
|
||||
|
||||
void ScriptUndoCommand::doUndo() {
|
||||
QScriptValueList args;
|
||||
args << _undoData;
|
||||
_undoFunction.call(QScriptValue(), args);
|
||||
}
|
||||
|
||||
void ScriptUndoCommand::doRedo() {
|
||||
QScriptValueList args;
|
||||
args << _redoData;
|
||||
_redoFunction.call(QScriptValue(), args);
|
||||
}
|
|
@ -1,53 +0,0 @@
|
|||
//
|
||||
// UndoStackScriptingInterface.h
|
||||
// libraries/script-engine/src
|
||||
//
|
||||
// Created by Ryan Huffman on 10/22/14.
|
||||
// Copyright 2014 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#ifndef hifi_UndoStackScriptingInterface_h
|
||||
#define hifi_UndoStackScriptingInterface_h
|
||||
|
||||
#include <QUndoCommand>
|
||||
#include <QUndoStack>
|
||||
#include <QScriptValue>
|
||||
|
||||
class UndoStackScriptingInterface : public QObject {
|
||||
Q_OBJECT
|
||||
public:
|
||||
UndoStackScriptingInterface(QUndoStack* undoStack);
|
||||
|
||||
public slots:
|
||||
void pushCommand(QScriptValue undoFunction, QScriptValue undoData, QScriptValue redoFunction, QScriptValue redoData);
|
||||
|
||||
private:
|
||||
QUndoStack* _undoStack;
|
||||
};
|
||||
|
||||
class ScriptUndoCommand : public QObject, public QUndoCommand {
|
||||
Q_OBJECT
|
||||
public:
|
||||
ScriptUndoCommand(QScriptValue undoFunction, QScriptValue undoData, QScriptValue redoFunction, QScriptValue redoData);
|
||||
|
||||
virtual void undo() override;
|
||||
virtual void redo() override;
|
||||
virtual bool mergeWith(const QUndoCommand* command) override { return false; }
|
||||
virtual int id() const override { return -1; }
|
||||
|
||||
public slots:
|
||||
void doUndo();
|
||||
void doRedo();
|
||||
|
||||
private:
|
||||
bool _hasRedone;
|
||||
QScriptValue _undoFunction;
|
||||
QScriptValue _undoData;
|
||||
QScriptValue _redoFunction;
|
||||
QScriptValue _redoData;
|
||||
};
|
||||
|
||||
#endif // hifi_UndoStackScriptingInterface_h
|
|
@ -850,6 +850,7 @@ var toolBar = (function () {
|
|||
}));
|
||||
isActive = active;
|
||||
activeButton.editProperties({isActive: isActive});
|
||||
undoHistory.setEnabled(isActive);
|
||||
|
||||
var tablet = Tablet.getTablet("com.highfidelity.interface.tablet.system");
|
||||
|
||||
|
@ -1237,6 +1238,19 @@ var originalLightsArePickable = Entities.getLightsArePickable();
|
|||
|
||||
function setupModelMenus() {
|
||||
// adj our menuitems
|
||||
Menu.addMenuItem({
|
||||
menuName: "Edit",
|
||||
menuItemName: "Undo",
|
||||
shortcutKey: 'Ctrl+Z',
|
||||
position: 0,
|
||||
});
|
||||
Menu.addMenuItem({
|
||||
menuName: "Edit",
|
||||
menuItemName: "Redo",
|
||||
shortcutKey: 'Ctrl+Shift+Z',
|
||||
position: 1,
|
||||
});
|
||||
|
||||
Menu.addMenuItem({
|
||||
menuName: "Edit",
|
||||
menuItemName: "Entities",
|
||||
|
@ -1356,6 +1370,9 @@ function setupModelMenus() {
|
|||
setupModelMenus(); // do this when first running our script.
|
||||
|
||||
function cleanupModelMenus() {
|
||||
Menu.removeMenuItem("Edit", "Undo");
|
||||
Menu.removeMenuItem("Edit", "Redo");
|
||||
|
||||
Menu.removeSeparator("Edit", "Entities");
|
||||
if (modelMenuAddedDelete) {
|
||||
// delete our menuitems
|
||||
|
@ -1698,6 +1715,10 @@ function handeMenuEvent(menuItem) {
|
|||
Entities.setLightsArePickable(Menu.isOptionChecked("Allow Selecting of Lights"));
|
||||
} else if (menuItem === "Delete") {
|
||||
deleteSelectedEntities();
|
||||
} else if (menuItem === "Undo") {
|
||||
undoHistory.undo();
|
||||
} else if (menuItem === "Redo") {
|
||||
undoHistory.redo();
|
||||
} else if (menuItem === "Parent Entity to Last") {
|
||||
parentSelectedEntities();
|
||||
} else if (menuItem === "Unparent Entity") {
|
||||
|
@ -1924,6 +1945,86 @@ function recursiveAdd(newParentID, parentData) {
|
|||
}
|
||||
}
|
||||
|
||||
var UndoHistory = function(onUpdate) {
|
||||
this.history = [];
|
||||
// The current position is the index of the last executed action in the history array.
|
||||
//
|
||||
// -1 0 1 2 3 <- position
|
||||
// A B C D <- actions in history
|
||||
//
|
||||
// If our lastExecutedIndex is 1, the last executed action is B.
|
||||
// If we undo, we undo B (index 1). If we redo, we redo C (index 2).
|
||||
this.lastExecutedIndex = -1;
|
||||
this.enabled = true;
|
||||
this.onUpdate = onUpdate;
|
||||
};
|
||||
|
||||
UndoHistory.prototype.pushCommand = function(undoFn, undoArgs, redoFn, redoArgs) {
|
||||
if (!this.enabled) {
|
||||
return;
|
||||
}
|
||||
// Delete any history following the last executed action.
|
||||
this.history.splice(this.lastExecutedIndex + 1);
|
||||
this.history.push({
|
||||
undoFn: undoFn,
|
||||
undoArgs: undoArgs,
|
||||
redoFn: redoFn,
|
||||
redoArgs: redoArgs
|
||||
});
|
||||
this.lastExecutedIndex++;
|
||||
|
||||
if (this.onUpdate) {
|
||||
this.onUpdate();
|
||||
}
|
||||
};
|
||||
UndoHistory.prototype.setEnabled = function(enabled) {
|
||||
this.enabled = enabled;
|
||||
if (this.onUpdate) {
|
||||
this.onUpdate();
|
||||
}
|
||||
};
|
||||
UndoHistory.prototype.canUndo = function() {
|
||||
return this.enabled && this.lastExecutedIndex >= 0;
|
||||
};
|
||||
UndoHistory.prototype.canRedo = function() {
|
||||
return this.enabled && this.lastExecutedIndex < this.history.length - 1;
|
||||
};
|
||||
UndoHistory.prototype.undo = function() {
|
||||
if (!this.canUndo()) {
|
||||
console.warn("Cannot undo action");
|
||||
return;
|
||||
}
|
||||
|
||||
var command = this.history[this.lastExecutedIndex];
|
||||
command.undoFn(command.undoArgs);
|
||||
this.lastExecutedIndex--;
|
||||
|
||||
if (this.onUpdate) {
|
||||
this.onUpdate();
|
||||
}
|
||||
};
|
||||
UndoHistory.prototype.redo = function() {
|
||||
if (!this.canRedo()) {
|
||||
console.warn("Cannot redo action");
|
||||
return;
|
||||
}
|
||||
|
||||
var command = this.history[this.lastExecutedIndex + 1];
|
||||
command.redoFn(command.redoArgs);
|
||||
this.lastExecutedIndex++;
|
||||
|
||||
if (this.onUpdate) {
|
||||
this.onUpdate();
|
||||
}
|
||||
};
|
||||
|
||||
function updateUndoRedoMenuItems() {
|
||||
Menu.setMenuEnabled("Edit > Undo", undoHistory.canUndo());
|
||||
Menu.setMenuEnabled("Edit > Redo", undoHistory.canRedo());
|
||||
}
|
||||
var undoHistory = new UndoHistory(updateUndoRedoMenuItems);
|
||||
updateUndoRedoMenuItems();
|
||||
|
||||
// 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.
|
||||
|
@ -2011,7 +2112,7 @@ function pushCommandForSelections(createdEntityData, deletedEntityData, doNotSav
|
|||
properties: currentProperties
|
||||
});
|
||||
}
|
||||
UndoStack.pushCommand(applyEntityProperties, undoData, applyEntityProperties, redoData);
|
||||
undoHistory.pushCommand(applyEntityProperties, undoData, applyEntityProperties, redoData);
|
||||
}
|
||||
|
||||
var ServerScriptStatusMonitor = function(entityID, statusCallback) {
|
||||
|
|
Loading…
Reference in a new issue