Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qcolordialog.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3// Qt-Security score:significant reason:default
4
5#include "qcolordialog.h"
6
7#if QT_CONFIG(accessibility)
8#include "qaccessible.h"
9#endif
10#include "qapplication.h"
11#include "qdrawutil.h"
12#include "qevent.h"
13#include "qimage.h"
14#if QT_CONFIG(draganddrop)
15#include <qdrag.h>
16#endif
17#include "qlabel.h"
18#include "qlayout.h"
19#include "qlineedit.h"
20#if QT_CONFIG(menu)
21#include "qmenu.h"
22#endif
23#include "qpainter.h"
24#include "qpixmap.h"
25#include "qpushbutton.h"
26#if QT_CONFIG(regularexpression)
27#include <qregularexpression.h>
28#endif
29#if QT_CONFIG(settings)
30#include "qsettings.h"
31#endif
32#include "qsharedpointer.h"
33#include "qstyle.h"
34#include "qstyleoption.h"
35#include "qvalidator.h"
36#include "qmimedata.h"
37#include "qspinbox.h"
39#include "qscreen.h"
40#include "qcursor.h"
41#include "qtimer.h"
42#include "qwindow.h"
43
44#include "private/qdialog_p.h"
45#include "private/qcolorwell_p.h"
46
47#include <qpa/qplatformintegration.h>
48#include <qpa/qplatformservices.h>
49#include <private/qguiapplication_p.h>
50
51#include <QtCore/qpointer.h>
52
53#include <algorithm>
54
55QT_BEGIN_NAMESPACE
56
57using namespace Qt::StringLiterals;
58
59namespace QtPrivate {
61class QColorPicker;
62class QColorShower;
64} // namespace QtPrivate
65
70
72{
73 Q_DECLARE_PUBLIC(QColorDialog)
74
75public:
81
83#ifdef Q_OS_WIN32
84 , updateTimer(0)
85#endif
86 {}
87
89 { return static_cast<QPlatformColorDialogHelper *>(platformHelper()); }
90
91 void init(const QColor &initial);
94 QColor currentQColor() const;
95 void setCurrentColor(const QColor &color, SetColorMode setColorMode = SetColorAll);
96 void setCurrentRgbColor(QRgb rgb);
97 void setCurrentQColor(const QColor &color);
98 bool selectColor(const QColor &color);
99 QColor grabScreenColor(const QPoint &p);
100
101 int currentAlpha() const;
102 void setCurrentAlpha(int a);
103 void showAlpha(bool b);
104 bool isAlphaVisible() const;
107
108 void addCustom();
109 void _q_setCustom(int index, QRgb color);
110
111 void newHsv(int h, int s, int v);
112 void newColorTypedIn(QRgb rgb);
113 void nextCustom(int, int);
114 void newCustom(int, int);
115 void newStandard(int, int);
119 void updateColorPicking(const QPoint &pos);
121 bool handleColorPickingMouseMove(QMouseEvent *e);
123 bool handleColorPickingKeyPress(QKeyEvent *e);
124
126 void setVisible(bool visible) override;
127
130
139 QPushButton *ok;
140 QPushButton *cancel;
141 QPushButton *addCusBt;
142 QPushButton *eyeDropperButton = nullptr;
150
154#ifdef Q_OS_WIN32
157#endif
158
159private:
160 virtual void initHelper(QPlatformDialogHelper *h) override;
161 virtual void helperPrepareShow(QPlatformDialogHelper *h) override;
162};
163
164//////////// QWellArray BEGIN
165
166void QWellArray::paintEvent(QPaintEvent *e)
167{
168 QRect r = e->rect();
169 int cx = r.x();
170 int cy = r.y();
171 int ch = r.height();
172 int cw = r.width();
173 int colfirst = columnAt(cx);
174 int collast = columnAt(cx + cw);
175 int rowfirst = rowAt(cy);
176 int rowlast = rowAt(cy + ch);
177
178 if (isRightToLeft()) {
179 int t = colfirst;
180 colfirst = collast;
181 collast = t;
182 }
183
184 QPainter painter(this);
185 QPainter *p = &painter;
186 QRect rect(0, 0, cellWidth(), cellHeight());
187
188
189 if (collast < 0 || collast >= ncols)
190 collast = ncols-1;
191 if (rowlast < 0 || rowlast >= nrows)
192 rowlast = nrows-1;
193
194 // Go through the rows
195 for (int r = rowfirst; r <= rowlast; ++r) {
196 // get row position and height
197 int rowp = rowY(r);
198
199 // Go through the columns in the row r
200 // if we know from where to where, go through [colfirst, collast],
201 // else go through all of them
202 for (int c = colfirst; c <= collast; ++c) {
203 // get position and width of column c
204 int colp = columnX(c);
205 // Translate painter and draw the cell
206 rect.translate(colp, rowp);
207 paintCell(p, r, c, rect);
208 rect.translate(-colp, -rowp);
209 }
210 }
211}
212
213QWellArray::QWellArray(int rows, int cols, QWidget *parent)
214 : QWidget(parent)
215 ,nrows(rows), ncols(cols)
216{
217 setFocusPolicy(Qt::StrongFocus);
218 cellw = 28;
219 cellh = 24;
220 curCol = 0;
221 curRow = 0;
222 selCol = -1;
223 selRow = -1;
224}
225
226QSize QWellArray::sizeHint() const
227{
228 ensurePolished();
229 return gridSize().boundedTo(QSize(640, 480));
230}
231
232
233void QWellArray::paintCell(QPainter* p, int row, int col, const QRect &rect)
234{
235 int b = 3; //margin
236
237 const QPalette & g = palette();
238 QStyleOptionFrame opt;
239 opt.initFrom(this);
240 int dfw = style()->pixelMetric(QStyle::PM_DefaultFrameWidth, &opt, this);
241 opt.lineWidth = dfw;
242 opt.midLineWidth = 1;
243 opt.rect = rect.adjusted(b, b, -b, -b);
244 opt.palette = g;
245 opt.state = QStyle::State_Enabled | QStyle::State_Sunken;
246 style()->drawPrimitive(QStyle::PE_Frame, &opt, p, this);
247 b += dfw;
248
249 if ((row == curRow) && (col == curCol)) {
250 if (hasFocus()) {
251 QStyleOptionFocusRect opt;
252 opt.palette = g;
253 opt.rect = rect;
254 opt.state = QStyle::State_None | QStyle::State_KeyboardFocusChange;
255 style()->drawPrimitive(QStyle::PE_FrameFocusRect, &opt, p, this);
256 }
257 }
258 paintCellContents(p, row, col, opt.rect.adjusted(dfw, dfw, -dfw, -dfw));
259}
260
261/*
262 Reimplement this function to change the contents of the well array.
263 */
264void QWellArray::paintCellContents(QPainter *p, int row, int col, const QRect &r)
265{
266 Q_UNUSED(row);
267 Q_UNUSED(col);
268 p->fillRect(r, Qt::white);
269 p->setPen(Qt::black);
270 p->drawLine(r.topLeft(), r.bottomRight());
271 p->drawLine(r.topRight(), r.bottomLeft());
272}
273
274void QWellArray::mousePressEvent(QMouseEvent *e)
275{
276 // The current cell marker is set to the cell the mouse is pressed in
277 QPoint pos = e->position().toPoint();
278 setCurrent(rowAt(pos.y()), columnAt(pos.x()));
279}
280
281void QWellArray::mouseReleaseEvent(QMouseEvent * /* event */)
282{
283 // The current cell marker is set to the cell the mouse is clicked in
284 setSelected(curRow, curCol);
285}
286
287
288/*
289 Sets the cell currently having the focus. This is not necessarily
290 the same as the currently selected cell.
291*/
292
293void QWellArray::setCurrent(int row, int col)
294{
295 if ((curRow == row) && (curCol == col))
296 return;
297
298 if (row < 0 || col < 0 || row >= nrows || col >= ncols)
299 row = col = -1;
300
301 int oldRow = curRow;
302 int oldCol = curCol;
303
304 curRow = row;
305 curCol = col;
306
307 updateCell(oldRow, oldCol);
308 updateCell(curRow, curCol);
309
310 emit currentChanged(curRow, curCol);
311 sendAccessibleChildFocusEvent();
312}
313
314/*
315 Sets the currently selected cell to \a row, \a column. If \a row or
316 \a column are less than zero, the current cell is unselected.
317
318 Does not set the position of the focus indicator.
319*/
320void QWellArray::setSelected(int row, int col)
321{
322 int oldRow = selRow;
323 int oldCol = selCol;
324
325 if (row < 0 || col < 0)
326 row = col = -1;
327
328 selCol = col;
329 selRow = row;
330
331 updateCell(oldRow, oldCol);
332 updateCell(selRow, selCol);
333 if (row >= 0)
334 emit selected(row, col);
335
336#if QT_CONFIG(menu)
337 if (isVisible() && qobject_cast<QMenu*>(parentWidget()))
338 parentWidget()->close();
339#endif
340}
341
342void QWellArray::focusInEvent(QFocusEvent*)
343{
344 updateCell(curRow, curCol);
345 emit currentChanged(curRow, curCol);
346 sendAccessibleChildFocusEvent();
347}
348
349
350void QWellArray::focusOutEvent(QFocusEvent*)
351{
352 updateCell(curRow, curCol);
353}
354
355void QWellArray::keyPressEvent(QKeyEvent* e)
356{
357 switch(e->key()) { // Look at the key code
358 case Qt::Key_Left: // If 'left arrow'-key,
359 if (curCol > 0) // and cr't not in leftmost col
360 setCurrent(curRow, curCol - 1); // set cr't to next left column
361 break;
362 case Qt::Key_Right: // Correspondingly...
363 if (curCol < numCols()-1)
364 setCurrent(curRow, curCol + 1);
365 break;
366 case Qt::Key_Up:
367 if (curRow > 0)
368 setCurrent(curRow - 1, curCol);
369 break;
370 case Qt::Key_Down:
371 if (curRow < numRows()-1)
372 setCurrent(curRow + 1, curCol);
373 break;
374 case Qt::Key_Space:
375 setSelected(curRow, curCol);
376 break;
377 default: // If not an interesting key,
378 e->ignore(); // we don't accept the event
379 return;
380 }
381}
382
383void QWellArray::sendAccessibleChildFocusEvent()
384{
385#if QT_CONFIG(accessibility)
386 if (!QAccessible::isActive())
387 return;
388
389 if (hasFocus() && curRow >= 0 && curCol >= 0) {
390 const int itemIndex = index(curRow, curCol);
391 QAccessibleEvent event(this, QAccessible::Focus);
392 event.setChild(itemIndex);
393 QAccessible::updateAccessibility(&event);
394 }
395#endif
396}
397
398//////////// QWellArray END
399
400namespace QtPrivate {
401
402// Event filter to be installed on the dialog while in color-picking mode.
404public:
405 explicit QColorPickingEventFilter(QColorDialogPrivate *dp, QObject *parent) : QObject(parent), m_dp(dp) {}
406
407 bool eventFilter(QObject *, QEvent *event) override
408 {
409 switch (event->type()) {
410 case QEvent::MouseMove:
411 return m_dp->handleColorPickingMouseMove(static_cast<QMouseEvent *>(event));
412 case QEvent::MouseButtonRelease:
413 return m_dp->handleColorPickingMouseButtonRelease(static_cast<QMouseEvent *>(event));
414 case QEvent::KeyPress:
415 return m_dp->handleColorPickingKeyPress(static_cast<QKeyEvent *>(event));
416 default:
417 break;
418 }
419 return false;
420 }
421
422 void applicationStateChanged(Qt::ApplicationState state)
423 {
424 if (state != Qt::ApplicationActive)
426 }
427
428private:
430};
431
432} // namespace QtPrivate
433
434/*
435 Internal event filter used to adjust dialog options during widget polish.
436
437 Enables DontUseNativeDialog automatically when QColorDialog is subclassed
438 and no explicit options were set by the user.
439*/
441{
442public:
443 explicit QColorPolishFilter(QColorDialog *cd) : QObject(cd)
444 {
445 cd->installEventFilter(this);
446 }
447
448 bool eventFilter(QObject *obj, QEvent *event) override
449 {
450 if (event->type() == QEvent::Polish ) {
451 Q_ASSERT(qobject_cast<QColorDialog *>(obj));
452 auto *cd = static_cast<QColorDialog *>(obj);
453 auto *d = static_cast<QColorDialogPrivate *>(QObjectPrivate::get(cd));
454
455 if (cd->metaObject() != &QColorDialog::staticMetaObject && !d->optionsExplicitlySet)
456 cd->setOption(QColorDialog::DontUseNativeDialog);
457
458 deleteLater(); // no longer needed after first polish
459 }
460 return false;
461 }
462};
463
464/*!
465 Returns the number of custom colors supported by QColorDialog. All
466 color dialogs share the same custom colors.
467*/
468int QColorDialog::customCount()
469{
470 return QColorDialogOptions::customColorCount();
471}
472
473/*!
474 Returns the custom color at the given \a index as a QColor value.
475*/
476QColor QColorDialog::customColor(int index)
477{
478 return QColor(QColorDialogOptions::customColor(index));
479}
480
481/*!
482 Sets the custom color at \a index to the QColor \a color value.
483
484 \note This function does not apply to the Native Color Dialog on the
485 \macos platform. If you still require this function, use the
486 QColorDialog::DontUseNativeDialog option.
487*/
488void QColorDialog::setCustomColor(int index, QColor color)
489{
490 QColorDialogOptions::setCustomColor(index, color.rgba());
491}
492
493/*!
494 \since 5.0
495
496 Returns the standard color at the given \a index as a QColor value.
497*/
498QColor QColorDialog::standardColor(int index)
499{
500 return QColor(QColorDialogOptions::standardColor(index));
501}
502
503/*!
504 Sets the standard color at \a index to the QColor \a color value.
505
506 \note This function does not apply to the Native Color Dialog on the
507 \macos platform. If you still require this function, use the
508 QColorDialog::DontUseNativeDialog option.
509*/
510void QColorDialog::setStandardColor(int index, QColor color)
511{
512 QColorDialogOptions::setStandardColor(index, color.rgba());
513}
514
515static inline void rgb2hsv(QRgb rgb, int &h, int &s, int &v)
516{
517 QColor c;
518 c.setRgb(rgb);
519 c.getHsv(&h, &s, &v);
520}
521
522void QColorWell::paintCellContents(QPainter *p, int row, int col, const QRect &r)
523{
524 int i = row + col*numRows();
525 p->fillRect(r, QColor(values[i]));
526}
527
528void QColorWell::mousePressEvent(QMouseEvent *e)
529{
530 oldCurrent = QPoint(selectedRow(), selectedColumn());
531 QWellArray::mousePressEvent(e);
532 mousePressed = true;
533 pressPos = e->position().toPoint();
534}
535
536void QColorWell::mouseMoveEvent(QMouseEvent *e)
537{
538 QWellArray::mouseMoveEvent(e);
539#if QT_CONFIG(draganddrop)
540 if (!mousePressed)
541 return;
542 if ((pressPos - e->position().toPoint()).manhattanLength() > QApplication::startDragDistance()) {
543 setCurrent(oldCurrent.x(), oldCurrent.y());
544 int i = rowAt(pressPos.y()) + columnAt(pressPos.x()) * numRows();
545 QColor col(values[i]);
546 QMimeData *mime = new QMimeData;
547 mime->setColorData(col);
548 QPixmap pix(cellWidth(), cellHeight());
549 pix.fill(col);
550 QPainter p(&pix);
551 p.drawRect(0, 0, pix.width() - 1, pix.height() - 1);
552 p.end();
553 QDrag *drg = new QDrag(this);
554 drg->setMimeData(mime);
555 drg->setPixmap(pix);
556 mousePressed = false;
557 drg->exec(Qt::CopyAction);
558 }
559#endif
560}
561
562#if QT_CONFIG(draganddrop)
563void QColorWell::dragEnterEvent(QDragEnterEvent *e)
564{
565 if (qvariant_cast<QColor>(e->mimeData()->colorData()).isValid())
566 e->accept();
567 else
568 e->ignore();
569}
570
571void QColorWell::dragLeaveEvent(QDragLeaveEvent *)
572{
573 if (hasFocus())
574 parentWidget()->setFocus();
575}
576
577void QColorWell::dragMoveEvent(QDragMoveEvent *e)
578{
579 if (qvariant_cast<QColor>(e->mimeData()->colorData()).isValid()) {
580 setCurrent(rowAt(e->position().toPoint().y()), columnAt(e->position().toPoint().x()));
581 e->accept();
582 } else {
583 e->ignore();
584 }
585}
586
587void QColorWell::dropEvent(QDropEvent *e)
588{
589 QColor col = qvariant_cast<QColor>(e->mimeData()->colorData());
590 if (col.isValid()) {
591 int i = rowAt(e->position().toPoint().y()) + columnAt(e->position().toPoint().x()) * numRows();
592 emit colorChanged(i, col.rgb());
593 e->accept();
594 } else {
595 e->ignore();
596 }
597}
598
599#endif // QT_CONFIG(draganddrop)
600
601void QColorWell::mouseReleaseEvent(QMouseEvent *e)
602{
603 if (!mousePressed)
604 return;
605 QWellArray::mouseReleaseEvent(e);
606 mousePressed = false;
607}
608
609namespace QtPrivate {
610
611class QColorPicker : public QFrame
612{
614public:
617
618 void setCrossVisible(bool visible);
619public slots:
620 void setCol(int h, int s);
621
622signals:
623 void newCol(int h, int s);
624
625protected:
626 QSize sizeHint() const override;
627 void paintEvent(QPaintEvent*) override;
628 void keyPressEvent(QKeyEvent *event) override;
629 void mouseMoveEvent(QMouseEvent *) override;
630 void mousePressEvent(QMouseEvent *) override;
631 void resizeEvent(QResizeEvent *) override;
632
633private:
634 QPoint m_pos;
635
636 QPixmap createColorsPixmap();
637 QPoint colPt(int hue, int sat);
638 int huePt(const QPoint &pt, const QSize &widgetSize);
639 int huePt(const QPoint &pt) { return huePt(pt, size()); }
640 int satPt(const QPoint &pt, const QSize &widgetSize);
641 int satPt(const QPoint &pt) { return satPt(pt, size()); }
642 void setCol(const QPoint &pt, bool notify = true);
643
644 QPixmap pix;
645 bool crossVisible;
646};
647
648} // namespace QtPrivate
649
650static int pWidth = 220;
651static int pHeight = 200;
652
653namespace QtPrivate {
654
656{
658public:
661
662public slots:
663 void setCol(int h, int s, int v);
664 void setCol(int h, int s);
665
666signals:
667 void newHsv(int h, int s, int v);
668
669protected:
670 void paintEvent(QPaintEvent*) override;
671 void keyPressEvent(QKeyEvent *event) override;
672 void mouseMoveEvent(QMouseEvent *) override;
673 void mousePressEvent(QMouseEvent *) override;
674
675private:
676 enum { foff = 3, coff = 4 }; //frame and contents offset
677 int val;
678 int hue;
679 int sat;
680
681 int y2val(int y);
682 int val2y(int val);
683 void setVal(int v);
684
685 QPixmap pix;
686};
687
688
689int QColorLuminancePicker::y2val(int y)
690{
691 int d = height() - 2*coff - 1;
692 return 255 - (y - coff)*255/d;
693}
694
695int QColorLuminancePicker::val2y(int v)
696{
697 int d = height() - 2*coff - 1;
698 return coff + (255-v)*d/255;
699}
700
701QColorLuminancePicker::QColorLuminancePicker(QWidget* parent)
702 :QWidget(parent)
703{
704 hue = 100; val = 100; sat = 100;
705 // setAttribute(WA_NoErase, true);
706 setFocusPolicy(Qt::StrongFocus);
707}
708
712
714{
715 switch (event->key()) {
716 case Qt::Key_Down:
717 setVal(std::clamp(val - 1, 0, 255));
718 break;
719 case Qt::Key_Up:
720 setVal(std::clamp(val + 1, 0, 255));
721 break;
722 default:
723 QWidget::keyPressEvent(event);
724 break;
725 }
726}
727
729{
730 if (m->buttons() == Qt::NoButton) {
731 m->ignore();
732 return;
733 }
734 setVal(y2val(m->position().toPoint().y()));
735}
737{
738 setVal(y2val(m->position().toPoint().y()));
739}
740
741void QColorLuminancePicker::setVal(int v)
742{
743 if (val == v)
744 return;
745 val = qMax(0, qMin(v,255));
746 pix = QPixmap();
747 repaint();
748 emit newHsv(hue, sat, val);
749}
750
751//receives from a hue,sat chooser and relays.
752void QColorLuminancePicker::setCol(int h, int s)
753{
754 setCol(h, s, val);
755 emit newHsv(h, s, val);
756}
757
759{
760 int w = width() - 5;
761
762 QRect r(0, foff, w, height() - 2*foff);
763 int wi = r.width() - 2;
764 int hi = r.height() - 2;
765 if (pix.isNull() || pix.height() != hi || pix.width() != wi) {
766 QImage img(wi, hi, QImage::Format_RGB32);
767 int y;
768 uint *pixel = (uint *) img.scanLine(0);
769 for (y = 0; y < hi; y++) {
770 uint *end = pixel + wi;
771 std::fill(pixel, end, QColor::fromHsv(hue, sat, y2val(y + coff)).rgb());
772 pixel = end;
773 }
774 pix = QPixmap::fromImage(img);
775 }
776 QPainter p(this);
777 p.drawPixmap(1, coff, pix);
778 const QPalette &g = palette();
779 qDrawShadePanel(&p, r, g, true);
780 p.setPen(g.windowText().color());
781 p.setBrush(g.windowText());
782 p.eraseRect(w, 0, 5, height());
783 const int y = val2y(val);
784 const std::array<QPoint, 3> points = {QPoint(w, y), QPoint(w + 5, y + 5), QPoint(w + 5, y - 5)};
785 p.drawPolygon(points.data(), static_cast<int>(points.size()));
786}
787
788void QColorLuminancePicker::setCol(int h, int s , int v)
789{
790 val = v;
791 hue = h;
792 sat = s;
793 pix = QPixmap();
794 repaint();
795}
796
797QPoint QColorPicker::colPt(int hue, int sat)
798{
799 QRect r = contentsRect();
800 return QPoint((360 - hue) * (r.width() - 1) / 360, (255 - sat) * (r.height() - 1) / 255);
801}
802
803int QColorPicker::huePt(const QPoint &pt, const QSize &widgetSize)
804{
805 QRect r = QRect(QPoint(0, 0), widgetSize) - contentsMargins();
806 return std::clamp(360 - pt.x() * 360 / (r.width() - 1), 0, 359);
807}
808
809int QColorPicker::satPt(const QPoint &pt, const QSize &widgetSize)
810{
811 QRect r = QRect(QPoint(0, 0), widgetSize) - contentsMargins();
812 return std::clamp(255 - pt.y() * 255 / (r.height() - 1), 0, 255);
813}
814
815void QColorPicker::setCol(const QPoint &pt, bool notify)
816{
817 if (pt == m_pos || pix.isNull())
818 return;
819
820 Q_ASSERT(pix.height());
821 Q_ASSERT(pix.width());
822
823 QRect r(m_pos, QSize(20, 20));
824 m_pos.setX(std::clamp(pt.x(), 0, pix.width() - 1));
825 m_pos.setY(std::clamp(pt.y(), 0, pix.height() - 1));
826 r = r.united(QRect(m_pos, QSize(20, 20)));
827 r.translate(contentsRect().x() - 9, contentsRect().y() - 9);
828 // update(r);
829 repaint(r);
830
831 if (notify)
832 emit newCol(huePt(m_pos), satPt(m_pos));
833}
834
835QColorPicker::QColorPicker(QWidget* parent)
836 : QFrame(parent)
837 , crossVisible(true)
838{
839 setAttribute(Qt::WA_NoSystemBackground);
840 setFocusPolicy(Qt::StrongFocus);
841 setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed) );
842 adjustSize();
843
844 pix = createColorsPixmap();
845
846 setCol(150, 255);
847}
848
852
853void QColorPicker::setCrossVisible(bool visible)
854{
855 if (crossVisible != visible) {
856 crossVisible = visible;
857 update();
858 }
859}
860
862{
863 return QSize(pWidth + 2*frameWidth(), pHeight + 2*frameWidth());
864}
865
866void QColorPicker::setCol(int h, int s)
867{
868 int nhue = qMin(qMax(0,h), 359);
869 int nsat = qMin(qMax(0,s), 255);
870 if (nhue == huePt(m_pos) && nsat == satPt(m_pos))
871 return;
872
873 setCol(colPt(nhue, nsat), false);
874}
875
876void QColorPicker::keyPressEvent(QKeyEvent *event)
877{
878 switch (event->key()) {
879 case Qt::Key_Down:
880 setCol(m_pos + QPoint(0, 1));
881 break;
882 case Qt::Key_Left:
883 setCol(m_pos + QPoint(-1, 0));
884 break;
885 case Qt::Key_Right:
886 setCol(m_pos + QPoint(1, 0));
887 break;
888 case Qt::Key_Up:
889 setCol(m_pos + QPoint(0, -1));
890 break;
891 default:
892 QFrame::keyPressEvent(event);
893 break;
894 }
895}
896
897void QColorPicker::mouseMoveEvent(QMouseEvent *m)
898{
899 QPoint p = m->position().toPoint() - contentsRect().topLeft();
900 if (m->buttons() == Qt::NoButton) {
901 m->ignore();
902 return;
903 }
904 setCol(p);
905}
906
907void QColorPicker::mousePressEvent(QMouseEvent *m)
908{
909 QPoint p = m->position().toPoint() - contentsRect().topLeft();
910 setCol(p);
911}
912
913void QColorPicker::paintEvent(QPaintEvent* )
914{
915 QPainter p(this);
916 drawFrame(&p);
917 QRect r = contentsRect();
918
919 p.drawPixmap(r.topLeft(), pix);
920
921 if (crossVisible) {
922 QPoint pt = m_pos + r.topLeft();
923 p.setPen(Qt::black);
924 p.fillRect(pt.x()-9, pt.y(), 20, 2, Qt::black);
925 p.fillRect(pt.x(), pt.y()-9, 2, 20, Qt::black);
926 }
927}
928
929void QColorPicker::resizeEvent(QResizeEvent *ev)
930{
931 QFrame::resizeEvent(ev);
932
933 pix = createColorsPixmap();
934
935 const QSize &oldSize = ev->oldSize();
936 if (!oldSize.isValid())
937 return;
938
939 // calculate hue/saturation based on previous widget size
940 // and update position accordingly
941 const int hue = huePt(m_pos, oldSize);
942 const int sat = satPt(m_pos, oldSize);
943 setCol(hue, sat);
944}
945
946QPixmap QColorPicker::createColorsPixmap()
947{
948 int w = width() - frameWidth() * 2;
949 int h = height() - frameWidth() * 2;
950 QImage img(w, h, QImage::Format_RGB32);
951 int x, y;
952 uint *pixel = (uint *) img.scanLine(0);
953 for (y = 0; y < h; y++) {
954 const uint *end = pixel + w;
955 x = 0;
956 while (pixel < end) {
957 QPoint p(x, y);
958 QColor c;
959 c.setHsv(huePt(p), satPt(p), 200);
960 *pixel = c.rgb();
961 ++pixel;
962 ++x;
963 }
964 }
965 return QPixmap::fromImage(img);
966}
967
968class QColSpinBox : public QSpinBox
969{
970public:
971 QColSpinBox(QWidget *parent)
972 : QSpinBox(parent) { setRange(0, 255); }
973 void setValue(int i) {
974 const QSignalBlocker blocker(this);
975 QSpinBox::setValue(i);
976 }
977};
978
979class QColorShowLabel;
980
981class QColorShower : public QWidget
982{
984public:
986
987 //things that don't emit signals
988 void setHsv(int h, int s, int v);
989
990 int currentAlpha() const
991 { return (colorDialog->options() & QColorDialog::ShowAlphaChannel) ? alphaEd->value() : 255; }
992 void setCurrentAlpha(int a) { alphaEd->setValue(a); rgbEd(); }
993 void showAlpha(bool b);
994 bool isAlphaVisible() const;
995
996 QRgb currentColor() const { return curCol; }
997 QColor currentQColor() const { return curQColor; }
1000
1001public slots:
1003
1004signals:
1006 void currentColorChanged(const QColor &color);
1007
1008private slots:
1009 void rgbEd();
1010 void hsvEd();
1011 void htmlEd();
1012
1013private:
1014 void showCurrentColor();
1015 int hue, sat, val;
1016 QRgb curCol;
1017 QColor curQColor;
1018 QLabel *lblHue;
1019 QLabel *lblSat;
1020 QLabel *lblVal;
1021 QLabel *lblRed;
1022 QLabel *lblGreen;
1023 QLabel *lblBlue;
1024 QLabel *lblHtml;
1025 QColSpinBox *hEd;
1026 QColSpinBox *sEd;
1027 QColSpinBox *vEd;
1028 QColSpinBox *rEd;
1029 QColSpinBox *gEd;
1030 QColSpinBox *bEd;
1031 QColSpinBox *alphaEd;
1032 QLabel *alphaLab;
1033 QLineEdit *htEd;
1034 QColorShowLabel *lab;
1035 bool rgbOriginal;
1036 QColorDialog *colorDialog;
1037 QGridLayout *gl;
1038
1041};
1042
1044{
1045 Q_OBJECT
1046
1047public:
1053 void setColor(QColor c) { col = c; }
1054
1055signals:
1057
1058protected:
1059 void paintEvent(QPaintEvent *) override;
1060 void mousePressEvent(QMouseEvent *e) override;
1061 void mouseMoveEvent(QMouseEvent *e) override;
1062 void mouseReleaseEvent(QMouseEvent *e) override;
1063#if QT_CONFIG(draganddrop)
1067#endif
1068
1069private:
1070 QColor col;
1071 bool mousePressed;
1072 QPoint pressPos;
1073};
1074
1075void QColorShowLabel::paintEvent(QPaintEvent *e)
1076{
1077 QPainter p(this);
1078 drawFrame(&p);
1079 p.fillRect(contentsRect()&e->rect(), col);
1080}
1081
1083{
1084 alphaLab->setVisible(b);
1085 alphaEd->setVisible(b);
1086}
1087
1088inline bool QColorShower::isAlphaVisible() const
1089{
1090 return alphaLab->isVisible();
1091}
1092
1094{
1095 mousePressed = true;
1096 pressPos = e->position().toPoint();
1097}
1098
1099void QColorShowLabel::mouseMoveEvent(QMouseEvent *e)
1100{
1101#if !QT_CONFIG(draganddrop)
1102 Q_UNUSED(e);
1103#else
1104 if (!mousePressed)
1105 return;
1106 if ((pressPos - e->position().toPoint()).manhattanLength() > QApplication::startDragDistance()) {
1107 QMimeData *mime = new QMimeData;
1108 mime->setColorData(col);
1109 QPixmap pix(30, 20);
1110 pix.fill(col);
1111 QPainter p(&pix);
1112 p.drawRect(0, 0, pix.width() - 1, pix.height() - 1);
1113 p.end();
1114 QDrag *drg = new QDrag(this);
1115 drg->setMimeData(mime);
1116 drg->setPixmap(pix);
1117 mousePressed = false;
1118 drg->exec(Qt::CopyAction);
1119 }
1120#endif
1121}
1122
1123#if QT_CONFIG(draganddrop)
1125{
1127 e->accept();
1128 else
1129 e->ignore();
1130}
1131
1133{
1134}
1135
1137{
1139 if (color.isValid()) {
1140 col = color;
1141 repaint();
1143 e->accept();
1144 } else {
1145 e->ignore();
1146 }
1147}
1148#endif // QT_CONFIG(draganddrop)
1149
1151{
1152 if (!mousePressed)
1153 return;
1154 mousePressed = false;
1155}
1156
1157QColorShower::QColorShower(QColorDialog *parent)
1158 : QWidget(parent)
1159{
1160 colorDialog = parent;
1161
1162 curCol = qRgb(255, 255, 255);
1163 curQColor = Qt::white;
1164
1165 gl = new QGridLayout(this);
1166 const int s = gl->spacing();
1167 gl->setContentsMargins(s, s, s, s);
1168 lab = new QColorShowLabel(this);
1169
1170#ifdef QT_SMALL_COLORDIALOG
1171 lab->setMinimumHeight(60);
1172#endif
1173 lab->setMinimumWidth(60);
1174
1175// For QVGA screens only the comboboxes and color label are visible.
1176// For nHD screens only color and luminence pickers and color label are visible.
1177#if !defined(QT_SMALL_COLORDIALOG)
1178 gl->addWidget(lab, 0, 0, -1, 1);
1179#else
1180 gl->addWidget(lab, 0, 0, 1, -1);
1181#endif
1182 connect(lab, &QColorShowLabel::colorDropped, this, &QColorShower::newCol);
1183 connect(lab, &QColorShowLabel::colorDropped, this, &QColorShower::setRgb);
1184
1185 hEd = new QColSpinBox(this);
1186 hEd->setRange(0, 359);
1187 lblHue = new QLabel(this);
1188#ifndef QT_NO_SHORTCUT
1189 lblHue->setBuddy(hEd);
1190#endif
1191 lblHue->setAlignment(Qt::AlignRight|Qt::AlignVCenter);
1192#if !defined(QT_SMALL_COLORDIALOG)
1193 gl->addWidget(lblHue, 0, 1);
1194 gl->addWidget(hEd, 0, 2);
1195#else
1196 gl->addWidget(lblHue, 1, 0);
1197 gl->addWidget(hEd, 2, 0);
1198#endif
1199
1200 sEd = new QColSpinBox(this);
1201 lblSat = new QLabel(this);
1202#ifndef QT_NO_SHORTCUT
1203 lblSat->setBuddy(sEd);
1204#endif
1205 lblSat->setAlignment(Qt::AlignRight|Qt::AlignVCenter);
1206#if !defined(QT_SMALL_COLORDIALOG)
1207 gl->addWidget(lblSat, 1, 1);
1208 gl->addWidget(sEd, 1, 2);
1209#else
1210 gl->addWidget(lblSat, 1, 1);
1211 gl->addWidget(sEd, 2, 1);
1212#endif
1213
1214 vEd = new QColSpinBox(this);
1215 lblVal = new QLabel(this);
1216#ifndef QT_NO_SHORTCUT
1217 lblVal->setBuddy(vEd);
1218#endif
1219 lblVal->setAlignment(Qt::AlignRight|Qt::AlignVCenter);
1220#if !defined(QT_SMALL_COLORDIALOG)
1221 gl->addWidget(lblVal, 2, 1);
1222 gl->addWidget(vEd, 2, 2);
1223#else
1224 gl->addWidget(lblVal, 1, 2);
1225 gl->addWidget(vEd, 2, 2);
1226#endif
1227
1228 rEd = new QColSpinBox(this);
1229 lblRed = new QLabel(this);
1230#ifndef QT_NO_SHORTCUT
1231 lblRed->setBuddy(rEd);
1232#endif
1233 lblRed->setAlignment(Qt::AlignRight|Qt::AlignVCenter);
1234#if !defined(QT_SMALL_COLORDIALOG)
1235 gl->addWidget(lblRed, 0, 3);
1236 gl->addWidget(rEd, 0, 4);
1237#else
1238 gl->addWidget(lblRed, 3, 0);
1239 gl->addWidget(rEd, 4, 0);
1240#endif
1241
1242 gEd = new QColSpinBox(this);
1243 lblGreen = new QLabel(this);
1244#ifndef QT_NO_SHORTCUT
1245 lblGreen->setBuddy(gEd);
1246#endif
1247 lblGreen->setAlignment(Qt::AlignRight|Qt::AlignVCenter);
1248#if !defined(QT_SMALL_COLORDIALOG)
1249 gl->addWidget(lblGreen, 1, 3);
1250 gl->addWidget(gEd, 1, 4);
1251#else
1252 gl->addWidget(lblGreen, 3, 1);
1253 gl->addWidget(gEd, 4, 1);
1254#endif
1255
1256 bEd = new QColSpinBox(this);
1257 lblBlue = new QLabel(this);
1258#ifndef QT_NO_SHORTCUT
1259 lblBlue->setBuddy(bEd);
1260#endif
1261 lblBlue->setAlignment(Qt::AlignRight|Qt::AlignVCenter);
1262#if !defined(QT_SMALL_COLORDIALOG)
1263 gl->addWidget(lblBlue, 2, 3);
1264 gl->addWidget(bEd, 2, 4);
1265#else
1266 gl->addWidget(lblBlue, 3, 2);
1267 gl->addWidget(bEd, 4, 2);
1268#endif
1269
1270 alphaEd = new QColSpinBox(this);
1271 alphaLab = new QLabel(this);
1272#ifndef QT_NO_SHORTCUT
1273 alphaLab->setBuddy(alphaEd);
1274#endif
1275 alphaLab->setAlignment(Qt::AlignRight|Qt::AlignVCenter);
1276#if !defined(QT_SMALL_COLORDIALOG)
1277 gl->addWidget(alphaLab, 3, 1, 1, 3);
1278 gl->addWidget(alphaEd, 3, 4);
1279#else
1280 gl->addWidget(alphaLab, 1, 3, 3, 1);
1281 gl->addWidget(alphaEd, 4, 3);
1282#endif
1283 alphaEd->hide();
1284 alphaLab->hide();
1285 lblHtml = new QLabel(this);
1286 htEd = new QLineEdit(this);
1287 htEd->setObjectName("qt_colorname_lineedit");
1288#ifndef QT_NO_SHORTCUT
1289 lblHtml->setBuddy(htEd);
1290#endif
1291
1292#if QT_CONFIG(regularexpression)
1293 QRegularExpression regExp(QStringLiteral("#?([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})"));
1294 QRegularExpressionValidator *validator = new QRegularExpressionValidator(regExp, this);
1295 htEd->setValidator(validator);
1296#else
1297 htEd->setReadOnly(true);
1298#endif
1299 htEd->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Fixed);
1300
1301 lblHtml->setAlignment(Qt::AlignRight|Qt::AlignVCenter);
1302#if defined(QT_SMALL_COLORDIALOG)
1303 gl->addWidget(lblHtml, 5, 0);
1304 gl->addWidget(htEd, 5, 1, 1, /*colspan=*/ 2);
1305#else
1306 gl->addWidget(lblHtml, 5, 1);
1307 gl->addWidget(htEd, 5, 2, 1, /*colspan=*/ 3);
1308#endif
1309
1310 connect(hEd, &QSpinBox::valueChanged, this, &QColorShower::hsvEd);
1311 connect(sEd, &QSpinBox::valueChanged, this, &QColorShower::hsvEd);
1312 connect(vEd, &QSpinBox::valueChanged, this, &QColorShower::hsvEd);
1313
1314 connect(rEd, &QSpinBox::valueChanged, this, &QColorShower::rgbEd);
1315 connect(gEd, &QSpinBox::valueChanged, this, &QColorShower::rgbEd);
1316 connect(bEd, &QSpinBox::valueChanged, this, &QColorShower::rgbEd);
1317 connect(alphaEd, &QSpinBox::valueChanged, this, &QColorShower::rgbEd);
1318 connect(htEd, &QLineEdit::textEdited, this, &QColorShower::htmlEd);
1319
1321}
1322
1323} // namespace QtPrivate
1324
1325inline QRgb QColorDialogPrivate::currentColor() const { return cs->currentColor(); }
1330
1332{
1333 if (nativeDialogInUse)
1334 return platformColorDialogHelper()->currentColor();
1335 return cs->currentQColor();
1336}
1337
1338void QColorShower::showCurrentColor()
1339{
1340 lab->setColor(currentColor());
1341 lab->repaint();
1342}
1343
1344void QColorShower::rgbEd()
1345{
1346 rgbOriginal = true;
1347 curCol = qRgba(rEd->value(), gEd->value(), bEd->value(), currentAlpha());
1348
1349 rgb2hsv(currentColor(), hue, sat, val);
1350
1351 hEd->setValue(hue);
1352 sEd->setValue(sat);
1353 vEd->setValue(val);
1354
1355 htEd->setText(QColor(curCol).name());
1356
1357 showCurrentColor();
1358 emit newCol(currentColor());
1360}
1361
1362void QColorShower::hsvEd()
1363{
1364 rgbOriginal = false;
1365 hue = hEd->value();
1366 sat = sEd->value();
1367 val = vEd->value();
1368
1369 QColor c;
1370 c.setHsv(hue, sat, val);
1371 curCol = c.rgb();
1372
1373 rEd->setValue(qRed(currentColor()));
1374 gEd->setValue(qGreen(currentColor()));
1375 bEd->setValue(qBlue(currentColor()));
1376
1377 htEd->setText(c.name());
1378
1379 showCurrentColor();
1380 emit newCol(currentColor());
1382}
1383
1384void QColorShower::htmlEd()
1385{
1386 QString t = htEd->text();
1387 if (t.isEmpty())
1388 return;
1389
1390 if (!t.startsWith(u"#")) {
1391 t.prepend(u"#");
1392 QSignalBlocker blocker(htEd);
1393 htEd->setText(t);
1394 }
1395
1396 QColor c = QColor::fromString(t);
1397 if (!c.isValid())
1398 return;
1399
1400 curCol = qRgba(c.red(), c.green(), c.blue(), currentAlpha());
1401 rgb2hsv(curCol, hue, sat, val);
1402
1403 hEd->setValue(hue);
1404 sEd->setValue(sat);
1405 vEd->setValue(val);
1406
1407 rEd->setValue(qRed(currentColor()));
1408 gEd->setValue(qGreen(currentColor()));
1409 bEd->setValue(qBlue(currentColor()));
1410
1411 showCurrentColor();
1412 emit newCol(currentColor());
1414}
1415
1416void QColorShower::setRgb(QRgb rgb)
1417{
1418 rgbOriginal = true;
1419 curCol = rgb;
1420
1421 rgb2hsv(currentColor(), hue, sat, val);
1422
1423 hEd->setValue(hue);
1424 sEd->setValue(sat);
1425 vEd->setValue(val);
1426
1427 rEd->setValue(qRed(currentColor()));
1428 gEd->setValue(qGreen(currentColor()));
1429 bEd->setValue(qBlue(currentColor()));
1430
1431 htEd->setText(QColor(rgb).name());
1432
1433 showCurrentColor();
1435}
1436
1437void QColorShower::setHsv(int h, int s, int v)
1438{
1439 if (h < -1 || (uint)s > 255 || (uint)v > 255)
1440 return;
1441
1442 rgbOriginal = false;
1443 hue = h; val = v; sat = s;
1444 QColor c;
1445 c.setHsv(hue, sat, val);
1446 curCol = c.rgb();
1447
1448 hEd->setValue(hue);
1449 sEd->setValue(sat);
1450 vEd->setValue(val);
1451
1452 rEd->setValue(qRed(currentColor()));
1453 gEd->setValue(qGreen(currentColor()));
1454 bEd->setValue(qBlue(currentColor()));
1455
1456 htEd->setText(c.name());
1457
1458 showCurrentColor();
1460}
1461
1463{
1464 lblHue->setText(QColorDialog::tr("Hu&e:"));
1465 lblSat->setText(QColorDialog::tr("&Sat:"));
1466 lblVal->setText(QColorDialog::tr("&Val:"));
1467 lblRed->setText(QColorDialog::tr("&Red:"));
1468 lblGreen->setText(QColorDialog::tr("&Green:"));
1469 lblBlue->setText(QColorDialog::tr("Bl&ue:"));
1470 alphaLab->setText(QColorDialog::tr("A&lpha channel:"));
1471 lblHtml->setText(QColorDialog::tr("&HTML:"));
1472}
1473
1475{
1476 QColor oldQColor(curQColor);
1477 curQColor.setRgba(qRgba(qRed(curCol), qGreen(curCol), qBlue(curCol), currentAlpha()));
1478 if (curQColor != oldQColor)
1479 emit currentColorChanged(curQColor);
1480}
1481
1482//sets all widgets to display h,s,v
1483void QColorDialogPrivate::newHsv(int h, int s, int v)
1484{
1485 if (!nativeDialogInUse) {
1486 cs->setHsv(h, s, v);
1487 cp->setCol(h, s);
1488 lp->setCol(h, s, v);
1489 }
1490}
1491
1492//sets all widgets to display rgb
1494{
1495 if (!nativeDialogInUse) {
1496 cs->setRgb(rgb);
1497 newColorTypedIn(rgb);
1498 }
1499}
1500
1501// hack; doesn't keep curCol in sync, so use with care
1502void QColorDialogPrivate::setCurrentQColor(const QColor &color)
1503{
1504 Q_Q(QColorDialog);
1505 if (cs->curQColor != color) {
1506 cs->curQColor = color;
1507 emit q->currentColorChanged(color);
1508 }
1509}
1510
1511// size of standard and custom color selector
1512enum {
1516};
1517
1518bool QColorDialogPrivate::selectColor(const QColor &col)
1519{
1520 QRgb color = col.rgb();
1521 // Check standard colors
1522 if (standard) {
1523 const QRgb *standardColors = QColorDialogOptions::standardColors();
1524 const QRgb *standardColorsEnd = standardColors + standardColorRows * colorColumns;
1525 const QRgb *match = std::find(standardColors, standardColorsEnd, color);
1526 if (match != standardColorsEnd) {
1527 const int index = int(match - standardColors);
1528 const int column = index / standardColorRows;
1529 const int row = index % standardColorRows;
1530 newStandard(row, column);
1531 standard->setCurrent(row, column);
1532 standard->setSelected(row, column);
1533 standard->setFocus();
1534 return true;
1535 }
1536 }
1537 // Check custom colors
1538 if (custom) {
1539 const QRgb *customColors = QColorDialogOptions::customColors();
1540 const QRgb *customColorsEnd = customColors + customColorRows * colorColumns;
1541 const QRgb *match = std::find(customColors, customColorsEnd, color);
1542 if (match != customColorsEnd) {
1543 const int index = int(match - customColors);
1544 const int column = index / customColorRows;
1545 const int row = index % customColorRows;
1546 newCustom(row, column);
1547 custom->setCurrent(row, column);
1548 custom->setSelected(row, column);
1549 custom->setFocus();
1550 return true;
1551 }
1552 }
1553 return false;
1554}
1555
1557{
1558 QScreen *screen = QGuiApplication::screenAt(p);
1559 if (!screen)
1560 screen = QGuiApplication::primaryScreen();
1561 const QRect screenRect = screen->geometry();
1562 const QPixmap pixmap =
1563 screen->grabWindow(0, p.x() - screenRect.x(), p.y() - screenRect.y(), 1, 1);
1564 const QImage i = pixmap.toImage();
1565 return i.pixel(0, 0);
1566}
1567
1568//sets all widgets except cs to display rgb
1570{
1571 if (!nativeDialogInUse) {
1572 int h, s, v;
1573 rgb2hsv(rgb, h, s, v);
1574 cp->setCol(h, s);
1575 lp->setCol(h, s, v);
1576 }
1577}
1578
1580{
1581 nextCust = r + customColorRows * c;
1582}
1583
1585{
1586 const int i = r + customColorRows * c;
1587 setCurrentRgbColor(QColorDialogOptions::customColor(i));
1588 if (standard)
1589 standard->setSelected(-1,-1);
1590}
1591
1593{
1594 setCurrentRgbColor(QColorDialogOptions::standardColor(r + c * 6));
1595 if (custom)
1596 custom->setSelected(-1,-1);
1597}
1598
1600{
1601 Q_Q(QColorDialog);
1602
1603 auto *platformServices = QGuiApplicationPrivate::platformIntegration()->services();
1604 if (platformServices && platformServices->hasCapability(QPlatformServices::Capability::ColorPicking)) {
1605 if (auto *colorPicker = platformServices->colorPicker(q->windowHandle())) {
1606 q->connect(colorPicker, &QPlatformServiceColorPicker::colorPicked, q,
1607 [q, colorPicker](const QColor &color) {
1608 colorPicker->deleteLater();
1609 q->setCurrentColor(color);
1610 });
1611 colorPicker->pickColor();
1612 return;
1613 }
1614 }
1615
1616 if (!colorPickingEventFilter)
1617 colorPickingEventFilter = new QColorPickingEventFilter(this, q);
1618 q->installEventFilter(colorPickingEventFilter);
1619 QObject::connect(qApp, &QGuiApplication::applicationStateChanged,
1620 colorPickingEventFilter, &QColorPickingEventFilter::applicationStateChanged);
1621 // If user pushes Escape, the last color before picking will be restored.
1622 beforeScreenColorPicking = cs->currentColor();
1623#ifndef QT_NO_CURSOR
1624 q->grabMouse(Qt::CrossCursor);
1625#else
1626 q->grabMouse();
1627#endif
1628
1629#ifdef Q_OS_WIN32
1630 // On Windows mouse tracking doesn't work over other processes's windows
1631 updateTimer->start(30);
1632
1633 // HACK: Because mouse grabbing doesn't work across processes, we have to have a dummy,
1634 // invisible window to catch the mouse click, otherwise we will click whatever we clicked
1635 // and loose focus.
1636 dummyTransparentWindow.show();
1637#endif
1638 q->grabKeyboard();
1639 /* With setMouseTracking(true) the desired color can be more precisely picked up,
1640 * and continuously pushing the mouse button is not necessary.
1641 */
1642 q->setMouseTracking(true);
1643
1644 addCusBt->setDisabled(true);
1645 buttons->setDisabled(true);
1646 if (eyeDropperButton) {
1647 eyeDropperButton->setDisabled(true);
1648 const QPoint globalPos = QCursor::pos();
1649 q->setCurrentColor(grabScreenColor(globalPos));
1650 updateColorLabelText(globalPos);
1651 }
1652}
1653
1655{
1656 if (lblScreenColorInfo)
1657 lblScreenColorInfo->setText(QColorDialog::tr("Cursor at %1, %2\nPress ESC to cancel")
1658 .arg(globalPos.x())
1659 .arg(globalPos.y()));
1660}
1661
1663{
1664 Q_Q(QColorDialog);
1666 q->removeEventFilter(colorPickingEventFilter);
1667 QObject::disconnect(qApp, &QGuiApplication::applicationStateChanged,
1668 colorPickingEventFilter, &QColorPickingEventFilter::applicationStateChanged);
1669 q->releaseMouse();
1670#ifdef Q_OS_WIN32
1671 updateTimer->stop();
1672 dummyTransparentWindow.setVisible(false);
1673#endif
1674 q->releaseKeyboard();
1675 q->setMouseTracking(false);
1676 lblScreenColorInfo->setText("\n"_L1);
1677 addCusBt->setDisabled(false);
1678 buttons->setDisabled(false);
1679 eyeDropperButton->setDisabled(false);
1680}
1681
1682void QColorDialogPrivate::init(const QColor &initial)
1683{
1684 Q_Q(QColorDialog);
1685
1686 q->setSizeGripEnabled(false);
1687 q->setWindowTitle(QColorDialog::tr("Select Color"));
1688
1689 // default: use the native dialog if possible. Can be overridden in setOptions()
1690 nativeDialogInUse = (platformColorDialogHelper() != nullptr);
1691 colorPickingEventFilter = nullptr;
1692 nextCust = 0;
1693
1694 if (!nativeDialogInUse)
1696
1697#ifdef Q_OS_WIN32
1698 dummyTransparentWindow.resize(1, 1);
1699 dummyTransparentWindow.setFlags(Qt::Tool | Qt::FramelessWindowHint);
1700#endif
1701
1702 q->setCurrentColor(initial);
1703}
1704
1706{
1707 Q_Q(QColorDialog);
1708 QVBoxLayout *mainLay = new QVBoxLayout(q);
1709 // there's nothing in this dialog that benefits from sizing up
1710 mainLay->setSizeConstraint(QLayout::SetFixedSize);
1711
1712 QHBoxLayout *topLay = new QHBoxLayout();
1713 mainLay->addLayout(topLay);
1714
1715 leftLay = nullptr;
1716
1717#if defined(QT_SMALL_COLORDIALOG)
1718 smallDisplay = true;
1719 const int lumSpace = 20;
1720#else
1721 // small displays (e.g. PDAs) cannot fit the full color dialog,
1722 // so just use the color picker.
1723 smallDisplay = (QGuiApplication::primaryScreen()->virtualGeometry().width() < 480 || QGuiApplication::primaryScreen()->virtualGeometry().height() < 350);
1724 const int lumSpace = topLay->spacing() / 2;
1725#endif
1726
1727 if (!smallDisplay) {
1728 leftLay = new QVBoxLayout;
1729 topLay->addLayout(leftLay);
1730
1731 standard = new QColorWell(q, standardColorRows, colorColumns, QColorDialogOptions::standardColors());
1732 lblBasicColors = new QLabel(q);
1733#ifndef QT_NO_SHORTCUT
1734 lblBasicColors->setBuddy(standard);
1735#endif
1736 QObjectPrivate::connect(standard, &QColorWell::selected,
1737 this, &QColorDialogPrivate::newStandard);
1738 leftLay->addWidget(lblBasicColors);
1739 leftLay->addWidget(standard);
1740
1741#if !defined(QT_SMALL_COLORDIALOG)
1743 eyeDropperButton = new QPushButton();
1744 leftLay->addWidget(eyeDropperButton);
1745 lblScreenColorInfo = new QLabel("\n"_L1);
1746 leftLay->addWidget(lblScreenColorInfo);
1747 QObjectPrivate::connect(eyeDropperButton, &QPushButton::clicked,
1748 this, &QColorDialogPrivate::pickScreenColor);
1749 } else {
1750 eyeDropperButton = nullptr;
1751 lblScreenColorInfo = nullptr;
1752 }
1753#endif
1754
1755 leftLay->addStretch();
1756
1757 custom = new QColorWell(q, customColorRows, colorColumns, QColorDialogOptions::customColors());
1758 custom->setAcceptDrops(true);
1759
1760 QObjectPrivate::connect(custom, &QColorWell::selected, this, &QColorDialogPrivate::newCustom);
1761 QObjectPrivate::connect(custom, &QColorWell::currentChanged, this, &QColorDialogPrivate::nextCustom);
1762
1763 QObject::connect(custom, &QWellArray::colorChanged, q, [this] (int index, QRgb color) {
1764 QColorDialogOptions::setCustomColor(index, color);
1765 if (custom)
1766 custom->update();
1767 });
1768
1769 lblCustomColors = new QLabel(q);
1770#ifndef QT_NO_SHORTCUT
1771 lblCustomColors->setBuddy(custom);
1772#endif
1773 leftLay->addWidget(lblCustomColors);
1774 leftLay->addWidget(custom);
1775
1776 addCusBt = new QPushButton(q);
1777 QObjectPrivate::connect(addCusBt, &QPushButton::clicked, this, &QColorDialogPrivate::addCustom);
1778 leftLay->addWidget(addCusBt);
1779 } else {
1780 // better color picker size for small displays
1781#if defined(QT_SMALL_COLORDIALOG)
1782 QSize screenSize = QGuiApplication::screenAt(QCursor::pos())->availableGeometry().size();
1783 pWidth = pHeight = qMin(screenSize.width(), screenSize.height());
1784 pHeight -= 20;
1785 if (screenSize.height() > screenSize.width())
1786 pWidth -= 20;
1787#else
1788 pWidth = 150;
1789 pHeight = 100;
1790#endif
1791 custom = nullptr;
1792 standard = nullptr;
1793 }
1794
1795 QVBoxLayout *rightLay = new QVBoxLayout;
1796 topLay->addLayout(rightLay);
1797
1798 QHBoxLayout *pickLay = new QHBoxLayout;
1799 rightLay->addLayout(pickLay);
1800
1801 QVBoxLayout *cLay = new QVBoxLayout;
1802 pickLay->addLayout(cLay);
1803 cp = new QColorPicker(q);
1804
1805 cp->setFrameStyle(QFrame::Panel | QFrame::Sunken);
1806
1807#if defined(QT_SMALL_COLORDIALOG)
1808 cp->hide();
1809#else
1810 cLay->addSpacing(lumSpace);
1811 cLay->addWidget(cp);
1812#endif
1813 cLay->addSpacing(lumSpace);
1814
1815 lp = new QColorLuminancePicker(q);
1816#if defined(QT_SMALL_COLORDIALOG)
1817 lp->hide();
1818#else
1819 lp->setFixedWidth(20);
1820 pickLay->addSpacing(10);
1821 pickLay->addWidget(lp);
1822 pickLay->addStretch();
1823#endif
1824
1825 QObject::connect(cp, &QColorPicker::newCol, lp, qOverload<int, int>(&QColorLuminancePicker::setCol));
1826 QObjectPrivate::connect(lp, &QColorLuminancePicker::newHsv, this, &QColorDialogPrivate::newHsv);
1827
1828 rightLay->addStretch();
1829
1830 cs = new QColorShower(q);
1831 pickLay->setContentsMargins(cs->gl->contentsMargins());
1832 QObjectPrivate::connect(cs, &QColorShower::newCol,
1833 this, &QColorDialogPrivate::newColorTypedIn);
1834 QObject::connect(cs, &QColorShower::currentColorChanged,
1835 q, &QColorDialog::currentColorChanged);
1836#if defined(QT_SMALL_COLORDIALOG)
1837 topLay->addWidget(cs);
1838#else
1839 rightLay->addWidget(cs);
1840 if (leftLay)
1841 leftLay->addSpacing(cs->gl->contentsMargins().right());
1842#endif
1843
1844 buttons = new QDialogButtonBox(q);
1845 mainLay->addWidget(buttons);
1846
1847 ok = buttons->addButton(QDialogButtonBox::Ok);
1848 QObject::connect(ok, &QPushButton::clicked, q, &QColorDialog::accept);
1849 ok->setDefault(true);
1850 cancel = buttons->addButton(QDialogButtonBox::Cancel);
1851 QObject::connect(cancel, &QPushButton::clicked, q, &QColorDialog::reject);
1852
1853#ifdef Q_OS_WIN32
1854 updateTimer = new QTimer(q);
1855 QObjectPrivate::connect(updateTimer, &QTimer::timeout,
1856 this, qOverload<>(&QColorDialogPrivate::updateColorPicking));
1857#endif
1859}
1860
1861void QColorDialogPrivate::initHelper(QPlatformDialogHelper *h)
1862{
1863 QColorDialog *d = q_func();
1864 auto *colorDialogHelper = static_cast<QPlatformColorDialogHelper*>(h);
1865 QObject::connect(colorDialogHelper, &QPlatformColorDialogHelper::currentColorChanged,
1866 d, &QColorDialog::currentColorChanged);
1867 QObject::connect(colorDialogHelper, &QPlatformColorDialogHelper::colorSelected,
1868 d, &QColorDialog::colorSelected);
1869 colorDialogHelper->setOptions(options);
1870}
1871
1872void QColorDialogPrivate::helperPrepareShow(QPlatformDialogHelper *)
1873{
1874 options->setWindowTitle(q_func()->windowTitle());
1875}
1876
1878{
1879 QColorDialogOptions::setCustomColor(nextCust, cs->currentColor());
1880 if (custom)
1881 custom->update();
1882 nextCust = (nextCust+1) % QColorDialogOptions::customColorCount();
1883}
1884
1886{
1887 if (nativeDialogInUse)
1888 return;
1889
1890 if (!smallDisplay) {
1891 lblBasicColors->setText(QColorDialog::tr("&Basic colors"));
1892 lblCustomColors->setText(QColorDialog::tr("&Custom colors"));
1893 addCusBt->setText(QColorDialog::tr("&Add to Custom Colors"));
1894#if !defined(QT_SMALL_COLORDIALOG)
1895 if (eyeDropperButton)
1896 eyeDropperButton->setText(QColorDialog::tr("&Pick Screen Color"));
1897#endif
1898 }
1899
1901}
1902
1904{
1905 const auto integration = QGuiApplicationPrivate::platformIntegration();
1906 return integration->hasCapability(QPlatformIntegration::ScreenWindowGrabbing)
1907 || integration->services()->hasCapability(QPlatformServices::Capability::ColorPicking);
1908}
1909
1911{
1912 // Don't use Q_Q here! This function is called from ~QDialog,
1913 // so Q_Q calling q_func() invokes undefined behavior (invalid cast in q_func()).
1914 const QDialog * const q = static_cast<const QDialog*>(q_ptr);
1915 if (nativeDialogInUse)
1916 return true;
1917 if (QCoreApplication::testAttribute(Qt::AA_DontUseNativeDialogs)
1918 || q->testAttribute(Qt::WA_DontShowOnScreen)
1919 || (options->options() & QColorDialog::DontUseNativeDialog)) {
1920 return false;
1921 }
1922
1923 return strcmp(QColorDialog::staticMetaObject.className(), q->metaObject()->className()) == 0;
1924}
1925
1927 Qt::Dialog | Qt::WindowTitleHint
1928 | Qt::WindowSystemMenuHint | Qt::WindowCloseButtonHint;
1929
1930/*!
1931 \class QColorDialog
1932 \brief The QColorDialog class provides a dialog widget for specifying colors.
1933
1934 \ingroup standard-dialogs
1935 \inmodule QtWidgets
1936
1937 The color dialog's function is to allow users to choose colors.
1938 For example, you might use this in a drawing program to allow the
1939 user to set the brush color.
1940
1941 The static functions provide modal color dialogs.
1942 \omit
1943 If you require a modeless dialog, use the QColorDialog constructor.
1944 \endomit
1945
1946 The static getColor() function shows the dialog, and allows the user to
1947 specify a color. This function can also be used to let users choose a
1948 color with a level of transparency: pass the ShowAlphaChannel option as
1949 an additional argument.
1950
1951 The user can store customCount() different custom colors. The
1952 custom colors are shared by all color dialogs, and remembered
1953 during the execution of the program. Use setCustomColor() to set
1954 the custom colors, and use customColor() to get them.
1955
1956 When pressing the "Pick Screen Color" button, the cursor changes to a haircross
1957 and the colors on the screen are scanned. The user can pick up one by clicking
1958 the mouse or the Enter button. Pressing Escape restores the last color selected
1959 before entering this mode.
1960
1961 The \l{dialogs/standarddialogs}{Standard Dialogs} example shows
1962 how to use QColorDialog as well as other built-in Qt dialogs.
1963
1964 \image fusion-colordialog.png A color dialog in the Fusion widget style.
1965
1966 \sa QColor, QFileDialog, QFontDialog, {Standard Dialogs Example}
1967*/
1968
1969/*!
1970 Constructs a color dialog with the given \a parent.
1971*/
1972QColorDialog::QColorDialog(QWidget *parent)
1973 : QColorDialog(QColor(Qt::white), parent)
1974{
1975 new QColorPolishFilter(this);
1976}
1977
1978/*!
1979 Constructs a color dialog with the given \a parent and specified
1980 \a initial color.
1981*/
1982QColorDialog::QColorDialog(const QColor &initial, QWidget *parent)
1983 : QDialog(*new QColorDialogPrivate, parent, qcd_DefaultWindowFlags)
1984{
1985 Q_D(QColorDialog);
1986 new QColorPolishFilter(this);
1987 d->init(initial);
1988}
1989
1990void QColorDialogPrivate::setCurrentColor(const QColor &color, SetColorMode setColorMode)
1991{
1992 if (nativeDialogInUse) {
1993 platformColorDialogHelper()->setCurrentColor(color);
1994 return;
1995 }
1996
1997 if (setColorMode & ShowColor) {
1998 setCurrentRgbColor(color.rgb());
1999 setCurrentAlpha(color.alpha());
2000 }
2001 if (setColorMode & SelectColor)
2002 selectColor(color);
2003}
2004
2005/*!
2006 \property QColorDialog::currentColor
2007 \brief the currently selected color in the dialog
2008*/
2009
2010void QColorDialog::setCurrentColor(const QColor &color)
2011{
2012 Q_D(QColorDialog);
2013 d->setCurrentColor(color);
2014}
2015
2016QColor QColorDialog::currentColor() const
2017{
2018 Q_D(const QColorDialog);
2019 return d->currentQColor();
2020}
2021
2022/*!
2023 Returns the color that the user selected by clicking the \uicontrol{OK}
2024 or equivalent button.
2025
2026 \note This color is not always the same as the color held by the
2027 \l currentColor property since the user can choose different colors
2028 before finally selecting the one to use.
2029*/
2030QColor QColorDialog::selectedColor() const
2031{
2032 Q_D(const QColorDialog);
2033 return d->selectedQColor;
2034}
2035
2036/*!
2037 Sets the given \a option to be enabled if \a on is true;
2038 otherwise, clears the given \a option.
2039
2040 \sa options, testOption()
2041*/
2042void QColorDialog::setOption(ColorDialogOption option, bool on)
2043{
2044 Q_D(QColorDialog);
2045 d->optionsExplicitlySet = true;
2046
2047 const QColorDialog::ColorDialogOptions previousOptions = options();
2048 if (!(previousOptions & option) != !on)
2049 setOptions(previousOptions ^ option);
2050}
2051
2052/*!
2053 Returns \c true if the given \a option is enabled; otherwise, returns
2054 false.
2055
2056 \sa options, setOption()
2057*/
2058bool QColorDialog::testOption(ColorDialogOption option) const
2059{
2060 Q_D(const QColorDialog);
2061 return d->options->testOption(static_cast<QColorDialogOptions::ColorDialogOption>(option));
2062}
2063
2064/*!
2065 \property QColorDialog::options
2066 \brief the various options that affect the look and feel of the dialog
2067
2068 By default, all options are disabled.
2069
2070 Options should be set before showing the dialog. Setting them while the
2071 dialog is visible is not guaranteed to have an immediate effect on the
2072 dialog (depending on the option and on the platform).
2073
2074 \sa setOption(), testOption()
2075*/
2076void QColorDialog::setOptions(ColorDialogOptions options)
2077{
2078 Q_D(QColorDialog);
2079 d->optionsExplicitlySet = true;
2080
2081 if (QColorDialog::options() == options)
2082 return;
2083
2084 d->options->setOptions(QColorDialogOptions::ColorDialogOptions(int(options)));
2085 if ((options & DontUseNativeDialog) && d->nativeDialogInUse) {
2086 d->nativeDialogInUse = false;
2087 d->initWidgets();
2088 }
2089 if (!d->nativeDialogInUse) {
2090 d->buttons->setVisible(!(options & NoButtons));
2091 d->showAlpha(options & ShowAlphaChannel);
2092 if (d->eyeDropperButton)
2093 d->eyeDropperButton->setVisible(!(options & NoEyeDropperButton));
2094 }
2095}
2096
2097QColorDialog::ColorDialogOptions QColorDialog::options() const
2098{
2099 Q_D(const QColorDialog);
2100 return QColorDialog::ColorDialogOptions(int(d->options->options()));
2101}
2102
2103/*!
2104 \enum QColorDialog::ColorDialogOption
2105
2106 This enum specifies various options that affect the look and feel
2107 of a color dialog.
2108
2109 \value ShowAlphaChannel Allow the user to select the alpha component of a color.
2110 \value NoButtons Don't display \uicontrol{OK} and \uicontrol{Cancel} buttons. (Useful for "live dialogs".)
2111 \value NoEyeDropperButton Hide the \uicontrol{Eye Dropper} button. This value was added in Qt 6.6.
2112 \value DontUseNativeDialog Use Qt's standard color dialog instead of the operating system
2113 native color dialog.
2114
2115 \sa options, setOption(), testOption(), windowModality()
2116*/
2117
2118/*!
2119 \fn void QColorDialog::currentColorChanged(const QColor &color)
2120
2121 This signal is emitted whenever the current color changes in the dialog.
2122 The current color is specified by \a color.
2123
2124 \sa color, colorSelected()
2125*/
2126
2127/*!
2128 \fn void QColorDialog::colorSelected(const QColor &color);
2129
2130 This signal is emitted just after the user has clicked \uicontrol{OK} to
2131 select a color to use. The chosen color is specified by \a color.
2132
2133 \sa color, currentColorChanged()
2134*/
2135
2136/*!
2137 Changes the visibility of the dialog. If \a visible is true, the dialog
2138 is shown; otherwise, it is hidden.
2139*/
2140void QColorDialog::setVisible(bool visible)
2141{
2142 // will call QColorDialogPrivate::setVisible override
2143 QDialog::setVisible(visible);
2144}
2145
2146/*!
2147 \internal
2148
2149 The implementation of QColorDialog::setVisible() has to live here so that the call
2150 to hide() in ~QDialog calls this function; it wouldn't call the override of
2151 QDialog::setVisible().
2152*/
2154{
2155 // Don't use Q_Q here! This function is called from ~QDialog,
2156 // so Q_Q calling q_func() invokes undefined behavior (invalid cast in q_func()).
2157 const auto q = static_cast<QDialog *>(q_ptr);
2158
2159 if (visible)
2160 selectedQColor = QColor();
2161
2162 if (nativeDialogInUse) {
2163 if (setNativeDialogVisible(visible)) {
2164 // Set WA_DontShowOnScreen so that QDialog::setVisible(visible) below
2165 // updates the state correctly, but skips showing the non-native version:
2166 q->setAttribute(Qt::WA_DontShowOnScreen);
2167 } else if (visible) {
2169 }
2170 } else {
2171 q->setAttribute(Qt::WA_DontShowOnScreen, false);
2172 }
2173
2174 QDialogPrivate::setVisible(visible);
2175}
2176
2177/*!
2178 Opens the dialog and connects its colorSelected() signal to the slot specified
2179 by \a receiver and \a member.
2180
2181 The signal will be disconnected from the slot when the dialog is closed.
2182*/
2183void QColorDialog::open(QObject *receiver, const char *member)
2184{
2185 Q_D(QColorDialog);
2186 connect(this, SIGNAL(colorSelected(QColor)), receiver, member);
2187 d->receiverToDisconnectOnClose = receiver;
2188 d->memberToDisconnectOnClose = member;
2189 QDialog::open();
2190}
2191
2192/*!
2193 Pops up a modal color dialog with the given window \a title (or "Select Color" if none is
2194 specified), lets the user choose a color, and returns that color. The color is initially set
2195 to \a initial. The dialog is a child of \a parent. It returns an invalid (see
2196 QColor::isValid()) color if the user cancels the dialog.
2197
2198 The \a options argument allows you to customize the dialog.
2199*/
2200QColor QColorDialog::getColor(const QColor &initial, QWidget *parent, const QString &title,
2201 ColorDialogOptions options)
2202{
2203 QAutoPointer<QColorDialog> dlg(new QColorDialog(parent));
2204 if (!title.isEmpty())
2205 dlg->setWindowTitle(title);
2206 dlg->setOptions(options);
2207 dlg->setCurrentColor(initial);
2208
2209 // If the dlg was deleted with a parent window,
2210 // dlg == nullptr after leaving the exec().
2211 dlg->exec();
2212 if (bool(dlg))
2213 return dlg->selectedColor();
2214 else
2215 return QColor();
2216}
2217
2218/*!
2219 Destroys the color dialog.
2220*/
2221
2222QColorDialog::~QColorDialog()
2223{
2224}
2225
2226/*!
2227 \reimp
2228*/
2229void QColorDialog::changeEvent(QEvent *e)
2230{
2231 Q_D(QColorDialog);
2232 if (e->type() == QEvent::LanguageChange)
2233 d->retranslateStrings();
2234 QDialog::changeEvent(e);
2235}
2236
2238{
2239#ifndef QT_NO_CURSOR
2240 Q_Q(QColorDialog);
2241 static QPoint lastGlobalPos;
2242 QPoint newGlobalPos = QCursor::pos();
2243 if (lastGlobalPos == newGlobalPos)
2244 return;
2245 lastGlobalPos = newGlobalPos;
2246
2247 if (!q->rect().contains(q->mapFromGlobal(newGlobalPos))) { // Inside the dialog mouse tracking works, handleColorPickingMouseMove will be called
2248 updateColorPicking(newGlobalPos);
2249#ifdef Q_OS_WIN32
2250 dummyTransparentWindow.setPosition(newGlobalPos);
2251#endif
2252 }
2253#endif // ! QT_NO_CURSOR
2254}
2255
2257{
2258 const QColor color = grabScreenColor(globalPos);
2259 // QTBUG-39792, do not change standard, custom color selectors while moving as
2260 // otherwise it is not possible to pre-select a custom cell for assignment.
2261 setCurrentColor(color, ShowColor);
2262 updateColorLabelText(globalPos);
2263}
2264
2266{
2267 // If the cross is visible the grabbed color will be black most of the times
2268 cp->setCrossVisible(!cp->geometry().contains(e->position().toPoint()));
2269
2270 updateColorPicking(e->globalPosition().toPoint());
2271 return true;
2272}
2273
2275{
2276 setCurrentColor(grabScreenColor(e->globalPosition().toPoint()), SetColorAll);
2278 return true;
2279}
2280
2282{
2283 Q_Q(QColorDialog);
2284#if QT_CONFIG(shortcut)
2285 if (e->matches(QKeySequence::Cancel)) {
2286 releaseColorPicking();
2287 q->setCurrentColor(beforeScreenColorPicking);
2288 } else
2289#endif
2290 if (e->key() == Qt::Key_Return || e->key() == Qt::Key_Enter) {
2291 q->setCurrentColor(grabScreenColor(QCursor::pos()));
2293 }
2294 e->accept();
2295 return true;
2296}
2297
2298/*!
2299 Closes the dialog and sets its result code to \a result. If this dialog
2300 is shown with exec(), done() causes the local event loop to finish,
2301 and exec() to return \a result.
2302
2303 \sa QDialog::done()
2304*/
2305void QColorDialog::done(int result)
2306{
2307 Q_D(QColorDialog);
2308 if (result == Accepted) {
2309 d->selectedQColor = d->currentQColor();
2310 emit colorSelected(d->selectedQColor);
2311 } else {
2312 d->selectedQColor = QColor();
2313 }
2314 QDialog::done(result);
2315 if (d->receiverToDisconnectOnClose) {
2316 disconnect(this, SIGNAL(colorSelected(QColor)),
2317 d->receiverToDisconnectOnClose, d->memberToDisconnectOnClose);
2318 d->receiverToDisconnectOnClose = nullptr;
2319 }
2320 d->memberToDisconnectOnClose.clear();
2321}
2322
2323QT_END_NAMESPACE
2324
2325#include "qcolordialog.moc"
2326#include "moc_qcolordialog.cpp"
QColor grabScreenColor(const QPoint &p)
bool selectColor(const QColor &color)
void init(const QColor &initial)
void setCurrentAlpha(int a)
QColorPickingEventFilter * colorPickingEventFilter
bool handleColorPickingMouseButtonRelease(QMouseEvent *e)
QColor currentQColor() const
bool handleColorPickingMouseMove(QMouseEvent *e)
void _q_setCustom(int index, QRgb color)
QPushButton * eyeDropperButton
void updateColorLabelText(const QPoint &)
void setCurrentColor(const QColor &color, SetColorMode setColorMode=SetColorAll)
bool isAlphaVisible() const
QVBoxLayout * leftLay
void setCurrentQColor(const QColor &color)
bool canBeNativeDialog() const override
void setCurrentRgbColor(QRgb rgb)
QRgb currentColor() const
void newColorTypedIn(QRgb rgb)
bool handleColorPickingKeyPress(QKeyEvent *e)
void updateColorPicking(const QPoint &pos)
QSharedPointer< QColorDialogOptions > options
void newStandard(int, int)
void setVisible(bool visible) override
QDialogButtonBox * buttons
bool supportsColorPicking() const
QPointer< QObject > receiverToDisconnectOnClose
virtual void initHelper(QPlatformDialogHelper *h) override
QByteArray memberToDisconnectOnClose
QPushButton * addCusBt
void newHsv(int h, int s, int v)
virtual void helperPrepareShow(QPlatformDialogHelper *h) override
QColorLuminancePicker * lp
void newCustom(int, int)
QPlatformColorDialogHelper * platformColorDialogHelper() const
void nextCustom(int, int)
bool eventFilter(QObject *obj, QEvent *event) override
Filters events if this object has been installed as an event filter for the watched object.
QColorPolishFilter(QColorDialog *cd)
friend class QPainter
\inmodule QtCore\reentrant
Definition qpoint.h:30
QColSpinBox(QWidget *parent)
void paintEvent(QPaintEvent *) override
This event handler can be reimplemented in a subclass to receive paint events passed in event.
void keyPressEvent(QKeyEvent *event) override
This event handler, for event event, can be reimplemented in a subclass to receive key press events f...
void mouseMoveEvent(QMouseEvent *) override
This event handler, for event event, can be reimplemented in a subclass to receive mouse move events ...
void mousePressEvent(QMouseEvent *) override
This event handler, for event event, can be reimplemented in a subclass to receive mouse press events...
void paintEvent(QPaintEvent *) override
This event handler can be reimplemented in a subclass to receive paint events passed in event.
void mouseMoveEvent(QMouseEvent *) override
This event handler, for event event, can be reimplemented in a subclass to receive mouse move events ...
QSize sizeHint() const override
void setCrossVisible(bool visible)
void resizeEvent(QResizeEvent *) override
This event handler can be reimplemented in a subclass to receive widget resize events which are passe...
void mousePressEvent(QMouseEvent *) override
This event handler, for event event, can be reimplemented in a subclass to receive mouse press events...
void keyPressEvent(QKeyEvent *event) override
This event handler, for event event, can be reimplemented in a subclass to receive key press events f...
bool eventFilter(QObject *, QEvent *event) override
Filters events if this object has been installed as an event filter for the watched object.
void applicationStateChanged(Qt::ApplicationState state)
QColorPickingEventFilter(QColorDialogPrivate *dp, QObject *parent)
void mouseReleaseEvent(QMouseEvent *e) override
This event handler, for event event, can be reimplemented in a subclass to receive mouse release even...
void mousePressEvent(QMouseEvent *e) override
This event handler, for event event, can be reimplemented in a subclass to receive mouse press events...
void mouseMoveEvent(QMouseEvent *e) override
This event handler, for event event, can be reimplemented in a subclass to receive mouse move events ...
void paintEvent(QPaintEvent *) override
This event handler can be reimplemented in a subclass to receive paint events passed in event.
QColor currentQColor() const
void setHsv(int h, int s, int v)
void currentColorChanged(const QColor &color)
friend class QT_PREPEND_NAMESPACE(QUntypedBindable)
QtPrivate::QColorShower QColorShower
static void rgb2hsv(QRgb rgb, int &h, int &s, int &v)
static int pHeight
static int pWidth
QtPrivate::QColorPickingEventFilter QColorPickingEventFilter
QtPrivate::QColorLuminancePicker QColorLuminancePicker
QtPrivate::QColorPicker QColorPicker
static const Qt::WindowFlags qcd_DefaultWindowFlags
@ colorColumns
@ standardColorRows
@ customColorRows
#define qApp