diff --git a/src/nostalgia/core/gba/core.arm.cpp b/src/nostalgia/core/gba/core.arm.cpp index 7ee1e217..f644e937 100644 --- a/src/nostalgia/core/gba/core.arm.cpp +++ b/src/nostalgia/core/gba/core.arm.cpp @@ -10,8 +10,6 @@ #include "irq.hpp" #include "core.hpp" -extern "C" void isr(); - namespace nostalgia::core { extern volatile gba_timer_t g_timerMs; diff --git a/src/nostalgia/core/studio/CMakeLists.txt b/src/nostalgia/core/studio/CMakeLists.txt index 8e7d73f2..5c1157f5 100644 --- a/src/nostalgia/core/studio/CMakeLists.txt +++ b/src/nostalgia/core/studio/CMakeLists.txt @@ -5,6 +5,7 @@ add_library( #new_tilesheet_wizard.cpp #newpalettewizard.cpp paletteeditor.cpp + paletteeditor-imgui.cpp tilesheeteditor-imgui.cpp tilesheeteditorview.cpp tilesheeteditormodel.cpp diff --git a/src/nostalgia/core/studio/module.cpp b/src/nostalgia/core/studio/module.cpp index e5e60d7b..ccef63f2 100644 --- a/src/nostalgia/core/studio/module.cpp +++ b/src/nostalgia/core/studio/module.cpp @@ -2,7 +2,7 @@ * Copyright 2016 - 2022 Gary Talent (gary@drinkingtea.net). All rights reserved. */ -#include "paletteeditor.hpp" +#include "paletteeditor-imgui.hpp" #include "tilesheeteditor-imgui.hpp" #include "module.hpp" diff --git a/src/nostalgia/core/studio/paletteeditor-imgui.cpp b/src/nostalgia/core/studio/paletteeditor-imgui.cpp new file mode 100644 index 00000000..f9956904 --- /dev/null +++ b/src/nostalgia/core/studio/paletteeditor-imgui.cpp @@ -0,0 +1,156 @@ +/* + * Copyright 2016 - 2022 Gary Talent (gary@drinkingtea.net). All rights reserved. + */ + +#include + +#include +#include +#include + +#include "paletteeditor.hpp" +#include "paletteeditor-imgui.hpp" + +namespace nostalgia::core { + +ox::Result PaletteEditorImGui::make(Context *ctx, const ox::String &path) noexcept { + auto out = ox::UniquePtr(new PaletteEditorImGui); + out->m_ctx = ctx; + out->m_itemPath = path; + const auto lastSlash = std::find(out->m_itemPath.rbegin(), out->m_itemPath.rend(), '/').offset(); + out->m_itemName = out->m_itemPath.substr(lastSlash + 1); + oxRequire(pal, core::readObj(out->m_ctx, out->m_itemPath)); + out->m_pal = *pal.get(); + out->undoStack()->changeTriggered.connect(out.get(), &PaletteEditorImGui::markUnsavedChanges); + return out.release(); +} + +const ox::String &PaletteEditorImGui::itemName() const { + return m_itemPath; +} + +const ox::String &PaletteEditorImGui::itemDisplayName() const noexcept { + return m_itemName; +} + +studio::UndoStack *PaletteEditorImGui::undoStack() noexcept { + return &m_undoStack; +} + +void PaletteEditorImGui::draw(core::Context*) noexcept { + static constexpr auto flags = ImGuiTableFlags_RowBg; + const auto paneSize = ImGui::GetContentRegionAvail(); + ImGui::BeginChild("PaletteEditor"); + { + ImGui::BeginChild("Colors", ImVec2(paneSize.x - 200, paneSize.y), false); + { + const auto colorsSz = ImGui::GetContentRegionAvail(); + static constexpr auto toolbarHeight = 40; + ImGui::BeginChild("Toolbar", ImVec2(colorsSz.x, toolbarHeight), true); + { + const auto sz = ImVec2(70, 24); + if (ImGui::Button("Add", sz)) { + m_undoStack.push(new AddColorCommand(&m_pal, 0, m_pal.colors.size())); + } + ImGui::SameLine(); + ImGui::BeginDisabled(m_selectedRow >= m_pal.colors.size()); + { + if (ImGui::Button("Remove", sz)) { + m_undoStack.push(new RemoveColorCommand(&m_pal, m_pal.colors[static_cast(m_selectedRow)], m_selectedRow)); + m_selectedRow = ox::min(m_pal.colors.size() - 1, m_selectedRow); + } + ImGui::SameLine(); + ImGui::BeginDisabled(m_selectedRow <= 0); + { + if (ImGui::Button("Move Up", sz)) { + m_undoStack.push(new MoveColorCommand(&m_pal, m_selectedRow, -1)); + --m_selectedRow; + } + } + ImGui::EndDisabled(); + ImGui::SameLine(); + ImGui::BeginDisabled(m_selectedRow >= m_pal.colors.size() - 1); + { + if (ImGui::Button("Move Down", sz)) { + m_undoStack.push(new MoveColorCommand(&m_pal, m_selectedRow, 1)); + ++m_selectedRow; + } + } + ImGui::EndDisabled(); + } + ImGui::EndDisabled(); + } + ImGui::EndChild(); + ImGui::BeginTable("Colors", 5, flags, ImVec2(colorsSz.x, colorsSz.y - (toolbarHeight + 5))); + { + ImGui::TableSetupColumn("Idx", ImGuiTableColumnFlags_WidthFixed, 25); + ImGui::TableSetupColumn("Red", ImGuiTableColumnFlags_WidthFixed, 50); + ImGui::TableSetupColumn("Green", ImGuiTableColumnFlags_WidthFixed, 50); + ImGui::TableSetupColumn("Blue", ImGuiTableColumnFlags_WidthFixed, 50); + ImGui::TableSetupColumn("Color Preview", ImGuiTableColumnFlags_NoHide); + ImGui::TableHeadersRow(); + for (auto i = 0u; const auto c : m_pal.colors) { + ImGui::PushID(static_cast(i)); + ImGui::TableNextRow(); + // Color No. + ImGui::TableNextColumn(); + ImGui::Text("%d", i); + // Red + ImGui::TableNextColumn(); + ImGui::Text("%d", red16(c)); + // Green + ImGui::TableNextColumn(); + ImGui::Text("%d", green16(c)); + // Blue + ImGui::TableNextColumn(); + ImGui::Text("%d", blue16(c)); + // ColorPreview + ImGui::TableNextColumn(); + const auto ic = ImGui::GetColorU32(ImVec4(redf(c), greenf(c), bluef(c), 1)); + ImGui::TableSetBgColor(ImGuiTableBgTarget_CellBg, ic); + if (ImGui::Selectable("##ColorRow", i == m_selectedRow, ImGuiSelectableFlags_SpanAllColumns)) { + m_selectedRow = i; + } + ImGui::PopID(); + ++i; + } + } + ImGui::EndTable(); + } + ImGui::EndChild(); + if (m_selectedRow < m_pal.colors.size()) { + ImGui::SameLine(); + ImGui::BeginChild("ColorEditor", ImVec2(200, paneSize.y), true); + { + const auto c = m_pal.colors[m_selectedRow]; + int r = red16(c); + int g = green16(c); + int b = blue16(c); + int a = alpha16(c); + ImGui::InputInt("Red", &r, 1, 5); + ImGui::InputInt("Green", &g, 1, 5); + ImGui::InputInt("Blue", &b, 1, 5); + const auto newColor = color16(r, g, b, a); + if (c != newColor) { + m_undoStack.push(new UpdateColorCommand(&m_pal, m_selectedRow, c, newColor)); + } + } + ImGui::EndChild(); + } + } + ImGui::EndChild(); +} + +ox::Error PaletteEditorImGui::saveItem() noexcept { + const auto sctx = applicationData(m_ctx); + oxReturnError(sctx->project->writeObj(m_itemPath, &m_pal)); + oxReturnError(m_ctx->assetManager.setAsset(m_itemPath, m_pal)); + return OxError(0); +} + +ox::Error PaletteEditorImGui::markUnsavedChanges(int) noexcept { + setUnsavedChanges(true); + return OxError(0); +} + +} diff --git a/src/nostalgia/core/studio/paletteeditor-imgui.hpp b/src/nostalgia/core/studio/paletteeditor-imgui.hpp new file mode 100644 index 00000000..2c8e5c90 --- /dev/null +++ b/src/nostalgia/core/studio/paletteeditor-imgui.hpp @@ -0,0 +1,46 @@ +/* + * Copyright 2016 - 2022 Gary Talent (gary@drinkingtea.net). All rights reserved. + */ + +#pragma once + +#include +#include + +namespace nostalgia::core { + +class PaletteEditorImGui: public studio::Editor { + + private: + Context *m_ctx = nullptr; + ox::String m_itemName; + ox::String m_itemPath; + Palette m_pal; + std::size_t m_selectedRow = 0; + studio::UndoStack m_undoStack; + + PaletteEditorImGui() noexcept = default; + + public: + static ox::Result make(Context *ctx, const ox::String &path) noexcept; + + /** + * Returns the name of item being edited. + */ + const ox::String &itemName() const override; + + const ox::String &itemDisplayName() const noexcept override; + + void draw(core::Context*) noexcept override; + + protected: + studio::UndoStack *undoStack() noexcept final; + + ox::Error saveItem() noexcept override; + + private: + ox::Error markUnsavedChanges(int) noexcept; + +}; + +} diff --git a/src/nostalgia/core/studio/paletteeditor.cpp b/src/nostalgia/core/studio/paletteeditor.cpp index 6c19f44a..9dab758e 100644 --- a/src/nostalgia/core/studio/paletteeditor.cpp +++ b/src/nostalgia/core/studio/paletteeditor.cpp @@ -2,318 +2,104 @@ * Copyright 2016 - 2022 Gary Talent (gary@drinkingtea.net). All rights reserved. */ -#include - -#include - -#include -#include -#include - #include "paletteeditor.hpp" namespace nostalgia::core { -enum class PaletteEditorCommandId { - AddColor, - RemoveColor, - UpdateColor, - MoveColor, -}; - - -class AddColorCommand: public studio::UndoCommand { - private: - PaletteEditorImGui *m_editor = nullptr; - Color16 m_color = 0; - int m_idx = -1; - - public: - AddColorCommand(PaletteEditorImGui *editor, Color16 color, int idx) noexcept { - m_editor = editor; - m_color = color; - m_idx = idx; - } - - ~AddColorCommand() noexcept override = default; - - [[nodiscard]] - int commandId() const noexcept override { - return static_cast(PaletteEditorCommandId::AddColor); - } - - void redo() noexcept override { - m_editor->addColor(m_idx, m_color); - } - - void undo() noexcept override { - m_editor->rmColor(m_idx); - } - -}; - -class RemoveColorCommand: public studio::UndoCommand { - private: - PaletteEditorImGui *m_editor = nullptr; - Color16 m_color = 0; - int m_idx = -1; - - public: - RemoveColorCommand(PaletteEditorImGui *editor, Color16 color, int idx) noexcept { - m_editor = editor; - m_color = color; - m_idx = idx; - } - - ~RemoveColorCommand() noexcept override = default; - - [[nodiscard]] - int commandId() const noexcept override { - return static_cast(PaletteEditorCommandId::RemoveColor); - } - - void redo() noexcept override { - m_editor->rmColor(m_idx); - } - - void undo() noexcept override { - m_editor->addColor(m_idx, m_color); - } - -}; - -class UpdateColorCommand: public studio::UndoCommand { - private: - PaletteEditorImGui *m_editor = nullptr; - Color16 m_oldColor = 0; - Color16 m_newColor = 0; - int m_idx = -1; - - public: - UpdateColorCommand(PaletteEditorImGui *editor, int idx, Color16 oldColor, Color16 newColor) noexcept { - m_editor = editor; - m_idx = idx; - m_oldColor = oldColor; - m_newColor = newColor; - //setObsolete(m_oldColor == m_newColor); - } - - ~UpdateColorCommand() noexcept override = default; - - bool mergeWith(const UndoCommand *cmd) noexcept final { - if (cmd->commandId() != static_cast(PaletteEditorCommandId::UpdateColor)) { - return false; - } - auto ucCmd = static_cast(cmd); - if (m_idx != ucCmd->m_idx) { - return false; - } - m_newColor = ucCmd->m_newColor; - return true; - } - - int commandId() const noexcept final { - return static_cast(PaletteEditorCommandId::UpdateColor); - } - - void redo() noexcept final { - m_editor->updateColor(m_idx, m_newColor); - } - - void undo() noexcept final { - m_editor->updateColor(m_idx, m_oldColor); - } - -}; - -class MoveColorCommand: public studio::UndoCommand { - private: - PaletteEditorImGui *m_editor = nullptr; - std::size_t m_idx = 0; - int m_offset = 0; - - public: - MoveColorCommand(PaletteEditorImGui *editor, std::size_t idx, int offset) noexcept { - m_editor = editor; - m_idx = idx; - m_offset = offset; - } - - ~MoveColorCommand() noexcept override = default; - - [[nodiscard]] - int commandId() const noexcept override { - return static_cast(PaletteEditorCommandId::MoveColor); - } - - void redo() noexcept override { - m_editor->moveColor(m_idx, m_offset); - } - - void undo() noexcept override { - m_editor->moveColor(static_cast(m_idx) + m_offset, -m_offset); - } - -}; - - -ox::Result PaletteEditorImGui::make(Context *ctx, const ox::String &path) noexcept { - auto out = ox::UniquePtr(new PaletteEditorImGui); - out->m_ctx = ctx; - out->m_itemPath = path; - const auto lastSlash = std::find(out->m_itemPath.rbegin(), out->m_itemPath.rend(), '/').offset(); - out->m_itemName = out->m_itemPath.substr(lastSlash + 1); - oxRequire(pal, core::readObj(out->m_ctx, out->m_itemPath)); - out->m_pal = *pal.get(); - out->undoStack()->changeTriggered.connect(out.get(), &PaletteEditorImGui::markUnsavedChanges); - return out.release(); +AddColorCommand::AddColorCommand(Palette *pal, Color16 color, int idx) noexcept { + m_pal = pal; + m_color = color; + m_idx = idx; } -const ox::String &PaletteEditorImGui::itemName() const { - return m_itemPath; +int AddColorCommand::commandId() const noexcept { + return static_cast(PaletteEditorCommandId::AddColor); } -const ox::String &PaletteEditorImGui::itemDisplayName() const noexcept { - return m_itemName; +void AddColorCommand::redo() noexcept { + m_pal->colors.insert(static_cast(m_idx), m_color); } -studio::UndoStack *PaletteEditorImGui::undoStack() noexcept { - return &m_undoStack; +void AddColorCommand::undo() noexcept { + oxIgnoreError(m_pal->colors.erase(static_cast(m_idx))); } -void PaletteEditorImGui::draw(core::Context*) noexcept { - static constexpr auto flags = ImGuiTableFlags_RowBg; - const auto paneSize = ImGui::GetContentRegionAvail(); - ImGui::BeginChild("PaletteEditor"); - { - ImGui::BeginChild("Colors", ImVec2(paneSize.x - 200, paneSize.y), false); - { - const auto colorsSz = ImGui::GetContentRegionAvail(); - static constexpr auto toolbarHeight = 40; - ImGui::BeginChild("Toolbar", ImVec2(colorsSz.x, toolbarHeight), true); - { - const auto sz = ImVec2(70, 24); - if (ImGui::Button("Add", sz)) { - m_undoStack.push(new AddColorCommand(this, 0, m_pal.colors.size())); - } - ImGui::SameLine(); - ImGui::BeginDisabled(m_selectedRow >= m_pal.colors.size()); - { - if (ImGui::Button("Remove", sz)) { - m_undoStack.push(new RemoveColorCommand(this, m_pal.colors[static_cast(m_selectedRow)], m_selectedRow)); - m_selectedRow = ox::min(m_pal.colors.size() - 1, m_selectedRow); - } - ImGui::SameLine(); - ImGui::BeginDisabled(m_selectedRow <= 0); - { - if (ImGui::Button("Move Up", sz)) { - m_undoStack.push(new MoveColorCommand(this, m_selectedRow, -1)); - --m_selectedRow; - } - } - ImGui::EndDisabled(); - ImGui::SameLine(); - ImGui::BeginDisabled(m_selectedRow >= m_pal.colors.size() - 1); - { - if (ImGui::Button("Move Down", sz)) { - m_undoStack.push(new MoveColorCommand(this, m_selectedRow, 1)); - ++m_selectedRow; - } - } - ImGui::EndDisabled(); - } - ImGui::EndDisabled(); - } - ImGui::EndChild(); - ImGui::BeginTable("Colors", 5, flags, ImVec2(colorsSz.x, colorsSz.y - (toolbarHeight + 5))); - { - ImGui::TableSetupColumn("Idx", ImGuiTableColumnFlags_WidthFixed, 25); - ImGui::TableSetupColumn("Red", ImGuiTableColumnFlags_WidthFixed, 50); - ImGui::TableSetupColumn("Green", ImGuiTableColumnFlags_WidthFixed, 50); - ImGui::TableSetupColumn("Blue", ImGuiTableColumnFlags_WidthFixed, 50); - ImGui::TableSetupColumn("Color Preview", ImGuiTableColumnFlags_NoHide); - ImGui::TableHeadersRow(); - for (auto i = 0u; const auto c : m_pal.colors) { - ImGui::PushID(static_cast(i)); - ImGui::TableNextRow(); - // Color No. - ImGui::TableNextColumn(); - ImGui::Text("%d", i); - // Red - ImGui::TableNextColumn(); - ImGui::Text("%d", red16(c)); - // Green - ImGui::TableNextColumn(); - ImGui::Text("%d", green16(c)); - // Blue - ImGui::TableNextColumn(); - ImGui::Text("%d", blue16(c)); - // ColorPreview - ImGui::TableNextColumn(); - const auto ic = ImGui::GetColorU32(ImVec4(redf(c), greenf(c), bluef(c), 1)); - ImGui::TableSetBgColor(ImGuiTableBgTarget_CellBg, ic); - if (ImGui::Selectable("##ColorRow", i == m_selectedRow, ImGuiSelectableFlags_SpanAllColumns)) { - m_selectedRow = i; - } - ImGui::PopID(); - ++i; - } - } - ImGui::EndTable(); - } - ImGui::EndChild(); - if (m_selectedRow < m_pal.colors.size()) { - ImGui::SameLine(); - ImGui::BeginChild("ColorEditor", ImVec2(200, paneSize.y), true); - { - const auto c = m_pal.colors[m_selectedRow]; - int r = red16(c); - int g = green16(c); - int b = blue16(c); - int a = alpha16(c); - ImGui::InputInt("Red", &r, 1, 5); - ImGui::InputInt("Green", &g, 1, 5); - ImGui::InputInt("Blue", &b, 1, 5); - const auto newColor = color16(r, g, b, a); - if (c != newColor) { - m_undoStack.push(new UpdateColorCommand(this, m_selectedRow, c, newColor)); - } - } - ImGui::EndChild(); - } + +RemoveColorCommand::RemoveColorCommand(Palette *pal, Color16 color, int idx) noexcept { + m_pal = pal; + m_color = color; + m_idx = idx; +} + +int RemoveColorCommand::commandId() const noexcept { + return static_cast(PaletteEditorCommandId::RemoveColor); +} + +void RemoveColorCommand::redo() noexcept { + oxIgnoreError(m_pal->colors.erase(static_cast(m_idx))); +} + +void RemoveColorCommand::undo() noexcept { +m_pal->colors.insert(static_cast(m_idx), m_color); +} + + +UpdateColorCommand::UpdateColorCommand(Palette *pal, int idx, Color16 oldColor, Color16 newColor) noexcept { + m_pal = pal; + m_idx = idx; + m_oldColor = oldColor; + m_newColor = newColor; + //setObsolete(m_oldColor == m_newColor); +} + +bool UpdateColorCommand::mergeWith(const UndoCommand *cmd) noexcept { + if (cmd->commandId() != static_cast(PaletteEditorCommandId::UpdateColor)) { + return false; } - ImGui::EndChild(); + auto ucCmd = static_cast(cmd); + if (m_idx != ucCmd->m_idx) { + return false; + } + m_newColor = ucCmd->m_newColor; + return true; } -void PaletteEditorImGui::addColor(int idx, Color16 c) noexcept { - m_pal.colors.insert(static_cast(idx), c); - setUnsavedChanges(true); +[[nodiscard]] +int UpdateColorCommand::commandId() const noexcept { + return static_cast(PaletteEditorCommandId::UpdateColor); } -void PaletteEditorImGui::rmColor(int idx) noexcept { - oxIgnoreError(m_pal.colors.erase(static_cast(idx))); - setUnsavedChanges(true); +void UpdateColorCommand::redo() noexcept { + m_pal->colors[static_cast(m_idx)] = m_newColor; } -void PaletteEditorImGui::updateColor(int idx, Color16 c) noexcept { - m_pal.colors[static_cast(idx)] = c; - setUnsavedChanges(true); +void UpdateColorCommand::undo() noexcept { + m_pal->colors[static_cast(m_idx)] = m_oldColor; } -void PaletteEditorImGui::moveColor(int idx, int offset) noexcept { - const auto c = m_pal.colors[static_cast(idx)]; - oxIgnoreError(m_pal.colors.erase(static_cast(idx))); - m_pal.colors.insert(static_cast(idx + offset), c); - setUnsavedChanges(true); + +MoveColorCommand::MoveColorCommand(Palette *pal, std::size_t idx, int offset) noexcept { + m_pal = pal; + m_idx = idx; + m_offset = offset; } -void PaletteEditorImGui::saveItem() { - //m_ctx->project->writeObj(m_itemPath, &m_pal); +int MoveColorCommand::commandId() const noexcept { + return static_cast(PaletteEditorCommandId::MoveColor); } -ox::Error PaletteEditorImGui::markUnsavedChanges(int) noexcept { - setUnsavedChanges(true); - return OxError(0); +void MoveColorCommand::redo() noexcept { + moveColor(static_cast(m_idx), m_offset); } +void MoveColorCommand::undo() noexcept { + moveColor(static_cast(m_idx) + m_offset, -m_offset); } + +void MoveColorCommand::moveColor(int idx, int offset) noexcept { + const auto c = m_pal->colors[static_cast(idx)]; + oxIgnoreError(m_pal->colors.erase(static_cast(idx))); + m_pal->colors.insert(static_cast(idx + offset), c); +} + +} \ No newline at end of file diff --git a/src/nostalgia/core/studio/paletteeditor.hpp b/src/nostalgia/core/studio/paletteeditor.hpp index 6047b490..a3f5fcf1 100644 --- a/src/nostalgia/core/studio/paletteeditor.hpp +++ b/src/nostalgia/core/studio/paletteeditor.hpp @@ -4,58 +4,104 @@ #pragma once -#include "nostalgia/studio/lib/undostack.hpp" #include #include -#include namespace nostalgia::core { -class PaletteEditorImGui: public studio::Editor { +enum class PaletteEditorCommandId { + AddColor, + RemoveColor, + UpdateColor, + MoveColor, +}; - friend class AddColorCommand; - friend class RemoveColorCommand; - friend class UpdateColorCommand; - friend class MoveColorCommand; +class AddColorCommand: public studio::UndoCommand { private: - Context *m_ctx = nullptr; - ox::String m_itemName; - ox::String m_itemPath; - Palette m_pal; - std::size_t m_selectedRow = 0; - studio::UndoStack m_undoStack; - - PaletteEditorImGui() noexcept = default; + Palette *m_pal = nullptr; + Color16 m_color = 0; + int m_idx = -1; public: - static ox::Result make(Context *ctx, const ox::String &path) noexcept; + AddColorCommand(Palette *pal, Color16 color, int idx) noexcept; - /** - * Returns the name of item being edited. - */ - const ox::String &itemName() const override; + ~AddColorCommand() noexcept override = default; - const ox::String &itemDisplayName() const noexcept override; + [[nodiscard]] + int commandId() const noexcept override; - void draw(core::Context*) noexcept override; + void redo() noexcept override; - studio::UndoStack *undoStack() noexcept final; - - protected: - void addColor(int idx, Color16 c) noexcept; - - void rmColor(int idx) noexcept; - - void updateColor(int idx, Color16) noexcept; - - void moveColor(int idx, int offset) noexcept; - - void saveItem() override; - - private: - ox::Error markUnsavedChanges(int) noexcept; + void undo() noexcept override; }; -} +class RemoveColorCommand: public studio::UndoCommand { + private: + Palette *m_pal = nullptr; + Color16 m_color = 0; + int m_idx = -1; + + public: + RemoveColorCommand(Palette *pal, Color16 color, int idx) noexcept; + + ~RemoveColorCommand() noexcept override = default; + + [[nodiscard]] + int commandId() const noexcept override; + + void redo() noexcept override; + + void undo() noexcept override; + +}; + +class UpdateColorCommand: public studio::UndoCommand { + private: + Palette *m_pal = nullptr; + Color16 m_oldColor = 0; + Color16 m_newColor = 0; + int m_idx = -1; + + public: + UpdateColorCommand(Palette *pal, int idx, Color16 oldColor, Color16 newColor) noexcept; + + ~UpdateColorCommand() noexcept override = default; + + [[nodiscard]] + bool mergeWith(const UndoCommand *cmd) noexcept final; + + [[nodiscard]] + int commandId() const noexcept final; + + void redo() noexcept final; + + void undo() noexcept final; + +}; + +class MoveColorCommand: public studio::UndoCommand { + private: + Palette *m_pal = nullptr; + std::size_t m_idx = 0; + int m_offset = 0; + + public: + MoveColorCommand(Palette *pal, std::size_t idx, int offset) noexcept; + + ~MoveColorCommand() noexcept override = default; + + [[nodiscard]] + int commandId() const noexcept override; + + public: + void redo() noexcept override; + + void undo() noexcept override; + + private: + void moveColor(int idx, int offset) noexcept; +}; + +} \ No newline at end of file diff --git a/src/nostalgia/core/studio/tilesheeteditor-imgui.cpp b/src/nostalgia/core/studio/tilesheeteditor-imgui.cpp index 95d603bb..13ba7a14 100644 --- a/src/nostalgia/core/studio/tilesheeteditor-imgui.cpp +++ b/src/nostalgia/core/studio/tilesheeteditor-imgui.cpp @@ -182,13 +182,8 @@ studio::UndoStack *TileSheetEditorImGui::undoStack() noexcept { return model()->undoStack(); } -void TileSheetEditorImGui::saveItem() { - const auto err = model()->saveFile(); - if (!err) { - this->setUnsavedChanges(false); - } else { - oxErrorf("Could not save file {}: {}", m_itemPath, toStr(err)); - } +ox::Error TileSheetEditorImGui::saveItem() noexcept { + return model()->saveFile(); } void TileSheetEditorImGui::drawTileSheet(const geo::Vec2 &fbSize) noexcept { diff --git a/src/nostalgia/core/studio/tilesheeteditor-imgui.hpp b/src/nostalgia/core/studio/tilesheeteditor-imgui.hpp index 7bf9ac42..9d01bab7 100644 --- a/src/nostalgia/core/studio/tilesheeteditor-imgui.hpp +++ b/src/nostalgia/core/studio/tilesheeteditor-imgui.hpp @@ -77,7 +77,7 @@ class TileSheetEditorImGui: public studio::Editor { studio::UndoStack *undoStack() noexcept final; protected: - void saveItem() override; + ox::Error saveItem() noexcept override; private: [[nodiscard]] diff --git a/src/nostalgia/studio/lib/CMakeLists.txt b/src/nostalgia/studio/lib/CMakeLists.txt index 65015f09..d5b623fd 100644 --- a/src/nostalgia/studio/lib/CMakeLists.txt +++ b/src/nostalgia/studio/lib/CMakeLists.txt @@ -16,7 +16,6 @@ add_library( task.cpp undostack.cpp widget.cpp - window.cpp filedialog_gtk.cpp $<$:filedialog_mac.mm> ) @@ -59,7 +58,6 @@ install( task.hpp undostack.hpp widget.hpp - window.hpp ${CMAKE_CURRENT_BINARY_DIR}/nostalgiastudio_export.h DESTINATION include/nostalgia/studio/lib diff --git a/src/nostalgia/studio/lib/editor.cpp b/src/nostalgia/studio/lib/editor.cpp index 06d91b94..d9f93140 100644 --- a/src/nostalgia/studio/lib/editor.cpp +++ b/src/nostalgia/studio/lib/editor.cpp @@ -28,9 +28,13 @@ void Editor::close() { this->closed.emit(itemName()); } -void Editor::save() { - saveItem(); - setUnsavedChanges(false); +void Editor::save() noexcept { + const auto err = saveItem(); + if (!err) { + setUnsavedChanges(false); + } else { + oxErrorf("Could not save file {}: {}", itemName(), toStr(err)); + } } void Editor::setUnsavedChanges(bool uc) { @@ -78,7 +82,8 @@ bool Editor::pasteEnabled() const { return m_pasteEnabled; } -void Editor::saveItem() { +ox::Error Editor::saveItem() noexcept { + return OxError(0); } } diff --git a/src/nostalgia/studio/lib/editor.hpp b/src/nostalgia/studio/lib/editor.hpp index 1c549893..a0ec1a3d 100644 --- a/src/nostalgia/studio/lib/editor.hpp +++ b/src/nostalgia/studio/lib/editor.hpp @@ -11,12 +11,17 @@ #include "nostalgiastudio_export.h" +namespace nostalgia { +class StudioUI; +} + namespace nostalgia::studio { class NOSTALGIASTUDIO_EXPORT Editor: public Widget { + friend StudioUI; + private: - UndoStack m_cmdStack; bool m_unsavedChanges = false; bool m_exportable = false; bool m_cutEnabled = false; @@ -43,20 +48,12 @@ class NOSTALGIASTUDIO_EXPORT Editor: public Widget { virtual void exportFile(); - /** - * Returns the undo stack holding changes to the item being edited. - */ - [[nodiscard]] - virtual UndoStack *undoStack() noexcept { - return nullptr; - } - void close(); /** * Save changes to item being edited. */ - void save(); + void save() noexcept; /** * Sets indication of item being edited has unsaved changes. Also emits @@ -91,7 +88,15 @@ class NOSTALGIASTUDIO_EXPORT Editor: public Widget { /** * Save changes to item being edited. */ - virtual void saveItem(); + virtual ox::Error saveItem() noexcept; + + /** + * Returns the undo stack holding changes to the item being edited. + */ + [[nodiscard]] + virtual UndoStack *undoStack() noexcept { + return nullptr; + } // signals public: diff --git a/src/nostalgia/studio/lib/project.hpp b/src/nostalgia/studio/lib/project.hpp index a3b6af3e..23a0e2aa 100644 --- a/src/nostalgia/studio/lib/project.hpp +++ b/src/nostalgia/studio/lib/project.hpp @@ -4,8 +4,6 @@ #pragma once -#include - #include #include #include diff --git a/src/nostalgia/studio/lib/window.cpp b/src/nostalgia/studio/lib/window.cpp deleted file mode 100644 index 96f9d3aa..00000000 --- a/src/nostalgia/studio/lib/window.cpp +++ /dev/null @@ -1,9 +0,0 @@ -/* - * Copyright 2016 - 2022 Gary Talent (gary@drinkingtea.net). All rights reserved. - */ - -#include "window.hpp" - - - - diff --git a/src/nostalgia/studio/lib/window.hpp b/src/nostalgia/studio/lib/window.hpp deleted file mode 100644 index c2d6f093..00000000 --- a/src/nostalgia/studio/lib/window.hpp +++ /dev/null @@ -1,15 +0,0 @@ -/* - * Copyright 2016 - 2022 Gary Talent (gary@drinkingtea.net). All rights reserved. - */ - -#pragma once - -#include "widget.hpp" - -namespace nostalgia::studio { - -class Window: public Widget { - -}; - -} \ No newline at end of file diff --git a/src/nostalgia/studio/studioapp.hpp b/src/nostalgia/studio/studioapp.hpp index 03440c30..0f78ec37 100644 --- a/src/nostalgia/studio/studioapp.hpp +++ b/src/nostalgia/studio/studioapp.hpp @@ -42,6 +42,7 @@ class StudioUI: public ox::SignalHandler { void handleKeyEvent(core::Key, bool down) noexcept; + [[nodiscard]] constexpr auto project() noexcept { return m_project.get(); }