Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qquickcolordialogimpl.cpp
Go to the documentation of this file.
1// Copyright (C) 2022 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
6
8
9#include <QtQuickTemplates2/private/qquickslider_p.h>
10
11#include <qpa/qplatformintegration.h>
12#include <qpa/qplatformservices.h>
13#include <private/qguiapplication_p.h>
14
16
18{
20 if (!screen)
22 const QRect screenRect = screen->geometry();
23 const QPixmap pixmap =
24 screen->grabWindow(0, p.x() - screenRect.x(), p.y() - screenRect.y(), 1, 1);
25 const QImage i = pixmap.toImage();
26 return i.pixel(0, 0);
27}
28
30{
31 switch (event->type()) {
32 case QEvent::MouseMove: {
33 m_lastPosition = static_cast<QMouseEvent *>(event)->globalPosition().toPoint();
34 m_update(m_lastPosition);
35 return true;
36 }
38 m_lastPosition = static_cast<QMouseEvent *>(event)->globalPosition().toPoint();
40 return true;
41 }
43 return true;
44 case QEvent::KeyPress: {
45 auto keyEvent = static_cast<QKeyEvent *>(event);
46#if QT_CONFIG(shortcut)
47 if (keyEvent->matches(QKeySequence::Cancel))
49 else
50#endif
51 if (keyEvent->key() == Qt::Key_Return || keyEvent->key() == Qt::Key_Enter) {
53 } else if (keyEvent->key() == Qt::Key_Escape) {
55 }
56 keyEvent->accept();
57 return true;
58 }
59 default:
61 }
62}
63
65
71
73{
75 const auto c = q->color();
77 q->setColor(c);
78 q->accept();
79 }
81}
82
84{
87 qmlAttachedPropertiesObject<QQuickColorDialogImpl>(q, false));
88 if (!attached)
89 qmlWarning(q) << "Expected ColorDialogImpl attached object to be present on" << this;
90 return attached;
91}
92
94{
97 return;
98
100 if (window.isNull()) {
101 qWarning() << "No window found, cannot enter eyeDropperMode.";
102 return;
103 }
104
106 }
107
108 if (auto *platformServices = QGuiApplicationPrivate::platformIntegration()->services();
109 platformServices && platformServices->hasCapability(QPlatformServices::Capability::ColorPicking)) {
110 if (auto *colorPickerService = platformServices->colorPicker(m_eyeDropperWindow)) {
112 [q, colorPickerService](const QColor &color) {
113 colorPickerService->deleteLater();
114 q->setColor(color);
115 });
116 colorPickerService->pickColor();
117 return;
118 }
119 }
120
121 m_eyeDropperPreviousColor = q->color();
122
123 if (!bool(eyeDropperEventFilter))
127 },
128 [this](QPoint pos) { eyeDropperPointerMoved(pos); }));
129
130 if (m_eyeDropperWindow->setMouseGrabEnabled(true)) {
131#if QT_CONFIG(cursor)
133#endif
135 m_eyeDropperMode = true;
136 }
137}
138
141{
143
144 if (!m_eyeDropperMode)
145 return;
146
147 if (!m_eyeDropperWindow) {
148 qWarning() << "Window not set, cannot leave eyeDropperMode.";
149 return;
150 }
151
152 const QColor colorToUse = actionOnLeave == QQuickEyeDropperEventFilter::LeaveReason::Cancel
155 q->setColor(colorToUse);
156
158 m_eyeDropperWindow->setMouseGrabEnabled(false);
159#if QT_CONFIG(cursor)
161#endif
162
163 m_eyeDropperMode = false;
165}
166
172
174{
176 if (auto attached = attachedOrWarn())
177 q->setAlpha(attached->alphaSlider()->value());
178}
179
184
189
191{
192 Q_D(const QQuickColorDialogImpl);
193 return d->m_hsl ? QColor::fromHslF(d->m_hsva.h, d->m_hsva.s, d->m_hsva.l, d->m_hsva.a)
194 : QColor::fromHsvF(d->m_hsva.h, d->m_hsva.s, d->m_hsva.v, d->m_hsva.a);
195}
196
198{
200 if (color().rgba() == c.rgba())
201 return;
202
203 // If we get a QColor from an Hsv or Hsl color system,
204 // we want to get the raw values without the risk of QColor converting them,
205 // and possible deleting relevant information for achromatic cases.
206 if (c.spec() == QColor::Spec::Hsv) {
207 d->m_hsva.h = qBound(.0, c.hsvHueF(), 1.0);
208 if (d->m_hsl) {
209 const auto sl = getSaturationAndLightness(c.hsvSaturationF(), c.valueF());
210 d->m_hsva.s = qBound(.0, sl.first, 1.0);
211 d->m_hsva.l = qBound(.0, sl.second, 1.0);
212 } else {
213 d->m_hsva.s = qBound(.0, c.hsvSaturationF(), 1.0);
214 d->m_hsva.v = qBound(.0, c.valueF(), 1.0);
215 }
216 } else if (c.spec() == QColor::Spec::Hsl) {
217 d->m_hsva.h = qBound(.0, c.hslHueF(), 1.0);
218 if (d->m_hsl) {
219 d->m_hsva.s = qBound(.0, c.hslSaturationF(), 1.0);
220 d->m_hsva.l = qBound(.0, c.lightnessF(), 1.0);
221 } else {
222 const auto sv = getSaturationAndValue(c.hslSaturationF(), c.lightnessF());
223 d->m_hsva.s = qBound(.0, sv.first, 1.0);
224 d->m_hsva.v = qBound(.0, sv.second, 1.0);
225 }
226 } else {
227 d->m_hsva.h = qBound(.0, d->m_hsl ? c.hslHueF() : c.hsvHueF(), 1.0);
228 d->m_hsva.s = qBound(.0, d->m_hsl ? c.hslSaturationF() : c.hsvSaturationF(), 1.0);
229 d->m_hsva.v = qBound(.0, d->m_hsl ? c.lightnessF() : c.valueF(), 1.0);
230 }
231
232 d->m_hsva.a = c.alphaF();
233
235}
236
238{
239 return color().red();
240}
241
243{
245
246 auto c = color();
247
248 if (c.red() == red)
249 return;
250
251 c.setRed(red);
252
253 d->m_hsva.h = d->m_hsl ? c.hslHueF() : c.hsvHueF();
254 d->m_hsva.s = d->m_hsl ? c.hslSaturationF() : c.hsvSaturationF();
255 d->m_hsva.v = d->m_hsl ? c.lightnessF() : c.valueF();
256 d->m_hsva.a = c.alphaF();
257
259}
260
262{
263 return color().green();
264}
265
267{
269
270 auto c = color();
271
272 if (c.green() == green)
273 return;
274
275 c.setGreen(green);
276
277 d->m_hsva.h = d->m_hsl ? c.hslHueF() : c.hsvHueF();
278 d->m_hsva.s = d->m_hsl ? c.hslSaturationF() : c.hsvSaturationF();
279 d->m_hsva.v = d->m_hsl ? c.lightnessF() : c.valueF();
280 d->m_hsva.a = c.alphaF();
281
283}
284
286{
287 return color().blue();
288}
289
291{
293
294 auto c = color();
295
296 if (c.blue() == blue)
297 return;
298
299 c.setBlue(blue);
300
301 d->m_hsva.h = d->m_hsl ? c.hslHueF() : c.hsvHueF();
302 d->m_hsva.s = d->m_hsl ? c.hslSaturationF() : c.hsvSaturationF();
303 d->m_hsva.v = d->m_hsl ? c.lightnessF() : c.valueF();
304 d->m_hsva.a = c.alphaF();
305
307}
308
310{
311 Q_D(const QQuickColorDialogImpl);
312 return d->m_hsva.a;
313}
314
316{
318
319 if (!qt_is_finite(alpha))
320 return;
321
322 alpha = qBound(.0, alpha, 1.0);
323
324 if (qFuzzyCompare(d->m_hsva.a, alpha))
325 return;
326
327 d->m_hsva.a = alpha;
328
330}
331
333{
334 Q_D(const QQuickColorDialogImpl);
335 return d->m_hsva.h;
336}
337
339{
341
342 if (!qt_is_finite(hue))
343 return;
344
345 d->m_hsva.h = hue;
346
348}
349
351{
352 Q_D(const QQuickColorDialogImpl);
353 return d->m_hsva.s;
354}
355
357{
360 return;
361
362 d->m_hsva.s = saturation;
363
365}
366
368{
369 Q_D(const QQuickColorDialogImpl);
370 return d->m_hsl ? getSaturationAndValue(d->m_hsva.s, d->m_hsva.l).second : d->m_hsva.v;
371}
372
374{
376 if (!qt_is_finite(value))
377 return;
378
379 d->m_hsva.v = value;
380
381 if (d->m_hsl)
382 d->m_hsva.s = getSaturationAndValue(d->m_hsva.s, d->m_hsva.l).first;
383
384 d->m_hsl = false;
386}
387
389{
390 Q_D(const QQuickColorDialogImpl);
391 return d->m_hsl ? d->m_hsva.l : getSaturationAndLightness(d->m_hsva.s, d->m_hsva.v).second;
392}
393
395{
398 return;
399
400 d->m_hsva.l = lightness;
401
402 if (!d->m_hsl)
403 d->m_hsva.s = getSaturationAndLightness(d->m_hsva.s, d->m_hsva.v).first;
404
405 d->m_hsl = true;
407}
408
410{
411 Q_D(const QQuickColorDialogImpl);
412 return d->m_hsl;
413}
414
416{
418
419 if (d->m_hsl == hsl)
420 return;
421
422 d->m_hsl = hsl;
424}
425
426QSharedPointer<QColorDialogOptions> QQuickColorDialogImpl::options() const
427{
428 Q_D(const QQuickColorDialogImpl);
429 return d->options;
430}
431
432void QQuickColorDialogImpl::setOptions(const QSharedPointer<QColorDialogOptions> &options)
433{
435 d->options = options;
436
437 QQuickColorDialogImplAttached *attached = d->attachedOrWarn();
438
439 if (attached) {
440 const auto *integration = QGuiApplicationPrivate::platformIntegration();
441 const bool canSupportEyeDropper =
442 integration->hasCapability(QPlatformIntegration::ScreenWindowGrabbing)
443 || integration->services()->hasCapability(QPlatformServices::Capability::ColorPicking);
444 const bool offscreen = qgetenv("QT_QPA_PLATFORM").compare(QLatin1String("offscreen"), Qt::CaseInsensitive) == 0;
445 const bool noEyeDropperButton = (d->options && d->options->options() & QColorDialogOptions::NoEyeDropperButton);
446 attached->eyeDropperButton()->setVisible(!noEyeDropperButton && canSupportEyeDropper && !offscreen);
447
448 if (d->options) {
449 attached->buttonBox()->setVisible(
450 !(d->options->options() & QColorDialogOptions::NoButtons));
451
452 const bool showAlpha = d->options->options() & QColorDialogOptions::ShowAlphaChannel;
453 attached->alphaSlider()->setVisible(showAlpha);
454 attached->colorInputs()->setShowAlpha(showAlpha);
455 }
456 }
457}
458
460{
462 d->eyeDropperEnter();
463}
464
467{
468 if (!qobject_cast<QQuickColorDialogImpl *>(parent)) {
469 qmlWarning(this) << "ColorDialogImpl attached properties should only be "
470 << "accessed through the root ColorDialogImpl instance";
471 }
472}
473
479
481{
483 if (d->buttonBox == buttonBox)
484 return;
485
486 if (d->buttonBox) {
487 QQuickColorDialogImpl *colorDialogImpl = qobject_cast<QQuickColorDialogImpl *>(parent());
488 if (colorDialogImpl) {
489 auto dialogPrivate = QQuickDialogPrivate::get(colorDialogImpl);
491 dialogPrivate, &QQuickDialogPrivate::handleAccept);
493 dialogPrivate, &QQuickDialogPrivate::handleReject);
495 dialogPrivate, &QQuickDialogPrivate::handleClick);
496 }
497 }
498
499 d->buttonBox = buttonBox;
500
501 if (d->buttonBox) {
502 QQuickColorDialogImpl *colorDialogImpl = qobject_cast<QQuickColorDialogImpl *>(parent());
503 if (colorDialogImpl) {
504 auto dialogPrivate = QQuickDialogPrivate::get(colorDialogImpl);
506 dialogPrivate, &QQuickDialogPrivate::handleAccept);
508 dialogPrivate, &QQuickDialogPrivate::handleReject);
510 dialogPrivate, &QQuickDialogPrivate::handleClick);
511 }
512 }
513
515}
516
518{
520 return d->eyeDropperButton;
521}
522
524{
526 Q_ASSERT(!d->eyeDropperButton);
527 if (d->eyeDropperButton == eyeDropperButton)
528 return;
529
530 d->eyeDropperButton = eyeDropperButton;
531 if (auto dialog = qobject_cast<QQuickColorDialogImpl *>(parent()))
534}
535
542{
544 if (d->colorPicker == colorPicker)
545 return;
546
547 if (d->colorPicker) {
548 QQuickColorDialogImpl *colorDialogImpl = qobject_cast<QQuickColorDialogImpl *>(parent());
549 if (colorDialogImpl) {
551 colorDialogImpl, &QQuickColorDialogImpl::setColor);
552 }
553 }
554
555 d->colorPicker = colorPicker;
556
557 if (d->colorPicker) {
558 QQuickColorDialogImpl *colorDialogImpl = qobject_cast<QQuickColorDialogImpl *>(parent());
559 if (colorDialogImpl) {
561 colorDialogImpl, &QQuickColorDialogImpl::setColor);
562 }
563 }
564
566}
567
569{
571 return d->alphaSlider;
572}
573
575{
577 if (d->alphaSlider == alphaSlider)
578 return;
579
580 if (d->alphaSlider) {
581 QQuickColorDialogImpl *colorDialogImpl = qobject_cast<QQuickColorDialogImpl *>(parent());
582 if (colorDialogImpl) {
583 auto dialogPrivate = QQuickColorDialogImplPrivate::get(colorDialogImpl);
584 QObjectPrivate::disconnect(d->alphaSlider, &QQuickSlider::moved,
586 }
587 }
588
589 d->alphaSlider = alphaSlider;
590
591 if (d->alphaSlider) {
592 QQuickColorDialogImpl *colorDialogImpl = qobject_cast<QQuickColorDialogImpl *>(parent());
593 if (colorDialogImpl) {
594 auto dialogPrivate = QQuickColorDialogImplPrivate::get(colorDialogImpl);
595 QObjectPrivate::connect(d->alphaSlider, &QQuickSlider::moved,
597 }
598 }
599
601}
602
604{
606 return d->colorInputs;
607}
608
610{
612
613 if (d->colorInputs == colorInputs)
614 return;
615
616 if (d->colorInputs) {
617 QQuickColorDialogImpl *colorDialogImpl = qobject_cast<QQuickColorDialogImpl *>(parent());
618 if (colorDialogImpl)
620 colorDialogImpl, &QQuickColorDialogImpl::setColor);
621 }
622
623 d->colorInputs = colorInputs;
624
625 if (d->colorInputs) {
626 QQuickColorDialogImpl *colorDialogImpl = qobject_cast<QQuickColorDialogImpl *>(parent());
627 if (colorDialogImpl)
629 colorDialogImpl, &QQuickColorDialogImpl::setColor);
630 }
631
633}
634
std::vector< ObjCStrongReference< CBMutableService > > services
The QColor class provides colors based on RGB, HSV or CMYK values.
Definition qcolor.h:31
@ Hsv
Definition qcolor.h:35
@ Hsl
Definition qcolor.h:35
static QColor fromHslF(float h, float s, float l, float a=1.0)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qcolor.cpp:2594
QRgb rgba() const noexcept
Returns the RGB value of the color, including its alpha.
Definition qcolor.cpp:1376
int red() const noexcept
Returns the red color component of this color.
Definition qcolor.cpp:1528
int blue() const noexcept
Returns the blue color component of this color.
Definition qcolor.cpp:1583
int green() const noexcept
Returns the green color component of this color.
Definition qcolor.cpp:1555
static QColor fromHsvF(float h, float s, float v, float a=1.0)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qcolor.cpp:2530
static QPoint pos()
Returns the position of the cursor (hot spot) of the primary screen in global screen coordinates.
Definition qcursor.cpp:188
\inmodule QtCore
Definition qcoreevent.h:45
@ MouseMove
Definition qcoreevent.h:63
@ KeyPress
Definition qcoreevent.h:64
@ MouseButtonPress
Definition qcoreevent.h:60
@ MouseButtonRelease
Definition qcoreevent.h:61
static QPlatformIntegration * platformIntegration()
QScreen * primaryScreen
the primary (or default) screen of the application.
static void setOverrideCursor(const QCursor &)
Sets the application override cursor to cursor.
static void restoreOverrideCursor()
Undoes the last setOverrideCursor().
static QScreen * screenAt(const QPoint &point)
Returns the screen at point, or \nullptr if outside of any screen.
\inmodule QtGui
Definition qimage.h:37
QRgb pixel(int x, int y) const
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qimage.cpp:2493
The QKeyEvent class describes a key event.
Definition qevent.h:424
\inmodule QtGui
Definition qevent.h:196
static QMetaObject::Connection connect(const typename QtPrivate::FunctionPointer< Func1 >::Object *sender, Func1 signal, const typename QtPrivate::FunctionPointer< Func2 >::Object *receiverPrivate, Func2 slot, Qt::ConnectionType type=Qt::AutoConnection)
Definition qobject_p.h:299
static bool disconnect(const typename QtPrivate::FunctionPointer< Func1 >::Object *sender, Func1 signal, const typename QtPrivate::FunctionPointer< Func2 >::Object *receiverPrivate, Func2 slot)
Definition qobject_p.h:328
\inmodule QtCore
Definition qobject.h:103
void installEventFilter(QObject *filterObj)
Installs an event filter filterObj on this object.
Definition qobject.cpp:2339
QObject * parent() const
Returns a pointer to the parent object.
Definition qobject.h:346
static QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
\threadsafe
Definition qobject.cpp:2960
virtual bool eventFilter(QObject *watched, QEvent *event)
Filters events if this object has been installed as an event filter for the watched object.
Definition qobject.cpp:1555
static bool disconnect(const QObject *sender, const char *signal, const QObject *receiver, const char *member)
\threadsafe
Definition qobject.cpp:3236
void removeEventFilter(QObject *obj)
Removes an event filter object obj from this object.
Definition qobject.cpp:2370
Returns a copy of the pixmap that is transformed using the given transformation transform and transfo...
Definition qpixmap.h:27
void colorPicked(const QColor &color)
\inmodule QtCore\reentrant
Definition qpoint.h:25
void clear() noexcept
Definition qpointer.h:87
bool isNull() const noexcept
Definition qpointer.h:84
void colorPicked(const QColor &color)
void setButtonBox(QQuickDialogButtonBox *buttonBox)
void setEyeDropperButton(QQuickAbstractButton *eyeDropperButton)
QQuickColorDialogImplAttached(QObject *parent=nullptr)
void setColorInputs(QQuickColorInputs *colorInputs)
void setColorPicker(QQuickAbstractColorPicker *colorPicker)
QQuickAbstractColorPicker * colorPicker
void setAlphaSlider(QQuickSlider *alphaSlider)
std::unique_ptr< QQuickEyeDropperEventFilter > eyeDropperEventFilter
void eyeDropperLeave(const QPoint &pos, QQuickEyeDropperEventFilter::LeaveReason actionOnLeave)
void handleClick(QQuickAbstractButton *button) override
static QQuickColorDialogImplPrivate * get(QQuickColorDialogImpl *dialog)
QQuickColorDialogImplAttached * attachedOrWarn()
void eyeDropperPointerMoved(const QPoint &pos)
QPointer< QQuickWindow > m_eyeDropperWindow
Q_INVOKABLE void invokeEyeDropper()
void setLightness(qreal lightness)
QQuickColorDialogImpl(QObject *parent=nullptr)
void setOptions(const QSharedPointer< QColorDialogOptions > &options)
QSharedPointer< QColorDialogOptions > options() const
static QQuickColorDialogImplAttached * qmlAttachedProperties(QObject *object)
void setSaturation(qreal saturation)
void setColor(const QColor &c)
void setShowAlpha(bool showAlpha)
void colorModified(const QColor &c)
void clicked(QQuickAbstractButton *button)
virtual void handleClick(QQuickAbstractButton *button)
static QQuickDialogPrivate * get(QQuickDialog *dialog)
virtual void handleAccept()
static QPlatformDialogHelper::ButtonRole buttonRole(QQuickAbstractButton *button)
Popup dialog with standard buttons and a title, used for short-term interaction with the user.
virtual void handleReject()
bool eventFilter(QObject *obj, QEvent *event) override
Filters events if this object has been installed as an event filter for the watched object.
void setVisible(bool)
QPointer< QQuickWindow > window
\inmodule QtCore\reentrant
Definition qrect.h:30
constexpr int x() const noexcept
Returns the x-coordinate of the rectangle's left edge.
Definition qrect.h:185
constexpr int y() const noexcept
Returns the y-coordinate of the rectangle's top edge.
Definition qrect.h:188
The QScreen class is used to query screen properties. \inmodule QtGui.
Definition qscreen.h:32
QRect geometry
the screen's geometry in pixels
Definition qscreen.h:45
QPixmap grabWindow(WId window=0, int x=0, int y=0, int w=-1, int h=-1)
Creates and returns a pixmap constructed by grabbing the contents of the given window restricted by Q...
Definition qscreen.cpp:685
QPushButton * button
[2]
void colorChanged()
Combined button and popup list for selecting options.
@ CrossCursor
@ Key_Escape
Definition qnamespace.h:663
@ Key_Return
Definition qnamespace.h:667
@ Key_Enter
Definition qnamespace.h:668
@ CaseInsensitive
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
bool qFuzzyCompare(qfloat16 p1, qfloat16 p2) noexcept
Definition qfloat16.h:333
#define qWarning
Definition qlogging.h:166
constexpr const T & qBound(const T &min, const T &val, const T &max)
Definition qminmax.h:44
static Q_DECL_CONST_FUNCTION bool qt_is_finite(double d)
Definition qnumeric_p.h:117
GLuint color
[2]
struct _cl_event * event
GLhandleARB obj
[2]
GLbyte GLbyte blue
Definition qopenglext.h:385
const GLubyte * c
GLdouble GLdouble GLdouble GLdouble q
Definition qopenglext.h:259
GLfloat GLfloat p
[1]
GLfloat GLfloat GLfloat alpha
Definition qopenglext.h:418
GLbyte green
Definition qopenglext.h:385
Q_QML_EXPORT QQmlInfo qmlWarning(const QObject *me)
QT_BEGIN_NAMESPACE QColor grabScreenColor(const QPoint &p)
std::pair< qreal, qreal > getSaturationAndLightness(qreal saturation, qreal value)
std::pair< qreal, qreal > getSaturationAndValue(qreal saturation, qreal lightness)
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
QLatin1StringView QLatin1String
Definition qstringfwd.h:31
QScreen * screen
[1]
Definition main.cpp:29
Q_CORE_EXPORT QByteArray qgetenv(const char *varName)
#define emit
double qreal
Definition qtypes.h:187
QFileDialog dialog(this)
[1]
widget render & pixmap
QGraphicsSvgItem * red