[nostalgia/core] Add ability to save tile sheets and store columns and rows in ng file
This commit is contained in:
parent
748fea3d43
commit
bf00ff0e41
@ -1 +0,0 @@
|
|||||||
<03><>隔
|
|
Binary file not shown.
Binary file not shown.
@ -34,8 +34,11 @@ struct NostalgiaPalette {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct NostalgiaGraphic {
|
struct NostalgiaGraphic {
|
||||||
static constexpr auto Fields = 4;
|
static constexpr auto Fields = 6;
|
||||||
uint8_t bpp = 0;
|
int8_t bpp = 0;
|
||||||
|
// rows and columns are really only used by TileSheetEditor
|
||||||
|
int rows = 1;
|
||||||
|
int columns = 1;
|
||||||
ox::FileAddress defaultPalette;
|
ox::FileAddress defaultPalette;
|
||||||
NostalgiaPalette pal;
|
NostalgiaPalette pal;
|
||||||
ox::Vector<uint8_t> tiles;
|
ox::Vector<uint8_t> tiles;
|
||||||
@ -52,6 +55,8 @@ template<typename T>
|
|||||||
ox::Error model(T *io, NostalgiaGraphic *ng) {
|
ox::Error model(T *io, NostalgiaGraphic *ng) {
|
||||||
io->setTypeInfo("nostalgia::core::NostalgiaGraphic", NostalgiaGraphic::Fields);
|
io->setTypeInfo("nostalgia::core::NostalgiaGraphic", NostalgiaGraphic::Fields);
|
||||||
oxReturnError(io->field("bpp", &ng->bpp));
|
oxReturnError(io->field("bpp", &ng->bpp));
|
||||||
|
oxReturnError(io->field("rows", &ng->rows));
|
||||||
|
oxReturnError(io->field("columns", &ng->columns));
|
||||||
oxReturnError(io->field("defaultPalette", &ng->defaultPalette));
|
oxReturnError(io->field("defaultPalette", &ng->defaultPalette));
|
||||||
oxReturnError(io->field("pal", &ng->pal));
|
oxReturnError(io->field("pal", &ng->pal));
|
||||||
oxReturnError(io->field("tiles", &ng->tiles));
|
oxReturnError(io->field("tiles", &ng->tiles));
|
||||||
|
@ -104,6 +104,10 @@ Rectangle {
|
|||||||
height: tileGrid.rows * tileGrid.baseTileSize * tileGrid.scaleFactor
|
height: tileGrid.rows * tileGrid.baseTileSize * tileGrid.scaleFactor
|
||||||
rows: sheetData ? sheetData.rows : 1
|
rows: sheetData ? sheetData.rows : 1
|
||||||
columns: sheetData ? sheetData.columns : 1
|
columns: sheetData ? sheetData.columns : 1
|
||||||
|
states: State {
|
||||||
|
name: "widthChanged"
|
||||||
|
PropertyChanges { target: tileGrid.width; width: tileGrid.columns * tileGrid.baseTileSize * tileGrid.scaleFactor }
|
||||||
|
}
|
||||||
Repeater {
|
Repeater {
|
||||||
model: tileGrid.rows * tileGrid.columns
|
model: tileGrid.rows * tileGrid.columns
|
||||||
Tile {
|
Tile {
|
||||||
|
@ -15,6 +15,7 @@ constexpr auto PluginName = "NostalgiaCore";
|
|||||||
// Command IDs to use with QUndoCommand::id()
|
// Command IDs to use with QUndoCommand::id()
|
||||||
enum class CommandId {
|
enum class CommandId {
|
||||||
UpdatePixel = 1,
|
UpdatePixel = 1,
|
||||||
|
UpdateDimension = 2,
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -10,14 +10,17 @@
|
|||||||
#include <QHeaderView>
|
#include <QHeaderView>
|
||||||
#include <QPointer>
|
#include <QPointer>
|
||||||
#include <QQmlContext>
|
#include <QQmlContext>
|
||||||
|
#include <QQuickItem>
|
||||||
#include <QQuickWidget>
|
#include <QQuickWidget>
|
||||||
#include <QSet>
|
#include <QSet>
|
||||||
#include <QSettings>
|
#include <QSettings>
|
||||||
#include <QSpinBox>
|
#include <QSpinBox>
|
||||||
#include <QSplitter>
|
#include <QSplitter>
|
||||||
#include <QUndoCommand>
|
#include <QUndoCommand>
|
||||||
|
#include <QTableWidget>
|
||||||
#include <QToolBar>
|
#include <QToolBar>
|
||||||
#include <QVBoxLayout>
|
#include <QVBoxLayout>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
#include "consts.hpp"
|
#include "consts.hpp"
|
||||||
#include "tilesheeteditor.hpp"
|
#include "tilesheeteditor.hpp"
|
||||||
@ -53,6 +56,59 @@ struct LabeledSpinner: public QWidget {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class UpdateDimensionsCommand: public QUndoCommand {
|
||||||
|
public:
|
||||||
|
enum class Dimension {
|
||||||
|
Rows,
|
||||||
|
Columns,
|
||||||
|
};
|
||||||
|
|
||||||
|
private:
|
||||||
|
Dimension m_dimension = Dimension::Rows;
|
||||||
|
int m_oldVal = 0;
|
||||||
|
int m_newVal = 0;
|
||||||
|
SheetData *m_sheetData = nullptr;
|
||||||
|
|
||||||
|
public:
|
||||||
|
UpdateDimensionsCommand(SheetData *sheetData, Dimension dim, int oldVal, int newVal) {
|
||||||
|
m_sheetData = sheetData;
|
||||||
|
m_dimension = dim;
|
||||||
|
m_newVal = newVal;
|
||||||
|
m_oldVal = oldVal;
|
||||||
|
setObsolete(newVal == oldVal);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual ~UpdateDimensionsCommand() = default;
|
||||||
|
|
||||||
|
int id() const override {
|
||||||
|
return static_cast<int>(CommandId::UpdateDimension);
|
||||||
|
}
|
||||||
|
|
||||||
|
void redo() override {
|
||||||
|
switch (m_dimension) {
|
||||||
|
case Dimension::Rows:
|
||||||
|
m_sheetData->setRows(m_newVal);
|
||||||
|
break;
|
||||||
|
case Dimension::Columns:
|
||||||
|
m_sheetData->setColumns(m_newVal);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void undo() override {
|
||||||
|
switch (m_dimension) {
|
||||||
|
case Dimension::Rows:
|
||||||
|
m_sheetData->setRows(m_oldVal);
|
||||||
|
break;
|
||||||
|
case Dimension::Columns:
|
||||||
|
m_sheetData->setColumns(m_oldVal);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
class UpdatePixelsCommand: public QUndoCommand {
|
class UpdatePixelsCommand: public QUndoCommand {
|
||||||
private:
|
private:
|
||||||
struct PixelUpdate {
|
struct PixelUpdate {
|
||||||
@ -96,8 +152,8 @@ class UpdatePixelsCommand: public QUndoCommand {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool mergeWith(const QUndoCommand *cmd) override {
|
bool mergeWith(const QUndoCommand *cmd) override {
|
||||||
auto other = static_cast<const UpdatePixelsCommand*>(cmd);
|
auto other = dynamic_cast<const UpdatePixelsCommand*>(cmd);
|
||||||
if (m_cmdIdx == other->m_cmdIdx) {
|
if (other && m_cmdIdx == other->m_cmdIdx) {
|
||||||
m_pixelUpdates.unite(other->m_pixelUpdates);
|
m_pixelUpdates.unite(other->m_pixelUpdates);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -107,7 +163,14 @@ class UpdatePixelsCommand: public QUndoCommand {
|
|||||||
void redo() override {
|
void redo() override {
|
||||||
for (const auto &pu : m_pixelUpdates) {
|
for (const auto &pu : m_pixelUpdates) {
|
||||||
pu.item->setProperty("color", m_palette[m_newColorId]);
|
pu.item->setProperty("color", m_palette[m_newColorId]);
|
||||||
m_pixels[pu.item->property("pixelNumber").toInt()] = m_newColorId;
|
const auto index = pu.item->property("pixelNumber").toInt();
|
||||||
|
// resize to appropriate number of tiles if pixel beyond current
|
||||||
|
// range
|
||||||
|
if (m_pixels.size() < index) {
|
||||||
|
auto sz = (index / 64 + 1) * 64;
|
||||||
|
m_pixels.resize(sz);
|
||||||
|
}
|
||||||
|
m_pixels[index] = m_newColorId;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -117,6 +180,7 @@ class UpdatePixelsCommand: public QUndoCommand {
|
|||||||
m_pixels[pu.item->property("pixelNumber").toInt()] = pu.oldColorId;
|
m_pixels[pu.item->property("pixelNumber").toInt()] = pu.oldColorId;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -145,19 +209,49 @@ QStringList SheetData::palette() {
|
|||||||
return m_palette;
|
return m_palette;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SheetData::updatePixels(const studio::Context *ctx, QString ngPath, QString palPath) {
|
void SheetData::load(const studio::Context *ctx, QString ngPath, QString palPath) {
|
||||||
auto ng = ctx->project->loadObj<NostalgiaGraphic>(ngPath);
|
auto ng = ctx->project->loadObj<NostalgiaGraphic>(ngPath);
|
||||||
std::unique_ptr<NostalgiaPalette> npal;
|
|
||||||
if (palPath == "" && ng->defaultPalette.type() == ox::FileAddressType::Path) {
|
if (palPath == "" && ng->defaultPalette.type() == ox::FileAddressType::Path) {
|
||||||
palPath = ng->defaultPalette.getPath().value;
|
palPath = ng->defaultPalette.getPath().value;
|
||||||
}
|
}
|
||||||
|
m_tilesheetPath = ngPath;
|
||||||
|
m_currentPalettePath = palPath;
|
||||||
|
setRows(ng->rows);
|
||||||
|
setColumns(ng->columns);
|
||||||
|
if (palPath != "") {
|
||||||
|
setPalette(ctx, palPath);
|
||||||
|
} else {
|
||||||
|
setPalette(&ng->pal);
|
||||||
|
}
|
||||||
|
updatePixels(ng.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
void SheetData::save(const studio::Context *ctx, QString ngPath) {
|
||||||
|
auto ng = toNostalgiaGraphic();
|
||||||
|
ctx->project->writeObj(ngPath, ng.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
void SheetData::setPalette(const NostalgiaPalette *npal) {
|
||||||
|
// load palette
|
||||||
|
m_palette.clear();
|
||||||
|
for (std::size_t i = 0; i < npal->colors.size(); i++) {
|
||||||
|
const auto c = toQColor(npal->colors[i]);
|
||||||
|
const auto color = c.name(QColor::HexArgb);
|
||||||
|
m_palette.append(color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SheetData::setPalette(const studio::Context *ctx, QString palPath) {
|
||||||
|
std::unique_ptr<NostalgiaPalette> npal;
|
||||||
try {
|
try {
|
||||||
npal = ctx->project->loadObj<NostalgiaPalette>(palPath);
|
npal = ctx->project->loadObj<NostalgiaPalette>(palPath);
|
||||||
qInfo() << "Opened palette" << palPath;
|
qInfo() << "Opened palette" << palPath;
|
||||||
} catch (ox::Error) {
|
} catch (ox::Error) {
|
||||||
qWarning() << "Could not open palette" << palPath;
|
qWarning() << "Could not open palette" << palPath;
|
||||||
}
|
}
|
||||||
updatePixels(ng.get(), npal.get());
|
if (npal) {
|
||||||
|
setPalette(npal.get());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SheetData::setSelectedColor(int index) {
|
void SheetData::setSelectedColor(int index) {
|
||||||
@ -171,25 +265,24 @@ QUndoStack *SheetData::undoStack() {
|
|||||||
void SheetData::setColumns(int columns) {
|
void SheetData::setColumns(int columns) {
|
||||||
m_columns = columns;
|
m_columns = columns;
|
||||||
emit columnsChanged(columns);
|
emit columnsChanged(columns);
|
||||||
|
emit changeOccurred();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SheetData::setRows(int rows) {
|
void SheetData::setRows(int rows) {
|
||||||
m_rows = rows;
|
m_rows = rows;
|
||||||
emit rowsChanged(rows);
|
emit rowsChanged(rows);
|
||||||
|
emit changeOccurred();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SheetData::updatePixels(const NostalgiaGraphic *ng, const NostalgiaPalette *npal) {
|
void SheetData::updateColumns(int columns) {
|
||||||
if (!npal) {
|
m_cmdStack.push(new UpdateDimensionsCommand(this, UpdateDimensionsCommand::Dimension::Columns, m_columns, columns));
|
||||||
npal = &ng->pal;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// load palette
|
void SheetData::updateRows(int rows) {
|
||||||
for (std::size_t i = 0; i < npal->colors.size(); i++) {
|
m_cmdStack.push(new UpdateDimensionsCommand(this, UpdateDimensionsCommand::Dimension::Rows, m_rows, rows));
|
||||||
const auto c = toQColor(npal->colors[i]);
|
}
|
||||||
const auto color = c.name(QColor::HexArgb);
|
|
||||||
m_palette.append(color);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
void SheetData::updatePixels(const NostalgiaGraphic *ng) {
|
||||||
if (ng->bpp == 8) {
|
if (ng->bpp == 8) {
|
||||||
for (std::size_t i = 0; i < ng->tiles.size(); i++) {
|
for (std::size_t i = 0; i < ng->tiles.size(); i++) {
|
||||||
m_pixels.push_back(ng->tiles[i]);
|
m_pixels.push_back(ng->tiles[i]);
|
||||||
@ -209,6 +302,31 @@ void SheetData::updatePixels(const NostalgiaGraphic *ng, const NostalgiaPalette
|
|||||||
emit paletteChanged();
|
emit paletteChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<NostalgiaGraphic> SheetData::toNostalgiaGraphic() {
|
||||||
|
auto ng = std::make_unique<NostalgiaGraphic>();
|
||||||
|
const auto highestColorIdx = static_cast<uint8_t>(*std::max_element(m_pixels.begin(), m_pixels.end()));
|
||||||
|
ng->defaultPalette = m_currentPalettePath.toUtf8().data();
|
||||||
|
ng->bpp = highestColorIdx > 15 ? 8 : 4;
|
||||||
|
ng->columns = m_columns;
|
||||||
|
ng->rows = m_rows;
|
||||||
|
if (ng->bpp == 4) {
|
||||||
|
ng->tiles.resize(m_pixels.size() / 2);
|
||||||
|
for (int i = 0; i < m_pixels.size(); ++i) {
|
||||||
|
if (i & 1) {
|
||||||
|
ng->tiles[i / 2] |= static_cast<uint8_t>(m_pixels[i]) << 4;
|
||||||
|
} else {
|
||||||
|
ng->tiles[i / 2] = static_cast<uint8_t>(m_pixels[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ng->tiles.resize(m_pixels.size());
|
||||||
|
for (int i = 0; i < m_pixels.size(); ++i) {
|
||||||
|
ng->tiles[i] = static_cast<uint8_t>(m_pixels[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ng;
|
||||||
|
}
|
||||||
|
|
||||||
void SheetData::beginCmd() {
|
void SheetData::beginCmd() {
|
||||||
++m_cmdIdx;
|
++m_cmdIdx;
|
||||||
}
|
}
|
||||||
@ -220,6 +338,7 @@ void SheetData::endCmd() {
|
|||||||
|
|
||||||
TileSheetEditor::TileSheetEditor(QString path, const studio::Context *ctx, QWidget *parent): studio::Editor(parent) {
|
TileSheetEditor::TileSheetEditor(QString path, const studio::Context *ctx, QWidget *parent): studio::Editor(parent) {
|
||||||
m_ctx = ctx;
|
m_ctx = ctx;
|
||||||
|
m_itemPath = path;
|
||||||
m_itemName = path.mid(path.lastIndexOf('/'));
|
m_itemName = path.mid(path.lastIndexOf('/'));
|
||||||
auto lyt = new QVBoxLayout(this);
|
auto lyt = new QVBoxLayout(this);
|
||||||
m_splitter = new QSplitter(this);
|
m_splitter = new QSplitter(this);
|
||||||
@ -227,12 +346,29 @@ TileSheetEditor::TileSheetEditor(QString path, const studio::Context *ctx, QWidg
|
|||||||
auto canvasLyt = new QVBoxLayout(canvasParent);
|
auto canvasLyt = new QVBoxLayout(canvasParent);
|
||||||
m_canvas = new QQuickWidget(canvasParent);
|
m_canvas = new QQuickWidget(canvasParent);
|
||||||
canvasLyt->addWidget(m_canvas);
|
canvasLyt->addWidget(m_canvas);
|
||||||
canvasLyt->setMenuBar(setupToolBar());
|
auto tb = new QToolBar(tr("Tile Sheet Options"));
|
||||||
|
m_tilesX = new LabeledSpinner(tr("Tiles &X:"), 1, m_sheetData.columns());
|
||||||
|
m_tilesY = new LabeledSpinner(tr("Tiles &Y:"), 1, m_sheetData.rows());
|
||||||
|
tb->addWidget(m_tilesX);
|
||||||
|
tb->addWidget(m_tilesY);
|
||||||
|
canvasLyt->setMenuBar(tb);
|
||||||
lyt->addWidget(m_splitter);
|
lyt->addWidget(m_splitter);
|
||||||
m_splitter->addWidget(canvasParent);
|
m_splitter->addWidget(canvasParent);
|
||||||
m_splitter->addWidget(setupColorPicker(m_splitter));
|
m_splitter->addWidget(setupColorPicker(m_splitter));
|
||||||
m_splitter->setStretchFactor(0, 1);
|
m_splitter->setStretchFactor(0, 1);
|
||||||
m_sheetData.updatePixels(m_ctx, path);
|
connect(&m_sheetData, &SheetData::columnsChanged, [this](int val) {
|
||||||
|
disconnect(m_tilesX->spinBox, QOverload<int>::of(&QSpinBox::valueChanged), &m_sheetData, &SheetData::updateColumns);
|
||||||
|
m_tilesX->spinBox->setValue(val);
|
||||||
|
connect(m_tilesX->spinBox, QOverload<int>::of(&QSpinBox::valueChanged), &m_sheetData, &SheetData::updateColumns);
|
||||||
|
});
|
||||||
|
connect(&m_sheetData, &SheetData::rowsChanged, [this](int val) {
|
||||||
|
disconnect(m_tilesY->spinBox, QOverload<int>::of(&QSpinBox::valueChanged), &m_sheetData, &SheetData::updateRows);
|
||||||
|
m_tilesY->spinBox->setValue(val);
|
||||||
|
connect(m_tilesY->spinBox, QOverload<int>::of(&QSpinBox::valueChanged), &m_sheetData, &SheetData::updateRows);
|
||||||
|
});
|
||||||
|
m_sheetData.load(m_ctx, m_itemPath);
|
||||||
|
connect(m_tilesX->spinBox, QOverload<int>::of(&QSpinBox::valueChanged), &m_sheetData, &SheetData::updateColumns);
|
||||||
|
connect(m_tilesY->spinBox, QOverload<int>::of(&QSpinBox::valueChanged), &m_sheetData, &SheetData::updateRows);
|
||||||
m_canvas->rootContext()->setContextProperty("sheetData", &m_sheetData);
|
m_canvas->rootContext()->setContextProperty("sheetData", &m_sheetData);
|
||||||
m_canvas->setSource(QUrl::fromLocalFile(":/qml/TileSheetEditor.qml"));
|
m_canvas->setSource(QUrl::fromLocalFile(":/qml/TileSheetEditor.qml"));
|
||||||
m_canvas->setResizeMode(QQuickWidget::SizeRootObjectToView);
|
m_canvas->setResizeMode(QQuickWidget::SizeRootObjectToView);
|
||||||
@ -249,24 +385,12 @@ QString TileSheetEditor::itemName() {
|
|||||||
return m_itemName;
|
return m_itemName;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TileSheetEditor::saveItem() {
|
|
||||||
}
|
|
||||||
|
|
||||||
QUndoStack *TileSheetEditor::undoStack() {
|
QUndoStack *TileSheetEditor::undoStack() {
|
||||||
return m_sheetData.undoStack();
|
return m_sheetData.undoStack();
|
||||||
}
|
}
|
||||||
|
|
||||||
QWidget *TileSheetEditor::setupToolBar() {
|
void TileSheetEditor::saveItem() {
|
||||||
auto tb = new QToolBar(tr("Tile Sheet Options"));
|
m_sheetData.save(m_ctx, m_itemPath);
|
||||||
m_tilesX = new LabeledSpinner(tr("Tiles &X:"), 1, m_sheetData.columns());
|
|
||||||
m_tilesY = new LabeledSpinner(tr("Tiles &Y:"), 1, m_sheetData.rows());
|
|
||||||
tb->addWidget(m_tilesX);
|
|
||||||
tb->addWidget(m_tilesY);
|
|
||||||
connect(&m_sheetData, &SheetData::columnsChanged, m_tilesX->spinBox, &QSpinBox::setValue);
|
|
||||||
connect(&m_sheetData, &SheetData::rowsChanged, m_tilesY->spinBox, &QSpinBox::setValue);
|
|
||||||
connect(m_tilesX->spinBox, QOverload<int>::of(&QSpinBox::valueChanged), &m_sheetData, &SheetData::setColumns);
|
|
||||||
connect(m_tilesY->spinBox, QOverload<int>::of(&QSpinBox::valueChanged), &m_sheetData, &SheetData::setRows);
|
|
||||||
return tb;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QWidget *TileSheetEditor::setupColorPicker(QWidget *parent) {
|
QWidget *TileSheetEditor::setupColorPicker(QWidget *parent) {
|
||||||
@ -314,8 +438,6 @@ void TileSheetEditor::restoreState() {
|
|||||||
QSettings settings(m_ctx->orgName, PluginName);
|
QSettings settings(m_ctx->orgName, PluginName);
|
||||||
settings.beginGroup("TileSheetEditor/" + m_itemName);
|
settings.beginGroup("TileSheetEditor/" + m_itemName);
|
||||||
m_splitter->restoreState(settings.value("m_splitter/state", m_splitter->saveState()).toByteArray());
|
m_splitter->restoreState(settings.value("m_splitter/state", m_splitter->saveState()).toByteArray());
|
||||||
m_sheetData.setRows(settings.value("m_sheetData/tileRows", 1).toInt());
|
|
||||||
m_sheetData.setColumns(settings.value("m_sheetData/tileColumns", 1).toInt());
|
|
||||||
m_colorPicker.colorTable->horizontalHeader()->restoreState(settings.value("m_colorPicker.colorTable/geometry", m_colorPicker.colorTable->horizontalHeader()->saveState()).toByteArray());
|
m_colorPicker.colorTable->horizontalHeader()->restoreState(settings.value("m_colorPicker.colorTable/geometry", m_colorPicker.colorTable->horizontalHeader()->saveState()).toByteArray());
|
||||||
settings.endGroup();
|
settings.endGroup();
|
||||||
}
|
}
|
||||||
|
@ -8,14 +8,9 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <QQuickItem>
|
|
||||||
#include <QSplitter>
|
|
||||||
#include <QStringList>
|
#include <QStringList>
|
||||||
#include <QStringView>
|
|
||||||
#include <QTableWidget>
|
|
||||||
#include <QUndoStack>
|
#include <QUndoStack>
|
||||||
#include <QVariant>
|
#include <QVariant>
|
||||||
#include <QWidget>
|
|
||||||
|
|
||||||
#include <nostalgia/core/gfx.hpp>
|
#include <nostalgia/core/gfx.hpp>
|
||||||
#include <nostalgia/studio/studio.hpp>
|
#include <nostalgia/studio/studio.hpp>
|
||||||
@ -30,7 +25,9 @@ class SheetData: public QObject {
|
|||||||
Q_PROPERTY(QStringList palette READ palette NOTIFY paletteChanged)
|
Q_PROPERTY(QStringList palette READ palette NOTIFY paletteChanged)
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QQuickItem *m_prevPixelUpdated = nullptr;
|
class QQuickItem *m_prevPixelUpdated = nullptr;
|
||||||
|
QString m_tilesheetPath;
|
||||||
|
QString m_currentPalettePath;
|
||||||
uint64_t m_cmdIdx = 0;
|
uint64_t m_cmdIdx = 0;
|
||||||
QUndoStack m_cmdStack;
|
QUndoStack m_cmdStack;
|
||||||
QStringList m_palette;
|
QStringList m_palette;
|
||||||
@ -54,7 +51,13 @@ class SheetData: public QObject {
|
|||||||
|
|
||||||
QStringList palette();
|
QStringList palette();
|
||||||
|
|
||||||
void updatePixels(const studio::Context *ctx, QString ngPath, QString palPath = "");
|
void load(const studio::Context *ctx, QString ngPath, QString palPath = "");
|
||||||
|
|
||||||
|
void save(const studio::Context *ctx, QString ngPath);
|
||||||
|
|
||||||
|
void setPalette(const NostalgiaPalette *pal);
|
||||||
|
|
||||||
|
void setPalette(const studio::Context *ctx, QString palPath);
|
||||||
|
|
||||||
void setSelectedColor(int index);
|
void setSelectedColor(int index);
|
||||||
|
|
||||||
@ -65,8 +68,20 @@ class SheetData: public QObject {
|
|||||||
|
|
||||||
void setRows(int rows);
|
void setRows(int rows);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets columns through a QUndoCommand.
|
||||||
|
*/
|
||||||
|
void updateColumns(int columns);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets rows through a QUndoCommand.
|
||||||
|
*/
|
||||||
|
void updateRows(int rows);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void updatePixels(const NostalgiaGraphic *ng, const NostalgiaPalette *npal);
|
void updatePixels(const NostalgiaGraphic *ng);
|
||||||
|
|
||||||
|
[[nodiscard]] std::unique_ptr<NostalgiaGraphic> toNostalgiaGraphic();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void changeOccurred();
|
void changeOccurred();
|
||||||
@ -86,16 +101,17 @@ class TileSheetEditor: public studio::Editor {
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
QString m_itemPath;
|
||||||
QString m_itemName;
|
QString m_itemName;
|
||||||
const studio::Context *m_ctx = nullptr;
|
const studio::Context *m_ctx = nullptr;
|
||||||
SheetData m_sheetData;
|
SheetData m_sheetData;
|
||||||
QSplitter *m_splitter = nullptr;
|
class QSplitter *m_splitter = nullptr;
|
||||||
struct LabeledSpinner *m_tilesX = nullptr;
|
struct LabeledSpinner *m_tilesX = nullptr;
|
||||||
struct LabeledSpinner *m_tilesY = nullptr;
|
struct LabeledSpinner *m_tilesY = nullptr;
|
||||||
class QQuickWidget* m_canvas = nullptr;
|
class QQuickWidget* m_canvas = nullptr;
|
||||||
struct {
|
struct {
|
||||||
QComboBox *palette = nullptr;
|
QComboBox *palette = nullptr;
|
||||||
QTableWidget *colorTable = nullptr;
|
class QTableWidget *colorTable = nullptr;
|
||||||
} m_colorPicker;
|
} m_colorPicker;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@ -105,13 +121,12 @@ class TileSheetEditor: public studio::Editor {
|
|||||||
|
|
||||||
QString itemName() override;
|
QString itemName() override;
|
||||||
|
|
||||||
void saveItem() override;
|
|
||||||
|
|
||||||
QUndoStack *undoStack() override;
|
QUndoStack *undoStack() override;
|
||||||
|
|
||||||
private:
|
protected:
|
||||||
QWidget *setupToolBar();
|
void saveItem() override;
|
||||||
|
|
||||||
|
private:
|
||||||
QWidget *setupColorPicker(QWidget *widget);
|
QWidget *setupColorPicker(QWidget *widget);
|
||||||
|
|
||||||
void setColorTable(QStringList hexColors);
|
void setColorTable(QStringList hexColors);
|
||||||
|
Loading…
Reference in New Issue
Block a user