diff options
author | Eike Ziller <eike.ziller@qt.io> | 2020-10-19 15:22:37 +0200 |
---|---|---|
committer | Eike Ziller <eike.ziller@qt.io> | 2020-10-19 15:22:37 +0200 |
commit | 80951d3e59f8b6ff270333692adfe2d65adf6c9c (patch) | |
tree | 8a5da6c06f7558d847e24dac386bb60775bd7d76 /share/qtcreator/qml/qmlpuppet/qml2puppet/instances | |
parent | af0e135e7328d5672e54d08ba35765308e554f23 (diff) | |
parent | 436f111a4609462fcaae501b3d6d9b072adbb0b0 (diff) |
Merge remote-tracking branch 'origin/4.14' into master
Conflicts:
src/plugins/cppeditor/cppquickfix_test.cpp
Change-Id: Ib2984a3b3d9d071d11304b6cf132c2f8cef77e1c
Diffstat (limited to 'share/qtcreator/qml/qmlpuppet/qml2puppet/instances')
17 files changed, 329 insertions, 29 deletions
diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/instances.pri b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/instances.pri index 85de00c5ff..448a67c913 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/instances.pri +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/instances.pri @@ -9,6 +9,7 @@ HEADERS += $$PWD/qt5nodeinstanceserver.h \ $$PWD/capturenodeinstanceserverdispatcher.h \ $$PWD/capturescenecreatedcommand.h \ $$PWD/nodeinstanceserverdispatcher.h \ + $$PWD/qt5captureimagenodeinstanceserver.h \ $$PWD/qt5capturepreviewnodeinstanceserver.h \ $$PWD/qt5testnodeinstanceserver.h \ $$PWD/qt5informationnodeinstanceserver.h \ @@ -33,11 +34,13 @@ HEADERS += $$PWD/qt5nodeinstanceserver.h \ $$PWD/layoutnodeinstance.h \ $$PWD/qt3dpresentationnodeinstance.h \ $$PWD/quick3dnodeinstance.h \ - $$PWD/quick3dtexturenodeinstance.h + $$PWD/quick3dtexturenodeinstance.h \ + SOURCES += $$PWD/qt5nodeinstanceserver.cpp \ $$PWD/capturenodeinstanceserverdispatcher.cpp \ $$PWD/nodeinstanceserverdispatcher.cpp \ + $$PWD/qt5captureimagenodeinstanceserver.cpp \ $$PWD/qt5capturepreviewnodeinstanceserver.cpp \ $$PWD/qt5testnodeinstanceserver.cpp \ $$PWD/qt5informationnodeinstanceserver.cpp \ diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/nodeinstanceserver.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/nodeinstanceserver.cpp index 45d5fce845..183f036bf7 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/nodeinstanceserver.cpp +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/nodeinstanceserver.cpp @@ -72,22 +72,23 @@ #include <requestmodelnodepreviewimagecommand.h> #include <changelanguagecommand.h> +#include <designersupportdelegate.h> +#include <QAbstractAnimation> #include <QDebug> -#include <QQmlEngine> -#include <QQmlApplicationEngine> -#include <QFileSystemWatcher> -#include <QUrl> -#include <QSet> #include <QDir> -#include <QVariant> +#include <QFileSystemWatcher> #include <QMetaType> +#include <QMutableVectorIterator> +#include <QQmlApplicationEngine> #include <QQmlComponent> #include <QQmlContext> -#include <qqmllist.h> -#include <QAbstractAnimation> +#include <QQmlEngine> +#include <QQuickItemGrabResult> #include <QQuickView> #include <QSet> -#include <designersupportdelegate.h> +#include <QUrl> +#include <QVariant> +#include <qqmllist.h> #include <algorithm> @@ -1461,4 +1462,19 @@ void NodeInstanceServer::disableTimer() m_timerMode = TimerMode::DisableTimer; } +void NodeInstanceServer::sheduleRootItemRender() +{ + QSharedPointer<QQuickItemGrabResult> result = m_rootNodeInstance.createGrabResult(); + qint32 instanceId = m_rootNodeInstance.instanceId(); + + if (result) { + connect(result.data(), &QQuickItemGrabResult::ready, [this, result, instanceId] { + QVector<ImageContainer> imageVector; + ImageContainer container(instanceId, result->image(), instanceId); + imageVector.append(container); + nodeInstanceClient()->pixmapChanged(PixmapChangedCommand(imageVector)); + }); + } +} + } // namespace QmlDesigner diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/nodeinstanceserver.h b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/nodeinstanceserver.h index bd6349d29a..d5726a31f6 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/nodeinstanceserver.h +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/nodeinstanceserver.h @@ -241,6 +241,8 @@ protected: ComponentCompletedCommand createComponentCompletedCommand(const QList<ServerNodeInstance> &instanceList); ChangeSelectionCommand createChangeSelectionCommand(const QList<ServerNodeInstance> &instanceList); + void sheduleRootItemRender(); + void addChangedProperty(const InstancePropertyPair &property); virtual void startRenderTimer(); diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/nodeinstanceserverdispatcher.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/nodeinstanceserverdispatcher.cpp index dd9c42c5bd..eb5aae6a7e 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/nodeinstanceserverdispatcher.cpp +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/nodeinstanceserverdispatcher.cpp @@ -25,6 +25,7 @@ #include "nodeinstanceserverdispatcher.h" +#include "qt5captureimagenodeinstanceserver.h" #include "qt5capturepreviewnodeinstanceserver.h" #include "qt5informationnodeinstanceserver.h" #include "qt5rendernodeinstanceserver.h" @@ -183,6 +184,8 @@ std::unique_ptr<NodeInstanceServer> createNodeInstanceServer( { if (serverName == "capturemode") return std::make_unique<Qt5CapturePreviewNodeInstanceServer>(nodeInstanceClient); + else if (serverName == "captureiconmode") + return std::make_unique<Qt5CaptureImageNodeInstanceServer>(nodeInstanceClient); else if (serverName == "rendermode") return std::make_unique<Qt5RenderNodeInstanceServer>(nodeInstanceClient); else if (serverName == "editormode") diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/objectnodeinstance.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/objectnodeinstance.cpp index 5991e2b28e..d69846d400 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/objectnodeinstance.cpp +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/objectnodeinstance.cpp @@ -908,6 +908,11 @@ QImage ObjectNodeInstance::renderPreviewImage(const QSize & /*previewImageSize*/ return QImage(); } +QSharedPointer<QQuickItemGrabResult> ObjectNodeInstance::createGrabResult() const +{ + return {}; +} + QObject *ObjectNodeInstance::parent() const { if (!object()) diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/objectnodeinstance.h b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/objectnodeinstance.h index 3026ffefce..29e7dc640b 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/objectnodeinstance.h +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/objectnodeinstance.h @@ -84,6 +84,8 @@ public: virtual QImage renderImage() const; virtual QImage renderPreviewImage(const QSize &previewImageSize) const; + virtual QSharedPointer<QQuickItemGrabResult> createGrabResult() const; + virtual QObject *parent() const; Pointer parentInstance() const; diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5captureimagenodeinstanceserver.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5captureimagenodeinstanceserver.cpp new file mode 100644 index 0000000000..d24c4e5552 --- /dev/null +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5captureimagenodeinstanceserver.cpp @@ -0,0 +1,84 @@ +/**************************************************************************** +** +** 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 "qt5captureimagenodeinstanceserver.h" +#include "servernodeinstance.h" + +#include <captureddatacommand.h> +#include <createscenecommand.h> +#include <nodeinstanceclientinterface.h> + +#include <QImage> +#include <QQuickItem> +#include <QQuickView> + +namespace QmlDesigner { + +namespace { + +QImage renderImage(ServerNodeInstance rootNodeInstance) +{ + rootNodeInstance.updateDirtyNodeRecursive(); + + QSize previewImageSize = rootNodeInstance.boundingRect().size().toSize(); + if (previewImageSize.isEmpty()) + previewImageSize = {640, 480}; + + if (previewImageSize.width() > 800 || previewImageSize.height() > 800) + previewImageSize.scale({800, 800}, Qt::KeepAspectRatio); + + QImage previewImage = rootNodeInstance.renderPreviewImage(previewImageSize); + + return previewImage; +} +} // namespace + +void Qt5CaptureImageNodeInstanceServer::collectItemChangesAndSendChangeCommands() +{ + static bool inFunction = false; + + if (!rootNodeInstance().holdsGraphical()) { + nodeInstanceClient()->capturedData(CapturedDataCommand{}); + return; + } + + if (!inFunction) { + inFunction = true; + + auto rooNodeInstance = rootNodeInstance(); + rooNodeInstance.rootQuickItem()->setClip(true); + + DesignerSupport::polishItems(quickView()); + + QImage image = renderImage(rooNodeInstance); + + nodeInstanceClient()->capturedData(CapturedDataCommand{std::move(image)}); + + slowDownRenderTimer(); + inFunction = false; + } +} + +} // namespace diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5captureimagenodeinstanceserver.h b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5captureimagenodeinstanceserver.h new file mode 100644 index 0000000000..7c26e47a87 --- /dev/null +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5captureimagenodeinstanceserver.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 Qt5CaptureImageNodeInstanceServer : public Qt5PreviewNodeInstanceServer +{ +public: + explicit Qt5CaptureImageNodeInstanceServer(NodeInstanceClientInterface *nodeInstanceClient) + : Qt5PreviewNodeInstanceServer(nodeInstanceClient) + {} + +protected: + void collectItemChangesAndSendChangeCommands() override; + +private: +}; + +} // namespace QmlDesigner diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5capturepreviewnodeinstanceserver.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5capturepreviewnodeinstanceserver.cpp index c70ef76afe..7fb87defb0 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5capturepreviewnodeinstanceserver.cpp +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5capturepreviewnodeinstanceserver.cpp @@ -100,7 +100,7 @@ void Qt5CapturePreviewNodeInstanceServer::collectItemChangesAndSendChangeCommand stateInstance.deactivateState(); } - nodeInstanceClient()->capturedData(CapturedDataCommand{stateDatas}); + nodeInstanceClient()->capturedData(CapturedDataCommand{std::move(stateDatas)}); slowDownRenderTimer(); inFunction = false; diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5informationnodeinstanceserver.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5informationnodeinstanceserver.cpp index 2963119def..ecd066d16c 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5informationnodeinstanceserver.cpp +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5informationnodeinstanceserver.cpp @@ -101,6 +101,30 @@ static QVariant objectToVariant(QObject *object) return QVariant::fromValue(object); } +static QImage nonVisualComponentPreviewImage() +{ + static double ratio = qgetenv("FORMEDITOR_DEVICE_PIXEL_RATIO").toDouble(); + if (ratio == 1.) { + static const QImage image(":/qtquickplugin/images/non-visual-component.png"); + return image; + } else { + static const QImage image(":/qtquickplugin/images/non-visual-component@2x.png"); + return image; + } +} + +static bool imageHasContent(const QImage &image) +{ + // Check if any image pixel contains non-zero data + const uchar *pData = image.constBits(); + const qsizetype size = image.sizeInBytes(); + for (qsizetype i = 0; i < size; ++i) { + if (*(pData++) != 0) + return true; + } + return false; +} + QQuickView *Qt5InformationNodeInstanceServer::createAuxiliaryQuickView(const QUrl &url, QQuickItem *&rootItem) { @@ -556,7 +580,7 @@ void Qt5InformationNodeInstanceServer::doRenderModelNode3DImageView() ServerNodeInstance instance = instanceForId(m_modelNodePreviewImageCommand.instanceId()); instanceObj = instance.internalObject(); } - QSize renderSize = m_modelNodePreviewImageCommand.size() * 2; + QSize renderSize = m_modelNodePreviewImageCommand.size(); QMetaObject::invokeMethod(m_ModelNode3DImageViewRootItem, "createViewForObject", Q_ARG(QVariant, objectToVariant(instanceObj)), @@ -652,7 +676,7 @@ void Qt5InformationNodeInstanceServer::doRenderModelNode2DImageView() // Some component may expect to always be shown at certain size, so their layouts may // not support scaling, so let's always render at the default size if item has one and // scale the resulting image instead. - QSize finalSize = m_modelNodePreviewImageCommand.size() * 2; + QSize finalSize = m_modelNodePreviewImageCommand.size(); QRectF renderRect = itemBoundingRect(instanceItem); QSize renderSize = renderRect.size().toSize(); if (renderSize.isEmpty()) { @@ -665,6 +689,9 @@ void Qt5InformationNodeInstanceServer::doRenderModelNode2DImageView() renderImage = designerSupport()->renderImageForItem(m_ModelNode2DImageViewContentItem, renderRect, renderSize); + if (!imageHasContent(renderImage)) + renderImage = nonVisualComponentPreviewImage(); + if (renderSize != finalSize) renderImage = renderImage.scaled(finalSize, Qt::KeepAspectRatio); diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5nodeinstanceclientproxy.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5nodeinstanceclientproxy.cpp index defbf5614a..93e6e786cd 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5nodeinstanceclientproxy.cpp +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5nodeinstanceclientproxy.cpp @@ -28,11 +28,13 @@ #include <QCoreApplication> #include "capturenodeinstanceserverdispatcher.h" +#include "qt5captureimagenodeinstanceserver.h" #include "qt5capturepreviewnodeinstanceserver.h" #include "qt5informationnodeinstanceserver.h" #include "qt5previewnodeinstanceserver.h" #include "qt5rendernodeinstanceserver.h" #include "qt5testnodeinstanceserver.h" +#include "quickitemnodeinstance.h" #include <designersupportdelegate.h> @@ -56,7 +58,19 @@ Qt5NodeInstanceClientProxy::Qt5NodeInstanceClientProxy(QObject *parent) : NodeInstanceClientProxy(parent) { prioritizeDown(); - DesignerSupport::activateDesignerWindowManager(); +#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) + const bool qt6 = false; +#else + const bool qt6 = true; +#endif + + const bool unifiedRenderPath = qt6 || qEnvironmentVariableIsSet("QMLPUPPET_UNIFIED_RENDER_PATH"); + + if (unifiedRenderPath) + Internal::QuickItemNodeInstance::enableUnifiedRenderPath(true); + else + DesignerSupport::activateDesignerWindowManager(); + if (QCoreApplication::arguments().at(1) == QLatin1String("--readcapturedstream")) { qputenv("DESIGNER_DONT_USE_SHARED_MEMORY", "1"); setNodeInstanceServer(std::make_unique<Qt5TestNodeInstanceServer>(this)); @@ -79,6 +93,9 @@ Qt5NodeInstanceClientProxy::Qt5NodeInstanceClientProxy(QObject *parent) : } else if (QCoreApplication::arguments().at(2) == QLatin1String("capturemode")) { setNodeInstanceServer(std::make_unique<Qt5CapturePreviewNodeInstanceServer>(this)); initializeSocket(); + } else if (QCoreApplication::arguments().at(2) == QLatin1String("captureiconmode")) { + setNodeInstanceServer(std::make_unique<Qt5CaptureImageNodeInstanceServer>(this)); + initializeSocket(); } } diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5nodeinstanceserver.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5nodeinstanceserver.cpp index 8a4b086aa5..c2015299c5 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5nodeinstanceserver.cpp +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5nodeinstanceserver.cpp @@ -64,6 +64,8 @@ void Qt5NodeInstanceServer::initializeView() m_quickView = new QQuickView; +#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) + /* enables grab window without show */ QSurfaceFormat surfaceFormat = m_quickView->requestedFormat(); surfaceFormat.setVersion(4, 1); surfaceFormat.setProfile(QSurfaceFormat::CoreProfile); @@ -72,6 +74,7 @@ void Qt5NodeInstanceServer::initializeView() m_quickView->setFormat(surfaceFormat); DesignerSupport::createOpenGLContext(m_quickView.data()); +#endif if (qEnvironmentVariableIsSet("QML_FILE_SELECTORS")) { QQmlFileSelector *fileSelector = new QQmlFileSelector(engine(), engine()); diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5rendernodeinstanceserver.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5rendernodeinstanceserver.cpp index 08b20ccd22..fd3446f396 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5rendernodeinstanceserver.cpp +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5rendernodeinstanceserver.cpp @@ -87,17 +87,27 @@ void Qt5RenderNodeInstanceServer::collectItemChangesAndSendChangeCommands() if (ancestorInstance.isValid()) m_dirtyInstanceSet.insert(ancestorInstance); } - DesignerSupport::updateDirtyNode(item); + Internal::QuickItemNodeInstance::updateDirtyNode(item); } } clearChangedPropertyList(); - if (!m_dirtyInstanceSet.isEmpty()) { - nodeInstanceClient()->pixmapChanged(createPixmapChangedCommand(QtHelpers::toList(m_dirtyInstanceSet))); - m_dirtyInstanceSet.clear(); + if (Internal::QuickItemNodeInstance::unifiedRenderPath()) { + /* QQuickItem::grabToImage render path */ + /* TODO implement QQuickItem::grabToImage based rendering */ + /* sheduleRootItemRender(); */ + nodeInstanceClient()->pixmapChanged(createPixmapChangedCommand({rootNodeInstance()})); + } else { + if (!m_dirtyInstanceSet.isEmpty()) { + nodeInstanceClient()->pixmapChanged( + createPixmapChangedCommand(QtHelpers::toList(m_dirtyInstanceSet))); + m_dirtyInstanceSet.clear(); + } } + m_dirtyInstanceSet.clear(); + resetAllItems(); slowDownRenderTimer(); @@ -137,6 +147,11 @@ void Qt5RenderNodeInstanceServer::createScene(const CreateSceneCommand &command) } nodeInstanceClient()->pixmapChanged(createPixmapChangedCommand(instanceList)); + +#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) +#else + quickView()->show(); +#endif } void Qt5RenderNodeInstanceServer::clearScene(const ClearSceneCommand &command) diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quickitemnodeinstance.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quickitemnodeinstance.cpp index 6e67d58b92..1f54bffdbd 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quickitemnodeinstance.cpp +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quickitemnodeinstance.cpp @@ -41,6 +41,7 @@ namespace QmlDesigner { namespace Internal { bool QuickItemNodeInstance::s_createEffectItem = false; +bool QuickItemNodeInstance::s_unifiedRenderPath = false; QuickItemNodeInstance::QuickItemNodeInstance(QQuickItem *item) : ObjectNodeInstance(item), @@ -58,7 +59,7 @@ QuickItemNodeInstance::QuickItemNodeInstance(QQuickItem *item) QuickItemNodeInstance::~QuickItemNodeInstance() { - if (quickItem()) + if (quickItem() && checkIfRefFromEffect(instanceId())) designerSupport()->derefFromEffectItem(quickItem()); } @@ -156,6 +157,19 @@ void QuickItemNodeInstance::createEffectItem(bool createEffectItem) s_createEffectItem = createEffectItem; } +void QuickItemNodeInstance::enableUnifiedRenderPath(bool unifiedRenderPath) +{ + s_unifiedRenderPath = unifiedRenderPath; +} + +bool QuickItemNodeInstance::checkIfRefFromEffect(qint32 id) +{ + if (s_unifiedRenderPath) + return false; + + return (s_createEffectItem || id == 0); +} + void QuickItemNodeInstance::initialize(const ObjectNodeInstance::Pointer &objectNodeInstance, InstanceContainer::NodeFlags flags) { @@ -166,10 +180,10 @@ void QuickItemNodeInstance::initialize(const ObjectNodeInstance::Pointer &object quickItem()->setParentItem(qobject_cast<QQuickItem*>(nodeInstanceServer()->quickView()->rootObject())); } - if (quickItem()->window()) { - if (s_createEffectItem || instanceId() == 0) - designerSupport()->refFromEffectItem(quickItem(), - !flags.testFlag(InstanceContainer::ParentTakesOverRendering)); + if (quickItem()->window() && checkIfRefFromEffect(instanceId())) { + designerSupport()->refFromEffectItem(quickItem(), + !flags.testFlag( + InstanceContainer::ParentTakesOverRendering)); } ObjectNodeInstance::initialize(objectNodeInstance, flags); @@ -246,6 +260,20 @@ QStringList QuickItemNodeInstance::allStates() const return list; } +void QuickItemNodeInstance::updateDirtyNode(QQuickItem *item) +{ + if (s_unifiedRenderPath) { + item->update(); + return; + } + DesignerSupport::updateDirtyNode(item); +} + +bool QuickItemNodeInstance::unifiedRenderPath() +{ + return s_unifiedRenderPath; +} + QRectF QuickItemNodeInstance::contentItemBoundingBox() const { if (contentItem()) { @@ -378,6 +406,9 @@ double QuickItemNodeInstance::y() const QImage QuickItemNodeInstance::renderImage() const { + if (s_unifiedRenderPath && !isRootNodeInstance()) + return {}; + updateDirtyNodesRecursive(quickItem()); QRectF renderBoundingRect = boundingRect(); @@ -390,7 +421,16 @@ QImage QuickItemNodeInstance::renderImage() const nodeInstanceServer()->quickView()->beforeSynchronizing(); nodeInstanceServer()->quickView()->beforeRendering(); - QImage renderImage = designerSupport()->renderImageForItem(quickItem(), renderBoundingRect, size); + QImage renderImage; + +#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) + if (s_unifiedRenderPath) + renderImage = nodeInstanceServer()->quickView()->grabWindow(); + else + renderImage = designerSupport()->renderImageForItem(quickItem(), renderBoundingRect, size); +#else + renderImage = nodeInstanceServer()->quickView()->grabWindow(); +#endif nodeInstanceServer()->quickView()->afterRendering(); @@ -411,7 +451,20 @@ QImage QuickItemNodeInstance::renderPreviewImage(const QSize &previewImageSize) nodeInstanceServer()->quickView()->beforeSynchronizing(); nodeInstanceServer()->quickView()->beforeRendering(); - QImage image = designerSupport()->renderImageForItem(quickItem(), previewItemBoundingRect, size); + QImage image; +#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) + if (s_unifiedRenderPath) + image = nodeInstanceServer()->quickView()->grabWindow(); + else + image = designerSupport()->renderImageForItem(quickItem(), + previewItemBoundingRect, + size); + +#else + image = nodeInstanceServer()->quickView()->grabWindow(); +#endif + + image = image.scaledToWidth(size.width()); nodeInstanceServer()->quickView()->afterRendering(); @@ -426,6 +479,11 @@ QImage QuickItemNodeInstance::renderPreviewImage(const QSize &previewImageSize) return QImage(); } +QSharedPointer<QQuickItemGrabResult> QuickItemNodeInstance::createGrabResult() const +{ + return quickItem()->grabToImage(size().toSize()); +} + void QuickItemNodeInstance::updateAllDirtyNodesRecursive() { updateAllDirtyNodesRecursive(quickItem()); @@ -490,10 +548,11 @@ void QuickItemNodeInstance::updateDirtyNodesRecursive(QQuickItem *parentItem) co void QuickItemNodeInstance::updateAllDirtyNodesRecursive(QQuickItem *parentItem) const { - foreach (QQuickItem *childItem, parentItem->childItems()) - updateAllDirtyNodesRecursive(childItem); + const QList<QQuickItem *> children = parentItem->childItems(); + for (QQuickItem *childItem : children) + updateAllDirtyNodesRecursive(childItem); - DesignerSupport::updateDirtyNode(parentItem); + updateDirtyNode(parentItem); } static inline bool isRectangleSane(const QRectF &rect) @@ -507,7 +566,7 @@ QRectF QuickItemNodeInstance::boundingRectWithStepChilds(QQuickItem *parentItem) boundingRect = boundingRect.united(QRectF(QPointF(0, 0), size())); - foreach (QQuickItem *childItem, parentItem->childItems()) { + for (QQuickItem *childItem : parentItem->childItems()) { if (!nodeInstanceServer()->hasInstanceForObject(childItem)) { QRectF transformedRect = childItem->mapRectToItem(parentItem, boundingRectWithStepChilds(childItem)); if (isRectangleSane(transformedRect)) @@ -515,6 +574,9 @@ QRectF QuickItemNodeInstance::boundingRectWithStepChilds(QQuickItem *parentItem) } } + if (boundingRect.isEmpty()) + QRectF{0, 0, 640, 480}; + return boundingRect; } diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quickitemnodeinstance.h b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quickitemnodeinstance.h index f42e45a8ff..2c68fe7974 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quickitemnodeinstance.h +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quickitemnodeinstance.h @@ -45,6 +45,7 @@ public: static Pointer create(QObject *objectToBeWrapped); static void createEffectItem(bool createEffectItem); + static void enableUnifiedRenderPath(bool createEffectItem); void initialize(const ObjectNodeInstance::Pointer &objectNodeInstance, InstanceContainer::NodeFlags flags) override; @@ -70,6 +71,8 @@ public: QImage renderImage() const override; QImage renderPreviewImage(const QSize &previewImageSize) const override; + QSharedPointer<QQuickItemGrabResult> createGrabResult() const override; + void updateAllDirtyNodesRecursive() override; @@ -98,6 +101,9 @@ public: QList<QQuickItem*> allItemsRecursive() const override; QStringList allStates() const override; + static void updateDirtyNode(QQuickItem *item); + static bool unifiedRenderPath(); + protected: explicit QuickItemNodeInstance(QQuickItem*); QQuickItem *quickItem() const; @@ -118,6 +124,7 @@ protected: double x() const; double y() const; + bool checkIfRefFromEffect(qint32 id); private: //variables QPointer<QQuickItem> m_contentItem; @@ -131,6 +138,7 @@ private: //variables double m_width; double m_height; static bool s_createEffectItem; + static bool s_unifiedRenderPath; }; } // namespace Internal diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/servernodeinstance.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/servernodeinstance.cpp index 69c854f3e9..511a89b62b 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/servernodeinstance.cpp +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/servernodeinstance.cpp @@ -120,6 +120,11 @@ QImage ServerNodeInstance::renderPreviewImage(const QSize &previewImageSize) con return m_nodeInstance->renderPreviewImage(previewImageSize); } +QSharedPointer<QQuickItemGrabResult> ServerNodeInstance::createGrabResult() const +{ + return m_nodeInstance->createGrabResult(); +} + bool ServerNodeInstance::isRootNodeInstance() const { return isValid() && m_nodeInstance->isRootNodeInstance(); diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/servernodeinstance.h b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/servernodeinstance.h index 975d0e8c37..9150b2bd4e 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/servernodeinstance.h +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/servernodeinstance.h @@ -40,6 +40,7 @@ class QGraphicsItem; class QGraphicsTransform; #if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)) class QQuickItem; +class QQuickItemGrabResult; #endif QT_END_NAMESPACE @@ -102,6 +103,8 @@ public: QImage renderImage() const; QImage renderPreviewImage(const QSize &previewImageSize) const; + QSharedPointer<QQuickItemGrabResult> createGrabResult() const; + ServerNodeInstance parent() const; bool hasParent() const; |