From 5d1f680a513788d9cedac5b711d68eb085d780a6 Mon Sep 17 00:00:00 2001 From: Gary Talent Date: Sat, 20 Jan 2024 14:59:43 -0600 Subject: [PATCH] [nostalgia/core] Cleanup TileSheetEditor with new ImGui util functions --- .../tilesheeteditor/tilesheeteditor-imgui.cpp | 79 ++++++------------- .../tilesheeteditor/tilesheeteditor-imgui.hpp | 4 +- .../modlib/include/studio/imguiutil.hpp | 26 +++--- src/olympic/studio/modlib/src/imguiutil.cpp | 31 +++++++- 4 files changed, 71 insertions(+), 69 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 e04c3636..22d4dc40 100644 --- a/src/nostalgia/modules/core/src/studio/tilesheeteditor/tilesheeteditor-imgui.cpp +++ b/src/nostalgia/modules/core/src/studio/tilesheeteditor/tilesheeteditor-imgui.cpp @@ -12,6 +12,8 @@ namespace nostalgia::core { +namespace ig = studio::ig; + static ox::Vector normalizePixelSizes( ox::Vector const&inPixels, int const bpp) noexcept { @@ -194,9 +196,9 @@ void TileSheetEditorImGui::draw(turbine::Context&) noexcept { ImGui::EndChild(); ImGui::BeginChild("SubSheets", ImVec2(m_palViewWidth - 24, ySize / 2.f), true); { - static constexpr auto btnHeight = 18; - auto const btnSize = ImVec2(18, btnHeight); - if (ImGui::Button("+", btnSize)) { + static constexpr auto btnHeight = ig::BtnSz.y; + auto const btnSize = ImVec2(btnHeight, btnHeight); + if (ig::PushButton("+", btnSize)) { auto insertOnIdx = m_model.activeSubSheetIdx(); auto const&parent = m_model.activeSubSheet(); m_model.addSubsheet(insertOnIdx); @@ -204,18 +206,18 @@ void TileSheetEditorImGui::draw(turbine::Context&) noexcept { m_model.setActiveSubsheet(insertOnIdx); } ImGui::SameLine(); - if (ImGui::Button("-", btnSize)) { + if (ig::PushButton("-", btnSize)) { auto const&activeSubsheetIdx = m_model.activeSubSheetIdx(); if (!activeSubsheetIdx.empty()) { m_model.rmSubsheet(activeSubsheetIdx); } } ImGui::SameLine(); - if (ImGui::Button("Edit", ImVec2(51, btnHeight))) { + if (ig::PushButton("Edit")) { showSubsheetEditor(); } ImGui::SameLine(); - if (ImGui::Button("Export", ImVec2(51, btnHeight))) { + if (ig::PushButton("Export")) { m_exportMenu.show(); } TileSheet::SubSheetIdx path; @@ -233,11 +235,12 @@ void TileSheetEditorImGui::draw(turbine::Context&) noexcept { ImGui::EndChild(); } ImGui::EndChild(); - m_subsheetEditor.draw(); - m_exportMenu.draw(); + m_subsheetEditor.draw(m_ctx); + m_exportMenu.draw(m_ctx); } -void TileSheetEditorImGui::drawSubsheetSelector(TileSheet::SubSheet &subsheet, TileSheet::SubSheetIdx &path) { +void TileSheetEditorImGui::drawSubsheetSelector( + TileSheet::SubSheet &subsheet, TileSheet::SubSheetIdx &path) { constexpr auto indentReduce = 14; ImGui::TableNextRow(0, 5); using Str = ox::BasicString<100>; @@ -398,22 +401,10 @@ void TileSheetEditorImGui::drawTileSheet(ox::Vec2 const&fbSize) noexcept { void TileSheetEditorImGui::drawPaletteSelector() noexcept { auto &sctx = *applicationData(m_ctx); auto const&files = sctx.project->fileList(core::FileExt_npal); - auto const first = m_selectedPaletteIdx < files.size() ? - files[m_selectedPaletteIdx].c_str() : ""; auto const comboWidthSub = 62; ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x - comboWidthSub); - if (ImGui::BeginCombo("Palette", first, 0)) { - for (auto n = 0u; n < files.size(); ++n) { - const auto selected = (m_selectedPaletteIdx == n); - if (ImGui::Selectable(files[n].c_str(), selected) && m_selectedPaletteIdx != n) { - m_selectedPaletteIdx = n; - oxLogError(m_model.setPalette(files[n])); - } - if (selected) { - ImGui::SetItemDefaultFocus(); - } - } - ImGui::EndCombo(); + if (ig::ComboBox("Palette", files, m_selectedPaletteIdx)) { + oxLogError(m_model.setPalette(files[m_selectedPaletteIdx])); } auto const pages = m_model.pal().pages.size(); if (pages > 1) { @@ -491,34 +482,24 @@ ox::Error TileSheetEditorImGui::markUnsavedChanges(studio::UndoCommand const*) n return {}; } -void TileSheetEditorImGui::SubSheetEditor::draw() noexcept { - constexpr auto modalFlags = ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize; +void TileSheetEditorImGui::SubSheetEditor::draw(turbine::Context &ctx) noexcept { constexpr auto popupName = "Edit Subsheet"; if (!m_show) { return; } - ImGui::OpenPopup(popupName); auto const modSize = m_cols > 0; - auto const popupWidth = 235.f; - auto const popupHeight = modSize ? 125.f : 80.f; - ImGui::SetNextWindowSize(ImVec2(popupWidth, popupHeight)); - if (ImGui::BeginPopupModal(popupName, &m_show, modalFlags)) { + auto constexpr popupWidth = 235.f; + auto const popupHeight = modSize ? 130.f : 85.f; + auto const popupSz = ImVec2(popupWidth, popupHeight); + if (ig::BeginPopup(ctx, popupName, m_show, popupSz)) { ImGui::InputText("Name", m_name.data(), m_name.cap()); if (modSize) { ImGui::InputInt("Columns", &m_cols); ImGui::InputInt("Rows", &m_rows); } - ImGui::SetCursorPosX(popupWidth - 116); - if (ImGui::Button("OK", ImVec2{50, 20})) { - ImGui::CloseCurrentPopup(); - m_show = false; + if (ig::PopupControlsOkCancel(popupWidth, m_show) == ig::PopupResponse::OK) { inputSubmitted.emit(m_name, m_cols, m_rows); } - ImGui::SameLine(); - if (ImGui::Button("Cancel", ImVec2{50, 20})) { - ImGui::CloseCurrentPopup(); - m_show = false; - } ImGui::EndPopup(); } } @@ -527,28 +508,20 @@ void TileSheetEditorImGui::SubSheetEditor::close() noexcept { m_show = false; } -void TileSheetEditorImGui::ExportMenu::draw() noexcept { - constexpr auto modalFlags = ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize; +void TileSheetEditorImGui::ExportMenu::draw(turbine::Context &ctx) noexcept { constexpr auto popupName = "Export Tile Sheet"; if (!m_show) { return; } - ImGui::OpenPopup(popupName); - constexpr auto popupHeight = 80.f; - ImGui::SetNextWindowSize(ImVec2(235, popupHeight)); - if (ImGui::BeginPopupModal(popupName, &m_show, modalFlags)) { + constexpr auto popupWidth = 235.f; + constexpr auto popupHeight = 85.f; + constexpr auto popupSz = ImVec2(popupWidth, popupHeight); + if (ig::BeginPopup(ctx, popupName, m_show, popupSz)) { ImGui::InputInt("Scale", &m_scale); m_scale = ox::clamp(m_scale, 1, 50); - if (ImGui::Button("OK", ImVec2{50, 20})) { - ImGui::CloseCurrentPopup(); - m_show = false; + if (ig::PopupControlsOkCancel(popupWidth, m_show) == ig::PopupResponse::OK) { inputSubmitted.emit(m_scale); } - ImGui::SameLine(); - if (ImGui::Button("Cancel", ImVec2{50, 20})) { - ImGui::CloseCurrentPopup(); - m_show = false; - } ImGui::EndPopup(); } } 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 eacf35f9..70b3eda5 100644 --- a/src/nostalgia/modules/core/src/studio/tilesheeteditor/tilesheeteditor-imgui.hpp +++ b/src/nostalgia/modules/core/src/studio/tilesheeteditor/tilesheeteditor-imgui.hpp @@ -40,7 +40,7 @@ class TileSheetEditorImGui: public studio::Editor { m_cols = cols; m_rows = rows; } - void draw() noexcept; + void draw(turbine::Context &ctx) noexcept; void close() noexcept; [[nodiscard]] inline bool isOpen() const noexcept { return m_show; } @@ -55,7 +55,7 @@ class TileSheetEditorImGui: public studio::Editor { m_show = true; m_scale = 5; } - void draw() noexcept; + void draw(turbine::Context &ctx) noexcept; void close() noexcept; [[nodiscard]] inline bool isOpen() const noexcept { return m_show; } diff --git a/src/olympic/studio/modlib/include/studio/imguiutil.hpp b/src/olympic/studio/modlib/include/studio/imguiutil.hpp index f92ea7fb..dc71cbcb 100644 --- a/src/olympic/studio/modlib/include/studio/imguiutil.hpp +++ b/src/olympic/studio/modlib/include/studio/imguiutil.hpp @@ -10,26 +10,30 @@ namespace studio::ig { -inline constexpr auto BtnSz = ImVec2{50, 22}; +inline constexpr auto BtnSz = ImVec2{52, 22}; -template class IDStackItem { - private: - T m_id; public: - explicit IDStackItem(T id) noexcept: m_id(id) { - ImGui::PushID(m_id); - } - ~IDStackItem() noexcept { - ImGui::PopID(); - } + explicit IDStackItem(int id) noexcept; + explicit IDStackItem(const char *id) noexcept; + explicit IDStackItem(ox::CStringView id) noexcept; + ~IDStackItem() noexcept; }; void centerNextWindow(turbine::Context &ctx) noexcept; bool PushButton(ox::CStringView lbl, ImVec2 const&btnSz = BtnSz) noexcept; -void PopupBtns(float popupWidth, bool &popupOpen); +enum class PopupResponse { + None, + OK, + Cancel, +}; + +PopupResponse PopupControlsOkCancel(float popupWidth, bool &popupOpen); + +[[nodiscard]] +bool BeginPopup(turbine::Context &ctx, ox::CStringView popupName, bool &show, ImVec2 const&sz = {285, 0}); /** * diff --git a/src/olympic/studio/modlib/src/imguiutil.cpp b/src/olympic/studio/modlib/src/imguiutil.cpp index e52f3153..3f7fc141 100644 --- a/src/olympic/studio/modlib/src/imguiutil.cpp +++ b/src/olympic/studio/modlib/src/imguiutil.cpp @@ -10,6 +10,20 @@ namespace studio::ig { +IDStackItem::IDStackItem(int id) noexcept { + ImGui::PushID(id); +} + +IDStackItem::IDStackItem(const char *id) noexcept { + ImGui::PushID(id); +} + +IDStackItem::IDStackItem(ox::CStringView id) noexcept: IDStackItem(id.c_str()) {} + +IDStackItem::~IDStackItem() noexcept { + ImGui::PopID(); +} + void centerNextWindow(turbine::Context &ctx) noexcept { auto const sz = turbine::getScreenSize(ctx); auto const screenW = static_cast(sz.width); @@ -22,19 +36,31 @@ bool PushButton(ox::CStringView lbl, ImVec2 const&btnSz) noexcept { return ImGui::Button(lbl.c_str(), btnSz); } -void PopupBtns(float popupWidth, bool &popupOpen) { +PopupResponse PopupControlsOkCancel(float popupWidth, bool &popupOpen) { + auto out = PopupResponse::None; constexpr auto btnSz = ImVec2{50, BtnSz.y}; ImGui::Separator(); ImGui::SetCursorPosX(popupWidth - 118); if (ImGui::Button("OK", btnSz)) { ImGui::CloseCurrentPopup(); popupOpen = false; + out = PopupResponse::OK; } ImGui::SameLine(); - if (ImGui::Button("Cancel", btnSz)) { + if (ImGui::IsKeyDown(ImGuiKey_Escape) || ImGui::Button("Cancel", btnSz)) { ImGui::CloseCurrentPopup(); popupOpen = false; + out = PopupResponse::Cancel; } + return out; +} + +bool BeginPopup(turbine::Context &ctx, ox::CStringView popupName, bool &show, ImVec2 const&sz) { + constexpr auto modalFlags = ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize; + ig::centerNextWindow(ctx); + ImGui::OpenPopup(popupName.c_str()); + ImGui::SetNextWindowSize(sz); + return ImGui::BeginPopupModal(popupName.c_str(), &show, modalFlags); } bool ComboBox( @@ -48,7 +74,6 @@ bool ComboBox( const auto selected = (selectedIdx == i); if (ImGui::Selectable(list[i].c_str(), selected) && selectedIdx != i) { selectedIdx = i; - //oxLogError(m_model.setPalette(list[n])); out = true; } }