From 2bc2003caa5cffee5d744b847802ccee2a499de1 Mon Sep 17 00:00:00 2001 From: Gary Talent Date: Wed, 17 Jan 2024 22:48:53 -0600 Subject: [PATCH] [nostalgia/core/studio] Add key shortcuts for switching Palette pages --- .../paletteeditor/paletteeditor-imgui.cpp | 19 +++++++ .../paletteeditor/paletteeditor-imgui.hpp | 2 + .../tilesheeteditor/tilesheeteditor-imgui.cpp | 51 ++++++++++++------- .../tilesheeteditor/tilesheeteditor-imgui.hpp | 3 +- .../tilesheeteditor/tilesheeteditormodel.cpp | 1 + .../tilesheeteditor/tilesheeteditormodel.hpp | 8 +-- .../tilesheeteditor/tilesheeteditorview.cpp | 2 +- .../tilesheeteditor/tilesheeteditorview.hpp | 7 --- .../tilesheeteditor/tilesheetpixels.cpp | 50 +++++++++--------- .../tilesheeteditor/tilesheetpixels.hpp | 11 +++- 10 files changed, 94 insertions(+), 60 deletions(-) diff --git a/src/nostalgia/modules/core/src/studio/paletteeditor/paletteeditor-imgui.cpp b/src/nostalgia/modules/core/src/studio/paletteeditor/paletteeditor-imgui.cpp index bd7ccc2e..7bdd1974 100644 --- a/src/nostalgia/modules/core/src/studio/paletteeditor/paletteeditor-imgui.cpp +++ b/src/nostalgia/modules/core/src/studio/paletteeditor/paletteeditor-imgui.cpp @@ -22,6 +22,25 @@ PaletteEditorImGui::PaletteEditorImGui(turbine::Context &ctx, ox::CRStringView p undoStack()->changeTriggered.connect(this, &PaletteEditorImGui::handleCommand); } +void PaletteEditorImGui::keyStateChanged(turbine::Key key, bool down) { + if (!down) { + return; + } + if (key >= turbine::Key::Num_1 && key <= turbine::Key::Num_9) { + if (turbine::buttonDown(m_ctx, turbine::Key::Mod_Alt)) { + m_page = ox::min( + static_cast(key - turbine::Key::Num_1), m_pal.pages.size() - 1); + } + } else if (key == turbine::Key::Num_0) { + if (turbine::buttonDown(m_ctx, turbine::Key::Mod_Alt)) { + m_selectedColorRow = + ox::min( + static_cast(key - turbine::Key::Num_1 + 9), m_pal.pages.size() - 1); + } + } + +} + void PaletteEditorImGui::draw(turbine::Context&) noexcept { auto const paneSize = ImGui::GetContentRegionAvail(); { diff --git a/src/nostalgia/modules/core/src/studio/paletteeditor/paletteeditor-imgui.hpp b/src/nostalgia/modules/core/src/studio/paletteeditor/paletteeditor-imgui.hpp index 183aa2f4..20c84dc4 100644 --- a/src/nostalgia/modules/core/src/studio/paletteeditor/paletteeditor-imgui.hpp +++ b/src/nostalgia/modules/core/src/studio/paletteeditor/paletteeditor-imgui.hpp @@ -22,6 +22,8 @@ class PaletteEditorImGui: public studio::Editor { public: PaletteEditorImGui(turbine::Context &ctx, ox::CRStringView path); + void keyStateChanged(turbine::Key key, bool down) override; + void draw(turbine::Context&) noexcept final; protected: 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 0f68ec52..fb5f7311 100644 --- a/src/nostalgia/modules/core/src/studio/tilesheeteditor/tilesheeteditor-imgui.cpp +++ b/src/nostalgia/modules/core/src/studio/tilesheeteditor/tilesheeteditor-imgui.cpp @@ -112,8 +112,8 @@ void TileSheetEditorImGui::keyStateChanged(turbine::Key key, bool down) { } auto const popupOpen = m_subsheetEditor.isOpen() && m_exportMenu.isOpen(); auto const pal = m_model.pal(); - if (pal && !popupOpen) { - const auto colorCnt = pal->pages[m_palPage].size(); + if (!popupOpen) { + const auto colorCnt = pal.pages[m_model.palettePage()].size(); if (key == turbine::Key::Alpha_D) { m_tool = Tool::Draw; setCopyEnabled(false); @@ -131,12 +131,25 @@ void TileSheetEditorImGui::keyStateChanged(turbine::Key key, bool down) { 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_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_view.setPalIdx(idx); + } else if (key >= turbine::Key::Num_1 && key <= turbine::Key::Num_9) { + if (turbine::buttonDown(m_ctx, turbine::Key::Mod_Alt)) { + auto const idx = ox::min( + static_cast(key - turbine::Key::Num_1), m_model.pal().pages.size() - 1); + m_model.setPalettePage(idx); + } else if (key <= turbine::Key::Num_0 + colorCnt) { + auto idx = ox::min(static_cast(key - turbine::Key::Num_1), colorCnt - 1); + m_view.setPalIdx(idx); + } + } else if (key == turbine::Key::Num_0) { + if (turbine::buttonDown(m_ctx, turbine::Key::Mod_Alt)) { + auto const idx = ox::min( + static_cast(key - turbine::Key::Num_1 + 9), m_model.pal().pages.size() - 1); + m_model.setPalettePage(idx); + } else if (colorCnt >= 10) { + auto idx = ox::min( + static_cast(key - turbine::Key::Num_1 + 9), colorCnt - 1); + m_view.setPalIdx(idx); + } } } } @@ -306,8 +319,8 @@ ox::Error TileSheetEditorImGui::exportSubhseetToPng(int scale) noexcept { auto const err = toPngFile( path, std::move(pixels), - *pal, - m_palPage, + pal, + m_model.palettePage(), static_cast(width * scale), static_cast(height * scale)); if (err) { @@ -402,19 +415,18 @@ void TileSheetEditorImGui::drawPaletteSelector() noexcept { } ImGui::EndCombo(); } - auto const pages = m_model.pal()->pages.size(); + auto const pages = m_model.pal().pages.size(); if (pages > 1) { ImGui::Indent(20); ox::Array numStr; - ox_itoa(m_palPage + 1, numStr.data()); + ox_itoa(m_model.palettePage() + 1, numStr.data()); ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x - comboWidthSub); if (ImGui::BeginCombo("Page", numStr.data(), 0)) { for (auto n = 0u; n < pages; ++n) { - const auto selected = (m_palPage == n); + const auto selected = (m_model.palettePage() == n); ox_itoa(n + 1, numStr.data()); - if (ImGui::Selectable(numStr.data(), selected) && m_palPage != n) { - m_palPage = n; - m_model.setPalettePage(m_palPage); + if (ImGui::Selectable(numStr.data(), selected) && m_model.palettePage() != n) { + m_model.setPalettePage(n); } if (selected) { ImGui::SetItemDefaultFocus(); @@ -430,8 +442,9 @@ void TileSheetEditorImGui::drawPaletteSelector() noexcept { ImGui::TableSetupColumn("", 0, 0.22f); ImGui::TableSetupColumn("Color16", 0, 3); ImGui::TableHeadersRow(); - if (auto pal = m_view.pal()) { - for (auto i = 0u; auto c: pal->pages[m_palPage]) { + { + auto const&pal = m_model.pal(); + for (auto i = 0u; auto c: pal.pages[m_model.palettePage()]) { ImGui::PushID(static_cast(i)); // Column: color idx ImGui::TableNextColumn(); @@ -473,7 +486,7 @@ ox::Error TileSheetEditorImGui::setPaletteSelection() noexcept { return {}; } -ox::Error TileSheetEditorImGui::markUnsavedChanges(const studio::UndoCommand*) noexcept { +ox::Error TileSheetEditorImGui::markUnsavedChanges(studio::UndoCommand const*) noexcept { setUnsavedChanges(true); return {}; } 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 ad1689c7..657a9d45 100644 --- a/src/nostalgia/modules/core/src/studio/tilesheeteditor/tilesheeteditor-imgui.hpp +++ b/src/nostalgia/modules/core/src/studio/tilesheeteditor/tilesheeteditor-imgui.hpp @@ -69,7 +69,6 @@ class TileSheetEditorImGui: public studio::Editor { float m_palViewWidth = 300; ox::Vec2 m_prevMouseDownPos; Tool m_tool = Tool::Draw; - size_t m_palPage = 0; public: TileSheetEditorImGui(turbine::Context &ctx, ox::CRStringView path); @@ -111,7 +110,7 @@ class TileSheetEditorImGui: public studio::Editor { // slots private: - ox::Error markUnsavedChanges(const studio::UndoCommand*) noexcept; + ox::Error markUnsavedChanges(studio::UndoCommand const*) noexcept; }; diff --git a/src/nostalgia/modules/core/src/studio/tilesheeteditor/tilesheeteditormodel.cpp b/src/nostalgia/modules/core/src/studio/tilesheeteditor/tilesheeteditormodel.cpp index fa9bf648..1484738c 100644 --- a/src/nostalgia/modules/core/src/studio/tilesheeteditor/tilesheeteditormodel.cpp +++ b/src/nostalgia/modules/core/src/studio/tilesheeteditor/tilesheeteditormodel.cpp @@ -228,6 +228,7 @@ ox::Error TileSheetEditorModel::markUpdatedCmdId(studio::UndoCommand const*cmd) const auto cmdId = cmd->commandId(); if (static_cast(cmdId) == CommandId::PaletteChange) { oxReturnError(readObj(keelCtx(m_ctx), m_img.defaultPalette).moveTo(m_pal)); + m_palettePage = ox::min(m_pal->pages.size(), 0); paletteChanged.emit(); } auto tsCmd = dynamic_cast(cmd); diff --git a/src/nostalgia/modules/core/src/studio/tilesheeteditor/tilesheeteditormodel.hpp b/src/nostalgia/modules/core/src/studio/tilesheeteditor/tilesheeteditormodel.hpp index d54bedf4..d3069b9b 100644 --- a/src/nostalgia/modules/core/src/studio/tilesheeteditor/tilesheeteditormodel.hpp +++ b/src/nostalgia/modules/core/src/studio/tilesheeteditor/tilesheeteditormodel.hpp @@ -55,7 +55,7 @@ class TileSheetEditorModel: public ox::SignalHandler { constexpr TileSheet &img() noexcept; [[nodiscard]] - constexpr Palette const*pal() const noexcept; + constexpr Palette const&pal() const noexcept; [[nodiscard]] ox::StringView palPath() const noexcept; @@ -139,11 +139,11 @@ constexpr TileSheet &TileSheetEditorModel::img() noexcept { return m_img; } -constexpr Palette const*TileSheetEditorModel::pal() const noexcept { +constexpr Palette const&TileSheetEditorModel::pal() const noexcept { if (m_pal) { - return m_pal.get(); + return *m_pal; } - return &s_defaultPalette; + return s_defaultPalette; } constexpr studio::UndoStack *TileSheetEditorModel::undoStack() noexcept { diff --git a/src/nostalgia/modules/core/src/studio/tilesheeteditor/tilesheeteditorview.cpp b/src/nostalgia/modules/core/src/studio/tilesheeteditor/tilesheeteditorview.cpp index a202aff3..0bfd5b7f 100644 --- a/src/nostalgia/modules/core/src/studio/tilesheeteditor/tilesheeteditorview.cpp +++ b/src/nostalgia/modules/core/src/studio/tilesheeteditor/tilesheeteditorview.cpp @@ -66,7 +66,7 @@ void TileSheetEditorView::deleteTile(ox::Vec2 const&paneSize, ox::Vec2 const&cli m_model.deleteTiles(m_model.activeSubSheetIdx(), tileIdx, 1); } -void TileSheetEditorView::clickDraw(ox::Vec2 const &paneSize, ox::Vec2 const&clickPos) noexcept { +void TileSheetEditorView::clickDraw(ox::Vec2 const&paneSize, ox::Vec2 const&clickPos) noexcept { const auto pt = clickPoint(paneSize, clickPos); m_model.drawCommand(pt, m_palIdx); } diff --git a/src/nostalgia/modules/core/src/studio/tilesheeteditor/tilesheeteditorview.hpp b/src/nostalgia/modules/core/src/studio/tilesheeteditor/tilesheeteditorview.hpp index 94f9e46e..52ef3028 100644 --- a/src/nostalgia/modules/core/src/studio/tilesheeteditor/tilesheeteditorview.hpp +++ b/src/nostalgia/modules/core/src/studio/tilesheeteditor/tilesheeteditorview.hpp @@ -80,9 +80,6 @@ class TileSheetEditorView: public ox::SignalHandler { [[nodiscard]] constexpr TileSheet &img() noexcept; - [[nodiscard]] - constexpr const Palette *pal() const noexcept; - [[nodiscard]] constexpr auto &model() noexcept { return m_model; @@ -126,8 +123,4 @@ constexpr TileSheet &TileSheetEditorView::img() noexcept { return m_model.img(); } -constexpr const Palette *TileSheetEditorView::pal() const noexcept { - return m_model.pal(); -} - } diff --git a/src/nostalgia/modules/core/src/studio/tilesheeteditor/tilesheetpixels.cpp b/src/nostalgia/modules/core/src/studio/tilesheeteditor/tilesheetpixels.cpp index 1c91d2d7..89537be2 100644 --- a/src/nostalgia/modules/core/src/studio/tilesheeteditor/tilesheetpixels.cpp +++ b/src/nostalgia/modules/core/src/studio/tilesheeteditor/tilesheetpixels.cpp @@ -17,8 +17,8 @@ void TileSheetPixels::setPixelSizeMod(float sm) noexcept { } ox::Error TileSheetPixels::buildShader() noexcept { - const auto Vshad = ox::sfmt(VShad, gl::GlslVersion); - const auto Fshad = ox::sfmt(FShad, gl::GlslVersion); + auto const Vshad = ox::sfmt(VShad, gl::GlslVersion); + auto const Fshad = ox::sfmt(FShad, gl::GlslVersion); return glutils::buildShaderProgram(Vshad, Fshad).moveTo(m_shader); } @@ -28,7 +28,7 @@ void TileSheetPixels::draw(bool update, ox::Vec2 const&scroll) noexcept { if (update) { glutils::sendVbo(m_bufferSet); } - const auto uniformScroll = glGetUniformLocation(m_shader, "vScroll"); + auto const uniformScroll = glGetUniformLocation(m_shader, "vScroll"); glUniform2f(uniformScroll, scroll.x, scroll.y); glDrawElements(GL_TRIANGLES, static_cast(m_bufferSet.elements.size()), GL_UNSIGNED_INT, nullptr); glBindVertexArray(0); @@ -41,10 +41,10 @@ void TileSheetPixels::initBufferSet(ox::Vec2 const&paneSize) noexcept { m_bufferSet.ebo = glutils::generateBuffer(); update(paneSize); // vbo layout - const auto posAttr = static_cast(glGetAttribLocation(m_shader, "vPosition")); + auto const posAttr = static_cast(glGetAttribLocation(m_shader, "vPosition")); glEnableVertexAttribArray(posAttr); glVertexAttribPointer(posAttr, 2, GL_FLOAT, GL_FALSE, VertexVboRowLength * sizeof(float), nullptr); - const auto colorAttr = static_cast(glGetAttribLocation(m_shader, "vColor")); + auto const colorAttr = static_cast(glGetAttribLocation(m_shader, "vColor")); glEnableVertexAttribArray(colorAttr); glVertexAttribPointer(colorAttr, 3, GL_FLOAT, GL_FALSE, VertexVboRowLength * sizeof(float), std::bit_cast(uintptr_t{2 * sizeof(float)})); @@ -58,9 +58,9 @@ void TileSheetPixels::update(ox::Vec2 const&paneSize) noexcept { } ox::Vec2 TileSheetPixels::pixelSize(ox::Vec2 const&paneSize) const noexcept { - const auto [sw, sh] = paneSize; + auto const [sw, sh] = paneSize; constexpr float ymod = 0.35f / 10.0f; - const auto xmod = ymod * sh / sw; + auto const xmod = ymod * sh / sw; return {xmod * m_pixelSizeMod, ymod * m_pixelSizeMod}; } @@ -71,21 +71,21 @@ void TileSheetPixels::setPixelBufferObject( Color16 color, float *vbo, GLuint *ebo) const noexcept { - const auto [xmod, ymod] = pixelSize(paneSize); + auto const [xmod, ymod] = pixelSize(paneSize); x *= xmod; y *= -ymod; x -= 1.0f; y += 1.0f - ymod; - const auto r = redf(color), g = greenf(color), b = bluef(color); + auto const r = redf(color), g = greenf(color), b = bluef(color); // don't worry, these memcpys gets optimized to something much more ideal - const ox::Array vertices = { + ox::Array const vertices = { x, y, r, g, b, // bottom left x + xmod, y, r, g, b, // bottom right x + xmod, y + ymod, r, g, b, // top right x, y + ymod, r, g, b, // top left }; memcpy(vbo, vertices.data(), sizeof(vertices)); - const ox::Array elms = { + ox::Array const elms = { vertexRow + 0, vertexRow + 1, vertexRow + 2, vertexRow + 2, vertexRow + 3, vertexRow + 0, }; @@ -94,21 +94,21 @@ void TileSheetPixels::setPixelBufferObject( void TileSheetPixels::setBufferObjects(ox::Vec2 const&paneSize) noexcept { // set buffer lengths - const auto subSheet = m_model.activeSubSheet(); - const auto pal = m_model.pal(); - const auto width = subSheet->columns * TileWidth; - const auto height = subSheet->rows * TileHeight; - const auto pixels = static_cast(width * height); + auto const subSheet = m_model.activeSubSheet(); + auto const&pal = m_model.pal(); + auto const width = subSheet->columns * TileWidth; + auto const height = subSheet->rows * TileHeight; + auto const pixels = static_cast(width) * static_cast(height); m_bufferSet.vertices.resize(pixels * VertexVboLength); m_bufferSet.elements.resize(pixels * VertexEboLength); // set pixels walkPixels(*subSheet, m_model.img().bpp, [&](std::size_t i, uint8_t p) { - auto color = core::color(*pal, m_model.palettePage(), p); - const auto pt = idxToPt(static_cast(i), subSheet->columns); - const auto fx = static_cast(pt.x); - const auto fy = static_cast(pt.y); - const auto vbo = &m_bufferSet.vertices[i * VertexVboLength]; - const auto ebo = &m_bufferSet.elements[i * VertexEboLength]; + auto color = core::color(pal, m_model.palettePage(), p); + auto const pt = idxToPt(static_cast(i), subSheet->columns); + auto const fx = static_cast(pt.x); + auto const fy = static_cast(pt.y); + auto const vbo = &m_bufferSet.vertices[i * VertexVboLength]; + auto const ebo = &m_bufferSet.elements[i * VertexEboLength]; if (i * VertexVboLength + VertexVboLength > m_bufferSet.vertices.size()) { return; } @@ -116,9 +116,9 @@ void TileSheetPixels::setBufferObjects(ox::Vec2 const&paneSize) noexcept { return; } if (m_model.pixelSelected(i)) { - const auto r = red16(color) / 2; - const auto g = (green16(color) + 20) / 2; - const auto b = (blue16(color) + 31) / 2; + auto const r = red16(color) / 2; + auto const g = (green16(color) + 20) / 2; + auto const b = (blue16(color) + 31) / 2; color = color16(r, g, b); } setPixelBufferObject(paneSize, static_cast(i * VertexVboRows), fx, fy, color, vbo, ebo); diff --git a/src/nostalgia/modules/core/src/studio/tilesheeteditor/tilesheetpixels.hpp b/src/nostalgia/modules/core/src/studio/tilesheeteditor/tilesheetpixels.hpp index 9e1e054b..89c73d43 100644 --- a/src/nostalgia/modules/core/src/studio/tilesheeteditor/tilesheetpixels.hpp +++ b/src/nostalgia/modules/core/src/studio/tilesheeteditor/tilesheetpixels.hpp @@ -43,7 +43,7 @@ class TileSheetPixels { float m_pixelSizeMod = 1; glutils::GLProgram m_shader; glutils::BufferSet m_bufferSet; - const class TileSheetEditorModel &m_model; + class TileSheetEditorModel const&m_model; public: explicit TileSheetPixels(class TileSheetEditorModel &model) noexcept; @@ -62,7 +62,14 @@ class TileSheetPixels { ox::Vec2 pixelSize(ox::Vec2 const&paneSize) const noexcept; private: - void setPixelBufferObject(ox::Vec2 const&paneS, unsigned vertexRow, float x, float y, Color16 color, float *vbo, GLuint *ebo) const noexcept; + void setPixelBufferObject( + ox::Vec2 const&paneS, + unsigned vertexRow, + float x, + float y, + Color16 color, + float *vbo, + GLuint *ebo) const noexcept; void setBufferObjects(ox::Vec2 const&paneS) noexcept;