mirror of
https://github.com/huderlem/porymap.git
synced 2026-09-25 09:15:34 -05:00
Merge branch 'master' into event-paste
This commit is contained in:
128
src/config.cpp
128
src/config.cpp
@@ -79,6 +79,14 @@ void KeyValueConfigBase::save() {
|
||||
}
|
||||
}
|
||||
|
||||
void KeyValueConfigBase::setConfigBool(QString key, bool * field, QString value) {
|
||||
bool ok;
|
||||
*field = value.toInt(&ok);
|
||||
if (!ok) {
|
||||
logWarn(QString("Invalid config value for %1: '%2'. Must be 0 or 1.").arg(key).arg(value));
|
||||
}
|
||||
}
|
||||
|
||||
const QMap<MapSortOrder, QString> mapSortOrderMap = {
|
||||
{MapSortOrder::Group, "group"},
|
||||
{MapSortOrder::Layout, "layout"},
|
||||
@@ -108,12 +116,10 @@ QString PorymapConfig::getConfigFilepath() {
|
||||
void PorymapConfig::parseConfigKeyValue(QString key, QString value) {
|
||||
if (key == "recent_project") {
|
||||
this->recentProject = value;
|
||||
} else if (key == "reopen_on_launch") {
|
||||
setConfigBool(key, &this->reopenOnLaunch, value);
|
||||
} else if (key == "pretty_cursors") {
|
||||
bool ok;
|
||||
this->prettyCursors = value.toInt(&ok);
|
||||
if (!ok) {
|
||||
logWarn(QString("Invalid config value for pretty_cursors: '%1'. Must be 0 or 1.").arg(value));
|
||||
}
|
||||
setConfigBool(key, &this->prettyCursors, value);
|
||||
} else if (key == "map_sort_order") {
|
||||
QString sortOrder = value.toLower();
|
||||
if (mapSortOrderReverseMap.contains(sortOrder)) {
|
||||
@@ -157,35 +163,15 @@ void PorymapConfig::parseConfigKeyValue(QString key, QString value) {
|
||||
this->metatilesZoom = 30;
|
||||
}
|
||||
} else if (key == "show_player_view") {
|
||||
bool ok;
|
||||
this->showPlayerView = value.toInt(&ok);
|
||||
if (!ok) {
|
||||
logWarn(QString("Invalid config value for show_player_view: '%1'. Must be 0 or 1.").arg(value));
|
||||
}
|
||||
setConfigBool(key, &this->showPlayerView, value);
|
||||
} else if (key == "show_cursor_tile") {
|
||||
bool ok;
|
||||
this->showCursorTile = value.toInt(&ok);
|
||||
if (!ok) {
|
||||
logWarn(QString("Invalid config value for show_cursor_tile: '%1'. Must be 0 or 1.").arg(value));
|
||||
}
|
||||
setConfigBool(key, &this->showCursorTile, value);
|
||||
} else if (key == "show_border") {
|
||||
bool ok;
|
||||
this->showBorder = value.toInt(&ok);
|
||||
if (!ok) {
|
||||
logWarn(QString("Invalid config value for show_border: '%1'. Must be 0 or 1.").arg(value));
|
||||
}
|
||||
setConfigBool(key, &this->showBorder, value);
|
||||
} else if (key == "show_grid") {
|
||||
bool ok;
|
||||
this->showGrid = value.toInt(&ok);
|
||||
if (!ok) {
|
||||
logWarn(QString("Invalid config value for show_grid: '%1'. Must be 0 or 1.").arg(value));
|
||||
}
|
||||
setConfigBool(key, &this->showGrid, value);
|
||||
} else if (key == "monitor_files") {
|
||||
bool ok;
|
||||
this->monitorFiles = value.toInt(&ok);
|
||||
if (!ok) {
|
||||
logWarn(QString("Invalid config value for monitor_files: '%1'. Must be 0 or 1.").arg(value));
|
||||
}
|
||||
setConfigBool(key, &this->monitorFiles, value);
|
||||
} else if (key == "region_map_dimensions") {
|
||||
bool ok1, ok2;
|
||||
QStringList dims = value.split("x");
|
||||
@@ -211,6 +197,7 @@ void PorymapConfig::parseConfigKeyValue(QString key, QString value) {
|
||||
QMap<QString, QString> PorymapConfig::getKeyValueMap() {
|
||||
QMap<QString, QString> map;
|
||||
map.insert("recent_project", this->recentProject);
|
||||
map.insert("reopen_on_launch", this->reopenOnLaunch ? "1" : "0");
|
||||
map.insert("pretty_cursors", this->prettyCursors ? "1" : "0");
|
||||
map.insert("map_sort_order", mapSortOrderMap.value(this->mapSortOrder));
|
||||
map.insert("main_window_geometry", stringFromByteArray(this->mainWindowGeometry));
|
||||
@@ -260,6 +247,11 @@ void PorymapConfig::setRecentProject(QString project) {
|
||||
this->save();
|
||||
}
|
||||
|
||||
void PorymapConfig::setReopenOnLaunch(bool enabled) {
|
||||
this->reopenOnLaunch = enabled;
|
||||
this->save();
|
||||
}
|
||||
|
||||
void PorymapConfig::setMapSortOrder(MapSortOrder order) {
|
||||
this->mapSortOrder = order;
|
||||
this->save();
|
||||
@@ -354,6 +346,10 @@ QString PorymapConfig::getRecentProject() {
|
||||
return this->recentProject;
|
||||
}
|
||||
|
||||
bool PorymapConfig::getReopenOnLaunch() {
|
||||
return this->reopenOnLaunch;
|
||||
}
|
||||
|
||||
MapSortOrder PorymapConfig::getMapSortOrder() {
|
||||
return this->mapSortOrder;
|
||||
}
|
||||
@@ -475,77 +471,29 @@ void ProjectConfig::parseConfigKeyValue(QString key, QString value) {
|
||||
} else if (key == "recent_map") {
|
||||
this->recentMap = value;
|
||||
} else if (key == "use_encounter_json") {
|
||||
bool ok;
|
||||
this->useEncounterJson = value.toInt(&ok);
|
||||
if (!ok) {
|
||||
logWarn(QString("Invalid config value for use_encounter_json: '%1'. Must be 0 or 1.").arg(value));
|
||||
}
|
||||
setConfigBool(key, &this->useEncounterJson, value);
|
||||
} else if (key == "use_poryscript") {
|
||||
bool ok;
|
||||
this->usePoryScript = value.toInt(&ok);
|
||||
if (!ok) {
|
||||
logWarn(QString("Invalid config value for use_poryscript: '%1'. Must be 0 or 1.").arg(value));
|
||||
}
|
||||
setConfigBool(key, &this->usePoryScript, value);
|
||||
} else if (key == "use_custom_border_size") {
|
||||
bool ok;
|
||||
this->useCustomBorderSize = value.toInt(&ok);
|
||||
if (!ok) {
|
||||
logWarn(QString("Invalid config value for use_custom_border_size: '%1'. Must be 0 or 1.").arg(value));
|
||||
}
|
||||
setConfigBool(key, &this->useCustomBorderSize, value);
|
||||
} else if (key == "enable_event_weather_trigger") {
|
||||
bool ok;
|
||||
this->enableEventWeatherTrigger = value.toInt(&ok);
|
||||
if (!ok) {
|
||||
logWarn(QString("Invalid config value for enable_event_weather_trigger: '%1'. Must be 0 or 1.").arg(value));
|
||||
}
|
||||
setConfigBool(key, &this->enableEventWeatherTrigger, value);
|
||||
} else if (key == "enable_event_secret_base") {
|
||||
bool ok;
|
||||
this->enableEventSecretBase = value.toInt(&ok);
|
||||
if (!ok) {
|
||||
logWarn(QString("Invalid config value for enable_event_secret_base: '%1'. Must be 0 or 1.").arg(value));
|
||||
}
|
||||
setConfigBool(key, &this->enableEventSecretBase, value);
|
||||
} else if (key == "enable_hidden_item_quantity") {
|
||||
bool ok;
|
||||
this->enableHiddenItemQuantity = value.toInt(&ok);
|
||||
if (!ok) {
|
||||
logWarn(QString("Invalid config value for enable_hidden_item_quantity: '%1'. Must be 0 or 1.").arg(value));
|
||||
}
|
||||
setConfigBool(key, &this->enableHiddenItemQuantity, value);
|
||||
} else if (key == "enable_hidden_item_requires_itemfinder") {
|
||||
bool ok;
|
||||
this->enableHiddenItemRequiresItemfinder = value.toInt(&ok);
|
||||
if (!ok) {
|
||||
logWarn(QString("Invalid config value for enable_hidden_item_requires_itemfinder: '%1'. Must be 0 or 1.").arg(value));
|
||||
}
|
||||
setConfigBool(key, &this->enableHiddenItemRequiresItemfinder, value);
|
||||
} else if (key == "enable_heal_location_respawn_data") {
|
||||
bool ok;
|
||||
this->enableHealLocationRespawnData = value.toInt(&ok);
|
||||
if (!ok) {
|
||||
logWarn(QString("Invalid config value for enable_heal_location_respawn_data: '%1'. Must be 0 or 1.").arg(value));
|
||||
}
|
||||
setConfigBool(key, &this->enableHealLocationRespawnData, value);
|
||||
} else if (key == "enable_event_clone_object") {
|
||||
bool ok;
|
||||
this->enableEventCloneObject = value.toInt(&ok);
|
||||
if (!ok) {
|
||||
logWarn(QString("Invalid config value for enable_event_clone_object: '%1'. Must be 0 or 1.").arg(value));
|
||||
}
|
||||
setConfigBool(key, &this->enableEventCloneObject, value);
|
||||
} else if (key == "enable_floor_number") {
|
||||
bool ok;
|
||||
this->enableFloorNumber = value.toInt(&ok);
|
||||
if (!ok) {
|
||||
logWarn(QString("Invalid config value for enable_floor_number: '%1'. Must be 0 or 1.").arg(value));
|
||||
}
|
||||
setConfigBool(key, &this->enableFloorNumber, value);
|
||||
} else if (key == "create_map_text_file") {
|
||||
bool ok;
|
||||
this->createMapTextFile = value.toInt(&ok);
|
||||
if (!ok) {
|
||||
logWarn(QString("Invalid config value for create_map_text_file: '%1'. Must be 0 or 1.").arg(value));
|
||||
}
|
||||
setConfigBool(key, &this->createMapTextFile, value);
|
||||
} else if (key == "enable_triple_layer_metatiles") {
|
||||
bool ok;
|
||||
this->enableTripleLayerMetatiles = value.toInt(&ok);
|
||||
if (!ok) {
|
||||
logWarn(QString("Invalid config value for enable_triple_layer_metatiles: '%1'. Must be 0 or 1.").arg(value));
|
||||
}
|
||||
setConfigBool(key, &this->enableTripleLayerMetatiles, value);
|
||||
} else if (key == "custom_scripts") {
|
||||
this->customScripts.clear();
|
||||
QList<QString> paths = value.split(",");
|
||||
|
||||
@@ -461,6 +461,7 @@ void MainWindow::loadUserSettings() {
|
||||
ui->horizontalSlider_MetatileZoom->setValue(porymapConfig.getMetatilesZoom());
|
||||
ui->horizontalSlider_MetatileZoom->blockSignals(false);
|
||||
ui->actionMonitor_Project_Files->setChecked(porymapConfig.getMonitorFiles());
|
||||
ui->actionOpen_Recent_Project_On_Launch->setChecked(porymapConfig.getReopenOnLaunch());
|
||||
setTheme(porymapConfig.getTheme());
|
||||
}
|
||||
|
||||
@@ -485,6 +486,9 @@ void MainWindow::setTheme(QString theme) {
|
||||
}
|
||||
|
||||
bool MainWindow::openRecentProject() {
|
||||
if (!porymapConfig.getReopenOnLaunch())
|
||||
return false;
|
||||
|
||||
QString default_dir = porymapConfig.getRecentProject();
|
||||
if (!default_dir.isNull() && default_dir.length() > 0) {
|
||||
logInfo(QString("Opening recent project: '%1'").arg(default_dir));
|
||||
@@ -1774,6 +1778,11 @@ void MainWindow::on_actionUse_Poryscript_triggered(bool checked)
|
||||
projectConfig.setUsePoryScript(checked);
|
||||
}
|
||||
|
||||
void MainWindow::on_actionOpen_Recent_Project_On_Launch_triggered(bool checked)
|
||||
{
|
||||
porymapConfig.setReopenOnLaunch(checked);
|
||||
}
|
||||
|
||||
void MainWindow::on_actionEdit_Shortcuts_triggered()
|
||||
{
|
||||
if (!shortcutsEditor)
|
||||
|
||||
81
src/ui/colorpicker.cpp
Normal file
81
src/ui/colorpicker.cpp
Normal file
@@ -0,0 +1,81 @@
|
||||
#include "colorpicker.h"
|
||||
#include "ui_colorpicker.h"
|
||||
|
||||
#include <QtWidgets>
|
||||
|
||||
const int zoom_box_dimensions = 15;
|
||||
|
||||
ColorPicker::ColorPicker(QWidget *parent) :
|
||||
QDialog(parent),
|
||||
ui(new Ui::ColorPicker)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
this->scene = new QGraphicsScene;
|
||||
|
||||
// listen for spacebar press to take color
|
||||
QShortcut *takeColor = new QShortcut(Qt::Key_Space, this);
|
||||
QObject::connect(takeColor, &QShortcut::activated, [this](){
|
||||
timer->stop();
|
||||
this->accept();
|
||||
});
|
||||
|
||||
// need to set up a timer because there is no good way to get global mouse movement
|
||||
// outside of the application in a cross-platform way
|
||||
timer = new QTimer(this);
|
||||
connect(timer, &QTimer::timeout, [this]() {
|
||||
QPoint cursorPos = QCursor::pos();
|
||||
if (lastCursorPos != cursorPos) {
|
||||
lastCursorPos = cursorPos;
|
||||
this->hover(cursorPos.x(), cursorPos.y());
|
||||
}
|
||||
});
|
||||
timer->start(10);
|
||||
}
|
||||
|
||||
ColorPicker::~ColorPicker()
|
||||
{
|
||||
delete scene;
|
||||
delete timer;
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void ColorPicker::hover(int mouseX, int mouseY) {
|
||||
QScreen *screen = QGuiApplication::primaryScreen();
|
||||
if (const QWindow *window = windowHandle())
|
||||
screen = window->screen();
|
||||
if (!screen)
|
||||
return;
|
||||
|
||||
// 15 X 15 box with 8x magnification = 120px square)
|
||||
QRect zoomRect(mouseX - zoom_box_dimensions / 2, mouseY - zoom_box_dimensions / 2, zoom_box_dimensions, zoom_box_dimensions);
|
||||
QPixmap grab = screen->grabWindow(0, mouseX - zoom_box_dimensions / 2, mouseY - zoom_box_dimensions / 2, zoom_box_dimensions, zoom_box_dimensions);
|
||||
int pixelRatio = grab.devicePixelRatio();
|
||||
|
||||
// TODO: investigate for high dpi displays why text is too high res
|
||||
grab.setDevicePixelRatio(1);
|
||||
QPixmap magnified = grab.scaled(zoom_box_dimensions * 8, zoom_box_dimensions * 8, Qt::KeepAspectRatio);
|
||||
|
||||
QPainter painter(&magnified);
|
||||
painter.setRenderHint(QPainter::Antialiasing, false);
|
||||
QRectF rect(zoom_box_dimensions / 2 * 8 - 1, zoom_box_dimensions / 2 * 8 - 1, zoom_box_dimensions / 2 + 2, zoom_box_dimensions / 2 + 2);
|
||||
painter.drawRect(rect);
|
||||
painter.end();
|
||||
|
||||
// TODO: bounds checking?
|
||||
|
||||
this->color = grab.toImage().pixelColor(zoom_box_dimensions / 2 * pixelRatio, zoom_box_dimensions / 2 * pixelRatio);
|
||||
int r = this->color.red();
|
||||
int g = this->color.green();
|
||||
int b = this->color.blue();
|
||||
|
||||
// update the displayed color value
|
||||
QString rgb = QString("rgb(%1, %2, %3)").arg(r).arg(g).arg(b);
|
||||
QString stylesheet = QString("background-color: %1;").arg(rgb);
|
||||
this->ui->frame_centralColor->setStyleSheet(stylesheet);
|
||||
|
||||
this->ui->label_RGB->setText(rgb);
|
||||
this->ui->label_HEX->setText(color.name());
|
||||
|
||||
this->ui->viewport->setPixmap(magnified);
|
||||
}
|
||||
@@ -1,11 +1,20 @@
|
||||
#include "paletteeditor.h"
|
||||
#include "ui_paletteeditor.h"
|
||||
#include "colorpicker.h"
|
||||
#include "paletteutil.h"
|
||||
#include "config.h"
|
||||
#include "log.h"
|
||||
|
||||
#include <cmath>
|
||||
#include <QFileDialog>
|
||||
#include <QMessageBox>
|
||||
|
||||
static inline int rgb5(int rgb) { return round(static_cast<double>(rgb * 31) / 255.0); }
|
||||
static inline int rgb8(int rgb) { return round(rgb * 255. / 31.); }
|
||||
static inline int gbaRed(int rgb) { return rgb & 0x1f; }
|
||||
static inline int gbaGreen(int rgb) { return (rgb >> 5) & 0x1f; }
|
||||
static inline int gbaBlue(int rgb) { return (rgb >> 10) & 0x1f; }
|
||||
|
||||
PaletteEditor::PaletteEditor(Project *project, Tileset *primaryTileset, Tileset *secondaryTileset, int paletteId, QWidget *parent) :
|
||||
QMainWindow(parent),
|
||||
ui(new Ui::PaletteEditor)
|
||||
@@ -16,101 +25,74 @@ PaletteEditor::PaletteEditor(Project *project, Tileset *primaryTileset, Tileset
|
||||
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<QSlider*>());
|
||||
QList<QSlider *> rgbSliders;
|
||||
rgbSliders.append(this->ui->container->findChild<QSlider *>("slider_red_" + QString::number(i)));
|
||||
rgbSliders.append(this->ui->container->findChild<QSlider *>("slider_green_" + QString::number(i)));
|
||||
rgbSliders.append(this->ui->container->findChild<QSlider *>("slider_blue_" + QString::number(i)));
|
||||
this->sliders.append(rgbSliders);
|
||||
|
||||
connect(this->sliders[i][0], &QSlider::valueChanged, [=](int) { setRgbFromSliders(i); });
|
||||
connect(this->sliders[i][1], &QSlider::valueChanged, [=](int) { setRgbFromSliders(i); });
|
||||
connect(this->sliders[i][2], &QSlider::valueChanged, [=](int) { setRgbFromSliders(i); });
|
||||
}
|
||||
|
||||
this->spinners.clear();
|
||||
for (int i = 0; i < 16; i++) {
|
||||
QList<QSpinBox *> rgbSpinners;
|
||||
rgbSpinners.append(this->ui->container->findChild<QSpinBox *>("spin_red_" + QString::number(i)));
|
||||
rgbSpinners.append(this->ui->container->findChild<QSpinBox *>("spin_green_" + QString::number(i)));
|
||||
rgbSpinners.append(this->ui->container->findChild<QSpinBox *>("spin_blue_" + QString::number(i)));
|
||||
this->spinners.append(rgbSpinners);
|
||||
|
||||
connect(this->spinners[i][0], QOverload<int>::of(&QSpinBox::valueChanged), [=](int) { setRgbFromSpinners(i); });
|
||||
connect(this->spinners[i][1], QOverload<int>::of(&QSpinBox::valueChanged), [=](int) { setRgbFromSpinners(i); });
|
||||
connect(this->spinners[i][2], QOverload<int>::of(&QSpinBox::valueChanged), [=](int) { setRgbFromSpinners(i); });
|
||||
}
|
||||
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);
|
||||
for (int i = 0; i < 16; i++) {
|
||||
this->frames.append(this->ui->container->findChild<QFrame *>("colorFrame_" + QString::number(i)));
|
||||
this->frames[i]->setFrameStyle(QFrame::NoFrame);
|
||||
}
|
||||
|
||||
this->rgbLabels.clear();
|
||||
this->rgbLabels.append(this->ui->label_rgb0);
|
||||
this->rgbLabels.append(this->ui->label_rgb1);
|
||||
this->rgbLabels.append(this->ui->label_rgb2);
|
||||
this->rgbLabels.append(this->ui->label_rgb3);
|
||||
this->rgbLabels.append(this->ui->label_rgb4);
|
||||
this->rgbLabels.append(this->ui->label_rgb5);
|
||||
this->rgbLabels.append(this->ui->label_rgb6);
|
||||
this->rgbLabels.append(this->ui->label_rgb7);
|
||||
this->rgbLabels.append(this->ui->label_rgb8);
|
||||
this->rgbLabels.append(this->ui->label_rgb9);
|
||||
this->rgbLabels.append(this->ui->label_rgb10);
|
||||
this->rgbLabels.append(this->ui->label_rgb11);
|
||||
this->rgbLabels.append(this->ui->label_rgb12);
|
||||
this->rgbLabels.append(this->ui->label_rgb13);
|
||||
this->rgbLabels.append(this->ui->label_rgb14);
|
||||
this->rgbLabels.append(this->ui->label_rgb15);
|
||||
this->pickButtons.clear();
|
||||
for (int i = 0; i < 16; i++) {
|
||||
this->pickButtons.append(this->ui->container->findChild<QToolButton *>("pick_" + QString::number(i)));
|
||||
}
|
||||
|
||||
this->hexValidator = new HexCodeValidator;
|
||||
this->hexEdits.clear();
|
||||
for (int i = 0; i < 16; i++) {
|
||||
this->hexEdits.append(this->ui->container->findChild<QLineEdit *>("hex_" + QString::number(i)));
|
||||
this->hexEdits[i]->setValidator(hexValidator);
|
||||
}
|
||||
|
||||
// Connect to function that will update color when hex edit is changed
|
||||
for (int i = 0; i < this->hexEdits.length(); i++) {
|
||||
connect(this->hexEdits[i], &QLineEdit::textEdited, [this, i](QString text){
|
||||
if ((this->bitDepth == 24 && text.length() == 6) || (this->bitDepth == 15 && text.length() == 4)) setRgbFromHexEdit(i);
|
||||
});
|
||||
}
|
||||
|
||||
// Setup edit-undo history for each of the palettes.
|
||||
for (int i = 0; i < Project::getNumPalettesTotal(); i++) {
|
||||
this->palettesHistory.append(History<PaletteHistoryItem*>());
|
||||
}
|
||||
|
||||
this->initColorSliders();
|
||||
// Connect the color picker's selection to the correct color index
|
||||
for (int i = 0; i < 16; i++) {
|
||||
connect(this->pickButtons[i], &QToolButton::clicked, [this, i](){ this->pickColor(i); });
|
||||
}
|
||||
|
||||
setBitDepth(24);
|
||||
|
||||
// Connect bit depth buttons
|
||||
connect(this->ui->bit_depth_15, &QRadioButton::toggled, [this](bool checked){ if (checked) this->setBitDepth(15); });
|
||||
connect(this->ui->bit_depth_24, &QRadioButton::toggled, [this](bool checked){ if (checked) this->setBitDepth(24); });
|
||||
|
||||
this->setPaletteId(paletteId);
|
||||
this->commitEditHistory(this->ui->spinBox_PaletteId->value());
|
||||
this->restoreWindowState();
|
||||
@@ -119,34 +101,194 @@ PaletteEditor::PaletteEditor(Project *project, Tileset *primaryTileset, Tileset
|
||||
PaletteEditor::~PaletteEditor()
|
||||
{
|
||||
delete ui;
|
||||
delete this->hexValidator;
|
||||
}
|
||||
|
||||
void PaletteEditor::disableSliderSignals() {
|
||||
void PaletteEditor::updateColorUi(int colorIndex, QRgb rgb) {
|
||||
setSignalsEnabled(false);
|
||||
|
||||
int red = qRed(rgb);
|
||||
int green = qGreen(rgb);
|
||||
int blue = qBlue(rgb);
|
||||
|
||||
if (this->bitDepth == 15) {
|
||||
// sliders
|
||||
this->sliders[colorIndex][0]->setValue(rgb5(red));
|
||||
this->sliders[colorIndex][1]->setValue(rgb5(green));
|
||||
this->sliders[colorIndex][2]->setValue(rgb5(blue));
|
||||
|
||||
// hex
|
||||
int hex15 = (rgb5(blue) << 10) | (rgb5(green) << 5) | rgb5(red);
|
||||
QString hexcode = QString("%1").arg(hex15, 4, 16, QLatin1Char('0')).toUpper();
|
||||
this->hexEdits[colorIndex]->setText(hexcode);
|
||||
|
||||
// spinners
|
||||
this->spinners[colorIndex][0]->setValue(rgb5(red));
|
||||
this->spinners[colorIndex][1]->setValue(rgb5(green));
|
||||
this->spinners[colorIndex][2]->setValue(rgb5(blue));
|
||||
} else {
|
||||
// sliders
|
||||
this->sliders[colorIndex][0]->setValue(red);
|
||||
this->sliders[colorIndex][1]->setValue(green);
|
||||
this->sliders[colorIndex][2]->setValue(blue);
|
||||
|
||||
// hex
|
||||
QColor color(red, green, blue);
|
||||
QString hexcode = color.name().remove(0, 1).toUpper();
|
||||
this->hexEdits[colorIndex]->setText(hexcode);
|
||||
|
||||
// spinners
|
||||
this->spinners[colorIndex][0]->setValue(red);
|
||||
this->spinners[colorIndex][1]->setValue(green);
|
||||
this->spinners[colorIndex][2]->setValue(blue);
|
||||
}
|
||||
|
||||
// frame
|
||||
QString stylesheet = QString("background-color: rgb(%1, %2, %3);").arg(red).arg(green).arg(blue);
|
||||
this->frames[colorIndex]->setStyleSheet(stylesheet);
|
||||
|
||||
setSignalsEnabled(true);
|
||||
}
|
||||
|
||||
void PaletteEditor::setSignalsEnabled(bool enabled) {
|
||||
// spinners, sliders, hexbox
|
||||
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);
|
||||
this->sliders.at(i).at(0)->blockSignals(!enabled);
|
||||
this->sliders.at(i).at(1)->blockSignals(!enabled);
|
||||
this->sliders.at(i).at(2)->blockSignals(!enabled);
|
||||
}
|
||||
|
||||
for (int i = 0; i < this->spinners.length(); i++) {
|
||||
this->spinners.at(i).at(0)->blockSignals(!enabled);
|
||||
this->spinners.at(i).at(1)->blockSignals(!enabled);
|
||||
this->spinners.at(i).at(2)->blockSignals(!enabled);
|
||||
}
|
||||
|
||||
for (int i = 0; i < this->hexEdits.length(); i++) {
|
||||
this->hexEdits.at(i)->blockSignals(!enabled);
|
||||
}
|
||||
}
|
||||
|
||||
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::setBitDepth(int bits) {
|
||||
setSignalsEnabled(false);
|
||||
switch (bits) {
|
||||
case 15:
|
||||
for (int i = 0; i < 16; i++) {
|
||||
// sliders ranged [0, 31] with 1 single step and 4 page step
|
||||
this->sliders[i][0]->setSingleStep(1);
|
||||
this->sliders[i][1]->setSingleStep(1);
|
||||
this->sliders[i][2]->setSingleStep(1);
|
||||
this->sliders[i][0]->setPageStep(4);
|
||||
this->sliders[i][1]->setPageStep(4);
|
||||
this->sliders[i][2]->setPageStep(4);
|
||||
this->sliders[i][0]->setMaximum(31);
|
||||
this->sliders[i][1]->setMaximum(31);
|
||||
this->sliders[i][2]->setMaximum(31);
|
||||
|
||||
// spinners limited [0, 31] with 1 step
|
||||
this->spinners[i][0]->setSingleStep(1);
|
||||
this->spinners[i][1]->setSingleStep(1);
|
||||
this->spinners[i][2]->setSingleStep(1);
|
||||
this->spinners[i][0]->setMaximum(31);
|
||||
this->spinners[i][1]->setMaximum(31);
|
||||
this->spinners[i][2]->setMaximum(31);
|
||||
|
||||
// hex box now 4 digits
|
||||
this->hexEdits[i]->setInputMask("HHHH");
|
||||
this->hexEdits[i]->setMaxLength(4);
|
||||
}
|
||||
break;
|
||||
case 24:
|
||||
default:
|
||||
for (int i = 0; i < 16; i++) {
|
||||
// sliders ranged [0, 31] with 1 single step and 4 page step
|
||||
this->sliders[i][0]->setSingleStep(8);
|
||||
this->sliders[i][1]->setSingleStep(8);
|
||||
this->sliders[i][2]->setSingleStep(8);
|
||||
this->sliders[i][0]->setPageStep(24);
|
||||
this->sliders[i][1]->setPageStep(24);
|
||||
this->sliders[i][2]->setPageStep(24);
|
||||
this->sliders[i][0]->setMaximum(255);
|
||||
this->sliders[i][1]->setMaximum(255);
|
||||
this->sliders[i][2]->setMaximum(255);
|
||||
|
||||
// spinners limited [0, 31] with 1 step
|
||||
this->spinners[i][0]->setSingleStep(8);
|
||||
this->spinners[i][1]->setSingleStep(8);
|
||||
this->spinners[i][2]->setSingleStep(8);
|
||||
this->spinners[i][0]->setMaximum(255);
|
||||
this->spinners[i][1]->setMaximum(255);
|
||||
this->spinners[i][2]->setMaximum(255);
|
||||
|
||||
// hex box now 4 digits
|
||||
this->hexEdits[i]->setInputMask("HHHHHH");
|
||||
this->hexEdits[i]->setMaxLength(6);
|
||||
}
|
||||
break;
|
||||
}
|
||||
this->bitDepth = bits;
|
||||
refreshColorUis();
|
||||
setSignalsEnabled(true);
|
||||
}
|
||||
|
||||
void PaletteEditor::setRgb(int colorIndex, QRgb rgb) {
|
||||
int paletteNum = this->ui->spinBox_PaletteId->value();
|
||||
|
||||
Tileset *tileset = paletteNum < Project::getNumPalettesPrimary()
|
||||
? this->primaryTileset
|
||||
: this->secondaryTileset;
|
||||
tileset->palettes[paletteNum][colorIndex] = rgb;
|
||||
tileset->palettePreviews[paletteNum][colorIndex] = rgb;
|
||||
|
||||
this->updateColorUi(colorIndex, rgb);
|
||||
|
||||
this->commitEditHistory(paletteNum);
|
||||
emit this->changedPaletteColor();
|
||||
}
|
||||
|
||||
void PaletteEditor::setRgbFromSliders(int colorIndex) {
|
||||
if (this->bitDepth == 15) {
|
||||
setRgb(colorIndex, qRgb(rgb8(this->sliders[colorIndex][0]->value()),
|
||||
rgb8(this->sliders[colorIndex][1]->value()),
|
||||
rgb8(this->sliders[colorIndex][2]->value())));
|
||||
} else {
|
||||
setRgb(colorIndex, qRgb(this->sliders[colorIndex][0]->value(),
|
||||
this->sliders[colorIndex][1]->value(),
|
||||
this->sliders[colorIndex][2]->value()));
|
||||
}
|
||||
}
|
||||
|
||||
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::setRgbFromHexEdit(int colorIndex) {
|
||||
QString text = this->hexEdits[colorIndex]->text();
|
||||
bool ok = false;
|
||||
if (this->bitDepth == 15) {
|
||||
int rgb15 = text.toInt(&ok, 16);
|
||||
int rc = gbaRed(rgb15);
|
||||
int gc = gbaGreen(rgb15);
|
||||
int bc = gbaBlue(rgb15);
|
||||
QRgb rgb = qRgb(rc, gc, bc);
|
||||
if (!ok) rgb = 0xFFFFFFFF;
|
||||
setRgb(colorIndex, rgb);
|
||||
} else {
|
||||
QRgb rgb = text.toInt(&ok, 16);
|
||||
if (!ok) rgb = 0xFFFFFFFF;
|
||||
setRgb(colorIndex, rgb);
|
||||
}
|
||||
}
|
||||
|
||||
void PaletteEditor::refreshColorSliders() {
|
||||
disableSliderSignals();
|
||||
void PaletteEditor::setRgbFromSpinners(int colorIndex) {
|
||||
if (this->bitDepth == 15) {
|
||||
setRgb(colorIndex, qRgb(rgb8(this->spinners[colorIndex][0]->value()),
|
||||
rgb8(this->spinners[colorIndex][1]->value()),
|
||||
rgb8(this->spinners[colorIndex][2]->value())));
|
||||
} else {
|
||||
setRgb(colorIndex, qRgb(this->spinners[colorIndex][0]->value(),
|
||||
this->spinners[colorIndex][1]->value(),
|
||||
this->spinners[colorIndex][2]->value()));
|
||||
}
|
||||
}
|
||||
|
||||
void PaletteEditor::refreshColorUis() {
|
||||
int paletteNum = this->ui->spinBox_PaletteId->value();
|
||||
for (int i = 0; i < 16; i++) {
|
||||
QRgb color;
|
||||
@@ -156,64 +298,34 @@ void PaletteEditor::refreshColorSliders() {
|
||||
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);
|
||||
this->updateColorUi(i, color);
|
||||
}
|
||||
enableSliderSignals();
|
||||
}
|
||||
|
||||
void PaletteEditor::refreshColors() {
|
||||
for (int i = 0; i < 16; i++) {
|
||||
this->refreshColor(i);
|
||||
}
|
||||
}
|
||||
|
||||
void PaletteEditor::refreshColor(int colorIndex) {
|
||||
int red = this->sliders[colorIndex][0]->value() * 8;
|
||||
int green = this->sliders[colorIndex][1]->value() * 8;
|
||||
int blue = this->sliders[colorIndex][2]->value() * 8;
|
||||
QString stylesheet = QString("background-color: rgb(%1, %2, %3);")
|
||||
.arg(red)
|
||||
.arg(green)
|
||||
.arg(blue);
|
||||
this->frames[colorIndex]->setStyleSheet(stylesheet);
|
||||
this->rgbLabels[colorIndex]->setText(QString("RGB(%1, %2, %3)").arg(red).arg(green).arg(blue));
|
||||
}
|
||||
|
||||
void PaletteEditor::setPaletteId(int paletteId) {
|
||||
this->ui->spinBox_PaletteId->blockSignals(true);
|
||||
this->ui->spinBox_PaletteId->setValue(paletteId);
|
||||
this->refreshColorSliders();
|
||||
this->refreshColors();
|
||||
this->refreshColorUis();
|
||||
this->ui->spinBox_PaletteId->blockSignals(false);
|
||||
}
|
||||
|
||||
void PaletteEditor::setTilesets(Tileset *primaryTileset, Tileset *secondaryTileset) {
|
||||
this->primaryTileset = primaryTileset;
|
||||
this->secondaryTileset = secondaryTileset;
|
||||
this->refreshColorSliders();
|
||||
this->refreshColors();
|
||||
this->refreshColorUis();
|
||||
}
|
||||
|
||||
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);
|
||||
tileset->palettePreviews[paletteNum][colorIndex] = qRgb(red, green, blue);
|
||||
this->refreshColor(colorIndex);
|
||||
this->commitEditHistory(paletteNum);
|
||||
emit this->changedPaletteColor();
|
||||
void PaletteEditor::pickColor(int index) {
|
||||
ColorPicker picker(this);
|
||||
if (picker.exec() == QDialog::Accepted) {
|
||||
QColor c = picker.getColor();
|
||||
this->setRgb(index, c.rgb());
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void PaletteEditor::on_spinBox_PaletteId_valueChanged(int paletteId) {
|
||||
this->refreshColorSliders();
|
||||
this->refreshColors();
|
||||
this->refreshColorUis();
|
||||
if (!this->palettesHistory[paletteId].current()) {
|
||||
this->commitEditHistory(paletteId);
|
||||
}
|
||||
@@ -223,7 +335,7 @@ void PaletteEditor::on_spinBox_PaletteId_valueChanged(int paletteId) {
|
||||
void PaletteEditor::commitEditHistory(int paletteId) {
|
||||
QList<QRgb> colors;
|
||||
for (int i = 0; i < 16; i++) {
|
||||
colors.append(qRgb(this->sliders[i][0]->value() * 8, this->sliders[i][1]->value() * 8, this->sliders[i][2]->value() * 8));
|
||||
colors.append(qRgb(this->spinners[i][0]->value(), this->spinners[i][1]->value(), this->spinners[i][2]->value()));
|
||||
}
|
||||
PaletteHistoryItem *commit = new PaletteHistoryItem(colors);
|
||||
this->palettesHistory[paletteId].push(commit);
|
||||
@@ -263,8 +375,7 @@ void PaletteEditor::setColorsFromHistory(PaletteHistoryItem *history, int palett
|
||||
}
|
||||
}
|
||||
|
||||
this->refreshColorSliders();
|
||||
this->refreshColors();
|
||||
this->refreshColorUis();
|
||||
emit this->changedPaletteColor();
|
||||
}
|
||||
|
||||
@@ -314,8 +425,7 @@ void PaletteEditor::on_actionImport_Palette_triggered()
|
||||
}
|
||||
}
|
||||
|
||||
this->refreshColorSliders();
|
||||
this->refreshColors();
|
||||
this->refreshColorUis();
|
||||
this->commitEditHistory(paletteId);
|
||||
emit this->changedPaletteColor();
|
||||
}
|
||||
|
||||
@@ -556,10 +556,15 @@ void TilesetEditor::on_comboBox_terrainType_activated(int terrainType)
|
||||
|
||||
void TilesetEditor::on_actionSave_Tileset_triggered()
|
||||
{
|
||||
// need this temporary metatile ID to reset selection after saving
|
||||
// when the tilesetsSaved signal is sent, it will be reset to the current map metatile
|
||||
uint16_t reselectMetatileID = this->metatileSelector->getSelectedMetatileId();
|
||||
|
||||
saveMetatileLabel();
|
||||
|
||||
this->project->saveTilesets(this->primaryTileset, this->secondaryTileset);
|
||||
emit this->tilesetsSaved(this->primaryTileset->name, this->secondaryTileset->name);
|
||||
this->metatileSelector->select(reselectMetatileID);
|
||||
if (this->paletteEditor) {
|
||||
this->paletteEditor->setTilesets(this->primaryTileset, this->secondaryTileset);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user