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);
466void QQuickColorDialogImpl::itemChange(QQuickItem::ItemChange change,
const QQuickItem::ItemChangeData &data)
468 Q_D(QQuickColorDialogImpl);
469 QQuickDialog::itemChange(change, data);
471 if (change != QQuickItem::ItemVisibleHasChanged || !isComponentComplete() || !data.boolValue)
474 if (QQuickColorDialogImplAttached *attached = d->attachedOrWarn(); attached && attached->buttonBox())
475 attached->buttonBox()->forceActiveFocus(Qt::OtherFocusReason);
493void QQuickColorDialogImplAttached::setButtonBox(QQuickDialogButtonBox *buttonBox)
495 Q_D(QQuickColorDialogImplAttached);
496 if (d->buttonBox == buttonBox)
500 QQuickColorDialogImpl *colorDialogImpl = qobject_cast<QQuickColorDialogImpl *>(parent());
501 if (colorDialogImpl) {
502 auto dialogPrivate = QQuickDialogPrivate::get(colorDialogImpl);
503 QObjectPrivate::disconnect(d->buttonBox, &QQuickDialogButtonBox::accepted,
504 dialogPrivate, &QQuickDialogPrivate::handleAccept);
505 QObjectPrivate::disconnect(d->buttonBox, &QQuickDialogButtonBox::rejected,
506 dialogPrivate, &QQuickDialogPrivate::handleReject);
507 QObjectPrivate::disconnect(d->buttonBox, &QQuickDialogButtonBox::clicked,
508 dialogPrivate, &QQuickDialogPrivate::handleClick);
512 d->buttonBox = buttonBox;
515 QQuickColorDialogImpl *colorDialogImpl = qobject_cast<QQuickColorDialogImpl *>(parent());
516 if (colorDialogImpl) {
517 auto dialogPrivate = QQuickDialogPrivate::get(colorDialogImpl);
518 QObjectPrivate::connect(d->buttonBox, &QQuickDialogButtonBox::accepted,
519 dialogPrivate, &QQuickDialogPrivate::handleAccept);
520 QObjectPrivate::connect(d->buttonBox, &QQuickDialogButtonBox::rejected,
521 dialogPrivate, &QQuickDialogPrivate::handleReject);
522 QObjectPrivate::connect(d->buttonBox, &QQuickDialogButtonBox::clicked,
523 dialogPrivate, &QQuickDialogPrivate::handleClick);
527 emit buttonBoxChanged();
536void QQuickColorDialogImplAttached::setEyeDropperButton(QQuickAbstractButton *eyeDropperButton)
538 Q_D(QQuickColorDialogImplAttached);
539 Q_ASSERT(!d->eyeDropperButton);
540 if (d->eyeDropperButton == eyeDropperButton)
543 d->eyeDropperButton = eyeDropperButton;
544 if (
auto dialog = qobject_cast<QQuickColorDialogImpl *>(parent()))
545 connect(d->eyeDropperButton, &QQuickAbstractButton::clicked, dialog, &QQuickColorDialogImpl::invokeEyeDropper);
546 emit eyeDropperButtonChanged();
554void QQuickColorDialogImplAttached::setColorPicker(QQuickAbstractColorPicker *colorPicker)
556 Q_D(QQuickColorDialogImplAttached);
557 if (d->colorPicker == colorPicker)
560 if (d->colorPicker) {
561 QQuickColorDialogImpl *colorDialogImpl = qobject_cast<QQuickColorDialogImpl *>(parent());
562 if (colorDialogImpl) {
563 QObject::disconnect(d->colorPicker, &QQuickAbstractColorPicker::colorPicked,
564 colorDialogImpl, &QQuickColorDialogImpl::setColor);
568 d->colorPicker = colorPicker;
570 if (d->colorPicker) {
571 QQuickColorDialogImpl *colorDialogImpl = qobject_cast<QQuickColorDialogImpl *>(parent());
572 if (colorDialogImpl) {
573 QObject::connect(d->colorPicker, &QQuickAbstractColorPicker::colorPicked,
574 colorDialogImpl, &QQuickColorDialogImpl::setColor);
578 emit colorPickerChanged();
587void QQuickColorDialogImplAttached::setAlphaSlider(QQuickSlider *alphaSlider)
589 Q_D(QQuickColorDialogImplAttached);
590 if (d->alphaSlider == alphaSlider)
593 if (d->alphaSlider) {
594 QQuickColorDialogImpl *colorDialogImpl = qobject_cast<QQuickColorDialogImpl *>(parent());
595 if (colorDialogImpl) {
596 auto dialogPrivate = QQuickColorDialogImplPrivate::get(colorDialogImpl);
597 QObjectPrivate::disconnect(d->alphaSlider, &QQuickSlider::moved,
598 dialogPrivate, &QQuickColorDialogImplPrivate::alphaSliderMoved);
602 d->alphaSlider = alphaSlider;
604 if (d->alphaSlider) {
605 QQuickColorDialogImpl *colorDialogImpl = qobject_cast<QQuickColorDialogImpl *>(parent());
606 if (colorDialogImpl) {
607 auto dialogPrivate = QQuickColorDialogImplPrivate::get(colorDialogImpl);
608 QObjectPrivate::connect(d->alphaSlider, &QQuickSlider::moved,
609 dialogPrivate, &QQuickColorDialogImplPrivate::alphaSliderMoved);
613 emit alphaSliderChanged();
622void QQuickColorDialogImplAttached::setColorInputs(QQuickColorInputs *colorInputs)
624 Q_D(QQuickColorDialogImplAttached);
626 if (d->colorInputs == colorInputs)
629 if (d->colorInputs) {
630 QQuickColorDialogImpl *colorDialogImpl = qobject_cast<QQuickColorDialogImpl *>(parent());
632 QObject::disconnect(d->colorInputs, &QQuickColorInputs::colorModified,
633 colorDialogImpl, &QQuickColorDialogImpl::setColor);
636 d->colorInputs = colorInputs;
638 if (d->colorInputs) {
639 QQuickColorDialogImpl *colorDialogImpl = qobject_cast<QQuickColorDialogImpl *>(parent());
641 QObject::connect(d->colorInputs, &QQuickColorInputs::colorModified,
642 colorDialogImpl, &QQuickColorDialogImpl::setColor);
645 emit colorInputsChanged();