[nostalgia/core] Add PaletteV4, with support for page names, make PaletteColor object
All checks were successful
Build / build (push) Successful in 2m30s

This commit is contained in:
Gary Talent 2024-09-06 01:11:03 -05:00
parent 6189193ac4
commit 1a2b2b8bac
15 changed files with 303 additions and 83 deletions

View File

@ -0,0 +1,12 @@
O1;net.drinkingtea.ox.TypeDescriptor;1;{
"fieldList" :
[
{
"fieldName" : "name",
"typeId" : "net.drinkingtea.ox.BasicString#8#;1"
}
],
"primitiveType" : 5,
"typeName" : "net.drinkingtea.nostalgia.core.Palette.ColorInfo",
"typeVersion" : 3
}

View File

@ -0,0 +1,23 @@
O1;net.drinkingtea.ox.TypeDescriptor;1;{
"fieldList" :
[
{
"fieldName" : "name",
"typeId" : "net.drinkingtea.ox.BasicString#8#;1"
},
{
"fieldName" : "colors",
"subscriptLevels" : 1,
"subscriptStack" :
[
{
"subscriptType" : 4
}
],
"typeId" : "net.drinkingtea.nostalgia.core.PaletteColor;1"
}
],
"primitiveType" : 5,
"typeName" : "net.drinkingtea.nostalgia.core.Palette.PalettePage",
"typeVersion" : 1
}

View File

@ -1,6 +1,17 @@
O1;net.drinkingtea.ox.TypeDescriptor;1;{
"fieldList" :
[
{
"fieldName" : "colorInfo",
"subscriptLevels" : 1,
"subscriptStack" :
[
{
"subscriptType" : 4
}
],
"typeId" : "net.drinkingtea.nostalgia.core.Palette.ColorInfo;3"
},
{
"fieldName" : "pages",
"subscriptLevels" : 2,
@ -13,7 +24,7 @@ O1;net.drinkingtea.ox.TypeDescriptor;1;{
"subscriptType" : 4
}
],
"typeId" : "net.drinkingtea.nostalgia.core.Palette.Page;3"
"typeId" : "B.uint16;0"
}
],
"preloadable" : true,

View File

@ -0,0 +1,31 @@
O1;net.drinkingtea.ox.TypeDescriptor;1;{
"fieldList" :
[
{
"fieldName" : "colorNames",
"subscriptLevels" : 1,
"subscriptStack" :
[
{
"subscriptType" : 4
}
],
"typeId" : "net.drinkingtea.ox.BasicString#8#;1"
},
{
"fieldName" : "pages",
"subscriptLevels" : 1,
"subscriptStack" :
[
{
"subscriptType" : 4
}
],
"typeId" : "net.drinkingtea.nostalgia.core.Palette.PalettePage;1"
}
],
"preloadable" : true,
"primitiveType" : 5,
"typeName" : "net.drinkingtea.nostalgia.core.Palette",
"typeVersion" : 4
}

View File

@ -0,0 +1,24 @@
O1;net.drinkingtea.ox.TypeDescriptor;1;{
"fieldList" :
[
{
"fieldName" : "r",
"typeId" : "B.uint8;0"
},
{
"fieldName" : "g",
"typeId" : "B.uint8;0"
},
{
"fieldName" : "b",
"typeId" : "B.uint8;0"
},
{
"fieldName" : "a",
"typeId" : "B.uint8;0"
}
],
"primitiveType" : 5,
"typeName" : "net.drinkingtea.nostalgia.core.PaletteColor",
"typeVersion" : 1
}

View File

