More work on Undo/Redo

This commit is contained in:
Atlante45 2014-04-07 17:10:15 -07:00
parent d7b3c8b8fa
commit d213cd7840
8 changed files with 190 additions and 21 deletions

View file

@ -911,7 +911,6 @@ function mousePressEvent(event) {
}
voxelDetails = calculateVoxelFromIntersection(intersection,"add");
Voxels.eraseVoxel(voxelDetails.x, voxelDetails.y, voxelDetails.z, voxelDetails.s);
Voxels.setVoxel(voxelDetails.x, voxelDetails.y, voxelDetails.z, voxelDetails.s,
newColor.red, newColor.green, newColor.blue);
lastVoxelPosition = { x: voxelDetails.x, y: voxelDetails.y, z: voxelDetails.z };

View file

@ -3274,6 +3274,7 @@ void Application::loadScript(const QString& scriptName) {
// we can use the same ones from the application.
scriptEngine->getVoxelsScriptingInterface()->setPacketSender(&_voxelEditSender);
scriptEngine->getVoxelsScriptingInterface()->setVoxelTree(_voxels.getTree());
scriptEngine->getVoxelsScriptingInterface()->setUndoStack(&_undoStack);
scriptEngine->getParticlesScriptingInterface()->setPacketSender(&_particleEditSender);
scriptEngine->getParticlesScriptingInterface()->setParticleTree(_particles.getTree());

View file

@ -161,14 +161,15 @@ Menu::Menu() :
QMenu* editMenu = addMenu("Edit");
QUndoStack* undoStack = Application::getInstance()->getUndoStack();
QAction* undoAction = undoStack->createUndoAction(editMenu);
undoAction->setShortcut(Qt::CTRL | Qt::Key_Z);
addActionToQMenuAndActionHash(editMenu, undoAction);
QAction* redoAction = undoStack->createRedoAction(editMenu);
addActionToQMenuAndActionHash(editMenu,
undoAction);
addActionToQMenuAndActionHash(editMenu,
redoAction);
redoAction->setShortcut(Qt::CTRL | Qt::SHIFT | Qt::Key_Z);
addActionToQMenuAndActionHash(editMenu, redoAction);
addActionToQMenuAndActionHash(editMenu,
MenuOption::Preferences,

View file

@ -1,4 +1,4 @@
//
//
// VoxelTree.h
// hifi
//
@ -14,6 +14,7 @@
#include "VoxelTreeElement.h"
#include "VoxelEditPacketSender.h"
class QUndoStack;
class ReadCodeColorBufferToTreeArgs;
class VoxelTree : public Octree {
@ -44,6 +45,8 @@ public:
virtual bool handlesEditPacketType(PacketType packetType) const;
virtual int processEditPacketData(PacketType packetType, const unsigned char* packetData, int packetLength,
const unsigned char* editData, int maxLength, const SharedNodePointer& node);
void setUndoStack(QUndoStack* undoStack) { _undoStack = undoStack; }
private:
// helper functions for nudgeSubTree
@ -52,6 +55,8 @@ private:
void nudgeLeaf(VoxelTreeElement* element, void* extraData);
void chunkifyLeaf(VoxelTreeElement* element);
void readCodeColorBufferToTreeRecursion(VoxelTreeElement* node, ReadCodeColorBufferToTreeArgs& args);
QUndoStack* _undoStack;
};
#endif /* defined(__hifi__VoxelTree__) */

View file

@ -0,0 +1,64 @@
//
// VoxelTreeCommands.cpp
// hifi
//
// Created by Clement on 4/4/14.
// Copyright (c) 2013 High Fidelity, Inc. All rights reserved.
//
//
#include "VoxelTree.h"
#include "VoxelTreeCommands.h"
AddVoxelCommand::AddVoxelCommand(VoxelTree* tree, VoxelDetail& voxel, VoxelEditPacketSender* packetSender, QUndoCommand* parent) :
QUndoCommand("Add Voxel", parent),
_tree(tree),
_packetSender(packetSender),
_voxel(voxel)
{
}
void AddVoxelCommand::redo() {
if (_tree) {
_tree->createVoxel(_voxel.x, _voxel.y, _voxel.z, _voxel.s, _voxel.red, _voxel.green, _voxel.blue);
}
if (_packetSender) {
_packetSender->queueVoxelEditMessages(PacketTypeVoxelSet, 1, &_voxel);
}
}
void AddVoxelCommand::undo() {
if (_tree) {
_tree->deleteVoxelAt(_voxel.x, _voxel.y, _voxel.z, _voxel.s);
}
if (_packetSender) {
_packetSender->queueVoxelEditMessages(PacketTypeVoxelErase, 1, &_voxel);
}
}
DeleteVoxelCommand::DeleteVoxelCommand(VoxelTree* tree, VoxelDetail& voxel, VoxelEditPacketSender* packetSender, QUndoCommand* parent) :
QUndoCommand("Delete Voxel", parent),
_tree(tree),
_packetSender(packetSender),
_voxel(voxel)
{
}
void DeleteVoxelCommand::redo() {
if (_tree) {
_tree->deleteVoxelAt(_voxel.x, _voxel.y, _voxel.z, _voxel.s);
}
if (_packetSender) {
_packetSender->queueVoxelEditMessages(PacketTypeVoxelErase, 1, &_voxel);
}
}
void DeleteVoxelCommand::undo() {
if (_tree) {
_tree->createVoxel(_voxel.x, _voxel.y, _voxel.z, _voxel.s, _voxel.red, _voxel.green, _voxel.blue);
}
if (_packetSender) {
_packetSender->queueVoxelEditMessages(PacketTypeVoxelSet, 1, &_voxel);
}
}

View file

@ -0,0 +1,46 @@
//
// VoxelTreeCommands.h
// hifi
//
// Created by Clement on 4/4/14.
// Copyright (c) 2013 High Fidelity, Inc. All rights reserved.
//
#ifndef __hifi__VoxelTreeCommands__
#define __hifi__VoxelTreeCommands__
#include <QRgb>
#include <QUndoCommand>
#include "VoxelDetail.h"
#include "VoxelEditPacketSender.h"
class VoxelTree;
class AddVoxelCommand : public QUndoCommand {
public:
AddVoxelCommand(VoxelTree* tree, VoxelDetail& voxel, VoxelEditPacketSender* packetSender = NULL, QUndoCommand* parent = NULL);
virtual void redo();
virtual void undo();
private:
VoxelTree* _tree;
VoxelEditPacketSender* _packetSender;
VoxelDetail _voxel;
};
class DeleteVoxelCommand : public QUndoCommand {
public:
DeleteVoxelCommand(VoxelTree* tree, VoxelDetail& voxel, VoxelEditPacketSender* packetSender = NULL, QUndoCommand* parent = NULL);
virtual void redo();
virtual void undo();
private:
VoxelTree* _tree;
VoxelEditPacketSender* _packetSender;
VoxelDetail _voxel;
};
#endif /* defined(__hifi__VoxelTreeCommands__) */

View file

@ -6,6 +6,8 @@
// Copyright (c) 2013 HighFidelity, Inc. All rights reserved.
//
#include "VoxelTreeCommands.h"
#include "VoxelsScriptingInterface.h"
void VoxelsScriptingInterface::queueVoxelAdd(PacketType addPacketType, VoxelDetail& addVoxelDetails) {
@ -37,17 +39,24 @@ VoxelDetail VoxelsScriptingInterface::getVoxelAt(float x, float y, float z, floa
}
void VoxelsScriptingInterface::setVoxelNonDestructive(float x, float y, float z, float scale,
uchar red, uchar green, uchar blue) {
uchar red, uchar green, uchar blue) {
// setup a VoxelDetail struct with the data
VoxelDetail addVoxelDetail = {x / (float)TREE_SCALE, y / (float)TREE_SCALE, z / (float)TREE_SCALE,
VoxelDetail addVoxelDetail = {x / (float)TREE_SCALE, y / (float)TREE_SCALE, z / (float)TREE_SCALE,
scale / (float)TREE_SCALE, red, green, blue};
// queue the add packet
queueVoxelAdd(PacketTypeVoxelSet, addVoxelDetail);
// handle the local tree also...
if (_tree) {
_tree->createVoxel(addVoxelDetail.x, addVoxelDetail.y, addVoxelDetail.z, addVoxelDetail.s, red, green, blue, false);
if (_undoStack) {
AddVoxelCommand* command = new AddVoxelCommand(_tree,
addVoxelDetail,
getVoxelPacketSender());
_undoStack->push(command);
} else {
// queue the add packet
queueVoxelAdd(PacketTypeVoxelSet, addVoxelDetail);
_tree->createVoxel(addVoxelDetail.x, addVoxelDetail.y, addVoxelDetail.z, addVoxelDetail.s, red, green, blue, false);
}
}
}
@ -57,26 +66,68 @@ void VoxelsScriptingInterface::setVoxel(float x, float y, float z, float scale,
VoxelDetail addVoxelDetail = {x / (float)TREE_SCALE, y / (float)TREE_SCALE, z / (float)TREE_SCALE,
scale / (float)TREE_SCALE, red, green, blue};
// queue the destructive add
queueVoxelAdd(PacketTypeVoxelSetDestructive, addVoxelDetail);
// handle the local tree also...
if (_tree) {
_tree->createVoxel(addVoxelDetail.x, addVoxelDetail.y, addVoxelDetail.z, addVoxelDetail.s, red, green, blue, true);
if (_undoStack) {
AddVoxelCommand* addCommand = new AddVoxelCommand(_tree,
addVoxelDetail,
getVoxelPacketSender());
VoxelTreeElement* deleteVoxelElement = _tree->getVoxelAt(addVoxelDetail.x, addVoxelDetail.y, addVoxelDetail.z, addVoxelDetail.s);
if (deleteVoxelElement) {
nodeColor color;
memcpy(&color, &deleteVoxelElement->getColor(), sizeof(nodeColor));
VoxelDetail deleteVoxelDetail = {addVoxelDetail.x,
addVoxelDetail.y,
addVoxelDetail.z,
addVoxelDetail.s,
color[0],
color[1],
color[2]};
DeleteVoxelCommand* delCommand = new DeleteVoxelCommand(_tree,
deleteVoxelDetail,
getVoxelPacketSender());
_undoStack->beginMacro(addCommand->text());
qDebug() << "Macro";
_undoStack->push(delCommand);
_undoStack->push(addCommand);
_undoStack->endMacro();
} else {
_undoStack->push(addCommand);
}
} else {
// queue the destructive add
queueVoxelAdd(PacketTypeVoxelSetDestructive, addVoxelDetail);
_tree->createVoxel(addVoxelDetail.x, addVoxelDetail.y, addVoxelDetail.z, addVoxelDetail.s, red, green, blue, true);
}
}
}
void VoxelsScriptingInterface::eraseVoxel(float x, float y, float z, float scale) {
// setup a VoxelDetail struct with data
VoxelDetail deleteVoxelDetail = {x / (float)TREE_SCALE, y / (float)TREE_SCALE, z / (float)TREE_SCALE,
scale / (float)TREE_SCALE, 0, 0, 0};
VoxelDetail deleteVoxelDetail = {x / (float)TREE_SCALE, y / (float)TREE_SCALE, z / (float)TREE_SCALE,
scale / (float)TREE_SCALE};
getVoxelPacketSender()->queueVoxelEditMessages(PacketTypeVoxelErase, 1, &deleteVoxelDetail);
// handle the local tree also...
if (_tree) {
_tree->deleteVoxelAt(deleteVoxelDetail.x, deleteVoxelDetail.y, deleteVoxelDetail.z, deleteVoxelDetail.s);
VoxelTreeElement* deleteVoxelElement = _tree->getVoxelAt(deleteVoxelDetail.x, deleteVoxelDetail.y, deleteVoxelDetail.z, deleteVoxelDetail.s);
if (deleteVoxelElement) {
deleteVoxelDetail.red = deleteVoxelElement->getColor()[0];
deleteVoxelDetail.green = deleteVoxelElement->getColor()[1];
deleteVoxelDetail.blue = deleteVoxelElement->getColor()[2];
}
if (_undoStack) {
DeleteVoxelCommand* command = new DeleteVoxelCommand(_tree,
deleteVoxelDetail,
getVoxelPacketSender());
_undoStack->push(command);
} else {
getVoxelPacketSender()->queueVoxelEditMessages(PacketTypeVoxelErase, 1, &deleteVoxelDetail);
_tree->deleteVoxelAt(deleteVoxelDetail.x, deleteVoxelDetail.y, deleteVoxelDetail.z, deleteVoxelDetail.s);
}
}
}

View file

@ -22,12 +22,13 @@
class VoxelsScriptingInterface : public OctreeScriptingInterface {
Q_OBJECT
public:
VoxelsScriptingInterface() : _tree(NULL) {};
VoxelsScriptingInterface() : _tree(NULL), _undoStack(NULL) {};
VoxelEditPacketSender* getVoxelPacketSender() { return (VoxelEditPacketSender*)getPacketSender(); }
virtual NodeType_t getServerNodeType() const { return NodeType::VoxelServer; }
virtual OctreeEditPacketSender* createPacketSender() { return new VoxelEditPacketSender(); }
void setVoxelTree(VoxelTree* tree) { _tree = tree; }
void setUndoStack(QUndoStack* undoStack) { _undoStack = undoStack; }
public slots:
@ -79,6 +80,7 @@ public slots:
private:
void queueVoxelAdd(PacketType addPacketType, VoxelDetail& addVoxelDetails);
VoxelTree* _tree;
QUndoStack* _undoStack;
};
#endif /* defined(__hifi__VoxelsScriptingInterface__) */