From 61ec1af0fb257571c2a2fff551336571b0181557 Mon Sep 17 00:00:00 2001 From: Marcus Huderle Date: Tue, 2 Oct 2018 19:01:41 -0500 Subject: [PATCH] Add tileset palette editor --- forms/paletteeditor.ui | 1536 ++++++++++++++++++++++++++++++++++++ forms/tileseteditor.ui | 6 + include/core/tileset.h | 1 + include/project.h | 2 + include/ui/paletteeditor.h | 43 + include/ui/tileseteditor.h | 7 + porymap.pro | 5 +- src/core/tileset.cpp | 3 + src/project.cpp | 74 +- src/ui/paletteeditor.cpp | 176 +++++ src/ui/tileseteditor.cpp | 41 +- 11 files changed, 1871 insertions(+), 23 deletions(-) create mode 100644 forms/paletteeditor.ui create mode 100644 include/ui/paletteeditor.h create mode 100644 src/ui/paletteeditor.cpp diff --git a/forms/paletteeditor.ui b/forms/paletteeditor.ui new file mode 100644 index 00000000..a8b18de4 --- /dev/null +++ b/forms/paletteeditor.ui @@ -0,0 +1,1536 @@ + + + PaletteEditor + + + + 0 + 0 + 817 + 739 + + + + MainWindow + + + + + + + + 0 + 0 + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + Palette + + + + + + + + + + + + + + 0 + 0 + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + Color 4 + + + + + + + 32 + 32 + + + + + 32 + 32 + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + + Red + + + + + + + 31 + + + Qt::Horizontal + + + false + + + false + + + QSlider::NoTicks + + + + + + + Green + + + + + + + Blue + + + + + + + 31 + + + Qt::Horizontal + + + + + + + 31 + + + Qt::Horizontal + + + + + + + + + + Color 5 + + + + + + + 32 + 32 + + + + + 32 + 32 + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + + Red + + + + + + + 31 + + + Qt::Horizontal + + + false + + + false + + + QSlider::NoTicks + + + + + + + Green + + + + + + + Blue + + + + + + + 31 + + + Qt::Horizontal + + + + + + + 31 + + + Qt::Horizontal + + + + + + + + + + Color 7 + + + + + + + 32 + 32 + + + + + 32 + 32 + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + + Red + + + + + + + 31 + + + Qt::Horizontal + + + false + + + false + + + QSlider::NoTicks + + + + + + + Green + + + + + + + Blue + + + + + + + 31 + + + Qt::Horizontal + + + + + + + 31 + + + Qt::Horizontal + + + + + + + + + + Color 6 + + + + + + + 32 + 32 + + + + + 32 + 32 + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + + Red + + + + + + + 31 + + + Qt::Horizontal + + + false + + + false + + + QSlider::NoTicks + + + + + + + Green + + + + + + + Blue + + + + + + + 31 + + + Qt::Horizontal + + + + + + + 31 + + + Qt::Horizontal + + + + + + + + + + Color 10 + + + + + + + 32 + 32 + + + + + 32 + 32 + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + + Red + + + + + + + 31 + + + Qt::Horizontal + + + false + + + false + + + QSlider::NoTicks + + + + + + + Green + + + + + + + Blue + + + + + + + 31 + + + Qt::Horizontal + + + + + + + 31 + + + Qt::Horizontal + + + + + + + + + + Color 8 + + + + + + + 32 + 32 + + + + + 32 + 32 + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + + Red + + + + + + + 31 + + + Qt::Horizontal + + + false + + + false + + + QSlider::NoTicks + + + + + + + Green + + + + + + + Blue + + + + + + + 31 + + + Qt::Horizontal + + + + + + + 31 + + + Qt::Horizontal + + + + + + + + + + Color 9 + + + + + + + 32 + 32 + + + + + 32 + 32 + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + + Red + + + + + + + 31 + + + Qt::Horizontal + + + false + + + false + + + QSlider::NoTicks + + + + + + + Green + + + + + + + Blue + + + + + + + 31 + + + Qt::Horizontal + + + + + + + 31 + + + Qt::Horizontal + + + + + + + + + + Color 11 + + + + + + + 32 + 32 + + + + + 32 + 32 + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + + Red + + + + + + + 31 + + + Qt::Horizontal + + + false + + + false + + + QSlider::NoTicks + + + + + + + Green + + + + + + + Blue + + + + + + + 31 + + + Qt::Horizontal + + + + + + + 31 + + + Qt::Horizontal + + + + + + + + + + Color 12 + + + + + + + 32 + 32 + + + + + 32 + 32 + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + + Red + + + + + + + 31 + + + Qt::Horizontal + + + false + + + false + + + QSlider::NoTicks + + + + + + + Green + + + + + + + Blue + + + + + + + 31 + + + Qt::Horizontal + + + + + + + 31 + + + Qt::Horizontal + + + + + + + + + + Color 14 + + + + + + + 32 + 32 + + + + + 32 + 32 + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + + Red + + + + + + + 31 + + + Qt::Horizontal + + + false + + + false + + + QSlider::NoTicks + + + + + + + Green + + + + + + + Blue + + + + + + + 31 + + + Qt::Horizontal + + + + + + + 31 + + + Qt::Horizontal + + + + + + + + + + Color 13 + + + + + + + 32 + 32 + + + + + 32 + 32 + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + + Red + + + + + + + 31 + + + Qt::Horizontal + + + false + + + false + + + QSlider::NoTicks + + + + + + + Green + + + + + + + Blue + + + + + + + 31 + + + Qt::Horizontal + + + + + + + 31 + + + Qt::Horizontal + + + + + + + + + + Color 15 + + + + + + + 32 + 32 + + + + + 32 + 32 + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + + Red + + + + + + + 31 + + + Qt::Horizontal + + + false + + + false + + + QSlider::NoTicks + + + + + + + Green + + + + + + + Blue + + + + + + + 31 + + + Qt::Horizontal + + + + + + + 31 + + + Qt::Horizontal + + + + + + + + + + Color 0 + + + + + + Red + + + + + + + 31 + + + Qt::Horizontal + + + false + + + false + + + QSlider::NoTicks + + + + + + + Green + + + + + + + 31 + + + Qt::Horizontal + + + + + + + Blue + + + + + + + 31 + + + Qt::Horizontal + + + + + + + + 32 + 32 + + + + + 32 + 32 + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + + + + + Color 1 + + + + + + + 32 + 32 + + + + + 32 + 32 + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + + Red + + + + + + + 31 + + + Qt::Horizontal + + + false + + + false + + + QSlider::NoTicks + + + + + + + Green + + + + + + + 31 + + + Qt::Horizontal + + + + + + + Blue + + + + + + + 31 + + + Qt::Horizontal + + + + + + + + + + Color 2 + + + + + + + 32 + 32 + + + + + 32 + 32 + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + + Red + + + + + + + 31 + + + Qt::Horizontal + + + false + + + false + + + QSlider::NoTicks + + + + + + + Green + + + + + + + Blue + + + + + + + 31 + + + Qt::Horizontal + + + + + + + 31 + + + Qt::Horizontal + + + + + + + + + + Color 3 + + + + + + + 32 + 32 + + + + + 32 + 32 + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + + Red + + + + + + + 31 + + + Qt::Horizontal + + + false + + + false + + + QSlider::NoTicks + + + + + + + Green + + + + + + + Blue + + + + + + + 31 + + + Qt::Horizontal + + + + + + + 31 + + + Qt::Horizontal + + + + + + + + + + + + + + + 0 + 0 + 817 + 21 + + + + + + + + diff --git a/forms/tileseteditor.ui b/forms/tileseteditor.ui index bdbbae89..f8b6947f 100644 --- a/forms/tileseteditor.ui +++ b/forms/tileseteditor.ui @@ -405,6 +405,7 @@ + @@ -433,6 +434,11 @@ Change Number of Metatiles + + + Change Palettes + + diff --git a/include/core/tileset.h b/include/core/tileset.h index aea9f458..ce735e35 100644 --- a/include/core/tileset.h +++ b/include/core/tileset.h @@ -23,6 +23,7 @@ public: QString metatile_attrs_path; QString tilesImagePath; QImage tilesImage; + QList palettePaths; QList *tiles = nullptr; QList *metatiles = nullptr; diff --git a/include/project.h b/include/project.h index 21acd40a..fa4ee2ed 100644 --- a/include/project.h +++ b/include/project.h @@ -109,6 +109,7 @@ public: void loadEventPixmaps(QList objects); QMap getEventObjGfxConstants(); + QString fixPalettePath(QString path); QString fixGraphicPath(QString path); void readMapEvents(Map *map); @@ -136,6 +137,7 @@ private: void saveTilesetMetatileAttributes(Tileset*); void saveTilesetMetatiles(Tileset*); void saveTilesetTilesImage(Tileset*); + void saveTilesetPalettes(Tileset*, bool); void updateMapsWithConnections(Map*); void saveMapsWithConnections(); void saveMapLayoutsTable(); diff --git a/include/ui/paletteeditor.h b/include/ui/paletteeditor.h new file mode 100644 index 00000000..d8866f24 --- /dev/null +++ b/include/ui/paletteeditor.h @@ -0,0 +1,43 @@ +#ifndef PALETTEEDITOR_H +#define PALETTEEDITOR_H + +#include +#include +#include +#include "project.h" + +namespace Ui { +class PaletteEditor; +} + +class PaletteEditor : public QMainWindow { + Q_OBJECT +public: + explicit PaletteEditor(Project*, Tileset*, Tileset*, QWidget *parent = nullptr); + ~PaletteEditor(); + void setPaletteId(int); + +private: + Ui::PaletteEditor *ui; + Project *project = nullptr; + QList> sliders; + QList frames; + Tileset *primaryTileset; + Tileset *secondaryTileset; + void disableSliderSignals(); + void enableSliderSignals(); + void initColorSliders(); + void refreshColorSliders(); + void refreshColors(); + void refreshColor(int); + void setColor(int); + +signals: + void closed(); + void changedPaletteColor(); + void changedPalette(int); +private slots: + void on_spinBox_PaletteId_valueChanged(int arg1); +}; + +#endif // PALETTEEDITOR_H diff --git a/include/ui/tileseteditor.h b/include/ui/tileseteditor.h index 53755153..f2d1f54e 100644 --- a/include/ui/tileseteditor.h +++ b/include/ui/tileseteditor.h @@ -3,6 +3,7 @@ #include #include "project.h" +#include "paletteeditor.h" #include "tileseteditormetatileselector.h" #include "tileseteditortileselector.h" #include "metatilelayersitem.h" @@ -29,6 +30,9 @@ private slots: void onHoveredTileCleared(); void onSelectedTilesChanged(); void onMetatileLayerTileChanged(int, int); + void onPaletteEditorClosed(); + void onPaletteEditorChangedPaletteColor(); + void onPaletteEditorChangedPalette(int); void on_spinBox_paletteSelector_valueChanged(int arg1); @@ -48,6 +52,8 @@ private slots: void on_actionChange_Metatiles_Count_triggered(); + void on_actionChange_Palettes_triggered(); + private: void closeEvent(QCloseEvent*); void initMetatileSelector(); @@ -61,6 +67,7 @@ private: TilesetEditorMetatileSelector *metatileSelector = nullptr; TilesetEditorTileSelector *tileSelector = nullptr; MetatileLayersItem *metatileLayersItem = nullptr; + PaletteEditor *paletteEditor = nullptr; Project *project = nullptr; Metatile *metatile = nullptr; int paletteId; diff --git a/porymap.pro b/porymap.pro index b0ef9c13..70767deb 100644 --- a/porymap.pro +++ b/porymap.pro @@ -40,6 +40,7 @@ SOURCES += src/core/block.cpp \ src/ui/neweventtoolbutton.cpp \ src/ui/noscrollcombobox.cpp \ src/ui/noscrollspinbox.cpp \ + src/ui/paletteeditor.cpp \ src/ui/selectablepixmapitem.cpp \ src/ui/tileseteditor.cpp \ src/ui/tileseteditormetatileselector.cpp \ @@ -78,6 +79,7 @@ HEADERS += include/core/block.h \ include/ui/neweventtoolbutton.h \ include/ui/noscrollcombobox.h \ include/ui/noscrollspinbox.h \ + include/ui/paletteeditor.h \ include/ui/selectablepixmapitem.h \ include/ui/tileseteditor.h \ include/ui/tileseteditormetatileselector.h \ @@ -89,7 +91,8 @@ HEADERS += include/core/block.h \ FORMS += forms/mainwindow.ui \ forms/eventpropertiesframe.ui \ - forms/tileseteditor.ui + forms/tileseteditor.ui \ + forms/paletteeditor.ui RESOURCES += \ resources/images.qrc diff --git a/src/core/tileset.cpp b/src/core/tileset.cpp index f62135ad..d3acbf2b 100644 --- a/src/core/tileset.cpp +++ b/src/core/tileset.cpp @@ -26,6 +26,9 @@ Tileset* Tileset::copy() { copy->metatile_attrs_path = this->metatile_attrs_path; copy->tilesImage = this->tilesImage.copy(); copy->tilesImagePath = this->tilesImagePath; + for (int i = 0; i < this->palettePaths.length(); i++) { + copy->palettePaths.append(this->palettePaths.at(i)); + } copy->tiles = new QList; for (QImage tile : *this->tiles) { copy->tiles->append(tile.copy()); diff --git a/src/project.cpp b/src/project.cpp index 714868fa..f1168123 100644 --- a/src/project.cpp +++ b/src/project.cpp @@ -583,6 +583,8 @@ void Project::saveTilesets(Tileset *primaryTileset, Tileset *secondaryTileset) { saveTilesetMetatiles(secondaryTileset); saveTilesetTilesImage(primaryTileset); saveTilesetTilesImage(secondaryTileset); + saveTilesetPalettes(primaryTileset, true); + saveTilesetPalettes(secondaryTileset, false); } void Project::saveTilesetMetatileAttributes(Tileset *tileset) { @@ -622,10 +624,29 @@ void Project::saveTilesetMetatiles(Tileset *tileset) { } void Project::saveTilesetTilesImage(Tileset *tileset) { - qDebug() << QString("saving tiles png to '%1'").arg(tileset->tilesImagePath); tileset->tilesImage.save(tileset->tilesImagePath); } +void Project::saveTilesetPalettes(Tileset *tileset, bool primary) { + int startPaletteId = primary ? 0 : Project::getNumPalettesPrimary(); + int endPaletteId = primary ? Project::getNumPalettesPrimary() : Project::getNumPalettesTotal(); + for (int i = startPaletteId; i < endPaletteId; i++) { + QString filepath = tileset->palettePaths.at(i); + QString content = "JASC-PAL\r\n"; + content += "0100\r\n"; + content += "16\r\n"; + for (int j = 0; j < 16; j++) { + QRgb color = tileset->palettes->at(i).at(j); + content += QString("%1 %2 %3\r\n") + .arg(qRed(color)) + .arg(qGreen(color)) + .arg(qBlue(color)); + } + + saveTextFile(filepath, content); + } +} + void Project::loadMapTilesets(Map* map) { if (map->layout->has_unsaved_changes) { return; @@ -820,16 +841,15 @@ void Project::loadTilesetAssets(Tileset* tileset) { } } - QStringList *palette_paths = new QStringList; if (!palettes_values->isEmpty()) { for (int i = 0; i < palettes_values->length(); i++) { QString value = palettes_values->value(i); - palette_paths->append(root + "/" + value.section('"', 1, 1)); + tileset->palettePaths.append(this->fixPalettePath(root + "/" + value.section('"', 1, 1))); } } else { QString palettes_dir_path = dir_path + "/palettes"; for (int i = 0; i < 16; i++) { - palette_paths->append(palettes_dir_path + "/" + QString("%1").arg(i, 2, 10, QLatin1Char('0')) + ".gbapal"); + tileset->palettePaths.append(palettes_dir_path + "/" + QString("%1").arg(i, 2, 10, QLatin1Char('0')) + ".pal"); } } @@ -856,24 +876,31 @@ void Project::loadTilesetAssets(Tileset* tileset) { // palettes QList> *palettes = new QList>; - for (int i = 0; i < palette_paths->length(); i++) { - QString path = palette_paths->value(i); - // the palettes are not compressed. this should never happen. it's only a precaution. - path = path.replace(QRegExp("\\.lz$"), ""); - // TODO default to .pal (JASC-PAL) - // just use .gbapal for now - QFile file(path); + for (int i = 0; i < tileset->palettePaths.length(); i++) { QList palette; - if (file.open(QIODevice::ReadOnly)) { - QByteArray data = file.readAll(); - for (int j = 0; j < 16; j++) { - uint16_t word = data[j*2] & 0xff; - word += (data[j*2 + 1] & 0xff) << 8; - int red = word & 0x1f; - int green = (word >> 5) & 0x1f; - int blue = (word >> 10) & 0x1f; - QRgb color = qRgb(red * 8, green * 8, blue * 8); - palette.append(color); + QString path = tileset->palettePaths.value(i); + QString text = readTextFile(path); + if (!text.isNull()) { + QStringList lines = text.split(QRegExp("[\r\n]"),QString::SkipEmptyParts); + if (lines.length() == 19 && lines[0] == "JASC-PAL" && lines[1] == "0100" && lines[2] == "16") { + for (int j = 0; j < 16; j++) { + QStringList rgb = lines[j + 3].split(QRegExp(" "), QString::SkipEmptyParts); + if (rgb.length() != 3) { + qDebug() << QString("Invalid tileset palette RGB value: '%1'").arg(lines[j + 3]); + palette.append(qRgb((j - 3) * 16, (j - 3) * 16, (j - 3) * 16)); + } else { + int red = rgb[0].toInt(); + int green = rgb[1].toInt(); + int blue = rgb[2].toInt(); + QRgb color = qRgb(red, green, blue); + palette.append(color); + } + } + } else { + qDebug() << QString("Invalid JASC-PAL palette file for tileset."); + for (int j = 0; j < 16; j++) { + palette.append(qRgb(j * 16, j * 16, j * 16)); + } } } else { for (int j = 0; j < 16; j++) { @@ -1405,6 +1432,11 @@ QMap Project::getEventObjGfxConstants() { return constants; } +QString Project::fixPalettePath(QString path) { + path = path.replace(QRegExp("\\.gbapal$"), ".pal"); + return path; +} + QString Project::fixGraphicPath(QString path) { path = path.replace(QRegExp("\\.lz$"), ""); path = path.replace(QRegExp("\\.[1248]bpp$"), ".png"); diff --git a/src/ui/paletteeditor.cpp b/src/ui/paletteeditor.cpp new file mode 100644 index 00000000..bd67fa5f --- /dev/null +++ b/src/ui/paletteeditor.cpp @@ -0,0 +1,176 @@ +#include "paletteeditor.h" +#include "ui_paletteeditor.h" + +PaletteEditor::PaletteEditor(Project *project, Tileset *primaryTileset, Tileset *secondaryTileset, QWidget *parent) : + QMainWindow(parent), + ui(new Ui::PaletteEditor) +{ + this->project = project; + this->primaryTileset = primaryTileset; + this->secondaryTileset = secondaryTileset; + this->ui->setupUi(this); + this->ui->spinBox_PaletteId->setMinimum(0); + this->ui->spinBox_PaletteId->setMaximum(Project::getNumPalettesTotal() - 1); + this->sliders.clear(); + for (int i = 0; i < 16; i++) { + this->sliders.append(QList()); + } + this->sliders[0].append(this->ui->horizontalSlider); + this->sliders[0].append(this->ui->horizontalSlider_2); + this->sliders[0].append(this->ui->horizontalSlider_3); + this->sliders[1].append(this->ui->horizontalSlider_4); + this->sliders[1].append(this->ui->horizontalSlider_5); + this->sliders[1].append(this->ui->horizontalSlider_6); + this->sliders[2].append(this->ui->horizontalSlider_7); + this->sliders[2].append(this->ui->horizontalSlider_8); + this->sliders[2].append(this->ui->horizontalSlider_9); + this->sliders[3].append(this->ui->horizontalSlider_10); + this->sliders[3].append(this->ui->horizontalSlider_11); + this->sliders[3].append(this->ui->horizontalSlider_12); + this->sliders[4].append(this->ui->horizontalSlider_13); + this->sliders[4].append(this->ui->horizontalSlider_14); + this->sliders[4].append(this->ui->horizontalSlider_15); + this->sliders[5].append(this->ui->horizontalSlider_16); + this->sliders[5].append(this->ui->horizontalSlider_17); + this->sliders[5].append(this->ui->horizontalSlider_18); + this->sliders[6].append(this->ui->horizontalSlider_19); + this->sliders[6].append(this->ui->horizontalSlider_20); + this->sliders[6].append(this->ui->horizontalSlider_21); + this->sliders[7].append(this->ui->horizontalSlider_22); + this->sliders[7].append(this->ui->horizontalSlider_23); + this->sliders[7].append(this->ui->horizontalSlider_24); + this->sliders[8].append(this->ui->horizontalSlider_25); + this->sliders[8].append(this->ui->horizontalSlider_26); + this->sliders[8].append(this->ui->horizontalSlider_27); + this->sliders[9].append(this->ui->horizontalSlider_28); + this->sliders[9].append(this->ui->horizontalSlider_29); + this->sliders[9].append(this->ui->horizontalSlider_30); + this->sliders[10].append(this->ui->horizontalSlider_31); + this->sliders[10].append(this->ui->horizontalSlider_32); + this->sliders[10].append(this->ui->horizontalSlider_33); + this->sliders[11].append(this->ui->horizontalSlider_34); + this->sliders[11].append(this->ui->horizontalSlider_35); + this->sliders[11].append(this->ui->horizontalSlider_36); + this->sliders[12].append(this->ui->horizontalSlider_37); + this->sliders[12].append(this->ui->horizontalSlider_38); + this->sliders[12].append(this->ui->horizontalSlider_39); + this->sliders[13].append(this->ui->horizontalSlider_40); + this->sliders[13].append(this->ui->horizontalSlider_41); + this->sliders[13].append(this->ui->horizontalSlider_42); + this->sliders[14].append(this->ui->horizontalSlider_43); + this->sliders[14].append(this->ui->horizontalSlider_44); + this->sliders[14].append(this->ui->horizontalSlider_45); + this->sliders[15].append(this->ui->horizontalSlider_46); + this->sliders[15].append(this->ui->horizontalSlider_47); + this->sliders[15].append(this->ui->horizontalSlider_48); + + this->frames.clear(); + this->frames.append(this->ui->frame); + this->frames.append(this->ui->frame_2); + this->frames.append(this->ui->frame_3); + this->frames.append(this->ui->frame_4); + this->frames.append(this->ui->frame_5); + this->frames.append(this->ui->frame_6); + this->frames.append(this->ui->frame_7); + this->frames.append(this->ui->frame_8); + this->frames.append(this->ui->frame_9); + this->frames.append(this->ui->frame_10); + this->frames.append(this->ui->frame_11); + this->frames.append(this->ui->frame_12); + this->frames.append(this->ui->frame_13); + this->frames.append(this->ui->frame_14); + this->frames.append(this->ui->frame_15); + this->frames.append(this->ui->frame_16); + + this->initColorSliders(); + this->refreshColorSliders(); + this->refreshColors(); +} + +PaletteEditor::~PaletteEditor() +{ + delete ui; +} + +void PaletteEditor::disableSliderSignals() { + for (int i = 0; i < this->sliders.length(); i++) { + this->sliders.at(i).at(0)->blockSignals(true); + this->sliders.at(i).at(1)->blockSignals(true); + this->sliders.at(i).at(2)->blockSignals(true); + } +} + +void PaletteEditor::enableSliderSignals() { + for (int i = 0; i < this->sliders.length(); i++) { + this->sliders.at(i).at(0)->blockSignals(false); + this->sliders.at(i).at(1)->blockSignals(false); + this->sliders.at(i).at(2)->blockSignals(false); + } +} + +void PaletteEditor::initColorSliders() { + for (int i = 0; i < 16; i++) { + connect(this->sliders[i][0], &QSlider::valueChanged, [=](int) { this->setColor(i); }); + connect(this->sliders[i][1], &QSlider::valueChanged, [=](int) { this->setColor(i); }); + connect(this->sliders[i][2], &QSlider::valueChanged, [=](int) { this->setColor(i); }); + } +} + +void PaletteEditor::refreshColorSliders() { + disableSliderSignals(); + int paletteNum = this->ui->spinBox_PaletteId->value(); + for (int i = 0; i < 16; i++) { + QRgb color; + if (paletteNum < Project::getNumPalettesPrimary()) { + color = this->primaryTileset->palettes->at(paletteNum).at(i); + } else { + color = this->secondaryTileset->palettes->at(paletteNum).at(i); + } + + this->sliders[i][0]->setValue(qRed(color) / 8); + this->sliders[i][1]->setValue(qGreen(color) / 8); + this->sliders[i][2]->setValue(qBlue(color) / 8); + } + enableSliderSignals(); +} + +void PaletteEditor::refreshColors() { + for (int i = 0; i < 16; i++) { + this->refreshColor(i); + } +} + +void PaletteEditor::refreshColor(int colorIndex) { + QString stylesheet = QString("background-color: rgb(%1, %2, %3);") + .arg(this->sliders[colorIndex][0]->value() * 8) + .arg(this->sliders[colorIndex][1]->value() * 8) + .arg(this->sliders[colorIndex][2]->value() * 8); + this->frames[colorIndex]->setStyleSheet(stylesheet); +} + +void PaletteEditor::setPaletteId(int paletteId) { + this->ui->spinBox_PaletteId->blockSignals(true); + this->ui->spinBox_PaletteId->setValue(paletteId); + this->refreshColorSliders(); + this->refreshColors(); + this->ui->spinBox_PaletteId->blockSignals(false); +} + +void PaletteEditor::setColor(int colorIndex) { + int paletteNum = this->ui->spinBox_PaletteId->value(); + int red = this->sliders[colorIndex][0]->value() * 8; + int green = this->sliders[colorIndex][1]->value() * 8; + int blue = this->sliders[colorIndex][2]->value() * 8; + Tileset *tileset = paletteNum < Project::getNumPalettesPrimary() + ? this->primaryTileset + : this->secondaryTileset; + (*tileset->palettes)[paletteNum][colorIndex] = qRgb(red, green, blue); + this->refreshColor(colorIndex); + emit this->changedPaletteColor(); +} + +void PaletteEditor::on_spinBox_PaletteId_valueChanged(int paletteId) { + this->refreshColorSliders(); + this->refreshColors(); + emit this->changedPalette(paletteId); +} diff --git a/src/ui/tileseteditor.cpp b/src/ui/tileseteditor.cpp index b1d388c7..60fe30d4 100644 --- a/src/ui/tileseteditor.cpp +++ b/src/ui/tileseteditor.cpp @@ -215,9 +215,15 @@ void TilesetEditor::onMetatileLayerTileChanged(int x, int y) { void TilesetEditor::on_spinBox_paletteSelector_valueChanged(int paletteId) { + this->ui->spinBox_paletteSelector->blockSignals(true); + this->ui->spinBox_paletteSelector->setValue(paletteId); + this->ui->spinBox_paletteSelector->blockSignals(false); this->paletteId = paletteId; this->tileSelector->setPaletteId(paletteId); this->drawSelectedTiles(); + if (this->paletteEditor) { + this->paletteEditor->setPaletteId(paletteId); + } } void TilesetEditor::on_checkBox_xFlip_stateChanged(int checked) @@ -241,7 +247,6 @@ void TilesetEditor::on_comboBox_metatileBehaviors_currentIndexChanged(const QStr } } - void TilesetEditor::on_comboBox_layerType_currentIndexChanged(int layerType) { if (this->metatile) { @@ -419,3 +424,37 @@ void TilesetEditor::on_actionChange_Metatiles_Count_triggered() this->hasUnsavedChanges = true; } } + +void TilesetEditor::onPaletteEditorClosed() { + if (this->paletteEditor) { + delete this->paletteEditor; + this->paletteEditor = nullptr; + } +} + +void TilesetEditor::on_actionChange_Palettes_triggered() +{ + if (!this->paletteEditor) { + this->paletteEditor = new PaletteEditor(this->project, this->primaryTileset, this->secondaryTileset, this); + connect(this->paletteEditor, SIGNAL(closed()), this, SLOT(onPaletteEditorClosed())); + connect(this->paletteEditor, SIGNAL(changedPaletteColor()), this, SLOT(onPaletteEditorChangedPaletteColor())); + connect(this->paletteEditor, SIGNAL(changedPalette(int)), this, SLOT(onPaletteEditorChangedPalette(int))); + } + + if (!this->paletteEditor->isVisible()) { + this->paletteEditor->show(); + } else if (this->paletteEditor->isMinimized()) { + this->paletteEditor->showNormal(); + } else { + this->paletteEditor->activateWindow(); + } +} + +void TilesetEditor::onPaletteEditorChangedPaletteColor() { + this->refresh(); + this->hasUnsavedChanges = true; +} + +void TilesetEditor::onPaletteEditorChangedPalette(int paletteId) { + this->on_spinBox_paletteSelector_valueChanged(paletteId); +}