add a color picker dialog to palette editor

This commit is contained in:
garak 2022-06-17 15:04:12 -04:00 committed by garakmon
parent 11661818b6
commit 45cb2a19af
7 changed files with 2079 additions and 1163 deletions

192
forms/colorpicker.ui Normal file
View file

@ -0,0 +1,192 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>ColorPicker</class>
<widget class="QDialog" name="ColorPicker">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>357</width>
<height>186</height>
</rect>
</property>
<property name="windowTitle">
<string>Color Picker</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QFrame" name="frame_4">
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Plain</enum>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="viewport">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>120</width>
<height>120</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>120</width>
<height>120</height>
</size>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QFrame" name="frame_3">
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Plain</enum>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QFrame" name="frame">
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Plain</enum>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QFrame" name="frame_centralColor">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>50</width>
<height>50</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>50</width>
<height>50</height>
</size>
</property>
<property name="baseSize">
<size>
<width>50</width>
<height>50</height>
</size>
</property>
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QLabel" name="label_RGB">
<property name="font">
<font>
<family>Courier</family>
</font>
</property>
<property name="text">
<string>RGB (000, 000, 000)</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_HEX">
<property name="font">
<font>
<family>Courier</family>
</font>
</property>
<property name="text">
<string>#FFFFFF</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

File diff suppressed because it is too large Load diff

33
include/ui/colorpicker.h Normal file
View file

@ -0,0 +1,33 @@
#ifndef COLORPICKER_H
#define COLORPICKER_H
#include <QDialog>
#include <QGraphicsScene>
namespace Ui {
class ColorPicker;
}
class ColorPicker : public QDialog
{
Q_OBJECT
public:
explicit ColorPicker(QWidget *parent = nullptr);
~ColorPicker();
QColor getColor() { return this->color; }
private:
Ui::ColorPicker *ui;
QGraphicsScene *scene = nullptr;
QTimer *timer = nullptr;
QPoint lastCursorPos = QPoint(0, 0);
QColor color = Qt::white;
void hover(int mouseX, int mouseY);
};
#endif // COLORPICKER_H

View file

@ -34,6 +34,7 @@ private:
QList<QList<QSlider*>> sliders;
QList<QFrame*> frames;
QList<QLabel*> rgbLabels;
QList<QToolButton *> pickButtons;
Tileset *primaryTileset;
Tileset *secondaryTileset;
QList<History<PaletteHistoryItem*>> palettesHistory;
@ -48,6 +49,7 @@ private:
void restoreWindowState();
void setColorsFromHistory(PaletteHistoryItem*, int);
void closeEvent(QCloseEvent*);
void pickColor(int i);
signals:
void closed();

View file

@ -82,6 +82,7 @@ SOURCES += src/core/block.cpp \
src/ui/multikeyedit.cpp \
src/ui/preferenceeditor.cpp \
src/ui/regionmappropertiesdialog.cpp \
src/ui/colorpicker.cpp \
src/config.cpp \
src/editor.cpp \
src/main.cpp \
@ -164,6 +165,7 @@ HEADERS += include/core/block.h \
include/ui/multikeyedit.h \
include/ui/preferenceeditor.h \
include/ui/regionmappropertiesdialog.h \
include/ui/colorpicker.h \
include/config.h \
include/editor.h \
include/mainwindow.h \
@ -184,6 +186,7 @@ FORMS += forms/mainwindow.ui \
forms/shortcutseditor.ui \
forms/preferenceeditor.ui \
forms/regionmappropertiesdialog.ui
forms/colorpicker.ui
RESOURCES += \
resources/images.qrc \

81
src/ui/colorpicker.cpp Normal file
View file

@ -0,0 +1,81 @@
#include "colorpicker.h"
#include "ui_colorpicker.h"
#include <QtWidgets>
const int zoom_box_dimensions = 7;
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 - 7, mouseY - 7, 15, 15);
QPixmap grab = screen->grabWindow(0, mouseX - 7, mouseY - 7, 15, 15);
int pixelRatio = grab.devicePixelRatio();
// TODO: investigate for high dpi displays why text is too high res
grab.setDevicePixelRatio(1);
QPixmap magnified = grab.scaled(120, 120, Qt::KeepAspectRatio);
QPainter painter(&magnified);
painter.setRenderHint(QPainter::Antialiasing, false);
QRectF rect(55, 55, 9, 9);
painter.drawRect(rect);
painter.end();
// TODO: bounds checking?
this->color = grab.toImage().pixelColor(7 * pixelRatio, 7 * 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);
}

View file

@ -1,8 +1,10 @@
#include "paletteeditor.h"
#include "ui_paletteeditor.h"
#include "colorpicker.h"
#include "paletteutil.h"
#include "config.h"
#include "log.h"
#include <QFileDialog>
#include <QMessageBox>
@ -105,11 +107,40 @@ PaletteEditor::PaletteEditor(Project *project, Tileset *primaryTileset, Tileset
this->rgbLabels.append(this->ui->label_rgb14);
this->rgbLabels.append(this->ui->label_rgb15);
this->pickButtons.clear();
this->pickButtons.append(this->ui->toolButton_0);
this->pickButtons.append(this->ui->toolButton_1);
this->pickButtons.append(this->ui->toolButton_2);
this->pickButtons.append(this->ui->toolButton_3);
this->pickButtons.append(this->ui->toolButton_4);
this->pickButtons.append(this->ui->toolButton_5);
this->pickButtons.append(this->ui->toolButton_6);
this->pickButtons.append(this->ui->toolButton_7);
this->pickButtons.append(this->ui->toolButton_8);
this->pickButtons.append(this->ui->toolButton_9);
this->pickButtons.append(this->ui->toolButton_10);
this->pickButtons.append(this->ui->toolButton_11);
this->pickButtons.append(this->ui->toolButton_12);
this->pickButtons.append(this->ui->toolButton_13);
this->pickButtons.append(this->ui->toolButton_14);
this->pickButtons.append(this->ui->toolButton_15);
// Setup edit-undo history for each of the palettes.
for (int i = 0; i < Project::getNumPalettesTotal(); i++) {
this->palettesHistory.append(History<PaletteHistoryItem*>());
}
// 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](){
disableSliderSignals();
this->pickColor(i);
this->setColor(i);
enableSliderSignals();
});
this->pickButtons[i]->setEnabled(i < (Project::getNumPalettesTotal() - 1));
}
this->initColorSliders();
this->setPaletteId(paletteId);
this->commitEditHistory(this->ui->spinBox_PaletteId->value());
@ -211,6 +242,18 @@ void PaletteEditor::setColor(int colorIndex) {
emit this->changedPaletteColor();
}
void PaletteEditor::pickColor(int i) {
ColorPicker picker(this);
if (picker.exec() == QDialog::Accepted) {
QColor c = picker.getColor();
// TODO: round? or keep floor?
this->sliders[i][0]->setValue(c.red() / 8);
this->sliders[i][1]->setValue(c.green() / 8);
this->sliders[i][2]->setValue(c.blue() / 8);
}
return;
}
void PaletteEditor::on_spinBox_PaletteId_valueChanged(int paletteId) {
this->refreshColorSliders();
this->refreshColors();