From 9b6f60992cadf3835a9e6d752cfe860bf0da85bc Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Fri, 8 Oct 2021 13:59:02 +0300 Subject: [PATCH] QmlDesigner: Update repeater parent when repeater properties change Any time repeater properties change, the repeater parent should be dirtied to ensure it rerenders. Often the rerender is triggered incidentally due to other triggers, but e.g. in case model value is changed to zero, or if model property is removed, no other trigger causes rerender. Also moved the repeater parent checks into QuickItemNodeInstance to avoid polluting Qt5NodeInstanceServer with such stuff. Fixes: QDS-5233 Change-Id: Idd89e23c5ad022d26f443d665dac81dc2cbb0b28 Reviewed-by: Mahmoud Badri Reviewed-by: Thomas Hartmann --- .../instances/qt5nodeinstanceserver.cpp | 42 ------------------- .../instances/qt5nodeinstanceserver.h | 2 - .../instances/quickitemnodeinstance.cpp | 37 ++++++++++++++++ .../instances/quickitemnodeinstance.h | 1 + 4 files changed, 38 insertions(+), 44 deletions(-) diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5nodeinstanceserver.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5nodeinstanceserver.cpp index 2e1e03fa630..9f8f5caf528 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5nodeinstanceserver.cpp +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5nodeinstanceserver.cpp @@ -37,7 +37,6 @@ #include #include #include -#include #include #include @@ -194,32 +193,6 @@ QList Qt5NodeInstanceServer::allItems() const return QList(); } -void Qt5NodeInstanceServer::markRepeaterParentDirty(qint32 id) const -{ - if (!hasInstanceForId(id)) - return; - - ServerNodeInstance instance = instanceForId(id); - if (!instance.isValid()) - return; - - ServerNodeInstance parentInstance = instance.parent(); - if (!parentInstance.isValid()) - return; - - // If a Repeater instance was moved/removed, the old parent must be marked dirty to rerender it - const QByteArray type("QQuickRepeater"); - if (ServerNodeInstance::isSubclassOf(instance.internalObject(), type)) - DesignerSupport::addDirty(parentInstance.rootQuickItem(), QQuickDesignerSupport::Content); - - // Repeater's parent must also be dirtied when a child of a repeater was moved/removed. - if (ServerNodeInstance::isSubclassOf(parentInstance.internalObject(), type)) { - ServerNodeInstance parentsParent = parentInstance.parent(); - if (parentsParent.isValid()) - DesignerSupport::addDirty(parentsParent.rootQuickItem(), QQuickDesignerSupport::Content); - } -} - bool Qt5NodeInstanceServer::initRhi(RenderViewData &viewData) { #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) @@ -550,23 +523,8 @@ void Qt5NodeInstanceServer::clearScene(const ClearSceneCommand &command) void Qt5NodeInstanceServer::reparentInstances(const ReparentInstancesCommand &command) { - const QVector &containerVector = command.reparentInstances(); - for (const ReparentContainer &container : containerVector) - markRepeaterParentDirty(container.instanceId()); - NodeInstanceServer::reparentInstances(command.reparentInstances()); startRenderTimer(); } -void Qt5NodeInstanceServer::removeInstances(const RemoveInstancesCommand &command) -{ - const QVector &idVector = command.instanceIds(); - for (const qint32 id : idVector) - markRepeaterParentDirty(id); - - NodeInstanceServer::removeInstances(command); - startRenderTimer(); -} - - } // QmlDesigner diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5nodeinstanceserver.h b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5nodeinstanceserver.h index d93ecad84ed..4af451b61ae 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5nodeinstanceserver.h +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5nodeinstanceserver.h @@ -67,7 +67,6 @@ public: void createScene(const CreateSceneCommand &command) override; void clearScene(const ClearSceneCommand &command) override; void reparentInstances(const ReparentInstancesCommand &command) override; - void removeInstances(const RemoveInstancesCommand &command) override; QImage grabWindow() override; QImage grabItem(QQuickItem *item) override; @@ -80,7 +79,6 @@ protected: void resetAllItems(); void setupScene(const CreateSceneCommand &command) override; QList allItems() const; - void markRepeaterParentDirty(qint32 id) const; struct RenderViewData { QPointer window = nullptr; diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quickitemnodeinstance.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quickitemnodeinstance.cpp index 34693cc0bcf..403ba9fbe9a 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quickitemnodeinstance.cpp +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quickitemnodeinstance.cpp @@ -767,6 +767,8 @@ void QuickItemNodeInstance::reparent(const ObjectNodeInstance::Pointer &oldParen setMovable(true); } + markRepeaterParentDirty(); + ObjectNodeInstance::reparent(oldParentInstance, oldParentProperty, newParentInstance, newParentProperty); if (!newParentInstance) @@ -831,6 +833,8 @@ void QuickItemNodeInstance::setPropertyVariant(const PropertyName &name, const Q if (name == "layer.enabled" || name == "layer.effect") setAllNodesDirtyRecursive(quickItem()); + markRepeaterParentDirty(); + ObjectNodeInstance::setPropertyVariant(name, value); refresh(); @@ -850,6 +854,8 @@ void QuickItemNodeInstance::setPropertyBinding(const PropertyName &name, const Q if (name.startsWith("anchors.") && isRootNodeInstance()) return; + markRepeaterParentDirty(); + ObjectNodeInstance::setPropertyBinding(name, expression); refresh(); @@ -927,6 +933,8 @@ void QuickItemNodeInstance::resetProperty(const PropertyName &name) resetVertical(); } + markRepeaterParentDirty(); + ObjectNodeInstance::resetProperty(name); if (isInLayoutable()) @@ -1003,6 +1011,35 @@ QQuickItem *QuickItemNodeInstance::quickItem() const return static_cast(object()); } +void QuickItemNodeInstance::markRepeaterParentDirty() const +{ + const qint32 id = instanceId(); + if (id <= 0 && !isValid()) + return; + + QQuickItem *item = quickItem(); + if (!item) + return; + + QQuickItem *parentItem = item->parentItem(); + if (!parentItem) + return; + + // If a Repeater instance was changed in any way, the parent must be marked dirty to rerender it + const QByteArray type("QQuickRepeater"); + if (ServerNodeInstance::isSubclassOf(item, type)) + DesignerSupport::addDirty(parentItem, QQuickDesignerSupport::Content); + + // Repeater's parent must also be dirtied when a child of a repeater was changed + if (ServerNodeInstance::isSubclassOf(parentItem, type)) { + QQuickItem *parentsParent = parentItem->parentItem(); + if (parentsParent) + DesignerSupport::addDirty(parentsParent, QQuickDesignerSupport::Content); + } +} + + + } // namespace Internal } // namespace QmlDesigner diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quickitemnodeinstance.h b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quickitemnodeinstance.h index 77d3a3fc6b5..46b22b8c9a8 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quickitemnodeinstance.h +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quickitemnodeinstance.h @@ -130,6 +130,7 @@ protected: double x() const; double y() const; bool checkIfRefFromEffect(qint32 id); + void markRepeaterParentDirty() const; private: //variables QPointer m_contentItem;