[nostalgia/studio] Fix TileSheetEditor to switch to appropriate subsheet on undo/redo
This commit is contained in:
parent
71f6364ea3
commit
6854e658a0
@ -18,6 +18,7 @@ if(NOT NOSTALGIA_BUILD_TYPE STREQUAL "GBA")
|
|||||||
${OPENGL_gl_LIBRARY}
|
${OPENGL_gl_LIBRARY}
|
||||||
glfw
|
glfw
|
||||||
imgui
|
imgui
|
||||||
|
OxEvent
|
||||||
NostalgiaGlUtils
|
NostalgiaGlUtils
|
||||||
)
|
)
|
||||||
else()
|
else()
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <ox/model/typenamecatcher.hpp>
|
#include <ox/model/typenamecatcher.hpp>
|
||||||
|
#include <ox/event/signal.hpp>
|
||||||
#include <ox/fs/fs.hpp>
|
#include <ox/fs/fs.hpp>
|
||||||
#include <ox/std/hashmap.hpp>
|
#include <ox/std/hashmap.hpp>
|
||||||
#include <ox/std/utility.hpp>
|
#include <ox/std/utility.hpp>
|
||||||
@ -27,6 +28,8 @@ struct AssetContainer {
|
|||||||
mutable int m_references = 0;
|
mutable int m_references = 0;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
ox::Signal<ox::Error()> updated;
|
||||||
|
|
||||||
template<class... Args>
|
template<class... Args>
|
||||||
explicit constexpr AssetContainer(Args&&... args): m_obj(ox::forward<Args>(args)...) {
|
explicit constexpr AssetContainer(Args&&... args): m_obj(ox::forward<Args>(args)...) {
|
||||||
}
|
}
|
||||||
@ -39,6 +42,14 @@ struct AssetContainer {
|
|||||||
return &m_obj;
|
return &m_obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
constexpr void set(T &&val) {
|
||||||
|
m_obj = std::move(val);
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr void set(const T &val) {
|
||||||
|
m_obj = val;
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
constexpr void incRefs() const noexcept {
|
constexpr void incRefs() const noexcept {
|
||||||
++m_references;
|
++m_references;
|
||||||
@ -55,27 +66,20 @@ struct AssetContainer {
|
|||||||
};
|
};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
class AssetRef {
|
class AssetRef: public ox::SignalHandler {
|
||||||
private:
|
private:
|
||||||
const AssetContainer<T> *m_ctr = nullptr;
|
const AssetContainer<T> *m_ctr = nullptr;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit constexpr AssetRef(const AssetContainer<T> *c = nullptr) noexcept: m_ctr(c) {
|
ox::Signal<ox::Error()> updated;
|
||||||
}
|
|
||||||
|
|
||||||
constexpr AssetRef(const AssetRef &h) noexcept {
|
explicit constexpr AssetRef(const AssetContainer<T> *c = nullptr) noexcept;
|
||||||
m_ctr = h.m_ctr;
|
|
||||||
if (m_ctr) {
|
|
||||||
m_ctr->incRefs();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr AssetRef(AssetRef &&h) noexcept {
|
constexpr AssetRef(const AssetRef &h) noexcept;
|
||||||
m_ctr = h.m_ctr;
|
|
||||||
h.m_ctr = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
~AssetRef() noexcept {
|
constexpr AssetRef(AssetRef &&h) noexcept;
|
||||||
|
|
||||||
|
~AssetRef() noexcept override {
|
||||||
if (m_ctr) {
|
if (m_ctr) {
|
||||||
m_ctr->decRefs();
|
m_ctr->decRefs();
|
||||||
}
|
}
|
||||||
@ -103,8 +107,10 @@ class AssetRef {
|
|||||||
}
|
}
|
||||||
if (m_ctr) {
|
if (m_ctr) {
|
||||||
m_ctr->decRefs();
|
m_ctr->decRefs();
|
||||||
|
oxIgnoreError(m_ctr->updated.disconnectObject(this));
|
||||||
}
|
}
|
||||||
m_ctr = h.m_ctr;
|
m_ctr = h.m_ctr;
|
||||||
|
m_ctr->updated.connect(&updated, &ox::Signal<ox::Error()>::emitCheckError);
|
||||||
if (m_ctr) {
|
if (m_ctr) {
|
||||||
m_ctr->incRefs();
|
m_ctr->incRefs();
|
||||||
}
|
}
|
||||||
@ -115,7 +121,12 @@ class AssetRef {
|
|||||||
if (this == &h) {
|
if (this == &h) {
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
if (m_ctr) {
|
||||||
|
m_ctr->decRefs();
|
||||||
|
oxIgnoreError(m_ctr->updated.disconnectObject(this));
|
||||||
|
}
|
||||||
m_ctr = h.m_ctr;
|
m_ctr = h.m_ctr;
|
||||||
|
m_ctr->updated.connect(this, &AssetRef::emitUpdated);
|
||||||
h.m_ctr = nullptr;
|
h.m_ctr = nullptr;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
@ -124,8 +135,36 @@ class AssetRef {
|
|||||||
return m_ctr;
|
return m_ctr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
constexpr ox::Error emitUpdated() const noexcept {
|
||||||
|
updated.emit();
|
||||||
|
return OxError(0);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
constexpr AssetRef<T>::AssetRef(const AssetContainer<T> *c) noexcept: m_ctr(c) {
|
||||||
|
if (c) {
|
||||||
|
c->updated.connect(this, &AssetRef::emitUpdated);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
constexpr AssetRef<T>::AssetRef(const AssetRef &h) noexcept {
|
||||||
|
m_ctr = h.m_ctr;
|
||||||
|
if (m_ctr) {
|
||||||
|
m_ctr->updated.connect(this, &AssetRef::emitUpdated);
|
||||||
|
m_ctr->incRefs();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
constexpr AssetRef<T>::AssetRef(AssetRef &&h) noexcept {
|
||||||
|
m_ctr = h.m_ctr;
|
||||||
|
m_ctr->updated.connect(this, &AssetRef::emitUpdated);
|
||||||
|
h.m_ctr = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
class AssetManager {
|
class AssetManager {
|
||||||
private:
|
private:
|
||||||
class AssetTypeManagerBase {
|
class AssetTypeManagerBase {
|
||||||
@ -148,7 +187,24 @@ class AssetManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ox::Result<AssetRef<T>> setAsset(const ox::String &path, const T &obj) noexcept {
|
ox::Result<AssetRef<T>> setAsset(const ox::String &path, const T &obj) noexcept {
|
||||||
auto &p = m_cache[path] = ox::make_unique<AssetContainer<T>>(obj);
|
auto &p = m_cache[path];
|
||||||
|
if (!p) {
|
||||||
|
p = ox::make_unique<AssetContainer<T>>(obj);
|
||||||
|
} else {
|
||||||
|
p->set(obj);
|
||||||
|
p->updated.emit();
|
||||||
|
}
|
||||||
|
return AssetRef<T>(p.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
ox::Result<AssetRef<T>> setAsset(const ox::String &path, T &&obj) noexcept {
|
||||||
|
auto &p = m_cache[path];
|
||||||
|
if (!p) {
|
||||||
|
p = ox::make_unique<AssetContainer<T>>(obj);
|
||||||
|
} else {
|
||||||
|
p->set(std::move(obj));
|
||||||
|
p->updated.emit();
|
||||||
|
}
|
||||||
return AssetRef<T>(p.get());
|
return AssetRef<T>(p.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -150,7 +150,7 @@ void TileSheetEditorImGui::draw(core::Context*) noexcept {
|
|||||||
m_subsheetEditor.draw();
|
m_subsheetEditor.draw();
|
||||||
}
|
}
|
||||||
|
|
||||||
void TileSheetEditorImGui::drawSubsheetSelector(TileSheet::SubSheet *subsheet, TileSheet::SubSheetIdx *path) noexcept {
|
void TileSheetEditorImGui::drawSubsheetSelector(TileSheet::SubSheet *subsheet, TileSheet::SubSheetIdx *path) {
|
||||||
ImGui::TableNextRow(0, 5);
|
ImGui::TableNextRow(0, 5);
|
||||||
using Str = ox::BasicString<100>;
|
using Str = ox::BasicString<100>;
|
||||||
auto pathStr = ox::join<Str>("##", *path).value;
|
auto pathStr = ox::join<Str>("##", *path).value;
|
||||||
@ -305,7 +305,7 @@ ox::Error TileSheetEditorImGui::updateActiveSubsheet(const ox::String &name, int
|
|||||||
return model()->updateSubsheet(model()->activeSubSheetIdx(), name, cols, rows);
|
return model()->updateSubsheet(model()->activeSubSheetIdx(), name, cols, rows);
|
||||||
}
|
}
|
||||||
|
|
||||||
ox::Error TileSheetEditorImGui::markUnsavedChanges(int) noexcept {
|
ox::Error TileSheetEditorImGui::markUnsavedChanges(const studio::UndoCommand*) noexcept {
|
||||||
setUnsavedChanges(true);
|
setUnsavedChanges(true);
|
||||||
return OxError(0);
|
return OxError(0);
|
||||||
}
|
}
|
||||||
|
@ -74,7 +74,7 @@ class TileSheetEditorImGui: public studio::BaseEditor {
|
|||||||
|
|
||||||
void draw(core::Context*) noexcept override;
|
void draw(core::Context*) noexcept override;
|
||||||
|
|
||||||
void drawSubsheetSelector(TileSheet::SubSheet*, TileSheet::SubSheetIdx *path) noexcept;
|
void drawSubsheetSelector(TileSheet::SubSheet*, TileSheet::SubSheetIdx *path);
|
||||||
|
|
||||||
studio::UndoStack *undoStack() noexcept final;
|
studio::UndoStack *undoStack() noexcept final;
|
||||||
|
|
||||||
@ -114,7 +114,7 @@ class TileSheetEditorImGui: public studio::BaseEditor {
|
|||||||
private:
|
private:
|
||||||
ox::Error updateAfterClicked() noexcept;
|
ox::Error updateAfterClicked() noexcept;
|
||||||
|
|
||||||
ox::Error markUnsavedChanges(int) noexcept;
|
ox::Error markUnsavedChanges(const studio::UndoCommand*) noexcept;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -73,7 +73,13 @@ constexpr bool operator==(int i, CommandId c) noexcept {
|
|||||||
return static_cast<int>(c) == i;
|
return static_cast<int>(c) == i;
|
||||||
}
|
}
|
||||||
|
|
||||||
class DrawCommand: public studio::UndoCommand {
|
class TileSheetCommand: public studio::UndoCommand {
|
||||||
|
public:
|
||||||
|
[[nodiscard]]
|
||||||
|
virtual const TileSheet::SubSheetIdx &subsheetIdx() const noexcept = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
class DrawCommand: public TileSheetCommand {
|
||||||
private:
|
private:
|
||||||
struct Change {
|
struct Change {
|
||||||
uint32_t idx = 0;
|
uint32_t idx = 0;
|
||||||
@ -150,10 +156,15 @@ class DrawCommand: public studio::UndoCommand {
|
|||||||
return static_cast<int>(CommandId::Draw);
|
return static_cast<int>(CommandId::Draw);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[[nodiscard]]
|
||||||
|
const TileSheet::SubSheetIdx &subsheetIdx() const noexcept override {
|
||||||
|
return m_subSheetIdx;
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template<CommandId CommandId>
|
template<CommandId CommandId>
|
||||||
class CutPasteCommand: public studio::UndoCommand {
|
class CutPasteCommand: public TileSheetCommand {
|
||||||
private:
|
private:
|
||||||
struct Change {
|
struct Change {
|
||||||
uint32_t idx = 0;
|
uint32_t idx = 0;
|
||||||
@ -202,9 +213,14 @@ class CutPasteCommand: public studio::UndoCommand {
|
|||||||
return static_cast<int>(CommandId);
|
return static_cast<int>(CommandId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[[nodiscard]]
|
||||||
|
const TileSheet::SubSheetIdx &subsheetIdx() const noexcept override {
|
||||||
|
return m_subSheetIdx;
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class AddSubSheetCommand: public studio::UndoCommand {
|
class AddSubSheetCommand: public TileSheetCommand {
|
||||||
private:
|
private:
|
||||||
TileSheet *m_img = nullptr;
|
TileSheet *m_img = nullptr;
|
||||||
TileSheet::SubSheetIdx m_parentIdx;
|
TileSheet::SubSheetIdx m_parentIdx;
|
||||||
@ -261,9 +277,14 @@ class AddSubSheetCommand: public studio::UndoCommand {
|
|||||||
return static_cast<int>(CommandId::AddSubSheet);
|
return static_cast<int>(CommandId::AddSubSheet);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[[nodiscard]]
|
||||||
|
const TileSheet::SubSheetIdx &subsheetIdx() const noexcept override {
|
||||||
|
return m_parentIdx;
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class RmSubSheetCommand: public studio::UndoCommand {
|
class RmSubSheetCommand: public TileSheetCommand {
|
||||||
private:
|
private:
|
||||||
TileSheet *m_img = nullptr;
|
TileSheet *m_img = nullptr;
|
||||||
TileSheet::SubSheetIdx m_idx;
|
TileSheet::SubSheetIdx m_idx;
|
||||||
@ -296,9 +317,14 @@ class RmSubSheetCommand: public studio::UndoCommand {
|
|||||||
return static_cast<int>(CommandId::RmSubSheet);
|
return static_cast<int>(CommandId::RmSubSheet);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[[nodiscard]]
|
||||||
|
const TileSheet::SubSheetIdx &subsheetIdx() const noexcept override {
|
||||||
|
return m_idx;
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class UpdateSubSheetCommand: public studio::UndoCommand {
|
class UpdateSubSheetCommand: public TileSheetCommand {
|
||||||
private:
|
private:
|
||||||
TileSheet *m_img = nullptr;
|
TileSheet *m_img = nullptr;
|
||||||
TileSheet::SubSheetIdx m_idx;
|
TileSheet::SubSheetIdx m_idx;
|
||||||
@ -336,16 +362,23 @@ class UpdateSubSheetCommand: public studio::UndoCommand {
|
|||||||
return static_cast<int>(CommandId::UpdateSubSheet);
|
return static_cast<int>(CommandId::UpdateSubSheet);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[[nodiscard]]
|
||||||
|
const TileSheet::SubSheetIdx &subsheetIdx() const noexcept override {
|
||||||
|
return m_idx;
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class PaletteChangeCommand: public studio::UndoCommand {
|
class PaletteChangeCommand: public TileSheetCommand {
|
||||||
private:
|
private:
|
||||||
|
TileSheet::SubSheetIdx m_idx;
|
||||||
TileSheet *m_img = nullptr;
|
TileSheet *m_img = nullptr;
|
||||||
ox::FileAddress m_oldPalette;
|
ox::FileAddress m_oldPalette;
|
||||||
ox::FileAddress m_newPalette;
|
ox::FileAddress m_newPalette;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
constexpr PaletteChangeCommand(TileSheet *img, const ox::String &newPalette) noexcept {
|
constexpr PaletteChangeCommand(const TileSheet::SubSheetIdx &idx, TileSheet *img, const ox::String &newPalette) noexcept {
|
||||||
|
m_idx = idx;
|
||||||
m_img = img;
|
m_img = img;
|
||||||
m_oldPalette = m_img->defaultPalette;
|
m_oldPalette = m_img->defaultPalette;
|
||||||
m_newPalette = newPalette;
|
m_newPalette = newPalette;
|
||||||
@ -364,6 +397,11 @@ class PaletteChangeCommand: public studio::UndoCommand {
|
|||||||
return static_cast<int>(CommandId::PaletteChange);
|
return static_cast<int>(CommandId::PaletteChange);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[[nodiscard]]
|
||||||
|
const TileSheet::SubSheetIdx &subsheetIdx() const noexcept override {
|
||||||
|
return m_idx;
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -373,7 +411,8 @@ TileSheetEditorModel::TileSheetEditorModel(Context *ctx, const ox::String &path)
|
|||||||
oxRequireT(img, readObj<TileSheet>(ctx, path.c_str()));
|
oxRequireT(img, readObj<TileSheet>(ctx, path.c_str()));
|
||||||
m_img = *img;
|
m_img = *img;
|
||||||
oxThrowError(readObj<Palette>(ctx, m_img.defaultPalette).moveTo(&m_pal));
|
oxThrowError(readObj<Palette>(ctx, m_img.defaultPalette).moveTo(&m_pal));
|
||||||
m_undoStack.changeTriggered.connect(this, &TileSheetEditorModel::markUpdated);
|
m_pal.updated.connect(this, &TileSheetEditorModel::markUpdated);
|
||||||
|
m_undoStack.changeTriggered.connect(this, &TileSheetEditorModel::markUpdatedCmdId);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TileSheetEditorModel::cut() {
|
void TileSheetEditorModel::cut() {
|
||||||
@ -431,7 +470,7 @@ const ox::FileAddress &TileSheetEditorModel::palPath() const noexcept {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ox::Error TileSheetEditorModel::setPalette(const ox::String &path) noexcept {
|
ox::Error TileSheetEditorModel::setPalette(const ox::String &path) noexcept {
|
||||||
pushCommand(new PaletteChangeCommand(&m_img, path));
|
pushCommand(new PaletteChangeCommand(activeSubSheetIdx(), &m_img, path));
|
||||||
return OxError(0);
|
return OxError(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -526,18 +565,12 @@ bool TileSheetEditorModel::updated() const noexcept {
|
|||||||
return m_updated;
|
return m_updated;
|
||||||
}
|
}
|
||||||
|
|
||||||
ox::Error TileSheetEditorModel::markUpdated(int cmdId) noexcept {
|
ox::Error TileSheetEditorModel::markUpdatedCmdId(const studio::UndoCommand *cmd) noexcept {
|
||||||
m_updated = true;
|
m_updated = true;
|
||||||
|
const auto cmdId = cmd->commandId();
|
||||||
switch (static_cast<CommandId>(cmdId)) {
|
switch (static_cast<CommandId>(cmdId)) {
|
||||||
case CommandId::AddSubSheet:
|
case CommandId::AddSubSheet:
|
||||||
case CommandId::RmSubSheet: {
|
case CommandId::RmSubSheet:
|
||||||
// make sure the current active SubSheet is still valid
|
|
||||||
auto idx = m_img.validateSubSheetIdx(m_activeSubsSheetIdx);
|
|
||||||
if (idx != m_activeSubsSheetIdx) {
|
|
||||||
setActiveSubsheet(idx);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case CommandId::Cut:
|
case CommandId::Cut:
|
||||||
case CommandId::Draw:
|
case CommandId::Draw:
|
||||||
case CommandId::Paste:
|
case CommandId::Paste:
|
||||||
@ -547,6 +580,16 @@ ox::Error TileSheetEditorModel::markUpdated(int cmdId) noexcept {
|
|||||||
oxReturnError(readObj<Palette>(m_ctx, m_img.defaultPalette.getPath().value).moveTo(&m_pal));
|
oxReturnError(readObj<Palette>(m_ctx, m_img.defaultPalette.getPath().value).moveTo(&m_pal));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
auto tsCmd = dynamic_cast<const TileSheetCommand*>(cmd);
|
||||||
|
auto idx = m_img.validateSubSheetIdx(tsCmd->subsheetIdx());
|
||||||
|
if (idx != m_activeSubsSheetIdx) {
|
||||||
|
setActiveSubsheet(idx);
|
||||||
|
}
|
||||||
|
return OxError(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
ox::Error TileSheetEditorModel::markUpdated() noexcept {
|
||||||
|
m_updated = true;
|
||||||
return OxError(0);
|
return OxError(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -94,7 +94,9 @@ class TileSheetEditorModel: public ox::SignalHandler {
|
|||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
bool updated() const noexcept;
|
bool updated() const noexcept;
|
||||||
|
|
||||||
ox::Error markUpdated(int) noexcept;
|
ox::Error markUpdatedCmdId(const studio::UndoCommand *cmd) noexcept;
|
||||||
|
|
||||||
|
ox::Error markUpdated() noexcept;
|
||||||
|
|
||||||
void ackUpdate() noexcept;
|
void ackUpdate() noexcept;
|
||||||
|
|
||||||
|
@ -79,6 +79,11 @@ bool TileSheetEditorView::updated() const noexcept {
|
|||||||
return m_updated || m_model.updated();
|
return m_updated || m_model.updated();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ox::Error TileSheetEditorView::markUpdated() noexcept {
|
||||||
|
m_updated = true;
|
||||||
|
return OxError(0);
|
||||||
|
}
|
||||||
|
|
||||||
void TileSheetEditorView::ackUpdate() noexcept {
|
void TileSheetEditorView::ackUpdate() noexcept {
|
||||||
m_updated = false;
|
m_updated = false;
|
||||||
m_model.ackUpdate();
|
m_model.ackUpdate();
|
||||||
|
@ -100,6 +100,8 @@ class TileSheetEditorView: public ox::SignalHandler {
|
|||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
bool updated() const noexcept;
|
bool updated() const noexcept;
|
||||||
|
|
||||||
|
ox::Error markUpdated() noexcept;
|
||||||
|
|
||||||
void ackUpdate() noexcept;
|
void ackUpdate() noexcept;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -93,7 +93,7 @@ Editor::Editor() noexcept {
|
|||||||
m_undoStack.changeTriggered.connect(this, &Editor::markUnsavedChanges);
|
m_undoStack.changeTriggered.connect(this, &Editor::markUnsavedChanges);
|
||||||
}
|
}
|
||||||
|
|
||||||
ox::Error Editor::markUnsavedChanges(int) noexcept {
|
ox::Error Editor::markUnsavedChanges(const UndoCommand*) noexcept {
|
||||||
setUnsavedChanges(true);
|
setUnsavedChanges(true);
|
||||||
return OxError(0);
|
return OxError(0);
|
||||||
}
|
}
|
||||||
|
@ -123,7 +123,7 @@ class Editor: public studio::BaseEditor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ox::Error markUnsavedChanges(int) noexcept;
|
ox::Error markUnsavedChanges(const UndoCommand*) noexcept;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -14,10 +14,9 @@ void UndoStack::push(UndoCommand *cmd) noexcept {
|
|||||||
for (const auto i = m_stackIdx; i < m_stack.size();) {
|
for (const auto i = m_stackIdx; i < m_stack.size();) {
|
||||||
oxIgnoreError(m_stack.erase(i));
|
oxIgnoreError(m_stack.erase(i));
|
||||||
}
|
}
|
||||||
auto cmdId = cmd->commandId();
|
|
||||||
cmd->redo();
|
cmd->redo();
|
||||||
redoTriggered.emit(cmdId);
|
redoTriggered.emit(cmd);
|
||||||
changeTriggered.emit(cmdId);
|
changeTriggered.emit(cmd);
|
||||||
if (!m_stack.size() || !m_stack.back().value->mergeWith(cmd)) {
|
if (!m_stack.size() || !m_stack.back().value->mergeWith(cmd)) {
|
||||||
m_stack.emplace_back(cmd);
|
m_stack.emplace_back(cmd);
|
||||||
++m_stackIdx;
|
++m_stackIdx;
|
||||||
@ -29,20 +28,18 @@ void UndoStack::push(UndoCommand *cmd) noexcept {
|
|||||||
void UndoStack::redo() noexcept {
|
void UndoStack::redo() noexcept {
|
||||||
if (m_stackIdx < m_stack.size()) {
|
if (m_stackIdx < m_stack.size()) {
|
||||||
auto &c = m_stack[m_stackIdx++];
|
auto &c = m_stack[m_stackIdx++];
|
||||||
auto cmdId = c->commandId();
|
|
||||||
c->redo();
|
c->redo();
|
||||||
redoTriggered.emit(cmdId);
|
redoTriggered.emit(c.get());
|
||||||
changeTriggered.emit(cmdId);
|
changeTriggered.emit(c.get());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void UndoStack::undo() noexcept {
|
void UndoStack::undo() noexcept {
|
||||||
if (m_stackIdx) {
|
if (m_stackIdx) {
|
||||||
auto &c = m_stack[--m_stackIdx];
|
auto &c = m_stack[--m_stackIdx];
|
||||||
auto cmdId = c->commandId();
|
|
||||||
c->undo();
|
c->undo();
|
||||||
undoTriggered.emit(cmdId);
|
undoTriggered.emit(c.get());
|
||||||
changeTriggered.emit(cmdId);
|
changeTriggered.emit(c.get());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,9 +43,9 @@ class UndoStack {
|
|||||||
return m_stackIdx;
|
return m_stackIdx;
|
||||||
}
|
}
|
||||||
|
|
||||||
ox::Signal<ox::Error(int)> redoTriggered;
|
ox::Signal<ox::Error(const studio::UndoCommand*)> redoTriggered;
|
||||||
ox::Signal<ox::Error(int)> undoTriggered;
|
ox::Signal<ox::Error(const studio::UndoCommand*)> undoTriggered;
|
||||||
ox::Signal<ox::Error(int)> changeTriggered;
|
ox::Signal<ox::Error(const studio::UndoCommand*)> changeTriggered;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user