| 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 | |
| 4 | #include "qquickcolordialogimpl_p.h" |
| 5 | #include "qquickcolordialogimpl_p_p.h" |
| 6 | |
| 7 | #include "qquickcolordialogutils_p.h" |
| 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 | |
| 15 | QT_BEGIN_NAMESPACE |
| 16 | |
| 17 | QColor grabScreenColor(const QPoint &p) |
| 18 | { |
| 19 | QScreen *screen = QGuiApplication::screenAt(point: p); |
| 20 | if (!screen) |
| 21 | screen = QGuiApplication::primaryScreen(); |
| 22 | const QRect screenRect = screen->geometry(); |
| 23 | const QPixmap pixmap = |
| 24 | screen->grabWindow(window: 0, x: p.x() - screenRect.x(), y: p.y() - screenRect.y(), w: 1, h: 1); |
| 25 | const QImage i = pixmap.toImage(); |
| 26 | return i.pixel(x: 0, y: 0); |
| 27 | } |
| 28 | |
| 29 | bool QQuickEyeDropperEventFilter::eventFilter(QObject *obj, QEvent *event) |
| 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 | } |
| 37 | case QEvent::MouseButtonRelease: { |
| 38 | m_lastPosition = static_cast<QMouseEvent *>(event)->globalPosition().toPoint(); |
| 39 | m_leave(m_lastPosition, QQuickEyeDropperEventFilter::LeaveReason::Default); |
| 40 | return true; |
| 41 | } |
| 42 | case QEvent::MouseButtonPress: |
| 43 | return true; |
| 44 | case QEvent::KeyPress: { |
| 45 | auto keyEvent = static_cast<QKeyEvent *>(event); |
| 46 | #if QT_CONFIG(shortcut) |
| 47 | if (keyEvent->matches(key: QKeySequence::Cancel)) |
| 48 | m_leave(m_lastPosition, QQuickEyeDropperEventFilter::LeaveReason::Cancel); |
| 49 | else |
| 50 | #endif |
| 51 | if (keyEvent->key() == Qt::Key_Return || keyEvent->key() == Qt::Key_Enter) { |
| 52 | m_leave(m_lastPosition, QQuickEyeDropperEventFilter::LeaveReason::Default); |
| 53 | } else if (keyEvent->key() == Qt::Key_Escape) { |
| 54 | m_leave(m_lastPosition, QQuickEyeDropperEventFilter::LeaveReason::Cancel); |
| 55 | } |
| 56 | keyEvent->accept(); |
| 57 | return true; |
| 58 | } |
| 59 | default: |
| 60 | return QObject::eventFilter(watched: obj, event); |
| 61 | } |
| 62 | } |
| 63 | |
| 64 | QQuickColorDialogImplPrivate::QQuickColorDialogImplPrivate() = default; |
| 65 | |
| 66 | QQuickColorDialogImplPrivate::~QQuickColorDialogImplPrivate() |
| 67 | { |
| 68 | if (m_eyeDropperMode) |
| 69 | eyeDropperLeave(pos: QCursor::pos(), actionOnLeave: QQuickEyeDropperEventFilter::LeaveReason::Default); |
| 70 | } |
| 71 | |
| 72 | void QQuickColorDialogImplPrivate::handleClick(QQuickAbstractButton *button) |
| 73 | { |
| 74 | Q_Q(QQuickColorDialogImpl); |
| 75 | const auto c = q->color(); |
| 76 | if (buttonRole(button) == QPlatformDialogHelper::AcceptRole && c.isValid()) { |
| 77 | q->setColor(c); |
| 78 | q->accept(); |
| 79 | } |
| 80 | QQuickDialogPrivate::handleClick(button); |
| 81 | } |
| 82 | |
| 83 | QQuickColorDialogImplAttached *QQuickColorDialogImplPrivate::attachedOrWarn() |
| 84 | { |
| 85 | Q_Q(QQuickColorDialogImpl); |
| 86 | QQuickColorDialogImplAttached *attached = static_cast<QQuickColorDialogImplAttached *>( |
| 87 | qmlAttachedPropertiesObject<QQuickColorDialogImpl>(obj: q, create: false)); |
| 88 | if (!attached) |
| 89 | qmlWarning(me: q) << "Expected ColorDialogImpl attached object to be present on" << this; |
| 90 | return attached; |
| 91 | } |
| 92 | |
| 93 | void QQuickColorDialogImplPrivate::eyeDropperEnter() |
| 94 | { |
| 95 | Q_Q(QQuickColorDialogImpl); |
| 96 | if (m_eyeDropperMode) |
| 97 | return; |
| 98 | |
| 99 | if (m_eyeDropperWindow.isNull()) { |
| 100 | if (window.isNull()) { |
| 101 | qWarning() << "No window found, cannot enter eyeDropperMode." ; |
| 102 | return; |
| 103 | } |
| 104 | |
| 105 | m_eyeDropperWindow = window; |
| 106 | } |
| 107 | |
| 108 | if (auto *platformServices = QGuiApplicationPrivate::platformIntegration()->services(); |
| 109 | platformServices && platformServices->hasCapability(capability: QPlatformServices::Capability::ColorPicking)) { |
| 110 | if (auto *colorPickerService = platformServices->colorPicker(parent: m_eyeDropperWindow)) { |
| 111 | q->connect(sender: colorPickerService, signal: &QPlatformServiceColorPicker::colorPicked, context: q, |
| 112 | slot: [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)) |
| 124 | eyeDropperEventFilter.reset(p: new QQuickEyeDropperEventFilter( |
| 125 | [this](QPoint pos, QQuickEyeDropperEventFilter::LeaveReason c) { |
| 126 | eyeDropperLeave(pos, actionOnLeave: c); |
| 127 | }, |
| 128 | [this](QPoint pos) { eyeDropperPointerMoved(pos); })); |
| 129 | |
| 130 | if (m_eyeDropperWindow->setMouseGrabEnabled(true)) { |
| 131 | #if QT_CONFIG(cursor) |
| 132 | QGuiApplication::setOverrideCursor(Qt::CrossCursor); |
| 133 | #endif |
| 134 | m_eyeDropperWindow->installEventFilter(filterObj: eyeDropperEventFilter.get()); |
| 135 | m_eyeDropperMode = true; |
| 136 | } |
| 137 | } |
| 138 | |
| 139 | void QQuickColorDialogImplPrivate::eyeDropperLeave( |
| 140 | const QPoint &pos, QQuickEyeDropperEventFilter::LeaveReason actionOnLeave) |
| 141 | { |
| 142 | Q_Q(QQuickColorDialogImpl); |
| 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 |
| 153 | ? m_eyeDropperPreviousColor |
| 154 | : grabScreenColor(p: pos); |
| 155 | q->setColor(colorToUse); |
| 156 | |
| 157 | m_eyeDropperWindow->removeEventFilter(obj: eyeDropperEventFilter.get()); |
| 158 | m_eyeDropperWindow->setMouseGrabEnabled(false); |
| 159 | #if QT_CONFIG(cursor) |
| 160 | QGuiApplication::restoreOverrideCursor(); |
| 161 | #endif |
| 162 | |
| 163 | m_eyeDropperMode = false; |
| 164 | m_eyeDropperWindow.clear(); |
| 165 | } |
| 166 | |
| 167 | void QQuickColorDialogImplPrivate::eyeDropperPointerMoved(const QPoint &pos) |
| 168 | { |
| 169 | Q_Q(QQuickColorDialogImpl); |
| 170 | q->setColor(grabScreenColor(p: pos)); |
| 171 | } |
| 172 | |
| 173 | void QQuickColorDialogImplPrivate::alphaSliderMoved() |
| 174 | { |
| 175 | Q_Q(QQuickColorDialogImpl); |
| 176 | if (auto attached = attachedOrWarn()) |
| 177 | q->setAlpha(attached->alphaSlider()->value()); |
| 178 | } |
| 179 | |
| 180 | QQuickColorDialogImpl::QQuickColorDialogImpl(QObject *parent) |
| 181 | : QQuickDialog(*(new QQuickColorDialogImplPrivate), parent) |
| 182 | { |
| 183 | setPopupType(QQuickPopup::Window); |
| 184 | } |
| 185 | |
| 186 | QQuickColorDialogImplAttached *QQuickColorDialogImpl::qmlAttachedProperties(QObject *object) |
| 187 | { |
| 188 | return new QQuickColorDialogImplAttached(object); |
| 189 | } |
| 190 | |
| 191 | QColor QQuickColorDialogImpl::color() const |
| 192 | { |
| 193 | Q_D(const QQuickColorDialogImpl); |
| 194 | return d->m_hsl ? QColor::fromHslF(h: d->m_hsva.h, s: d->m_hsva.s, l: d->m_hsva.l, a: d->m_hsva.a) |
| 195 | : QColor::fromHsvF(h: d->m_hsva.h, s: d->m_hsva.s, v: d->m_hsva.v, a: d->m_hsva.a); |
| 196 | } |
| 197 | |
| 198 | void QQuickColorDialogImpl::setColor(const QColor &c) |
| 199 | { |
| 200 | Q_D(QQuickColorDialogImpl); |
| 201 | if (color().rgba() == c.rgba()) |
| 202 | return; |
| 203 | |
| 204 | // If we get a QColor from an Hsv or Hsl color system, |
| 205 | // we want to get the raw values without the risk of QColor converting them, |
| 206 | // and possible deleting relevant information for achromatic cases. |
| 207 | if (c.spec() == QColor::Spec::Hsv) { |
| 208 | d->m_hsva.h = qBound(min: .0, val: c.hsvHueF(), max: 1.0); |
| 209 | if (d->m_hsl) { |
| 210 | const auto sl = getSaturationAndLightness(saturation: c.hsvSaturationF(), value: c.valueF()); |
| 211 | d->m_hsva.s = qBound(min: .0, val: sl.first, max: 1.0); |
| 212 | d->m_hsva.l = qBound(min: .0, val: sl.second, max: 1.0); |
| 213 | } else { |
| 214 | d->m_hsva.s = qBound(min: .0, val: c.hsvSaturationF(), max: 1.0); |
| 215 | d->m_hsva.v = qBound(min: .0, val: c.valueF(), max: 1.0); |
| 216 | } |
| 217 | } else if (c.spec() == QColor::Spec::Hsl) { |
| 218 | d->m_hsva.h = qBound(min: .0, val: c.hslHueF(), max: 1.0); |
| 219 | if (d->m_hsl) { |
| 220 | d->m_hsva.s = qBound(min: .0, val: c.hslSaturationF(), max: 1.0); |
| 221 | d->m_hsva.l = qBound(min: .0, val: c.lightnessF(), max: 1.0); |
| 222 | } else { |
| 223 | const auto sv = getSaturationAndValue(saturation: c.hslSaturationF(), lightness: c.lightnessF()); |
| 224 | d->m_hsva.s = qBound(min: .0, val: sv.first, max: 1.0); |
| 225 | d->m_hsva.v = qBound(min: .0, val: sv.second, max: 1.0); |
| 226 | } |
| 227 | } else { |
| 228 | d->m_hsva.h = qBound(min: .0, val: d->m_hsl ? c.hslHueF() : c.hsvHueF(), max: 1.0); |
| 229 | d->m_hsva.s = qBound(min: .0, val: d->m_hsl ? c.hslSaturationF() : c.hsvSaturationF(), max: 1.0); |
| 230 | d->m_hsva.v = qBound(min: .0, val: d->m_hsl ? c.lightnessF() : c.valueF(), max: 1.0); |
| 231 | } |
| 232 | |
| 233 | d->m_hsva.a = c.alphaF(); |
| 234 | |
| 235 | emit colorChanged(color: color()); |
| 236 | } |
| 237 | |
| 238 | int QQuickColorDialogImpl::red() const |
| 239 | { |
| 240 | return color().red(); |
| 241 | } |
| 242 | |
| 243 | void QQuickColorDialogImpl::setRed(int red) |
| 244 | { |
| 245 | Q_D(QQuickColorDialogImpl); |
| 246 | |
| 247 | auto c = color(); |
| 248 | |
| 249 | if (c.red() == red) |
| 250 | return; |
| 251 | |
| 252 | c.setRed(red); |
| 253 | |
| 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(); |
| 258 | |
| 259 | emit colorChanged(color: c); |
| 260 | } |
| 261 | |
| 262 | int QQuickColorDialogImpl::green() const |
| 263 | { |
| 264 | return color().green(); |
| 265 | } |
| 266 | |
| 267 | void QQuickColorDialogImpl::setGreen(int green) |
| 268 | { |
| 269 | Q_D(QQuickColorDialogImpl); |
| 270 | |
| 271 | auto c = color(); |
| 272 | |
| 273 | if (c.green() == green) |
| 274 | return; |
| 275 | |
| 276 | c.setGreen(green); |
| 277 | |
| 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(); |
| 282 | |
| 283 | emit colorChanged(color: c); |
| 284 | } |
| 285 | |
| 286 | int QQuickColorDialogImpl::blue() const |
| 287 | { |
| 288 | return color().blue(); |
| 289 | } |
| 290 | |
| 291 | void QQuickColorDialogImpl::setBlue(int blue) |
| 292 | { |
| 293 | Q_D(QQuickColorDialogImpl); |
| 294 | |
| 295 | auto c = color(); |
| 296 | |
| 297 | if (c.blue() == blue) |
| 298 | return; |
| 299 | |
| 300 | c.setBlue(blue); |
| 301 | |
| 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(); |
| 306 | |
| 307 | emit colorChanged(color: c); |
| 308 | } |
| 309 | |
| 310 | qreal QQuickColorDialogImpl::alpha() const |
| 311 | { |
| 312 | Q_D(const QQuickColorDialogImpl); |
| 313 | return d->m_hsva.a; |
| 314 | } |
| 315 | |
| 316 | void QQuickColorDialogImpl::setAlpha(qreal alpha) |
| 317 | { |
| 318 | Q_D(QQuickColorDialogImpl); |
| 319 | |
| 320 | if (!qt_is_finite(d: alpha)) |
| 321 | return; |
| 322 | |
| 323 | alpha = qBound(min: .0, val: alpha, max: 1.0); |
| 324 | |
| 325 | if (qFuzzyCompare(p1: d->m_hsva.a, p2: alpha)) |
| 326 | return; |
| 327 | |
| 328 | d->m_hsva.a = alpha; |
| 329 | |
| 330 | emit colorChanged(color: color()); |
| 331 | } |
| 332 | |
| 333 | qreal QQuickColorDialogImpl::hue() const |
| 334 | { |
| 335 | Q_D(const QQuickColorDialogImpl); |
| 336 | return d->m_hsva.h; |
| 337 | } |
| 338 | |
| 339 | void QQuickColorDialogImpl::setHue(qreal hue) |
| 340 | { |
| 341 | Q_D(QQuickColorDialogImpl); |
| 342 | |
| 343 | if (!qt_is_finite(d: hue)) |
| 344 | return; |
| 345 | |
| 346 | d->m_hsva.h = hue; |
| 347 | |
| 348 | emit colorChanged(color: color()); |
| 349 | } |
| 350 | |
| 351 | qreal QQuickColorDialogImpl::saturation() const |
| 352 | { |
| 353 | Q_D(const QQuickColorDialogImpl); |
| 354 | return d->m_hsva.s; |
| 355 | } |
| 356 | |
| 357 | void QQuickColorDialogImpl::setSaturation(qreal saturation) |
| 358 | { |
| 359 | Q_D(QQuickColorDialogImpl); |
| 360 | if (!qt_is_finite(d: saturation)) |
| 361 | return; |
| 362 | |
| 363 | d->m_hsva.s = saturation; |
| 364 | |
| 365 | emit colorChanged(color: color()); |
| 366 | } |
| 367 | |
| 368 | qreal QQuickColorDialogImpl::value() const |
| 369 | { |
| 370 | Q_D(const QQuickColorDialogImpl); |
| 371 | return d->m_hsl ? getSaturationAndValue(saturation: d->m_hsva.s, lightness: d->m_hsva.l).second : d->m_hsva.v; |
| 372 | } |
| 373 | |
| 374 | void QQuickColorDialogImpl::setValue(qreal value) |
| 375 | { |
| 376 | Q_D(QQuickColorDialogImpl); |
| 377 | if (!qt_is_finite(d: value)) |
| 378 | return; |
| 379 | |
| 380 | d->m_hsva.v = value; |
| 381 | |
| 382 | if (d->m_hsl) |
| 383 | d->m_hsva.s = getSaturationAndValue(saturation: d->m_hsva.s, lightness: d->m_hsva.l).first; |
| 384 | |
| 385 | d->m_hsl = false; |
| 386 | emit colorChanged(color: color()); |
| 387 | } |
| 388 | |
| 389 | qreal QQuickColorDialogImpl::lightness() const |
| 390 | { |
| 391 | Q_D(const QQuickColorDialogImpl); |
| 392 | return d->m_hsl ? d->m_hsva.l : getSaturationAndLightness(saturation: d->m_hsva.s, value: d->m_hsva.v).second; |
| 393 | } |
| 394 | |
| 395 | void QQuickColorDialogImpl::setLightness(qreal lightness) |
| 396 | { |
| 397 | Q_D(QQuickColorDialogImpl); |
| 398 | if (!qt_is_finite(d: lightness)) |
| 399 | return; |
| 400 | |
| 401 | d->m_hsva.l = lightness; |
| 402 | |
| 403 | if (!d->m_hsl) |
| 404 | d->m_hsva.s = getSaturationAndLightness(saturation: d->m_hsva.s, value: d->m_hsva.v).first; |
| 405 | |
| 406 | d->m_hsl = true; |
| 407 | emit colorChanged(color: color()); |
| 408 | } |
| 409 | |
| 410 | bool QQuickColorDialogImpl::isHsl() const |
| 411 | { |
| 412 | Q_D(const QQuickColorDialogImpl); |
| 413 | return d->m_hsl; |
| 414 | } |
| 415 | |
| 416 | void QQuickColorDialogImpl::setHsl(bool hsl) |
| 417 | { |
| 418 | Q_D(QQuickColorDialogImpl); |
| 419 | |
| 420 | if (d->m_hsl == hsl) |
| 421 | return; |
| 422 | |
| 423 | d->m_hsl = hsl; |
| 424 | emit specChanged(); |
| 425 | } |
| 426 | |
| 427 | QSharedPointer<QColorDialogOptions> QQuickColorDialogImpl::options() const |
| 428 | { |
| 429 | Q_D(const QQuickColorDialogImpl); |
| 430 | return d->options; |
| 431 | } |
| 432 | |
| 433 | void QQuickColorDialogImpl::setOptions(const QSharedPointer<QColorDialogOptions> &options) |
| 434 | { |
| 435 | Q_D(QQuickColorDialogImpl); |
| 436 | d->options = options; |
| 437 | |
| 438 | QQuickColorDialogImplAttached *attached = d->attachedOrWarn(); |
| 439 | |
| 440 | if (attached) { |
| 441 | const auto *integration = QGuiApplicationPrivate::platformIntegration(); |
| 442 | const bool canSupportEyeDropper = |
| 443 | integration->hasCapability(cap: QPlatformIntegration::ScreenWindowGrabbing) |
| 444 | || integration->services()->hasCapability(capability: QPlatformServices::Capability::ColorPicking); |
| 445 | const bool offscreen = qgetenv(varName: "QT_QPA_PLATFORM" ).compare(a: QLatin1String("offscreen" ), cs: Qt::CaseInsensitive) == 0; |
| 446 | const bool noEyeDropperButton = (d->options && d->options->options() & QColorDialogOptions::NoEyeDropperButton); |
| 447 | attached->eyeDropperButton()->setVisible(!noEyeDropperButton && canSupportEyeDropper && !offscreen); |
| 448 | |
| 449 | if (d->options) { |
| 450 | attached->buttonBox()->setVisible( |
| 451 | !(d->options->options() & QColorDialogOptions::NoButtons)); |
| 452 | |
| 453 | const bool showAlpha = d->options->options() & QColorDialogOptions::ShowAlphaChannel; |
| 454 | attached->alphaSlider()->setVisible(showAlpha); |
| 455 | attached->colorInputs()->setShowAlpha(showAlpha); |
| 456 | } |
| 457 | } |
| 458 | } |
| 459 | |
| 460 | void QQuickColorDialogImpl::invokeEyeDropper() |
| 461 | { |
| 462 | Q_D(QQuickColorDialogImpl); |
| 463 | d->eyeDropperEnter(); |
| 464 | } |
| 465 | |
| 466 | QQuickColorDialogImplAttached::QQuickColorDialogImplAttached(QObject *parent) |
| 467 | : QObject(*(new QQuickColorDialogImplAttachedPrivate), parent) |
| 468 | { |
| 469 | if (!qobject_cast<QQuickColorDialogImpl *>(object: parent)) { |
| 470 | qmlWarning(me: this) << "ColorDialogImpl attached properties should only be " |
| 471 | << "accessed through the root ColorDialogImpl instance" ; |
| 472 | } |
| 473 | } |
| 474 | |
| 475 | QQuickDialogButtonBox *QQuickColorDialogImplAttached::buttonBox() const |
| 476 | { |
| 477 | Q_D(const QQuickColorDialogImplAttached); |
| 478 | return d->buttonBox; |
| 479 | } |
| 480 | |
| 481 | void QQuickColorDialogImplAttached::setButtonBox(QQuickDialogButtonBox *buttonBox) |
| 482 | { |
| 483 | Q_D(QQuickColorDialogImplAttached); |
| 484 | if (d->buttonBox == buttonBox) |
| 485 | return; |
| 486 | |
| 487 | if (d->buttonBox) { |
| 488 | QQuickColorDialogImpl *colorDialogImpl = qobject_cast<QQuickColorDialogImpl *>(object: parent()); |
| 489 | if (colorDialogImpl) { |
| 490 | auto dialogPrivate = QQuickDialogPrivate::get(dialog: colorDialogImpl); |
| 491 | QObjectPrivate::disconnect(sender: d->buttonBox, signal: &QQuickDialogButtonBox::accepted, |
| 492 | receiverPrivate: dialogPrivate, slot: &QQuickDialogPrivate::handleAccept); |
| 493 | QObjectPrivate::disconnect(sender: d->buttonBox, signal: &QQuickDialogButtonBox::rejected, |
| 494 | receiverPrivate: dialogPrivate, slot: &QQuickDialogPrivate::handleReject); |
| 495 | QObjectPrivate::disconnect(sender: d->buttonBox, signal: &QQuickDialogButtonBox::clicked, |
| 496 | receiverPrivate: dialogPrivate, slot: &QQuickDialogPrivate::handleClick); |
| 497 | } |
| 498 | } |
| 499 | |
| 500 | d->buttonBox = buttonBox; |
| 501 | |
| 502 | if (d->buttonBox) { |
| 503 | QQuickColorDialogImpl *colorDialogImpl = qobject_cast<QQuickColorDialogImpl *>(object: parent()); |
| 504 | if (colorDialogImpl) { |
| 505 | auto dialogPrivate = QQuickDialogPrivate::get(dialog: colorDialogImpl); |
| 506 | QObjectPrivate::connect(sender: d->buttonBox, signal: &QQuickDialogButtonBox::accepted, |
| 507 | receiverPrivate: dialogPrivate, slot: &QQuickDialogPrivate::handleAccept); |
| 508 | QObjectPrivate::connect(sender: d->buttonBox, signal: &QQuickDialogButtonBox::rejected, |
| 509 | receiverPrivate: dialogPrivate, slot: &QQuickDialogPrivate::handleReject); |
| 510 | QObjectPrivate::connect(sender: d->buttonBox, signal: &QQuickDialogButtonBox::clicked, |
| 511 | receiverPrivate: dialogPrivate, slot: &QQuickDialogPrivate::handleClick); |
| 512 | } |
| 513 | } |
| 514 | |
| 515 | emit buttonBoxChanged(); |
| 516 | } |
| 517 | |
| 518 | QQuickAbstractButton *QQuickColorDialogImplAttached::eyeDropperButton() const |
| 519 | { |
| 520 | Q_D(const QQuickColorDialogImplAttached); |
| 521 | return d->eyeDropperButton; |
| 522 | } |
| 523 | |
| 524 | void QQuickColorDialogImplAttached::setEyeDropperButton(QQuickAbstractButton *eyeDropperButton) |
| 525 | { |
| 526 | Q_D(QQuickColorDialogImplAttached); |
| 527 | Q_ASSERT(!d->eyeDropperButton); |
| 528 | if (d->eyeDropperButton == eyeDropperButton) |
| 529 | return; |
| 530 | |
| 531 | d->eyeDropperButton = eyeDropperButton; |
| 532 | if (auto dialog = qobject_cast<QQuickColorDialogImpl *>(object: parent())) |
| 533 | connect(sender: d->eyeDropperButton, signal: &QQuickAbstractButton::clicked, context: dialog, slot: &QQuickColorDialogImpl::invokeEyeDropper); |
| 534 | emit eyeDropperButtonChanged(); |
| 535 | } |
| 536 | |
| 537 | QQuickAbstractColorPicker *QQuickColorDialogImplAttached::colorPicker() const |
| 538 | { |
| 539 | Q_D(const QQuickColorDialogImplAttached); |
| 540 | return d->colorPicker; |
| 541 | } |
| 542 | void QQuickColorDialogImplAttached::setColorPicker(QQuickAbstractColorPicker *colorPicker) |
| 543 | { |
| 544 | Q_D(QQuickColorDialogImplAttached); |
| 545 | if (d->colorPicker == colorPicker) |
| 546 | return; |
| 547 | |
| 548 | if (d->colorPicker) { |
| 549 | QQuickColorDialogImpl *colorDialogImpl = qobject_cast<QQuickColorDialogImpl *>(object: parent()); |
| 550 | if (colorDialogImpl) { |
| 551 | QObject::disconnect(sender: d->colorPicker, signal: &QQuickAbstractColorPicker::colorPicked, |
| 552 | receiver: colorDialogImpl, slot: &QQuickColorDialogImpl::setColor); |
| 553 | } |
| 554 | } |
| 555 | |
| 556 | d->colorPicker = colorPicker; |
| 557 | |
| 558 | if (d->colorPicker) { |
| 559 | QQuickColorDialogImpl *colorDialogImpl = qobject_cast<QQuickColorDialogImpl *>(object: parent()); |
| 560 | if (colorDialogImpl) { |
| 561 | QObject::connect(sender: d->colorPicker, signal: &QQuickAbstractColorPicker::colorPicked, |
| 562 | context: colorDialogImpl, slot: &QQuickColorDialogImpl::setColor); |
| 563 | } |
| 564 | } |
| 565 | |
| 566 | emit colorPickerChanged(); |
| 567 | } |
| 568 | |
| 569 | QQuickSlider *QQuickColorDialogImplAttached::alphaSlider() const |
| 570 | { |
| 571 | Q_D(const QQuickColorDialogImplAttached); |
| 572 | return d->alphaSlider; |
| 573 | } |
| 574 | |
| 575 | void QQuickColorDialogImplAttached::setAlphaSlider(QQuickSlider *alphaSlider) |
| 576 | { |
| 577 | Q_D(QQuickColorDialogImplAttached); |
| 578 | if (d->alphaSlider == alphaSlider) |
| 579 | return; |
| 580 | |
| 581 | if (d->alphaSlider) { |
| 582 | QQuickColorDialogImpl *colorDialogImpl = qobject_cast<QQuickColorDialogImpl *>(object: parent()); |
| 583 | if (colorDialogImpl) { |
| 584 | auto dialogPrivate = QQuickColorDialogImplPrivate::get(dialog: colorDialogImpl); |
| 585 | QObjectPrivate::disconnect(sender: d->alphaSlider, signal: &QQuickSlider::moved, |
| 586 | receiverPrivate: dialogPrivate, slot: &QQuickColorDialogImplPrivate::alphaSliderMoved); |
| 587 | } |
| 588 | } |
| 589 | |
| 590 | d->alphaSlider = alphaSlider; |
| 591 | |
| 592 | if (d->alphaSlider) { |
| 593 | QQuickColorDialogImpl *colorDialogImpl = qobject_cast<QQuickColorDialogImpl *>(object: parent()); |
| 594 | if (colorDialogImpl) { |
| 595 | auto dialogPrivate = QQuickColorDialogImplPrivate::get(dialog: colorDialogImpl); |
| 596 | QObjectPrivate::connect(sender: d->alphaSlider, signal: &QQuickSlider::moved, |
| 597 | receiverPrivate: dialogPrivate, slot: &QQuickColorDialogImplPrivate::alphaSliderMoved); |
| 598 | } |
| 599 | } |
| 600 | |
| 601 | emit alphaSliderChanged(); |
| 602 | } |
| 603 | |
| 604 | QQuickColorInputs *QQuickColorDialogImplAttached::colorInputs() const |
| 605 | { |
| 606 | Q_D(const QQuickColorDialogImplAttached); |
| 607 | return d->colorInputs; |
| 608 | } |
| 609 | |
| 610 | void QQuickColorDialogImplAttached::setColorInputs(QQuickColorInputs *colorInputs) |
| 611 | { |
| 612 | Q_D(QQuickColorDialogImplAttached); |
| 613 | |
| 614 | if (d->colorInputs == colorInputs) |
| 615 | return; |
| 616 | |
| 617 | if (d->colorInputs) { |
| 618 | QQuickColorDialogImpl *colorDialogImpl = qobject_cast<QQuickColorDialogImpl *>(object: parent()); |
| 619 | if (colorDialogImpl) |
| 620 | QObject::disconnect(sender: d->colorInputs, signal: &QQuickColorInputs::colorModified, |
| 621 | receiver: colorDialogImpl, slot: &QQuickColorDialogImpl::setColor); |
| 622 | } |
| 623 | |
| 624 | d->colorInputs = colorInputs; |
| 625 | |
| 626 | if (d->colorInputs) { |
| 627 | QQuickColorDialogImpl *colorDialogImpl = qobject_cast<QQuickColorDialogImpl *>(object: parent()); |
| 628 | if (colorDialogImpl) |
| 629 | QObject::connect(sender: d->colorInputs, signal: &QQuickColorInputs::colorModified, |
| 630 | context: colorDialogImpl, slot: &QQuickColorDialogImpl::setColor); |
| 631 | } |
| 632 | |
| 633 | emit colorInputsChanged(); |
| 634 | } |
| 635 | |
| 636 | QT_END_NAMESPACE |
| 637 | |