aboutsummaryrefslogtreecommitdiffstats
path: root/src/quicktemplates2/qquickcontrol.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/quicktemplates2/qquickcontrol.cpp')
-rw-r--r--src/quicktemplates2/qquickcontrol.cpp530
1 files changed, 362 insertions, 168 deletions
diff --git a/src/quicktemplates2/qquickcontrol.cpp b/src/quicktemplates2/qquickcontrol.cpp
index 4bf0a867..1c9bcfd5 100644
--- a/src/quicktemplates2/qquickcontrol.cpp
+++ b/src/quicktemplates2/qquickcontrol.cpp
@@ -130,8 +130,7 @@ QQuickControlPrivate::QQuickControlPrivate()
focusPolicy(Qt::NoFocus),
focusReason(Qt::OtherFocusReason),
background(nullptr),
- contentItem(nullptr),
- accessibleAttached(nullptr)
+ contentItem(nullptr)
{
#if QT_CONFIG(accessibility)
QAccessible::installActivationObserver(this);
@@ -330,27 +329,11 @@ QAccessible::Role QQuickControlPrivate::accessibleRole() const
return q->accessibleRole();
}
-QAccessible::Role QQuickControl::accessibleRole() const
-{
- return QAccessible::NoRole;
-}
-
-void QQuickControl::accessibilityActiveChanged(bool active)
+QQuickAccessibleAttached *QQuickControlPrivate::accessibleAttached(const QObject *object)
{
- Q_D(QQuickControl);
- if (d->accessibleAttached || !active)
- return;
-
- d->accessibleAttached = qobject_cast<QQuickAccessibleAttached *>(qmlAttachedPropertiesObject<QQuickAccessibleAttached>(this, true));
-
- // QQuickControl relies on the existence of a QQuickAccessibleAttached object.
- // However, qmlAttachedPropertiesObject(create=true) creates an instance only
- // for items that have been created by a QML engine. Therefore we create the
- // object by hand for items created in C++ (QQuickPopupItem, for instance).
- if (!d->accessibleAttached)
- d->accessibleAttached = new QQuickAccessibleAttached(this);
-
- d->accessibleAttached->setRole(accessibleRole());
+ if (!QAccessible::isActive())
+ return nullptr;
+ return QQuickAccessibleAttached::attachedProperties(object);
}
#endif
@@ -410,11 +393,11 @@ void QQuickControlPrivate::resolveFont()
inheritFont(parentFont(q));
}
-void QQuickControlPrivate::inheritFont(const QFont &f)
+void QQuickControlPrivate::inheritFont(const QFont &font)
{
Q_Q(QQuickControl);
- QFont parentFont = extra.isAllocated() ? extra->font.resolve(f) : f;
- parentFont.resolve(extra.isAllocated() ? extra->font.resolve() | f.resolve() : f.resolve());
+ QFont parentFont = extra.isAllocated() ? extra->requestedFont.resolve(font) : font;
+ parentFont.resolve(extra.isAllocated() ? extra->requestedFont.resolve() | font.resolve() : font.resolve());
const QFont defaultFont = q->defaultFont();
const QFont resolvedFont = parentFont.resolve(defaultFont);
@@ -427,35 +410,192 @@ void QQuickControlPrivate::inheritFont(const QFont &f)
Assign \a font to this control, and propagate it to all children.
*/
-void QQuickControlPrivate::updateFont(const QFont &f)
+void QQuickControlPrivate::updateFont(const QFont &font)
{
Q_Q(QQuickControl);
- QFont old = resolvedFont;
- resolvedFont = f;
+ QFont oldFont = resolvedFont;
+ resolvedFont = font;
- if (old != f)
- q->fontChange(f, old);
+ if (oldFont != font)
+ q->fontChange(font, oldFont);
- QQuickControlPrivate::updateFontRecur(q, f);
+ QQuickControlPrivate::updateFontRecur(q, font);
- if (old != f)
+ if (oldFont != font)
emit q->fontChanged();
}
-void QQuickControlPrivate::updateFontRecur(QQuickItem *item, const QFont &f)
+void QQuickControlPrivate::updateFontRecur(QQuickItem *item, const QFont &font)
{
const auto childItems = item->childItems();
for (QQuickItem *child : childItems) {
if (QQuickControl *control = qobject_cast<QQuickControl *>(child))
- QQuickControlPrivate::get(control)->inheritFont(f);
+ QQuickControlPrivate::get(control)->inheritFont(font);
else if (QQuickLabel *label = qobject_cast<QQuickLabel *>(child))
- QQuickLabelPrivate::get(label)->inheritFont(f);
+ QQuickLabelPrivate::get(label)->inheritFont(font);
else if (QQuickTextArea *textArea = qobject_cast<QQuickTextArea *>(child))
- QQuickTextAreaPrivate::get(textArea)->inheritFont(f);
+ QQuickTextAreaPrivate::get(textArea)->inheritFont(font);
else if (QQuickTextField *textField = qobject_cast<QQuickTextField *>(child))
- QQuickTextFieldPrivate::get(textField)->inheritFont(f);
+ QQuickTextFieldPrivate::get(textField)->inheritFont(font);
+ else
+ QQuickControlPrivate::updateFontRecur(child, 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;
+ while (p) {
+ if (const QQuickControl *control = qobject_cast<const QQuickControl *>(p))
+ return control->locale();
+
+ QVariant v = p->property("locale");
+ if (v.isValid() && v.userType() == QMetaType::QLocale)
+ return v.toLocale();
+
+ p = p->parentItem();
+ }
+
+ if (item) {
+ if (QQuickApplicationWindow *window = qobject_cast<QQuickApplicationWindow *>(item->window()))
+ return window->locale();
+ }
+
+ return QLocale();
+}
+
+void QQuickControlPrivate::updateLocale(const QLocale &l, bool e)
+{
+ Q_Q(QQuickControl);
+ if (!e && hasLocale)
+ return;
+
+ QLocale old = q->locale();
+ hasLocale = e;
+ if (old != l) {
+ bool wasMirrored = q->isMirrored();
+ q->localeChange(l, old);
+ locale = l;
+ QQuickControlPrivate::updateLocaleRecur(q, l);
+ emit q->localeChanged();
+ if (wasMirrored != q->isMirrored())
+ q->mirrorChange();
+ }
+}
+
+void QQuickControlPrivate::updateLocaleRecur(QQuickItem *item, const QLocale &l)
+{
+ const auto childItems = item->childItems();
+ for (QQuickItem *child : childItems) {
+ if (QQuickControl *control = qobject_cast<QQuickControl *>(child))
+ QQuickControlPrivate::get(control)->updateLocale(l, false);
else
- QQuickControlPrivate::updateFontRecur(child, f);
+ updateLocaleRecur(child, l);
}
}
@@ -517,48 +657,44 @@ bool QQuickControlPrivate::calcHoverEnabled(const QQuickItem *item)
}
#endif
-QString QQuickControl::accessibleName() const
+static inline QString contentItemName() { return QStringLiteral("contentItem"); }
+
+void QQuickControlPrivate::cancelContentItem()
{
-#if QT_CONFIG(accessibility)
- Q_D(const QQuickControl);
- if (d->accessibleAttached)
- return d->accessibleAttached->name();
-#endif
- return QString();
+ Q_Q(QQuickControl);
+ quickCancelDeferred(q, contentItemName());
}
-void QQuickControl::setAccessibleName(const QString &name)
+void QQuickControlPrivate::executeContentItem(bool complete)
{
-#if QT_CONFIG(accessibility)
- Q_D(QQuickControl);
- if (d->accessibleAttached)
- d->accessibleAttached->setName(name);
-#else
- Q_UNUSED(name)
-#endif
+ Q_Q(QQuickControl);
+ if (contentItem.wasExecuted())
+ return;
+
+ if (!contentItem || complete)
+ quickBeginDeferred(q, contentItemName(), contentItem);
+ if (complete)
+ quickCompleteDeferred(q, contentItemName(), contentItem);
}
-QVariant QQuickControl::accessibleProperty(const char *propertyName)
+static inline QString backgroundName() { return QStringLiteral("background"); }
+
+void QQuickControlPrivate::cancelBackground()
{
-#if QT_CONFIG(accessibility)
- Q_D(QQuickControl);
- if (d->accessibleAttached)
- return QQuickAccessibleAttached::property(this, propertyName);
-#endif
- Q_UNUSED(propertyName)
- return QVariant();
+ Q_Q(QQuickControl);
+ quickCancelDeferred(q, backgroundName());
}
-bool QQuickControl::setAccessibleProperty(const char *propertyName, const QVariant &value)
+void QQuickControlPrivate::executeBackground(bool complete)
{
-#if QT_CONFIG(accessibility)
- Q_D(QQuickControl);
- if (d->accessibleAttached)
- return QQuickAccessibleAttached::setProperty(this, propertyName, value);
-#endif
- Q_UNUSED(propertyName)
- Q_UNUSED(value)
- return false;
+ Q_Q(QQuickControl);
+ if (background.wasExecuted())
+ return;
+
+ if (!background || complete)
+ quickBeginDeferred(q, backgroundName(), background);
+ if (complete)
+ quickCompleteDeferred(q, backgroundName(), background);
}
QQuickControl::QQuickControl(QQuickItem *parent)
@@ -576,6 +712,9 @@ void QQuickControl::itemChange(QQuickItem::ItemChange change, const QQuickItem::
Q_D(QQuickControl);
QQuickItem::itemChange(change, value);
switch (change) {
+ case ItemEnabledHasChanged:
+ emit paletteChanged();
+ break;
case ItemVisibleHasChanged:
#if QT_CONFIG(quicktemplates2_hover)
if (!value.boolValue)
@@ -586,6 +725,7 @@ void QQuickControl::itemChange(QQuickItem::ItemChange change, const QQuickItem::
case ItemParentHasChanged:
if ((change == ItemParentHasChanged && value.item) || (change == ItemSceneChange && value.window)) {
d->resolveFont();
+ d->resolvePalette();
if (!d->hasLocale)
d->updateLocale(QQuickControlPrivate::calcLocale(d->parentItem), false); // explicit=false
#if QT_CONFIG(quicktemplates2_hover)
@@ -615,9 +755,14 @@ void QQuickControl::itemChange(QQuickItem::ItemChange change, const QQuickItem::
The default font depends on the system environment. ApplicationWindow maintains a system/theme
font which serves as a default for all controls. There may also be special font defaults for
- certain types of controls. You can also set the default font for controls by passing a custom
- font to QGuiApplication::setFont(), before loading the QML. Finally, the font is matched
- against Qt's font database to find the best match.
+ certain types of controls. You can also set the default font for controls by either:
+
+ \list
+ \li passing a custom font to QGuiApplication::setFont(), before loading the QML; or
+ \li specifying the fonts in the \l {Qt Quick Controls 2 Configuration File}{qtquickcontrols2.conf file}.
+ \endlist
+
+ Finally, the font is matched against Qt's font database to find the best match.
Control propagates explicit font properties from parent to children. If you change a specific
property on a control's font, that property propagates to all of the control's children,
@@ -638,6 +783,9 @@ void QQuickControl::itemChange(QQuickItem::ItemChange change, const QQuickItem::
}
}
\endcode
+
+ For the full list of available font properties, see the
+ \l [QtQuick]{font}{font QML Basic Type} documentation.
*/
QFont QQuickControl::font() const
{
@@ -648,10 +796,10 @@ QFont QQuickControl::font() const
void QQuickControl::setFont(const QFont &font)
{
Q_D(QQuickControl);
- if (d->extra.value().font.resolve() == font.resolve() && d->extra.value().font == font)
+ if (d->extra.value().requestedFont.resolve() == font.resolve() && d->extra.value().requestedFont == font)
return;
- d->extra.value().font = font;
+ d->extra.value().requestedFont = font;
d->resolveFont();
}
@@ -924,98 +1072,6 @@ void QQuickControl::resetLocale()
d->updateLocale(QQuickControlPrivate::calcLocale(d->parentItem), false); // explicit=false
}
-QLocale QQuickControlPrivate::calcLocale(const QQuickItem *item)
-{
- const QQuickItem *p = item;
- while (p) {
- if (const QQuickControl *control = qobject_cast<const QQuickControl *>(p))
- return control->locale();
-
- QVariant v = p->property("locale");
- if (v.isValid() && v.userType() == QMetaType::QLocale)
- return v.toLocale();
-
- p = p->parentItem();
- }
-
- if (item) {
- if (QQuickApplicationWindow *window = qobject_cast<QQuickApplicationWindow *>(item->window()))
- return window->locale();
- }
-
- return QLocale();
-}
-
-static inline QString contentItemName() { return QStringLiteral("contentItem"); }
-
-void QQuickControlPrivate::cancelContentItem()
-{
- Q_Q(QQuickControl);
- quickCancelDeferred(q, contentItemName());
-}
-
-void QQuickControlPrivate::executeContentItem(bool complete)
-{
- Q_Q(QQuickControl);
- if (contentItem.wasExecuted())
- return;
-
- if (!contentItem || complete)
- quickBeginDeferred(q, contentItemName(), contentItem);
- if (complete)
- quickCompleteDeferred(q, contentItemName(), contentItem);
-}
-
-static inline QString backgroundName() { return QStringLiteral("background"); }
-
-void QQuickControlPrivate::cancelBackground()
-{
- Q_Q(QQuickControl);
- quickCancelDeferred(q, backgroundName());
-}
-
-void QQuickControlPrivate::executeBackground(bool complete)
-{
- Q_Q(QQuickControl);
- if (background.wasExecuted())
- return;
-
- if (!background || complete)
- quickBeginDeferred(q, backgroundName(), background);
- if (complete)
- quickCompleteDeferred(q, backgroundName(), background);
-}
-
-void QQuickControlPrivate::updateLocale(const QLocale &l, bool e)
-{
- Q_Q(QQuickControl);
- if (!e && hasLocale)
- return;
-
- QLocale old = q->locale();
- hasLocale = e;
- if (old != l) {
- bool wasMirrored = q->isMirrored();
- q->localeChange(l, old);
- locale = l;
- QQuickControlPrivate::updateLocaleRecur(q, l);
- emit q->localeChanged();
- if (wasMirrored != q->isMirrored())
- q->mirrorChange();
- }
-}
-
-void QQuickControlPrivate::updateLocaleRecur(QQuickItem *item, const QLocale &l)
-{
- const auto childItems = item->childItems();
- for (QQuickItem *child : childItems) {
- if (QQuickControl *control = qobject_cast<QQuickControl *>(child))
- QQuickControlPrivate::get(control)->updateLocale(l, false);
- else
- updateLocaleRecur(child, l);
- }
-}
-
/*!
\qmlproperty bool QtQuick.Controls::Control::mirrored
\readonly
@@ -1315,11 +1371,81 @@ void QQuickControl::setContentItem(QQuickItem *item)
d->setContentItem_helper(item, true);
}
+/*!
+ \since QtQuick.Controls 2.3 (Qt 5.10)
+ \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 either:
+
+ \list
+ \li passing a custom palette to QGuiApplication::setPalette(), before loading any QML; or
+ \li specifying the colors in the \l {Qt Quick Controls 2 Configuration File}{qtquickcontrols2.conf file}.
+ \endlist
+
+ 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
+
+ For the full list of available palette colors, see the
+ \l {qtquickcontrols2-palette}{palette QML Basic Type} documentation.
+
+ \sa ApplicationWindow::palette, Popup::palette
+*/
+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()
@@ -1337,7 +1463,7 @@ void QQuickControl::componentComplete()
setAcceptHoverEvents(QQuickControlPrivate::calcHoverEnabled(d->parentItem));
#endif
#if QT_CONFIG(accessibility)
- if (!d->accessibleAttached && QAccessible::isActive())
+ if (QAccessible::isActive())
accessibilityActiveChanged(true);
#endif
}
@@ -1347,6 +1473,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);
@@ -1520,4 +1651,67 @@ 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
+{
+ return QAccessible::NoRole;
+}
+
+void QQuickControl::accessibilityActiveChanged(bool active)
+{
+ if (!active)
+ return;
+
+ QQuickAccessibleAttached *accessibleAttached = qobject_cast<QQuickAccessibleAttached *>(qmlAttachedPropertiesObject<QQuickAccessibleAttached>(this, true));
+ Q_ASSERT(accessibleAttached);
+ accessibleAttached->setRole(accessibleRole());
+}
+#endif
+
+QString QQuickControl::accessibleName() const
+{
+#if QT_CONFIG(accessibility)
+ if (QQuickAccessibleAttached *accessibleAttached = QQuickControlPrivate::accessibleAttached(this))
+ return accessibleAttached->name();
+#endif
+ return QString();
+}
+
+void QQuickControl::setAccessibleName(const QString &name)
+{
+#if QT_CONFIG(accessibility)
+ if (QQuickAccessibleAttached *accessibleAttached = QQuickControlPrivate::accessibleAttached(this))
+ accessibleAttached->setName(name);
+#else
+ Q_UNUSED(name)
+#endif
+}
+
+QVariant QQuickControl::accessibleProperty(const char *propertyName)
+{
+#if QT_CONFIG(accessibility)
+ if (QAccessible::isActive())
+ return QQuickAccessibleAttached::property(this, propertyName);
+#endif
+ Q_UNUSED(propertyName)
+ return QVariant();
+}
+
+bool QQuickControl::setAccessibleProperty(const char *propertyName, const QVariant &value)
+{
+#if QT_CONFIG(accessibility)
+ if (QAccessible::isActive())
+ return QQuickAccessibleAttached::setProperty(this, propertyName, value);
+#endif
+ Q_UNUSED(propertyName)
+ Q_UNUSED(value)
+ return false;
+}
+
QT_END_NAMESPACE