mirror of
https://github.com/ckb-next/ckb-next.git
synced 2026-10-10 12:27:21 -04:00
253 lines
9.0 KiB
C++
253 lines
9.0 KiB
C++
#include <cmath>
|
|
#include <QMessageBox>
|
|
#include <QPainter>
|
|
#include <QSettings>
|
|
#include "ckbsettings.h"
|
|
#include "gradientdialog.h"
|
|
#include "ui_gradientdialog.h"
|
|
|
|
static const QString prefsPath = "Stored Gradients";
|
|
|
|
GradientDialog::GradientDialog(QWidget *parent) :
|
|
QDialog(parent),
|
|
ui(new Ui::GradientDialog)
|
|
{
|
|
ui->setupUi(this);
|
|
connect(ui->widget, SIGNAL(currentChanged(QColor,bool,int)), this, SLOT(currentChanged(QColor,bool,int)));
|
|
connect(ui->stopColor, SIGNAL(colorChanged(QColor)), this, SLOT(colorChanged(QColor)));
|
|
|
|
// Add built-in presets
|
|
Preset blackAndWhite("B & W", true);
|
|
blackAndWhite.gradient.append(QGradientStop(0., QColor(0, 0, 0)));
|
|
blackAndWhite.gradient.append(QGradientStop(1., QColor(255, 255, 255)));
|
|
Preset fade("Fade", true);
|
|
fade.gradient.append(QGradientStop(0., QColor(255, 255, 255)));
|
|
fade.gradient.append(QGradientStop(1., QColor(255, 255, 255, 0)));
|
|
Preset rainbow("Rainbow", true);
|
|
rainbow.gradient.append(QGradientStop(0.00, QColor(255, 0, 0)));
|
|
rainbow.gradient.append(QGradientStop(0.17, QColor(255, 255, 0)));
|
|
rainbow.gradient.append(QGradientStop(0.33, QColor(0, 255, 0)));
|
|
rainbow.gradient.append(QGradientStop(0.50, QColor(0, 255, 255)));
|
|
rainbow.gradient.append(QGradientStop(0.67, QColor(0, 0, 255)));
|
|
rainbow.gradient.append(QGradientStop(0.83, QColor(255, 0, 255)));
|
|
rainbow.gradient.append(QGradientStop(1.00, QColor(255, 0, 0)));
|
|
Preset pastelRainbow("Pastel Rainbow", true);
|
|
pastelRainbow.gradient.append(QGradientStop(0.00, QColor(240, 158, 167)));
|
|
pastelRainbow.gradient.append(QGradientStop(0.17, QColor(246, 202, 148)));
|
|
pastelRainbow.gradient.append(QGradientStop(0.33, QColor(193, 235, 192)));
|
|
pastelRainbow.gradient.append(QGradientStop(0.50, QColor(160, 255, 252)));
|
|
pastelRainbow.gradient.append(QGradientStop(0.67, QColor(199, 202, 255)));
|
|
pastelRainbow.gradient.append(QGradientStop(0.83, QColor(246, 194, 243)));
|
|
pastelRainbow.gradient.append(QGradientStop(1.00, QColor(240, 158, 167)));
|
|
addPreset(blackAndWhite);
|
|
addPreset(fade);
|
|
addPreset(rainbow);
|
|
addPreset(pastelRainbow);
|
|
|
|
// Load stored presets
|
|
CkbSettings settings(prefsPath);
|
|
foreach(const QString& name, settings.childGroups()){
|
|
QString pName = name.toLower();
|
|
if(presets.contains(pName))
|
|
continue;
|
|
SGroup group(settings, name);
|
|
// Create keys in a map to ensure correct order and no duplicates
|
|
QMap<int, QColor> colors;
|
|
foreach(const QString& position, settings.childKeys()){
|
|
int pos = position.toInt();
|
|
if(pos < 0 || pos > 100)
|
|
continue;
|
|
colors[pos] = settings.value(position).value<QColor>();
|
|
}
|
|
if(colors.count() < 2)
|
|
continue;
|
|
Preset preset(name);
|
|
QMapIterator<int, QColor> i(colors);
|
|
while(i.hasNext()){
|
|
i.next();
|
|
preset.gradient.append(QGradientStop(i.key() / 100., i.value()));
|
|
}
|
|
presets[pName] = preset;
|
|
}
|
|
|
|
updatePresets();
|
|
}
|
|
|
|
QGradientStops GradientDialog::getGradient(const QGradientStops& prevGradient){
|
|
ui->presetDelete->setEnabled(false);
|
|
ui->presetSave->setEnabled(true);
|
|
ui->widget->setStops(prevGradient);
|
|
exec();
|
|
if(result() != QDialog::Accepted)
|
|
return prevGradient;
|
|
return ui->widget->stops();
|
|
}
|
|
|
|
GradientDialog::~GradientDialog(){
|
|
// Save presets
|
|
CkbSettings settings(prefsPath, true);
|
|
QMapIterator<QString, Preset> i(presets);
|
|
while(i.hasNext()){
|
|
Preset preset = i.next().value();
|
|
if(!preset.builtIn){
|
|
SGroup group(settings, preset.name);
|
|
foreach(const QGradientStop& stop, preset.gradient)
|
|
settings.setValue(QString::number((int)(stop.first * 100.)), stop.second);
|
|
}
|
|
}
|
|
delete ui;
|
|
}
|
|
|
|
QIcon GradientDialog::makeIcon(const Preset& preset){
|
|
// Paint gradient into a square
|
|
int w = 60, h = 60;
|
|
QImage image(w, h, QImage::Format_RGB888);
|
|
QPainter painter(&image);
|
|
// Draw background
|
|
for(int x = 0; x < w; x += 30){
|
|
for(int y = 0; y < h; y += 30){
|
|
painter.fillRect(x, y, 15, 15, QColor(255, 255, 255));
|
|
painter.fillRect(x + 15, y, 15, 15, QColor(192, 192, 192));
|
|
painter.fillRect(x, y + 15, 15, 15, QColor(192, 192, 192));
|
|
painter.fillRect(x + 15, y + 15, 15, 15, QColor(255, 255, 255));
|
|
}
|
|
}
|
|
// Draw gradient
|
|
painter.setPen(QColor(0, 0, 0));
|
|
QLinearGradient gradient(1., 1., w - 1., h - 1.);
|
|
gradient.setStops(preset.gradient);
|
|
painter.setBrush(gradient);
|
|
painter.drawRect(0, 0, w - 1, h - 1);
|
|
return QPixmap::fromImage(image);
|
|
}
|
|
|
|
void GradientDialog::updatePresets(){
|
|
ui->presetList->clear();
|
|
QMapIterator<QString, Preset> i(presets);
|
|
while(i.hasNext()){
|
|
i.next();
|
|
const Preset& preset = i.value();
|
|
QListWidgetItem* item = new QListWidgetItem(makeIcon(preset), preset.name, ui->presetList);
|
|
if(currentPreset == i.key())
|
|
item->setSelected(true);
|
|
ui->presetList->addItem(item);
|
|
}
|
|
}
|
|
|
|
void GradientDialog::currentChanged(const QColor& color, bool spontaneous, int position){
|
|
int pCount = ui->widget->stopCount();
|
|
if(pCount == 1)
|
|
ui->stopBox->setTitle(tr("1 point"));
|
|
else
|
|
ui->stopBox->setTitle(tr("%1 points").arg(pCount));
|
|
if(!color.isValid()){
|
|
ui->stopBox->setEnabled(false);
|
|
ui->stopPos->setValue(0);
|
|
ui->stopColor->color(QColor(0, 0, 0));
|
|
ui->stopOpacity->setValue(0);
|
|
} else {
|
|
ui->stopBox->setEnabled(true);
|
|
ui->stopPos->setValue(position);
|
|
ui->stopColor->color(color);
|
|
ui->stopOpacity->setValue(round(color.alphaF() * 100.f));
|
|
}
|
|
// Un-set current preset
|
|
if(spontaneous)
|
|
setPreset("");
|
|
setFocus();
|
|
}
|
|
|
|
void GradientDialog::setPreset(const QString &newPreset){
|
|
if(currentPreset == newPreset)
|
|
return;
|
|
if(newPreset == ""){
|
|
ui->presetList->clearSelection();
|
|
ui->presetList->setCurrentItem(nullptr);
|
|
Preset current = presets.value(currentPreset);
|
|
QString curName = ui->presetName->text().trimmed();
|
|
if(curName == "" || (curName == current.name && current.builtIn))
|
|
ui->presetName->setText(tr("Custom"));
|
|
ui->presetDelete->setEnabled(false);
|
|
ui->presetSave->setEnabled(true);
|
|
} else {
|
|
Preset current = presets.value(newPreset);
|
|
ui->presetName->setText(current.name);
|
|
ui->presetDelete->setEnabled(!current.builtIn);
|
|
ui->presetSave->setEnabled(false);
|
|
ui->widget->setStops(current.gradient);
|
|
}
|
|
currentPreset = newPreset;
|
|
setFocus();
|
|
}
|
|
|
|
void GradientDialog::on_presetList_currentItemChanged(QListWidgetItem *current, QListWidgetItem *previous){
|
|
setPreset(current ? current->text().toLower() : "");
|
|
}
|
|
|
|
void GradientDialog::on_presetName_textEdited(const QString &arg1){
|
|
if(currentPreset != "" && arg1.trimmed() != presets[currentPreset].name)
|
|
setPreset("");
|
|
}
|
|
|
|
void GradientDialog::on_presetSave_clicked(){
|
|
if(currentPreset != "")
|
|
return;
|
|
QString name = ui->presetName->text().trimmed();
|
|
if(name == "")
|
|
ui->presetName->setText(name = tr("Custom"));
|
|
QString pName = name.toLower();
|
|
// Make sure not to overwrite a built-in preset
|
|
Preset previous = presets[pName];
|
|
if(previous.builtIn){
|
|
QMessageBox::warning(this, tr("Error"), tr("Can't overwrite a built-in preset. Please choose a different name."));
|
|
setFocus();
|
|
return;
|
|
} else if(previous.name != ""){
|
|
// Warn when overwriting an existing preset
|
|
if(QMessageBox::warning(this, tr("Warning"), tr("Preset \"%1\" already exists. Replace?").arg(name), QMessageBox::StandardButtons(QMessageBox::Save | QMessageBox::Cancel)) != QMessageBox::Save){
|
|
setFocus();
|
|
return;
|
|
}
|
|
}
|
|
presets[pName] = Preset(name, ui->widget->stops());
|
|
currentPreset = pName;
|
|
ui->presetDelete->setEnabled(true);
|
|
ui->presetSave->setEnabled(false);
|
|
updatePresets();
|
|
setFocus();
|
|
}
|
|
|
|
void GradientDialog::on_presetDelete_clicked(){
|
|
Preset current = presets.value(currentPreset);
|
|
if(current.name == "" || current.builtIn)
|
|
return;
|
|
if(QMessageBox::warning(this, tr("Warning"), tr("Delete preset \"%1\"?").arg(current.name), QMessageBox::StandardButtons(QMessageBox::Yes | QMessageBox::No)) != QMessageBox::Yes){
|
|
setFocus();
|
|
return;
|
|
}
|
|
presets.remove(currentPreset);
|
|
currentPreset = "";
|
|
ui->presetDelete->setEnabled(false);
|
|
ui->presetSave->setEnabled(true);
|
|
updatePresets();
|
|
setFocus();
|
|
}
|
|
|
|
void GradientDialog::on_stopPos_valueChanged(int arg1){
|
|
int res = ui->widget->moveCurrent(arg1);
|
|
if(res != arg1)
|
|
ui->stopPos->setValue(res);
|
|
setPreset("");
|
|
}
|
|
|
|
void GradientDialog::colorChanged(QColor color){
|
|
color.setAlphaF(ui->stopOpacity->value() / 100.f);
|
|
ui->widget->setCurrentColor(color);
|
|
setPreset("");
|
|
}
|
|
|
|
void GradientDialog::on_stopOpacity_valueChanged(int arg1){
|
|
colorChanged(ui->stopColor->color());
|
|
setPreset("");
|
|
}
|