Compare commits
8 Commits
1f6fefdb68
...
135f0e4ce8
Author | SHA1 | Date | |
---|---|---|---|
135f0e4ce8 | |||
cb16687641 | |||
cb3ef0e79d | |||
0a62d90065 | |||
ba7e3929e9 | |||
36c4022b56 | |||
e22b25e54c | |||
c6efabaa1d |
@ -41,31 +41,10 @@ PaletteEditorImGui::PaletteEditorImGui(studio::StudioContext &sctx, ox::StringPa
|
|||||||
m_sctx(sctx),
|
m_sctx(sctx),
|
||||||
m_tctx(sctx.tctx),
|
m_tctx(sctx.tctx),
|
||||||
m_pal(*keel::readObj<Palette>(keelCtx(m_tctx), itemPath()).unwrapThrow()) {
|
m_pal(*keel::readObj<Palette>(keelCtx(m_tctx), itemPath()).unwrapThrow()) {
|
||||||
if (keel::ensureValid(m_pal).errCode) {
|
|
||||||
throw OxException(1, "PaletteEditorImGui: invalid Palette object");
|
|
||||||
}
|
|
||||||
undoStack()->changeTriggered.connect(this, &PaletteEditorImGui::handleCommand);
|
undoStack()->changeTriggered.connect(this, &PaletteEditorImGui::handleCommand);
|
||||||
m_pageRename.inputSubmitted.connect(this, &PaletteEditorImGui::renamePage);
|
m_pageRename.inputSubmitted.connect(this, &PaletteEditorImGui::renamePage);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PaletteEditorImGui::keyStateChanged(turbine::Key key, bool down) {
|
|
||||||
if (!down || m_pageRename.isOpen()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (key >= turbine::Key::Num_1 && key <= turbine::Key::Num_9) {
|
|
||||||
if (turbine::buttonDown(m_tctx, turbine::Key::Mod_Alt)) {
|
|
||||||
m_page = ox::min<std::size_t>(
|
|
||||||
static_cast<uint32_t>(key - turbine::Key::Num_1), m_pal.pages.size() - 1);
|
|
||||||
}
|
|
||||||
} else if (key == turbine::Key::Num_0) {
|
|
||||||
if (turbine::buttonDown(m_tctx, turbine::Key::Mod_Alt)) {
|
|
||||||
m_selectedColorRow =
|
|
||||||
ox::min<std::size_t>(
|
|
||||||
static_cast<uint32_t>(key - turbine::Key::Num_1 + 9), m_pal.pages.size() - 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void PaletteEditorImGui::draw(studio::StudioContext&) noexcept {
|
void PaletteEditorImGui::draw(studio::StudioContext&) noexcept {
|
||||||
auto const paneSize = ImGui::GetContentRegionAvail();
|
auto const paneSize = ImGui::GetContentRegionAvail();
|
||||||
{
|
{
|
||||||
@ -98,6 +77,19 @@ void PaletteEditorImGui::drawColumn(ox::CStringView txt) noexcept {
|
|||||||
ImGui::Text("%s", txt.c_str());
|
ImGui::Text("%s", txt.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PaletteEditorImGui::numShortcuts(size_t &val, size_t const sizeRange) noexcept {
|
||||||
|
auto const lastElem = sizeRange - 1;
|
||||||
|
if (ImGui::IsKeyPressed(ImGuiKey_0)) {
|
||||||
|
val = ox::min<size_t>(9, lastElem);
|
||||||
|
} else for (auto i = 9u; i < 10; --i) {
|
||||||
|
auto const key = static_cast<ImGuiKey>(ImGuiKey_1 + i);
|
||||||
|
if (ImGui::IsKeyPressed(key)) {
|
||||||
|
val = ox::min<size_t>(i, lastElem);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void PaletteEditorImGui::colorInput(ox::CStringView label, int &v, bool &inputFocused) noexcept {
|
void PaletteEditorImGui::colorInput(ox::CStringView label, int &v, bool &inputFocused) noexcept {
|
||||||
ImGui::InputInt(label.c_str(), &v, 1, 5);
|
ImGui::InputInt(label.c_str(), &v, 1, 5);
|
||||||
inputFocused = inputFocused || ImGui::IsItemFocused();
|
inputFocused = inputFocused || ImGui::IsItemFocused();
|
||||||
@ -240,10 +232,8 @@ void PaletteEditorImGui::drawColorEditor() noexcept {
|
|||||||
int g = green16(c);
|
int g = green16(c);
|
||||||
int b = blue16(c);
|
int b = blue16(c);
|
||||||
int const a = alpha16(c);
|
int const a = alpha16(c);
|
||||||
auto const¤tName = m_pal.colorNames[m_selectedColorRow];
|
auto const newName = ig::InputText<50>(
|
||||||
ox::IString<50> name;
|
"Name", m_pal.colorNames[m_selectedColorRow]);
|
||||||
name = currentName;
|
|
||||||
auto const nameUpdated = ImGui::InputText("Name", name.data(), name.cap() + 1);
|
|
||||||
bool inputFocused = ImGui::IsItemFocused();
|
bool inputFocused = ImGui::IsItemFocused();
|
||||||
ImGui::Separator();
|
ImGui::Separator();
|
||||||
colorInput("Red", r, inputFocused);
|
colorInput("Red", r, inputFocused);
|
||||||
@ -254,24 +244,19 @@ void PaletteEditorImGui::drawColorEditor() noexcept {
|
|||||||
m_pal, m_page, m_selectedColorRow);
|
m_pal, m_page, m_selectedColorRow);
|
||||||
}
|
}
|
||||||
if (!inputFocused && !m_pageRename.isOpen()) {
|
if (!inputFocused && !m_pageRename.isOpen()) {
|
||||||
auto const lastColor = largestPage(m_pal) - 1;
|
if (!ImGui::IsKeyDown(ImGuiKey_ModAlt)) {
|
||||||
if (ImGui::IsKeyPressed(ImGuiKey_0, false)) {
|
numShortcuts(m_selectedColorRow, largestPage(m_pal));
|
||||||
m_selectedColorRow = ox::min<size_t>(9, lastColor);
|
} else {
|
||||||
} else for (auto i = 9u; i < 10; --i) {
|
numShortcuts(m_page, m_pal.pages.size());
|
||||||
auto const key = static_cast<ImGuiKey>(ImGuiKey_1 + i);
|
|
||||||
if (ImGui::IsKeyPressed(key, false)) {
|
|
||||||
m_selectedColorRow = ox::min<size_t>(i, lastColor);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
auto const newColor = color16(r, g, b, a);
|
auto const newColor = color16(r, g, b, a);
|
||||||
if (c != newColor) {
|
if (c != newColor) {
|
||||||
std::ignore = pushCommand<UpdateColorCommand>(m_pal, m_page, m_selectedColorRow, newColor);
|
std::ignore = pushCommand<UpdateColorCommand>(m_pal, m_page, m_selectedColorRow, newColor);
|
||||||
}
|
}
|
||||||
if (nameUpdated) {
|
if (newName) {
|
||||||
std::ignore = pushCommand<UpdateColorInfoCommand>(
|
std::ignore = pushCommand<UpdateColorInfoCommand>(
|
||||||
m_pal, m_selectedColorRow, ox::String{name.data()});
|
m_pal, m_selectedColorRow, ox::String{newName});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -40,8 +40,6 @@ class PaletteEditorImGui: public studio::Editor {
|
|||||||
public:
|
public:
|
||||||
PaletteEditorImGui(studio::StudioContext &sctx, ox::StringParam path);
|
PaletteEditorImGui(studio::StudioContext &sctx, ox::StringParam path);
|
||||||
|
|
||||||
void keyStateChanged(turbine::Key key, bool down) override;
|
|
||||||
|
|
||||||
void draw(studio::StudioContext&) noexcept final;
|
void draw(studio::StudioContext&) noexcept final;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@ -56,6 +54,8 @@ class PaletteEditorImGui: public studio::Editor {
|
|||||||
drawColumn(ox::itoa(i));
|
drawColumn(ox::itoa(i));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void numShortcuts(size_t &val, size_t sizeRange) noexcept;
|
||||||
|
|
||||||
static void colorInput(ox::CStringView label, int &v, bool &inputFocused) noexcept;
|
static void colorInput(ox::CStringView label, int &v, bool &inputFocused) noexcept;
|
||||||
|
|
||||||
void drawColorsEditor() noexcept;
|
void drawColorsEditor() noexcept;
|
||||||
|
@ -188,19 +188,21 @@ UpdateColorInfoCommand::UpdateColorInfoCommand(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool UpdateColorInfoCommand::mergeWith(UndoCommand const&cmd) noexcept {
|
bool UpdateColorInfoCommand::mergeWith(UndoCommand &cmd) noexcept {
|
||||||
if (cmd.commandId() != static_cast<int>(PaletteEditorCommandId::UpdateColor)) {
|
if (cmd.commandId() != static_cast<int>(PaletteEditorCommandId::UpdateColorInfo)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
auto ucCmd = static_cast<UpdateColorInfoCommand const*>(&cmd);
|
auto ucCmd = dynamic_cast<UpdateColorInfoCommand const*>(&cmd);
|
||||||
if (m_idx != ucCmd->m_idx) {
|
if (m_idx != ucCmd->m_idx) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
m_pal.colorNames[m_idx] = std::move(ucCmd->m_pal.colorNames[m_idx]);
|
||||||
|
setObsolete(m_altColorInfo == m_pal.colorNames[m_idx]);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
int UpdateColorInfoCommand::commandId() const noexcept {
|
int UpdateColorInfoCommand::commandId() const noexcept {
|
||||||
return static_cast<int>(PaletteEditorCommandId::UpdateColor);
|
return static_cast<int>(PaletteEditorCommandId::UpdateColorInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
ox::Error UpdateColorInfoCommand::redo() noexcept {
|
ox::Error UpdateColorInfoCommand::redo() noexcept {
|
||||||
@ -232,11 +234,11 @@ UpdateColorCommand::UpdateColorCommand(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool UpdateColorCommand::mergeWith(UndoCommand const&cmd) noexcept {
|
bool UpdateColorCommand::mergeWith(UndoCommand &cmd) noexcept {
|
||||||
if (cmd.commandId() != static_cast<int>(PaletteEditorCommandId::UpdateColor)) {
|
if (cmd.commandId() != static_cast<int>(PaletteEditorCommandId::UpdateColor)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
auto ucCmd = static_cast<UpdateColorCommand const*>(&cmd);
|
auto ucCmd = dynamic_cast<UpdateColorCommand const*>(&cmd);
|
||||||
if (m_idx != ucCmd->m_idx) {
|
if (m_idx != ucCmd->m_idx) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -163,7 +163,7 @@ class UpdateColorInfoCommand: public studio::UndoCommand {
|
|||||||
~UpdateColorInfoCommand() noexcept override = default;
|
~UpdateColorInfoCommand() noexcept override = default;
|
||||||
|
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
bool mergeWith(const UndoCommand &cmd) noexcept final;
|
bool mergeWith(UndoCommand &cmd) noexcept final;
|
||||||
|
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
int commandId() const noexcept final;
|
int commandId() const noexcept final;
|
||||||
@ -194,7 +194,7 @@ class UpdateColorCommand: public studio::UndoCommand {
|
|||||||
~UpdateColorCommand() noexcept override = default;
|
~UpdateColorCommand() noexcept override = default;
|
||||||
|
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
bool mergeWith(const UndoCommand &cmd) noexcept final;
|
bool mergeWith(UndoCommand &cmd) noexcept final;
|
||||||
|
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
int commandId() const noexcept final;
|
int commandId() const noexcept final;
|
||||||
|
@ -158,21 +158,25 @@ void TileSheetEditorImGui::keyStateChanged(turbine::Key key, bool down) {
|
|||||||
} else if (key >= turbine::Key::Num_1 && key <= turbine::Key::Num_9) {
|
} else if (key >= turbine::Key::Num_1 && key <= turbine::Key::Num_9) {
|
||||||
if (turbine::buttonDown(m_tctx, turbine::Key::Mod_Alt)) {
|
if (turbine::buttonDown(m_tctx, turbine::Key::Mod_Alt)) {
|
||||||
auto const idx = ox::min<std::size_t>(
|
auto const idx = ox::min<std::size_t>(
|
||||||
static_cast<uint32_t>(key - turbine::Key::Num_1), m_model.pal().pages.size() - 1);
|
static_cast<uint32_t>(key - turbine::Key::Num_1),
|
||||||
|
m_model.pal().pages.size() - 1);
|
||||||
m_model.setPalettePage(idx);
|
m_model.setPalettePage(idx);
|
||||||
} else if (key <= turbine::Key::Num_0 + colorCnt) {
|
} else if (key <= turbine::Key::Num_9) {
|
||||||
auto const idx = ox::min<std::size_t>(
|
auto const idx = ox::min<std::size_t>(
|
||||||
static_cast<uint32_t>(key - turbine::Key::Num_1), colorCnt - 1);
|
static_cast<uint32_t>(key - turbine::Key::Num_1),
|
||||||
|
colorCnt - 1);
|
||||||
m_view.setPalIdx(idx);
|
m_view.setPalIdx(idx);
|
||||||
}
|
}
|
||||||
} else if (key == turbine::Key::Num_0) {
|
} else if (key == turbine::Key::Num_0) {
|
||||||
if (turbine::buttonDown(m_tctx, turbine::Key::Mod_Alt)) {
|
if (turbine::buttonDown(m_tctx, turbine::Key::Mod_Alt)) {
|
||||||
auto const idx = ox::min<std::size_t>(
|
auto const idx = ox::min<std::size_t>(
|
||||||
static_cast<uint32_t>(key - turbine::Key::Num_1 + 9), m_model.pal().pages.size() - 1);
|
static_cast<uint32_t>(key - turbine::Key::Num_1 + 9),
|
||||||
|
m_model.pal().pages.size() - 1);
|
||||||
m_model.setPalettePage(idx);
|
m_model.setPalettePage(idx);
|
||||||
} else if (colorCnt >= 10) {
|
} else {
|
||||||
auto const idx = ox::min<std::size_t>(
|
auto const idx = ox::min<std::size_t>(
|
||||||
static_cast<uint32_t>(key - turbine::Key::Num_1 + 9), colorCnt - 1);
|
static_cast<uint32_t>(key - turbine::Key::Num_1 + 9),
|
||||||
|
colorCnt - 1);
|
||||||
m_view.setPalIdx(idx);
|
m_view.setPalIdx(idx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,6 @@ SceneEditorImGui::SceneEditorImGui(studio::StudioContext &ctx, ox::StringView pa
|
|||||||
m_ctx(ctx.tctx),
|
m_ctx(ctx.tctx),
|
||||||
m_editor(m_ctx, path),
|
m_editor(m_ctx, path),
|
||||||
m_view(m_ctx, m_editor.scene()) {
|
m_view(m_ctx, m_editor.scene()) {
|
||||||
setRequiresConstantRefresh(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SceneEditorImGui::draw(studio::StudioContext&) noexcept {
|
void SceneEditorImGui::draw(studio::StudioContext&) noexcept {
|
||||||
|
@ -23,7 +23,6 @@ class BaseEditor: public Widget {
|
|||||||
bool m_cutEnabled = false;
|
bool m_cutEnabled = false;
|
||||||
bool m_copyEnabled = false;
|
bool m_copyEnabled = false;
|
||||||
bool m_pasteEnabled = false;
|
bool m_pasteEnabled = false;
|
||||||
bool m_requiresConstantRefresh = false;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
~BaseEditor() override = default;
|
~BaseEditor() override = default;
|
||||||
@ -52,9 +51,6 @@ class BaseEditor: public Widget {
|
|||||||
|
|
||||||
virtual void onActivated() noexcept;
|
virtual void onActivated() noexcept;
|
||||||
|
|
||||||
[[nodiscard]]
|
|
||||||
bool requiresConstantRefresh() const noexcept;
|
|
||||||
|
|
||||||
void close() const;
|
void close() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -71,10 +67,10 @@ class BaseEditor: public Widget {
|
|||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
bool unsavedChanges() const noexcept;
|
bool unsavedChanges() const noexcept;
|
||||||
|
|
||||||
void setExportable(bool);
|
void setExportable(bool) noexcept;
|
||||||
|
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
bool exportable() const;
|
bool exportable() const noexcept;
|
||||||
|
|
||||||
void setCutEnabled(bool);
|
void setCutEnabled(bool);
|
||||||
|
|
||||||
|
@ -128,9 +128,35 @@ void centerNextWindow(turbine::Context &ctx) noexcept;
|
|||||||
|
|
||||||
bool PushButton(ox::CStringView lbl, ImVec2 const&btnSz = BtnSz) noexcept;
|
bool PushButton(ox::CStringView lbl, ImVec2 const&btnSz = BtnSz) noexcept;
|
||||||
|
|
||||||
|
template<typename Str>
|
||||||
|
struct TextInput {
|
||||||
|
bool changed{};
|
||||||
|
Str text;
|
||||||
|
explicit constexpr operator ox::String() const noexcept { return ox::String{text}; }
|
||||||
|
constexpr operator ox::CStringView() const noexcept { return text; }
|
||||||
|
constexpr operator ox::StringView() const noexcept { return text; }
|
||||||
|
constexpr operator bool() const noexcept { return changed; }
|
||||||
|
};
|
||||||
|
|
||||||
|
template<size_t MaxChars = 50>
|
||||||
|
TextInput<ox::IString<MaxChars>> InputText(
|
||||||
|
ox::CStringViewCR label,
|
||||||
|
ox::StringViewCR currentText,
|
||||||
|
ImGuiInputTextFlags const flags = 0,
|
||||||
|
ImGuiInputTextCallback const callback = nullptr,
|
||||||
|
void *user_data = nullptr) noexcept {
|
||||||
|
TextInput<ox::IString<MaxChars>> out = {.text = currentText};
|
||||||
|
out.changed = ImGui::InputText(
|
||||||
|
label.c_str(), out.text.data(), MaxChars + 1, flags, callback, user_data);
|
||||||
|
if (out.changed) {
|
||||||
|
std::ignore = out.text.unsafeResize(ox::strlen(out.text.c_str()));
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
template<size_t StrCap>
|
template<size_t StrCap>
|
||||||
bool InputText(
|
bool InputText(
|
||||||
ox::CStringView label,
|
ox::CStringViewCR label,
|
||||||
ox::IString<StrCap> &text,
|
ox::IString<StrCap> &text,
|
||||||
ImGuiInputTextFlags const flags = 0,
|
ImGuiInputTextFlags const flags = 0,
|
||||||
ImGuiInputTextCallback const callback = nullptr,
|
ImGuiInputTextCallback const callback = nullptr,
|
||||||
|
@ -17,13 +17,22 @@ class NoChangesException: public ox::Exception {
|
|||||||
};
|
};
|
||||||
|
|
||||||
class UndoCommand {
|
class UndoCommand {
|
||||||
|
private:
|
||||||
|
bool m_obsolete{};
|
||||||
public:
|
public:
|
||||||
virtual ~UndoCommand() noexcept = default;
|
virtual ~UndoCommand() noexcept = default;
|
||||||
virtual ox::Error redo() noexcept = 0;
|
virtual ox::Error redo() noexcept = 0;
|
||||||
virtual ox::Error undo() noexcept = 0;
|
virtual ox::Error undo() noexcept = 0;
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
virtual int commandId() const noexcept = 0;
|
virtual int commandId() const noexcept = 0;
|
||||||
virtual bool mergeWith(UndoCommand const&cmd) noexcept;
|
virtual bool mergeWith(UndoCommand &cmd) noexcept;
|
||||||
|
constexpr void setObsolete(bool obsolete) noexcept {
|
||||||
|
m_obsolete = obsolete;
|
||||||
|
}
|
||||||
|
[[nodiscard]]
|
||||||
|
constexpr bool isObsolete() const noexcept {
|
||||||
|
return m_obsolete;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -36,10 +36,6 @@ void BaseEditor::keyStateChanged(turbine::Key, bool) {
|
|||||||
void BaseEditor::onActivated() noexcept {
|
void BaseEditor::onActivated() noexcept {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BaseEditor::requiresConstantRefresh() const noexcept {
|
|
||||||
return m_requiresConstantRefresh;
|
|
||||||
}
|
|
||||||
|
|
||||||
void BaseEditor::close() const {
|
void BaseEditor::close() const {
|
||||||
this->closed.emit(itemPath());
|
this->closed.emit(itemPath());
|
||||||
}
|
}
|
||||||
@ -66,12 +62,12 @@ bool BaseEditor::unsavedChanges() const noexcept {
|
|||||||
return m_unsavedChanges;
|
return m_unsavedChanges;
|
||||||
}
|
}
|
||||||
|
|
||||||
void BaseEditor::setExportable(bool exportable) {
|
void BaseEditor::setExportable(bool exportable) noexcept {
|
||||||
m_exportable = exportable;
|
m_exportable = exportable;
|
||||||
exportableChanged.emit(exportable);
|
exportableChanged.emit(exportable);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BaseEditor::exportable() const {
|
bool BaseEditor::exportable() const noexcept {
|
||||||
return m_exportable;
|
return m_exportable;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -110,10 +106,6 @@ UndoStack *BaseEditor::undoStack() noexcept {
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void BaseEditor::setRequiresConstantRefresh(bool value) noexcept {
|
|
||||||
m_requiresConstantRefresh = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Editor::Editor(ox::StringParam itemPath) noexcept:
|
Editor::Editor(ox::StringParam itemPath) noexcept:
|
||||||
m_itemPath(std::move(itemPath)),
|
m_itemPath(std::move(itemPath)),
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
namespace studio {
|
namespace studio {
|
||||||
|
|
||||||
bool UndoCommand::mergeWith(UndoCommand const&) noexcept {
|
bool UndoCommand::mergeWith(UndoCommand&) noexcept {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,6 +17,10 @@ ox::Error UndoStack::push(ox::UPtr<UndoCommand> &&cmd) noexcept {
|
|||||||
m_stack.emplace_back(std::move(cmd));
|
m_stack.emplace_back(std::move(cmd));
|
||||||
++m_stackIdx;
|
++m_stackIdx;
|
||||||
}
|
}
|
||||||
|
if ((*m_stack.back().unwrap())->isObsolete()) {
|
||||||
|
m_stack.pop_back();
|
||||||
|
--m_stackIdx;
|
||||||
|
}
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user