From d1c6ab9f77e2fc98d6ee1f8f838bb580dd415715 Mon Sep 17 00:00:00 2001 From: Gary Talent Date: Thu, 14 Dec 2023 19:36:10 -0600 Subject: [PATCH] [nostalgia/core/studio] Cleanup TileSheetEditor, make it set copy/cut/paste enabled/disabled --- .../tilesheeteditor/tilesheeteditor-imgui.cpp | 115 ++++++++++-------- .../tilesheeteditor/tilesheeteditor-imgui.hpp | 13 +- .../tilesheeteditor/tilesheeteditormodel.hpp | 12 -- .../tilesheeteditor/tilesheeteditorview.hpp | 8 +- 4 files changed, 67 insertions(+), 81 deletions(-) diff --git a/src/nostalgia/modules/core/src/studio/tilesheeteditor/tilesheeteditor-imgui.cpp b/src/nostalgia/modules/core/src/studio/tilesheeteditor/tilesheeteditor-imgui.cpp index d30b19b0..ac39cf92 100644 --- a/src/nostalgia/modules/core/src/studio/tilesheeteditor/tilesheeteditor-imgui.cpp +++ b/src/nostalgia/modules/core/src/studio/tilesheeteditor/tilesheeteditor-imgui.cpp @@ -42,14 +42,15 @@ ox::Error toPngFile( } TileSheetEditorImGui::TileSheetEditorImGui(turbine::Context &ctx, ox::CRStringView path): - Editor(path), - m_ctx(ctx), - m_tileSheetEditor(m_ctx, path, *undoStack()) { + Editor(path), + m_ctx(ctx), + m_view(m_ctx, path, *undoStack()), + m_model(m_view.model()) { oxIgnoreError(setPaletteSelection()); // connect signal/slots undoStack()->changeTriggered.connect(this, &TileSheetEditorImGui::markUnsavedChanges); m_subsheetEditor.inputSubmitted.connect(this, &TileSheetEditorImGui::updateActiveSubsheet); - model()->paletteChanged.connect(this, &TileSheetEditorImGui::setPaletteSelection); + m_model.paletteChanged.connect(this, &TileSheetEditorImGui::setPaletteSelection); } void TileSheetEditorImGui::exportFile() { @@ -57,15 +58,15 @@ void TileSheetEditorImGui::exportFile() { } void TileSheetEditorImGui::cut() { - model()->cut(); + m_model.cut(); } void TileSheetEditorImGui::copy() { - model()->copy(); + m_model.copy(); } void TileSheetEditorImGui::paste() { - model()->paste(); + m_model.paste(); } void TileSheetEditorImGui::keyStateChanged(turbine::Key key, bool down) { @@ -75,23 +76,32 @@ void TileSheetEditorImGui::keyStateChanged(turbine::Key key, bool down) { if (key == turbine::Key::Escape) { m_subsheetEditor.close(); } - auto pal = model()->pal(); + auto pal = m_model.pal(); if (pal) { const auto colorCnt = pal->colors.size(); if (key == turbine::Key::Alpha_D) { m_tool = Tool::Draw; - model()->clearSelection(); + setCopyEnabled(false); + setCutEnabled(false); + setPasteEnabled(false); + m_model.clearSelection(); } else if (key == turbine::Key::Alpha_S) { m_tool = Tool::Select; + setCopyEnabled(true); + setCutEnabled(true); + setPasteEnabled(true); } else if (key == turbine::Key::Alpha_F) { m_tool = Tool::Fill; - model()->clearSelection(); + setCopyEnabled(false); + setCutEnabled(false); + setPasteEnabled(false); + m_model.clearSelection(); } else if (key >= turbine::Key::Num_1 && key <= turbine::Key::Num_9 && key <= turbine::Key::Num_0 + colorCnt) { auto idx = ox::min(static_cast(key - turbine::Key::Num_1), colorCnt - 1); - m_tileSheetEditor.setPalIdx(idx); + m_view.setPalIdx(idx); } else if (key == turbine::Key::Num_0 && colorCnt >= 10) { auto idx = ox::min(static_cast(key - turbine::Key::Num_1 + 9), colorCnt - 1); - m_tileSheetEditor.setPalIdx(idx); + m_view.setPalIdx(idx); } } } @@ -118,12 +128,12 @@ void TileSheetEditorImGui::draw(turbine::Context&) noexcept { ImGui::SameLine(); if (ImGui::Selectable("Draw", m_tool == Tool::Draw, 0, btnSz)) { m_tool = Tool::Draw; - model()->clearSelection(); + m_model.clearSelection(); } ImGui::SameLine(); if (ImGui::Selectable("Fill", m_tool == Tool::Fill, 0, btnSz)) { m_tool = Tool::Fill; - model()->clearSelection(); + m_model.clearSelection(); } } ImGui::EndChild(); @@ -139,17 +149,17 @@ void TileSheetEditorImGui::draw(turbine::Context&) noexcept { static constexpr auto btnHeight = 18; const auto btnSize = ImVec2(18, btnHeight); if (ImGui::Button("+", btnSize)) { - auto insertOnIdx = model()->activeSubSheetIdx(); - const auto &parent = *model()->activeSubSheet(); - model()->addSubsheet(insertOnIdx); + auto insertOnIdx = m_model.activeSubSheetIdx(); + const auto &parent = *m_model.activeSubSheet(); + m_model.addSubsheet(insertOnIdx); insertOnIdx.emplace_back(parent.subsheets.size() - 1); - model()->setActiveSubsheet(insertOnIdx); + m_model.setActiveSubsheet(insertOnIdx); } ImGui::SameLine(); if (ImGui::Button("-", btnSize)) { - const auto &activeSubsheetIdx = model()->activeSubSheetIdx(); + const auto &activeSubsheetIdx = m_model.activeSubSheetIdx(); if (activeSubsheetIdx.size() > 0) { - model()->rmSubsheet(activeSubsheetIdx); + m_model.rmSubsheet(activeSubsheetIdx); } } ImGui::SameLine(); @@ -167,7 +177,7 @@ void TileSheetEditorImGui::draw(turbine::Context&) noexcept { ImGui::TableSetupColumn("Columns", ImGuiTableColumnFlags_WidthFixed, 50); ImGui::TableSetupColumn("Rows", ImGuiTableColumnFlags_WidthFixed, 50); ImGui::TableHeadersRow(); - drawSubsheetSelector(&m_tileSheetEditor.img().subsheet, &path); + drawSubsheetSelector(&m_view.img().subsheet, &path); ImGui::EndTable(); } } @@ -182,7 +192,7 @@ void TileSheetEditorImGui::drawSubsheetSelector(TileSheet::SubSheet *subsheet, T using Str = ox::BasicString<100>; auto pathStr = ox::join("##", *path).value; auto lbl = ox::sfmt("{}##{}", subsheet->name, pathStr); - const auto rowSelected = *path == model()->activeSubSheetIdx(); + const auto rowSelected = *path == m_model.activeSubSheetIdx(); const auto flags = ImGuiTreeNodeFlags_SpanFullWidth | ImGuiTreeNodeFlags_OpenOnArrow | ImGuiTreeNodeFlags_DefaultOpen @@ -192,7 +202,7 @@ void TileSheetEditorImGui::drawSubsheetSelector(TileSheet::SubSheet *subsheet, T const auto open = ImGui::TreeNodeEx(lbl.c_str(), flags); ImGui::SameLine(); if (ImGui::IsItemClicked()) { - model()->setActiveSubsheet(*path); + m_model.setActiveSubsheet(*path); } if (ImGui::IsMouseDoubleClicked(0) && ImGui::IsItemHovered()) { showSubsheetEditor(); @@ -229,11 +239,11 @@ ox::Vec2 TileSheetEditorImGui::clickPos(ImVec2 const&winPos, ox::Vec2 clickPos) } ox::Error TileSheetEditorImGui::saveItem() noexcept { - return model()->saveFile(); + return m_model.saveFile(); } void TileSheetEditorImGui::showSubsheetEditor() noexcept { - const auto sheet = model()->activeSubSheet(); + const auto sheet = m_model.activeSubSheet(); if (sheet->subsheets.size()) { m_subsheetEditor.show(sheet->name, -1, -1); } else { @@ -247,9 +257,9 @@ void TileSheetEditorImGui::exportSubhseetToPng() noexcept { return; } // subsheet to png - const auto &img = model()->img(); - const auto &s = *model()->activeSubSheet(); - const auto &pal = model()->pal(); + const auto &img = m_model.img(); + const auto &s = *m_model.activeSubSheet(); + const auto &pal = m_model.pal(); err = toPngFile(path, s, *pal, img.bpp); if (err) { oxErrorf("Tilesheet export failed: {}", toStr(err)); @@ -261,20 +271,17 @@ void TileSheetEditorImGui::drawTileSheet(ox::Vec2 const&fbSize) noexcept { const auto fbSizei = ox::Size(static_cast(fbSize.x), static_cast(fbSize.y)); if (m_framebuffer.width != fbSizei.width || m_framebuffer.height != fbSizei.height) { glutils::resizeInitFrameBuffer(m_framebuffer, fbSizei.width, fbSizei.height); - m_tileSheetEditor.resizeView(fbSize); - } else if (m_tileSheetEditor.updated()) { - m_tileSheetEditor.ackUpdate(); + m_view.resizeView(fbSize); + } else if (m_view.updated()) { + m_view.ackUpdate(); } glBindFramebuffer(GL_FRAMEBUFFER, m_framebuffer); // clear screen and draw glViewport(0, 0, fbSizei.width, fbSizei.height); - m_tileSheetEditor.draw(); + m_view.draw(); glBindFramebuffer(GL_FRAMEBUFFER, 0); - ImTextureID buffId{}; - static_assert(sizeof(ImTextureID) >= sizeof(m_framebuffer.color.id)); - memcpy(&buffId, &m_framebuffer.color.id, sizeof(m_framebuffer.color.id)); ImGui::Image( - buffId, + std::bit_cast(uintptr_t{m_framebuffer.color.id}), static_cast(fbSize), ImVec2(0, 1), ImVec2(1, 0)); @@ -287,22 +294,22 @@ void TileSheetEditorImGui::drawTileSheet(ox::Vec2 const&fbSize) noexcept { if (wheel != 0) { const auto zoomMod = ox::defines::OS == ox::OS::Darwin ? io.KeySuper : turbine::buttonDown(m_ctx, turbine::Key::Mod_Ctrl); - m_tileSheetEditor.scrollV(fbSize, wheel, zoomMod); + m_view.scrollV(fbSize, wheel, zoomMod); } if (wheelh != 0) { - m_tileSheetEditor.scrollH(fbSize, wheelh); + m_view.scrollH(fbSize, wheelh); } if (io.MouseDown[0] && m_prevMouseDownPos != mousePos) { m_prevMouseDownPos = mousePos; switch (m_tool) { case Tool::Draw: - m_tileSheetEditor.clickDraw(fbSize, clickPos(winPos, mousePos)); + m_view.clickDraw(fbSize, clickPos(winPos, mousePos)); break; case Tool::Fill: - m_tileSheetEditor.clickFill(fbSize, clickPos(winPos, mousePos)); + m_view.clickFill(fbSize, clickPos(winPos, mousePos)); break; case Tool::Select: - m_tileSheetEditor.clickSelect(fbSize, clickPos(winPos, mousePos)); + m_view.clickSelect(fbSize, clickPos(winPos, mousePos)); break; case Tool::None: break; @@ -312,22 +319,22 @@ void TileSheetEditorImGui::drawTileSheet(ox::Vec2 const&fbSize) noexcept { if (ImGui::BeginPopupContextItem("TileMenu", ImGuiPopupFlags_MouseButtonRight)) { const auto popupPos = ox::Vec2(ImGui::GetWindowPos()); if (ImGui::MenuItem("Insert Tile")) { - m_tileSheetEditor.insertTile(fbSize, clickPos(winPos, popupPos)); + m_view.insertTile(fbSize, clickPos(winPos, popupPos)); } if (ImGui::MenuItem("Delete Tile")) { - m_tileSheetEditor.deleteTile(fbSize, clickPos(winPos, popupPos)); + m_view.deleteTile(fbSize, clickPos(winPos, popupPos)); } ImGui::EndPopup(); } if (io.MouseReleased[0]) { m_prevMouseDownPos = {-1, -1}; - m_tileSheetEditor.releaseMouseButton(); + m_view.releaseMouseButton(); } } void TileSheetEditorImGui::drawPaletteSelector() noexcept { - auto sctx = applicationData(m_ctx); - const auto &files = sctx->project->fileList(core::FileExt_npal); + auto &sctx = *applicationData(m_ctx); + const auto &files = sctx.project->fileList(core::FileExt_npal); const auto first = m_selectedPaletteIdx < files.size() ? files[m_selectedPaletteIdx].c_str() : ""; if (ImGui::BeginCombo("Palette", first, 0)) { @@ -335,7 +342,7 @@ void TileSheetEditorImGui::drawPaletteSelector() noexcept { const auto selected = (m_selectedPaletteIdx == n); if (ImGui::Selectable(files[n].c_str(), selected) && m_selectedPaletteIdx != n) { m_selectedPaletteIdx = n; - oxLogError(model()->setPalette(files[n])); + oxLogError(m_model.setPalette(files[n])); } if (selected) { ImGui::SetItemDefaultFocus(); @@ -349,15 +356,15 @@ void TileSheetEditorImGui::drawPaletteSelector() noexcept { ImGui::TableSetupColumn("", 0, 0.22f); ImGui::TableSetupColumn("Color16", 0, 3); ImGui::TableHeadersRow(); - if (auto pal = m_tileSheetEditor.pal()) { + if (auto pal = m_view.pal()) { for (auto i = 0u; auto c: pal->colors) { ImGui::PushID(static_cast(i)); // Column: color idx ImGui::TableNextColumn(); const auto label = ox::BString<8>() + (i + 1); - const auto rowSelected = i == m_tileSheetEditor.palIdx(); + const auto rowSelected = i == m_view.palIdx(); if (ImGui::Selectable(label.c_str(), rowSelected, ImGuiSelectableFlags_SpanAllColumns)) { - m_tileSheetEditor.setPalIdx(i); + m_view.setPalIdx(i); } // Column: color RGB ImGui::TableNextColumn(); @@ -375,13 +382,13 @@ void TileSheetEditorImGui::drawPaletteSelector() noexcept { } ox::Error TileSheetEditorImGui::updateActiveSubsheet(ox::StringView const&name, int cols, int rows) noexcept { - return model()->updateSubsheet(model()->activeSubSheetIdx(), name, cols, rows); + return m_model.updateSubsheet(m_model.activeSubSheetIdx(), name, cols, rows); } ox::Error TileSheetEditorImGui::setPaletteSelection() noexcept { - const auto &palPath = model()->palPath(); - auto sctx = applicationData(m_ctx); - const auto &palList = sctx->project->fileList(core::FileExt_npal); + const auto &palPath = m_model.palPath(); + auto &sctx = *applicationData(m_ctx); + const auto &palList = sctx.project->fileList(core::FileExt_npal); for (std::size_t i = 0; const auto &pal : palList) { if (palPath == pal) { m_selectedPaletteIdx = i; diff --git a/src/nostalgia/modules/core/src/studio/tilesheeteditor/tilesheeteditor-imgui.hpp b/src/nostalgia/modules/core/src/studio/tilesheeteditor/tilesheeteditor-imgui.hpp index e9451dcc..fe13d7db 100644 --- a/src/nostalgia/modules/core/src/studio/tilesheeteditor/tilesheeteditor-imgui.hpp +++ b/src/nostalgia/modules/core/src/studio/tilesheeteditor/tilesheeteditor-imgui.hpp @@ -47,7 +47,8 @@ class TileSheetEditorImGui: public studio::Editor { ox::Vector m_paletteList; SubSheetEditor m_subsheetEditor; glutils::FrameBuffer m_framebuffer; - TileSheetEditorView m_tileSheetEditor; + TileSheetEditorView m_view; + TileSheetEditorModel &m_model; float m_palViewWidth = 300; ox::Vec2 m_prevMouseDownPos; Tool m_tool = Tool::Draw; @@ -82,16 +83,6 @@ class TileSheetEditorImGui: public studio::Editor { void exportSubhseetToPng() noexcept; - [[nodiscard]] - constexpr auto model() const noexcept { - return m_tileSheetEditor.model(); - } - - [[nodiscard]] - constexpr auto model() noexcept { - return m_tileSheetEditor.model(); - } - void drawTileSheet(ox::Vec2 const&fbSize) noexcept; void drawPaletteSelector() noexcept; diff --git a/src/nostalgia/modules/core/src/studio/tilesheeteditor/tilesheeteditormodel.hpp b/src/nostalgia/modules/core/src/studio/tilesheeteditor/tilesheeteditormodel.hpp index a3763bbc..11bb0159 100644 --- a/src/nostalgia/modules/core/src/studio/tilesheeteditor/tilesheeteditormodel.hpp +++ b/src/nostalgia/modules/core/src/studio/tilesheeteditor/tilesheeteditormodel.hpp @@ -124,18 +124,6 @@ class TileSheetEditorModel: public ox::SignalHandler { private: void pushCommand(studio::UndoCommand *cmd) noexcept; - void setPalette(); - - void saveState(); - - void restoreState(); - - [[nodiscard]] - ox::String paletteName(ox::String const&palettePath) const; - - [[nodiscard]] - ox::String palettePath(ox::String const&palettePath) const; - }; constexpr const TileSheet &TileSheetEditorModel::img() const noexcept { diff --git a/src/nostalgia/modules/core/src/studio/tilesheeteditor/tilesheeteditorview.hpp b/src/nostalgia/modules/core/src/studio/tilesheeteditor/tilesheeteditorview.hpp index 1642f58e..dbd6e28f 100644 --- a/src/nostalgia/modules/core/src/studio/tilesheeteditor/tilesheeteditorview.hpp +++ b/src/nostalgia/modules/core/src/studio/tilesheeteditor/tilesheeteditorview.hpp @@ -84,13 +84,13 @@ class TileSheetEditorView: public ox::SignalHandler { constexpr const Palette *pal() const noexcept; [[nodiscard]] - constexpr auto *model() noexcept { - return &m_model; + constexpr auto &model() noexcept { + return m_model; } [[nodiscard]] - constexpr auto *model() const noexcept { - return &m_model; + constexpr auto &model() const noexcept { + return m_model; } constexpr auto setPalIdx(auto palIdx) noexcept {