diff --git a/GUI/View/SampleDesigner/LayerOrientedSampleEditor.cpp b/GUI/View/SampleDesigner/LayerOrientedSampleEditor.cpp index f0ff3815badad632c89f277696c971d0e74a6c31..a58651ecf0a019a530f5f9411559e0abfdaafac8 100644 --- a/GUI/View/SampleDesigner/LayerOrientedSampleEditor.cpp +++ b/GUI/View/SampleDesigner/LayerOrientedSampleEditor.cpp @@ -141,7 +141,11 @@ void LayerOrientedSampleEditor::setCurrentSample(MultiLayerItem* multiLayerItem) void LayerOrientedSampleEditor::updateActionEnabling() { - // #baLayerEditor implement updateActionEnabling() + // Undo/Redo is not complete => hide the related buttons/actions + if (m_undoAction) + m_undoAction->setVisible(false); + if (m_redoAction) + m_redoAction->setVisible(false); } void LayerOrientedSampleEditor::onShowInlineEditButtonsToggled(bool checked) diff --git a/GUI/View/SampleDesigner/SampleEditorCommands.cpp b/GUI/View/SampleDesigner/SampleEditorCommands.cpp index b85665bd730119566398f1bbfc231fc2db350867..d8a0b0c7836af51828adb9dd3f23008fbb614ad1 100644 --- a/GUI/View/SampleDesigner/SampleEditorCommands.cpp +++ b/GUI/View/SampleDesigner/SampleEditorCommands.cpp @@ -23,29 +23,6 @@ namespace { constexpr int COMMAND_ID_CHANGE_VALUE = 11; -constexpr auto TagBackup = "backup"; - -template <typename ItemType> -QByteArray serialize(ItemType& t) -{ - QByteArray a; - QXmlStreamWriter w(&a); - w.writeStartElement(TagBackup); - Streamer s(&w); - t.serialize(s); - w.writeEndElement(); - return a; -} - -template <typename ItemType> -void deserialize(ItemType* t, const QByteArray& a) -{ - QXmlStreamReader r(a); - Streamer sr(&r); - r.readNextStartElement(); - ASSERT(r.name().toString() == TagBackup); - t->serialize(sr); -} } // namespace @@ -55,18 +32,14 @@ CommandRemoveLayer::CommandRemoveLayer(SampleEditorController* ec, LayerItem* la : QUndoCommand(parent) , m_ec(ec) { + setText("Remove layer"); m_indexOfLayer = ec->multiLayerItem()->layers().indexOf(layerItem); m_layerItemBackup = GUI::Util::createBackup(layerItem); } void CommandRemoveLayer::redo() { - auto* layer = m_ec->multiLayerItem()->layers()[m_indexOfLayer]; - emit m_ec->aboutToRemoveItem(layer); - m_ec->multiLayerForm()->onAboutToRemoveLayer(layer); - m_ec->multiLayerItem()->removeLayer(layer); - m_ec->multiLayerForm()->updateRowVisibilities(); - emit m_ec->modified(); + m_ec->removeLayerFromUndo(m_indexOfLayer); } void CommandRemoveLayer::undo() @@ -77,14 +50,37 @@ void CommandRemoveLayer::undo() emit m_ec->modified(); } +// --------------------------------------------------------------------------------------------- // + +CommandAddLayer::CommandAddLayer(SampleEditorController* ec, int atIndex, QUndoCommand* parent) + : m_ec(ec) + , m_atIndex(atIndex) +{ + setText("Add layer"); +} + +void CommandAddLayer::redo() +{ + m_ec->addLayerFromUndo(m_atIndex); +} + +void CommandAddLayer::undo() +{ + // no backup of the layer has to be stored, since redo always creates the layer + // from scratch - no contents required for this + m_ec->removeLayerFromUndo(m_atIndex); +} + +// --------------------------------------------------------------------------------------------- // + CommandChangeValue::CommandChangeValue(const QString& label, SampleEditorController* ec, - double oldValue, double newValue, QString path, + double oldValue, double newValue, const QString& path, QUndoCommand* parent /*= nullptr*/) : QUndoCommand(parent) , m_ec(ec) , m_oldValue(oldValue) , m_newValue(newValue) - , m_path(std::move(path)) + , m_path(path) { setText("change " + label + "\n"); } @@ -96,7 +92,7 @@ int CommandChangeValue::id() const bool CommandChangeValue::mergeWith(const QUndoCommand* command) { - if (command->id() != id()) // make sure other is also an AppendText command + if (command->id() != id()) // make sure other is also a changeValue command return false; const auto* const other = dynamic_cast<const CommandChangeValue*>(command); diff --git a/GUI/View/SampleDesigner/SampleEditorCommands.h b/GUI/View/SampleDesigner/SampleEditorCommands.h index 69f91eb1aba3ed81b4f60e107fdc1a3e109519b9..4f8308c6087ded593589f4e04ee462e1e36ba01c 100644 --- a/GUI/View/SampleDesigner/SampleEditorCommands.h +++ b/GUI/View/SampleDesigner/SampleEditorCommands.h @@ -24,7 +24,7 @@ class LayerItem; class CommandChangeValue : public QUndoCommand { public: CommandChangeValue(const QString& label, SampleEditorController* ec, double oldValue, - double newValue, QString path, QUndoCommand* parent = nullptr); + double newValue, const QString& path, QUndoCommand* parent = nullptr); int id() const override; bool mergeWith(const QUndoCommand* command) override; @@ -40,6 +40,19 @@ private: bool m_isFirst = true; }; +//! Command to add a layer to a multilayer +class CommandAddLayer : public QUndoCommand { +public: + CommandAddLayer(SampleEditorController* ec, int atIndex, QUndoCommand* parent = nullptr); + + void redo() override; + void undo() override; + +private: + SampleEditorController* m_ec; + int m_atIndex; +}; + //! Command to remove a layer from a multilayer class CommandRemoveLayer : public QUndoCommand { public: diff --git a/GUI/View/SampleDesigner/SampleEditorController.cpp b/GUI/View/SampleDesigner/SampleEditorController.cpp index e474585a3ba24032fb891d7173342486ec1f81d3..907343bceee0fc76d46caa14055620faf5ee2056 100644 --- a/GUI/View/SampleDesigner/SampleEditorController.cpp +++ b/GUI/View/SampleDesigner/SampleEditorController.cpp @@ -62,8 +62,13 @@ MultiLayerItem* SampleEditorController::multiLayerItem() const void SampleEditorController::addLayer(LayerItem* before) { - const int rowInMultiLayer = (before != nullptr) ? m_multiLayerItem->layers().indexOf(before) - : m_multiLayerItem->layers().size(); + const int newIndex = (before != nullptr) ? m_multiLayerItem->layers().indexOf(before) + : m_multiLayerItem->layers().size(); + m_undoStack.push(new CommandAddLayer(this, newIndex)); +} + +void SampleEditorController::addLayerFromUndo(int atIndex) +{ // -- find a color for the new layer QColor color; @@ -85,11 +90,10 @@ void SampleEditorController::addLayer(LayerItem* before) [&](const QColor& a, const QColor& b) { return usage[a.name()] < usage[b.name()]; }); - const QColor above = (rowInMultiLayer > 0) - ? m_multiLayerItem->layers()[rowInMultiLayer - 1]->color() - : QColor(); - const QColor below = (rowInMultiLayer < m_multiLayerItem->layers().size()) - ? m_multiLayerItem->layers()[rowInMultiLayer]->color() + const QColor above = + (atIndex > 0) ? m_multiLayerItem->layers()[atIndex - 1]->color() : QColor(); + const QColor below = (atIndex < m_multiLayerItem->layers().size()) + ? m_multiLayerItem->layers()[atIndex]->color() : QColor(); for (const auto& col : sortedByUsage) @@ -100,7 +104,7 @@ void SampleEditorController::addLayer(LayerItem* before) } // - create new layer - LayerItem* layer = m_multiLayerItem->addLayer(rowInMultiLayer); + LayerItem* layer = m_multiLayerItem->addLayer(atIndex); layer->setMaterial(materialItems()->defaultMaterial()); layer->setColor(color); @@ -133,6 +137,16 @@ void SampleEditorController::removeLayer(LayerItem* layerItem) m_undoStack.push(new CommandRemoveLayer(this, layerItem)); } +void SampleEditorController::removeLayerFromUndo(int atIndex) +{ + auto* layer = m_multiLayerItem->layers()[atIndex]; + emit aboutToRemoveItem(layer); + m_multiLayerForm->onAboutToRemoveLayer(layer); + m_multiLayerItem->removeLayer(layer); + m_multiLayerForm->updateRowVisibilities(); + emit modified(); +} + void SampleEditorController::removeLayout(LayerForm* layerItemWidget, ParticleLayoutItem* layout) { emit aboutToRemoveItem(layout); diff --git a/GUI/View/SampleDesigner/SampleEditorController.h b/GUI/View/SampleDesigner/SampleEditorController.h index 562fd9ef4e92e8249e495f074c4583f05d1af8e4..b6e533167e37b8a9b9982d3c73142b7adc12ef4f 100644 --- a/GUI/View/SampleDesigner/SampleEditorController.h +++ b/GUI/View/SampleDesigner/SampleEditorController.h @@ -74,7 +74,9 @@ public: ProjectDocument* projectDocument() const; void addLayer(LayerItem* before); + void addLayerFromUndo(int atIndex); void removeLayer(LayerItem* layerItem); + void removeLayerFromUndo(int atIndex); void addLayout(LayerForm* layerItem); void removeLayout(LayerForm* layerItem, ParticleLayoutItem* layout);