aboutsummaryrefslogtreecommitdiffstats
path: root/src/quickcontrols2impl/qquickattachedobject.cpp
diff options
context:
space:
mode:
authorMitch Curtis <mitch.curtis@qt.io>2022-06-23 15:33:34 +0800
committerMitch Curtis <mitch.curtis@qt.io>2022-10-13 11:34:11 +0800
commit49b9f1f1e85ce9aee960b1384fb542daacd8b7a7 (patch)
tree575cebdd0dd014d6569bfec36f20dbe5f6cddf4b /src/quickcontrols2impl/qquickattachedobject.cpp
parent5eb52b725526c26d0efa3856b6aba1919010f8fd (diff)
Make QQuickAttachedPropertyPropagator public
This type has been used internally as QQuickAttachedObject by the Imagine, Material and Universal styles to enable propagation of colors, dark mode flags, etc. for a while now. Users would benefit from having access to it to create their own styles (although it's not just limited to that use case). This patch: - Makes the type public in quickcontrols2. - Adds documentation and an example. - Fixes the test_window test to ensure that propagation through child windows actually works. [ChangeLog][Controls] Added QQuickAttachedPropertyPropagator, which provides a way to propagate attached properties from parent objects to children. This is especially useful when creating your own style. Fixes: QTBUG-63267 Change-Id: I2f1794dc4a9f2be56fad2f5e5f39e2ab845157fa Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io> Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@qt.io>
Diffstat (limited to 'src/quickcontrols2impl/qquickattachedobject.cpp')
-rw-r--r--src/quickcontrols2impl/qquickattachedobject.cpp243
1 files changed, 0 insertions, 243 deletions
diff --git a/src/quickcontrols2impl/qquickattachedobject.cpp b/src/quickcontrols2impl/qquickattachedobject.cpp
deleted file mode 100644
index a6bf6fc667..0000000000
--- a/src/quickcontrols2impl/qquickattachedobject.cpp
+++ /dev/null
@@ -1,243 +0,0 @@
-// Copyright (C) 2017 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
-
-#include "qquickattachedobject_p.h"
-
-#include <QtCore/qpointer.h>
-#include <QtQuick/qquickwindow.h>
-#include <QtQuick/private/qquickitem_p.h>
-#include <QtQuick/private/qquickitemchangelistener_p.h>
-#include <QtQuickTemplates2/private/qquickpopup_p.h>
-
-QT_BEGIN_NAMESPACE
-
-static QQuickAttachedObject *attachedObject(const QMetaObject *type, QObject *object, bool create = false)
-{
- if (!object)
- return nullptr;
- auto func = qmlAttachedPropertiesFunction(object, type);
- return qobject_cast<QQuickAttachedObject *>(qmlAttachedPropertiesObject(object, func, create));
-}
-
-static QQuickAttachedObject *findAttachedParent(const QMetaObject *type, QObject *object)
-{
- QQuickItem *item = qobject_cast<QQuickItem *>(object);
- if (item) {
- // lookup parent items and popups
- QQuickItem *parent = item->parentItem();
- while (parent) {
- QQuickAttachedObject *attached = attachedObject(type, parent);
- if (attached)
- return attached;
-
- QQuickPopup *popup = qobject_cast<QQuickPopup *>(parent->parent());
- if (popup)
- return attachedObject(type, popup);
-
- parent = parent->parentItem();
- }
-
- // fallback to item's window
- QQuickAttachedObject *attached = attachedObject(type, item->window());
- if (attached)
- return attached;
- } else {
- // lookup popup's window
- QQuickPopup *popup = qobject_cast<QQuickPopup *>(object);
- if (popup)
- return attachedObject(type, popup->popupItem()->window());
- }
-
- // lookup parent window
- QQuickWindow *window = qobject_cast<QQuickWindow *>(object);
- if (window) {
- QQuickWindow *parentWindow = qobject_cast<QQuickWindow *>(window->parent());
- if (parentWindow) {
- QQuickAttachedObject *attached = attachedObject(type, window);
- if (attached)
- return attached;
- }
- }
-
- // fallback to engine (global)
- if (object) {
- QQmlEngine *engine = qmlEngine(object);
- if (engine) {
- QByteArray name = QByteArray("_q_") + type->className();
- QQuickAttachedObject *attached = engine->property(name).value<QQuickAttachedObject *>();
- if (!attached) {
- attached = attachedObject(type, engine, true);
- engine->setProperty(name, QVariant::fromValue(attached));
- }
- return attached;
- }
- }
-
- return nullptr;
-}
-
-static QList<QQuickAttachedObject *> findAttachedChildren(const QMetaObject *type, QObject *object)
-{
- QList<QQuickAttachedObject *> children;
-
- QQuickItem *item = qobject_cast<QQuickItem *>(object);
- if (!item) {
- QQuickWindow *window = qobject_cast<QQuickWindow *>(object);
- if (window) {
- item = window->contentItem();
-
- const auto &windowChildren = window->children();
- for (QObject *child : windowChildren) {
- QQuickWindow *childWindow = qobject_cast<QQuickWindow *>(child);
- if (childWindow) {
- QQuickAttachedObject *attached = attachedObject(type, childWindow);
- if (attached)
- children += attached;
- }
- }
- }
- }
-
- if (item) {
- const auto childItems = item->childItems();
- for (QQuickItem *child : childItems) {
- QQuickAttachedObject *attached = attachedObject(type, child);
- if (attached)
- children += attached;
- else
- children += findAttachedChildren(type, child);
- }
- }
-
- return children;
-}
-
-static QQuickItem *findAttachedItem(QObject *parent)
-{
- QQuickItem *item = qobject_cast<QQuickItem *>(parent);
- if (!item) {
- QQuickPopup *popup = qobject_cast<QQuickPopup *>(parent);
- if (popup)
- item = popup->popupItem();
- }
- return item;
-}
-
-class QQuickAttachedObjectPrivate : public QObjectPrivate, public QQuickItemChangeListener
-{
-public:
- Q_DECLARE_PUBLIC(QQuickAttachedObject)
-
- static QQuickAttachedObjectPrivate *get(QQuickAttachedObject *attachedObject)
- {
- return attachedObject->d_func();
- }
-
- void attachTo(QObject *object);
- void detachFrom(QObject *object);
-
- void itemWindowChanged(QQuickWindow *window);
- void itemParentChanged(QQuickItem *item, QQuickItem *parent) override;
-
- QList<QQuickAttachedObject *> attachedChildren;
- QPointer<QQuickAttachedObject> attachedParent;
-};
-
-void QQuickAttachedObjectPrivate::attachTo(QObject *object)
-{
- QQuickItem *item = findAttachedItem(object);
- if (item) {
- connect(item, &QQuickItem::windowChanged, this, &QQuickAttachedObjectPrivate::itemWindowChanged);
- QQuickItemPrivate::get(item)->addItemChangeListener(this, QQuickItemPrivate::Parent);
- }
-}
-
-void QQuickAttachedObjectPrivate::detachFrom(QObject *object)
-{
- QQuickItem *item = findAttachedItem(object);
- if (item) {
- disconnect(item, &QQuickItem::windowChanged, this, &QQuickAttachedObjectPrivate::itemWindowChanged);
- QQuickItemPrivate::get(item)->removeItemChangeListener(this, QQuickItemPrivate::Parent);
- }
-}
-
-void QQuickAttachedObjectPrivate::itemWindowChanged(QQuickWindow *window)
-{
- Q_Q(QQuickAttachedObject);
- QQuickAttachedObject *attachedParent = nullptr;
- QQuickItem *item = qobject_cast<QQuickItem *>(q->sender());
- if (item)
- attachedParent = findAttachedParent(q->metaObject(), item);
- if (!attachedParent)
- attachedParent = attachedObject(q->metaObject(), window);
- q->setAttachedParent(attachedParent);
-}
-
-void QQuickAttachedObjectPrivate::itemParentChanged(QQuickItem *item, QQuickItem *parent)
-{
- Q_Q(QQuickAttachedObject);
- Q_UNUSED(parent);
- q->setAttachedParent(findAttachedParent(q->metaObject(), item));
-}
-
-QQuickAttachedObject::QQuickAttachedObject(QObject *parent)
- : QObject(*(new QQuickAttachedObjectPrivate), parent)
-{
- Q_D(QQuickAttachedObject);
- d->attachTo(parent);
-}
-
-QQuickAttachedObject::~QQuickAttachedObject()
-{
- Q_D(QQuickAttachedObject);
- d->detachFrom(parent());
- setAttachedParent(nullptr);
-}
-
-QList<QQuickAttachedObject *> QQuickAttachedObject::attachedChildren() const
-{
- Q_D(const QQuickAttachedObject);
- return d->attachedChildren;
-}
-
-QQuickAttachedObject *QQuickAttachedObject::attachedParent() const
-{
- Q_D(const QQuickAttachedObject);
- return d->attachedParent;
-}
-
-void QQuickAttachedObject::setAttachedParent(QQuickAttachedObject *parent)
-{
- Q_D(QQuickAttachedObject);
- if (d->attachedParent == parent)
- return;
-
- QQuickAttachedObject *oldParent = d->attachedParent;
- if (d->attachedParent)
- QQuickAttachedObjectPrivate::get(d->attachedParent)->attachedChildren.removeOne(this);
- d->attachedParent = parent;
- if (parent)
- QQuickAttachedObjectPrivate::get(parent)->attachedChildren.append(this);
- attachedParentChange(parent, oldParent);
-}
-
-void QQuickAttachedObject::init()
-{
- QQuickAttachedObject *attachedParent = findAttachedParent(metaObject(), parent());
- if (attachedParent)
- setAttachedParent(attachedParent);
-
- const QList<QQuickAttachedObject *> attachedChildren = findAttachedChildren(metaObject(), parent());
- for (QQuickAttachedObject *child : attachedChildren)
- child->setAttachedParent(this);
-}
-
-void QQuickAttachedObject::attachedParentChange(QQuickAttachedObject *newParent, QQuickAttachedObject *oldParent)
-{
- Q_UNUSED(newParent);
- Q_UNUSED(oldParent);
-}
-
-QT_END_NAMESPACE
-
-#include "moc_qquickattachedobject_p.cpp"