diff --git a/src/include/filter.h b/src/include/filter.h index 9c0a58fb..c1efa92a 100644 --- a/src/include/filter.h +++ b/src/include/filter.h @@ -296,6 +296,7 @@ void restorepalette(struct palette *dest, struct palette *src); void convertupgeneric(struct filter *f, int *x, int *y); void convertdowngeneric(struct filter *f, int *x, int *y); int fixedalloccolor(struct palette *palette, int init, int r, int g, int b); +void getPaletteColor(struct palette *palette, int seed, int algorithm, int shift, int newColors[101][3]); #define setfractalpalette(f, p) \ if ((f)->fractalc->palette == (f)->image->palette) \ diff --git a/src/include/xmenu.h b/src/include/xmenu.h index 04630ebc..747fdbae 100644 --- a/src/include/xmenu.h +++ b/src/include/xmenu.h @@ -31,6 +31,7 @@ typedef char *(*tokenfunc)(struct uih_context *c); #define DIALOG_CHOICE 7 #define DIALOG_ONOFF 8 #define DIALOG_COORD 9 +#define DIALOG_PALSLIDER 10 #define DIALOGIFILE(question, filename) \ { \ @@ -68,6 +69,10 @@ typedef char *(*tokenfunc)(struct uih_context *c); { \ question, DIALOG_COORD, 0, NULL, default1, default2 \ } +#define DIALOGPALSLIDER(question, default) \ + { \ + question, DIALOG_SLIDER, default \ + } #define DIALOGIFILE_I(_question, _filename) \ menudialogs_i18n[no_menudialogs_i18n].question = _question; \ @@ -135,6 +140,12 @@ typedef char *(*tokenfunc)(struct uih_context *c); menudialogs_i18n[no_menudialogs_i18n].deffloat2 = _default2; \ ++no_menudialogs_i18n; +#define DIALOGPALSLIDER_I(_question, _default) \ + menudialogs_i18n[no_menudialogs_i18n].question = _question; \ + menudialogs_i18n[no_menudialogs_i18n].type = DIALOG_PALSLIDER; \ + menudialogs_i18n[no_menudialogs_i18n].defint = _default; \ + ++no_menudialogs_i18n; + #define NULL_I() \ menudialogs_i18n[no_menudialogs_i18n].question = NULL; \ menudialogs_i18n[no_menudialogs_i18n].type = 0; \ diff --git a/src/ui-hlp/menu.cpp b/src/ui-hlp/menu.cpp index 263fffd6..3131e2a4 100644 --- a/src/ui-hlp/menu.cpp +++ b/src/ui-hlp/menu.cpp @@ -62,7 +62,7 @@ const char *const uih_colornames[] = {"white", "black", "red", NULL}; * Zoltan Kovacs , 2003-01-05 */ -#define MAX_MENUDIALOGS_I18N 102 +#define MAX_MENUDIALOGS_I18N 103 #define Register(variable) variable = &menudialogs_i18n[no_menudialogs_i18n] static menudialog menudialogs_i18n[MAX_MENUDIALOGS_I18N]; // static int no_menudialogs_i18n; @@ -266,9 +266,10 @@ void uih_registermenudialogs_i18n(void) NULL_I(); Register(palettedialog); - DIALOGINT_I(TR("Dialog", "Algorithm number:"), 0); - DIALOGINT_I(TR("Dialog", "Seed:"), 0); - DIALOGINT_I(TR("Dialog", "Shift:"), 0); + DIALOGINT_I(TR("Dialog", "Current Algorithm:"), 0); + DIALOGINT_I(TR("Dialog", "Current Seed:"), 0); + DIALOGINT_I(TR("Dialog", "Current Shift:"), 0); + DIALOGPALSLIDER_I(TR("Dialog", "Visualiser:"), 0); NULL_I(); Register(uih_cyclingdialog); @@ -557,6 +558,7 @@ static menudialog *uih_getpalettedialog(struct uih_context *uih) palettedialog[0].defint = uih->palettetype; palettedialog[1].defint = uih->paletteseed; palettedialog[2].defint = uih->paletteshift + uih->manualpaletteshift; + palettedialog[3].defint = 0; } return (palettedialog); } @@ -590,6 +592,7 @@ static void uih_palette(struct uih_context *uih, dialogparam *p) int n1 = p[0].dint; int n2 = p[1].dint; int shift = p[2].dint; + if (!n1) { uih_playdefpalette(uih, shift); return; diff --git a/src/ui/customdialog.cpp b/src/ui/customdialog.cpp index 44d0a2b2..b0f19b61 100644 --- a/src/ui/customdialog.cpp +++ b/src/ui/customdialog.cpp @@ -7,11 +7,15 @@ #include "config.h" #include "ui.h" #include "misc-f.h" +#include "filter.h" +#include "ui_helper.h" #ifdef USE_FLOAT128 #include #endif +struct palette *gradientpal; + QString format(number_t number) { char buf[256]; @@ -27,7 +31,7 @@ QString format(number_t number) return QString(buf); } -CustomDialog::CustomDialog(struct uih_context */*uih*/, const menuitem *item, +CustomDialog::CustomDialog(struct uih_context *uih, const menuitem *item, const menudialog *dialog, QWidget *parent) : QDialog(parent) { @@ -103,6 +107,79 @@ CustomDialog::CustomDialog(struct uih_context */*uih*/, const menuitem *item, formLayout->addRow(label, combo); + } else if(dialog[i].type == DIALOG_PALSLIDER) { + + gradientpal = clonepalette(uih->image->palette); + //Separator Line + QFrame *line = new QFrame(this); + line->setGeometry(QRect(320, 150, 118, 3)); + line->setFrameShape(QFrame::HLine); + line->setFrameShadow(QFrame::Sunken); + line->setContentsMargins(0,5,0,5); + formLayout->addRow(line); + + // 3 inputs decide color, Algorithm Number, Seed and shift + // For Algorithm number + algono = new QSpinBox(this); + algono->setObjectName(label + "algono"); + algono->setValue(m_dialog[0].defint); + algono->setRange(1, 3); + + // Algo Slider + algoslider = new QSlider(Qt::Horizontal, this); + algoslider->setObjectName(label); + algoslider->setRange(1, 3); + algoslider->setValue(algono->value()); + + // For Seed Number + seedno = new QSpinBox(this); + seedno->setObjectName(label + "seedno"); + seedno->setValue(m_dialog[1].defint); + seedno->setRange(0, gradientpal->size); + + // Seed Slider + seedslider = new QSlider(Qt::Horizontal, this); + seedslider->setObjectName(label); + seedslider->setRange(0, gradientpal->size); + seedslider->setValue(seedno->value()); + + // For Shift Number + shiftno = new QSpinBox(this); + shiftno->setObjectName(label + "shiftno"); + shiftno->setValue(m_dialog[2].defint); + shiftno->setRange(0, gradientpal->size); + + // Shift Slider + shiftslider = new QSlider(Qt::Horizontal, this); + shiftslider->setObjectName(label); + shiftslider->setRange(0, gradientpal->size); + shiftslider->setValue(shiftno->value()); + + // Add them to Layout + QLabel *visualClue = new QLabel(this); + visualClue->setText("New Values"); + visualClue->setToolTip("Set these values to get palette"); + formLayout->addRow(visualClue); + formLayout->addRow("Algorithm", algono); + formLayout->addWidget(algoslider); + formLayout->addRow("Seed", seedno); + formLayout->addWidget(seedslider); + formLayout->addRow("Shift", shiftno); + formLayout->addWidget(shiftslider); + + img = new QLabel(this); + img->setScaledContents(true); + formLayout->addRow(img); + updateVisualiser(); + connect(algono,SIGNAL(valueChanged(int)), algoslider, SLOT(setValue(int))); + connect(algoslider, SIGNAL(valueChanged(int)), algono, SLOT(setValue(int))); + connect(algono, SIGNAL(valueChanged(int)), this, SLOT(updateVisualiser())); + connect(seedno,SIGNAL(valueChanged(int)), seedslider, SLOT(setValue(int))); + connect(seedslider, SIGNAL(valueChanged(int)), seedno, SLOT(setValue(int))); + connect(seedno, SIGNAL(valueChanged(int)), this, SLOT(updateVisualiser())); + connect(shiftno,SIGNAL(valueChanged(int)), shiftslider, SLOT(setValue(int))); + connect(shiftslider, SIGNAL(valueChanged(int)), shiftno, SLOT(setValue(int))); + connect(shiftno, SIGNAL(valueChanged(int)), this, SLOT(updateVisualiser())); } else { QLineEdit *field = new QLineEdit(this); @@ -167,6 +244,13 @@ void CustomDialog::accept() m_parameters[i].dint = field->text().toInt(); else if (m_dialog[i].type == DIALOG_FLOAT) m_parameters[i].number = xstrtonum(field->text().toUtf8(), &ps); + else if (m_dialog[i].type == DIALOG_PALSLIDER) { + m_parameters[0].dint = algono->value(); + m_parameters[1].dint = seedno->value(); + m_parameters[2].dint = shiftno->value(); + m_parameters[i].dint = 0; + destroypalette(gradientpal); + } else m_parameters[i].dstring = strdup(field->text().toUtf8()); } @@ -203,3 +287,24 @@ void CustomDialog::chooseOutputFile() settings.setValue("MainWindow/lastFileLocation", QFileInfo(fileName).absolutePath()); } } + +void CustomDialog::updateVisualiser() +{ + // Get updated Colors + int colors[101][3]; + getPaletteColor(gradientpal, seedno->value(), + algono->value()-1 < 0? 0:algono->value()-1, shiftno->value(), colors); + + // Load Curve + QImage editImage(100, 1, QImage::Format_RGB32); + + // Fill Curve + for(int i=0;i<100;i++) { + QRgb value = qRgb(colors[i][0], colors[i][1], colors[i][2]); + editImage.setPixelColor(i, 0, value); + } + + // Save Result + QPixmap newImage = QPixmap::fromImage(editImage.scaled(this->algono->width(), this->algono->height())); + img->setPixmap(newImage); +} diff --git a/src/ui/customdialog.h b/src/ui/customdialog.h index 291b2f6b..c522e06e 100644 --- a/src/ui/customdialog.h +++ b/src/ui/customdialog.h @@ -2,6 +2,9 @@ #define CUSTOMDIALOG_H #include +#include +#include +#include #include "ui.h" class CustomDialog : public QDialog @@ -11,9 +14,13 @@ class CustomDialog : public QDialog const menuitem *m_menuitem; const menudialog *m_dialog; dialogparam *m_parameters; + QSpinBox *algono, *seedno, *shiftno; + QLabel *img; + QSlider *seedslider, *algoslider, *shiftslider; private slots: void chooseInputFile(); void chooseOutputFile(); + void updateVisualiser(); public: CustomDialog(struct uih_context *uih, const menuitem *item, diff --git a/src/util/palette.cpp b/src/util/palette.cpp index dcfdc7bc..af8beb77 100644 --- a/src/util/palette.cpp +++ b/src/util/palette.cpp @@ -1055,3 +1055,48 @@ int mkrgb(struct palette *c) return red * 256 * 256 + green * 256 + blue; } + +void getPaletteColor(struct palette *src, int seed, int algorithm, int shift, int newColors[101][3]) { + mkpalette(src, seed, algorithm); + shiftpalette(src, shift); + for (int i = 0; i < 101; i++) { + int r = 0, g = 0, b = 0; + switch (src->type) { + case SMALLITER: + r = g = b = i; + break; + case LARGEITER: + r = g = b = i / 256; + break; + case GRAYSCALE: + r = g = b = src->pixels[i]; + break; + case C256: + case FIXEDCOLOR: + case MBITMAP: + case LBITMAP: + case MIBITMAP: + case LIBITMAP: + r = src->rgb[src->pixels[i]][0]; + g = src->rgb[src->pixels[i]][1]; + b = src->rgb[src->pixels[i]][2]; + break; + case TRUECOLOR: + case TRUECOLOR16: + case TRUECOLOR24: + r = (((src->pixels[i] & src->info.truec.rmask) >> + src->info.truec.rshift)) + << src->info.truec.rprec; + g = (((src->pixels[i] & src->info.truec.gmask) >> + src->info.truec.gshift)) + << src->info.truec.gprec; + b = (((src->pixels[i] & src->info.truec.bmask) >> + src->info.truec.bshift)) + << src->info.truec.bprec; + break; + } + newColors[i][0]=r; + newColors[i][1]=g; + newColors[i][2]=b; + } +}