feat(editor): undoing movement/transformations
This commit is contained in:
parent
cef5db5b2d
commit
ed5aa597ad
3 changed files with 42 additions and 0 deletions
|
@ -117,4 +117,18 @@ void PartAssembly::Scale(Vector3 newSize, bool scaleUp) {
|
|||
}
|
||||
|
||||
_bounds = _bounds * factor;
|
||||
}
|
||||
|
||||
std::vector<PartTransformState> PartAssembly::GetCurrentTransforms() {
|
||||
std::vector<PartTransformState> transforms;
|
||||
|
||||
for (auto part : parts) {
|
||||
PartTransformState t;
|
||||
t.part = part;
|
||||
t.cframe = part->cframe;
|
||||
t.size = part->size;
|
||||
transforms.push_back(t);
|
||||
}
|
||||
|
||||
return transforms;
|
||||
}
|
|
@ -8,6 +8,12 @@ class Part;
|
|||
class Instance;
|
||||
class Selection;
|
||||
|
||||
struct PartTransformState {
|
||||
std::shared_ptr<Part> part;
|
||||
Vector3 size;
|
||||
CFrame cframe;
|
||||
};
|
||||
|
||||
class PartAssembly {
|
||||
CFrame _assemblyOrigin;
|
||||
Vector3 _bounds;
|
||||
|
@ -25,6 +31,9 @@ public:
|
|||
inline Vector3 size() { return _size; };
|
||||
inline bool multipleSelected() { return parts.size() > 1; }
|
||||
|
||||
// Gets the current transform state of all the parts in the assembly
|
||||
std::vector<PartTransformState> GetCurrentTransforms();
|
||||
|
||||
// Transforms the assembly such that newOrigin is now this assembly's new assemblyOrigin
|
||||
void SetOrigin(CFrame newOrigin);
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include "rendering/renderer.h"
|
||||
#include "rendering/shader.h"
|
||||
#include "datatypes/variant.h"
|
||||
#include "undohistory.h"
|
||||
|
||||
#define PI 3.14159
|
||||
#define M_mainWindow dynamic_cast<MainWindow*>(window())
|
||||
|
@ -120,6 +121,8 @@ CFrame snapCFrame(CFrame frame) {
|
|||
return CFrame(frame.Position(), frame.Position() + closestVec1, closestVec2);
|
||||
}
|
||||
|
||||
std::vector<PartTransformState> initialTransforms;
|
||||
|
||||
bool tryMouseContextMenu = false;
|
||||
bool isMouseDragging = false;
|
||||
std::weak_ptr<Part> draggingObject;
|
||||
|
@ -359,6 +362,7 @@ void MainGLWidget::mouseMoveEvent(QMouseEvent* evt) {
|
|||
}
|
||||
|
||||
void MainGLWidget::mousePressEvent(QMouseEvent* evt) {
|
||||
initialTransforms = {};
|
||||
tryMouseContextMenu = evt->button() == Qt::RightButton;
|
||||
switch(evt->button()) {
|
||||
// Camera drag
|
||||
|
@ -377,6 +381,8 @@ void MainGLWidget::mousePressEvent(QMouseEvent* evt) {
|
|||
startPoint = glm::vec2(evt->pos().x(), evt->pos().y());
|
||||
initialAssembly = PartAssembly::FromSelection(gDataModel->GetService<Selection>());
|
||||
initialFrame = initialAssembly.assemblyOrigin();
|
||||
initialTransforms = PartAssembly::FromSelection(gDataModel->GetService<Selection>()).GetCurrentTransforms();
|
||||
printf("%ld\n", initialTransforms.size());
|
||||
isMouseDragging = true;
|
||||
draggingHandle = handle;
|
||||
startLinearTransform(evt);
|
||||
|
@ -430,6 +436,7 @@ void MainGLWidget::mousePressEvent(QMouseEvent* evt) {
|
|||
//part.selected = true;
|
||||
isMouseDragging = true;
|
||||
draggingObject = part;
|
||||
initialTransforms = PartAssembly::FromSelection({part}).GetCurrentTransforms();
|
||||
if (evt->modifiers() & (Qt::ControlModifier | Qt::ShiftModifier)) {
|
||||
auto sel = selection->Get();
|
||||
if (std::find(sel.begin(), sel.end(), selObject) == sel.end())
|
||||
|
@ -455,6 +462,17 @@ void MainGLWidget::mouseReleaseEvent(QMouseEvent* evt) {
|
|||
draggingObject = {};
|
||||
draggingHandle = std::nullopt;
|
||||
|
||||
if (!initialTransforms.empty()) {
|
||||
UndoState historyState;
|
||||
|
||||
for (auto t : initialTransforms) {
|
||||
historyState.push_back(UndoStatePropertyChanged { t.part, "CFrame", t.cframe, t.part->cframe });
|
||||
historyState.push_back(UndoStatePropertyChanged { t.part, "Size", t.size, t.part->size });
|
||||
}
|
||||
|
||||
M_mainWindow->undoManager.PushState(historyState);
|
||||
}
|
||||
|
||||
// Open context menu
|
||||
if (tryMouseContextMenu)
|
||||
contextMenu.exec(QCursor::pos());
|
||||
|
@ -505,6 +523,7 @@ void MainGLWidget::keyPressEvent(QKeyEvent* evt) {
|
|||
}));
|
||||
gWorkspace()->SyncPartPhysics(lastPart);
|
||||
lastPart->name = "Part" + std::to_string(partId++);
|
||||
M_mainWindow->undoManager.PushState({ UndoStateInstanceCreated { lastPart, gWorkspace() } });
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue