diff --git a/src/nostalgia/core/studio/tilesheeteditor-imgui.cpp b/src/nostalgia/core/studio/tilesheeteditor-imgui.cpp index cb3e6af0..4601a0ea 100644 --- a/src/nostalgia/core/studio/tilesheeteditor-imgui.cpp +++ b/src/nostalgia/core/studio/tilesheeteditor-imgui.cpp @@ -16,6 +16,7 @@ TileSheetEditorImGui::TileSheetEditorImGui(Context *ctx, const ox::String &path) const auto lastSlash = std::find(m_itemPath.rbegin(), m_itemPath.rend(), '/').offset(); m_itemName = m_itemPath.substr(lastSlash + 1); undoStack()->changeTriggered.connect(this, &TileSheetEditorImGui::markUnsavedChanges); + m_subsheetEditor.inputSubmitted.connect(model(), &TileSheetEditorModel::updateActiveSubsheet); } ox::String TileSheetEditorImGui::itemName() const noexcept { @@ -61,7 +62,8 @@ void TileSheetEditorImGui::draw(core::Context*) noexcept { ImGui::EndChild(); ImGui::BeginChild("child2", ImVec2(m_palViewWidth - 24, paneSize.y / 2.07f), true); { - const auto btnSize = ImVec2(18, 18); + constexpr auto btnHeight = 18; + const auto btnSize = ImVec2(18, btnHeight); if (ImGui::Button("+", btnSize)) { auto insertOnIdx = model()->activeSubSheetIdx(); const auto &parent = *model()->activeSubSheet(); @@ -76,6 +78,15 @@ void TileSheetEditorImGui::draw(core::Context*) noexcept { model()->rmSubsheet(activeSubsheetIdx); } } + ImGui::SameLine(); + if (ImGui::Button("Edit", ImVec2(36, btnHeight))) { + const auto sheet = model()->activeSubSheet(); + if (sheet->subsheets.size()) { + m_subsheetEditor.show(sheet->name, -1, -1); + } else { + m_subsheetEditor.show(sheet->name, sheet->columns, sheet->rows); + } + } TileSheet::SubSheetIdx path; constexpr auto flags = ImGuiTableFlags_RowBg | ImGuiTableFlags_NoBordersInBody; if (ImGui::BeginTable("Subsheets", 3, flags)) { @@ -90,6 +101,8 @@ void TileSheetEditorImGui::draw(core::Context*) noexcept { ImGui::EndChild(); } ImGui::EndChild(); + m_subsheetEditor.draw(); + ImGui::ShowDemoWindow(); } void TileSheetEditorImGui::drawSubsheetSelector(TileSheet::SubSheet *subsheet, TileSheet::SubSheetIdx *path) noexcept { @@ -105,6 +118,8 @@ void TileSheetEditorImGui::drawSubsheetSelector(TileSheet::SubSheet *subsheet, T | (rowSelected ? ImGuiTreeNodeFlags_Selected : 0); ImGui::TableNextColumn(); const auto open = ImGui::TreeNodeEx(lbl.c_str(), flags); + Str newName = subsheet->name.c_str(); + ImGui::SameLine(); if (ImGui::IsItemClicked()) { model()->setActiveSubsheet(*path); } @@ -223,4 +238,31 @@ ox::Error TileSheetEditorImGui::markUnsavedChanges(int) noexcept { return OxError(0); } +void TileSheetEditorImGui::SubSheetEditor::draw() noexcept { + constexpr auto modalFlags = ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize; + constexpr auto popupName = "Edit SubSheet"; + if (m_show) { + ImGui::OpenPopup(popupName); + ImGui::SetNextWindowSize(ImVec2(235, 125)); + } + if (ImGui::BeginPopupModal(popupName, &m_show, modalFlags)) { + ImGui::InputText("Name", m_name.data(), m_name.cap()); + if (m_cols != -1) { + ImGui::InputInt("Columns", &m_cols); + ImGui::InputInt("Rows", &m_rows); + } + if (ImGui::Button("OK")) { + ImGui::CloseCurrentPopup(); + m_show = false; + inputSubmitted.emit(m_name.c_str(), m_cols, m_rows); + } + ImGui::SameLine(); + if (ImGui::Button("Cancel")) { + ImGui::CloseCurrentPopup(); + m_show = false; + } + ImGui::EndPopup(); + } +} + } diff --git a/src/nostalgia/core/studio/tilesheeteditor-imgui.hpp b/src/nostalgia/core/studio/tilesheeteditor-imgui.hpp index 7946dd66..d4924d48 100644 --- a/src/nostalgia/core/studio/tilesheeteditor-imgui.hpp +++ b/src/nostalgia/core/studio/tilesheeteditor-imgui.hpp @@ -21,6 +21,22 @@ namespace nostalgia::core { class TileSheetEditorImGui: public studio::Editor { private: + class SubSheetEditor { + ox::BString<100> m_name; + int m_cols = 0; + int m_rows = 0; + bool m_show; + public: + ox::Signal inputSubmitted; + constexpr void show(const ox::String &name, int cols, int rows) noexcept { + m_show = true; + m_name = name.c_str(); + m_cols = cols; + m_rows = rows; + } + void draw() noexcept; + }; + SubSheetEditor m_subsheetEditor; ox::String m_itemPath; ox::String m_itemName; glutils::FrameBuffer m_framebuffer; diff --git a/src/nostalgia/core/studio/tilesheeteditormodel.cpp b/src/nostalgia/core/studio/tilesheeteditormodel.cpp index 9c865795..1724d75f 100644 --- a/src/nostalgia/core/studio/tilesheeteditormodel.cpp +++ b/src/nostalgia/core/studio/tilesheeteditormodel.cpp @@ -55,6 +55,11 @@ void TileSheetEditorModel::rmSubsheet(const TileSheet::SubSheetIdx &idx) noexcep pushCommand(new RmSubSheetCommand(&m_img, idx)); } +ox::Error TileSheetEditorModel::updateActiveSubsheet(const ox::String &name, int cols, int rows) noexcept { + pushCommand(new UpdateSubSheetCommand(&m_img, m_activeSubsSheetIdx, name, cols, rows)); + return OxError(0); +} + void TileSheetEditorModel::setActiveSubsheet(const TileSheet::SubSheetIdx &idx) noexcept { m_activeSubsSheetIdx = idx; this->activeSubsheetChanged.emit(m_activeSubsSheetIdx); diff --git a/src/nostalgia/core/studio/tilesheeteditormodel.hpp b/src/nostalgia/core/studio/tilesheeteditormodel.hpp index ac8cfcb8..97b9305d 100644 --- a/src/nostalgia/core/studio/tilesheeteditormodel.hpp +++ b/src/nostalgia/core/studio/tilesheeteditormodel.hpp @@ -19,6 +19,7 @@ enum class CommandId { Draw = 1, AddSubSheet = 2, RmSubSheet = 3, + UpdateSubSheet = 4, }; constexpr bool operator==(CommandId c, int i) noexcept { @@ -180,6 +181,46 @@ struct RmSubSheetCommand: public studio::UndoCommand { }; +struct UpdateSubSheetCommand: public studio::UndoCommand { + private: + TileSheet *m_img = nullptr; + TileSheet::SubSheetIdx m_idx; + TileSheet::SubSheet m_sheet; + ox::String m_newName; + int m_newCols = 0; + int m_newRows = 0; + + public: + constexpr UpdateSubSheetCommand(TileSheet *img, const TileSheet::SubSheetIdx &idx, + const ox::String &name, int cols, int rows) noexcept { + m_img = img; + m_idx = idx; + m_sheet = img->getSubSheet(idx); + m_newName = name; + m_newCols = cols; + m_newRows = rows; + } + + void redo() noexcept final { + auto &sheet = m_img->getSubSheet(m_idx); + sheet.name = m_newName; + sheet.columns = m_newCols; + sheet.rows = m_newRows; + sheet.pixels.resize(static_cast(m_newCols * m_newRows * PixelsPerTile)); + } + + void undo() noexcept final { + auto &sheet = m_img->getSubSheet(m_idx); + sheet = m_sheet; + } + + [[nodiscard]] + int commandId() const noexcept final { + return static_cast(CommandId::UpdateSubSheet); + } + +}; + struct TileSheetClipboard { static constexpr auto TypeName = "net.drinkingtea.nostalgia.core.studio.TileSheetClipboard"; static constexpr auto TypeVersion = 1; @@ -262,6 +303,8 @@ class TileSheetEditorModel: public ox::SignalHandler { void rmSubsheet(const TileSheet::SubSheetIdx &idx) noexcept; + ox::Error updateActiveSubsheet(const ox::String &name, int cols, int rows) noexcept; + void setActiveSubsheet(const TileSheet::SubSheetIdx&) noexcept; constexpr const TileSheet::SubSheet *activeSubSheet() const noexcept {