add a color picker dialog to palette editor
This commit is contained in:
parent
11661818b6
commit
45cb2a19af
7 changed files with 2079 additions and 1163 deletions
192
forms/colorpicker.ui
Normal file
192
forms/colorpicker.ui
Normal 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
33
include/ui/colorpicker.h
Normal 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
|
|
@ -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();
|
||||
|
|
|
@ -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
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 = 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);
|
||||
}
|
|
@ -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();
|
||||
|
|
Loading…
Reference in a new issue