@ -4,10 +4,6 @@
#pragma once
#include <ox/std/array.hpp>
#include <ox/std/point.hpp>
#include <ox/std/size.hpp>
#include <ox/std/types.hpp>
#include <ox/std/vector.hpp>
#include <ox/model/def.hpp>
@ -17,6 +13,54 @@
namespace nostalgia::core {
struct PaletteColorV1 {
static constexpr auto TypeName = "net.drinkingtea.nostalgia.core.PaletteColor";
static constexpr auto TypeVersion = 1;
uint8_t r{}, g{}, b{}, a{};
constexpr PaletteColorV1() noexcept = default;
constexpr PaletteColorV1(Color16 const c) noexcept:
r{red16(c)},
g{green16(c)},
b{blue16(c)},
a{alpha16(c)} {}
constexpr operator Color16() const noexcept { return color16(r, g, b, a); }
};
oxModelBegin(PaletteColorV1)
oxModelField(r)
oxModelField(g)
oxModelField(b)
oxModelField(a)
oxModelEnd()
using PaletteColor = PaletteColorV1;
struct PalettePageV1 {
static constexpr auto TypeName = "net.drinkingtea.nostalgia.core.Palette.PalettePage";
static constexpr auto TypeVersion = 1;
ox::String name;
ox::Vector<PaletteColorV1> colors;
constexpr PalettePageV1() noexcept = default;
constexpr PalettePageV1(ox::StringParam pName, ox::Vector<PaletteColorV1> pColors) noexcept:
name(std::move(pName)), colors(std::move(pColors)) {}
constexpr PalettePageV1(ox::StringParam pName, ox::Vector<Color16> const&pColors) noexcept:
name(std::move(pName)) {
colors.reserve(pColors.size());
for (auto const c : pColors) {
colors.emplace_back(c);
}
}
};
oxModelBegin(PalettePageV1)
oxModelField(name)
oxModelField(colors)
oxModelEnd()
using PalettePage = PalettePageV1;
struct NostalgiaPalette {
static constexpr auto TypeName = "net.drinkingtea.nostalgia.core.NostalgiaPalette";
static constexpr auto TypeVersion = 1;
@ -36,6 +80,7 @@ struct PaletteV2 {
ox::Vector<ox::Vector<Color16>> pages;
};
struct PaletteV3 {
static constexpr auto TypeName = "net.drinkingtea.nostalgia.core.Palette";
static constexpr auto TypeVersion = 3;
@ -44,17 +89,54 @@ struct PaletteV3 {
static constexpr auto TypeName = "net.drinkingtea.nostalgia.core.Palette.ColorInfo";
static constexpr auto TypeVersion = 3;
ox::String name;
constexpr ColorInfo() noexcept = default;
constexpr explicit ColorInfo(ox::StringView pName) noexcept:
name(pName) {}
constexpr explicit ColorInfo(ox::String &&pName) noexcept:
name(std::move(pName)) {}
};
ox::Vector<ColorInfo> colorInfo;
ox::Vector<ox::Vector<Color16>> pages;
};
using Palette = PaletteV3;
[[nodiscard]]
constexpr bool valid(PaletteV3 const&p) noexcept {
auto const colors = p.colorInfo.size();
return ox::all_of(p.pages.begin(), p.pages.end(), [colors](auto const&page) {
return page.size() == colors;
});
}
constexpr ox::Error repair(PaletteV3 &p) noexcept {
auto const colors = p.colorInfo.size();
for (auto &page : p.pages) {
page.resize(colors);
}
return {};
}
struct PaletteV4 {
static constexpr auto TypeName = "net.drinkingtea.nostalgia.core.Palette";
static constexpr auto TypeVersion = 4;
static constexpr auto Preloadable = true;
ox::Vector<ox::String> colorNames;
ox::Vector<PalettePageV1> pages;
};
[[nodiscard]]
constexpr bool valid(PaletteV4 const&p) noexcept {
auto const colors = p.colorNames.size();
return ox::all_of(p.pages.begin(), p.pages.end(), [colors](PalettePageV1 const&page) {
return page.colors.size() == colors;
});
}
constexpr ox::Error repair(PaletteV4 &p) noexcept {
auto const colors = p.colorNames.size();
for (auto &page : p.pages) {
page.colors.resize(colors);
}
return {};
}
using Palette = PaletteV4;
struct CompactPaletteV1 {
@ -64,29 +146,36 @@ struct CompactPaletteV1 {
ox::Vector<ox::Vector<Color16>> pages{};
};
using CompactPalette = CompactPaletteV1;
[[nodiscard]]
constexpr bool valid(Palette const&p) noexcept {
auto const colors = p.colorInfo.size();
return ox::all_of(p.pages.begin(), p.pages.end(), [colors](auto const&page) {
constexpr bool valid(CompactPaletteV1 const&p) noexcept {
size_t colors{};
for (auto const&page : p.pages) {
colors = ox::max(colors, page.size());
}
return ox::all_of(p.pages.begin(), p.pages.end(), [colors](ox::Vector<Color16> const&page) {
return page.size() == colors;
});
}
[[nodiscard]]
constexpr ox::Error repair(Palette &p) noexcept {
auto const colors = p.colorInfo.size();
constexpr ox::Error repair(CompactPaletteV1 &p) noexcept {
size_t colors{};
for (auto const&page : p.pages) {
colors = ox::max(colors, page.size());
}
for (auto &page : p.pages) {
page.resize(colors);
}
return {};
}
using CompactPalette = CompactPaletteV1;
[[nodiscard]]
constexpr Color16 color(Palette const&pal, size_t page, size_t idx) noexcept {
if (page < pal.pages.size() && idx < pal.pages[page].size()) [[likely]] {
return pal.pages[page][idx];
if (page < pal.pages.size() && idx < pal.pages[page].colors.size()) [[likely]] {
return pal.pages[page].colors[idx];
}
return 0;
}
@ -111,7 +200,7 @@ constexpr Color16 color(CompactPalette const&pal, size_t idx) noexcept {
[[nodiscard]]
constexpr auto &colors(Palette &pal, size_t page = 0) noexcept {
return pal.pages[page];
return pal.pages[page].colors;
}
[[nodiscard]]
@ -132,7 +221,7 @@ constexpr auto &colors(CompactPalette const&pal, size_t page = 0) noexcept {
[[nodiscard]]
constexpr size_t colorCnt(Palette const&pal, size_t page = 0) noexcept {
if (page < pal.pages.size()) [[likely]] {
return pal.pages[page].size();
return pal.pages[page].colors.size();
}
return 0;
}
@ -149,7 +238,7 @@ constexpr size_t colorCnt(CompactPalette const&pal, size_t page = 0) noexcept {
constexpr size_t largestPage(Palette const&pal) noexcept {
size_t out{};
for (auto const&page : pal.pages) {
out = ox::max(out, page.size());
out = ox::max(out, page.colors.size());
}
return out;
}
@ -184,6 +273,11 @@ oxModelBegin(PaletteV3)
oxModelField(pages)
oxModelEnd()
oxModelBegin(PaletteV4)
oxModelField(colorNames)
oxModelField(pages)
oxModelEnd()
oxModelBegin(CompactPaletteV1)
oxModelField(pages)
oxModelEnd()

View File

@ -19,6 +19,7 @@ static class: public keel::Module {
NostalgiaPaletteToPaletteV1Converter m_nostalgiaPaletteToPaletteV1Converter;
PaletteV1ToPaletteV2Converter m_paletteV1ToPaletteV2Converter;
PaletteV2ToPaletteV3Converter m_paletteV2ToPaletteV3Converter;
PaletteV3ToPaletteV4Converter m_paletteV3ToPaletteV4Converter;
PaletteToCompactPaletteConverter m_paletteToCompactPaletteConverter;
TileSheetV1ToTileSheetV2Converter m_tileSheetV1ToTileSheetV2Converter;
TileSheetV2ToTileSheetV3Converter m_tileSheetV2ToTileSheetV3Converter;
@ -41,6 +42,8 @@ static class: public keel::Module {
keel::generateTypeDesc<CompactTileSheetV1>,
keel::generateTypeDesc<PaletteV1>,
keel::generateTypeDesc<PaletteV2>,
keel::generateTypeDesc<PaletteV3>,
keel::generateTypeDesc<PaletteV4>,
keel::generateTypeDesc<CompactPaletteV1>,
};
}
@ -51,6 +54,7 @@ static class: public keel::Module {
&m_nostalgiaPaletteToPaletteV1Converter,
&m_paletteV1ToPaletteV2Converter,
&m_paletteV2ToPaletteV3Converter,
&m_paletteV3ToPaletteV4Converter,
&m_paletteToCompactPaletteConverter,
&m_tileSheetV1ToTileSheetV2Converter,
&m_tileSheetV2ToTileSheetV3Converter,
@ -78,7 +82,8 @@ static class: public keel::Module {
if (typeId == ox::ModelTypeId_v<NostalgiaPalette> ||
typeId == ox::ModelTypeId_v<PaletteV1> ||
typeId == ox::ModelTypeId_v<PaletteV2> ||
typeId == ox::ModelTypeId_v<PaletteV3>) {
typeId == ox::ModelTypeId_v<PaletteV3> ||
typeId == ox::ModelTypeId_v<PaletteV4>) {
oxReturnError(keel::convertBuffToBuff<CompactPalette>(
ctx, buff, ox::ClawFormat::Metal).moveTo(buff));
return true;

View File

@ -28,6 +28,7 @@ ox::Error PaletteV2ToPaletteV3Converter::convert(
PaletteV3 &dst) const noexcept {
dst.pages = std::move(src.pages);
if (!dst.pages.empty()) {
dst.colorInfo.reserve(dst.pages[0].size());
for (size_t i = 0; i < dst.pages[0].size(); ++i) {
dst.colorInfo.emplace_back(ox::sfmt("Color {}", i + 1));
}
@ -35,11 +36,33 @@ ox::Error PaletteV2ToPaletteV3Converter::convert(
return {};
}
ox::Error PaletteV3ToPaletteV4Converter::convert(
keel::Context&,
PaletteV3 &src,
PaletteV4 &dst) const noexcept {
dst.pages.reserve(src.pages.size());
for (auto i = 1; auto &page : src.pages) {
dst.pages.emplace_back(ox::sfmt("Page {}", i), std::move(page));
++i;
}
dst.colorNames.reserve(src.colorInfo.size());
for (auto &ci : src.colorInfo) {
dst.colorNames.emplace_back(std::move(ci.name));
}
return {};
}
ox::Error PaletteToCompactPaletteConverter::convert(
keel::Context&,
Palette &src,
CompactPalette &dst) const noexcept {
dst.pages = std::move(src.pages);
dst.pages.reserve(src.pages.size());
for (auto &page : src.pages) {
auto &p = dst.pages.emplace_back();
for (auto const c : page.colors) {
p.emplace_back(c);
}
}
return {};
}

View File

@ -28,6 +28,10 @@ class PaletteV2ToPaletteV3Converter: public keel::Converter<PaletteV2, PaletteV3
ox::Error convert(keel::Context&, PaletteV2 &src, PaletteV3 &dst) const noexcept final;
};
class PaletteV3ToPaletteV4Converter: public keel::Converter<PaletteV3, PaletteV4> {
ox::Error convert(keel::Context&, PaletteV3 &src, PaletteV4 &dst) const noexcept final;
};
class PaletteToCompactPaletteConverter: public keel::Converter<Palette, CompactPalette> {
ox::Error convert(keel::Context&, Palette &src, CompactPalette &dst) const noexcept final;
};

View File

@ -49,13 +49,13 @@ void PaletteEditorImGui::keyStateChanged(turbine::Key key, bool down) {
void PaletteEditorImGui::draw(studio::StudioContext&) noexcept {
auto const paneSize = ImGui::GetContentRegionAvail();
{
ImGui::BeginChild("Pages", ImVec2(250, paneSize.y), true);
ImGui::BeginChild("Pages", {250, paneSize.y}, true);
drawPagesEditor();
ImGui::EndChild();
}
ImGui::SameLine();
{
ImGui::BeginChild("Colors", ImVec2(-1, paneSize.y), true);
ImGui::BeginChild("Colors", {-1, paneSize.y}, true);
drawColorsEditor();
ImGui::EndChild();
}
@ -84,7 +84,7 @@ void PaletteEditorImGui::drawColorsEditor() noexcept {
auto const colorEditorWidth = 220;
static constexpr auto toolbarHeight = 40;
{
auto const sz = ImVec2(70, 24);
auto constexpr sz = ImVec2{70, 24};
if (ImGui::Button("Add", sz)) {
auto const colorSz = colorCnt(m_pal, m_page);
constexpr Color16 c = 0;
@ -126,7 +126,7 @@ void PaletteEditorImGui::drawColorsEditor() noexcept {
"Colors",
6,
tableFlags,
ImVec2(tblWidth, colorsSz.y - (toolbarHeight + 5)));
{tblWidth, colorsSz.y - (toolbarHeight + 5)});
{
ImGui::TableSetupColumn("Idx", ImGuiTableColumnFlags_WidthFixed, 25);
ImGui::TableSetupColumn("Name", ImGuiTableColumnFlags_WidthFixed, 100);
@ -135,30 +135,28 @@ void PaletteEditorImGui::drawColorsEditor() noexcept {
ImGui::TableSetupColumn("Blue", ImGuiTableColumnFlags_WidthFixed, 40);
ImGui::TableSetupColumn("Preview", ImGuiTableColumnFlags_NoHide);
ImGui::TableHeadersRow();
for (auto i = 0u; auto const&c : m_pal.pages[m_page]) {
ImGui::PushID(static_cast<int>(i));
for (auto i = 0u; auto const&c : m_pal.pages[m_page].colors) {
ig::IDStackItem const idStackItem(static_cast<int>(i));
ImGui::TableNextRow();
drawColumn(i + 1);
drawColumnLeftAlign(m_pal.colorInfo[i].name);
drawColumnLeftAlign(m_pal.colorNames[i]);
drawColumn(red16(c));
drawColumn(green16(c));
drawColumn(blue16(c));
ImGui::TableNextColumn();
auto const ic = ImGui::GetColorU32(
ImVec4(redf(c), greenf(c), bluef(c), 1));
auto const ic = ImGui::GetColorU32({redf(c), greenf(c), bluef(c), 1});
ImGui::TableSetBgColor(ImGuiTableBgTarget_CellBg, ic);
if (ImGui::Selectable(
"##ColorRow", i == m_selectedColorRow, ImGuiSelectableFlags_SpanAllColumns)) {
m_selectedColorRow = i;
}
ImGui::PopID();
++i;
}
}
ImGui::EndTable();
if (colorEditor) {
ImGui::SameLine();
ImGui::BeginChild("ColorEditor", ImVec2(colorEditorWidth, -1), true);
ImGui::BeginChild("ColorEditor", {colorEditorWidth, -1}, true);
drawColorEditor();
ImGui::EndChild();
}
@ -168,7 +166,7 @@ void PaletteEditorImGui::drawPagesEditor() noexcept {
constexpr auto tableFlags = ImGuiTableFlags_RowBg;
auto const paneSz = ImGui::GetContentRegionAvail();
constexpr auto toolbarHeight = 40;
auto const btnSz = ImVec2(paneSz.x / 3 - 5.5f, 24);
auto const btnSz = ImVec2{paneSz.x / 3 - 5.5f, 24};
if (ImGui::Button("Add", btnSz)) {
std::ignore = pushCommand<DuplicatePageCommand>(m_pal, 0u, m_pal.pages.size());
m_page = m_pal.pages.size() - 1;
@ -186,19 +184,18 @@ void PaletteEditorImGui::drawPagesEditor() noexcept {
"PageSelect",
2,
tableFlags,
ImVec2(paneSz.x, paneSz.y - (toolbarHeight + 5)));
{paneSz.x, paneSz.y - (toolbarHeight + 5)});
{
ImGui::TableSetupColumn("Page", ImGuiTableColumnFlags_WidthFixed, 60);
ImGui::TableHeadersRow();
for (auto i = 0u; i < m_pal.pages.size(); ++i) {
ImGui::PushID(static_cast<int>(i));
ig::IDStackItem const idStackItem(static_cast<int>(i));
ImGui::TableNextRow();
drawColumn(i + 1);
ImGui::SameLine();
if (ImGui::Selectable("##PageRow", i == m_page, ImGuiSelectableFlags_SpanAllColumns)) {
m_page = i;
}
ImGui::PopID();
}
}
ImGui::EndTable();
@ -210,7 +207,7 @@ void PaletteEditorImGui::drawColorEditor() noexcept {
int g = green16(c);
int b = blue16(c);
int const a = alpha16(c);
auto const&currentName = m_pal.colorInfo[m_selectedColorRow].name;
auto const&currentName = m_pal.colorNames[m_selectedColorRow];
ox::IString<50> name;
name = currentName;
ImGui::InputText("Name", name.data(), name.cap() + 1);
@ -229,9 +226,9 @@ void PaletteEditorImGui::drawColorEditor() noexcept {
if (c != newColor) {
std::ignore = pushCommand<UpdateColorCommand>(m_pal, m_page, m_selectedColorRow, newColor);
}
if (currentName != name.data()) {
if (currentName != name) {
std::ignore = pushCommand<UpdateColorInfoCommand>(
m_pal, m_selectedColorRow, Palette::ColorInfo{name.data()});
m_pal, m_selectedColorRow, ox::String{name});
}
}

View File

@ -14,13 +14,13 @@ ApplyColorAllPagesCommand::ApplyColorAllPagesCommand(Palette &pal, size_t const
ox::Vector<Color16> colors;
colors.reserve(m_pal.pages.size());
for (auto const&p : m_pal.pages) {
colors.emplace_back(p[m_idx]);
colors.emplace_back(p.colors[m_idx]);
}
return colors;
}()) {
auto const c = color(m_pal, m_page, m_idx);
if (ox::all_of(m_pal.pages.begin(), m_pal.pages.end(), [this, c](ox::SpanView<Color16> const page) {
return page[m_idx] == c;
if (ox::all_of(m_pal.pages.begin(), m_pal.pages.end(), [this, c](PalettePage const&page) {
return page.colors[m_idx] == c;
})) {
throw studio::NoChangesException();
}
@ -33,14 +33,14 @@ int ApplyColorAllPagesCommand::commandId() const noexcept {
ox::Error ApplyColorAllPagesCommand::redo() noexcept {
auto const c = color(m_pal, m_page, m_idx);
for (auto &page : m_pal.pages) {
page[m_idx] = c;
page.colors[m_idx] = c;
}
return {};
}
ox::Error ApplyColorAllPagesCommand::undo() noexcept {
for (size_t p = 0u; auto &page : m_pal.pages) {
page[m_idx] = m_origColors[p];
page.colors[m_idx] = m_origColors[p];
++p;
}
return {};
@ -51,8 +51,8 @@ DuplicatePageCommand::DuplicatePageCommand(Palette &pal, size_t srcIdx, size_t d
m_pal(pal),
m_dstIdx(dstIdx) {
auto const&src = m_pal.pages[srcIdx];
m_page.reserve(src.size());
for (auto const&s : src) {
m_page.reserve(src.colors.size());
for (auto const&s : src.colors) {
m_page.emplace_back(s);
}
}
@ -62,12 +62,12 @@ int DuplicatePageCommand::commandId() const noexcept {
}
ox::Error DuplicatePageCommand::redo() noexcept {
m_pal.pages.emplace(m_dstIdx, std::move(m_page));
m_pal.pages.emplace(m_dstIdx, "", std::move(m_page));
return {};
}
ox::Error DuplicatePageCommand::undo() noexcept {
m_page = std::move(m_pal.pages[m_dstIdx]);
m_page = std::move(m_pal.pages[m_dstIdx].colors);
return m_pal.pages.erase(m_dstIdx).error;
}
@ -85,7 +85,7 @@ int RemovePageCommand::commandId() const noexcept {
}
ox::Error RemovePageCommand::redo() noexcept {
m_page = std::move(colors(m_pal, m_idx));
m_page = std::move(m_pal.pages[m_idx]);
return m_pal.pages.erase(m_idx).error;
}
@ -105,17 +105,17 @@ int AddColorCommand::commandId() const noexcept {
}
ox::Error AddColorCommand::redo() noexcept {
m_pal.colorInfo.emplace(m_idx, ox::sfmt("Color {}", m_pal.colorInfo.size() + 1));
m_pal.colorNames.emplace(m_idx, ox::sfmt("Color {}", m_pal.colorNames.size() + 1));
for (auto &page : m_pal.pages) {
page.emplace(m_idx, m_color);
page.colors.emplace(m_idx, m_color);
}
return {};
}
ox::Error AddColorCommand::undo() noexcept {
oxReturnError(m_pal.colorInfo.erase(m_idx));
oxReturnError(m_pal.colorNames.erase(m_idx));
for (auto &page : m_pal.pages) {
oxReturnError(page.erase(m_idx));
oxReturnError(page.colors.erase(m_idx));
}
return {};
}
@ -128,7 +128,7 @@ RemoveColorCommand::RemoveColorCommand(Palette &pal, size_t const idx) noexcept:
ox::Vector<Color16> colors;
colors.reserve(m_pal.pages.size());
for (auto const&p : m_pal.pages) {
colors.emplace_back(p[m_idx]);
colors.emplace_back(p.colors[m_idx]);
}
return colors;
}()) {}
@ -138,18 +138,18 @@ int RemoveColorCommand::commandId() const noexcept {
}
ox::Error RemoveColorCommand::redo() noexcept {
m_colorInfo = std::move(m_pal.colorInfo[m_idx]);
oxReturnError(m_pal.colorInfo.erase(m_idx));
m_colorInfo = std::move(m_pal.colorNames[m_idx]);
oxReturnError(m_pal.colorNames.erase(m_idx));
for (auto &page : m_pal.pages) {
oxReturnError(page.erase(m_idx));
oxReturnError(page.colors.erase(m_idx));
}
return {};
}
ox::Error RemoveColorCommand::undo() noexcept {
m_pal.colorInfo.emplace(m_idx, std::move(m_colorInfo));
m_pal.colorNames.emplace(m_idx, std::move(m_colorInfo));
for (size_t p = 0; auto &page : m_pal.pages) {
page.emplace(m_idx, m_colors[p]);
page.colors.emplace(m_idx, m_colors[p]);
++p;
}
return {};
@ -159,11 +159,11 @@ ox::Error RemoveColorCommand::undo() noexcept {
UpdateColorInfoCommand::UpdateColorInfoCommand(
Palette &pal,
size_t idx,
Palette::ColorInfo newColorInfo):
ox::StringParam newColorInfo):
m_pal(pal),
m_idx(idx),
m_altColorInfo(std::move(newColorInfo)) {
if (m_pal.colorInfo[m_idx].name == m_altColorInfo.name) {
if (m_pal.colorNames[m_idx] == m_altColorInfo) {
throw studio::NoChangesException();
}
}
@ -179,7 +179,6 @@ bool UpdateColorInfoCommand::mergeWith(UndoCommand const&cmd) noexcept {
return true;
}
[[nodiscard]]
int UpdateColorInfoCommand::commandId() const noexcept {
return static_cast<int>(PaletteEditorCommandId::UpdateColor);
}
@ -195,7 +194,7 @@ ox::Error UpdateColorInfoCommand::undo() noexcept {
}
void UpdateColorInfoCommand::swap() noexcept {
std::swap(m_pal.colorInfo[m_idx], m_altColorInfo);
std::swap(m_pal.colorNames[m_idx], m_altColorInfo);
}
@ -224,7 +223,6 @@ bool UpdateColorCommand::mergeWith(UndoCommand const&cmd) noexcept {
return true;
}
[[nodiscard]]
int UpdateColorCommand::commandId() const noexcept {
return static_cast<int>(PaletteEditorCommandId::UpdateColor);
}

View File

@ -7,7 +7,6 @@
#include <studio/studio.hpp>
#include <nostalgia/core/color.hpp>
#include <nostalgia/core/gfx.hpp>
#include <nostalgia/core/palette.hpp>
namespace nostalgia::core {
@ -48,7 +47,7 @@ class DuplicatePageCommand: public studio::UndoCommand {
private:
Palette &m_pal;
size_t m_dstIdx = 0;
ox::Vector<Color16> m_page;
ox::Vector<PaletteColor> m_page;
public:
DuplicatePageCommand(Palette &pal, size_t srcIdx, size_t dstIdx) noexcept;
@ -71,7 +70,7 @@ class RemovePageCommand: public studio::UndoCommand {
private:
Palette &m_pal;
size_t m_idx = 0;
ox::Vector<Color16> m_page;
PalettePage m_page;
public:
RemovePageCommand(Palette &pal, size_t idx) noexcept;
@ -111,7 +110,7 @@ class RemoveColorCommand: public studio::UndoCommand {
private:
Palette &m_pal;
size_t const m_idx = 0;
Palette::ColorInfo m_colorInfo;
ox::String m_colorInfo;
ox::Vector<Color16> const m_colors;
public:
@ -132,13 +131,13 @@ class UpdateColorInfoCommand: public studio::UndoCommand {
private:
Palette &m_pal;
size_t const m_idx{};
Palette::ColorInfo m_altColorInfo;
ox::String m_altColorInfo;
public:
UpdateColorInfoCommand(
Palette &pal,
size_t idx,
Palette::ColorInfo newColorInfo);
ox::StringParam newColorInfo);
~UpdateColorInfoCommand() noexcept override = default;
@ -162,7 +161,7 @@ class UpdateColorCommand: public studio::UndoCommand {
Palette &m_pal;
size_t const m_page = 0;
size_t const m_idx{};
Color16 m_altColor{};
PaletteColor m_altColor{};
public:
UpdateColorCommand(
@ -203,7 +202,6 @@ class MoveColorCommand: public studio::UndoCommand {
[[nodiscard]]
int commandId() const noexcept override;
public:
ox::Error redo() noexcept override;
ox::Error undo() noexcept override;

View File

@ -343,7 +343,7 @@ void TileSheetEditorImGui::showSubsheetEditor() noexcept {
}
}
ox::Error TileSheetEditorImGui::exportSubhseetToPng(int scale) noexcept {
ox::Error TileSheetEditorImGui::exportSubhseetToPng(int const scale) const noexcept {
oxRequire(path, studio::saveFile({{"PNG", "png"}}));
// subsheet to png
auto const&img = m_model.img();
@ -469,7 +469,7 @@ void TileSheetEditorImGui::drawPaletteSelector() noexcept {
{
auto const&pal = m_model.pal();
if (pal.pages.size() > m_model.palettePage()) {
for (auto i = 0u; auto const&c: pal.pages[m_model.palettePage()]) {
for (auto i = 0u; auto const&c: pal.pages[m_model.palettePage()].colors) {
ImGui::PushID(static_cast<int>(i));
// Column: color idx
ImGui::TableNextColumn();
@ -484,7 +484,7 @@ void TileSheetEditorImGui::drawPaletteSelector() noexcept {
auto ic = ImGui::GetColorU32(ImVec4(redf(c), greenf(c), bluef(c), 1));
ImGui::TableSetBgColor(ImGuiTableBgTarget_CellBg, ic);
ImGui::TableNextColumn();
auto const&name = i < pal.colorInfo.size() ? pal.colorInfo[i].name.c_str() : "";
auto const&name = i < pal.colorNames.size() ? pal.colorNames[i].c_str() : "";
ImGui::Text("%s", name);
ImGui::TableNextColumn();
ImGui::Text("(%02d, %02d, %02d)", red16(c), green16(c), blue16(c));

View File

@ -97,7 +97,7 @@ class TileSheetEditorImGui: public studio::Editor {
private:
void showSubsheetEditor() noexcept;
ox::Error exportSubhseetToPng(int scale) noexcept;
ox::Error exportSubhseetToPng(int scale) const noexcept;
void drawTileSheet(ox::Vec2 const&fbSize) noexcept;

View File

@ -27,8 +27,8 @@
namespace nostalgia::core {
Palette const TileSheetEditorModel::s_defaultPalette = {
.colorInfo = {ox::Vector<Palette::ColorInfo>{{}}},
.pages = {{ox::Vector<Color16>(128)}},
.colorNames = {ox::Vector<ox::String>{{}}},
.pages = {{"Page 1", ox::Vector<Color16>(128)}},
};
// delete pixels of all non-leaf nodes