diff options
Diffstat (limited to 'src/quicktemplates2')
-rw-r--r-- | src/quicktemplates2/qquickapplicationwindow.cpp | 71 | ||||
-rw-r--r-- | src/quicktemplates2/qquickapplicationwindow_p.h | 7 | ||||
-rw-r--r-- | src/quicktemplates2/qquickcontrol.cpp | 182 | ||||
-rw-r--r-- | src/quicktemplates2/qquickcontrol_p.h | 9 | ||||
-rw-r--r-- | src/quicktemplates2/qquickcontrol_p_p.h | 14 | ||||
-rw-r--r-- | src/quicktemplates2/qquicklabel.cpp | 77 | ||||
-rw-r--r-- | src/quicktemplates2/qquicklabel_p.h | 7 | ||||
-rw-r--r-- | src/quicktemplates2/qquicklabel_p_p.h | 11 | ||||
-rw-r--r-- | src/quicktemplates2/qquickpopup.cpp | 60 | ||||
-rw-r--r-- | src/quicktemplates2/qquickpopup_p.h | 9 | ||||
-rw-r--r-- | src/quicktemplates2/qquickpopupitem.cpp | 22 | ||||
-rw-r--r-- | src/quicktemplates2/qquickpopupitem_p_p.h | 2 | ||||
-rw-r--r-- | src/quicktemplates2/qquicktextarea.cpp | 74 | ||||
-rw-r--r-- | src/quicktemplates2/qquicktextarea_p.h | 7 | ||||
-rw-r--r-- | src/quicktemplates2/qquicktextarea_p_p.h | 11 | ||||
-rw-r--r-- | src/quicktemplates2/qquicktextfield.cpp | 74 | ||||
-rw-r--r-- | src/quicktemplates2/qquicktextfield_p.h | 7 | ||||
-rw-r--r-- | src/quicktemplates2/qquicktextfield_p_p.h | 11 |
18 files changed, 654 insertions, 1 deletions
diff --git a/src/quicktemplates2/qquickapplicationwindow.cpp b/src/quicktemplates2/qquickapplicationwindow.cpp index 4a445d9b..b936301d 100644 --- a/src/quicktemplates2/qquickapplicationwindow.cpp +++ b/src/quicktemplates2/qquickapplicationwindow.cpp @@ -168,6 +168,14 @@ public: } void resolveFont(); + void updatePalette(const QPalette &p); + inline void setPalette_helper(const QPalette &p) { + if (palette.resolve() == p.resolve() && palette == p) + return; + updatePalette(p); + } + void resolvePalette(); + void _q_updateActiveFocus(); void setActiveFocusControl(QQuickItem *item); @@ -179,6 +187,7 @@ public: QQuickOverlay *overlay; QFont font; QLocale locale; + QPalette palette; QQuickItem *activeFocusControl; QQuickApplicationWindow *q_ptr; }; @@ -274,6 +283,30 @@ void QQuickApplicationWindowPrivate::resolveFont() setFont_helper(resolvedFont); } +void QQuickApplicationWindowPrivate::updatePalette(const QPalette &p) +{ + Q_Q(QQuickApplicationWindow); + const bool changed = palette != p; + palette = p; + + QQuickItem *rootItem = q->QQuickWindow::contentItem(); + QQuickControlPrivate::updatePaletteRecur(rootItem, p); + + // TODO: internal QQuickPopupManager that provides reliable access to all QQuickPopup instances + const QList<QQuickPopup *> popups = rootItem->findChildren<QQuickPopup *>(); + for (QQuickPopup *popup : popups) + QQuickControlPrivate::get(static_cast<QQuickControl *>(popup->popupItem()))->inheritPalette(p); + + if (changed) + emit q->paletteChanged(); +} + +void QQuickApplicationWindowPrivate::resolvePalette() +{ + QPalette resolvedPalette = palette.resolve(QQuickControlPrivate::themePalette(QPlatformTheme::SystemPalette)); + setPalette_helper(resolvedPalette); +} + void QQuickApplicationWindowPrivate::_q_updateActiveFocus() { Q_Q(QQuickApplicationWindow); @@ -680,6 +713,43 @@ void QQuickApplicationWindow::resetLocale() setLocale(QLocale()); } +/*! + \since QtQuick.Controls 2.3 + \qmlproperty palette QtQuick.Controls::ApplicationWindow::palette + + This property holds the palette currently set for the window. + + The default palette depends on the system environment. QGuiApplication maintains a system/theme + palette which serves as a default for all application windows. You can also set the default palette + for windows by passing a custom palette to QGuiApplication::setPalette(), before loading any QML. + + ApplicationWindow propagates explicit palette properties to child controls. If you change a specific + property on the window's palette, that property propagates to all child controls in the window, + overriding any system defaults for that property. + + \sa Control::palette +*/ +QPalette QQuickApplicationWindow::palette() const +{ + Q_D(const QQuickApplicationWindow); + return d->palette; +} + +void QQuickApplicationWindow::setPalette(const QPalette &palette) +{ + Q_D(QQuickApplicationWindow); + if (d->palette.resolve() == palette.resolve() && d->palette == palette) + return; + + QPalette resolvedPalette = palette.resolve(QQuickControlPrivate::themePalette(QPlatformTheme::SystemPalette)); + d->setPalette_helper(resolvedPalette); +} + +void QQuickApplicationWindow::resetPalette() +{ + setPalette(QPalette()); +} + QQuickApplicationWindowAttached *QQuickApplicationWindow::qmlAttachedProperties(QObject *object) { return new QQuickApplicationWindowAttached(object); @@ -697,6 +767,7 @@ void QQuickApplicationWindow::classBegin() d->complete = false; QQuickWindowQmlImpl::classBegin(); d->resolveFont(); + d->resolvePalette(); } void QQuickApplicationWindow::componentComplete() diff --git a/src/quicktemplates2/qquickapplicationwindow_p.h b/src/quicktemplates2/qquickapplicationwindow_p.h index 07ddc67e..8747e70f 100644 --- a/src/quicktemplates2/qquickapplicationwindow_p.h +++ b/src/quicktemplates2/qquickapplicationwindow_p.h @@ -51,6 +51,7 @@ #include <QtQuick/private/qquickwindowmodule_p.h> #include <QtQuickTemplates2/private/qtquicktemplates2global_p.h> #include <QtGui/qfont.h> +#include <QtGui/qpalette.h> #include <QtCore/qlocale.h> QT_BEGIN_NAMESPACE @@ -72,6 +73,7 @@ class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickApplicationWindow : public QQuickWi Q_PROPERTY(QQuickOverlay *overlay READ overlay CONSTANT FINAL) Q_PROPERTY(QFont font READ font WRITE setFont RESET resetFont NOTIFY fontChanged FINAL) Q_PROPERTY(QLocale locale READ locale WRITE setLocale RESET resetLocale NOTIFY localeChanged FINAL) + Q_PROPERTY(QPalette palette READ palette WRITE setPalette RESET resetPalette NOTIFY paletteChanged FINAL REVISION 3) Q_CLASSINFO("DefaultProperty", "contentData") public: @@ -102,6 +104,10 @@ public: void setLocale(const QLocale &locale); void resetLocale(); + QPalette palette() const; + void setPalette(const QPalette &palette); + void resetPalette(); + static QQuickApplicationWindowAttached *qmlAttachedProperties(QObject *object); Q_SIGNALS: @@ -111,6 +117,7 @@ Q_SIGNALS: void footerChanged(); void fontChanged(); void localeChanged(); + Q_REVISION(3) void paletteChanged(); protected: bool isComponentComplete() const; diff --git a/src/quicktemplates2/qquickcontrol.cpp b/src/quicktemplates2/qquickcontrol.cpp index d285fdd2..e866a9a3 100644 --- a/src/quicktemplates2/qquickcontrol.cpp +++ b/src/quicktemplates2/qquickcontrol.cpp @@ -421,6 +421,111 @@ void QQuickControlPrivate::updateFontRecur(QQuickItem *item, const QFont &font) } } +/*! + \internal + + Returns the palette that the item inherits from its ancestors and + QGuiApplication::palette. +*/ +QPalette QQuickControlPrivate::parentPalette(const QQuickItem *item) +{ + QQuickItem *p = item->parentItem(); + while (p) { + if (QQuickControl *control = qobject_cast<QQuickControl *>(p)) + return control->palette(); + else if (QQuickLabel *label = qobject_cast<QQuickLabel *>(p)) + return label->palette(); + else if (QQuickTextField *textField = qobject_cast<QQuickTextField *>(p)) + return textField->palette(); + else if (QQuickTextArea *textArea = qobject_cast<QQuickTextArea *>(p)) + return textArea->palette(); + + p = p->parentItem(); + } + + if (QQuickApplicationWindow *window = qobject_cast<QQuickApplicationWindow *>(item->window())) + return window->palette(); + + return themePalette(QPlatformTheme::SystemPalette); +} + +QPalette QQuickControlPrivate::themePalette(QPlatformTheme::Palette type) +{ + if (QPlatformTheme *theme = QGuiApplicationPrivate::platformTheme()) { + if (const QPalette *palette = theme->palette(type)) { + QPalette p = *palette; + if (type == QPlatformTheme::SystemPalette) + p.resolve(0); + return p; + } + } + + return QPalette(); +} + +/*! + \internal + + Determine which palette is implicitly imposed on this control by its ancestors + and QGuiApplication::palette, resolve this against its own palette (attributes from + the implicit palette are copied over). Then propagate this palette to this + control's children. +*/ +void QQuickControlPrivate::resolvePalette() +{ + Q_Q(QQuickControl); + inheritPalette(parentPalette(q)); +} + +void QQuickControlPrivate::inheritPalette(const QPalette &palette) +{ + Q_Q(QQuickControl); + QPalette parentPalette = extra.isAllocated() ? extra->requestedPalette.resolve(palette) : palette; + parentPalette.resolve(extra.isAllocated() ? extra->requestedPalette.resolve() | palette.resolve() : palette.resolve()); + + const QPalette defaultPalette = q->defaultPalette(); + const QPalette resolvedPalette = parentPalette.resolve(defaultPalette); + + setPalette_helper(resolvedPalette); +} + +/*! + \internal + + Assign \a palette to this control, and propagate it to all children. +*/ +void QQuickControlPrivate::updatePalette(const QPalette &palette) +{ + Q_Q(QQuickControl); + QPalette oldPalette = resolvedPalette; + resolvedPalette = palette; + + if (oldPalette != palette) + q->paletteChange(palette, oldPalette); + + QQuickControlPrivate::updatePaletteRecur(q, palette); + + if (oldPalette != palette) + emit q->paletteChanged(); +} + +void QQuickControlPrivate::updatePaletteRecur(QQuickItem *item, const QPalette &palette) +{ + const auto childItems = item->childItems(); + for (QQuickItem *child : childItems) { + if (QQuickControl *control = qobject_cast<QQuickControl *>(child)) + QQuickControlPrivate::get(control)->inheritPalette(palette); + else if (QQuickLabel *label = qobject_cast<QQuickLabel *>(child)) + QQuickLabelPrivate::get(label)->inheritPalette(palette); + else if (QQuickTextArea *textArea = qobject_cast<QQuickTextArea *>(child)) + QQuickTextAreaPrivate::get(textArea)->inheritPalette(palette); + else if (QQuickTextField *textField = qobject_cast<QQuickTextField *>(child)) + QQuickTextFieldPrivate::get(textField)->inheritPalette(palette); + else + QQuickControlPrivate::updatePaletteRecur(child, palette); + } +} + QLocale QQuickControlPrivate::calcLocale(const QQuickItem *item) { const QQuickItem *p = item; @@ -556,11 +661,15 @@ void QQuickControlPrivate::destroyDelegate(QObject *delegate, QObject *parent) QQuickControl::QQuickControl(QQuickItem *parent) : QQuickItem(*(new QQuickControlPrivate), parent) { + // ### TODO: ItemEnabledChanged? + connect(this, &QQuickItem::enabledChanged, this, &QQuickControl::paletteChanged); } QQuickControl::QQuickControl(QQuickControlPrivate &dd, QQuickItem *parent) : QQuickItem(dd, parent) { + // ### TODO: ItemEnabledChanged? + connect(this, &QQuickItem::enabledChanged, this, &QQuickControl::paletteChanged); } void QQuickControl::itemChange(QQuickItem::ItemChange change, const QQuickItem::ItemChangeData &value) @@ -577,6 +686,7 @@ void QQuickControl::itemChange(QQuickItem::ItemChange change, const QQuickItem:: case ItemParentHasChanged: if (value.item) { d->resolveFont(); + d->resolvePalette(); if (!d->hasLocale) d->updateLocale(QQuickControlPrivate::calcLocale(d->parentItem), false); // explicit=false #if QT_CONFIG(quicktemplates2_hover) @@ -1208,11 +1318,72 @@ void QQuickControl::setContentItem(QQuickItem *item) d->setContentItem_helper(item, true); } +/*! + \since QtQuick.Controls 2.3 + \qmlproperty palette QtQuick.Controls::Control::palette + + This property holds the palette currently set for the control. + + This property describes the control's requested palette. The palette is used by the control's + style when rendering standard components, and is available as a means to ensure that custom + controls can maintain consistency with the native platform's native look and feel. It's common + that different platforms, or different styles, define different palettes for an application. + + The default palette depends on the system environment. ApplicationWindow maintains a system/theme + palette which serves as a default for all controls. There may also be special palette defaults for + certain types of controls. You can also set the default palette for controls by passing a custom + palette to QGuiApplication::setPalette(), before loading any QML. + + Control propagates explicit palette properties from parent to children. If you change a specific + property on a control's palette, that property propagates to all of the control's children, + overriding any system defaults for that property. + + \code + Page { + palette.text: "red" + + Column { + Label { + text: qsTr("This will use red color...") + } + + Switch { + text: qsTr("... and so will this") + } + } + } + \endcode +*/ +QPalette QQuickControl::palette() const +{ + Q_D(const QQuickControl); + QPalette palette = d->resolvedPalette; + if (!isEnabled()) + palette.setCurrentColorGroup(QPalette::Disabled); + return palette; +} + +void QQuickControl::setPalette(const QPalette &palette) +{ + Q_D(QQuickControl); + if (d->extra.value().requestedPalette.resolve() == palette.resolve() && d->extra.value().requestedPalette == palette) + return; + + d->extra.value().requestedPalette = palette; + d->resolvePalette(); +} + +void QQuickControl::resetPalette() +{ + setPalette(QPalette()); +} + void QQuickControl::classBegin() { Q_D(QQuickControl); QQuickItem::classBegin(); d->resolveFont(); + d->resolvePalette(); } void QQuickControl::componentComplete() @@ -1237,6 +1408,11 @@ QFont QQuickControl::defaultFont() const return QQuickControlPrivate::themeFont(QPlatformTheme::SystemFont); } +QPalette QQuickControl::defaultPalette() const +{ + return QQuickControlPrivate::themePalette(QPlatformTheme::SystemPalette); +} + void QQuickControl::focusInEvent(QFocusEvent *event) { QQuickItem::focusInEvent(event); @@ -1420,6 +1596,12 @@ void QQuickControl::localeChange(const QLocale &newLocale, const QLocale &oldLoc Q_UNUSED(oldLocale); } +void QQuickControl::paletteChange(const QPalette &newPalette, const QPalette &oldPalette) +{ + Q_UNUSED(newPalette); + Q_UNUSED(oldPalette); +} + #if QT_CONFIG(accessibility) QAccessible::Role QQuickControl::accessibleRole() const { diff --git a/src/quicktemplates2/qquickcontrol_p.h b/src/quicktemplates2/qquickcontrol_p.h index feb6646e..5207d46c 100644 --- a/src/quicktemplates2/qquickcontrol_p.h +++ b/src/quicktemplates2/qquickcontrol_p.h @@ -49,6 +49,7 @@ // #include <QtCore/qlocale.h> +#include <QtGui/qpalette.h> #include <QtQuick/qquickitem.h> #include <QtQuickTemplates2/private/qtquicktemplates2global_p.h> @@ -78,6 +79,7 @@ class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickControl : public QQuickItem Q_PROPERTY(bool wheelEnabled READ isWheelEnabled WRITE setWheelEnabled NOTIFY wheelEnabledChanged FINAL) Q_PROPERTY(QQuickItem *background READ background WRITE setBackground NOTIFY backgroundChanged FINAL) Q_PROPERTY(QQuickItem *contentItem READ contentItem WRITE setContentItem NOTIFY contentItemChanged FINAL) + Q_PROPERTY(QPalette palette READ palette WRITE setPalette RESET resetPalette NOTIFY paletteChanged FINAL REVISION 3) public: explicit QQuickControl(QQuickItem *parent = nullptr); @@ -143,6 +145,10 @@ public: QQuickItem *contentItem() const; void setContentItem(QQuickItem *item); + QPalette palette() const; + void setPalette(const QPalette &palette); + void resetPalette(); + Q_SIGNALS: void fontChanged(); void availableWidthChanged(); @@ -163,9 +169,11 @@ Q_SIGNALS: void wheelEnabledChanged(); void backgroundChanged(); void contentItemChanged(); + Q_REVISION(3) void paletteChanged(); protected: virtual QFont defaultFont() const; + virtual QPalette defaultPalette() const; QQuickControl(QQuickControlPrivate &dd, QQuickItem *parent); @@ -202,6 +210,7 @@ protected: virtual void paddingChange(const QMarginsF &newPadding, const QMarginsF &oldPadding); virtual void contentItemChange(QQuickItem *newItem, QQuickItem *oldItem); virtual void localeChange(const QLocale &newLocale, const QLocale &oldLocale); + virtual void paletteChange(const QPalette &newPalette, const QPalette &oldPalette); #if QT_CONFIG(accessibility) virtual QAccessible::Role accessibleRole() const; diff --git a/src/quicktemplates2/qquickcontrol_p_p.h b/src/quicktemplates2/qquickcontrol_p_p.h index 7ff9dff3..65c4a7ec 100644 --- a/src/quicktemplates2/qquickcontrol_p_p.h +++ b/src/quicktemplates2/qquickcontrol_p_p.h @@ -114,6 +114,18 @@ public: static QFont parentFont(const QQuickItem *item); static QFont themeFont(QPlatformTheme::Font type); + virtual void resolvePalette(); + void inheritPalette(const QPalette &palette); + void updatePalette(const QPalette &palette); + static void updatePaletteRecur(QQuickItem *item, const QPalette &palette); + inline void setPalette_helper(const QPalette &palette) { + if (resolvedPalette.resolve() == palette.resolve() && resolvedPalette == palette) + return; + updatePalette(palette); + } + static QPalette parentPalette(const QQuickItem *item); + static QPalette themePalette(QPlatformTheme::Palette type); + void updateLocale(const QLocale &l, bool e); static void updateLocaleRecur(QQuickItem *item, const QLocale &l); static QLocale calcLocale(const QQuickItem *item); @@ -129,6 +141,7 @@ public: struct ExtraData { ExtraData(); QFont requestedFont; + QPalette requestedPalette; }; QLazilyAllocated<ExtraData> extra; @@ -151,6 +164,7 @@ public: qreal spacing; QLocale locale; QFont resolvedFont; + QPalette resolvedPalette; Qt::FocusPolicy focusPolicy; Qt::FocusReason focusReason; QQuickItem *background; diff --git a/src/quicktemplates2/qquicklabel.cpp b/src/quicktemplates2/qquicklabel.cpp index fdda4542..be364830 100644 --- a/src/quicktemplates2/qquicklabel.cpp +++ b/src/quicktemplates2/qquicklabel.cpp @@ -136,6 +136,43 @@ void QQuickLabelPrivate::updateFont(const QFont &font) emit q->fontChanged(); } +/*! + \internal + + Determine which palette is implicitly imposed on this control by its ancestors + and QGuiApplication::palette, resolve this against its own palette (attributes from + the implicit palette are copied over). Then propagate this palette to this + control's children. +*/ +void QQuickLabelPrivate::resolvePalette() +{ + Q_Q(QQuickLabel); + inheritPalette(QQuickControlPrivate::parentPalette(q)); +} + +void QQuickLabelPrivate::inheritPalette(const QPalette &palette) +{ + QPalette parentPalette = extra.isAllocated() ? extra->requestedPalette.resolve(palette) : palette; + parentPalette.resolve(extra.isAllocated() ? extra->requestedPalette.resolve() | palette.resolve() : palette.resolve()); + + const QPalette defaultPalette = QQuickControlPrivate::themePalette(QPlatformTheme::LabelPalette); + const QPalette resolvedPalette = parentPalette.resolve(defaultPalette); + + setPalette_helper(resolvedPalette); +} + +void QQuickLabelPrivate::updatePalette(const QPalette &palette) +{ + Q_Q(QQuickLabel); + QPalette oldPalette = resolvedPalette; + resolvedPalette = palette; + + QQuickControlPrivate::updatePaletteRecur(q, palette); + + if (oldPalette != palette) + emit q->paletteChanged(); +} + void QQuickLabelPrivate::textChanged(const QString &text) { #if QT_CONFIG(accessibility) @@ -173,6 +210,9 @@ QQuickLabel::QQuickLabel(QQuickItem *parent) { Q_D(QQuickLabel); QObjectPrivate::connect(this, &QQuickText::textChanged, d, &QQuickLabelPrivate::textChanged); + + // ### TODO: ItemEnabledChanged? + connect(this, &QQuickItem::enabledChanged, this, &QQuickLabel::paletteChanged); } QFont QQuickLabel::font() const @@ -223,11 +263,44 @@ void QQuickLabel::setBackground(QQuickItem *background) emit backgroundChanged(); } +/*! + \since QtQuick.Controls 2.3 + \qmlproperty palette QtQuick.Controls::Label::palette + + This property holds the palette currently set for the label. + + \sa Control::palette +*/ +QPalette QQuickLabel::palette() const +{ + Q_D(const QQuickLabel); + QPalette palette = d->resolvedPalette; + if (!isEnabled()) + palette.setCurrentColorGroup(QPalette::Disabled); + return palette; +} + +void QQuickLabel::setPalette(const QPalette &palette) +{ + Q_D(QQuickLabel); + if (d->extra.value().requestedPalette.resolve() == palette.resolve() && d->extra.value().requestedPalette == palette) + return; + + d->extra.value().requestedPalette = palette; + d->resolvePalette(); +} + +void QQuickLabel::resetPalette() +{ + setPalette(QPalette()); +} + void QQuickLabel::classBegin() { Q_D(QQuickLabel); QQuickText::classBegin(); d->resolveFont(); + d->resolvePalette(); } void QQuickLabel::componentComplete() @@ -244,8 +317,10 @@ void QQuickLabel::itemChange(QQuickItem::ItemChange change, const QQuickItem::It { Q_D(QQuickLabel); QQuickText::itemChange(change, value); - if (change == ItemParentHasChanged && value.item) + if (change == ItemParentHasChanged && value.item) { d->resolveFont(); + d->resolvePalette(); + } } void QQuickLabel::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) diff --git a/src/quicktemplates2/qquicklabel_p.h b/src/quicktemplates2/qquicklabel_p.h index 04172900..a102c89a 100644 --- a/src/quicktemplates2/qquicklabel_p.h +++ b/src/quicktemplates2/qquicklabel_p.h @@ -48,6 +48,7 @@ // We mean it. // +#include <QtGui/qpalette.h> #include <QtQuick/private/qquicktext_p.h> #include <QtQuickTemplates2/private/qtquicktemplates2global_p.h> @@ -60,6 +61,7 @@ class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickLabel : public QQuickText Q_OBJECT Q_PROPERTY(QFont font READ font WRITE setFont NOTIFY fontChanged) // override Q_PROPERTY(QQuickItem *background READ background WRITE setBackground NOTIFY backgroundChanged FINAL) + Q_PROPERTY(QPalette palette READ palette WRITE setPalette RESET resetPalette NOTIFY paletteChanged FINAL REVISION 3) public: explicit QQuickLabel(QQuickItem *parent = nullptr); @@ -70,9 +72,14 @@ public: QQuickItem *background() const; void setBackground(QQuickItem *background); + QPalette palette() const; + void setPalette(const QPalette &palette); + void resetPalette(); + Q_SIGNALS: void fontChanged(); void backgroundChanged(); + Q_REVISION(3) void paletteChanged(); protected: void classBegin() override; diff --git a/src/quicktemplates2/qquicklabel_p_p.h b/src/quicktemplates2/qquicklabel_p_p.h index dadd63df..bc78d806 100644 --- a/src/quicktemplates2/qquicklabel_p_p.h +++ b/src/quicktemplates2/qquicklabel_p_p.h @@ -84,6 +84,15 @@ public: updateFont(font); } + void resolvePalette(); + void inheritPalette(const QPalette &palette); + void updatePalette(const QPalette &palette); + inline void setPalette_helper(const QPalette &palette) { + if (resolvedPalette.resolve() == palette.resolve() && resolvedPalette == palette) + return; + updatePalette(palette); + } + void textChanged(const QString &text); #if QT_CONFIG(accessibility) @@ -93,9 +102,11 @@ public: struct ExtraData { QFont requestedFont; + QPalette requestedPalette; }; QLazilyAllocated<ExtraData> extra; + QPalette resolvedPalette; QQuickItem *background; QQuickAccessibleAttached *accessibleAttached; }; diff --git a/src/quicktemplates2/qquickpopup.cpp b/src/quicktemplates2/qquickpopup.cpp index 045b0fb8..23d3ad2c 100644 --- a/src/quicktemplates2/qquickpopup.cpp +++ b/src/quicktemplates2/qquickpopup.cpp @@ -1347,6 +1347,53 @@ void QQuickPopup::resetFont() d->popupItem->resetFont(); } + +/*! + \since QtQuick.Controls 2.3 + \qmlproperty palette QtQuick.Controls::Popup::palette + + This property holds the palette currently set for the popup. + + Popup propagates explicit palette properties to its children. If you change a specific + property on a popup's palette, that property propagates to all of the popup's children, + overriding any system defaults for that property. + + \code + Popup { + palette.text: "red" + + Column { + Label { + text: qsTr("This will use red color...") + } + + Switch { + text: qsTr("... and so will this") + } + } + } + \endcode + + \sa Control::palette, ApplicationWindow::palette +*/ +QPalette QQuickPopup::palette() const +{ + Q_D(const QQuickPopup); + return d->popupItem->palette(); +} + +void QQuickPopup::setPalette(const QPalette &palette) +{ + Q_D(QQuickPopup); + d->popupItem->setPalette(palette); +} + +void QQuickPopup::resetPalette() +{ + Q_D(QQuickPopup); + d->popupItem->resetPalette(); +} + QQuickWindow *QQuickPopup::window() const { Q_D(const QQuickPopup); @@ -1389,6 +1436,7 @@ void QQuickPopup::setParentItem(QQuickItem *parent) QQuickControlPrivate *p = QQuickControlPrivate::get(d->popupItem); p->resolveFont(); + p->resolvePalette(); if (QQuickApplicationWindow *window = qobject_cast<QQuickApplicationWindow *>(parent->window())) p->updateLocale(window->locale(), false); // explicit=false } else { @@ -2104,6 +2152,13 @@ void QQuickPopup::paddingChange(const QMarginsF &newPadding, const QMarginsF &ol emit availableHeightChanged(); } +void QQuickPopup::paletteChange(const QPalette &newPalette, const QPalette &oldPalette) +{ + Q_UNUSED(newPalette); + Q_UNUSED(oldPalette); + emit paletteChanged(); +} + void QQuickPopup::spacingChange(qreal newSpacing, qreal oldSpacing) { Q_UNUSED(newSpacing); @@ -2116,6 +2171,11 @@ QFont QQuickPopup::defaultFont() const return QQuickControlPrivate::themeFont(QPlatformTheme::SystemFont); } +QPalette QQuickPopup::defaultPalette() const +{ + return QQuickControlPrivate::themePalette(QPlatformTheme::SystemPalette); +} + #if QT_CONFIG(accessibility) QAccessible::Role QQuickPopup::accessibleRole() const { diff --git a/src/quicktemplates2/qquickpopup_p.h b/src/quicktemplates2/qquickpopup_p.h index 12bbe91d..5f2169d3 100644 --- a/src/quicktemplates2/qquickpopup_p.h +++ b/src/quicktemplates2/qquickpopup_p.h @@ -53,6 +53,7 @@ #include <QtGui/qevent.h> #include <QtCore/qlocale.h> #include <QtGui/qfont.h> +#include <QtGui/qpalette.h> #include <QtQuickTemplates2/private/qtquicktemplates2global_p.h> #include <QtQml/qqml.h> #include <QtQml/qqmllist.h> @@ -97,6 +98,7 @@ class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickPopup : public QObject, public QQml Q_PROPERTY(qreal bottomPadding READ bottomPadding WRITE setBottomPadding RESET resetBottomPadding NOTIFY bottomPaddingChanged FINAL) Q_PROPERTY(QLocale locale READ locale WRITE setLocale RESET resetLocale NOTIFY localeChanged FINAL) Q_PROPERTY(QFont font READ font WRITE setFont RESET resetFont NOTIFY fontChanged FINAL) + Q_PROPERTY(QPalette palette READ palette WRITE setPalette RESET resetPalette NOTIFY paletteChanged FINAL REVISION 3) Q_PROPERTY(QQuickItem *parent READ parentItem WRITE setParentItem NOTIFY parentChanged FINAL) Q_PROPERTY(QQuickItem *background READ background WRITE setBackground NOTIFY backgroundChanged FINAL) Q_PROPERTY(QQuickItem *contentItem READ contentItem WRITE setContentItem NOTIFY contentItemChanged FINAL) @@ -207,6 +209,10 @@ public: void setFont(const QFont &font); void resetFont(); + QPalette palette() const; + void setPalette(const QPalette &palette); + void resetPalette(); + QQuickWindow *window() const; QQuickItem *popupItem() const; @@ -311,6 +317,7 @@ Q_SIGNALS: void bottomPaddingChanged(); void fontChanged(); void localeChanged(); + Q_REVISION(3) void paletteChanged(); void parentChanged(); void backgroundChanged(); void contentItemChanged(); @@ -364,9 +371,11 @@ protected: virtual void itemChange(QQuickItem::ItemChange change, const QQuickItem::ItemChangeData &data); virtual void marginsChange(const QMarginsF &newMargins, const QMarginsF &oldMargins); virtual void paddingChange(const QMarginsF &newPadding, const QMarginsF &oldPadding); + virtual void paletteChange(const QPalette &newPalette, const QPalette &oldPalette); virtual void spacingChange(qreal newSpacing, qreal oldSpacing); virtual QFont defaultFont() const; + virtual QPalette defaultPalette() const; #if QT_CONFIG(accessibility) virtual QAccessible::Role accessibleRole() const; diff --git a/src/quicktemplates2/qquickpopupitem.cpp b/src/quicktemplates2/qquickpopupitem.cpp index 3a770bf7..8251ad2f 100644 --- a/src/quicktemplates2/qquickpopupitem.cpp +++ b/src/quicktemplates2/qquickpopupitem.cpp @@ -56,6 +56,7 @@ public: void implicitHeightChanged() override; void resolveFont() override; + void resolvePalette() override; QQuickItem *getContentItem() override; @@ -90,6 +91,14 @@ void QQuickPopupItemPrivate::resolveFont() inheritFont(window->font()); } +void QQuickPopupItemPrivate::resolvePalette() +{ + if (QQuickApplicationWindow *window = qobject_cast<QQuickApplicationWindow *>(popup->window())) + inheritPalette(window->palette()); + else + inheritPalette(themePalette(QPlatformTheme::SystemPalette)); +} + QQuickItem *QQuickPopupItemPrivate::getContentItem() { Q_Q(QQuickPopupItem); @@ -290,12 +299,25 @@ void QQuickPopupItem::paddingChange(const QMarginsF &newPadding, const QMarginsF d->popup->paddingChange(newPadding, oldPadding); } +void QQuickPopupItem::paletteChange(const QPalette &newPalette, const QPalette &oldPalette) +{ + Q_D(QQuickPopupItem); + QQuickControl::paletteChange(newPalette, oldPalette); + d->popup->paletteChange(newPalette, oldPalette); +} + QFont QQuickPopupItem::defaultFont() const { Q_D(const QQuickPopupItem); return d->popup->defaultFont(); } +QPalette QQuickPopupItem::defaultPalette() const +{ + Q_D(const QQuickPopupItem); + return d->popup->defaultPalette(); +} + #if QT_CONFIG(accessibility) QAccessible::Role QQuickPopupItem::accessibleRole() const { diff --git a/src/quicktemplates2/qquickpopupitem_p_p.h b/src/quicktemplates2/qquickpopupitem_p_p.h index 9b3c76df..00ccd78f 100644 --- a/src/quicktemplates2/qquickpopupitem_p_p.h +++ b/src/quicktemplates2/qquickpopupitem_p_p.h @@ -91,8 +91,10 @@ protected: void localeChange(const QLocale &newLocale, const QLocale &oldLocale) override; void itemChange(ItemChange change, const ItemChangeData &data) override; void paddingChange(const QMarginsF &newPadding, const QMarginsF &oldPadding) override; + void paletteChange(const QPalette &newPalette, const QPalette &oldPalette) override; QFont defaultFont() const override; + QPalette defaultPalette() const override; #if QT_CONFIG(accessibility) QAccessible::Role accessibleRole() const override; diff --git a/src/quicktemplates2/qquicktextarea.cpp b/src/quicktemplates2/qquicktextarea.cpp index 3359f6cb..0df65cac 100644 --- a/src/quicktemplates2/qquicktextarea.cpp +++ b/src/quicktemplates2/qquicktextarea.cpp @@ -217,6 +217,43 @@ void QQuickTextAreaPrivate::updateFont(const QFont &font) emit q->fontChanged(); } +/*! + \internal + + Determine which palette is implicitly imposed on this control by its ancestors + and QGuiApplication::palette, resolve this against its own palette (attributes from + the implicit palette are copied over). Then propagate this palette to this + control's children. +*/ +void QQuickTextAreaPrivate::resolvePalette() +{ + Q_Q(QQuickTextArea); + inheritPalette(QQuickControlPrivate::parentPalette(q)); +} + +void QQuickTextAreaPrivate::inheritPalette(const QPalette &palette) +{ + QPalette parentPalette = extra.isAllocated() ? extra->requestedPalette.resolve(palette) : palette; + parentPalette.resolve(extra.isAllocated() ? extra->requestedPalette.resolve() | palette.resolve() : palette.resolve()); + + const QPalette defaultPalette = QQuickControlPrivate::themePalette(QPlatformTheme::TextEditPalette); + const QPalette resolvedPalette = parentPalette.resolve(defaultPalette); + + setPalette_helper(resolvedPalette); +} + +void QQuickTextAreaPrivate::updatePalette(const QPalette &palette) +{ + Q_Q(QQuickTextArea); + QPalette oldPalette = resolvedPalette; + resolvedPalette = palette; + + QQuickControlPrivate::updatePaletteRecur(q, palette); + + if (oldPalette != palette) + emit q->paletteChanged(); +} + #if QT_CONFIG(quicktemplates2_hover) void QQuickTextAreaPrivate::updateHoverEnabled(bool enabled, bool xplicit) { @@ -417,6 +454,9 @@ QQuickTextArea::QQuickTextArea(QQuickItem *parent) #endif QObjectPrivate::connect(this, &QQuickTextEdit::readOnlyChanged, d, &QQuickTextAreaPrivate::readOnlyChanged); + + // ### TODO: ItemEnabledChanged? + connect(this, &QQuickItem::enabledChanged, this, &QQuickTextArea::paletteChanged); } QQuickTextAreaAttached *QQuickTextArea::qmlAttachedProperties(QObject *object) @@ -603,11 +643,44 @@ bool QQuickTextArea::contains(const QPointF &point) const return QQuickTextEdit::contains(point); } +/*! + \since QtQuick.Controls 2.3 + \qmlproperty palette QtQuick.Controls::TextArea::palette + + This property holds the palette currently set for the text area. + + \sa Control::palette +*/ +QPalette QQuickTextArea::palette() const +{ + Q_D(const QQuickTextArea); + QPalette palette = d->resolvedPalette; + if (!isEnabled()) + palette.setCurrentColorGroup(QPalette::Disabled); + return palette; +} + +void QQuickTextArea::setPalette(const QPalette &palette) +{ + Q_D(QQuickTextArea); + if (d->extra.value().requestedPalette.resolve() == palette.resolve() && d->extra.value().requestedPalette == palette) + return; + + d->extra.value().requestedPalette = palette; + d->resolvePalette(); +} + +void QQuickTextArea::resetPalette() +{ + setPalette(QPalette()); +} + void QQuickTextArea::classBegin() { Q_D(QQuickTextArea); QQuickTextEdit::classBegin(); d->resolveFont(); + d->resolvePalette(); } void QQuickTextArea::componentComplete() @@ -630,6 +703,7 @@ void QQuickTextArea::itemChange(QQuickItem::ItemChange change, const QQuickItem: QQuickTextEdit::itemChange(change, value); if (change == ItemParentHasChanged && value.item) { d->resolveFont(); + d->resolvePalette(); #if QT_CONFIG(quicktemplates2_hover) if (!d->explicitHoverEnabled) d->updateHoverEnabled(QQuickControlPrivate::calcHoverEnabled(d->parentItem), false); // explicit=false diff --git a/src/quicktemplates2/qquicktextarea_p.h b/src/quicktemplates2/qquicktextarea_p.h index af7c1d13..6193e3ca 100644 --- a/src/quicktemplates2/qquicktextarea_p.h +++ b/src/quicktemplates2/qquicktextarea_p.h @@ -48,6 +48,7 @@ // We mean it. // +#include <QtGui/qpalette.h> #include <QtQuick/private/qquicktextedit_p.h> #include <QtQuickTemplates2/private/qtquicktemplates2global_p.h> @@ -69,6 +70,7 @@ class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickTextArea : public QQuickTextEdit Q_PROPERTY(Qt::FocusReason focusReason READ focusReason WRITE setFocusReason NOTIFY focusReasonChanged FINAL) Q_PROPERTY(bool hovered READ isHovered NOTIFY hoveredChanged FINAL REVISION 1) Q_PROPERTY(bool hoverEnabled READ isHoverEnabled WRITE setHoverEnabled RESET resetHoverEnabled NOTIFY hoverEnabledChanged FINAL REVISION 1) + Q_PROPERTY(QPalette palette READ palette WRITE setPalette RESET resetPalette NOTIFY paletteChanged FINAL REVISION 3) public: explicit QQuickTextArea(QQuickItem *parent = nullptr); @@ -96,6 +98,10 @@ public: bool contains(const QPointF &point) const override; + QPalette palette() const; + void setPalette(const QPalette &palette); + void resetPalette(); + Q_SIGNALS: void fontChanged(); void implicitWidthChanged3(); @@ -108,6 +114,7 @@ Q_SIGNALS: void pressAndHold(QQuickMouseEvent *event); Q_REVISION(1) void pressed(QQuickMouseEvent *event); Q_REVISION(1) void released(QQuickMouseEvent *event); + Q_REVISION(3) void paletteChanged(); protected: void classBegin() override; diff --git a/src/quicktemplates2/qquicktextarea_p_p.h b/src/quicktemplates2/qquicktextarea_p_p.h index 22ad4b09..82ea03cb 100644 --- a/src/quicktemplates2/qquicktextarea_p_p.h +++ b/src/quicktemplates2/qquicktextarea_p_p.h @@ -91,6 +91,15 @@ public: updateFont(font); } + void resolvePalette(); + void inheritPalette(const QPalette &palette); + void updatePalette(const QPalette &palette); + inline void setPalette_helper(const QPalette &palette) { + if (resolvedPalette.resolve() == palette.resolve() && resolvedPalette == palette) + return; + updatePalette(palette); + } + #if QT_CONFIG(quicktemplates2_hover) void updateHoverEnabled(bool h, bool e); #endif @@ -123,9 +132,11 @@ public: struct ExtraData { QFont requestedFont; + QPalette requestedPalette; }; QLazilyAllocated<ExtraData> extra; + QPalette resolvedPalette; QQuickItem *background; QString placeholder; Qt::FocusReason focusReason; diff --git a/src/quicktemplates2/qquicktextfield.cpp b/src/quicktemplates2/qquicktextfield.cpp index 241ff922..7322522b 100644 --- a/src/quicktemplates2/qquicktextfield.cpp +++ b/src/quicktemplates2/qquicktextfield.cpp @@ -191,6 +191,43 @@ void QQuickTextFieldPrivate::updateFont(const QFont &font) emit q->fontChanged(); } +/*! + \internal + + Determine which palette is implicitly imposed on this control by its ancestors + and QGuiApplication::palette, resolve this against its own palette (attributes from + the implicit palette are copied over). Then propagate this palette to this + control's children. +*/ +void QQuickTextFieldPrivate::resolvePalette() +{ + Q_Q(QQuickTextField); + inheritPalette(QQuickControlPrivate::parentPalette(q)); +} + +void QQuickTextFieldPrivate::inheritPalette(const QPalette &palette) +{ + QPalette parentPalette = extra.isAllocated() ? extra->requestedPalette.resolve(palette) : palette; + parentPalette.resolve(extra.isAllocated() ? extra->requestedPalette.resolve() | palette.resolve() : palette.resolve()); + + const QPalette defaultPalette = QQuickControlPrivate::themePalette(QPlatformTheme::TextLineEditPalette); + const QPalette resolvedPalette = parentPalette.resolve(defaultPalette); + + setPalette_helper(resolvedPalette); +} + +void QQuickTextFieldPrivate::updatePalette(const QPalette &palette) +{ + Q_Q(QQuickTextField); + QPalette oldPalette = resolvedPalette; + resolvedPalette = palette; + + QQuickControlPrivate::updatePaletteRecur(q, palette); + + if (oldPalette != palette) + emit q->paletteChanged(); +} + #if QT_CONFIG(quicktemplates2_hover) void QQuickTextFieldPrivate::updateHoverEnabled(bool enabled, bool xplicit) { @@ -291,6 +328,9 @@ QQuickTextField::QQuickTextField(QQuickItem *parent) #endif QObjectPrivate::connect(this, &QQuickTextInput::readOnlyChanged, d, &QQuickTextFieldPrivate::readOnlyChanged); QObjectPrivate::connect(this, &QQuickTextInput::echoModeChanged, d, &QQuickTextFieldPrivate::echoModeChanged); + + // ### TODO: ItemEnabledChanged? + connect(this, &QQuickItem::enabledChanged, this, &QQuickTextField::paletteChanged); } QFont QQuickTextField::font() const @@ -464,11 +504,44 @@ void QQuickTextField::resetHoverEnabled() #endif } +/*! + \since QtQuick.Controls 2.3 + \qmlproperty palette QtQuick.Controls::TextField::palette + + This property holds the palette currently set for the text field. + + \sa Control::palette +*/ +QPalette QQuickTextField::palette() const +{ + Q_D(const QQuickTextField); + QPalette palette = d->resolvedPalette; + if (!isEnabled()) + palette.setCurrentColorGroup(QPalette::Disabled); + return palette; +} + +void QQuickTextField::setPalette(const QPalette &palette) +{ + Q_D(QQuickTextField); + if (d->extra.value().requestedPalette.resolve() == palette.resolve() && d->extra.value().requestedPalette == palette) + return; + + d->extra.value().requestedPalette = palette; + d->resolvePalette(); +} + +void QQuickTextField::resetPalette() +{ + setPalette(QPalette()); +} + void QQuickTextField::classBegin() { Q_D(QQuickTextField); QQuickTextInput::classBegin(); d->resolveFont(); + d->resolvePalette(); } void QQuickTextField::componentComplete() @@ -491,6 +564,7 @@ void QQuickTextField::itemChange(QQuickItem::ItemChange change, const QQuickItem QQuickTextInput::itemChange(change, value); if (change == ItemParentHasChanged && value.item) { d->resolveFont(); + d->resolvePalette(); #if QT_CONFIG(quicktemplates2_hover) if (!d->explicitHoverEnabled) d->updateHoverEnabled(QQuickControlPrivate::calcHoverEnabled(d->parentItem), false); // explicit=false diff --git a/src/quicktemplates2/qquicktextfield_p.h b/src/quicktemplates2/qquicktextfield_p.h index 24e6ce53..0629a158 100644 --- a/src/quicktemplates2/qquicktextfield_p.h +++ b/src/quicktemplates2/qquicktextfield_p.h @@ -48,6 +48,7 @@ // We mean it. // +#include <QtGui/qpalette.h> #include <QtQuick/private/qquicktextinput_p.h> #include <QtQuickTemplates2/private/qtquicktemplates2global_p.h> @@ -68,6 +69,7 @@ class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickTextField : public QQuickTextInput Q_PROPERTY(Qt::FocusReason focusReason READ focusReason WRITE setFocusReason NOTIFY focusReasonChanged FINAL) Q_PROPERTY(bool hovered READ isHovered NOTIFY hoveredChanged FINAL REVISION 1) Q_PROPERTY(bool hoverEnabled READ isHoverEnabled WRITE setHoverEnabled RESET resetHoverEnabled NOTIFY hoverEnabledChanged FINAL REVISION 1) + Q_PROPERTY(QPalette palette READ palette WRITE setPalette RESET resetPalette NOTIFY paletteChanged FINAL REVISION 3) public: explicit QQuickTextField(QQuickItem *parent = nullptr); @@ -91,6 +93,10 @@ public: void setHoverEnabled(bool enabled); void resetHoverEnabled(); + QPalette palette() const; + void setPalette(const QPalette &palette); + void resetPalette(); + Q_SIGNALS: void fontChanged(); void implicitWidthChanged3(); @@ -103,6 +109,7 @@ Q_SIGNALS: void pressAndHold(QQuickMouseEvent *event); Q_REVISION(1) void pressed(QQuickMouseEvent *event); Q_REVISION(1) void released(QQuickMouseEvent *event); + Q_REVISION(3) void paletteChanged(); protected: void classBegin() override; diff --git a/src/quicktemplates2/qquicktextfield_p_p.h b/src/quicktemplates2/qquicktextfield_p_p.h index 6f36dda4..d726419b 100644 --- a/src/quicktemplates2/qquicktextfield_p_p.h +++ b/src/quicktemplates2/qquicktextfield_p_p.h @@ -87,6 +87,15 @@ public: updateFont(font); } + void resolvePalette(); + void inheritPalette(const QPalette &palette); + void updatePalette(const QPalette &palette); + inline void setPalette_helper(const QPalette &palette) { + if (resolvedPalette.resolve() == palette.resolve() && resolvedPalette == palette) + return; + updatePalette(palette); + } + #if QT_CONFIG(quicktemplates2_hover) void updateHoverEnabled(bool h, bool e); #endif @@ -112,9 +121,11 @@ public: struct ExtraData { QFont requestedFont; + QPalette requestedPalette; }; QLazilyAllocated<ExtraData> extra; + QPalette resolvedPalette; QQuickItem *background; QString placeholder; Qt::FocusReason focusReason; |