diff --git a/forms/colorinputwidget.ui b/forms/colorinputwidget.ui
new file mode 100644
index 00000000..eebd7955
--- /dev/null
+++ b/forms/colorinputwidget.ui
@@ -0,0 +1,313 @@
+
+
+ ColorInputWidget
+
+
+
+ 0
+ 0
+ 221
+ 212
+
+
+
+ Color
+
+
+ -
+
+
+ QFrame::Shape::NoFrame
+
+
+ QFrame::Shadow::Raised
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
-
+
+
+ QFrame::Shape::NoFrame
+
+
+ QFrame::Shadow::Raised
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
-
+
+
+ Red
+
+
+
+ -
+
+
+ Green
+
+
+
+ -
+
+
+ Blue
+
+
+
+
+
+
+ -
+
+
+ QFrame::Shape::NoFrame
+
+
+ QFrame::Shadow::Raised
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
-
+
+
+ 31
+
+
+ 4
+
+
+ Qt::Orientation::Horizontal
+
+
+
+ -
+
+
+ 31
+
+
+ 4
+
+
+ Qt::Orientation::Horizontal
+
+
+
+ -
+
+
+ 31
+
+
+ 4
+
+
+ Qt::Orientation::Horizontal
+
+
+
+
+
+
+ -
+
+
+ QFrame::Shape::NoFrame
+
+
+ QFrame::Shadow::Raised
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
-
+
+
+ 255
+
+
+ 8
+
+
+
+ -
+
+
+ 255
+
+
+ 8
+
+
+
+ -
+
+
+ 255
+
+
+ 8
+
+
+
+
+
+
+
+
+
+ -
+
+
+
+ 32
+ 32
+
+
+
+
+ 32
+ 32
+
+
+
+ QFrame::Shadow::Raised
+
+
+
+ -
+
+
+ Qt::Orientation::Vertical
+
+
+
+ 20
+ 40
+
+
+
+
+ -
+
+
+ QFrame::Shape::NoFrame
+
+
+ QFrame::Shadow::Raised
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
-
+
+
+ QFrame::Shape::NoFrame
+
+
+ QFrame::Shadow::Raised
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
-
+
+
+ #
+
+
+ Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+ ...
+
+
+
+ :/icons/pipette.ico:/icons/pipette.ico
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/forms/gridsettingsdialog.ui b/forms/gridsettingsdialog.ui
index c5aa299d..73411742 100644
--- a/forms/gridsettingsdialog.ui
+++ b/forms/gridsettingsdialog.ui
@@ -6,8 +6,8 @@
0
0
- 423
- 375
+ 331
+ 467
@@ -24,39 +24,23 @@
0
0
- 397
- 309
+ 305
+ 401
- -
-
-
- Offset (in pixels)
+
-
+
+
+ Qt::Orientation::Vertical
-
-
-
-
-
- X
-
-
-
- -
-
-
- Y
-
-
-
- -
-
-
- -
-
-
-
-
+
+
+ 20
+ 40
+
+
+
-
@@ -71,6 +55,19 @@
+ -
+
+
+ false
+
+
+ QComboBox::SizeAdjustPolicy::AdjustToContentsOnFirstShow
+
+
+ 0
+
+
+
-
@@ -121,31 +118,41 @@
- -
-
-
- false
-
-
- QComboBox::SizeAdjustPolicy::AdjustToContentsOnFirstShow
-
-
- 0
+
-
+
+
+ Offset (in pixels)
+
+
-
+
+
+ X
+
+
+
+ -
+
+
+ Y
+
+
+
+ -
+
+
+ -
+
+
+
- -
-
-
- Qt::Orientation::Vertical
+
-
+
+
+
-
-
- 20
- 40
-
-
-
+
@@ -174,6 +181,12 @@
QComboBox
+
+ ColorInputWidget
+ QGroupBox
+
+ 1
+
diff --git a/include/ui/colorinputwidget.h b/include/ui/colorinputwidget.h
new file mode 100644
index 00000000..5b414776
--- /dev/null
+++ b/include/ui/colorinputwidget.h
@@ -0,0 +1,45 @@
+#ifndef COLORINPUTWIDGET_H
+#define COLORINPUTWIDGET_H
+
+#include
+#include
+
+namespace Ui {
+class ColorInputWidget;
+}
+
+
+class ColorInputWidget : public QGroupBox {
+ Q_OBJECT
+public:
+ explicit ColorInputWidget(QWidget *parent = nullptr);
+ explicit ColorInputWidget(const QString &title, QWidget *parent = nullptr);
+ ~ColorInputWidget();
+
+ void setColor(QRgb color);
+ QRgb color() const { return m_color; }
+
+ bool setBitDepth(int bits);
+ int bitDepth() const { return m_bitDepth; }
+
+signals:
+ void colorChanged(QRgb color);
+ void bitDepthChanged(int bits);
+
+private:
+ Ui::ColorInputWidget *ui;
+
+ QRgb m_color = 0;
+ int m_bitDepth = 0;
+
+ void init();
+ void updateColorUi();
+ void pickColor();
+ void blockEditSignals(bool block);
+
+ void setRgbFromSliders();
+ void setRgbFromSpinners();
+ void setRgbFromHexString(const QString &);
+};
+
+#endif // COLORINPUTWIDGET_H
diff --git a/include/ui/gridsettingsdialog.h b/include/ui/gridsettingsdialog.h
index 957edb43..9c64f29d 100644
--- a/include/ui/gridsettingsdialog.h
+++ b/include/ui/gridsettingsdialog.h
@@ -34,6 +34,7 @@ private slots:
void on_spinBox_X_valueChanged(int value);
void on_spinBox_Y_valueChanged(int value);
void on_comboBox_Style_currentIndexChanged(int index);
+ void onColorChanged(QRgb color);
};
inline bool operator==(const struct GridSettings &a, const struct GridSettings &b) {
diff --git a/porymap.pro b/porymap.pro
index ae49c4aa..182ea11a 100644
--- a/porymap.pro
+++ b/porymap.pro
@@ -51,6 +51,7 @@ SOURCES += src/core/block.cpp \
src/scriptapi/apiutility.cpp \
src/scriptapi/scripting.cpp \
src/ui/aboutporymap.cpp \
+ src/ui/colorinputwidget.cpp \
src/ui/connectionslistitem.cpp \
src/ui/customscriptseditor.cpp \
src/ui/customscriptslistitem.cpp \
@@ -175,6 +176,7 @@ HEADERS += include/core/block.h \
include/ui/prefabcreationdialog.h \
include/ui/regionmappixmapitem.h \
include/ui/citymappixmapitem.h \
+ include/ui/colorinputwidget.h \
include/ui/mapsceneeventfilter.h \
include/ui/metatilelayersitem.h \
include/ui/metatileselector.h \
@@ -220,6 +222,7 @@ HEADERS += include/core/block.h \
include/ui/wildmonchart.h
FORMS += forms/mainwindow.ui \
+ forms/colorinputwidget.ui \
forms/connectionslistitem.ui \
forms/gridsettingsdialog.ui \
forms/newmapconnectiondialog.ui \
diff --git a/src/ui/colorinputwidget.cpp b/src/ui/colorinputwidget.cpp
new file mode 100644
index 00000000..200567af
--- /dev/null
+++ b/src/ui/colorinputwidget.cpp
@@ -0,0 +1,216 @@
+#include "colorinputwidget.h"
+#include "ui_colorinputwidget.h"
+#include "colorpicker.h"
+
+#include
+
+// TODO: Refactor palette editor to make use of this class
+
+class HexCodeValidator : public QValidator {
+ virtual QValidator::State validate(QString &input, int &) const override {
+ input = input.toUpper();
+ return QValidator::Acceptable;
+ }
+};
+
+static inline int rgb5(int rgb) { return round(static_cast(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; }
+
+ColorInputWidget::ColorInputWidget(QWidget *parent) :
+ QGroupBox(parent),
+ ui(new Ui::ColorInputWidget)
+{
+ init();
+}
+
+ColorInputWidget::ColorInputWidget(const QString &title, QWidget *parent) :
+ QGroupBox(title, parent),
+ ui(new Ui::ColorInputWidget)
+{
+ init();
+}
+
+void ColorInputWidget::init() {
+ ui->setupUi(this);
+
+ connect(ui->slider_Red, &QSlider::valueChanged, this, &ColorInputWidget::setRgbFromSliders);
+ connect(ui->slider_Green, &QSlider::valueChanged, this, &ColorInputWidget::setRgbFromSliders);
+ connect(ui->slider_Blue, &QSlider::valueChanged, this, &ColorInputWidget::setRgbFromSliders);
+
+ connect(ui->spinBox_Red, QOverload::of(&QSpinBox::valueChanged), this, &ColorInputWidget::setRgbFromSpinners);
+ connect(ui->spinBox_Green, QOverload::of(&QSpinBox::valueChanged), this, &ColorInputWidget::setRgbFromSpinners);
+ connect(ui->spinBox_Blue, QOverload::of(&QSpinBox::valueChanged), this, &ColorInputWidget::setRgbFromSpinners);
+
+ static const HexCodeValidator hexValidator;
+ ui->lineEdit_Hex->setValidator(&hexValidator);
+ connect(ui->lineEdit_Hex, &QLineEdit::textEdited, this, &ColorInputWidget::setRgbFromHexString);
+
+ connect(ui->button_Eyedrop, &QToolButton::clicked, this, &ColorInputWidget::pickColor);
+
+ setBitDepth(24);
+}
+
+ColorInputWidget::~ColorInputWidget() {
+ delete ui;
+}
+
+void ColorInputWidget::updateColorUi() {
+ blockEditSignals(true);
+
+ int red = qRed(m_color);
+ int green = qGreen(m_color);
+ int blue = qBlue(m_color);
+
+ if (m_bitDepth == 15) {
+ // Sliders
+ ui->slider_Red->setValue(rgb5(red));
+ ui->slider_Green->setValue(rgb5(green));
+ ui->slider_Blue->setValue(rgb5(blue));
+
+ // Hex
+ int hex15 = (rgb5(blue) << 10) | (rgb5(green) << 5) | rgb5(red);
+ ui->lineEdit_Hex->setText(QString("%1").arg(hex15, 4, 16, QLatin1Char('0')).toUpper());
+
+ // Spinners
+ ui->spinBox_Red->setValue(rgb5(red));
+ ui->spinBox_Green->setValue(rgb5(green));
+ ui->spinBox_Blue->setValue(rgb5(blue));
+ } else {
+ // Sliders
+ ui->slider_Red->setValue(red);
+ ui->slider_Green->setValue(green);
+ ui->slider_Blue->setValue(blue);
+
+ // Hex
+ QColor color(red, green, blue);
+ ui->lineEdit_Hex->setText(color.name().remove(0, 1).toUpper());
+
+ // Spinners
+ ui->spinBox_Red->setValue(red);
+ ui->spinBox_Green->setValue(green);
+ ui->spinBox_Blue->setValue(blue);
+ }
+
+ ui->frame_ColorDisplay->setStyleSheet(QString("background-color: rgb(%1, %2, %3);").arg(red).arg(green).arg(blue));
+
+ blockEditSignals(false);
+}
+
+void ColorInputWidget::blockEditSignals(bool block) {
+ ui->slider_Red->blockSignals(block);
+ ui->slider_Green->blockSignals(block);
+ ui->slider_Blue->blockSignals(block);
+
+ ui->spinBox_Red->blockSignals(block);
+ ui->spinBox_Green->blockSignals(block);
+ ui->spinBox_Blue->blockSignals(block);
+
+ ui->lineEdit_Hex->blockSignals(block);
+}
+
+bool ColorInputWidget::setBitDepth(int bits) {
+ if (m_bitDepth == bits)
+ return true;
+
+ int singleStep, pageStep, maximum;
+ QString hexInputMask;
+ if (bits == 15) {
+ singleStep = 1;
+ pageStep = 4;
+ maximum = 31;
+ hexInputMask = "HHHH";
+ } else if (bits == 24) {
+ singleStep = 8;
+ pageStep = 24;
+ maximum = 255;
+ hexInputMask = "HHHHHH";
+ } else {
+ // Unsupported bit depth
+ return false;
+ }
+ m_bitDepth = bits;
+
+ blockEditSignals(true);
+ ui->slider_Red->setSingleStep(singleStep);
+ ui->slider_Green->setSingleStep(singleStep);
+ ui->slider_Blue->setSingleStep(singleStep);
+ ui->slider_Red->setPageStep(pageStep);
+ ui->slider_Green->setPageStep(pageStep);
+ ui->slider_Blue->setPageStep(pageStep);
+ ui->slider_Red->setMaximum(maximum);
+ ui->slider_Green->setMaximum(maximum);
+ ui->slider_Blue->setMaximum(maximum);
+
+ ui->spinBox_Red->setSingleStep(singleStep);
+ ui->spinBox_Green->setSingleStep(singleStep);
+ ui->spinBox_Blue->setSingleStep(singleStep);
+ ui->spinBox_Red->setMaximum(maximum);
+ ui->spinBox_Green->setMaximum(maximum);
+ ui->spinBox_Blue->setMaximum(maximum);
+
+ ui->lineEdit_Hex->setInputMask(hexInputMask);
+ ui->lineEdit_Hex->setMaxLength(hexInputMask.length());
+
+ updateColorUi();
+ blockEditSignals(false);
+ emit bitDepthChanged(m_bitDepth);
+ return true;
+}
+
+void ColorInputWidget::setColor(QRgb rgb) {
+ if (m_color == rgb)
+ return;
+ m_color = rgb;
+ updateColorUi();
+ emit colorChanged(m_color);
+}
+
+void ColorInputWidget::setRgbFromSliders() {
+ if (m_bitDepth == 15) {
+ setColor(qRgb(rgb8(ui->slider_Red->value()),
+ rgb8(ui->slider_Green->value()),
+ rgb8(ui->slider_Blue->value())));
+ } else {
+ setColor(qRgb(ui->slider_Red->value(),
+ ui->slider_Green->value(),
+ ui->slider_Blue->value()));
+ }
+}
+
+void ColorInputWidget::setRgbFromSpinners() {
+ if (m_bitDepth == 15) {
+ setColor(qRgb(rgb8(ui->spinBox_Red->value()), rgb8(ui->spinBox_Green->value()), rgb8(ui->spinBox_Blue->value())));
+ } else {
+ setColor(qRgb(ui->spinBox_Red->value(), ui->spinBox_Green->value(), ui->spinBox_Blue->value()));
+ }
+}
+
+void ColorInputWidget::setRgbFromHexString(const QString &text) {
+ if ((m_bitDepth == 24 && text.length() != 6)
+ || (m_bitDepth == 15 && text.length() != 4))
+ return;
+
+ bool ok = false;
+ int rgb = text.toInt(&ok, 16);
+ if (!ok) rgb = 0xFFFFFFFF;
+
+ if (m_bitDepth == 15) {
+ int rc = gbaRed(rgb);
+ int gc = gbaGreen(rgb);
+ int bc = gbaBlue(rgb);
+ setColor(qRgb(rgb8(rc), rgb8(gc), rgb8(bc)));
+ } else {
+ setColor(qRgb(qRed(rgb), qGreen(rgb), qBlue(rgb)));
+ }
+}
+
+void ColorInputWidget::pickColor() {
+ ColorPicker picker(this);
+ if (picker.exec() == QDialog::Accepted) {
+ QColor c = picker.getColor();
+ setColor(c.rgb());
+ }
+}
diff --git a/src/ui/gridsettingsdialog.cpp b/src/ui/gridsettingsdialog.cpp
index 10934196..bfc814bc 100644
--- a/src/ui/gridsettingsdialog.cpp
+++ b/src/ui/gridsettingsdialog.cpp
@@ -1,7 +1,6 @@
#include "ui_gridsettingsdialog.h"
#include "gridsettingsdialog.h"
-// TODO: Add color picker
// TODO: Add linking chain button to width/height
// TODO: Add "snap to metatile" check box?
// TODO: Save settings in config
@@ -39,9 +38,7 @@ GridSettingsDialog::GridSettingsDialog(GridSettings *settings, QWidget *parent)
reset(true);
connect(ui->buttonBox, &QDialogButtonBox::clicked, this, &GridSettingsDialog::dialogButtonClicked);
-
- // TODO: Connect color picker
- // connect(ui->, &, this, &GridSettingsDialog::changedGridSettings);
+ connect(ui->colorInput, &ColorInputWidget::colorChanged, this, &GridSettingsDialog::onColorChanged);
}
GridSettingsDialog::~GridSettingsDialog() {
@@ -59,11 +56,13 @@ void GridSettingsDialog::reset(bool force) {
const QSignalBlocker b_X(ui->spinBox_X);
const QSignalBlocker b_Y(ui->spinBox_Y);
const QSignalBlocker b_Style(ui->comboBox_Style);
+ const QSignalBlocker b_Color(ui->colorInput);
ui->spinBox_Width->setValue(this->settings->width);
ui->spinBox_Height->setValue(this->settings->height);
ui->spinBox_X->setValue(this->settings->offsetX);
ui->spinBox_Y->setValue(this->settings->offsetY);
+ ui->colorInput->setColor(this->settings->color.rgb());
// TODO: Debug
//ui->comboBox_Style->setCurrentIndex(ui->comboBox_Style->findData(static_cast(this->settings->style)));
@@ -73,7 +72,6 @@ void GridSettingsDialog::reset(bool force) {
break;
}
}
- // TODO: Initialize color with settings-color
emit changedGridSettings();
}
@@ -106,6 +104,11 @@ void GridSettingsDialog::on_comboBox_Style_currentIndexChanged(int index) {
emit changedGridSettings();
}
+void GridSettingsDialog::onColorChanged(QRgb color) {
+ this->settings->color = QColor::fromRgb(color);
+ emit changedGridSettings();
+}
+
void GridSettingsDialog::dialogButtonClicked(QAbstractButton *button) {
auto role = ui->buttonBox->buttonRole(button);
if (role == QDialogButtonBox::AcceptRole) {
@@ -114,6 +117,6 @@ void GridSettingsDialog::dialogButtonClicked(QAbstractButton *button) {
reset();
close();
} else if (role == QDialogButtonBox::ResetRole) {
- reset();
+ reset(); // TODO: We should restore to original defaults, not to the values when the window was opened.
}
}