diff options
author | Marco Bubke <marco.bubke@qt.io> | 2020-07-27 18:14:33 +0200 |
---|---|---|
committer | Marco Bubke <marco.bubke@qt.io> | 2020-08-10 12:53:30 +0000 |
commit | e43c7fdb1de786a2d5b90d68830c5308319a7dcf (patch) | |
tree | baffab654aebea5569ae3ff408d18eb793765980 /share/qtcreator/qml/qmlpuppet/qml2puppet/instances | |
parent | b5d59c75a7dee830483631cd9045d5338fc25c2d (diff) |
QmlDesigner: Split messaging and process for puppets
This will make it easier to implement custom puppets. The new connection
manager will restucture the code and it add a mechanism to capture data
too.
Task-number: QDS-2529
Change-Id: I5d15c3303ef1c9a3e25ba197d350e0d561ce813a
Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io>
Diffstat (limited to 'share/qtcreator/qml/qmlpuppet/qml2puppet/instances')
8 files changed, 229 insertions, 69 deletions
diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/instances.pri b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/instances.pri index 4fe46e29d83..ce9bb2376e7 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/instances.pri +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/instances.pri @@ -5,52 +5,54 @@ versionAtLeast(QT_VERSION, 5.15.0):qtHaveModule(quick3d) { DEFINES *= QUICK3D_MODULE } -HEADERS += $$PWD/qt5nodeinstanceserver.h -HEADERS += $$PWD/qt5testnodeinstanceserver.h -HEADERS += $$PWD/qt5informationnodeinstanceserver.h -HEADERS += $$PWD/qt5rendernodeinstanceserver.h -HEADERS += $$PWD/qt5previewnodeinstanceserver.h -HEADERS += $$PWD/qt5nodeinstanceclientproxy.h -HEADERS += $$PWD/quickitemnodeinstance.h -HEADERS += $$PWD/behaviornodeinstance.h -HEADERS += $$PWD/dummycontextobject.h -HEADERS += $$PWD/childrenchangeeventfilter.h -HEADERS += $$PWD/componentnodeinstance.h -HEADERS += $$PWD/dummynodeinstance.h -HEADERS += $$PWD/nodeinstanceserver.h -HEADERS += $$PWD/nodeinstancesignalspy.h -HEADERS += $$PWD/objectnodeinstance.h -HEADERS += $$PWD/qmlpropertychangesnodeinstance.h -HEADERS += $$PWD/qmlstatenodeinstance.h -HEADERS += $$PWD/qmltransitionnodeinstance.h -HEADERS += $$PWD/servernodeinstance.h -HEADERS += $$PWD/anchorchangesnodeinstance.h -HEADERS += $$PWD/positionernodeinstance.h -HEADERS += $$PWD/layoutnodeinstance.h -HEADERS += $$PWD/qt3dpresentationnodeinstance.h -HEADERS += $$PWD/quick3dnodeinstance.h +HEADERS += $$PWD/qt5nodeinstanceserver.h \ + $$PWD/qt5capturenodeinstanceserver.h \ + $$PWD/qt5testnodeinstanceserver.h \ + $$PWD/qt5informationnodeinstanceserver.h \ + $$PWD/qt5rendernodeinstanceserver.h \ + $$PWD/qt5previewnodeinstanceserver.h \ + $$PWD/qt5nodeinstanceclientproxy.h \ + $$PWD/quickitemnodeinstance.h \ + $$PWD/behaviornodeinstance.h \ + $$PWD/dummycontextobject.h \ + $$PWD/childrenchangeeventfilter.h \ + $$PWD/componentnodeinstance.h \ + $$PWD/dummynodeinstance.h \ + $$PWD/nodeinstanceserver.h \ + $$PWD/nodeinstancesignalspy.h \ + $$PWD/objectnodeinstance.h \ + $$PWD/qmlpropertychangesnodeinstance.h \ + $$PWD/qmlstatenodeinstance.h \ + $$PWD/qmltransitionnodeinstance.h \ + $$PWD/servernodeinstance.h \ + $$PWD/anchorchangesnodeinstance.h \ + $$PWD/positionernodeinstance.h \ + $$PWD/layoutnodeinstance.h \ + $$PWD/qt3dpresentationnodeinstance.h \ + $$PWD/quick3dnodeinstance.h -SOURCES += $$PWD/qt5nodeinstanceserver.cpp -SOURCES += $$PWD/qt5testnodeinstanceserver.cpp -SOURCES += $$PWD/qt5informationnodeinstanceserver.cpp -SOURCES += $$PWD/qt5rendernodeinstanceserver.cpp -SOURCES += $$PWD/qt5previewnodeinstanceserver.cpp -SOURCES += $$PWD/qt5nodeinstanceclientproxy.cpp -SOURCES += $$PWD/quickitemnodeinstance.cpp -SOURCES += $$PWD/behaviornodeinstance.cpp -SOURCES += $$PWD/dummycontextobject.cpp -SOURCES += $$PWD/childrenchangeeventfilter.cpp -SOURCES += $$PWD/componentnodeinstance.cpp -SOURCES += $$PWD/dummynodeinstance.cpp -SOURCES += $$PWD/nodeinstanceserver.cpp -SOURCES += $$PWD/nodeinstancesignalspy.cpp -SOURCES += $$PWD/objectnodeinstance.cpp -SOURCES += $$PWD/qmlpropertychangesnodeinstance.cpp -SOURCES += $$PWD/qmlstatenodeinstance.cpp -SOURCES += $$PWD/qmltransitionnodeinstance.cpp -SOURCES += $$PWD/servernodeinstance.cpp -SOURCES += $$PWD/anchorchangesnodeinstance.cpp -SOURCES += $$PWD/positionernodeinstance.cpp -SOURCES += $$PWD/layoutnodeinstance.cpp -SOURCES += $$PWD/qt3dpresentationnodeinstance.cpp -SOURCES += $$PWD/quick3dnodeinstance.cpp +SOURCES += $$PWD/qt5nodeinstanceserver.cpp \ + $$PWD/qt5capturenodeinstanceserver.cpp \ + $$PWD/qt5testnodeinstanceserver.cpp \ + $$PWD/qt5informationnodeinstanceserver.cpp \ + $$PWD/qt5rendernodeinstanceserver.cpp \ + $$PWD/qt5previewnodeinstanceserver.cpp \ + $$PWD/qt5nodeinstanceclientproxy.cpp \ + $$PWD/quickitemnodeinstance.cpp \ + $$PWD/behaviornodeinstance.cpp \ + $$PWD/dummycontextobject.cpp \ + $$PWD/childrenchangeeventfilter.cpp \ + $$PWD/componentnodeinstance.cpp \ + $$PWD/dummynodeinstance.cpp \ + $$PWD/nodeinstanceserver.cpp \ + $$PWD/nodeinstancesignalspy.cpp \ + $$PWD/objectnodeinstance.cpp \ + $$PWD/qmlpropertychangesnodeinstance.cpp \ + $$PWD/qmlstatenodeinstance.cpp \ + $$PWD/qmltransitionnodeinstance.cpp \ + $$PWD/servernodeinstance.cpp \ + $$PWD/anchorchangesnodeinstance.cpp \ + $$PWD/positionernodeinstance.cpp \ + $$PWD/layoutnodeinstance.cpp \ + $$PWD/qt3dpresentationnodeinstance.cpp \ + $$PWD/quick3dnodeinstance.cpp diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/nodeinstanceserver.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/nodeinstanceserver.cpp index 9b0b59d58bb..1abfc634bd2 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/nodeinstanceserver.cpp +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/nodeinstanceserver.cpp @@ -179,6 +179,8 @@ NodeInstanceServer::NodeInstanceServer(NodeInstanceClientInterface *nodeInstance m_childrenChangeEventFilter(new Internal::ChildrenChangeEventFilter(this)), m_nodeInstanceClient(nodeInstanceClient) { + m_idInstances.reserve(1000); + qmlRegisterType<DummyContextObject>("QmlDesigner", 1, 0, "DummyContextObject"); connect(m_childrenChangeEventFilter.data(), &Internal::ChildrenChangeEventFilter::childrenChanged, this, &NodeInstanceServer::emitParentChanged); @@ -226,8 +228,8 @@ ServerNodeInstance NodeInstanceServer::instanceForId(qint32 id) const if (id < 0) return ServerNodeInstance(); - Q_ASSERT(m_idInstanceHash.contains(id)); - return m_idInstanceHash.value(id); + Q_ASSERT(m_idInstances.size() > id); + return m_idInstances[id]; } bool NodeInstanceServer::hasInstanceForId(qint32 id) const @@ -235,7 +237,7 @@ bool NodeInstanceServer::hasInstanceForId(qint32 id) const if (id < 0) return false; - return m_idInstanceHash.contains(id) && m_idInstanceHash.value(id).isValid(); + return m_idInstances.size() > id && m_idInstances[id].isValid(); } ServerNodeInstance NodeInstanceServer::instanceForObject(QObject *object) const @@ -790,7 +792,7 @@ void NodeInstanceServer::removeAllInstanceRelationships() instance.makeInvalid(); } - m_idInstanceHash.clear(); + m_idInstances.clear(); m_objectInstanceHash.clear(); } @@ -1243,10 +1245,11 @@ void NodeInstanceServer::notifyPropertyChange(qint32 instanceid, const PropertyN void NodeInstanceServer::insertInstanceRelationship(const ServerNodeInstance &instance) { Q_ASSERT(instance.isValid()); - Q_ASSERT(!m_idInstanceHash.contains(instance.instanceId())); Q_ASSERT(!m_objectInstanceHash.contains(instance.internalObject())); m_objectInstanceHash.insert(instance.internalObject(), instance); - m_idInstanceHash.insert(instance.instanceId(), instance); + if (instance.instanceId() >= m_idInstances.size()) + m_idInstances.resize(instance.instanceId() + 1); + m_idInstances[instance.instanceId()] = instance; } void NodeInstanceServer::removeInstanceRelationsip(qint32 instanceId) @@ -1255,7 +1258,7 @@ void NodeInstanceServer::removeInstanceRelationsip(qint32 instanceId) ServerNodeInstance instance = instanceForId(instanceId); if (instance.isValid()) instance.setId(QString()); - m_idInstanceHash.remove(instanceId); + m_idInstances[instanceId] = ServerNodeInstance{}; m_objectInstanceHash.remove(instance.internalObject()); instance.makeInvalid(); } @@ -1383,8 +1386,8 @@ void NodeInstanceServer::removeInstanceRelationsipForDeletedObject(QObject *obje ServerNodeInstance instance = instanceForObject(object); m_objectInstanceHash.remove(object); - if (m_idInstanceHash.contains(instance.instanceId())) - m_idInstanceHash.remove(instance.instanceId()); + if (instance.instanceId() >= 0 && m_idInstances.size() > instance.instanceId()) + m_idInstances[instance.instanceId()] = ServerNodeInstance{}; } } diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/nodeinstanceserver.h b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/nodeinstanceserver.h index 87eb5a1b7e9..2c628f1411b 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/nodeinstanceserver.h +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/nodeinstanceserver.h @@ -160,6 +160,8 @@ public: ServerNodeInstance instanceForObject(QObject *object) const; bool hasInstanceForObject(QObject *object) const; + const QVector<ServerNodeInstance> &nodeInstances() const { return m_idInstances; } + virtual QQmlEngine *engine() const = 0; QQmlContext *context() const; @@ -272,7 +274,7 @@ private: void setupOnlyWorkingImports(const QStringList &workingImportStatementList); ServerNodeInstance m_rootNodeInstance; ServerNodeInstance m_activeStateInstance; - QHash<qint32, ServerNodeInstance> m_idInstanceHash; + QVector<ServerNodeInstance> m_idInstances; QHash<QObject*, ServerNodeInstance> m_objectInstanceHash; QMultiHash<QString, ObjectPropertyPair> m_fileSystemWatcherHash; QList<QPair<QString, QPointer<QObject> > > m_dummyObjectList; diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5capturenodeinstanceserver.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5capturenodeinstanceserver.cpp new file mode 100644 index 00000000000..aea75a76c7f --- /dev/null +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5capturenodeinstanceserver.cpp @@ -0,0 +1,105 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +#include "qt5capturenodeinstanceserver.h" +#include "servernodeinstance.h" + +#include <captureddatacommand.h> +#include <createscenecommand.h> +#include <nodeinstanceclientinterface.h> + +#include <QImage> +#include <QQuickView> + +namespace QmlDesigner { + +namespace { + +QImage renderPreviewImage(ServerNodeInstance rootNodeInstance) +{ + rootNodeInstance.updateDirtyNodeRecursive(); + + QSize previewImageSize = rootNodeInstance.boundingRect().size().toSize(); + + QImage previewImage = rootNodeInstance.renderPreviewImage(previewImageSize); + + return previewImage; +} + +CapturedDataCommand::StateData collectStateData(ServerNodeInstance rootNodeInstance, + const QVector<ServerNodeInstance> &nodeInstances, + qint32 stateInstanceId) +{ + CapturedDataCommand::StateData stateData; + stateData.image = ImageContainer(stateInstanceId, + QmlDesigner::renderPreviewImage(rootNodeInstance), + stateInstanceId); + + for (const ServerNodeInstance &instance : nodeInstances) { + auto textProperty = instance.property("text"); + if (!textProperty.isNull() && instance.holdsGraphical()) { + CapturedDataCommand::NodeData nodeData; + nodeData.nodeId = instance.instanceId(); + nodeData.contentRect = instance.contentItemBoundingRect(); + nodeData.sceneTransform = instance.sceneTransform(); + nodeData.text = textProperty.toString(); + stateData.nodeData.push_back(std::move(nodeData)); + } + } + + return stateData; +} +} // namespace + +void Qt5CaptureNodeInstanceServer::collectItemChangesAndSendChangeCommands() +{ + static bool inFunction = false; + + if (!rootNodeInstance().holdsGraphical()) + return; + + if (!inFunction) { + inFunction = true; + + DesignerSupport::polishItems(quickView()); + + QVector<CapturedDataCommand::StateData> stateDatas; + stateDatas.push_back(collectStateData(rootNodeInstance(), nodeInstances(), 0)); + + for (ServerNodeInstance stateInstance : rootNodeInstance().stateInstances()) { + stateInstance.activateState(); + stateDatas.push_back( + collectStateData(rootNodeInstance(), nodeInstances(), stateInstance.instanceId())); + stateInstance.deactivateState(); + } + + nodeInstanceClient()->capturedData(CapturedDataCommand{stateDatas}); + + slowDownRenderTimer(); + inFunction = false; + } +} + +} // namespace QmlDesigner diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5capturenodeinstanceserver.h b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5capturenodeinstanceserver.h new file mode 100644 index 00000000000..cd0208e5633 --- /dev/null +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5capturenodeinstanceserver.h @@ -0,0 +1,45 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +#pragma once + +#include <qt5previewnodeinstanceserver.h> + +namespace QmlDesigner { + +class Qt5CaptureNodeInstanceServer : public Qt5PreviewNodeInstanceServer +{ +public: + explicit Qt5CaptureNodeInstanceServer(NodeInstanceClientInterface *nodeInstanceClient) + : Qt5PreviewNodeInstanceServer(nodeInstanceClient) + {} + +protected: + void collectItemChangesAndSendChangeCommands() override; + +private: +}; + +} // namespace QmlDesigner diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5nodeinstanceclientproxy.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5nodeinstanceclientproxy.cpp index 449e4ff188f..1cdfc910742 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5nodeinstanceclientproxy.cpp +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5nodeinstanceclientproxy.cpp @@ -27,6 +27,7 @@ #include <QCoreApplication> +#include "qt5capturenodeinstanceserver.h" #include "qt5informationnodeinstanceserver.h" #include "qt5previewnodeinstanceserver.h" #include "qt5rendernodeinstanceserver.h" @@ -37,7 +38,7 @@ #if defined(Q_OS_UNIX) #include <unistd.h> #elif defined(Q_OS_WIN) -#include <windows.h> +#include <Windows.h> #endif namespace QmlDesigner { @@ -57,18 +58,21 @@ Qt5NodeInstanceClientProxy::Qt5NodeInstanceClientProxy(QObject *parent) : DesignerSupport::activateDesignerWindowManager(); if (QCoreApplication::arguments().at(1) == QLatin1String("--readcapturedstream")) { qputenv("DESIGNER_DONT_USE_SHARED_MEMORY", "1"); - setNodeInstanceServer(new Qt5TestNodeInstanceServer(this)); + setNodeInstanceServer(std::make_unique<Qt5TestNodeInstanceServer>(this)); initializeCapturedStream(QCoreApplication::arguments().at(2)); readDataStream(); QCoreApplication::exit(); } else if (QCoreApplication::arguments().at(2) == QLatin1String("previewmode")) { - setNodeInstanceServer(new Qt5PreviewNodeInstanceServer(this)); + setNodeInstanceServer(std::make_unique<Qt5PreviewNodeInstanceServer>(this)); initializeSocket(); } else if (QCoreApplication::arguments().at(2) == QLatin1String("editormode")) { - setNodeInstanceServer(new Qt5InformationNodeInstanceServer(this)); + setNodeInstanceServer(std::make_unique<Qt5InformationNodeInstanceServer>(this)); initializeSocket(); } else if (QCoreApplication::arguments().at(2) == QLatin1String("rendermode")) { - setNodeInstanceServer(new Qt5RenderNodeInstanceServer(this)); + setNodeInstanceServer(std::make_unique<Qt5RenderNodeInstanceServer>(this)); + initializeSocket(); + } else if (QCoreApplication::arguments().at(2) == QLatin1String("capturemode")) { + setNodeInstanceServer(std::make_unique<Qt5CaptureNodeInstanceServer>(this)); initializeSocket(); } } diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5previewnodeinstanceserver.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5previewnodeinstanceserver.cpp index 50db9b99719..452f2ddd2fc 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5previewnodeinstanceserver.cpp +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5previewnodeinstanceserver.cpp @@ -84,7 +84,8 @@ void Qt5PreviewNodeInstanceServer::collectItemChangesAndSendChangeCommands() instance.deactivateState(); } - nodeInstanceClient()->statePreviewImagesChanged(StatePreviewImageChangedCommand(imageContainerVector)); + nodeInstanceClient()->statePreviewImagesChanged( + StatePreviewImageChangedCommand(imageContainerVector)); slowDownRenderTimer(); inFunction = false; diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/servernodeinstance.h b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/servernodeinstance.h index ceb3b1e5b14..0881b738d94 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/servernodeinstance.h +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/servernodeinstance.h @@ -71,6 +71,7 @@ class ServerNodeInstance friend class Qt5InformationNodeInstanceServer; friend class Qt5NodeInstanceServer; friend class Qt5PreviewNodeInstanceServer; + friend class Qt5CaptureNodeInstanceServer; friend class Qt5TestNodeInstanceServer; friend class QHash<qint32, ServerNodeInstance>; friend uint qHash(const ServerNodeInstance &instance); @@ -169,6 +170,8 @@ public: static bool isSubclassOf(QObject *object, const QByteArray &superTypeName); void setModifiedFlag(bool b); + void updateDirtyNodeRecursive(); + bool holdsGraphical() const; private: // functions ServerNodeInstance(const QSharedPointer<Internal::ObjectNodeInstance> &abstractInstance); @@ -195,7 +198,6 @@ private: // functions void setDeleteHeldInstance(bool deleteInstance); void reparent(const ServerNodeInstance &oldParentInstance, const PropertyName &oldParentProperty, const ServerNodeInstance &newParentInstance, const PropertyName &newParentProperty); - void setId(const QString &id); static QSharedPointer<Internal::ObjectNodeInstance> createInstance(QObject *objectToBeWrapped); @@ -204,10 +206,6 @@ private: // functions void setNodeSource(const QString &source); - bool holdsGraphical() const; - - void updateDirtyNodeRecursive(); - QObject *internalObject() const; // should be not used outside of the nodeinstances!!!! private: // variables |