Squashed 'deps/nostalgia/' changes from ab025e88..4d63a65f
4d63a65f [nostalgia/core/studio] Show Palette page names in TileSheetEditor 686db99d [nostalgia/core/studio] Disable Palette page hotkeys when Rename popup is open 52533c8c [nostalgia/core/studio] Add Palette page names to editor ba4540e4 [ox/std] Add IString::unsafeResize 36057bb0 [nostalgia/core/studio] Fix Clang build 1a2b2b8b [nostalgia/core] Add PaletteV4, with support for page names, make PaletteColor object 6189193a [nostalgia] Add NFDE install 67a10d35 [nostalgia/sample_project] Update type descriptor git-subtree-dir: deps/nostalgia git-subtree-split: 4d63a65fbde480235edd961e5cd19d8b4de1b66d
This commit is contained in:
parent
a1a34f27f9
commit
ca2d9eb534
@ -61,6 +61,7 @@ if(NOT BUILDCORE_TARGET STREQUAL "gba")
|
|||||||
add_subdirectory(deps/glutils)
|
add_subdirectory(deps/glutils)
|
||||||
add_subdirectory(deps/imgui)
|
add_subdirectory(deps/imgui)
|
||||||
add_subdirectory(deps/lodepng)
|
add_subdirectory(deps/lodepng)
|
||||||
|
set(NFD_INSTALL ON)
|
||||||
add_subdirectory(deps/nfde)
|
add_subdirectory(deps/nfde)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
14
deps/ox/src/ox/std/istring.hpp
vendored
14
deps/ox/src/ox/std/istring.hpp
vendored
@ -81,6 +81,11 @@ class IString {
|
|||||||
|
|
||||||
constexpr ox::Error resize(size_t sz) noexcept;
|
constexpr ox::Error resize(size_t sz) noexcept;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resizes without clearing memory between current end and new end.
|
||||||
|
*/
|
||||||
|
constexpr ox::Error unsafeResize(size_t sz) noexcept;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the capacity of bytes for this string.
|
* Returns the capacity of bytes for this string.
|
||||||
*/
|
*/
|
||||||
@ -220,6 +225,15 @@ constexpr ox::Error IString<StrCap>::resize(size_t sz) noexcept {
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<std::size_t StrCap>
|
||||||
|
constexpr ox::Error IString<StrCap>::unsafeResize(size_t sz) noexcept {
|
||||||
|
if (sz > StrCap) [[unlikely]] {
|
||||||
|
return OxError(1, "Trying to extend IString beyond its cap");
|
||||||
|
}
|
||||||
|
m_size = sz;
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
template<size_t sz>
|
template<size_t sz>
|
||||||
struct MaybeView<ox::IString<sz>> {
|
struct MaybeView<ox::IString<sz>> {
|
||||||
using type = ox::StringView;
|
using type = ox::StringView;
|
||||||
|
@ -21,6 +21,7 @@ O1;net.drinkingtea.ox.TypeDescriptor;1;{
|
|||||||
"typeId" : "B.uint8;0"
|
"typeId" : "B.uint8;0"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
"preloadable" : true,
|
||||||
"primitiveType" : 5,
|
"primitiveType" : 5,
|
||||||
"typeName" : "net.drinkingtea.nostalgia.core.CompactTileSheet",
|
"typeName" : "net.drinkingtea.nostalgia.core.CompactTileSheet",
|
||||||
"typeVersion" : 1
|
"typeVersion" : 1
|
||||||
|
@ -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;{
|
O1;net.drinkingtea.ox.TypeDescriptor;1;{
|
||||||
"fieldList" :
|
"fieldList" :
|
||||||
[
|
[
|
||||||
|
{
|
||||||
|
"fieldName" : "colorInfo",
|
||||||
|
"subscriptLevels" : 1,
|
||||||
|
"subscriptStack" :
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"subscriptType" : 4
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"typeId" : "net.drinkingtea.nostalgia.core.Palette.ColorInfo;3"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"fieldName" : "pages",
|
"fieldName" : "pages",
|
||||||
"subscriptLevels" : 2,
|
"subscriptLevels" : 2,
|
||||||
@ -13,7 +24,7 @@ O1;net.drinkingtea.ox.TypeDescriptor;1;{
|
|||||||
"subscriptType" : 4
|
"subscriptType" : 4
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"typeId" : "net.drinkingtea.nostalgia.core.Palette.Page;3"
|
"typeId" : "B.uint16;0"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"preloadable" : true,
|
"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
|
#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/std/vector.hpp>
|
||||||
#include <ox/model/def.hpp>
|
#include <ox/model/def.hpp>
|
||||||
|
|
||||||
@ -17,6 +13,54 @@
|
|||||||
|
|
||||||
namespace nostalgia::core {
|
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 {
|
struct NostalgiaPalette {
|
||||||
static constexpr auto TypeName = "net.drinkingtea.nostalgia.core.NostalgiaPalette";
|
static constexpr auto TypeName = "net.drinkingtea.nostalgia.core.NostalgiaPalette";
|
||||||
static constexpr auto TypeVersion = 1;
|
static constexpr auto TypeVersion = 1;
|
||||||
@ -36,6 +80,7 @@ struct PaletteV2 {
|
|||||||
ox::Vector<ox::Vector<Color16>> pages;
|
ox::Vector<ox::Vector<Color16>> pages;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct PaletteV3 {
|
struct PaletteV3 {
|
||||||
static constexpr auto TypeName = "net.drinkingtea.nostalgia.core.Palette";
|
static constexpr auto TypeName = "net.drinkingtea.nostalgia.core.Palette";
|
||||||
static constexpr auto TypeVersion = 3;
|
static constexpr auto TypeVersion = 3;
|
||||||
@ -45,16 +90,55 @@ struct PaletteV3 {
|
|||||||
static constexpr auto TypeVersion = 3;
|
static constexpr auto TypeVersion = 3;
|
||||||
ox::String name;
|
ox::String name;
|
||||||
constexpr ColorInfo() noexcept = default;
|
constexpr ColorInfo() noexcept = default;
|
||||||
constexpr explicit ColorInfo(ox::StringView pName) noexcept:
|
constexpr ColorInfo(ox::StringParam pName) noexcept: name{std::move(pName)} {}
|
||||||
name(pName) {}
|
|
||||||
constexpr explicit ColorInfo(ox::String &&pName) noexcept:
|
|
||||||
name(std::move(pName)) {}
|
|
||||||
};
|
};
|
||||||
ox::Vector<ColorInfo> colorInfo;
|
ox::Vector<ColorInfo> colorInfo;
|
||||||
ox::Vector<ox::Vector<Color16>> pages;
|
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 {
|
struct CompactPaletteV1 {
|
||||||
@ -64,29 +148,36 @@ struct CompactPaletteV1 {
|
|||||||
ox::Vector<ox::Vector<Color16>> pages{};
|
ox::Vector<ox::Vector<Color16>> pages{};
|
||||||
};
|
};
|
||||||
|
|
||||||
using CompactPalette = CompactPaletteV1;
|
|
||||||
|
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
constexpr bool valid(Palette const&p) noexcept {
|
constexpr bool valid(CompactPaletteV1 const&p) noexcept {
|
||||||
auto const colors = p.colorInfo.size();
|
size_t colors{};
|
||||||
return ox::all_of(p.pages.begin(), p.pages.end(), [colors](auto const&page) {
|
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;
|
return page.size() == colors;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]]
|
constexpr ox::Error repair(CompactPaletteV1 &p) noexcept {
|
||||||
constexpr ox::Error repair(Palette &p) noexcept {
|
size_t colors{};
|
||||||
auto const colors = p.colorInfo.size();
|
for (auto const&page : p.pages) {
|
||||||
|
colors = ox::max(colors, page.size());
|
||||||
|
}
|
||||||
for (auto &page : p.pages) {
|
for (auto &page : p.pages) {
|
||||||
page.resize(colors);
|
page.resize(colors);
|
||||||
}
|
}
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
using CompactPalette = CompactPaletteV1;
|
||||||
|
|
||||||
|
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
constexpr Color16 color(Palette const&pal, size_t page, size_t idx) noexcept {
|
constexpr Color16 color(Palette const&pal, size_t page, size_t idx) noexcept {
|
||||||
if (page < pal.pages.size() && idx < pal.pages[page].size()) [[likely]] {
|
if (page < pal.pages.size() && idx < pal.pages[page].colors.size()) [[likely]] {
|
||||||
return pal.pages[page][idx];
|
return pal.pages[page].colors[idx];
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -111,7 +202,7 @@ constexpr Color16 color(CompactPalette const&pal, size_t idx) noexcept {
|
|||||||
|
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
constexpr auto &colors(Palette &pal, size_t page = 0) noexcept {
|
constexpr auto &colors(Palette &pal, size_t page = 0) noexcept {
|
||||||
return pal.pages[page];
|
return pal.pages[page].colors;
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
@ -132,7 +223,7 @@ constexpr auto &colors(CompactPalette const&pal, size_t page = 0) noexcept {
|
|||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
constexpr size_t colorCnt(Palette const&pal, size_t page = 0) noexcept {
|
constexpr size_t colorCnt(Palette const&pal, size_t page = 0) noexcept {
|
||||||
if (page < pal.pages.size()) [[likely]] {
|
if (page < pal.pages.size()) [[likely]] {
|
||||||
return pal.pages[page].size();
|
return pal.pages[page].colors.size();
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -149,7 +240,7 @@ constexpr size_t colorCnt(CompactPalette const&pal, size_t page = 0) noexcept {
|
|||||||
constexpr size_t largestPage(Palette const&pal) noexcept {
|
constexpr size_t largestPage(Palette const&pal) noexcept {
|
||||||
size_t out{};
|
size_t out{};
|
||||||
for (auto const&page : pal.pages) {
|
for (auto const&page : pal.pages) {
|
||||||
out = ox::max(out, page.size());
|
out = ox::max(out, page.colors.size());
|
||||||
}
|
}
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
@ -184,6 +275,11 @@ oxModelBegin(PaletteV3)
|
|||||||
oxModelField(pages)
|
oxModelField(pages)
|
||||||
oxModelEnd()
|
oxModelEnd()
|
||||||
|
|
||||||
|
oxModelBegin(PaletteV4)
|
||||||
|
oxModelField(colorNames)
|
||||||
|
oxModelField(pages)
|
||||||
|
oxModelEnd()
|
||||||
|
|
||||||
oxModelBegin(CompactPaletteV1)
|
oxModelBegin(CompactPaletteV1)
|
||||||
oxModelField(pages)
|
oxModelField(pages)
|
||||||
oxModelEnd()
|
oxModelEnd()
|
||||||
|
@ -19,6 +19,7 @@ static class: public keel::Module {
|
|||||||
NostalgiaPaletteToPaletteV1Converter m_nostalgiaPaletteToPaletteV1Converter;
|
NostalgiaPaletteToPaletteV1Converter m_nostalgiaPaletteToPaletteV1Converter;
|
||||||
PaletteV1ToPaletteV2Converter m_paletteV1ToPaletteV2Converter;
|
PaletteV1ToPaletteV2Converter m_paletteV1ToPaletteV2Converter;
|
||||||
PaletteV2ToPaletteV3Converter m_paletteV2ToPaletteV3Converter;
|
PaletteV2ToPaletteV3Converter m_paletteV2ToPaletteV3Converter;
|
||||||
|
PaletteV3ToPaletteV4Converter m_paletteV3ToPaletteV4Converter;
|
||||||
PaletteToCompactPaletteConverter m_paletteToCompactPaletteConverter;
|
PaletteToCompactPaletteConverter m_paletteToCompactPaletteConverter;
|
||||||
TileSheetV1ToTileSheetV2Converter m_tileSheetV1ToTileSheetV2Converter;
|
TileSheetV1ToTileSheetV2Converter m_tileSheetV1ToTileSheetV2Converter;
|
||||||
TileSheetV2ToTileSheetV3Converter m_tileSheetV2ToTileSheetV3Converter;
|
TileSheetV2ToTileSheetV3Converter m_tileSheetV2ToTileSheetV3Converter;
|
||||||
@ -41,6 +42,8 @@ static class: public keel::Module {
|
|||||||
keel::generateTypeDesc<CompactTileSheetV1>,
|
keel::generateTypeDesc<CompactTileSheetV1>,
|
||||||
keel::generateTypeDesc<PaletteV1>,
|
keel::generateTypeDesc<PaletteV1>,
|
||||||
keel::generateTypeDesc<PaletteV2>,
|
keel::generateTypeDesc<PaletteV2>,
|
||||||
|
keel::generateTypeDesc<PaletteV3>,
|
||||||
|
keel::generateTypeDesc<PaletteV4>,
|
||||||
keel::generateTypeDesc<CompactPaletteV1>,
|
keel::generateTypeDesc<CompactPaletteV1>,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -51,6 +54,7 @@ static class: public keel::Module {
|
|||||||
&m_nostalgiaPaletteToPaletteV1Converter,
|
&m_nostalgiaPaletteToPaletteV1Converter,
|
||||||
&m_paletteV1ToPaletteV2Converter,
|
&m_paletteV1ToPaletteV2Converter,
|
||||||
&m_paletteV2ToPaletteV3Converter,
|
&m_paletteV2ToPaletteV3Converter,
|
||||||
|
&m_paletteV3ToPaletteV4Converter,
|
||||||
&m_paletteToCompactPaletteConverter,
|
&m_paletteToCompactPaletteConverter,
|
||||||
&m_tileSheetV1ToTileSheetV2Converter,
|
&m_tileSheetV1ToTileSheetV2Converter,
|
||||||
&m_tileSheetV2ToTileSheetV3Converter,
|
&m_tileSheetV2ToTileSheetV3Converter,
|
||||||
@ -78,7 +82,8 @@ static class: public keel::Module {
|
|||||||
if (typeId == ox::ModelTypeId_v<NostalgiaPalette> ||
|
if (typeId == ox::ModelTypeId_v<NostalgiaPalette> ||
|
||||||
typeId == ox::ModelTypeId_v<PaletteV1> ||
|
typeId == ox::ModelTypeId_v<PaletteV1> ||
|
||||||
typeId == ox::ModelTypeId_v<PaletteV2> ||
|
typeId == ox::ModelTypeId_v<PaletteV2> ||
|
||||||
typeId == ox::ModelTypeId_v<PaletteV3>) {
|
typeId == ox::ModelTypeId_v<PaletteV3> ||
|
||||||
|
typeId == ox::ModelTypeId_v<PaletteV4>) {
|
||||||
oxReturnError(keel::convertBuffToBuff<CompactPalette>(
|
oxReturnError(keel::convertBuffToBuff<CompactPalette>(
|
||||||
ctx, buff, ox::ClawFormat::Metal).moveTo(buff));
|
ctx, buff, ox::ClawFormat::Metal).moveTo(buff));
|
||||||
return true;
|
return true;
|
||||||
|
@ -28,6 +28,7 @@ ox::Error PaletteV2ToPaletteV3Converter::convert(
|
|||||||
PaletteV3 &dst) const noexcept {
|
PaletteV3 &dst) const noexcept {
|
||||||
dst.pages = std::move(src.pages);
|
dst.pages = std::move(src.pages);
|
||||||
if (!dst.pages.empty()) {
|
if (!dst.pages.empty()) {
|
||||||
|
dst.colorInfo.reserve(dst.pages[0].size());
|
||||||
for (size_t i = 0; i < dst.pages[0].size(); ++i) {
|
for (size_t i = 0; i < dst.pages[0].size(); ++i) {
|
||||||
dst.colorInfo.emplace_back(ox::sfmt("Color {}", i + 1));
|
dst.colorInfo.emplace_back(ox::sfmt("Color {}", i + 1));
|
||||||
}
|
}
|
||||||
@ -35,11 +36,33 @@ ox::Error PaletteV2ToPaletteV3Converter::convert(
|
|||||||
return {};
|
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(
|
ox::Error PaletteToCompactPaletteConverter::convert(
|
||||||
keel::Context&,
|
keel::Context&,
|
||||||
Palette &src,
|
Palette &src,
|
||||||
CompactPalette &dst) const noexcept {
|
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 {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,6 +28,10 @@ class PaletteV2ToPaletteV3Converter: public keel::Converter<PaletteV2, PaletteV3
|
|||||||
ox::Error convert(keel::Context&, PaletteV2 &src, PaletteV3 &dst) const noexcept final;
|
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> {
|
class PaletteToCompactPaletteConverter: public keel::Converter<Palette, CompactPalette> {
|
||||||
ox::Error convert(keel::Context&, Palette &src, CompactPalette &dst) const noexcept final;
|
ox::Error convert(keel::Context&, Palette &src, CompactPalette &dst) const noexcept final;
|
||||||
};
|
};
|
||||||
|
@ -4,8 +4,6 @@
|
|||||||
|
|
||||||
#include <imgui.h>
|
#include <imgui.h>
|
||||||
|
|
||||||
#include <ox/std/memory.hpp>
|
|
||||||
|
|
||||||
#include <keel/media.hpp>
|
#include <keel/media.hpp>
|
||||||
|
|
||||||
#include <nostalgia/core/gfx.hpp>
|
#include <nostalgia/core/gfx.hpp>
|
||||||
@ -17,6 +15,27 @@ namespace nostalgia::core {
|
|||||||
|
|
||||||
namespace ig = studio::ig;
|
namespace ig = studio::ig;
|
||||||
|
|
||||||
|
|
||||||
|
void PaletteEditorImGui::PageRename::draw(turbine::Context &tctx) noexcept {
|
||||||
|
if (!m_show) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (ig::BeginPopup(tctx, "Rename Page", m_show)) {
|
||||||
|
ig::InputText("Name", m_name);
|
||||||
|
switch (ig::PopupControlsOkCancel(m_show)) {
|
||||||
|
case ig::PopupResponse::OK:
|
||||||
|
inputSubmitted.emit(m_name);
|
||||||
|
[[fallthrough]];
|
||||||
|
case ig::PopupResponse::Cancel:
|
||||||
|
close();
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
ImGui::EndPopup();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
PaletteEditorImGui::PaletteEditorImGui(studio::StudioContext &sctx, ox::StringParam path):
|
PaletteEditorImGui::PaletteEditorImGui(studio::StudioContext &sctx, ox::StringParam path):
|
||||||
Editor(std::move(path)),
|
Editor(std::move(path)),
|
||||||
m_sctx(sctx),
|
m_sctx(sctx),
|
||||||
@ -26,10 +45,11 @@ PaletteEditorImGui::PaletteEditorImGui(studio::StudioContext &sctx, ox::StringPa
|
|||||||
throw OxException(1, "PaletteEditorImGui: invalid Palette object");
|
throw OxException(1, "PaletteEditorImGui: invalid Palette object");
|
||||||
}
|
}
|
||||||
undoStack()->changeTriggered.connect(this, &PaletteEditorImGui::handleCommand);
|
undoStack()->changeTriggered.connect(this, &PaletteEditorImGui::handleCommand);
|
||||||
|
m_pageRename.inputSubmitted.connect(this, &PaletteEditorImGui::renamePage);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PaletteEditorImGui::keyStateChanged(turbine::Key key, bool down) {
|
void PaletteEditorImGui::keyStateChanged(turbine::Key key, bool down) {
|
||||||
if (!down) {
|
if (!down || m_pageRename.isOpen()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (key >= turbine::Key::Num_1 && key <= turbine::Key::Num_9) {
|
if (key >= turbine::Key::Num_1 && key <= turbine::Key::Num_9) {
|
||||||
@ -49,16 +69,17 @@ void PaletteEditorImGui::keyStateChanged(turbine::Key key, bool down) {
|
|||||||
void PaletteEditorImGui::draw(studio::StudioContext&) noexcept {
|
void PaletteEditorImGui::draw(studio::StudioContext&) noexcept {
|
||||||
auto const paneSize = ImGui::GetContentRegionAvail();
|
auto const paneSize = ImGui::GetContentRegionAvail();
|
||||||
{
|
{
|
||||||
ImGui::BeginChild("Pages", ImVec2(250, paneSize.y), true);
|
ImGui::BeginChild("Pages", {280, paneSize.y}, true);
|
||||||
drawPagesEditor();
|
drawPagesEditor();
|
||||||
ImGui::EndChild();
|
ImGui::EndChild();
|
||||||
}
|
}
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
{
|
{
|
||||||
ImGui::BeginChild("Colors", ImVec2(-1, paneSize.y), true);
|
ImGui::BeginChild("Colors", {-1, paneSize.y}, true);
|
||||||
drawColorsEditor();
|
drawColorsEditor();
|
||||||
ImGui::EndChild();
|
ImGui::EndChild();
|
||||||
}
|
}
|
||||||
|
m_pageRename.draw(m_tctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
ox::Error PaletteEditorImGui::saveItem() noexcept {
|
ox::Error PaletteEditorImGui::saveItem() noexcept {
|
||||||
@ -84,7 +105,7 @@ void PaletteEditorImGui::drawColorsEditor() noexcept {
|
|||||||
auto const colorEditorWidth = 220;
|
auto const colorEditorWidth = 220;
|
||||||
static constexpr auto toolbarHeight = 40;
|
static constexpr auto toolbarHeight = 40;
|
||||||
{
|
{
|
||||||
auto const sz = ImVec2(70, 24);
|
auto constexpr sz = ImVec2{70, 24};
|
||||||
if (ImGui::Button("Add", sz)) {
|
if (ImGui::Button("Add", sz)) {
|
||||||
auto const colorSz = colorCnt(m_pal, m_page);
|
auto const colorSz = colorCnt(m_pal, m_page);
|
||||||
constexpr Color16 c = 0;
|
constexpr Color16 c = 0;
|
||||||
@ -126,7 +147,7 @@ void PaletteEditorImGui::drawColorsEditor() noexcept {
|
|||||||
"Colors",
|
"Colors",
|
||||||
6,
|
6,
|
||||||
tableFlags,
|
tableFlags,
|
||||||
ImVec2(tblWidth, colorsSz.y - (toolbarHeight + 5)));
|
{tblWidth, colorsSz.y - (toolbarHeight + 5)});
|
||||||
{
|
{
|
||||||
ImGui::TableSetupColumn("Idx", ImGuiTableColumnFlags_WidthFixed, 25);
|
ImGui::TableSetupColumn("Idx", ImGuiTableColumnFlags_WidthFixed, 25);
|
||||||
ImGui::TableSetupColumn("Name", ImGuiTableColumnFlags_WidthFixed, 100);
|
ImGui::TableSetupColumn("Name", ImGuiTableColumnFlags_WidthFixed, 100);
|
||||||
@ -135,30 +156,28 @@ void PaletteEditorImGui::drawColorsEditor() noexcept {
|
|||||||
ImGui::TableSetupColumn("Blue", ImGuiTableColumnFlags_WidthFixed, 40);
|
ImGui::TableSetupColumn("Blue", ImGuiTableColumnFlags_WidthFixed, 40);
|
||||||
ImGui::TableSetupColumn("Preview", ImGuiTableColumnFlags_NoHide);
|
ImGui::TableSetupColumn("Preview", ImGuiTableColumnFlags_NoHide);
|
||||||
ImGui::TableHeadersRow();
|
ImGui::TableHeadersRow();
|
||||||
for (auto i = 0u; auto const&c : m_pal.pages[m_page]) {
|
for (auto i = 0u; auto const&c : m_pal.pages[m_page].colors) {
|
||||||
ImGui::PushID(static_cast<int>(i));
|
ig::IDStackItem const idStackItem(static_cast<int>(i));
|
||||||
ImGui::TableNextRow();
|
ImGui::TableNextRow();
|
||||||
drawColumn(i + 1);
|
drawColumn(i + 1);
|
||||||
drawColumnLeftAlign(m_pal.colorInfo[i].name);
|
drawColumnLeftAlign(m_pal.colorNames[i]);
|
||||||
drawColumn(red16(c));
|
drawColumn(red16(c));
|
||||||
drawColumn(green16(c));
|
drawColumn(green16(c));
|
||||||
drawColumn(blue16(c));
|
drawColumn(blue16(c));
|
||||||
ImGui::TableNextColumn();
|
ImGui::TableNextColumn();
|
||||||
auto const ic = ImGui::GetColorU32(
|
auto const ic = ImGui::GetColorU32({redf(c), greenf(c), bluef(c), 1});
|
||||||
ImVec4(redf(c), greenf(c), bluef(c), 1));
|
|
||||||
ImGui::TableSetBgColor(ImGuiTableBgTarget_CellBg, ic);
|
ImGui::TableSetBgColor(ImGuiTableBgTarget_CellBg, ic);
|
||||||
if (ImGui::Selectable(
|
if (ImGui::Selectable(
|
||||||
"##ColorRow", i == m_selectedColorRow, ImGuiSelectableFlags_SpanAllColumns)) {
|
"##ColorRow", i == m_selectedColorRow, ImGuiSelectableFlags_SpanAllColumns)) {
|
||||||
m_selectedColorRow = i;
|
m_selectedColorRow = i;
|
||||||
}
|
}
|
||||||
ImGui::PopID();
|
|
||||||
++i;
|
++i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ImGui::EndTable();
|
ImGui::EndTable();
|
||||||
if (colorEditor) {
|
if (colorEditor) {
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
ImGui::BeginChild("ColorEditor", ImVec2(colorEditorWidth, -1), true);
|
ImGui::BeginChild("ColorEditor", {colorEditorWidth, -1}, true);
|
||||||
drawColorEditor();
|
drawColorEditor();
|
||||||
ImGui::EndChild();
|
ImGui::EndChild();
|
||||||
}
|
}
|
||||||
@ -168,7 +187,7 @@ void PaletteEditorImGui::drawPagesEditor() noexcept {
|
|||||||
constexpr auto tableFlags = ImGuiTableFlags_RowBg;
|
constexpr auto tableFlags = ImGuiTableFlags_RowBg;
|
||||||
auto const paneSz = ImGui::GetContentRegionAvail();
|
auto const paneSz = ImGui::GetContentRegionAvail();
|
||||||
constexpr auto toolbarHeight = 40;
|
constexpr auto toolbarHeight = 40;
|
||||||
auto const btnSz = ImVec2(paneSz.x / 3 - 5.5f, 24);
|
auto const btnSz = ImVec2{paneSz.x / 4 - 5.5f, 24};
|
||||||
if (ImGui::Button("Add", btnSz)) {
|
if (ImGui::Button("Add", btnSz)) {
|
||||||
std::ignore = pushCommand<DuplicatePageCommand>(m_pal, 0u, m_pal.pages.size());
|
std::ignore = pushCommand<DuplicatePageCommand>(m_pal, 0u, m_pal.pages.size());
|
||||||
m_page = m_pal.pages.size() - 1;
|
m_page = m_pal.pages.size() - 1;
|
||||||
@ -179,26 +198,31 @@ void PaletteEditorImGui::drawPagesEditor() noexcept {
|
|||||||
m_page = std::min(m_page, m_pal.pages.size() - 1);
|
m_page = std::min(m_page, m_pal.pages.size() - 1);
|
||||||
}
|
}
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
if (ImGui::Button("Duplicate", btnSz)) {
|
if (ImGui::Button("Clone", btnSz)) {
|
||||||
std::ignore = pushCommand<DuplicatePageCommand>(m_pal, m_page, m_pal.pages.size());
|
std::ignore = pushCommand<DuplicatePageCommand>(m_pal, m_page, m_pal.pages.size());
|
||||||
}
|
}
|
||||||
|
ImGui::SameLine();
|
||||||
|
if (ImGui::Button("Rename", btnSz)) {
|
||||||
|
m_pageRename.show(m_pal.pages[m_page].name);
|
||||||
|
}
|
||||||
ImGui::BeginTable(
|
ImGui::BeginTable(
|
||||||
"PageSelect",
|
"PageSelect",
|
||||||
2,
|
2,
|
||||||
tableFlags,
|
tableFlags,
|
||||||
ImVec2(paneSz.x, paneSz.y - (toolbarHeight + 5)));
|
{paneSz.x, paneSz.y - (toolbarHeight + 5)});
|
||||||
{
|
{
|
||||||
ImGui::TableSetupColumn("Page", ImGuiTableColumnFlags_WidthFixed, 60);
|
ImGui::TableSetupColumn("Page", ImGuiTableColumnFlags_WidthFixed, 60);
|
||||||
|
ImGui::TableSetupColumn("Name", ImGuiTableColumnFlags_WidthFixed, 200);
|
||||||
ImGui::TableHeadersRow();
|
ImGui::TableHeadersRow();
|
||||||
for (auto i = 0u; i < m_pal.pages.size(); ++i) {
|
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();
|
ImGui::TableNextRow();
|
||||||
drawColumn(i + 1);
|
drawColumn(i + 1);
|
||||||
|
drawColumnLeftAlign(m_pal.pages[i].name);
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
if (ImGui::Selectable("##PageRow", i == m_page, ImGuiSelectableFlags_SpanAllColumns)) {
|
if (ImGui::Selectable("##PageRow", i == m_page, ImGuiSelectableFlags_SpanAllColumns)) {
|
||||||
m_page = i;
|
m_page = i;
|
||||||
}
|
}
|
||||||
ImGui::PopID();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ImGui::EndTable();
|
ImGui::EndTable();
|
||||||
@ -210,7 +234,7 @@ void PaletteEditorImGui::drawColorEditor() noexcept {
|
|||||||
int g = green16(c);
|
int g = green16(c);
|
||||||
int b = blue16(c);
|
int b = blue16(c);
|
||||||
int const a = alpha16(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;
|
ox::IString<50> name;
|
||||||
name = currentName;
|
name = currentName;
|
||||||
ImGui::InputText("Name", name.data(), name.cap() + 1);
|
ImGui::InputText("Name", name.data(), name.cap() + 1);
|
||||||
@ -229,12 +253,16 @@ void PaletteEditorImGui::drawColorEditor() noexcept {
|
|||||||
if (c != newColor) {
|
if (c != newColor) {
|
||||||
std::ignore = pushCommand<UpdateColorCommand>(m_pal, m_page, m_selectedColorRow, newColor);
|
std::ignore = pushCommand<UpdateColorCommand>(m_pal, m_page, m_selectedColorRow, newColor);
|
||||||
}
|
}
|
||||||
if (currentName != name.data()) {
|
if (currentName != name) {
|
||||||
std::ignore = pushCommand<UpdateColorInfoCommand>(
|
std::ignore = pushCommand<UpdateColorInfoCommand>(
|
||||||
m_pal, m_selectedColorRow, Palette::ColorInfo{name.data()});
|
m_pal, m_selectedColorRow, ox::String{name});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ox::Error PaletteEditorImGui::renamePage(ox::StringView name) noexcept {
|
||||||
|
return pushCommand<RenamePageCommand>(m_pal, m_page, name);
|
||||||
|
}
|
||||||
|
|
||||||
ox::Error PaletteEditorImGui::handleCommand(studio::UndoCommand const*cmd) noexcept {
|
ox::Error PaletteEditorImGui::handleCommand(studio::UndoCommand const*cmd) noexcept {
|
||||||
if (dynamic_cast<RemovePageCommand const*>(cmd)) {
|
if (dynamic_cast<RemovePageCommand const*>(cmd)) {
|
||||||
m_page = ox::min(m_page, m_pal.pages.size() - 1);
|
m_page = ox::min(m_page, m_pal.pages.size() - 1);
|
||||||
|
@ -14,6 +14,23 @@ namespace nostalgia::core {
|
|||||||
class PaletteEditorImGui: public studio::Editor {
|
class PaletteEditorImGui: public studio::Editor {
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
class PageRename {
|
||||||
|
private:
|
||||||
|
ox::IString<50> m_name;
|
||||||
|
bool m_show = false;
|
||||||
|
public:
|
||||||
|
ox::Signal<ox::Error(ox::StringView name)> inputSubmitted;
|
||||||
|
constexpr void show(ox::StringView const&name) noexcept {
|
||||||
|
m_show = true;
|
||||||
|
m_name = name;
|
||||||
|
}
|
||||||
|
constexpr void close() noexcept {
|
||||||
|
m_show = false;
|
||||||
|
}
|
||||||
|
[[nodiscard]]
|
||||||
|
constexpr bool isOpen() const noexcept { return m_show; }
|
||||||
|
void draw(turbine::Context &tctx) noexcept;
|
||||||
|
} m_pageRename;
|
||||||
studio::StudioContext &m_sctx;
|
studio::StudioContext &m_sctx;
|
||||||
turbine::Context &m_tctx;
|
turbine::Context &m_tctx;
|
||||||
Palette m_pal;
|
Palette m_pal;
|
||||||
@ -45,6 +62,8 @@ class PaletteEditorImGui: public studio::Editor {
|
|||||||
|
|
||||||
void drawColorEditor() noexcept;
|
void drawColorEditor() noexcept;
|
||||||
|
|
||||||
|
ox::Error renamePage(ox::StringView name) noexcept;
|
||||||
|
|
||||||
ox::Error handleCommand(studio::UndoCommand const*) noexcept;
|
ox::Error handleCommand(studio::UndoCommand const*) noexcept;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -14,13 +14,13 @@ ApplyColorAllPagesCommand::ApplyColorAllPagesCommand(Palette &pal, size_t const
|
|||||||
ox::Vector<Color16> colors;
|
ox::Vector<Color16> colors;
|
||||||
colors.reserve(m_pal.pages.size());
|
colors.reserve(m_pal.pages.size());
|
||||||
for (auto const&p : m_pal.pages) {
|
for (auto const&p : m_pal.pages) {
|
||||||
colors.emplace_back(p[m_idx]);
|
colors.emplace_back(p.colors[m_idx]);
|
||||||
}
|
}
|
||||||
return colors;
|
return colors;
|
||||||
}()) {
|
}()) {
|
||||||
auto const c = color(m_pal, m_page, m_idx);
|
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) {
|
if (ox::all_of(m_pal.pages.begin(), m_pal.pages.end(), [this, c](PalettePage const&page) {
|
||||||
return page[m_idx] == c;
|
return page.colors[m_idx] == c;
|
||||||
})) {
|
})) {
|
||||||
throw studio::NoChangesException();
|
throw studio::NoChangesException();
|
||||||
}
|
}
|
||||||
@ -33,26 +33,46 @@ int ApplyColorAllPagesCommand::commandId() const noexcept {
|
|||||||
ox::Error ApplyColorAllPagesCommand::redo() noexcept {
|
ox::Error ApplyColorAllPagesCommand::redo() noexcept {
|
||||||
auto const c = color(m_pal, m_page, m_idx);
|
auto const c = color(m_pal, m_page, m_idx);
|
||||||
for (auto &page : m_pal.pages) {
|
for (auto &page : m_pal.pages) {
|
||||||
page[m_idx] = c;
|
page.colors[m_idx] = c;
|
||||||
}
|
}
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
ox::Error ApplyColorAllPagesCommand::undo() noexcept {
|
ox::Error ApplyColorAllPagesCommand::undo() noexcept {
|
||||||
for (size_t p = 0u; auto &page : m_pal.pages) {
|
for (size_t p = 0u; auto &page : m_pal.pages) {
|
||||||
page[m_idx] = m_origColors[p];
|
page.colors[m_idx] = m_origColors[p];
|
||||||
++p;
|
++p;
|
||||||
}
|
}
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
RenamePageCommand::RenamePageCommand(Palette &pal, size_t const page, ox::StringParam name) noexcept:
|
||||||
|
m_pal(pal),
|
||||||
|
m_page(page),
|
||||||
|
m_name{std::move(name)} {}
|
||||||
|
|
||||||
|
int RenamePageCommand::commandId() const noexcept {
|
||||||
|
return static_cast<int>(PaletteEditorCommandId::RenamePage);
|
||||||
|
}
|
||||||
|
|
||||||
|
ox::Error RenamePageCommand::redo() noexcept {
|
||||||
|
std::swap(m_pal.pages[m_page].name, m_name);
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
ox::Error RenamePageCommand::undo() noexcept {
|
||||||
|
std::swap(m_pal.pages[m_page].name, m_name);
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
DuplicatePageCommand::DuplicatePageCommand(Palette &pal, size_t srcIdx, size_t dstIdx) noexcept:
|
DuplicatePageCommand::DuplicatePageCommand(Palette &pal, size_t srcIdx, size_t dstIdx) noexcept:
|
||||||
m_pal(pal),
|
m_pal(pal),
|
||||||
m_dstIdx(dstIdx) {
|
m_dstIdx(dstIdx) {
|
||||||
auto const&src = m_pal.pages[srcIdx];
|
auto const&src = m_pal.pages[srcIdx];
|
||||||
m_page.reserve(src.size());
|
m_page.reserve(src.colors.size());
|
||||||
for (auto const&s : src) {
|
for (auto const&s : src.colors) {
|
||||||
m_page.emplace_back(s);
|
m_page.emplace_back(s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -62,12 +82,12 @@ int DuplicatePageCommand::commandId() const noexcept {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ox::Error DuplicatePageCommand::redo() 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 {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
ox::Error DuplicatePageCommand::undo() noexcept {
|
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;
|
return m_pal.pages.erase(m_dstIdx).error;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -85,7 +105,7 @@ int RemovePageCommand::commandId() const noexcept {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ox::Error RemovePageCommand::redo() 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;
|
return m_pal.pages.erase(m_idx).error;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -105,17 +125,17 @@ int AddColorCommand::commandId() const noexcept {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ox::Error AddColorCommand::redo() 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) {
|
for (auto &page : m_pal.pages) {
|
||||||
page.emplace(m_idx, m_color);
|
page.colors.emplace(m_idx, m_color);
|
||||||
}
|
}
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
ox::Error AddColorCommand::undo() noexcept {
|
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) {
|
for (auto &page : m_pal.pages) {
|
||||||
oxReturnError(page.erase(m_idx));
|
oxReturnError(page.colors.erase(m_idx));
|
||||||
}
|
}
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
@ -128,7 +148,7 @@ RemoveColorCommand::RemoveColorCommand(Palette &pal, size_t const idx) noexcept:
|
|||||||
ox::Vector<Color16> colors;
|
ox::Vector<Color16> colors;
|
||||||
colors.reserve(m_pal.pages.size());
|
colors.reserve(m_pal.pages.size());
|
||||||
for (auto const&p : m_pal.pages) {
|
for (auto const&p : m_pal.pages) {
|
||||||
colors.emplace_back(p[m_idx]);
|
colors.emplace_back(p.colors[m_idx]);
|
||||||
}
|
}
|
||||||
return colors;
|
return colors;
|
||||||
}()) {}
|
}()) {}
|
||||||
@ -138,18 +158,18 @@ int RemoveColorCommand::commandId() const noexcept {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ox::Error RemoveColorCommand::redo() noexcept {
|
ox::Error RemoveColorCommand::redo() noexcept {
|
||||||
m_colorInfo = std::move(m_pal.colorInfo[m_idx]);
|
m_colorInfo = std::move(m_pal.colorNames[m_idx]);
|
||||||
oxReturnError(m_pal.colorInfo.erase(m_idx));
|
oxReturnError(m_pal.colorNames.erase(m_idx));
|
||||||
for (auto &page : m_pal.pages) {
|
for (auto &page : m_pal.pages) {
|
||||||
oxReturnError(page.erase(m_idx));
|
oxReturnError(page.colors.erase(m_idx));
|
||||||
}
|
}
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
ox::Error RemoveColorCommand::undo() noexcept {
|
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) {
|
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;
|
++p;
|
||||||
}
|
}
|
||||||
return {};
|
return {};
|
||||||
@ -159,11 +179,11 @@ ox::Error RemoveColorCommand::undo() noexcept {
|
|||||||
UpdateColorInfoCommand::UpdateColorInfoCommand(
|
UpdateColorInfoCommand::UpdateColorInfoCommand(
|
||||||
Palette &pal,
|
Palette &pal,
|
||||||
size_t idx,
|
size_t idx,
|
||||||
Palette::ColorInfo newColorInfo):
|
ox::StringParam newColorInfo):
|
||||||
m_pal(pal),
|
m_pal(pal),
|
||||||
m_idx(idx),
|
m_idx(idx),
|
||||||
m_altColorInfo(std::move(newColorInfo)) {
|
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();
|
throw studio::NoChangesException();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -179,7 +199,6 @@ bool UpdateColorInfoCommand::mergeWith(UndoCommand const&cmd) noexcept {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]]
|
|
||||||
int UpdateColorInfoCommand::commandId() const noexcept {
|
int UpdateColorInfoCommand::commandId() const noexcept {
|
||||||
return static_cast<int>(PaletteEditorCommandId::UpdateColor);
|
return static_cast<int>(PaletteEditorCommandId::UpdateColor);
|
||||||
}
|
}
|
||||||
@ -195,7 +214,7 @@ ox::Error UpdateColorInfoCommand::undo() noexcept {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void UpdateColorInfoCommand::swap() 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 +243,6 @@ bool UpdateColorCommand::mergeWith(UndoCommand const&cmd) noexcept {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]]
|
|
||||||
int UpdateColorCommand::commandId() const noexcept {
|
int UpdateColorCommand::commandId() const noexcept {
|
||||||
return static_cast<int>(PaletteEditorCommandId::UpdateColor);
|
return static_cast<int>(PaletteEditorCommandId::UpdateColor);
|
||||||
}
|
}
|
||||||
|
@ -7,13 +7,13 @@
|
|||||||
#include <studio/studio.hpp>
|
#include <studio/studio.hpp>
|
||||||
|
|
||||||
#include <nostalgia/core/color.hpp>
|
#include <nostalgia/core/color.hpp>
|
||||||
#include <nostalgia/core/gfx.hpp>
|
|
||||||
#include <nostalgia/core/palette.hpp>
|
#include <nostalgia/core/palette.hpp>
|
||||||
|
|
||||||
namespace nostalgia::core {
|
namespace nostalgia::core {
|
||||||
|
|
||||||
enum class PaletteEditorCommandId {
|
enum class PaletteEditorCommandId {
|
||||||
ApplyColorAllPages,
|
ApplyColorAllPages,
|
||||||
|
RenamePage,
|
||||||
DuplicatePage,
|
DuplicatePage,
|
||||||
RemovePage,
|
RemovePage,
|
||||||
AddColor,
|
AddColor,
|
||||||
@ -44,11 +44,31 @@ class ApplyColorAllPagesCommand: public studio::UndoCommand {
|
|||||||
ox::Error undo() noexcept final;
|
ox::Error undo() noexcept final;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class RenamePageCommand: public studio::UndoCommand {
|
||||||
|
private:
|
||||||
|
Palette &m_pal;
|
||||||
|
size_t m_page = 0;
|
||||||
|
ox::String m_name;
|
||||||
|
|
||||||
|
public:
|
||||||
|
RenamePageCommand(Palette &pal, size_t page, ox::StringParam name) noexcept;
|
||||||
|
|
||||||
|
~RenamePageCommand() noexcept override = default;
|
||||||
|
|
||||||
|
[[nodiscard]]
|
||||||
|
int commandId() const noexcept final;
|
||||||
|
|
||||||
|
ox::Error redo() noexcept final;
|
||||||
|
|
||||||
|
ox::Error undo() noexcept final;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
class DuplicatePageCommand: public studio::UndoCommand {
|
class DuplicatePageCommand: public studio::UndoCommand {
|
||||||
private:
|
private:
|
||||||
Palette &m_pal;
|
Palette &m_pal;
|
||||||
size_t m_dstIdx = 0;
|
size_t m_dstIdx = 0;
|
||||||
ox::Vector<Color16> m_page;
|
ox::Vector<PaletteColor> m_page;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
DuplicatePageCommand(Palette &pal, size_t srcIdx, size_t dstIdx) noexcept;
|
DuplicatePageCommand(Palette &pal, size_t srcIdx, size_t dstIdx) noexcept;
|
||||||
@ -71,7 +91,7 @@ class RemovePageCommand: public studio::UndoCommand {
|
|||||||
private:
|
private:
|
||||||
Palette &m_pal;
|
Palette &m_pal;
|
||||||
size_t m_idx = 0;
|
size_t m_idx = 0;
|
||||||
ox::Vector<Color16> m_page;
|
PalettePage m_page;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
RemovePageCommand(Palette &pal, size_t idx) noexcept;
|
RemovePageCommand(Palette &pal, size_t idx) noexcept;
|
||||||
@ -111,7 +131,7 @@ class RemoveColorCommand: public studio::UndoCommand {
|
|||||||
private:
|
private:
|
||||||
Palette &m_pal;
|
Palette &m_pal;
|
||||||
size_t const m_idx = 0;
|
size_t const m_idx = 0;
|
||||||
Palette::ColorInfo m_colorInfo;
|
ox::String m_colorInfo;
|
||||||
ox::Vector<Color16> const m_colors;
|
ox::Vector<Color16> const m_colors;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@ -132,13 +152,13 @@ class UpdateColorInfoCommand: public studio::UndoCommand {
|
|||||||
private:
|
private:
|
||||||
Palette &m_pal;
|
Palette &m_pal;
|
||||||
size_t const m_idx{};
|
size_t const m_idx{};
|
||||||
Palette::ColorInfo m_altColorInfo;
|
ox::String m_altColorInfo;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
UpdateColorInfoCommand(
|
UpdateColorInfoCommand(
|
||||||
Palette &pal,
|
Palette &pal,
|
||||||
size_t idx,
|
size_t idx,
|
||||||
Palette::ColorInfo newColorInfo);
|
ox::StringParam newColorInfo);
|
||||||
|
|
||||||
~UpdateColorInfoCommand() noexcept override = default;
|
~UpdateColorInfoCommand() noexcept override = default;
|
||||||
|
|
||||||
@ -162,7 +182,7 @@ class UpdateColorCommand: public studio::UndoCommand {
|
|||||||
Palette &m_pal;
|
Palette &m_pal;
|
||||||
size_t const m_page = 0;
|
size_t const m_page = 0;
|
||||||
size_t const m_idx{};
|
size_t const m_idx{};
|
||||||
Color16 m_altColor{};
|
PaletteColor m_altColor{};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
UpdateColorCommand(
|
UpdateColorCommand(
|
||||||
@ -203,7 +223,6 @@ class MoveColorCommand: public studio::UndoCommand {
|
|||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
int commandId() const noexcept override;
|
int commandId() const noexcept override;
|
||||||
|
|
||||||
public:
|
|
||||||
ox::Error redo() noexcept override;
|
ox::Error redo() noexcept override;
|
||||||
|
|
||||||
ox::Error undo() 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"}}));
|
oxRequire(path, studio::saveFile({{"PNG", "png"}}));
|
||||||
// subsheet to png
|
// subsheet to png
|
||||||
auto const&img = m_model.img();
|
auto const&img = m_model.img();
|
||||||
@ -441,12 +441,14 @@ void TileSheetEditorImGui::drawPaletteSelector() noexcept {
|
|||||||
auto const pages = m_model.pal().pages.size();
|
auto const pages = m_model.pal().pages.size();
|
||||||
if (pages > 1) {
|
if (pages > 1) {
|
||||||
ImGui::Indent(20);
|
ImGui::Indent(20);
|
||||||
auto numStr = ox::itoa(m_model.palettePage() + 1);
|
using Str = ox::IString<55>;
|
||||||
|
auto numStr = ox::sfmt<Str>(
|
||||||
|
"{} - {}", m_model.palettePage() + 1, m_model.pal().pages[m_model.palettePage()].name);
|
||||||
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x - comboWidthSub);
|
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x - comboWidthSub);
|
||||||
if (ImGui::BeginCombo("Page", numStr.c_str(), 0)) {
|
if (ImGui::BeginCombo("Page", numStr.c_str(), 0)) {
|
||||||
for (auto n = 0u; n < pages; ++n) {
|
for (auto n = 0u; n < pages; ++n) {
|
||||||
auto const selected = (m_model.palettePage() == n);
|
auto const selected = (m_model.palettePage() == n);
|
||||||
numStr = ox::itoa(n + 1);
|
numStr = ox::sfmt<Str>("{} - {}", n + 1, m_model.pal().pages[n].name);
|
||||||
if (ImGui::Selectable(numStr.c_str(), selected) && m_model.palettePage() != n) {
|
if (ImGui::Selectable(numStr.c_str(), selected) && m_model.palettePage() != n) {
|
||||||
m_model.setPalettePage(n);
|
m_model.setPalettePage(n);
|
||||||
}
|
}
|
||||||
@ -469,7 +471,7 @@ void TileSheetEditorImGui::drawPaletteSelector() noexcept {
|
|||||||
{
|
{
|
||||||
auto const&pal = m_model.pal();
|
auto const&pal = m_model.pal();
|
||||||
if (pal.pages.size() > m_model.palettePage()) {
|
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));
|
ImGui::PushID(static_cast<int>(i));
|
||||||
// Column: color idx
|
// Column: color idx
|
||||||
ImGui::TableNextColumn();
|
ImGui::TableNextColumn();
|
||||||
@ -484,7 +486,7 @@ void TileSheetEditorImGui::drawPaletteSelector() noexcept {
|
|||||||
auto ic = ImGui::GetColorU32(ImVec4(redf(c), greenf(c), bluef(c), 1));
|
auto ic = ImGui::GetColorU32(ImVec4(redf(c), greenf(c), bluef(c), 1));
|
||||||
ImGui::TableSetBgColor(ImGuiTableBgTarget_CellBg, ic);
|
ImGui::TableSetBgColor(ImGuiTableBgTarget_CellBg, ic);
|
||||||
ImGui::TableNextColumn();
|
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::Text("%s", name);
|
||||||
ImGui::TableNextColumn();
|
ImGui::TableNextColumn();
|
||||||
ImGui::Text("(%02d, %02d, %02d)", red16(c), green16(c), blue16(c));
|
ImGui::Text("(%02d, %02d, %02d)", red16(c), green16(c), blue16(c));
|
||||||
|
@ -97,7 +97,7 @@ class TileSheetEditorImGui: public studio::Editor {
|
|||||||
private:
|
private:
|
||||||
void showSubsheetEditor() noexcept;
|
void showSubsheetEditor() noexcept;
|
||||||
|
|
||||||
ox::Error exportSubhseetToPng(int scale) noexcept;
|
ox::Error exportSubhseetToPng(int scale) const noexcept;
|
||||||
|
|
||||||
void drawTileSheet(ox::Vec2 const&fbSize) noexcept;
|
void drawTileSheet(ox::Vec2 const&fbSize) noexcept;
|
||||||
|
|
||||||
|
@ -27,8 +27,8 @@
|
|||||||
namespace nostalgia::core {
|
namespace nostalgia::core {
|
||||||
|
|
||||||
Palette const TileSheetEditorModel::s_defaultPalette = {
|
Palette const TileSheetEditorModel::s_defaultPalette = {
|
||||||
.colorInfo = {ox::Vector<Palette::ColorInfo>{{}}},
|
.colorNames = {ox::Vector<ox::String>{{}}},
|
||||||
.pages = {{ox::Vector<Color16>(128)}},
|
.pages = {{"Page 1", ox::Vector<Color16>(128)}},
|
||||||
};
|
};
|
||||||
|
|
||||||
// delete pixels of all non-leaf nodes
|
// delete pixels of all non-leaf nodes
|
||||||
|
@ -29,7 +29,7 @@ bool AboutPopup::isOpen() const noexcept {
|
|||||||
return m_stage == Stage::Open;
|
return m_stage == Stage::Open;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AboutPopup::draw(studio::StudioContext &sctx) noexcept {
|
void AboutPopup::draw(StudioContext &sctx) noexcept {
|
||||||
switch (m_stage) {
|
switch (m_stage) {
|
||||||
case Stage::Closed:
|
case Stage::Closed:
|
||||||
break;
|
break;
|
||||||
@ -40,15 +40,14 @@ void AboutPopup::draw(studio::StudioContext &sctx) noexcept {
|
|||||||
case Stage::Open: {
|
case Stage::Open: {
|
||||||
constexpr auto modalFlags =
|
constexpr auto modalFlags =
|
||||||
ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize;
|
ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize;
|
||||||
ImGui::SetNextWindowSize(ImVec2(215, 90));
|
ig::centerNextWindow(sctx.tctx);
|
||||||
studio::ig::centerNextWindow(sctx.tctx);
|
|
||||||
auto open = true;
|
auto open = true;
|
||||||
if (ImGui::BeginPopupModal("About", &open, modalFlags)) {
|
if (ImGui::BeginPopupModal("About", &open, modalFlags)) {
|
||||||
ImGui::Text("%s", m_text.c_str());
|
ImGui::Text("%s", m_text.c_str());
|
||||||
ImGui::NewLine();
|
ImGui::NewLine();
|
||||||
ImGui::Dummy(ImVec2(148.0f, 0.0f));
|
ImGui::Dummy({148.0f, 0.0f});
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
if (ImGui::Button("Close")) {
|
if (ig::PushButton("Close")) {
|
||||||
ImGui::CloseCurrentPopup();
|
ImGui::CloseCurrentPopup();
|
||||||
open = false;
|
open = false;
|
||||||
}
|
}
|
||||||
|
@ -18,7 +18,7 @@ struct StudioContext {
|
|||||||
StudioUI &ui;
|
StudioUI &ui;
|
||||||
Project *project = nullptr;
|
Project *project = nullptr;
|
||||||
turbine::Context &tctx;
|
turbine::Context &tctx;
|
||||||
inline StudioContext(StudioUI &pUi, turbine::Context &pTctx) noexcept:
|
StudioContext(StudioUI &pUi, turbine::Context &pTctx) noexcept:
|
||||||
ui(pUi), tctx(pTctx) {}
|
ui(pUi), tctx(pTctx) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -45,10 +45,10 @@ class DragDropSource {
|
|||||||
private:
|
private:
|
||||||
bool const m_active{};
|
bool const m_active{};
|
||||||
public:
|
public:
|
||||||
inline DragDropSource() noexcept:
|
DragDropSource() noexcept:
|
||||||
m_active(ImGui::BeginDragDropSource()) {
|
m_active(ImGui::BeginDragDropSource()) {
|
||||||
}
|
}
|
||||||
inline ~DragDropSource() noexcept {
|
~DragDropSource() noexcept {
|
||||||
if (m_active) {
|
if (m_active) {
|
||||||
ImGui::EndDragDropSource();
|
ImGui::EndDragDropSource();
|
||||||
}
|
}
|
||||||
@ -58,7 +58,7 @@ class DragDropSource {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
inline auto dragDropSource(auto const&cb) noexcept {
|
auto dragDropSource(auto const&cb) noexcept {
|
||||||
if constexpr(ox::is_same_v<decltype(cb()), ox::Error>) {
|
if constexpr(ox::is_same_v<decltype(cb()), ox::Error>) {
|
||||||
if (ig::DragDropSource const tgt; tgt) [[unlikely]] {
|
if (ig::DragDropSource const tgt; tgt) [[unlikely]] {
|
||||||
return cb();
|
return cb();
|
||||||
@ -75,10 +75,10 @@ class DragDropTarget {
|
|||||||
private:
|
private:
|
||||||
bool const m_active{};
|
bool const m_active{};
|
||||||
public:
|
public:
|
||||||
inline DragDropTarget() noexcept:
|
DragDropTarget() noexcept:
|
||||||
m_active(ImGui::BeginDragDropTarget()) {
|
m_active(ImGui::BeginDragDropTarget()) {
|
||||||
}
|
}
|
||||||
inline ~DragDropTarget() noexcept {
|
~DragDropTarget() noexcept {
|
||||||
if (m_active) {
|
if (m_active) {
|
||||||
ImGui::EndDragDropTarget();
|
ImGui::EndDragDropTarget();
|
||||||
}
|
}
|
||||||
@ -128,6 +128,21 @@ void centerNextWindow(turbine::Context &ctx) noexcept;
|
|||||||
|
|
||||||
bool PushButton(ox::CStringView lbl, ImVec2 const&btnSz = BtnSz) noexcept;
|
bool PushButton(ox::CStringView lbl, ImVec2 const&btnSz = BtnSz) noexcept;
|
||||||
|
|
||||||
|
template<size_t StrCap>
|
||||||
|
bool InputText(
|
||||||
|
ox::CStringView label,
|
||||||
|
ox::IString<StrCap> &text,
|
||||||
|
ImGuiInputTextFlags const flags = 0,
|
||||||
|
ImGuiInputTextCallback const callback = nullptr,
|
||||||
|
void *user_data = nullptr) noexcept {
|
||||||
|
auto const out = ImGui::InputText(
|
||||||
|
label.c_str(), text.data(), StrCap + 1, flags, callback, user_data);
|
||||||
|
if (out) {
|
||||||
|
std::ignore = text.unsafeResize(ox::strlen(text.c_str()));
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
enum class PopupResponse {
|
enum class PopupResponse {
|
||||||
None,
|
None,
|
||||||
OK,
|
OK,
|
||||||
@ -136,6 +151,8 @@ enum class PopupResponse {
|
|||||||
|
|
||||||
PopupResponse PopupControlsOkCancel(float popupWidth, bool &popupOpen);
|
PopupResponse PopupControlsOkCancel(float popupWidth, bool &popupOpen);
|
||||||
|
|
||||||
|
PopupResponse PopupControlsOkCancel(bool &popupOpen);
|
||||||
|
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
bool BeginPopup(turbine::Context &ctx, ox::CStringView popupName, bool &show, ImVec2 const&sz = {285, 0});
|
bool BeginPopup(turbine::Context &ctx, ox::CStringView popupName, bool &show, ImVec2 const&sz = {285, 0});
|
||||||
|
|
||||||
|
@ -73,9 +73,13 @@ PopupResponse PopupControlsOkCancel(float popupWidth, bool &popupOpen) {
|
|||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PopupResponse PopupControlsOkCancel(bool &popupOpen) {
|
||||||
|
return PopupControlsOkCancel(ImGui::GetContentRegionAvail().x + 17, popupOpen);
|
||||||
|
}
|
||||||
|
|
||||||
bool BeginPopup(turbine::Context &ctx, ox::CStringView popupName, bool &show, ImVec2 const&sz) {
|
bool BeginPopup(turbine::Context &ctx, ox::CStringView popupName, bool &show, ImVec2 const&sz) {
|
||||||
constexpr auto modalFlags = ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize;
|
constexpr auto modalFlags = ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize;
|
||||||
ig::centerNextWindow(ctx);
|
centerNextWindow(ctx);
|
||||||
ImGui::OpenPopup(popupName.c_str());
|
ImGui::OpenPopup(popupName.c_str());
|
||||||
ImGui::SetNextWindowSize(sz);
|
ImGui::SetNextWindowSize(sz);
|
||||||
return ImGui::BeginPopupModal(popupName.c_str(), &show, modalFlags);
|
return ImGui::BeginPopupModal(popupName.c_str(), &show, modalFlags);
|
||||||
@ -122,23 +126,11 @@ bool ComboBox(
|
|||||||
|
|
||||||
bool FileComboBox(
|
bool FileComboBox(
|
||||||
ox::CStringView lbl,
|
ox::CStringView lbl,
|
||||||
studio::StudioContext &sctx,
|
StudioContext &sctx,
|
||||||
ox::StringView fileExt,
|
ox::StringView fileExt,
|
||||||
size_t &selectedIdx) noexcept {
|
size_t &selectedIdx) noexcept {
|
||||||
auto const&list = sctx.project->fileList(fileExt);
|
auto const&list = sctx.project->fileList(fileExt);
|
||||||
bool out{};
|
return ComboBox(lbl, list, selectedIdx);
|
||||||
auto const first = selectedIdx < list.size() ? list[selectedIdx].c_str() : "";
|
|
||||||
if (ImGui::BeginCombo(lbl.c_str(), first, 0)) {
|
|
||||||
for (auto i = 0u; i < list.size(); ++i) {
|
|
||||||
const auto selected = (selectedIdx == i);
|
|
||||||
if (ImGui::Selectable(list[i].c_str(), selected) && selectedIdx != i) {
|
|
||||||
selectedIdx = i;
|
|
||||||
out = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ImGui::EndCombo();
|
|
||||||
}
|
|
||||||
return out;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ListBox(
|
bool ListBox(
|
||||||
@ -164,14 +156,14 @@ bool ListBox(
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool ListBox(ox::CStringView name, ox::SpanView<ox::String> const&list, size_t &selIdx) noexcept {
|
bool ListBox(ox::CStringView name, ox::SpanView<ox::String> const&list, size_t &selIdx) noexcept {
|
||||||
return ig::ListBox(name, [list](size_t i) -> ox::CStringView {
|
return ListBox(name, [list](size_t i) -> ox::CStringView {
|
||||||
return list[i];
|
return list[i];
|
||||||
}, list.size(), selIdx);
|
}, list.size(), selIdx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
FilePicker::FilePicker(
|
FilePicker::FilePicker(
|
||||||
studio::StudioContext &sctx,
|
StudioContext &sctx,
|
||||||
ox::String title,
|
ox::String title,
|
||||||
ox::String fileExt,
|
ox::String fileExt,
|
||||||
ImVec2 const&size) noexcept:
|
ImVec2 const&size) noexcept:
|
||||||
@ -186,12 +178,12 @@ void FilePicker::draw() noexcept {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
auto constexpr popupSz = ImVec2{450.f, 0};
|
auto constexpr popupSz = ImVec2{450.f, 0};
|
||||||
ig::IDStackItem const idStackItem(m_title.c_str());
|
IDStackItem const idStackItem(m_title);
|
||||||
if (ig::BeginPopup(m_sctx.tctx, m_title.c_str(), m_show, popupSz)) {
|
if (BeginPopup(m_sctx.tctx, m_title, m_show, popupSz)) {
|
||||||
auto const&list = m_sctx.project->fileList(m_fileExt);
|
auto const&list = m_sctx.project->fileList(m_fileExt);
|
||||||
size_t selIdx{};
|
size_t selIdx{};
|
||||||
ig::ComboBox(m_title.c_str(), list, selIdx);
|
ComboBox(m_title, list, selIdx);
|
||||||
if (ig::PopupControlsOkCancel(popupSz.x, m_show) == ig::PopupResponse::OK) {
|
if (PopupControlsOkCancel(popupSz.x, m_show) == ig::PopupResponse::OK) {
|
||||||
filePicked.emit(list[selIdx]);
|
filePicked.emit(list[selIdx]);
|
||||||
}
|
}
|
||||||
ImGui::EndPopup();
|
ImGui::EndPopup();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user