Qt 6.x
The Qt SDK
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 <private/qguiapplication_p.h>
13
15
17{
19 if (!screen)
21 const QRect screenRect = screen->geometry();
22 const QPixmap pixmap =
23 screen->grabWindow(0, p.x() - screenRect.x(), p.y() - screenRect.y(), 1, 1);
24 const QImage i = pixmap.toImage();
25 return i.pixel(0, 0);
26}
27
29{
30 switch (event->type()) {
31 case QEvent::MouseMove: {
32 m_lastPosition = static_cast<QMouseEvent *>(event)->globalPosition().toPoint();
33 m_update(m_lastPosition);
34 return true;
35 }
37 m_lastPosition = static_cast<QMouseEvent *>(event)->globalPosition().toPoint();
39 return true;
40 }
42 return true;
43 case QEvent::KeyPress: {
44 auto keyEvent = static_cast<QKeyEvent *>(event);
45#if QT_CONFIG(shortcut)
46 if (keyEvent->matches(QKeySequence::Cancel))
48 else
49#endif
50 if (keyEvent->key() == Qt::Key_Return || keyEvent->key() == Qt::Key_Enter) {
52 } else if (keyEvent->key() == Qt::Key_Escape) {
54 }
55 keyEvent->accept();
56 return true;
57 }
58 default:
60 }
61}
62
64
66{
69}
70
72{
74 const auto c = q->color();
76 q->setColor(c);
77 q->accept();
78 }
80}
81
83{
86 qmlAttachedPropertiesObject<QQuickColorDialogImpl>(q, false));
87 if (!attached)
88 qmlWarning(q) << "Expected ColorDialogImpl attached object to be present on" << this;
89 return attached;
90}
91
93{
94 Q_Q(const QQuickColorDialogImpl);
96 return;
97
99 if (window.isNull()) {
100 qWarning() << "No window found, cannot enter eyeDropperMode.";
101 return;
102 }
103
105 }
106
107 m_eyeDropperPreviousColor = q->color();
108
109 if (!bool(eyeDropperEventFilter))
113 },
114 [this](QPoint pos) { eyeDropperPointerMoved(pos); }));
115
116 if (m_eyeDropperWindow->setMouseGrabEnabled(true)) {
117#if QT_CONFIG(cursor)
119#endif
121 m_eyeDropperMode = true;
122 }
123}
124
127{
129
130 if (!m_eyeDropperMode)
131 return;
132
133 if (!m_eyeDropperWindow) {
134 qWarning() << "Window not set, cannot leave eyeDropperMode.";
135 return;
136 }
137
138 const QColor colorToUse = actionOnLeave == QQuickEyeDropperEventFilter::LeaveReason::Cancel
141 q->setColor(colorToUse);
142
144 m_eyeDropperWindow->setMouseGrabEnabled(false);
145#if QT_CONFIG(cursor)
147#endif
148
149 m_eyeDropperMode = false;
151}
152
154{
156 q->setColor(grabScreenColor(pos));
157}
158
160{
162 if (auto attached = attachedOrWarn())
163 q->setAlpha(attached->alphaSlider()->value());
164}
165
168{
169}
170
172{
173 return new QQuickColorDialogImplAttached(object);
174}
175
177{
178 Q_D(const QQuickColorDialogImpl);
179 return d->m_hsl ? QColor::fromHslF(d->m_hsva.h, d->m_hsva.s, d->m_hsva.l, d->m_hsva.a)
180 : QColor::fromHsvF(d->m_hsva.h, d->m_hsva.s, d->m_hsva.v, d->m_hsva.a);
181}
182
184{
186 if (color().rgba() == c.rgba())
187 return;
188
189 // If we get a QColor from an Hsv or Hsl color system,
190 // we want to get the raw values without the risk of QColor converting them,
191 // and possible deleting relevant information for achromatic cases.
192 if (c.spec() == QColor::Spec::Hsv) {
193 d->m_hsva.h = qBound(.0, c.hsvHueF(), 1.0);
194 if (d->m_hsl) {
195 const auto sl = getSaturationAndLightness(c.hsvSaturationF(), c.valueF());
196 d->m_hsva.s = qBound(.0, sl.first, 1.0);
197 d->m_hsva.l = qBound(.0, sl.second, 1.0);
198 } else {
199 d->m_hsva.s = qBound(.0, c.hsvSaturationF(), 1.0);
200 d->m_hsva.v = qBound(.0, c.valueF(), 1.0);
201 }
202 } else if (c.spec() == QColor::Spec::Hsl) {
203 d->m_hsva.h = qBound(.0, c.hslHueF(), 1.0);
204 if (d->m_hsl) {
205 d->m_hsva.s = qBound(.0, c.hslSaturationF(), 1.0);
206 d->m_hsva.l = qBound(.0, c.lightnessF(), 1.0);
207 } else {
208 const auto sv = getSaturationAndValue(c.hslSaturationF(), c.lightnessF());
209 d->m_hsva.s = qBound(.0, sv.first, 1.0);
210 d->m_hsva.v = qBound(.0, sv.second, 1.0);
211 }
212 } else {
213 d->m_hsva.h = qBound(.0, d->m_hsl ? c.hslHueF() : c.hsvHueF(), 1.0);
214 d->m_hsva.s = qBound(.0, d->m_hsl ? c.hslSaturationF() : c.hsvSaturationF(), 1.0);
215 d->m_hsva.v = qBound(.0, d->m_hsl ? c.lightnessF() : c.valueF(), 1.0);
216 }
217
218 d->m_hsva.a = c.alphaF();
219
221}
222
224{
225 return color().red();
226}
227
229{
231
232 auto c = color();
233
234 if (c.red() == red)
235 return;
236
237 c.setRed(red);
238
239 d->m_hsva.h = d->m_hsl ? c.hslHueF() : c.hsvHueF();
240 d->m_hsva.s = d->m_hsl ? c.hslSaturationF() : c.hsvSaturationF();
241 d->m_hsva.v = d->m_hsl ? c.lightnessF() : c.valueF();
242 d->m_hsva.a = c.alphaF();
243
245}
246
248{
249 return color().green();
250}
251
253{
255
256 auto c = color();
257
258 if (c.green() == green)
259 return;
260
261 c.setGreen(green);
262
263 d->m_hsva.h = d->m_hsl ? c.hslHueF() : c.hsvHueF();
264 d->m_hsva.s = d->m_hsl ? c.hslSaturationF() : c.hsvSaturationF();
265 d->m_hsva.v = d->m_hsl ? c.lightnessF() : c.valueF();
266 d->m_hsva.a = c.alphaF();
267
269}
270
272{
273 return color().blue();
274}
275
277{
279
280 auto c = color();
281
282 if (c.blue() == blue)
283 return;
284
285 c.setBlue(blue);
286
287 d->m_hsva.h = d->m_hsl ? c.hslHueF() : c.hsvHueF();
288 d->m_hsva.s = d->m_hsl ? c.hslSaturationF() : c.hsvSaturationF();
289 d->m_hsva.v = d->m_hsl ? c.lightnessF() : c.valueF();
290 d->m_hsva.a = c.alphaF();
291
293}
294
296{
297 Q_D(const QQuickColorDialogImpl);
298 return d->m_hsva.a;
299}
300
302{
304
305 if (!qt_is_finite(alpha))
306 return;
307
308 alpha = qBound(.0, alpha, 1.0);
309
310 if (qFuzzyCompare(d->m_hsva.a, alpha))
311 return;
312
313 d->m_hsva.a = alpha;
314
316}
317
319{
320 Q_D(const QQuickColorDialogImpl);
321 return d->m_hsva.h;
322}
323
325{
327
328 if (!qt_is_finite(hue))
329 return;
330
331 d->m_hsva.h = hue;
332
334}
335
337{
338 Q_D(const QQuickColorDialogImpl);
339 return d->m_hsva.s;
340}
341
343{
346 return;
347
348 d->m_hsva.s = saturation;
349
351}
352
354{
355 Q_D(const QQuickColorDialogImpl);
356 return d->m_hsl ? getSaturationAndValue(d->m_hsva.s, d->m_hsva.l).second : d->m_hsva.v;
357}
358
360{
362 if (!qt_is_finite(value))
363 return;
364
365 d->m_hsva.v = value;
366
367 if (d->m_hsl)
368 d->m_hsva.s = getSaturationAndValue(d->m_hsva.s, d->m_hsva.l).first;
369
370 d->m_hsl = false;
372}
373
375{
376 Q_D(const QQuickColorDialogImpl);
377 return d->m_hsl ? d->m_hsva.l : getSaturationAndLightness(d->m_hsva.s, d->m_hsva.v).second;
378}
379
381{
384 return;
385
386 d->m_hsva.l = lightness;
387
388 if (!d->m_hsl)
389 d->m_hsva.s = getSaturationAndLightness(d->m_hsva.s, d->m_hsva.v).first;
390
391 d->m_hsl = true;
393}
394
396{
397 Q_D(const QQuickColorDialogImpl);
398 return d->m_hsl;
399}
400
402{
404
405 if (d->m_hsl == hsl)
406 return;
407
408 d->m_hsl = hsl;
410}
411
413{
414 Q_D(const QQuickColorDialogImpl);
415 return d->options;
416}
417
419{
421 d->options = options;
422
423 QQuickColorDialogImplAttached *attached = d->attachedOrWarn();
424
425 if (attached) {
427 const bool offscreen = qgetenv("QT_QPA_PLATFORM").compare(QLatin1String("offscreen"), Qt::CaseInsensitive) == 0;
428 const bool noEyeDropperButton = (d->options && d->options->options() & QColorDialogOptions::NoEyeDropperButton);
429 attached->eyeDropperButton()->setVisible(!noEyeDropperButton && screenGrabbingAllowed && !offscreen);
430
431 if (d->options) {
432 attached->buttonBox()->setVisible(
433 !(d->options->options() & QColorDialogOptions::NoButtons));
434
435 const bool showAlpha = d->options->options() & QColorDialogOptions::ShowAlphaChannel;
436 attached->alphaSlider()->setVisible(showAlpha);
437 attached->colorInputs()->setShowAlpha(showAlpha);
438 }
439 }
440}
441
443{
445 d->eyeDropperEnter();
446}
447
450{
451 if (!qobject_cast<QQuickColorDialogImpl *>(parent)) {
452 qmlWarning(this) << "ColorDialogImpl attached properties should only be "
453 << "accessed through the root ColorDialogImpl instance";
454 }
455}
456
458{
460 return d->buttonBox;
461}
462
464{
466 if (d->buttonBox == buttonBox)
467 return;
468
469 if (d->buttonBox) {
470 QQuickColorDialogImpl *colorDialogImpl = qobject_cast<QQuickColorDialogImpl *>(parent());
471 if (colorDialogImpl) {
472 auto dialogPrivate = QQuickDialogPrivate::get(colorDialogImpl);
474 dialogPrivate, &QQuickDialogPrivate::handleAccept);
476 dialogPrivate, &QQuickDialogPrivate::handleReject);
478 dialogPrivate, &QQuickDialogPrivate::handleClick);
479 }
480 }
481
482 d->buttonBox = buttonBox;
483
484 if (d->buttonBox) {
485 QQuickColorDialogImpl *colorDialogImpl = qobject_cast<QQuickColorDialogImpl *>(parent());
486 if (colorDialogImpl) {
487 auto dialogPrivate = QQuickDialogPrivate::get(colorDialogImpl);
489 dialogPrivate, &QQuickDialogPrivate::handleAccept);
491 dialogPrivate, &QQuickDialogPrivate::handleReject);
493 dialogPrivate, &QQuickDialogPrivate::handleClick);
494 }
495 }
496
498}
499
501{
503 return d->eyeDropperButton;
504}
505
507{
509 Q_ASSERT(!d->eyeDropperButton);
510 if (d->eyeDropperButton == eyeDropperButton)
511 return;
512
513 d->eyeDropperButton = eyeDropperButton;
514 if (auto dialog = qobject_cast<QQuickColorDialogImpl *>(parent()))
517}
518
520{
522 return d->colorPicker;
523}
525{
527 if (d->colorPicker == colorPicker)
528 return;
529
530 if (d->colorPicker) {
531 QQuickColorDialogImpl *colorDialogImpl = qobject_cast<QQuickColorDialogImpl *>(parent());
532 if (colorDialogImpl) {
534 colorDialogImpl, &QQuickColorDialogImpl::setColor);
535 }
536 }
537
538 d->colorPicker = colorPicker;
539
540 if (d->colorPicker) {
541 QQuickColorDialogImpl *colorDialogImpl = qobject_cast<QQuickColorDialogImpl *>(parent());
542 if (colorDialogImpl) {
544 colorDialogImpl, &QQuickColorDialogImpl::setColor);
545 }
546 }
547
549}
550
552{
554 return d->alphaSlider;
555}
556
558{
560 if (d->alphaSlider == alphaSlider)
561 return;
562
563 if (d->alphaSlider) {
564 QQuickColorDialogImpl *colorDialogImpl = qobject_cast<QQuickColorDialogImpl *>(parent());
565 if (colorDialogImpl) {
566 auto dialogPrivate = QQuickColorDialogImplPrivate::get(colorDialogImpl);
567 QObjectPrivate::disconnect(d->alphaSlider, &QQuickSlider::moved,
569 }
570 }
571
572 d->alphaSlider = alphaSlider;
573
574 if (d->alphaSlider) {
575 QQuickColorDialogImpl *colorDialogImpl = qobject_cast<QQuickColorDialogImpl *>(parent());
576 if (colorDialogImpl) {
577 auto dialogPrivate = QQuickColorDialogImplPrivate::get(colorDialogImpl);
578 QObjectPrivate::connect(d->alphaSlider, &QQuickSlider::moved,
580 }
581 }
582
584}
585
587{
589 return d->colorInputs;
590}
591
593{
595
596 if (d->colorInputs == colorInputs)
597 return;
598
599 if (d->colorInputs) {
600 QQuickColorDialogImpl *colorDialogImpl = qobject_cast<QQuickColorDialogImpl *>(parent());
601 if (colorDialogImpl)
603 colorDialogImpl, &QQuickColorDialogImpl::setColor);
604 }
605
606 d->colorInputs = colorInputs;
607
608 if (d->colorInputs) {
609 QQuickColorDialogImpl *colorDialogImpl = qobject_cast<QQuickColorDialogImpl *>(parent());
610 if (colorDialogImpl)
612 colorDialogImpl, &QQuickColorDialogImpl::setColor);
613 }
614
616}
617
int compare(QByteArrayView a, Qt::CaseSensitivity cs=Qt::CaseSensitive) const noexcept
Definition qbytearray.h:587
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
The QKeyEvent class describes a key event.
Definition qevent.h:423
\inmodule QtGui
Definition qevent.h:195
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:298
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:327
\inmodule QtCore
Definition qobject.h:90
void installEventFilter(QObject *filterObj)
Installs an event filter filterObj on this object.
Definition qobject.cpp:2269
QObject * parent() const
Returns a pointer to the parent object.
Definition qobject.h:311
static QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
\threadsafe
Definition qobject.cpp:2823
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:1518
static bool disconnect(const QObject *sender, const char *signal, const QObject *receiver, const char *member)
\threadsafe
Definition qobject.cpp:3099
void removeEventFilter(QObject *obj)
Removes an event filter object obj from this object.
Definition qobject.cpp:2300
Returns a copy of the pixmap that is transformed using the given transformation transform and transfo...
Definition qpixmap.h:27
virtual bool hasCapability(Capability cap) const
\inmodule QtCore\reentrant
Definition qpoint.h:23
void clear()
Definition qpointer.h:70
bool isNull() const
Returns true if the referenced object has been destroyed or if there is no referenced object; otherwi...
Definition qpointer.h:67
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 colorChanged(const QColor &color)
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:184
constexpr int y() const noexcept
Returns the y-coordinate of the rectangle's top edge.
Definition qrect.h:187
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
\inmodule QtCore
QPushButton * button
[2]
Combined button and popup list for selecting options.
@ CrossCursor
@ Key_Escape
Definition qnamespace.h:658
@ Key_Return
Definition qnamespace.h:662
@ Key_Enter
Definition qnamespace.h:663
@ CaseInsensitive
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
bool qFuzzyCompare(qfloat16 p1, qfloat16 p2) noexcept
Definition qfloat16.h:287
#define qWarning
Definition qlogging.h:162
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:111
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:92
QFileDialog dialog(this)
[1]
widget render & pixmap
QGraphicsSvgItem * red
IUIAutomationTreeWalker __RPC__deref_out_opt IUIAutomationElement ** parent