[nostalgia/core] Add PaletteV4, with support for page names, make PaletteColor object
All checks were successful
Build / build (push) Successful in 2m30s
All checks were successful
Build / build (push) Successful in 2m30s
This commit is contained in:
parent
6189193ac4
commit
1a2b2b8bac
@ -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
|
||||
}
|
@ -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
|
||||
}
|
@ -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,
|
||||
|
@ -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
|
||||
}
|
@ -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
|
||||
}
|
@ -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()
|
||||
|
@ -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;
|
||||
|
@ -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 {};
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
};
|
||||
|
@ -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¤tName = m_pal.colorInfo[m_selectedColorRow].name;
|
||||
auto const¤tName = 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});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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));
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user