aboutsummaryrefslogtreecommitdiffstats
path: root/share/qtcreator/qml/qmlpuppet
diff options
context:
space:
mode:
authorEike Ziller <eike.ziller@qt.io>2021-10-08 16:00:32 +0200
committerEike Ziller <eike.ziller@qt.io>2021-10-08 16:00:32 +0200
commit2ae0d4d0b1548d2d1ab61582a946cf3766856ca5 (patch)
tree98f0a7678810a5d06056743b9b965ae69a4f9b68 /share/qtcreator/qml/qmlpuppet
parent9cb0bd94f0473077269078cc0da34d5e1fb600a0 (diff)
parent7bb21fcfff2b0fe6c6248ff85cdafae452ef7c8c (diff)
Merge remote-tracking branch 'origin/6.0'
Diffstat (limited to 'share/qtcreator/qml/qmlpuppet')
-rw-r--r--share/qtcreator/qml/qmlpuppet/qml2puppet/instances/nodeinstanceserver.cpp26
-rw-r--r--share/qtcreator/qml/qmlpuppet/qml2puppet/instances/objectnodeinstance.cpp14
-rw-r--r--share/qtcreator/qml/qmlpuppet/qml2puppet/instances/objectnodeinstance.h4
-rw-r--r--share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5nodeinstanceserver.cpp41
-rw-r--r--share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5nodeinstanceserver.h2
-rw-r--r--share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5previewnodeinstanceserver.cpp4
-rw-r--r--share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quickitemnodeinstance.cpp3
-rw-r--r--share/qtcreator/qml/qmlpuppet/qml2puppet/instances/servernodeinstance.cpp7
-rw-r--r--share/qtcreator/qml/qmlpuppet/qml2puppet/instances/servernodeinstance.h2
9 files changed, 99 insertions, 4 deletions
diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/nodeinstanceserver.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/nodeinstanceserver.cpp
index 1fda59c964..bb80c2e2e1 100644
--- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/nodeinstanceserver.cpp
+++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/nodeinstanceserver.cpp
@@ -397,8 +397,19 @@ void NodeInstanceServer::reparentInstances(const QVector<ReparentContainer> &con
if (hasInstanceForId(container.instanceId())) {
ServerNodeInstance instance = instanceForId(container.instanceId());
if (instance.isValid()) {
- instance.reparent(instanceForId(container.oldParentInstanceId()), container.oldParentProperty(),
- instanceForId(container.newParentInstanceId()), container.newParentProperty());
+ ServerNodeInstance newParent = instanceForId(container.newParentInstanceId());
+ PropertyName newParentProperty = container.newParentProperty();
+ if (!isInformationServer()) {
+ // Children of the component wraps are left out of the node tree to avoid
+ // incorrectly rendering them
+ if (newParent.isComponentWrap()) {
+ newParent = {};
+ newParentProperty.clear();
+ }
+ }
+ instance.reparent(instanceForId(container.oldParentInstanceId()),
+ container.oldParentProperty(),
+ newParent, newParentProperty);
}
}
}
@@ -1287,8 +1298,15 @@ PixmapChangedCommand NodeInstanceServer::createPixmapChangedCommand(const QList<
QVector<ImageContainer> imageVector;
for (const ServerNodeInstance &instance : instanceList) {
- if (instance.isValid() && instance.hasContent())
- imageVector.append(ImageContainer(instance.instanceId(), instance.renderImage(), instance.instanceId()));
+ if (!instance.isValid())
+ continue;
+
+ QImage renderImage;
+ // We need to return empty image if instance has no content to correctly update the
+ // item image in case the instance changed from having content to not having content.
+ if (instance.hasContent())
+ renderImage = instance.renderImage();
+ imageVector.append(ImageContainer(instance.instanceId(), renderImage, instance.instanceId()));
}
return PixmapChangedCommand(imageVector);
diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/objectnodeinstance.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/objectnodeinstance.cpp
index ab764a98b3..4eb8cdd65f 100644
--- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/objectnodeinstance.cpp
+++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/objectnodeinstance.cpp
@@ -415,6 +415,16 @@ bool ObjectNodeInstance::isLockedInEditor() const
return m_isLockedInEditor;
}
+bool ObjectNodeInstance::isComponentWrap() const
+{
+ return m_isComponentWrap;
+}
+
+void ObjectNodeInstance::setComponentWrap(bool wrap)
+{
+ m_isComponentWrap = wrap;
+}
+
void ObjectNodeInstance::setModifiedFlag(bool b)
{
m_isModified = b;
@@ -732,6 +742,10 @@ QObject *ObjectNodeInstance::createComponentWrap(const QString &nodeSource, cons
QQmlComponent *component = new QQmlComponent(context->engine());
QByteArray data(nodeSource.toUtf8());
+ if (data.isEmpty()) {
+ // Add a fake root element as an empty component is not valid and crashes in some cases
+ data.append("QtObject{}");
+ }
data.prepend(importCode);
component->setData(data, context->baseUrl().resolved(QUrl("createComponent.qml")));
QObject *object = component;
diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/objectnodeinstance.h b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/objectnodeinstance.h
index c66365d392..67e1663496 100644
--- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/objectnodeinstance.h
+++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/objectnodeinstance.h
@@ -202,6 +202,9 @@ public:
virtual void setLockedInEditor(bool b);
bool isLockedInEditor() const;
+ bool isComponentWrap() const;
+ void setComponentWrap(bool wrap);
+
void setModifiedFlag(bool b);
protected:
@@ -234,6 +237,7 @@ private:
bool m_isModified = false;
bool m_isLockedInEditor = false;
bool m_isHiddenInEditor = false;
+ bool m_isComponentWrap = false;
static QHash<EnumerationName, QVariant> m_enumationValueHash;
};
diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5nodeinstanceserver.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5nodeinstanceserver.cpp
index 89e8c5d2db..2e1e03fa63 100644
--- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5nodeinstanceserver.cpp
+++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5nodeinstanceserver.cpp
@@ -37,6 +37,7 @@
#include <addimportcontainer.h>
#include <createscenecommand.h>
#include <reparentinstancescommand.h>
+#include <removeinstancescommand.h>
#include <clearscenecommand.h>
#include <QDebug>
@@ -193,6 +194,32 @@ QList<QQuickItem*> Qt5NodeInstanceServer::allItems() const
return QList<QQuickItem*>();
}
+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)
@@ -523,9 +550,23 @@ void Qt5NodeInstanceServer::clearScene(const ClearSceneCommand &command)
void Qt5NodeInstanceServer::reparentInstances(const ReparentInstancesCommand &command)
{
+ const QVector<ReparentContainer> &containerVector = command.reparentInstances();
+ for (const ReparentContainer &container : containerVector)
+ markRepeaterParentDirty(container.instanceId());
+
NodeInstanceServer::reparentInstances(command.reparentInstances());
startRenderTimer();
}
+void Qt5NodeInstanceServer::removeInstances(const RemoveInstancesCommand &command)
+{
+ const QVector<qint32> &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 4af451b61a..d93ecad84e 100644
--- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5nodeinstanceserver.h
+++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5nodeinstanceserver.h
@@ -67,6 +67,7 @@ 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;
@@ -79,6 +80,7 @@ protected:
void resetAllItems();
void setupScene(const CreateSceneCommand &command) override;
QList<QQuickItem*> allItems() const;
+ void markRepeaterParentDirty(qint32 id) const;
struct RenderViewData {
QPointer<QQuickWindow> window = nullptr;
diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5previewnodeinstanceserver.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5previewnodeinstanceserver.cpp
index daa1cab473..fb3113bdcd 100644
--- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5previewnodeinstanceserver.cpp
+++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5previewnodeinstanceserver.cpp
@@ -101,6 +101,10 @@ void Qt5PreviewNodeInstanceServer::changeState(const ChangeStateCommand &/*comma
QImage Qt5PreviewNodeInstanceServer::renderPreviewImage()
{
+ // Ensure the state preview image is always clipped properly to root item dimensions
+ if (auto rootItem = qobject_cast<QQuickItem *>(rootNodeInstance().internalObject()))
+ rootItem->setClip(true);
+
rootNodeInstance().updateDirtyNodeRecursive();
QRectF boundingRect = rootNodeInstance().boundingRect();
diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quickitemnodeinstance.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quickitemnodeinstance.cpp
index 2046a2039e..1dae931af3 100644
--- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quickitemnodeinstance.cpp
+++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quickitemnodeinstance.cpp
@@ -779,6 +779,9 @@ void QuickItemNodeInstance::reparent(const ObjectNodeInstance::Pointer &oldParen
ObjectNodeInstance::reparent(oldParentInstance, oldParentProperty, newParentInstance, newParentProperty);
+ if (!newParentInstance)
+ quickItem()->setParentItem(nullptr);
+
if (instanceIsValidLayoutable(newParentInstance, newParentProperty)) {
setInLayoutable(true);
setMovable(false);
diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/servernodeinstance.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/servernodeinstance.cpp
index be4c3ea626..2aa17d9e2b 100644
--- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/servernodeinstance.cpp
+++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/servernodeinstance.cpp
@@ -150,6 +150,11 @@ bool ServerNodeInstance::holdsGraphical() const
return m_nodeInstance->isQuickItem();
}
+bool ServerNodeInstance::isComponentWrap() const
+{
+ return m_nodeInstance->isComponentWrap();
+}
+
void ServerNodeInstance::updateDirtyNodeRecursive()
{
m_nodeInstance->updateAllDirtyNodesRecursive();
@@ -280,6 +285,8 @@ ServerNodeInstance ServerNodeInstance::create(NodeInstanceServer *nodeInstanceSe
instance.internalInstance()->setInstanceId(instanceContainer.instanceId());
+ instance.internalInstance()->setComponentWrap(componentWrap == WrapAsComponent);
+
instance.internalInstance()->initialize(instance.m_nodeInstance, instanceContainer.metaFlags());
// Handle hidden state to initialize pickable state
diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/servernodeinstance.h b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/servernodeinstance.h
index 786a09fd47..52ead77e12 100644
--- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/servernodeinstance.h
+++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/servernodeinstance.h
@@ -178,6 +178,8 @@ public:
void updateDirtyNodeRecursive();
bool holdsGraphical() const;
+ bool isComponentWrap() const;
+
private: // functions
ServerNodeInstance(const QSharedPointer<Internal::ObjectNodeInstance> &abstractInstance);