18QColor grabScreenColor(
const QPoint &p)
20 QScreen *screen = QGuiApplication::screenAt(p);
22 screen = QGuiApplication::primaryScreen();
23 const QRect screenRect = screen->geometry();
24 const QPixmap pixmap =
25 screen->grabWindow(0, p.x() - screenRect.x(), p.y() - screenRect.y(), 1, 1);
26 const QImage i = pixmap.toImage();
32 switch (event->type()) {
33 case QEvent::MouseMove: {
34 m_lastPosition =
static_cast<QMouseEvent *>(event)->globalPosition().toPoint();
35 m_update(m_lastPosition);
38 case QEvent::MouseButtonRelease: {
39 m_lastPosition =
static_cast<QMouseEvent *>(event)->globalPosition().toPoint();
40 m_leave(m_lastPosition, QQuickEyeDropperEventFilter::LeaveReason::Default);
43 case QEvent::MouseButtonPress:
45 case QEvent::KeyPress: {
46 auto keyEvent =
static_cast<QKeyEvent *>(event);
47#if QT_CONFIG(shortcut)
48 if (keyEvent->matches(QKeySequence::Cancel))
49 m_leave(m_lastPosition, QQuickEyeDropperEventFilter::LeaveReason::Cancel);
52 if (keyEvent->key() == Qt::Key_Return || keyEvent->key() == Qt::Key_Enter) {
53 m_leave(m_lastPosition, QQuickEyeDropperEventFilter::LeaveReason::Default);
54 }
else if (keyEvent->key() == Qt::Key_Escape) {
55 m_leave(m_lastPosition, QQuickEyeDropperEventFilter::LeaveReason::Cancel);
61 return QObject::eventFilter(obj, event);
86 Q_Q(QQuickColorDialogImpl);
87 QQuickColorDialogImplAttached *attached =
static_cast<QQuickColorDialogImplAttached *>(
88 qmlAttachedPropertiesObject<QQuickColorDialogImpl>(q,
false));
90 qmlWarning(q) <<
"Expected ColorDialogImpl attached object to be present on" <<
this;
96 Q_Q(QQuickColorDialogImpl);
100 if (m_eyeDropperWindow.isNull()) {
101 if (window.isNull()) {
102 qWarning() <<
"No window found, cannot enter eyeDropperMode.";
106 m_eyeDropperWindow = window;
109 if (
auto *platformServices = QGuiApplicationPrivate::platformIntegration()->services();
110 platformServices && platformServices->hasCapability(QPlatformServices::Capability::ColorPicking)) {
111 if (
auto *colorPickerService = platformServices->colorPicker(m_eyeDropperWindow)) {
112 q->connect(colorPickerService, &QPlatformServiceColorPicker::colorPicked, q,
113 [q, colorPickerService](
const QColor &color) {
114 colorPickerService->deleteLater();
117 colorPickerService->pickColor();
122 m_eyeDropperPreviousColor = q->color();
124 if (!
bool(eyeDropperEventFilter))
125 eyeDropperEventFilter.reset(
new QQuickEyeDropperEventFilter(
126 [
this](QPoint pos, QQuickEyeDropperEventFilter::LeaveReason c) {
127 eyeDropperLeave(pos, c);
129 [
this](QPoint pos) { eyeDropperPointerMoved(pos); }));
131 if (m_eyeDropperWindow->setMouseGrabEnabled(
true)) {
133 QGuiApplication::setOverrideCursor(Qt::CrossCursor);
135 m_eyeDropperWindow->installEventFilter(eyeDropperEventFilter.get());
143 Q_Q(QQuickColorDialogImpl);
148 if (!m_eyeDropperWindow) {
149 qWarning() <<
"Window not set, cannot leave eyeDropperMode.";
153 const QColor colorToUse = actionOnLeave == QQuickEyeDropperEventFilter::LeaveReason::Cancel
154 ? m_eyeDropperPreviousColor
155 : grabScreenColor(pos);
156 q->setColor(colorToUse);
158 m_eyeDropperWindow->removeEventFilter(eyeDropperEventFilter.get());
159 m_eyeDropperWindow->setMouseGrabEnabled(
false);
161 QGuiApplication::restoreOverrideCursor();
165 m_eyeDropperWindow.clear();
191QColor QQuickColorDialogImpl::color()
const
193 Q_D(
const QQuickColorDialogImpl);
194 return d->m_hsl ? QColor::fromHslF(d->m_hsva.h, d->m_hsva.s, d->m_hsva.l, d->m_hsva.a)
195 : QColor::fromHsvF(d->m_hsva.h, d->m_hsva.s, d->m_hsva.v, d->m_hsva.a);
198void QQuickColorDialogImpl::setColor(
const QColor &c)
200 Q_D(QQuickColorDialogImpl);
201 if (
const QColor old = color(); old.spec() == c.spec() && old == c)
207 if (c.spec() == QColor::Spec::Hsv) {
208 d->m_hsva.h = qBound(.0, c.hsvHueF(), 1.0);
210 const auto sl = getSaturationAndLightness(c.hsvSaturationF(), c.valueF());
211 d->m_hsva.s = qBound(.0, sl.first, 1.0);
212 d->m_hsva.l = qBound(.0, sl.second, 1.0);
214 d->m_hsva.s = qBound(.0, c.hsvSaturationF(), 1.0);
215 d->m_hsva.v = qBound(.0, c.valueF(), 1.0);
217 }
else if (c.spec() == QColor::Spec::Hsl) {
218 d->m_hsva.h = qBound(.0, c.hslHueF(), 1.0);
220 d->m_hsva.s = qBound(.0, c.hslSaturationF(), 1.0);
221 d->m_hsva.l = qBound(.0, c.lightnessF(), 1.0);
223 const auto sv = getSaturationAndValue(c.hslSaturationF(), c.lightnessF());
224 d->m_hsva.s = qBound(.0, sv.first, 1.0);
225 d->m_hsva.v = qBound(.0, sv.second, 1.0);
228 d->m_hsva.h = qBound(.0, d->m_hsl ? c.hslHueF() : c.hsvHueF(), 1.0);
229 d->m_hsva.s = qBound(.0, d->m_hsl ? c.hslSaturationF() : c.hsvSaturationF(), 1.0);
230 d->m_hsva.v = qBound(.0, d->m_hsl ? c.lightnessF() : c.valueF(), 1.0);
233 d->m_hsva.a = c.alphaF();
235 emit colorChanged(color());
243void QQuickColorDialogImpl::setRed(
int red)
245 Q_D(QQuickColorDialogImpl);
254 d->m_hsva.h = d->m_hsl ? c.hslHueF() : c.hsvHueF();
255 d->m_hsva.s = d->m_hsl ? c.hslSaturationF() : c.hsvSaturationF();
256 d->m_hsva.v = d->m_hsl ? c.lightnessF() : c.valueF();
257 d->m_hsva.a = c.alphaF();
259 emit colorChanged(c);
267void QQuickColorDialogImpl::setGreen(
int green)
269 Q_D(QQuickColorDialogImpl);
273 if (c.green() == green)
278 d->m_hsva.h = d->m_hsl ? c.hslHueF() : c.hsvHueF();
279 d->m_hsva.s = d->m_hsl ? c.hslSaturationF() : c.hsvSaturationF();
280 d->m_hsva.v = d->m_hsl ? c.lightnessF() : c.valueF();
281 d->m_hsva.a = c.alphaF();
283 emit colorChanged(c);
291void QQuickColorDialogImpl::setBlue(
int blue)
293 Q_D(QQuickColorDialogImpl);
297 if (c.blue() == blue)
302 d->m_hsva.h = d->m_hsl ? c.hslHueF() : c.hsvHueF();
303 d->m_hsva.s = d->m_hsl ? c.hslSaturationF() : c.hsvSaturationF();
304 d->m_hsva.v = d->m_hsl ? c.lightnessF() : c.valueF();
305 d->m_hsva.a = c.alphaF();
307 emit colorChanged(c);
316void QQuickColorDialogImpl::setAlpha(qreal alpha)
318 Q_D(QQuickColorDialogImpl);
320 if (!qt_is_finite(alpha))
323 alpha = qBound(.0, alpha, 1.0);
325 if (qFuzzyCompare(d->m_hsva.a, alpha))
330 emit colorChanged(color());
357void QQuickColorDialogImpl::setSaturation(qreal saturation)
359 Q_D(QQuickColorDialogImpl);
360 if (!qt_is_finite(saturation))
363 d->m_hsva.s = saturation;
365 emit colorChanged(color());
374void QQuickColorDialogImpl::setValue(qreal value)
376 Q_D(QQuickColorDialogImpl);
377 if (!qt_is_finite(value))
383 d->m_hsva.s = getSaturationAndValue(d->m_hsva.s, d->m_hsva.l).first;
386 emit colorChanged(color());
395void QQuickColorDialogImpl::setLightness(qreal lightness)
397 Q_D(QQuickColorDialogImpl);
398 if (!qt_is_finite(lightness))
401 d->m_hsva.l = lightness;
404 d->m_hsva.s = getSaturationAndLightness(d->m_hsva.s, d->m_hsva.v).first;
407 emit colorChanged(color());
433void QQuickColorDialogImpl::setOptions(
const QSharedPointer<QColorDialogOptions> &options)
435 Q_D(QQuickColorDialogImpl);
436 d->options = options;
438 QQuickColorDialogImplAttached *attached = d->attachedOrWarn();
441 const auto *integration = QGuiApplicationPrivate::platformIntegration();
442 const bool canSupportEyeDropper =
443 integration->hasCapability(QPlatformIntegration::ScreenWindowGrabbing)
444 || integration->services()->hasCapability(QPlatformServices::Capability::ColorPicking);
445 const bool offscreen = qgetenv(
"QT_QPA_PLATFORM").compare(QLatin1String(
"offscreen"), Qt::CaseInsensitive) == 0;
446 const bool noEyeDropperButton = (d->options && d->options->options() & QColorDialogOptions::NoEyeDropperButton);
447 attached->eyeDropperButton()->setVisible(!noEyeDropperButton && canSupportEyeDropper && !offscreen);
450 attached->buttonBox()->setVisible(
451 !(d->options->options() & QColorDialogOptions::NoButtons));
453 const bool showAlpha = d->options->options() & QColorDialogOptions::ShowAlphaChannel;
454 attached->alphaSlider()->setVisible(showAlpha);
455 attached->colorInputs()->setShowAlpha(showAlpha);
481void QQuickColorDialogImplAttached::setButtonBox(QQuickDialogButtonBox *buttonBox)
483 Q_D(QQuickColorDialogImplAttached);
484 if (d->buttonBox == buttonBox)
488 QQuickColorDialogImpl *colorDialogImpl = qobject_cast<QQuickColorDialogImpl *>(parent());
489 if (colorDialogImpl) {
490 auto dialogPrivate = QQuickDialogPrivate::get(colorDialogImpl);
491 QObjectPrivate::disconnect(d->buttonBox, &QQuickDialogButtonBox::accepted,
492 dialogPrivate, &QQuickDialogPrivate::handleAccept);
493 QObjectPrivate::disconnect(d->buttonBox, &QQuickDialogButtonBox::rejected,
494 dialogPrivate, &QQuickDialogPrivate::handleReject);
495 QObjectPrivate::disconnect(d->buttonBox, &QQuickDialogButtonBox::clicked,
496 dialogPrivate, &QQuickDialogPrivate::handleClick);
500 d->buttonBox = buttonBox;
503 QQuickColorDialogImpl *colorDialogImpl = qobject_cast<QQuickColorDialogImpl *>(parent());
504 if (colorDialogImpl) {
505 auto dialogPrivate = QQuickDialogPrivate::get(colorDialogImpl);
506 QObjectPrivate::connect(d->buttonBox, &QQuickDialogButtonBox::accepted,
507 dialogPrivate, &QQuickDialogPrivate::handleAccept);
508 QObjectPrivate::connect(d->buttonBox, &QQuickDialogButtonBox::rejected,
509 dialogPrivate, &QQuickDialogPrivate::handleReject);
510 QObjectPrivate::connect(d->buttonBox, &QQuickDialogButtonBox::clicked,
511 dialogPrivate, &QQuickDialogPrivate::handleClick);
515 emit buttonBoxChanged();
524void QQuickColorDialogImplAttached::setEyeDropperButton(QQuickAbstractButton *eyeDropperButton)
526 Q_D(QQuickColorDialogImplAttached);
527 Q_ASSERT(!d->eyeDropperButton);
528 if (d->eyeDropperButton == eyeDropperButton)
531 d->eyeDropperButton = eyeDropperButton;
532 if (
auto dialog = qobject_cast<QQuickColorDialogImpl *>(parent()))
533 connect(d->eyeDropperButton, &QQuickAbstractButton::clicked, dialog, &QQuickColorDialogImpl::invokeEyeDropper);
534 emit eyeDropperButtonChanged();
542void QQuickColorDialogImplAttached::setColorPicker(QQuickAbstractColorPicker *colorPicker)
544 Q_D(QQuickColorDialogImplAttached);
545 if (d->colorPicker == colorPicker)
548 if (d->colorPicker) {
549 QQuickColorDialogImpl *colorDialogImpl = qobject_cast<QQuickColorDialogImpl *>(parent());
550 if (colorDialogImpl) {
551 QObject::disconnect(d->colorPicker, &QQuickAbstractColorPicker::colorPicked,
552 colorDialogImpl, &QQuickColorDialogImpl::setColor);
556 d->colorPicker = colorPicker;
558 if (d->colorPicker) {
559 QQuickColorDialogImpl *colorDialogImpl = qobject_cast<QQuickColorDialogImpl *>(parent());
560 if (colorDialogImpl) {
561 QObject::connect(d->colorPicker, &QQuickAbstractColorPicker::colorPicked,
562 colorDialogImpl, &QQuickColorDialogImpl::setColor);
566 emit colorPickerChanged();
575void QQuickColorDialogImplAttached::setAlphaSlider(QQuickSlider *alphaSlider)
577 Q_D(QQuickColorDialogImplAttached);
578 if (d->alphaSlider == alphaSlider)
581 if (d->alphaSlider) {
582 QQuickColorDialogImpl *colorDialogImpl = qobject_cast<QQuickColorDialogImpl *>(parent());
583 if (colorDialogImpl) {
584 auto dialogPrivate = QQuickColorDialogImplPrivate::get(colorDialogImpl);
585 QObjectPrivate::disconnect(d->alphaSlider, &QQuickSlider::moved,
586 dialogPrivate, &QQuickColorDialogImplPrivate::alphaSliderMoved);
590 d->alphaSlider = alphaSlider;
592 if (d->alphaSlider) {
593 QQuickColorDialogImpl *colorDialogImpl = qobject_cast<QQuickColorDialogImpl *>(parent());
594 if (colorDialogImpl) {
595 auto dialogPrivate = QQuickColorDialogImplPrivate::get(colorDialogImpl);
596 QObjectPrivate::connect(d->alphaSlider, &QQuickSlider::moved,
597 dialogPrivate, &QQuickColorDialogImplPrivate::alphaSliderMoved);
601 emit alphaSliderChanged();
610void QQuickColorDialogImplAttached::setColorInputs(QQuickColorInputs *colorInputs)
612 Q_D(QQuickColorDialogImplAttached);
614 if (d->colorInputs == colorInputs)
617 if (d->colorInputs) {
618 QQuickColorDialogImpl *colorDialogImpl = qobject_cast<QQuickColorDialogImpl *>(parent());
620 QObject::disconnect(d->colorInputs, &QQuickColorInputs::colorModified,
621 colorDialogImpl, &QQuickColorDialogImpl::setColor);
624 d->colorInputs = colorInputs;
626 if (d->colorInputs) {
627 QQuickColorDialogImpl *colorDialogImpl = qobject_cast<QQuickColorDialogImpl *>(parent());
629 QObject::connect(d->colorInputs, &QQuickColorInputs::colorModified,
630 colorDialogImpl, &QQuickColorDialogImpl::setColor);
633 emit colorInputsChanged();