diff options
author | Volker Hilsheimer <volker.hilsheimer@qt.io> | 2021-12-03 13:27:51 +0100 |
---|---|---|
committer | Volker Hilsheimer <volker.hilsheimer@qt.io> | 2021-12-04 13:49:07 +0100 |
commit | 79c3cbe54eac3612bfe28232a765cf93d4abd665 (patch) | |
tree | 31f0753c564f698fea8d36ebb9ff63376d5f4d4b /src | |
parent | 6254b383309a0c3cd273264466105a7e3599a1ed (diff) |
Refactor: move change listener notification logic into helpers
A dozen loops doing more or less the same, all with the comment
"intentional copy (QTBUG-54732)", are best factored out into a helper.
Most of the loops call a different QQuickItemChangeListener member, so
provide a template that expects a pointer to a QQuickItemChangeListener
member function.
Some loops have some additional logic, so provide a second template that
just calls a functor.
No functional change, but needed for follow-up fixes to focus reason
handling in Qt Quick Controls.
Pick-to: 6.2
Change-Id: I6b11e06331da44b288315fc0732009d5f34f539a
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Diffstat (limited to 'src')
-rw-r--r-- | src/quick/items/qquickitem.cpp | 153 | ||||
-rw-r--r-- | src/quick/items/qquickitem_p.h | 27 | ||||
-rw-r--r-- | src/quick/items/qquickitemchangelistener_p.h | 1 |
3 files changed, 60 insertions, 121 deletions
diff --git a/src/quick/items/qquickitem.cpp b/src/quick/items/qquickitem.cpp index fffee1afa0..a6a14d7ce3 100644 --- a/src/quick/items/qquickitem.cpp +++ b/src/quick/items/qquickitem.cpp @@ -2355,31 +2355,22 @@ QQuickItem::~QQuickItem() while (!d->childItems.isEmpty()) d->childItems.constFirst()->setParentItem(nullptr); - if (!d->changeListeners.isEmpty()) { - const auto listeners = d->changeListeners; // NOTE: intentional copy (QTBUG-54732) - for (const QQuickItemPrivate::ChangeListener &change : listeners) { - QQuickAnchorsPrivate *anchor = change.listener->anchorPrivate(); - if (anchor) - anchor->clearItem(this); - } - - /* + d->notifyChangeListeners(QQuickItemPrivate::AllChanges, [this](const QQuickItemPrivate::ChangeListener &change){ + QQuickAnchorsPrivate *anchor = change.listener->anchorPrivate(); + if (anchor) + anchor->clearItem(this); + }); + /* update item anchors that depended on us unless they are our child (and will also be destroyed), or our sibling, and our parent is also being destroyed. */ - for (const QQuickItemPrivate::ChangeListener &change : listeners) { - QQuickAnchorsPrivate *anchor = change.listener->anchorPrivate(); - if (anchor && anchor->item && anchor->item->parentItem() && anchor->item->parentItem() != this) - anchor->update(); - } - - for (const QQuickItemPrivate::ChangeListener &change : listeners) { - if (change.types & QQuickItemPrivate::Destroyed) - change.listener->itemDestroyed(this); - } - - d->changeListeners.clear(); - } + d->notifyChangeListeners(QQuickItemPrivate::AllChanges, [this](const QQuickItemPrivate::ChangeListener &change){ + QQuickAnchorsPrivate *anchor = change.listener->anchorPrivate(); + if (anchor && anchor->item && anchor->item->parentItem() && anchor->item->parentItem() != this) + anchor->update(); + }); + d->notifyChangeListeners(QQuickItemPrivate::Destroyed, &QQuickItemChangeListener::itemDestroyed, this); + d->changeListeners.clear(); /* Remove any references our transforms have to us, in case they try to @@ -3663,14 +3654,7 @@ QQuickAnchors *QQuickItemPrivate::anchors() const void QQuickItemPrivate::siblingOrderChanged() { Q_Q(QQuickItem); - if (!changeListeners.isEmpty()) { - const auto listeners = changeListeners; // NOTE: intentional copy (QTBUG-54732) - for (const QQuickItemPrivate::ChangeListener &change : listeners) { - if (change.types & QQuickItemPrivate::SiblingOrder) { - change.listener->itemSiblingOrderChanged(q); - } - } - } + notifyChangeListeners(QQuickItemPrivate::SiblingOrder, &QQuickItemChangeListener::itemSiblingOrderChanged, q); } QQmlListProperty<QObject> QQuickItemPrivate::data() @@ -3801,15 +3785,10 @@ void QQuickItem::geometryChange(const QRectF &newGeometry, const QRectF &oldGeom change.setWidthChange(newGeometry.width() != oldGeometry.width()); change.setHeightChange(newGeometry.height() != oldGeometry.height()); - if (!d->changeListeners.isEmpty()) { - const auto listeners = d->changeListeners; // NOTE: intentional copy (QTBUG-54732) - for (const QQuickItemPrivate::ChangeListener &listener : listeners) { - if (listener.types & QQuickItemPrivate::Geometry) { - if (change.matches(listener.gTypes)) - listener.listener->itemGeometryChanged(this, change, oldGeometry); - } - } - } + d->notifyChangeListeners(QQuickItemPrivate::Geometry, [&](const QQuickItemPrivate::ChangeListener &listener){ + if (change.matches(listener.gTypes)) + listener.listener->itemGeometryChanged(this, change, oldGeometry); + }); // The notify method takes care of emitting the signal, and also notifies any // property observers. @@ -4439,16 +4418,11 @@ void QQuickItem::setBaselineOffset(qreal offset) d->baselineOffset = offset; - if (!d->changeListeners.isEmpty()) { - const auto listeners = d->changeListeners; // NOTE: intentional copy (QTBUG-54732) - for (const QQuickItemPrivate::ChangeListener &change : listeners) { - if (change.types & QQuickItemPrivate::Geometry) { - QQuickAnchorsPrivate *anchor = change.listener->anchorPrivate(); - if (anchor) - anchor->updateVerticalAnchors(); - } - } - } + d->notifyChangeListeners(QQuickItemPrivate::Geometry, [](const QQuickItemPrivate::ChangeListener &change){ + QQuickAnchorsPrivate *anchor = change.listener->anchorPrivate(); + if (anchor) + anchor->updateVerticalAnchors(); + }); if (d->_anchors && (d->_anchors->usedAnchors() & QQuickAnchors::BaselineAnchor)) QQuickAnchorsPrivate::get(d->_anchors)->updateVerticalAnchors(); @@ -6617,26 +6591,12 @@ void QQuickItemPrivate::itemChange(QQuickItem::ItemChange change, const QQuickIt q->itemChange(change, data); if (!subtreeTransformChangedEnabled) subtreeTransformChangedEnabled = true; - if (!changeListeners.isEmpty()) { - const auto listeners = changeListeners; // NOTE: intentional copy (QTBUG-54732) - for (const QQuickItemPrivate::ChangeListener &change : listeners) { - if (change.types & QQuickItemPrivate::Children) { - change.listener->itemChildAdded(q, data.item); - } - } - } + notifyChangeListeners(QQuickItemPrivate::Children, &QQuickItemChangeListener::itemChildAdded, q, data.item); break; } case QQuickItem::ItemChildRemovedChange: { q->itemChange(change, data); - if (!changeListeners.isEmpty()) { - const auto listeners = changeListeners; // NOTE: intentional copy (QTBUG-54732) - for (const QQuickItemPrivate::ChangeListener &change : listeners) { - if (change.types & QQuickItemPrivate::Children) { - change.listener->itemChildRemoved(q, data.item); - } - } - } + notifyChangeListeners(QQuickItemPrivate::Children, &QQuickItemChangeListener::itemChildRemoved, q, data.item); break; } case QQuickItem::ItemSceneChange: @@ -6644,50 +6604,22 @@ void QQuickItemPrivate::itemChange(QQuickItem::ItemChange change, const QQuickIt break; case QQuickItem::ItemVisibleHasChanged: { q->itemChange(change, data); - if (!changeListeners.isEmpty()) { - const auto listeners = changeListeners; // NOTE: intentional copy (QTBUG-54732) - for (const QQuickItemPrivate::ChangeListener &change : listeners) { - if (change.types & QQuickItemPrivate::Visibility) { - change.listener->itemVisibilityChanged(q); - } - } - } + notifyChangeListeners(QQuickItemPrivate::Visibility, &QQuickItemChangeListener::itemVisibilityChanged, q); break; } case QQuickItem::ItemEnabledHasChanged: { q->itemChange(change, data); - if (!changeListeners.isEmpty()) { - const auto listeners = changeListeners; // NOTE: intentional copy (QTBUG-54732) - for (const QQuickItemPrivate::ChangeListener &change : listeners) { - if (change.types & QQuickItemPrivate::Enabled) { - change.listener->itemEnabledChanged(q); - } - } - } + notifyChangeListeners(QQuickItemPrivate::Enabled, &QQuickItemChangeListener::itemEnabledChanged, q); break; } case QQuickItem::ItemParentHasChanged: { q->itemChange(change, data); - if (!changeListeners.isEmpty()) { - const auto listeners = changeListeners; // NOTE: intentional copy (QTBUG-54732) - for (const QQuickItemPrivate::ChangeListener &change : listeners) { - if (change.types & QQuickItemPrivate::Parent) { - change.listener->itemParentChanged(q, data.item); - } - } - } + notifyChangeListeners(QQuickItemPrivate::Parent, &QQuickItemChangeListener::itemParentChanged, q, data.item); break; } case QQuickItem::ItemOpacityHasChanged: { q->itemChange(change, data); - if (!changeListeners.isEmpty()) { - const auto listeners = changeListeners; // NOTE: intentional copy (QTBUG-54732) - for (const QQuickItemPrivate::ChangeListener &change : listeners) { - if (change.types & QQuickItemPrivate::Opacity) { - change.listener->itemOpacityChanged(q); - } - } - } + notifyChangeListeners(QQuickItemPrivate::Opacity, &QQuickItemChangeListener::itemOpacityChanged, q); break; } case QQuickItem::ItemActiveFocusHasChanged: @@ -6695,14 +6627,7 @@ void QQuickItemPrivate::itemChange(QQuickItem::ItemChange change, const QQuickIt break; case QQuickItem::ItemRotationHasChanged: { q->itemChange(change, data); - if (!changeListeners.isEmpty()) { - const auto listeners = changeListeners; // NOTE: intentional copy (QTBUG-54732) - for (const QQuickItemPrivate::ChangeListener &change : listeners) { - if (change.types & QQuickItemPrivate::Rotation) { - change.listener->itemRotationChanged(q); - } - } - } + notifyChangeListeners(QQuickItemPrivate::Rotation, &QQuickItemChangeListener::itemRotationChanged, q); break; } case QQuickItem::ItemAntialiasingHasChanged: @@ -7114,14 +7039,7 @@ void QQuickItem::resetWidth() void QQuickItemPrivate::implicitWidthChanged() { Q_Q(QQuickItem); - if (!changeListeners.isEmpty()) { - const auto listeners = changeListeners; // NOTE: intentional copy (QTBUG-54732) - for (const QQuickItemPrivate::ChangeListener &change : listeners) { - if (change.types & QQuickItemPrivate::ImplicitWidth) { - change.listener->itemImplicitWidthChanged(q); - } - } - } + notifyChangeListeners(QQuickItemPrivate::ImplicitWidth, &QQuickItemChangeListener::itemImplicitWidthChanged, q); emit q->implicitWidthChanged(); } @@ -7330,14 +7248,7 @@ void QQuickItem::resetHeight() void QQuickItemPrivate::implicitHeightChanged() { Q_Q(QQuickItem); - if (!changeListeners.isEmpty()) { - const auto listeners = changeListeners; // NOTE: intentional copy (QTBUG-54732) - for (const QQuickItemPrivate::ChangeListener &change : listeners) { - if (change.types & QQuickItemPrivate::ImplicitHeight) { - change.listener->itemImplicitHeightChanged(q); - } - } - } + notifyChangeListeners(QQuickItemPrivate::ImplicitHeight, &QQuickItemChangeListener::itemImplicitHeightChanged, q); emit q->implicitHeightChanged(); } diff --git a/src/quick/items/qquickitem_p.h b/src/quick/items/qquickitem_p.h index 51ef850d5f..576d392a26 100644 --- a/src/quick/items/qquickitem_p.h +++ b/src/quick/items/qquickitem_p.h @@ -331,6 +331,7 @@ public: ImplicitWidth = 0x100, ImplicitHeight = 0x200, Enabled = 0x400, + AllChanges = 0xFFFFFFFF }; Q_DECLARE_FLAGS(ChangeTypes, ChangeType) @@ -358,6 +359,32 @@ public: QQuickGeometryChange gTypes; //NOTE: not used for == }; + // call QQuickItemChangeListener PMF + template <typename Fn, typename ...Args> + void notifyChangeListeners(QQuickItemPrivate::ChangeTypes changeTypes, Fn &&function, Args &&...args) + { + if (changeListeners.isEmpty()) + return; + + const auto listeners = changeListeners; // NOTE: intentional copy (QTBUG-54732) + for (const QQuickItemPrivate::ChangeListener &change : listeners) { + if (change.types & changeTypes) + (change.listener->*function)(args...); + } + } + // call functor + template <typename Fn> + void notifyChangeListeners(QQuickItemPrivate::ChangeTypes changeTypes, Fn &&function) { + if (changeListeners.isEmpty()) + return; + + const auto listeners = changeListeners; // NOTE: intentional copy (QTBUG-54732) + for (const QQuickItemPrivate::ChangeListener &change : listeners) { + if (change.types & changeTypes) + function(change); + } + } + struct ExtraData { ExtraData(); diff --git a/src/quick/items/qquickitemchangelistener_p.h b/src/quick/items/qquickitemchangelistener_p.h index 31d06c9983..91e2d69cc0 100644 --- a/src/quick/items/qquickitemchangelistener_p.h +++ b/src/quick/items/qquickitemchangelistener_p.h @@ -134,6 +134,7 @@ public: virtual void itemRotationChanged(QQuickItem *) {} virtual void itemImplicitWidthChanged(QQuickItem *) {} virtual void itemImplicitHeightChanged(QQuickItem *) {} + virtual void itemFocusChanged(QQuickItem *, Qt::FocusReason /* reason */) {} virtual QQuickAnchorsPrivate *anchorPrivate() { return nullptr; } }; |