[KLF Backend][KLF Tools][KLF Home]
KLatexFormula Project
klfcolorchooser.cpp
Go to the documentation of this file.
1/***************************************************************************
2 * file klfcolorchooser.cpp
3 * This file is part of the KLatexFormula Project.
4 * Copyright (C) 2011 by Philippe Faist
5 * philippe.faist at bluewin.ch
6 * *
7 * This program is free software; you can redistribute it and/or modify *
8 * it under the terms of the GNU General Public License as published by *
9 * the Free Software Foundation; either version 2 of the License, or *
10 * (at your option) any later version. *
11 * *
12 * This program is distributed in the hope that it will be useful, *
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15 * GNU General Public License for more details. *
16 * *
17 * You should have received a copy of the GNU General Public License *
18 * along with this program; if not, write to the *
19 * Free Software Foundation, Inc., *
20 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
21 ***************************************************************************/
22/* $Id$ */
23
24#include <stdio.h>
25
26#include <QAction>
27#include <QMenu>
28#include <QDebug>
29#include <QColorDialog>
30#include <QPaintEvent>
31#include <QStyle>
32#include <QStylePainter>
33#include <QStyleFactory>
34#include <QStyleOptionButton>
35#include <QRegExp>
36
37#include <klfdefs.h>
38#include "klfflowlayout.h"
39#include "klfguiutil.h"
40#include "klfrelativefont.h"
41#include "klfcolorchooser.h"
42#include "klfcolorchooser_p.h"
43
44#include <ui_klfcolorchoosewidget.h>
45#include <ui_klfcolordialog.h>
46
47
48
49// -------------------------------------------------------------------
50
51
52KLFColorDialog::KLFColorDialog(QWidget *parent) : QDialog(parent)
53{
54 u = new Ui::KLFColorDialog;
55 u->setupUi(this);
56 setObjectName("KLFColorDialog");
57}
59{
60 delete u;
61}
62
64{
65 return u->mColorChooseWidget;
66}
67
68QColor KLFColorDialog::getColor(QColor startwith, bool alphaenabled, QWidget *parent)
69{
70 KLFColorDialog dlg(parent);
71 dlg.u->mColorChooseWidget->setAlphaEnabled(alphaenabled);
72 dlg.u->mColorChooseWidget->setColor(startwith);
73 int r = dlg.exec();
74 if ( r != QDialog::Accepted )
75 return QColor();
76 QColor color = dlg.u->mColorChooseWidget->color();
77 return color;
78}
79
81{
82 return u->mColorChooseWidget->color();
83}
85{
86 u->mColorChooseWidget->setColor(color);
87}
88void KLFColorDialog::slotAccepted()
89{
91}
92
93// -------------------------------------------------------------------
94
95KLFColorClickSquare::KLFColorClickSquare(QColor color, int size, bool removable, QWidget *parent)
96 : QWidget(parent), _color(color), _removable(removable)
97{
98 initwidget();
99 setSqSize(size);
100}
102 : QWidget(parent), _color(Qt::white), _removable(false)
103{
104 initwidget();
105 setSqSize(16);
106}
107void KLFColorClickSquare::initwidget()
108{
109 setFocusPolicy(Qt::StrongFocus);
110 setContextMenuPolicy(Qt::DefaultContextMenu);
111 // setAutoFillBackground(true);
112 // update();
113}
114
116{
117 if (_size == sz)
118 return;
119
120 _size = sz;
121 setFixedSize(_size, _size);
122}
123
125{
126 _removable = removable;
127}
128
130{
131 KLF_DEBUG_BLOCK(KLF_FUNC_NAME) ;
132 Q_UNUSED(event) ;
133 klfDbg("event->rect="<<event->rect()) ;
134 {
135 QPainter p(this);
136 p.fillRect(0, 0, width(), height(), QBrush(_color));
137 }
138 if (hasFocus()) {
139 QStylePainter p(this);
140 QStyleOptionFocusRect option;
141 option.initFrom(this);
142 option.backgroundColor = QColor(0,0,0,0);
143 p.drawPrimitive(QStyle::PE_FrameFocusRect, option);
144 }
145}
147{
148 Q_UNUSED(event) ;
149}
150
156{
157 if (kev->key() == Qt::Key_Space) {
158 activate();
159 }
160 return QWidget::keyPressEvent(kev);
161}
163{
164 if (_removable) {
165 QMenu *menu = new QMenu(this);
166 menu->addAction("Remove", this, SLOT(internalWantRemove()));
167 menu->popup(event->globalPos());
168 }
169}
170void KLFColorClickSquare::internalWantRemove()
171{
172 emit wantRemove();
173 emit wantRemoveColor(_color);
174}
175
176// -------------------------------------------------------------------
177
179 : QWidget(parent), _img()
180{
181 setPaneType("red+fix");
182 _color = Qt::black;
183}
184
186{
187 return QSize((_colorcomponent == "fix") ? 16 : 50, (_colorcomponent_b == "fix") ? 16 : 50);
188}
190{
191 return QSize(16, 16);
192}
193
195{
196 if (_color == newcolor)
197 return;
198
199 _color = newcolor;
200 update();
201 emit colorChanged(_color);
202}
204{
205 static QStringList okvals =
206 QStringList() << "hue"<<"sat"<<"val"<<"red"<<"green"<<"blue"<<"alpha"<<"fix";
207
208 QStringList strlist = panetype.split("+");
209 if (strlist.size() != 2) {
210 qWarning()<<KLF_FUNC_NAME<<": expected a pane-type string \"<pane1type>+<pane2type>\"!";
211 return;
212 }
213 _colorcomponent = strlist[0].toLower();
214 _colorcomponent_b = strlist[1].toLower();
215 if (!okvals.contains(_colorcomponent))
216 _colorcomponent = "fix";
217 if (!okvals.contains(_colorcomponent_b))
218 _colorcomponent_b = "fix";
219
220 if (_colorcomponent == "fix" && _colorcomponent_b == "fix")
221 setFocusPolicy(Qt::NoFocus);
222 else
223 setFocusPolicy(Qt::WheelFocus);
224}
226{
227 QStylePainter p(this);
228 // background: a checker grid to distinguish transparency
229 p.fillRect(0,0,width(),height(), QBrush(QPixmap(":/pics/checker.png")));
230 // then prepare an image for our gradients
231 int x;
232 int y;
233 _img = QImage(width(), height(), QImage::Format_ARGB32);
234 double xfac = (double)valueAMax() / (_img.width()-1);
235 double yfac = (double)valueBMax() / (_img.height()-1);
236 for (x = 0; x < _img.width(); ++x) {
237 for (y = 0; y < _img.height(); ++y) {
238 _img.setPixel(x, _img.height()-y-1, colorFromValues(_color, (int)(xfac*x), (int)(yfac*y)).rgba());
239 }
240 }
241 p.drawImage(0, 0, _img);
242 // draw crosshairs
243 QColor hairscol = qGray(_color.rgb()) > 80 ? QColor(0,0,0,180) : QColor(255,255,255,180);
244 if ( _colorcomponent != "fix" ) {
245 p.setPen(QPen(hairscol, 1.f, Qt::DotLine));
246 x = (int)(valueA()/xfac);
247 if (x < 0) { x = 0; }
248 if (x >= width()) { x = width()-1; }
249 p.drawLine(x, 0, x, height());
250 }
251 if ( _colorcomponent_b != "fix" ) {
252 p.setPen(QPen(hairscol, 1.f, Qt::DotLine));
253 y = (int)(valueB()/yfac);
254 if (y < 0) { y = 0; }
255 if (y >= height()) { y = height()-1; }
256 p.drawLine(0, height()-y-1, width(), height()-y-1);
257 }
258 // draw a focus rectangle if we have focus
259 if (hasFocus()) {
260 QStyleOptionFocusRect option;
261 option.initFrom(this);
262 option.backgroundColor = QColor(0,0,0,0);
263 p.drawPrimitive(QStyle::PE_FrameFocusRect, option);
264 }
265}
267{
268 double xfac = (double)valueAMax() / (_img.width()-1);
269 double yfac = (double)valueBMax() / (_img.height()-1);
270 int x = e->pos().x();
271 int y = height() - e->pos().y() - 1;
272
273 setColor(colorFromValues(_color, (int)(x*xfac), (int)(y*yfac)));
274}
276{
277 double xfac = (double)valueAMax() / (_img.width()-1);
278 double yfac = (double)valueBMax() / (_img.height()-1);
279 int x = e->pos().x();
280 int y = height() - e->pos().y() - 1;
281 if (x < 0) { x = 0; }
282 if (x >= width()) { x = width()-1; }
283 if (y < 0) { y = 0; } if (y >= height()) { y = height()-1; }
284
285 setColor(colorFromValues(_color, (int)(x*xfac), (int)(y*yfac)));
286}
288{
289 double step = - 7.5 * e->delta() / 120;
290
291 if (e->modifiers() == Qt::ShiftModifier)
292 step = step / 5.0;
293 if (e->modifiers() == Qt::ControlModifier)
294 step = step * 2.5;
295
296 // isA: TRUE if we are modifying component A, if FALSE then modifying component B
297 bool isA = (e->orientation() == Qt::Horizontal);
298 if (isA && _colorcomponent=="fix")
299 isA = false;
300 if (!isA && _colorcomponent_b=="fix")
301 isA = true;
302 if (isA) {
303 // the first component
304 int x = (int)(valueA()+step);
305 if (x < 0) x = 0;
306 if (x > valueAMax()) x = valueAMax();
308 } else {
309 int x = (int)(valueB() - step);
310 if (x < 0) x = 0;
311 if (x > valueBMax()) x = valueBMax();
313 }
314 e->accept();
315}
317{
318 const int dir_step = 5;
319 double xstep = 0;
320 double ystep = 0;
321
322 if (e->key() == Qt::Key_Left)
323 xstep -= dir_step;
324 if (e->key() == Qt::Key_Right)
325 xstep += dir_step;
326 if (e->key() == Qt::Key_Up)
327 ystep += dir_step;
328 if (e->key() == Qt::Key_Down)
329 ystep -= dir_step;
330 if (e->key() == Qt::Key_Home)
331 xstep = -10000;
332 if (e->key() == Qt::Key_End)
333 xstep = 10000;
334 if (e->key() == Qt::Key_PageUp)
335 ystep = 10000;
336 if (e->key() == Qt::Key_PageDown)
337 ystep = -10000;
338
339 // if a component is set to 'fix', add the deltas to the other component...
340 if (_colorcomponent == "fix") {
341 ystep += xstep;
342 xstep = 0;
343 } else if (_colorcomponent_b == "fix") {
344 xstep += ystep;
345 ystep = 0;
346 }
347
348 if (e->modifiers() == Qt::ShiftModifier) {
349 xstep = xstep / 5; ystep = ystep / 5;
350 }
351 if (e->modifiers() == Qt::ControlModifier) {
352 xstep = xstep * 2.5; ystep = ystep * 2.5;
353 }
354
355 int x = (int)(valueA() + xstep);
356 int y = (int)(valueB() + ystep);
357 if (x < 0) x = 0;
358 if (x > valueAMax()) x = valueAMax();
359 if (y < 0) y = 0;
360 if (y > valueBMax()) y = valueBMax();
361
363}
364
365
366// -------------------------------------------------------------------
367
368
369KLFGridFlowLayout::KLFGridFlowLayout(int columns, QWidget *parent)
370 : QGridLayout(parent), _ncols(columns),
371 _currow(0), _curcol(0)
372{
373 addItem(new QSpacerItem(1,1, QSizePolicy::Expanding, QSizePolicy::Fixed), 0, _ncols);
374}
376{
378 QGridLayout::addWidget(w, _currow, _curcol, align);
379 _curcol++;
380 if (_curcol >= _ncols) {
381 _curcol = 0;
382 _currow++;
383 }
384}
386{
387 int k;
388 for (k = 0; k < mGridFlowWidgets.size(); ++k) {
389 // because KLFColorClickSquare::wantRemoveColor() can call this by a chain of
390 // signal/slots; and we shouldn't delete an object inside one of its handlers
391 //delete mGridFlowWidgets[k];
392 mGridFlowWidgets[k]->deleteLater();
393 }
395 _currow = _curcol = 0;
396}
397
398
399// -------------------------------------------------------------------
400
401
411{
412 int value = -1;
413 if (component == "hue") {
414 value = color.hue();
415 } else if (component == "sat") {
416 value = color.saturation();
417 } else if (component == "val") {
418 value = color.value();
419 } else if (component == "red") {
420 value = color.red();
421 } else if (component == "green") {
422 value = color.green();
423 } else if (component == "blue") {
424 value = color.blue();
425 } else if (component == "alpha") {
426 value = color.alpha();
427 } else if (component == "fix" || component.isEmpty()) {
428 value = -1;
429 } else {
430 qWarning("Unknown color component property : %s", component.toLocal8Bit().constData());
431 }
432 return value;
433}
434
436{
437 if (component == "hue")
438 return 359;
439 else if (component == "sat" || component == "val" ||
440 component == "red" || component == "green" ||
441 component == "blue" || component == "alpha")
442 return 255;
443 else if (component == "fix" || component.isEmpty())
444 return -1;
445
446 qWarning("Unknown color component property : %s", component.toLocal8Bit().constData());
447 return -1;
448}
449
451{
452 QColor col = base;
453 /* printf("colorFromValues(%s/alpha=%d, %d, %d): My components:(%s+%s);\n", qPrintable(col.name()),
454 col.alpha(), a, b, qPrintable(_colorcomponent), qPrintable(_colorcomponent_b)); */
455 if (_colorcomponent == "hue") {
456 col.setHsv(a, col.saturation(), col.value());
457 col.setAlpha(base.alpha());
458 } else if (_colorcomponent == "sat") {
459 col.setHsv(col.hue(), a, col.value());
460 col.setAlpha(base.alpha());
461 } else if (_colorcomponent == "val") {
462 col.setHsv(col.hue(), col.saturation(), a);
463 col.setAlpha(base.alpha());
464 } else if (_colorcomponent == "red") {
465 col.setRgb(a, col.green(), col.blue());
466 col.setAlpha(base.alpha());
467 } else if (_colorcomponent == "green") {
468 col.setRgb(col.red(), a, col.blue());
469 col.setAlpha(base.alpha());
470 } else if (_colorcomponent == "blue") {
471 col.setRgb(col.red(), col.green(), a);
472 col.setAlpha(base.alpha());
473 } else if (_colorcomponent == "alpha") {
474 col.setAlpha(a);
475 } else if (_colorcomponent == "fix") {
476 // no change to col
477 } else {
478 qWarning("Unknown color component property : %s", _colorcomponent.toLocal8Bit().constData());
479 }
480 QColor base2 = col;
481 // printf("\tnew color is (%s/alpha=%d);\n", qPrintable(col.name()), col.alpha());
482 if ( ! _colorcomponent_b.isEmpty() && _colorcomponent_b != "fix" ) {
483 // printf("\twe have a second component\n");
484 if (_colorcomponent_b == "hue") {
485 col.setHsv(b, col.saturation(), col.value());
486 col.setAlpha(base2.alpha());
487 } else if (_colorcomponent_b == "sat") {
488 col.setHsv(col.hue(), b, col.value());
489 col.setAlpha(base2.alpha());
490 } else if (_colorcomponent_b == "val") {
491 col.setHsv(col.hue(), col.saturation(), b);
492 col.setAlpha(base2.alpha());
493 } else if (_colorcomponent_b == "red") {
494 col.setRgb(b, col.green(), col.blue());
495 col.setAlpha(base2.alpha());
496 } else if (_colorcomponent_b == "green") {
497 col.setRgb(col.red(), b, col.blue());
498 col.setAlpha(base2.alpha());
499 } else if (_colorcomponent_b == "blue") {
500 col.setRgb(col.red(), col.blue(), b);
501 col.setAlpha(base2.alpha());
502 } else if (_colorcomponent_b == "alpha") {
503 col.setAlpha(b);
504 } else {
505 qWarning("Unknown color component property : %s", _colorcomponent_b.toLocal8Bit().constData());
506 }
507 }
508 // printf("\tand color is finally %s/alpha=%d\n", qPrintable(col.name()), col.alpha());
509 return col;
510}
512{
513 QColor oldcolor = _color;
515 /* printf("My components:(%s+%s); New color is %s/alpha=%d\n", _colorcomponent.toLocal8Bit().constData(),
516 _colorcomponent_b.toLocal8Bit().constData(), _color.name().toLocal8Bit().constData(), _color.alpha()); */
517 if ( oldcolor != _color )
518 return true;
519 return false;
520}
521
522
523// -------------------------------------------------------------------
524
525
527 : QSpinBox(parent)
528{
529 _color = Qt::black;
530
531 setColorComponent("hue");
533
534 connect(this, SIGNAL(valueChanged(int)), this, SLOT(internalChanged(int)));
535
536 setValue(valueAFromNewColor(_color));
537}
538
540{
541 _colorcomponent = comp.toLower();
542 setMinimum(0);
543 setMaximum(valueAMax());
544}
545
546void KLFColorComponentSpinBox::internalChanged(int newvalue)
547{
548 if ( refreshColorFromInternalValues(newvalue) )
549 emit colorChanged(_color);
550}
551
553{
554 if (_color == color)
555 return;
556 int value = valueAFromNewColor(color);
557 /* printf("My components:(%s+%s); setColor(%s/alpha=%d); new value = %d\n",
558 _colorcomponent.toLocal8Bit().constData(), _colorcomponent_b.toLocal8Bit().constData(),
559 color.name().toLocal8Bit().constData(), color.alpha(), value); */
560 _color = color;
561 setValue(value); // will emit QSpinBox::valueChanged() --> internalChanged() --> colorChanged()
562}
563
564
565// -------------------------------------------------------------------
566
567
568KLFColorList * KLFColorChooseWidget::_recentcolors = 0;
569KLFColorList * KLFColorChooseWidget::_standardcolors = 0;
570KLFColorList * KLFColorChooseWidget::_customcolors = 0;
571
572// static
574{
576 _recentcolors->list = recentcolors;
577 _recentcolors->notifyListChanged();
578 _customcolors->list = customcolors;
579 _customcolors->notifyListChanged();
580}
581// static
583{
585 return _recentcolors->list;
586}
587// static
589{
591 return _customcolors->list;
592}
593
594
596 : QWidget(parent)
597{
598 u = new Ui::KLFColorChooseWidget;
599 u->setupUi(this);
600 setObjectName("KLFColorChooseWidget");
601
602 _alphaenabled = true;
603
605
606 if (_standardcolors->list.size() == 0) {
607 // add a few standard colors.
608 QList<QRgb> rgbs;
609 // inspired from the "Forty Colors" Palette in KDE3 color dialog
610 rgbs << 0x000000 << 0x303030 << 0x585858 << 0x808080 << 0xa0a0a0 << 0xc3c3c3
611 << 0xdcdcdc << 0xffffff << 0x400000 << 0x800000 << 0xc00000 << 0xff0000
612 << 0xffc0c0 << 0x004000 << 0x008000 << 0x00c000 << 0x00ff00 << 0xc0ffc0
613 << 0x000040 << 0x000080 << 0x0000c0 << 0x0000ff << 0xc0c0ff << 0x404000
614 << 0x808000 << 0xc0c000 << 0xffff00 << 0xffffc0 << 0x004040 << 0x008080
615 << 0x00c0c0 << 0x00ffff << 0xc0ffff << 0x400040 << 0x800080 << 0xc000c0
616 << 0xff00ff << 0xffc0ff << 0xc05800 << 0xff8000 << 0xffa858 << 0xffdca8 ;
617 for (int k = 0; k < rgbs.size(); ++k)
618 _standardcolors->list.append(QColor(QRgb(rgbs[k])));
619 }
620
621 _connectedColorChoosers.append(u->mDisplayColor);
622 _connectedColorChoosers.append(u->mHueSatPane);
623 _connectedColorChoosers.append(u->mValPane);
624 _connectedColorChoosers.append(u->mAlphaPane);
625 _connectedColorChoosers.append(u->mColorTriangle);
626 _connectedColorChoosers.append(u->mHueSlider);
627 _connectedColorChoosers.append(u->mSatSlider);
628 _connectedColorChoosers.append(u->mValSlider);
629 _connectedColorChoosers.append(u->mRedSlider);
630 _connectedColorChoosers.append(u->mGreenSlider);
631 _connectedColorChoosers.append(u->mBlueSlider);
632 _connectedColorChoosers.append(u->mAlphaSlider);
633 _connectedColorChoosers.append(u->spnHue);
634 _connectedColorChoosers.append(u->spnSat);
635 _connectedColorChoosers.append(u->spnVal);
636 _connectedColorChoosers.append(u->spnRed);
637 _connectedColorChoosers.append(u->spnGreen);
638 _connectedColorChoosers.append(u->spnBlue);
639 _connectedColorChoosers.append(u->spnAlpha);
640
641 /* KLFGridFlowLayout *lytRecent = new KLFGridFlowLayout(12, u->mRecentColorsPalette);
642 lytRecent->setSpacing(2);
643 // lytRecent->setSizeConstraint(QLayout::SetMinAndMaxSize);
644 KLFGridFlowLayout *lytStandard = new KLFGridFlowLayout(12, u->mStandardColorsPalette);
645 lytStandard->setSpacing(2);
646 // lytStandard->setSizeConstraint(QLayout::SetFixedSize);
647 KLFGridFlowLayout *lytCustom = new KLFGridFlowLayout(12, u->mCustomColorsPalette);
648 lytCustom->setSpacing(2);
649 // lytCustom->setSizeConstraint(QLayout::SetFixedSize);
650 */
651 KLFFlowLayout *lytRecent = new KLFFlowLayout(u->mRecentColorsPalette, 11, 2, 2);
653 KLFFlowLayout *lytStandard = new KLFFlowLayout(u->mStandardColorsPalette, 11, 2, 2);
655 KLFFlowLayout *lytCustom = new KLFFlowLayout(u->mCustomColorsPalette, 11, 2, 2);
657
658 connect(_recentcolors, SIGNAL(listChanged()), this, SLOT(updatePaletteRecent()));
659 connect(_standardcolors, SIGNAL(listChanged()), this, SLOT(updatePaletteStandard()));
660 connect(_customcolors, SIGNAL(listChanged()), this, SLOT(updatePaletteCustom()));
661
663
664 int k;
665 for (k = 0; k < _connectedColorChoosers.size(); ++k) {
666 connect(_connectedColorChoosers[k], SIGNAL(colorChanged(const QColor&)),
667 this, SLOT(internalColorChanged(const QColor&)));
668 }
669
670 connect(u->lstNames, SIGNAL(itemClicked(QListWidgetItem*)),
671 this, SLOT(internalColorNameSelected(QListWidgetItem*)));
672 connect(u->txtHex, SIGNAL(textChanged(const QString&)),
673 this, SLOT(internalColorNameSet(const QString&)));
674
675 QPalette p = u->txtHex->palette();
676 u->txtHex->setProperty("paletteDefault", QVariant::fromValue<QPalette>(p));
677 p.setColor(QPalette::Base, QColor(255,169, 184,128));
678 u->txtHex->setProperty("paletteInvalidInput", QVariant::fromValue<QPalette>(p));
679
680
681 connect(u->btnAddCustomColor, SIGNAL(clicked()),
682 this, SLOT(setCurrentToCustomColor()));
683
684 QStringList colornames = QColor::colorNames();
685 for (k = 0; k < colornames.size(); ++k) {
686 QPixmap colsample(16, 16);
687 colsample.fill(QColor(colornames[k]));
688 new QListWidgetItem(QIcon(colsample), colornames[k], u->lstNames);
689 }
690
691 internalColorChanged(_color);
692}
693
695{
696 QColor newcolor = wanted_newcolor;
697 if (!_alphaenabled)
698 newcolor.setAlpha(255);
699
700 int k;
701 for (k = 0; k < _connectedColorChoosers.size(); ++k) {
702 _connectedColorChoosers[k]->blockSignals(true);
703 _connectedColorChoosers[k]->setProperty("color", QVariant(newcolor));
704 _connectedColorChoosers[k]->blockSignals(false);
705 }
706 QString newcolorname = newcolor.name();
707 if (u->txtHex->text() != newcolorname) {
708 u->txtHex->blockSignals(true);
709 u->txtHex->setText(newcolorname);
710 u->txtHex->blockSignals(false);
711 }
712
713 _color = newcolor;
714
715 emit colorChanged(newcolor);
716}
717
719{
720 if (!item)
721 return;
722 QColor color(item->text());
724}
725
727{
728 klfDbg("name set: "<<n) ;
729 QString name = n;
730 static QRegExp rx("\\#?[0-9A-Fa-f]{6}");
731 bool validinput = false;
732 bool setcolor = false;
733 int listselect = -1;
735 if (rx.exactMatch(name)) {
736 if (name[0] != QLatin1Char('#'))
737 name = "#"+name;
738 validinput = setcolor = true;
739 color = QColor(name);
740 } else {
741 // try to match a color name, or the beginning of a color name
742 int k;
743 for (k = 0; k < u->lstNames->count(); ++k) {
744 QString s = u->lstNames->item(k)->text();
745 if (s == name) {
746 // found an exact match. Select it and set color
747 validinput = true;
748 listselect = k;
749 setcolor = true;
750 color = QColor(name);
751 break;
752 }
753 if (s.startsWith(n)) {
754 // found a matching name. Just select it for user feedback
755 validinput = true;
756 listselect = k;
757 setcolor = false;
758 break;
759 }
760 }
761 }
762 // now set the background color of the text input correctly (valid input or not)
763 if (!validinput) {
764 u->txtHex->setProperty("invalidInput", true);
765 u->txtHex->setStyleSheet(u->txtHex->styleSheet()); // style sheet recalc
766 u->txtHex->setPalette(u->txtHex->property("paletteInvalidInput").value<QPalette>());
767 } else {
768 u->txtHex->setProperty("invalidInput", QVariant());
769 u->txtHex->setStyleSheet(u->txtHex->styleSheet()); // style sheet recalc
770 u->txtHex->setPalette(u->txtHex->property("paletteDefault").value<QPalette>());
771 }
772 // select the appropriate list item if needed
773 if (listselect >= 0) {
774 u->lstNames->blockSignals(true);
775 u->lstNames->setCurrentRow(listselect, QItemSelectionModel::ClearAndSelect);
776 u->lstNames->blockSignals(false);
777 }
778 if (setcolor)
780}
781
783{
784 if (color == _color)
785 return;
786 if (!_alphaenabled && color.rgb() == _color.rgb())
787 return;
788
790}
791
793{
794 _alphaenabled = enabled;
795 u->spnAlpha->setVisible(enabled);
796 u->lblAlpha->setVisible(enabled);
797 u->mAlphaPane->setVisible(enabled);
798 u->lblsAlpha->setVisible(enabled);
799 u->mAlphaSlider->setVisible(enabled);
800 if (!enabled) {
801 _color.setAlpha(255);
802 setColor(_color);
803 }
804}
805
806void KLFColorChooseWidget::fillPalette(KLFColorList *colorlist, QWidget *w)
807{
808 KLF_DEBUG_BLOCK(KLF_FUNC_NAME) ;
809 klfDbg("colorlist is "<<colorlist<<", _customcolors is "<<_customcolors<<", _recentcolors is "<<_recentcolors) ;
810 int k;
811 // KLFGridFlowLayout *lyt = dynamic_cast<KLFGridFlowLayout*>( w->layout() );
812 // KLF_ASSERT_NOT_NULL(lyt, "Layout is not a KLFGridFlowLayout !", return; ) ;
813 KLFFlowLayout *lyt = dynamic_cast<KLFFlowLayout*>( w->layout() );
814 KLF_ASSERT_NOT_NULL(lyt, "Layout is not a KLFFlowLayout !", return; ) ;
815
816 lyt->clearAll();
817 for (k = 0; k < colorlist->list.size(); ++k) {
818 klfDbg("Adding a KLFColorClickSquare for color: "<<colorlist->list[k]) ;
819
820 KLFColorClickSquare *sq = new KLFColorClickSquare(colorlist->list[k], 12,
821 (colorlist == _customcolors ||
822 colorlist == _recentcolors),
823 w);
824 connect(sq, SIGNAL(colorActivated(const QColor&)),
825 this, SLOT(internalColorChanged(const QColor&)));
826 connect(sq, SIGNAL(wantRemoveColor(const QColor&)),
827 colorlist, SLOT(removeColor(const QColor&)));
828 // lyt->insertGridFlowWidget(sq);
829 lyt->addWidget(sq);
830 sq->show();
831 }
832 w->adjustSize(); // the widget is inside a scroll area
833}
834
836{
837 _customcolors->addColor(_color);
839}
840
847
849{
850 fillPalette(_recentcolors, u->mRecentColorsPalette);
851}
853{
854 fillPalette(_standardcolors, u->mStandardColorsPalette);
855}
857{
858 fillPalette(_customcolors, u->mCustomColorsPalette);
859}
860
861
862
863// static
865{
866 if ( _recentcolors == 0 )
867 _recentcolors = new KLFColorList(128);
868 if ( _standardcolors == 0 )
869 _standardcolors = new KLFColorList(256);
870 if ( _customcolors == 0 )
871 _customcolors = new KLFColorList(128);
872}
873
874// static
876{
878 QList<QColor>::iterator it = _recentcolors->list.begin();
879 while (it != _recentcolors->list.end()) {
880 if ( (*it) == col )
881 it = _recentcolors->list.erase(it);
882 else
883 ++it;
884 }
885 _recentcolors->list.append(col);
886
887 if (_recentcolors->list.size() > MAX_RECENT_COLORS) {
888 _recentcolors->list.removeAt(0);
889 }
890 _recentcolors->notifyListChanged();
891}
892
893
894
895// -------------------------------------------------------------------
896
897
898
899void KLFColorList::addColor(const QColor& color)
900{
901 int i;
902 if ( (i = list.indexOf(color)) >= 0 )
903 list.removeAt(i);
904
905 list.append(color);
906 while (list.size() >= _maxsize)
907 list.pop_front();
908
909 emit listChanged();
910}
911
912void KLFColorList::removeColor(const QColor& color)
913{
914 bool changed = false;
915 int i;
916 if ( (i = list.indexOf(color)) >= 0 ) {
917 list.removeAt(i);
918 changed = true;
919 }
920 if (changed)
921 emit listChanged();
922}
923
924// static
925KLFColorList *KLFColorChooser::_colorlist = NULL;
926
927QStyle *KLFColorChooser::mReplaceButtonStyle = NULL;
928
930 : QPushButton(parent), _color(0,0,0,255), _pix(), _allowdefaultstate(false),
931 _defaultstatestring(tr("[ Default ]")), _autoadd(true), _size(120, 20),
932 _xalignfactor(0.5f), _yalignfactor(0.5f), _alphaenabled(true), mMenu(NULL), menuRelFont(NULL)
933{
934 ensureColorListInstance();
935 connect(_colorlist, SIGNAL(listChanged()), this, SLOT(_makemenu()));
936
937 _makemenu();
938 _setpix();
939
940#ifdef KLF_WS_MAC
941 if ( mReplaceButtonStyle == NULL ) {
942 mReplaceButtonStyle = QStyleFactory::create("fusion");//new QPlastiqueStyle; // deprecated in Qt5
943 }
944 setStyle(mReplaceButtonStyle);
945#endif
946}
947
948
952
953
955{
956 return _color;
957}
958
960{
961 //KLF_DEBUG_BLOCK(KLF_FUNC_NAME) ;
962
963 // inspired by QPushButton::sizeHint() in qpushbutton.cpp
964
965 ensurePolished();
966
967 int w = 0, h = 0;
968 QStyleOptionButton opt;
969 initStyleOption(&opt);
970
971 // calculate contents size...
972 w = _pix.width()+4;
973 h = _pix.height()+2;
974
975 opt.rect.setSize(QSize(w,h));
976
977 if (menu())
978 w += KLF_DEBUG_TEE( style()->pixelMetric(QStyle::PM_MenuButtonIndicator, &opt, this) );
979
980 //klfDbg("itermediate stage: w="<<w);
981
982 QSize hint = style()->sizeFromContents(QStyle::CT_PushButton, &opt, QSize(w, h), this);
983 //klfDbg("before expansion to app/globalstrut; hint="<<hint) ;
984 hint = hint.expandedTo(QApplication::globalStrut());
985 //klfDbg("mename="<<objectName()<<" _pix size="<<_pix.size()<<" _size="<<_size<<" color="<<_color<<"; sizeHint="<<hint) ;
986 return hint;
987}
988
990{
991 if ( ! _allowdefaultstate && ! col.isValid() )
992 return;
993
994 if (_color == col)
995 return;
996
997 _color = col;
998 _setpix();
999
1000 if (_autoadd && _color.isValid()) {
1001 _colorlist->addColor(_color);
1002 }
1003 emit colorChanged(_color);
1004}
1005
1010
1012{
1013 _allowdefaultstate = allow;
1014 _makemenu();
1015}
1017{
1018 _defaultstatestring = str;
1019 _makemenu();
1020}
1021
1023{
1024 _autoadd = autoadd;
1025}
1027{
1028 _size = size;
1029 _setpix();
1030 if (size.isValid())
1031 setMinimumSize(sizeHint());
1032 else
1033 setMinimumSize(QSize());
1034}
1036{
1037 _xalignfactor = xalignfactor;
1038}
1039void KLFColorChooser::setPixYAlignFactor(float yalignfactor) {
1040 _yalignfactor = yalignfactor;
1041}
1042
1044{
1045 _alphaenabled = on;
1046 _makemenu();
1047}
1048
1050{
1051 // prefer our own color selection dialog
1052 QColor col = KLFColorDialog::getColor(_color, _alphaenabled, this);
1053 // QColor col = QColorDialog::getColor(_color, this);
1054 if ( ! col.isValid() )
1055 return;
1056
1057 setColor(col);
1058}
1059
1061{
1062 QColor c = sender()->property("setColor").value<QColor>();
1063 setColor(c);
1064}
1065
1067{
1068 if (mMenu) {
1069 setMenu(0);
1070 mMenu->deleteLater();
1071 }
1072
1073 QSize menuIconSize = QSize(16,16);
1074
1075 mMenu = new QMenu(this);
1076
1077 if (_allowdefaultstate) {
1078 mMenu->addAction(QIcon(colorPixmap(QColor(), menuIconSize)), _defaultstatestring,
1079 this, SLOT(setDefaultColor()));
1080 mMenu->addSeparator();
1081 }
1082
1083 int n, k, nk;
1084 ensureColorListInstance();
1085 n = _colorlist->list.size();
1086 for (k = 0; k < n; ++k) {
1087 nk = n - k - 1;
1088 QColor col = _colorlist->list[nk];
1089 if (!_alphaenabled)
1090 col.setAlpha(255);
1091 QString collabel;
1092 if (col.alpha() == 255)
1093 collabel = QString("%1").arg(col.name());
1094 else
1095 collabel = QString("%1 (%2%)").arg(col.name()).arg((int)(100.0*col.alpha()/255.0+0.5));
1096
1097 QAction *a = mMenu->addAction(QIcon(colorPixmap(col, menuIconSize)), collabel,
1098 this, SLOT(setSenderPropertyColor()));
1099 a->setIconVisibleInMenu(true);
1100 a->setProperty("setColor", QVariant::fromValue<QColor>(col));
1101 }
1102 if (k > 0)
1103 mMenu->addSeparator();
1104
1105 mMenu->addAction(tr("Custom ..."), this, SLOT(requestColor()));
1106
1107 if (menuRelFont != NULL)
1108 delete menuRelFont;
1109 menuRelFont = new KLFRelativeFont(this, mMenu);
1110 menuRelFont->setRelPointSize(-1);
1111 setMenu(mMenu);
1112}
1113
1115{
1116 QPushButton::paintEvent(e);
1117 QPainter p(this);
1118 p.setClipRect(e->rect());
1119 p.drawPixmap(QPointF(_xalignfactor*(width()-_pix.width()), _yalignfactor*(height()-_pix.height())), _pix);
1120}
1121
1122void KLFColorChooser::_setpix()
1123{
1124 // if (_color.isValid()) {
1125 _pix = colorPixmap(_color, _size);
1126 // DON'T setIcon() because we draw ourselves ! see paintEvent() !
1127 // setIconSize(_pix.size());
1128 // setIcon(_pix);
1129 setText("");
1130 // } else {
1131 // _pix = QPixmap();
1132 // setIcon(QIcon());
1133 // setIconSize(QSize(0,0));
1134 // setText("");
1135 // }
1136}
1137
1138
1139QPixmap KLFColorChooser::colorPixmap(const QColor& color, const QSize& size)
1140{
1141 QPixmap pix = QPixmap(size);
1142 pix.fill(Qt::transparent);
1143 if (color.isValid()) {
1144 pix.fill(Qt::black);
1145 QPainter p(&pix);
1146 // background: a checker grid to distinguish transparency
1147 p.fillRect(0,0,pix.width(),pix.height(), QBrush(QPixmap(":/pics/checker.png")));
1148 // and fill with color
1149 p.fillRect(0,0,pix.width(),pix.height(), QBrush(color));
1150 // pix.fill(color);
1151 } else {
1152 /*
1153 // draw "transparent"-representing pixmap
1154 pix.fill(QColor(127,127,127,80));
1155 QPainter p(&pix);
1156 p.setPen(QPen(QColor(255,0,0), 2));
1157 p.drawLine(0,0,size.width(),size.height());
1158 */
1159 // draw "default"/"transparent" pixmap
1160 QPainter p(&pix);
1161 p.setRenderHint(QPainter::Antialiasing);
1162 // QLinearGradient pgrad(0, 0, 0, 1);
1163 // pgrad.setColorAt(0, QColor(160,160,185));
1164 // pgrad.setColorAt(1, QColor(220,220,230));
1165 // pgrad.setCoordinateMode(QGradient::StretchToDeviceMode);
1166 // p.fillRect(0, 0, pix.width(), pix.height(), pgrad);
1167
1168 QPen pen(QColor(127,0,0), 2.f, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin);
1169 p.setPen(pen);
1170 // p.drawLine(QPointF(0,0), QPointF(pix.width(), pix.height()));
1171 p.drawLine(QPointF(0,pix.height()), QPointF(pix.width(), 0));
1172
1173 /*
1174 // p.scale((qreal)pix.width(), (qreal)pix.height());
1175
1176 QRectF dashrect(QPointF(0.34*pix.width(), 0.40*pix.height()),
1177 QPointF(0.67*pix.width(), 0.60*pix.height()));
1178 // QRectF dashrect(QPointF(0.1*pix.width(), 0.10*pix.height()),
1179 // QPointF(0.9*pix.width(), 0.90*pix.height()));
1180 p.setClipRect(dashrect);
1181 p.translate(dashrect.topLeft());
1182 p.scale(dashrect.width(), dashrect.height());
1183
1184 p.drawLine(0,0,1,1);
1185
1186 QRadialGradient dashgrad(QPointF(0.75, 0.3), 0.4, QPointF(0.95, 0.2));
1187 dashgrad.setColorAt(0, QColor(180, 180, 240));
1188 dashgrad.setColorAt(1, QColor(40, 40, 50));
1189 dashgrad.setCoordinateMode(QGradient::LogicalMode);
1190 p.setPen(Qt::NoPen);
1191 p.setBrush(dashgrad);
1192 p.fillRect(QRectF(0,0,1,1), dashgrad);
1193 */
1194
1195 // qreal yrad = 2;
1196 // qreal xrad = 2;//yrad * dashrect.height()/dashrect.width();
1197 // p.drawRoundedRect(QRectF(0,0,1,1), xrad, yrad, Qt::AbsoluteSize);
1198
1199 /*
1200 // QLinearGradient pdashgrad(0, 0, 1, 0);
1201 // pdashgrad.setColorAt(0, QColor(120, 0, 40));
1202 // pdashgrad.setColorAt(1, QColor(120, 0, 40));
1203 QRadialGradient dashgrad(QPointF(1.75, 1.9), 0.6, QPointF(1.9, 1.8));
1204 // QLinearGradient dashgrad(QPointF(0,0), QPointF(1,0));
1205 dashgrad.setColorAt(0, QColor(255, 0, 0));
1206 dashgrad.setColorAt(1, QColor(0, 255, 0));
1207 dashgrad.setCoordinateMode(QGradient::StretchToDeviceMode);
1208 // dashgrad.setColorAt(0, QColor(255, 255, 255));
1209 // dashgrad.setColorAt(1, QColor(40, 40, 50));
1210 // QPen pen(QBrush(dashgrad), pix.height()/5.f, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin);
1211 p.setPen(Qt::NoPen);
1212 p.setBrush(dashgrad);
1213 QRectF dashrect(QPointF(0.34*pix.width(), 0.40*pix.height()),
1214 QPointF(0.67*pix.width(), 0.65*pix.height()));
1215 qreal rad = pix.height()/8.;
1216 p.drawRoundedRect(dashrect, 1.2*rad, rad, Qt::AbsoluteSize);
1217 // p.drawLine(pix.width()*3./8., pix.height()/2., pix.width()*5./8., pix.height()/2.);
1218 // p.fillRect(0, 0, pix.width(), pix.height(), dashgrad); // debug this gradient
1219 */
1220 }
1221 return pix;
1222}
1223
1224
1225
1226// static
1227int KLFColorChooser::staticUserMaxColors = 10; // default of 10 colors
1228
1229
1230// static
1232{
1233 staticUserMaxColors = maxColors;
1234}
1235
1236// static
1237void KLFColorChooser::ensureColorListInstance()
1238{
1239 if ( _colorlist == 0 )
1240 _colorlist = new KLFColorList(staticUserMaxColors);
1241}
1242// static
1244{
1245 ensureColorListInstance();
1246 _colorlist->list = colors;
1247 _colorlist->notifyListChanged();
1248}
1249
1250// static
1252{
1253 ensureColorListInstance();
1254 QList<QColor> l = _colorlist->list;
1255 return l;
1256}
1257
1258
1259
1260
virtual void internalColorNameSet(const QString &colorname)
virtual void internalColorChanged(const QColor &newcolor)
void colorChanged(const QColor &color)
static void setRecentCustomColors(QList< QColor > recentcolors, QList< QColor > customcolors)
static QList< QColor > customColors()
static QList< QColor > recentColors()
static void addRecentColor(const QColor &col)
void setAlphaEnabled(bool alpha_enabled)
static void ensureColorListsInstance()
void setColor(const QColor &color)
virtual void internalColorNameSelected(QListWidgetItem *item)
KLFColorChooseWidget(QWidget *parent=0)
virtual void mousePressEvent(QMouseEvent *e)
void colorChanged(const QColor &color)
void setPaneType(const QString &panetype)
virtual void paintEvent(QPaintEvent *e)
virtual void mouseMoveEvent(QMouseEvent *e)
virtual void keyPressEvent(QKeyEvent *e)
void setColor(const QColor &newcolor)
KLFColorChooseWidgetPane(QWidget *parent=0)
virtual void wheelEvent(QWheelEvent *e)
void setAlphaEnabled(bool alpha_enabled)
KLFColorChooser(QWidget *parent)
void setAutoAddToList(bool autoadd)
void paintEvent(QPaintEvent *event)
void setPixXAlignFactor(float xalignfactor)
void setAllowDefaultState(bool allow)
void colorChanged(const QColor &newcolor)
void setShowSize(const QSize &size)
static QList< QColor > colorList()
static void setUserMaxColors(int maxcolors)
void setPixYAlignFactor(float yalignfactor)
void setColor(const QColor &color)
virtual QSize sizeHint() const
void setDefaultStateString(const QString &str)
static void setColorList(const QList< QColor > &colorlist)
void setSqSize(int sqsize)
void paintEvent(QPaintEvent *event)
void resizeEvent(QResizeEvent *event)
void mousePressEvent(QMouseEvent *event)
void wantRemoveColor(const QColor &color)
void keyPressEvent(QKeyEvent *event)
void setRemovable(bool removable)
KLFColorClickSquare(QColor color=Qt::white, int size=16, bool removable=true, QWidget *parent=0)
void contextMenuEvent(QContextMenuEvent *event)
void setColorComponent(const QString &component)
KLFColorComponentSpinBox(QWidget *parent)
void colorChanged(const QColor &color)
void setColor(const QColor &color)
static int valueMax(const QString &component)
QColor colorFromValues(QColor color_base, int value_a, int value_b=-1)
static int valueFromNewColor(const QColor &color, const QString &component)
int valueAFromNewColor(const QColor &color) const
bool refreshColorFromInternalValues(int value_a, int value_b=-1)
int valueBFromNewColor(const QColor &color) const
A dialog to let the user select a color.
KLFColorChooseWidget * colorChooseWidget()
static QColor getColor(QColor startwith=Qt::black, bool alphaenabled=true, QWidget *parent=0)
void setColor(const QColor &color)
virtual ~KLFColorDialog()
KLFColorDialog(QWidget *parent=0)
A Layout that places widgets left to right, top to bottom.
void clearAll(bool deleteItems=true)
virtual void addWidget(QWidget *w, int hstretch=0, int vstretch=0, Qt::Alignment align=0)
void setFlush(Flush f)
@ FlushBegin
Leave all extra space at end of line.
KLFGridFlowLayout(int columns, QWidget *parent)
virtual void insertGridFlowWidget(QWidget *w, Qt::Alignment align=0)
QList< QWidget * > mGridFlowWidgets
Definition klfguiutil.h:395
void setRelPointSize(int relps)
const char * style
#define KLF_DEBUG_BLOCK(msg)
Utility to debug the execution of a block.
Definition klfdebug.h:152
#define KLF_ASSERT_NOT_NULL(ptr, msg, failaction)
Asserting Non-NULL pointers (NON-FATAL)
Definition klfdebug.h:210
#define KLF_DEBUG_TEE(expr)
Print the value of expression and return it.
Definition klfdebug.h:154
#define klfDbg(streamableItems)
print debug stream items
Definition klfdebug.h:158
Base declarations for klatexformula and some utilities.
const char * constData() const
int alpha() const
int blue() const
QStringList colorNames()
int green() const
int hue() const
bool isValid() const
QString name() const
int red() const
QRgb rgb() const
int saturation() const
void setAlpha(int alpha)
void setHsv(int h, int s, int v, int a)
void setRgb(int r, int g, int b, int a)
int value() const
const QPoint & globalPos() const
void accept()
int height() const
void setPixel(int x, int y, uint index_or_rgb)
int width() const
Qt::KeyboardModifiers modifiers() const
int key() const
Qt::KeyboardModifiers modifiers() const
void append(const T &value)
void clear()
int size() const
QPoint pos() const
void drawPixmap(const QRectF &target, const QPixmap &pixmap, const QRectF &source)
void fillRect(const QRectF &rectangle, const QBrush &brush)
void setClipRect(const QRectF &rectangle, Qt::ClipOperation operation)
const QRect & rect() const
void setColor(ColorGroup group, ColorRole role, const QColor &color)
void fill(const QColor &color)
int height() const
int width() const
int x() const
int y() const
bool exactMatch(const QString &str) const
QSize expandedTo(const QSize &otherSize) const
bool isValid() const
QString arg(qlonglong a, int fieldWidth, int base, QChar fillChar) const
bool isEmpty() const
QStringList split(const QString &sep, SplitBehavior behavior, Qt::CaseSensitivity cs) const
bool startsWith(const QString &s, Qt::CaseSensitivity cs) const
QByteArray toLocal8Bit() const
QString toLower() const
bool contains(const QString &str, Qt::CaseSensitivity cs) const
typedef Alignment
QVariant fromValue(const T &value)
int delta() const
Qt::Orientation orientation() const

Generated by doxygen 1.12.0