diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/instances.pri b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/instances.pri index d3a81cc3705..2d3b4ceedfe 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/instances.pri +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/instances.pri @@ -46,7 +46,9 @@ HEADERS += $$PWD/qt5nodeinstanceserver.h \ $$PWD/positionernodeinstance.h \ $$PWD/layoutnodeinstance.h \ $$PWD/qt3dpresentationnodeinstance.h \ + $$PWD/quick3dmaterialnodeinstance.h \ $$PWD/quick3dnodeinstance.h \ + $$PWD/quick3drenderablenodeinstance.h \ $$PWD/quick3dtexturenodeinstance.h \ $$PWD/viewconfig.h \ $$PWD/animationdriver.h @@ -79,7 +81,9 @@ SOURCES += $$PWD/qt5nodeinstanceserver.cpp \ $$PWD/positionernodeinstance.cpp \ $$PWD/layoutnodeinstance.cpp \ $$PWD/qt3dpresentationnodeinstance.cpp \ + $$PWD/quick3dmaterialnodeinstance.cpp \ $$PWD/quick3dnodeinstance.cpp \ + $$PWD/quick3drenderablenodeinstance.cpp \ $$PWD/quick3dtexturenodeinstance.cpp \ $$PWD/viewconfig.cpp \ $$PWD/animationdriver.cpp diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5nodeinstanceserver.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5nodeinstanceserver.cpp index 908e06ea50a..32f63a8cd66 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5nodeinstanceserver.cpp +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5nodeinstanceserver.cpp @@ -202,6 +202,12 @@ QList Qt5NodeInstanceServer::allItems() const return QList(); } +bool Qt5NodeInstanceServer::rootIsRenderable3DObject() const +{ + return rootNodeInstance().isSubclassOf("QQuick3DNode") + || rootNodeInstance().isSubclassOf("QQuick3DMaterial"); +} + bool Qt5NodeInstanceServer::initRhi(RenderViewData &viewData) { #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) @@ -398,8 +404,6 @@ QImage Qt5NodeInstanceServer::grabItem(QQuickItem *item) QQuickItemPrivate *pItem = QQuickItemPrivate::get(item); - const bool rootIs3dNode = rootNodeInstance().isSubclassOf("QQuick3DNode"); - const bool renderEffects = qEnvironmentVariableIsSet("QMLPUPPET_RENDER_EFFECTS"); if (renderEffects) { @@ -429,7 +433,7 @@ QImage Qt5NodeInstanceServer::grabItem(QQuickItem *item) if (instance.isValid()) renderBoundingRect = instance.boundingRect(); - else if (rootIs3dNode) + else if (rootIsRenderable3DObject()) renderBoundingRect = item->boundingRect(); else renderBoundingRect = ServerNodeInstance::effectAdjustedBoundingRect(item); diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5nodeinstanceserver.h b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5nodeinstanceserver.h index a0c79296033..4c6dd2c7432 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5nodeinstanceserver.h +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5nodeinstanceserver.h @@ -80,6 +80,7 @@ protected: void resetAllItems(); void setupScene(const CreateSceneCommand &command) override; QList allItems() const; + bool rootIsRenderable3DObject() const; struct RenderViewData { QPointer window = nullptr; diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5rendernodeinstanceserver.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5rendernodeinstanceserver.cpp index 553b69e4815..2ff23395761 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5rendernodeinstanceserver.cpp +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5rendernodeinstanceserver.cpp @@ -133,7 +133,7 @@ void Qt5RenderNodeInstanceServer::collectItemChangesAndSendChangeCommands() nodeInstanceClient()->synchronizeWithClientProcess(); } - if (rootNodeInstance().isSubclassOf("QQuick3DNode") && rootNodeInstance().contentItem() + if (rootIsRenderable3DObject() && rootNodeInstance().contentItem() && DesignerSupport::isDirty(rootNodeInstance().contentItem(), DesignerSupport::AllMask) && nodeInstanceClient()->bytesToWrite() < 10000) { diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quick3dmaterialnodeinstance.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quick3dmaterialnodeinstance.cpp new file mode 100644 index 00000000000..fbfe6c2a2e7 --- /dev/null +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quick3dmaterialnodeinstance.cpp @@ -0,0 +1,57 @@ +/**************************************************************************** +** +** Copyright (C) 2022 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 "quick3dmaterialnodeinstance.h" + +namespace QmlDesigner { +namespace Internal { + +Quick3DMaterialNodeInstance::Quick3DMaterialNodeInstance(QObject *node) + : Quick3DRenderableNodeInstance(node) +{ +} + +Quick3DMaterialNodeInstance::~Quick3DMaterialNodeInstance() +{ +} + +void Quick3DMaterialNodeInstance::initialize(const ObjectNodeInstance::Pointer &objectNodeInstance, + InstanceContainer::NodeFlags flags) +{ + m_dummyRootViewCreateFunction = "createViewForMaterial"; + + Quick3DRenderableNodeInstance::initialize(objectNodeInstance, flags); +} + +Quick3DMaterialNodeInstance::Pointer Quick3DMaterialNodeInstance::create(QObject *object) +{ + Pointer instance(new Quick3DMaterialNodeInstance(object)); + instance->populateResetHashes(); + return instance; +} + +} // namespace Internal +} // namespace QmlDesigner + diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quick3dmaterialnodeinstance.h b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quick3dmaterialnodeinstance.h new file mode 100644 index 00000000000..b55cbb3f309 --- /dev/null +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quick3dmaterialnodeinstance.h @@ -0,0 +1,52 @@ +/**************************************************************************** +** +** Copyright (C) 2022 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 + +#include "quick3drenderablenodeinstance.h" + +QT_FORWARD_DECLARE_CLASS(QQuick3DMaterial) + +namespace QmlDesigner { +namespace Internal { + +class Quick3DMaterialNodeInstance : public Quick3DRenderableNodeInstance +{ +public: + using Pointer = QSharedPointer; + + ~Quick3DMaterialNodeInstance() override; + static Pointer create(QObject *objectToBeWrapped); + void initialize(const ObjectNodeInstance::Pointer &objectNodeInstance, + InstanceContainer::NodeFlags flags) override; + +protected: + explicit Quick3DMaterialNodeInstance(QObject *node); +}; + +} // namespace Internal +} // namespace QmlDesigner diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quick3dnodeinstance.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quick3dnodeinstance.cpp index 0c70ccca8f0..95dd4a7effb 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quick3dnodeinstance.cpp +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quick3dnodeinstance.cpp @@ -26,45 +26,28 @@ #include "quick3dnodeinstance.h" #include "qt5nodeinstanceserver.h" #include "qt5informationnodeinstanceserver.h" -#include "quickitemnodeinstance.h" -#include "../editor3d/generalhelper.h" - -#include - -#include -#include -#include -#include - -#include #ifdef QUICK3D_MODULE #include #include -#include #include #include #include #if defined(QUICK3D_ASSET_UTILS_MODULE) && QT_VERSION > QT_VERSION_CHECK(6, 2, 0) #include #endif -#include #endif - namespace QmlDesigner { namespace Internal { -const QRectF preview3dBoundingRect(0, 0, 640, 480); - Quick3DNodeInstance::Quick3DNodeInstance(QObject *node) - : ObjectNodeInstance(node) + : Quick3DRenderableNodeInstance(node) { } Quick3DNodeInstance::~Quick3DNodeInstance() { - delete m_dummyRootView; } void Quick3DNodeInstance::initialize(const ObjectNodeInstance::Pointer &objectNodeInstance, @@ -96,156 +79,10 @@ void Quick3DNodeInstance::initialize(const ObjectNodeInstance::Pointer &objectNo } } -#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) - // In case this is the scene root, we need to create a dummy View3D for the scene - // in preview puppets - if (instanceId() == 0 && (!nodeInstanceServer()->isInformationServer())) { - auto helper = new QmlDesigner::Internal::GeneralHelper(); - engine()->rootContext()->setContextProperty("_generalHelper", helper); + m_dummyRootViewCreateFunction = "createViewForNode"; - QQmlComponent component(engine()); - component.loadUrl(QUrl("qrc:/qtquickplugin/mockfiles/qt6/ModelNode3DImageView.qml")); - m_dummyRootView = qobject_cast(component.create()); - - QMetaObject::invokeMethod( - m_dummyRootView, "createViewForNode", - Q_ARG(QVariant, QVariant::fromValue(object()))); - - nodeInstanceServer()->setRootItem(m_dummyRootView); - } -#endif // QT_VERSION + Quick3DRenderableNodeInstance::initialize(objectNodeInstance, flags); #endif // QUICK3D_MODULE - ObjectNodeInstance::initialize(objectNodeInstance, flags); -} - -QImage Quick3DNodeInstance::renderImage() const -{ -#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) - if (!isRootNodeInstance() || !m_dummyRootView) - return {}; - - QSize size = preview3dBoundingRect.size().toSize(); - nodeInstanceServer()->quickWindow()->resize(size); - m_dummyRootView->setSize(size); - - // Just render the window once to update spatial nodes - nodeInstanceServer()->renderWindow(); - - QMetaObject::invokeMethod(m_dummyRootView, "fitToViewPort", Qt::DirectConnection); - - QRectF renderBoundingRect = m_dummyRootView->boundingRect(); - QImage renderImage; - - if (QuickItemNodeInstance::unifiedRenderPath()) { - renderImage = nodeInstanceServer()->grabWindow(); - renderImage = renderImage.copy(renderBoundingRect.toRect()); - } else { - renderImage = nodeInstanceServer()->grabItem(m_dummyRootView); - } - - // When grabbing an offscreen window the device pixel ratio is 1 - renderImage.setDevicePixelRatio(1); - - return renderImage; -#endif - return {}; -} - -QImage Quick3DNodeInstance::renderPreviewImage(const QSize &previewImageSize) const -{ -#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) - if (!isRootNodeInstance() || !m_dummyRootView) - return {}; - - nodeInstanceServer()->quickWindow()->resize(previewImageSize); - m_dummyRootView->setSize(previewImageSize); - - // Just render the window once to update spatial nodes - nodeInstanceServer()->renderWindow(); - - QMetaObject::invokeMethod(m_dummyRootView, "fitToViewPort", Qt::DirectConnection); - - QRectF previewItemBoundingRect = boundingRect(); - - if (previewItemBoundingRect.isValid()) { - const QSize size = previewImageSize; - if (m_dummyRootView->isVisible()) { - QImage image; - image = nodeInstanceServer()->grabWindow(); - image = image.copy(previewItemBoundingRect.toRect()); - image = image.scaledToWidth(size.width()); - return image; - } else { - QImage transparentImage(size, QImage::Format_ARGB32_Premultiplied); - transparentImage.fill(Qt::transparent); - return transparentImage; - } - } -#else - Q_UNUSED(previewImageSize) -#endif - return {}; -} - -bool Quick3DNodeInstance::isRenderable() const -{ - return m_dummyRootView; -} - -bool Quick3DNodeInstance::hasContent() const -{ - return true; -} - -QRectF Quick3DNodeInstance::boundingRect() const -{ - //The information server has no m_dummyRootView therefore we use the hardcoded value - if (nodeInstanceServer()->isInformationServer()) - return preview3dBoundingRect; - - if (m_dummyRootView) - return m_dummyRootView->boundingRect(); - return ObjectNodeInstance::boundingRect(); -} - -QRectF Quick3DNodeInstance::contentItemBoundingBox() const -{ - return boundingRect(); -} - -QPointF Quick3DNodeInstance::position() const -{ - return QPointF(0, 0); -} - -QSizeF Quick3DNodeInstance::size() const -{ - return boundingRect().size(); -} - -QList Quick3DNodeInstance::stateInstances() const -{ - QList instanceList; -#ifdef QUICK3D_MODULE - if (auto obj3D = quick3DNode()) { - const QList stateList = QQuick3DObjectPrivate::get(obj3D)->_states()->states(); - for (QQuickState *state : stateList) { - if (state && nodeInstanceServer()->hasInstanceForObject(state)) - instanceList.append(nodeInstanceServer()->instanceForObject(state)); - } - } -#endif - return instanceList; -} - -QQuickItem *Quick3DNodeInstance::contentItem() const -{ - return m_dummyRootView; -} - -Qt5NodeInstanceServer *Quick3DNodeInstance::qt5NodeInstanceServer() const -{ - return qobject_cast(nodeInstanceServer()); } QQuick3DNode *Quick3DNodeInstance::quick3DNode() const diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quick3dnodeinstance.h b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quick3dnodeinstance.h index b3b4f789724..ea44f277fb8 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quick3dnodeinstance.h +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quick3dnodeinstance.h @@ -27,16 +27,14 @@ #include -#include "objectnodeinstance.h" - -#include +#include "quick3drenderablenodeinstance.h" QT_FORWARD_DECLARE_CLASS(QQuick3DNode) namespace QmlDesigner { namespace Internal { -class Quick3DNodeInstance : public ObjectNodeInstance +class Quick3DNodeInstance : public Quick3DRenderableNodeInstance { public: using Pointer = QSharedPointer; @@ -47,28 +45,11 @@ public: void initialize(const ObjectNodeInstance::Pointer &objectNodeInstance, InstanceContainer::NodeFlags flags) override; - QImage renderImage() const override; - QImage renderPreviewImage(const QSize &previewImageSize) const override; - - bool isRenderable() const override; - bool hasContent() const override; - QRectF boundingRect() const override; - QRectF contentItemBoundingBox() const override; - QPointF position() const override; - QSizeF size() const override; - - QList stateInstances() const override; - - QQuickItem *contentItem() const override; - protected: explicit Quick3DNodeInstance(QObject *node); private: - Qt5NodeInstanceServer *qt5NodeInstanceServer() const; QQuick3DNode *quick3DNode() const; - - QQuickItem *m_dummyRootView = nullptr; }; } // namespace Internal diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quick3drenderablenodeinstance.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quick3drenderablenodeinstance.cpp new file mode 100644 index 00000000000..589f57cb5f1 --- /dev/null +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quick3drenderablenodeinstance.cpp @@ -0,0 +1,209 @@ +/**************************************************************************** +** +** Copyright (C) 2022 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 "quick3drenderablenodeinstance.h" +#include "qt5nodeinstanceserver.h" +#include "quickitemnodeinstance.h" +#include "../editor3d/generalhelper.h" + +#ifdef QUICK3D_MODULE +#include +#include +#endif + + +namespace QmlDesigner { +namespace Internal { + +const QRectF preview3dBoundingRect(0, 0, 640, 480); + +Quick3DRenderableNodeInstance::Quick3DRenderableNodeInstance(QObject *node) + : ObjectNodeInstance(node) +{ +} + +Quick3DRenderableNodeInstance::~Quick3DRenderableNodeInstance() +{ + delete m_dummyRootView; +} + +void Quick3DRenderableNodeInstance::initialize(const ObjectNodeInstance::Pointer &objectNodeInstance, + InstanceContainer::NodeFlags flags) +{ +#ifdef QUICK3D_MODULE +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) + // In case this is the scene root, we need to create a dummy View3D for the scene + // in preview puppets + if (instanceId() == 0 && (!nodeInstanceServer()->isInformationServer())) { + auto helper = new QmlDesigner::Internal::GeneralHelper(); + engine()->rootContext()->setContextProperty("_generalHelper", helper); + + QQmlComponent component(engine()); + component.loadUrl(QUrl("qrc:/qtquickplugin/mockfiles/qt6/ModelNode3DImageView.qml")); + m_dummyRootView = qobject_cast(component.create()); + + QMetaObject::invokeMethod(m_dummyRootView, m_dummyRootViewCreateFunction, + Q_ARG(QVariant, QVariant::fromValue(object()))); + + nodeInstanceServer()->setRootItem(m_dummyRootView); + } +#endif // QT_VERSION +#endif // QUICK3D_MODULE + ObjectNodeInstance::initialize(objectNodeInstance, flags); +} + +QImage Quick3DRenderableNodeInstance::renderImage() const +{ +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) + if (!isRootNodeInstance() || !m_dummyRootView) + return {}; + + QSize size = preview3dBoundingRect.size().toSize(); + nodeInstanceServer()->quickWindow()->resize(size); + m_dummyRootView->setSize(size); + + // Just render the window once to update spatial nodes + nodeInstanceServer()->renderWindow(); + + QMetaObject::invokeMethod(m_dummyRootView, "fitToViewPort", Qt::DirectConnection); + + QRectF renderBoundingRect = m_dummyRootView->boundingRect(); + QImage renderImage; + + if (QuickItemNodeInstance::unifiedRenderPath()) { + renderImage = nodeInstanceServer()->grabWindow(); + renderImage = renderImage.copy(renderBoundingRect.toRect()); + } else { + renderImage = nodeInstanceServer()->grabItem(m_dummyRootView); + } + + // When grabbing an offscreen window the device pixel ratio is 1 + renderImage.setDevicePixelRatio(1); + + return renderImage; +#endif + return {}; +} + +QImage Quick3DRenderableNodeInstance::renderPreviewImage(const QSize &previewImageSize) const +{ +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) + if (!isRootNodeInstance() || !m_dummyRootView) + return {}; + + nodeInstanceServer()->quickWindow()->resize(previewImageSize); + m_dummyRootView->setSize(previewImageSize); + + // Just render the window once to update spatial nodes + nodeInstanceServer()->renderWindow(); + + QMetaObject::invokeMethod(m_dummyRootView, "fitToViewPort", Qt::DirectConnection); + + QRectF previewItemBoundingRect = boundingRect(); + + if (previewItemBoundingRect.isValid()) { + const QSize size = previewImageSize; + if (m_dummyRootView->isVisible()) { + QImage image; + image = nodeInstanceServer()->grabWindow(); + image = image.copy(previewItemBoundingRect.toRect()); + image = image.scaledToWidth(size.width()); + return image; + } else { + QImage transparentImage(size, QImage::Format_ARGB32_Premultiplied); + transparentImage.fill(Qt::transparent); + return transparentImage; + } + } +#else + Q_UNUSED(previewImageSize) +#endif + return {}; +} + +bool Quick3DRenderableNodeInstance::isRenderable() const +{ + return m_dummyRootView; +} + +bool Quick3DRenderableNodeInstance::hasContent() const +{ + return true; +} + +QRectF Quick3DRenderableNodeInstance::boundingRect() const +{ + //The information server has no m_dummyRootView therefore we use the hardcoded value + if (nodeInstanceServer()->isInformationServer()) + return preview3dBoundingRect; + + if (m_dummyRootView) + return m_dummyRootView->boundingRect(); + return ObjectNodeInstance::boundingRect(); +} + +QRectF Quick3DRenderableNodeInstance::contentItemBoundingBox() const +{ + return boundingRect(); +} + +QPointF Quick3DRenderableNodeInstance::position() const +{ + return QPointF(0, 0); +} + +QSizeF Quick3DRenderableNodeInstance::size() const +{ + return boundingRect().size(); +} + +QList Quick3DRenderableNodeInstance::stateInstances() const +{ + QList instanceList; +#ifdef QUICK3D_MODULE + if (auto obj3D = qobject_cast(object())) { + const QList stateList = QQuick3DObjectPrivate::get(obj3D)->_states()->states(); + for (QQuickState *state : stateList) { + if (state && nodeInstanceServer()->hasInstanceForObject(state)) + instanceList.append(nodeInstanceServer()->instanceForObject(state)); + } + } +#endif + return instanceList; +} + +QQuickItem *Quick3DRenderableNodeInstance::contentItem() const +{ + return m_dummyRootView; +} + +Qt5NodeInstanceServer *Quick3DRenderableNodeInstance::qt5NodeInstanceServer() const +{ + return qobject_cast(nodeInstanceServer()); +} + +} // namespace Internal +} // namespace QmlDesigner + diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quick3drenderablenodeinstance.h b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quick3drenderablenodeinstance.h new file mode 100644 index 00000000000..ae03cb1b90f --- /dev/null +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quick3drenderablenodeinstance.h @@ -0,0 +1,67 @@ +/**************************************************************************** +** +** Copyright (C) 2022 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 + +#include "objectnodeinstance.h" + +namespace QmlDesigner { +namespace Internal { + +class Quick3DRenderableNodeInstance : public ObjectNodeInstance +{ +public: + ~Quick3DRenderableNodeInstance() override; + void initialize(const ObjectNodeInstance::Pointer &objectNodeInstance, + InstanceContainer::NodeFlags flags) override; + + QImage renderImage() const override; + QImage renderPreviewImage(const QSize &previewImageSize) const override; + + bool isRenderable() const override; + bool hasContent() const override; + QRectF boundingRect() const override; + QRectF contentItemBoundingBox() const override; + QPointF position() const override; + QSizeF size() const override; + + QList stateInstances() const override; + + QQuickItem *contentItem() const override; + +protected: + explicit Quick3DRenderableNodeInstance(QObject *node); + Qt5NodeInstanceServer *qt5NodeInstanceServer() const; + + QByteArray m_dummyRootViewCreateFunction; + +private: + QQuickItem *m_dummyRootView = nullptr; +}; + +} // namespace Internal +} // namespace QmlDesigner diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/servernodeinstance.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/servernodeinstance.cpp index f6c7f94bcaa..a4fdde97ec2 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/servernodeinstance.cpp +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/servernodeinstance.cpp @@ -39,6 +39,7 @@ #include "qt3dpresentationnodeinstance.h" #include "quickitemnodeinstance.h" +#include "quick3dmaterialnodeinstance.h" #include "quick3dnodeinstance.h" #include "quick3dtexturenodeinstance.h" @@ -203,6 +204,8 @@ Internal::ObjectNodeInstance::Pointer ServerNodeInstance::createInstance(QObject instance = Internal::Quick3DTextureNodeInstance::create(objectToBeWrapped); else if (isSubclassOf(objectToBeWrapped, "QQuick3DNode")) instance = Internal::Quick3DNodeInstance::create(objectToBeWrapped); + else if (isSubclassOf(objectToBeWrapped, "QQuick3DMaterial")) + instance = Internal::Quick3DMaterialNodeInstance::create(objectToBeWrapped); else if (isSubclassOf(objectToBeWrapped, "QQmlComponent")) instance = Internal::ComponentNodeInstance::create(objectToBeWrapped); else if (objectToBeWrapped->inherits("QQmlAnchorChanges")) diff --git a/share/qtcreator/qmldesigner/materialBrowserQmlSource/MaterialBrowser.qml b/share/qtcreator/qmldesigner/materialBrowserQmlSource/MaterialBrowser.qml index 77eedc67de1..ab061e4289c 100644 --- a/share/qtcreator/qmldesigner/materialBrowserQmlSource/MaterialBrowser.qml +++ b/share/qtcreator/qmldesigner/materialBrowserQmlSource/MaterialBrowser.qml @@ -102,6 +102,12 @@ Item { onTriggered: materialBrowserModel.applyToSelected(currentMaterial.materialInternalId, true) } + StudioControls.MenuItem { + text: qsTr("Duplicate") + enabled: currentMaterial + onTriggered: materialBrowserModel.duplicateMaterial(currentMaterialIdx) + } + StudioControls.MenuItem { text: qsTr("Rename") enabled: currentMaterial @@ -116,7 +122,7 @@ Item { text: qsTr("Delete") enabled: currentMaterial - onTriggered: materialBrowserModel.deleteMaterial(currentMaterial.materialInternalId) + onTriggered: materialBrowserModel.deleteMaterial(currentMaterialIdx) } StudioControls.MenuSeparator {} diff --git a/share/qtcreator/qmldesigner/newprojectdialog/imports/NewProjectDialog/Details.qml b/share/qtcreator/qmldesigner/newprojectdialog/imports/NewProjectDialog/Details.qml index 1f154810b00..a5ba5afdb3e 100644 --- a/share/qtcreator/qmldesigner/newprojectdialog/imports/NewProjectDialog/Details.qml +++ b/share/qtcreator/qmldesigner/newprojectdialog/imports/NewProjectDialog/Details.qml @@ -414,14 +414,15 @@ Item { SC.ComboBox { // Target Qt Version ComboBox id: qtVersionComboBox actionIndicatorVisible: false - implicitWidth: 70 + implicitWidth: 82 Layout.alignment: Qt.AlignRight currentIndex: BackendApi.targetQtVersionIndex font.pixelSize: DialogValues.defaultPixelSize model: ListModel { - ListElement { name: "Qt 5" } - ListElement { name: "Qt 6" } + ListElement { name: "Qt 5.15" } + ListElement { name: "Qt 6.2" } + ListElement { name: "Qt 6.3" } } onActivated: (index) => { diff --git a/share/qtcreator/qmldesigner/studio_templates/projects/application-3d/wizard.json b/share/qtcreator/qmldesigner/studio_templates/projects/application-3d/wizard.json index c35f10da210..ae3719243e6 100644 --- a/share/qtcreator/qmldesigner/studio_templates/projects/application-3d/wizard.json +++ b/share/qtcreator/qmldesigner/studio_templates/projects/application-3d/wizard.json @@ -236,23 +236,28 @@ "type": "ComboBox", "data": { - "index": 1, + "index": 2, "items": [ { "trKey": "Qt 5", "value": "({ - 'TargetQuickVersion': '2.15', - 'TargetQuick3DVersion': '1.15' + 'TargetQuickVersion': '2.15' })" }, { - "trKey": "Qt 6", + "trKey": "Qt 6.2", "value": "({ - 'TargetQuickVersion': '', - 'TargetQuick3DVersion': '' + 'TargetQuickVersion': '6.2' + })" + }, + { + "trKey": "Qt 6.3", + "value": + "({ + 'TargetQuickVersion': '6.3' })" } ] diff --git a/share/qtcreator/qmldesigner/studio_templates/projects/application/wizard.json b/share/qtcreator/qmldesigner/studio_templates/projects/application/wizard.json index accd83efdf4..51acc18af26 100644 --- a/share/qtcreator/qmldesigner/studio_templates/projects/application/wizard.json +++ b/share/qtcreator/qmldesigner/studio_templates/projects/application/wizard.json @@ -249,10 +249,17 @@ })" }, { - "trKey": "Qt 6", + "trKey": "Qt 6.2", "value": "({ - 'TargetQuickVersion': '' + 'TargetQuickVersion': '6.2' + })" + }, + { + "trKey": "Qt 6.3", + "value": + "({ + 'TargetQuickVersion': '6.3' })" } ] diff --git a/share/qtcreator/qmldesigner/studio_templates/projects/common/app.qmlproject.tpl b/share/qtcreator/qmldesigner/studio_templates/projects/common/app.qmlproject.tpl index d8aa87ee92d..3d2490e8d9c 100644 --- a/share/qtcreator/qmldesigner/studio_templates/projects/common/app.qmlproject.tpl +++ b/share/qtcreator/qmldesigner/studio_templates/projects/common/app.qmlproject.tpl @@ -92,6 +92,8 @@ Project { qdsVersion: "3.4" + quickVersion: "%{QtQuickVersion}" + @if %{IsQt6Project} /* If any modules the project imports require widgets (e.g. QtCharts), widgetApp must be true */ widgetApp: true diff --git a/share/qtcreator/qmldesigner/studio_templates/projects/desktop-launcher/wizard.json b/share/qtcreator/qmldesigner/studio_templates/projects/desktop-launcher/wizard.json index bdf4873fa09..f687b2ce385 100644 --- a/share/qtcreator/qmldesigner/studio_templates/projects/desktop-launcher/wizard.json +++ b/share/qtcreator/qmldesigner/studio_templates/projects/desktop-launcher/wizard.json @@ -235,6 +235,7 @@ "data": { "index": 1, + "items": "items": [ { @@ -245,10 +246,17 @@ })" }, { - "trKey": "Qt 6", + "trKey": "Qt 6.2", "value": "({ - 'TargetQuickVersion': '' + 'TargetQuickVersion': '6.2' + })" + }, + { + "trKey": "Qt 6.3", + "value": + "({ + 'TargetQuickVersion': '6.3' })" } ] diff --git a/share/qtcreator/qmldesigner/studio_templates/projects/mobile-scroll/wizard.json b/share/qtcreator/qmldesigner/studio_templates/projects/mobile-scroll/wizard.json index 6009869a8df..d12fc38bdc4 100644 --- a/share/qtcreator/qmldesigner/studio_templates/projects/mobile-scroll/wizard.json +++ b/share/qtcreator/qmldesigner/studio_templates/projects/mobile-scroll/wizard.json @@ -204,10 +204,17 @@ })" }, { - "trKey": "Qt 6", + "trKey": "Qt 6.2", "value": "({ - 'TargetQuickVersion': '' + 'TargetQuickVersion': '6.2' + })" + }, + { + "trKey": "Qt 6.3", + "value": + "({ + 'TargetQuickVersion': '6.3' })" } ] diff --git a/share/qtcreator/qmldesigner/studio_templates/projects/mobile-stack/wizard.json b/share/qtcreator/qmldesigner/studio_templates/projects/mobile-stack/wizard.json index 53c389177f0..1b76c290359 100644 --- a/share/qtcreator/qmldesigner/studio_templates/projects/mobile-stack/wizard.json +++ b/share/qtcreator/qmldesigner/studio_templates/projects/mobile-stack/wizard.json @@ -202,10 +202,17 @@ })" }, { - "trKey": "Qt 6", + "trKey": "Qt 6.2", "value": "({ - 'TargetQuickVersion': '' + 'TargetQuickVersion': '6.2' + })" + }, + { + "trKey": "Qt 6.3", + "value": + "({ + 'TargetQuickVersion': '6.3' })" } ] diff --git a/share/qtcreator/qmldesigner/studio_templates/projects/mobile-swipe/wizard.json b/share/qtcreator/qmldesigner/studio_templates/projects/mobile-swipe/wizard.json index 065d2783427..19e5865fb83 100644 --- a/share/qtcreator/qmldesigner/studio_templates/projects/mobile-swipe/wizard.json +++ b/share/qtcreator/qmldesigner/studio_templates/projects/mobile-swipe/wizard.json @@ -202,10 +202,17 @@ })" }, { - "trKey": "Qt 6", + "trKey": "Qt 6.2", "value": "({ - 'TargetQuickVersion': '' + 'TargetQuickVersion': '6.2' + })" + }, + { + "trKey": "Qt 6.3", + "value": + "({ + 'TargetQuickVersion': '6.3' })" } ] diff --git a/src/plugins/qmldesigner/components/curveeditor/curveeditorview.cpp b/src/plugins/qmldesigner/components/curveeditor/curveeditorview.cpp index c4040def71a..559a97c8fbc 100644 --- a/src/plugins/qmldesigner/components/curveeditor/curveeditorview.cpp +++ b/src/plugins/qmldesigner/components/curveeditor/curveeditorview.cpp @@ -148,16 +148,23 @@ void CurveEditorView::instancePropertyChanged(const QList &completedNodeList) { - if (Qml3DNode::isValidQml3DNode(rootModelNode())) { + if (Qml3DNode::isValidVisualRoot(rootModelNode())) { if (completedNodeList.contains(rootModelNode())) { FormEditorItem *item = scene()->itemForQmlItemNode(rootModelNode()); if (item) @@ -735,7 +735,7 @@ void FormEditorView::instancesRenderImageChanged(const QVector &nodeL if (QmlItemNode::isValidQmlItemNode(node)) if (FormEditorItem *item = scene()->itemForQmlItemNode(QmlItemNode(node))) item->update(); - if (Qml3DNode::isValidQml3DNode(node)) { + if (Qml3DNode::isValidVisualRoot(node)) { if (FormEditorItem *item = scene()->itemForQmlItemNode(node)) item->update(); } @@ -810,7 +810,7 @@ void FormEditorView::setupFormEditorWidget() if (QmlItemNode::isValidQmlItemNode(rootModelNode())) setupFormEditorItemTree(rootModelNode()); - if (Qml3DNode::isValidQml3DNode(rootModelNode())) + if (Qml3DNode::isValidVisualRoot(rootModelNode())) setupFormEditor3DView(); m_formEditorWidget->initialize(); @@ -922,7 +922,7 @@ void FormEditorView::checkRootModelNode() QTC_ASSERT(rootModelNode().isValid(), return); if (!rootModelNode().metaInfo().isGraphicalItem() - && !Qml3DNode::isValidQml3DNode(rootModelNode())) + && !Qml3DNode::isValidVisualRoot(rootModelNode())) m_formEditorWidget->showErrorMessageBox( {DocumentMessage(tr("%1 is not supported as the root element by Form Editor.") .arg(rootModelNode().simplifiedTypeName()))}); diff --git a/src/plugins/qmldesigner/components/materialbrowser/materialbrowsermodel.cpp b/src/plugins/qmldesigner/components/materialbrowser/materialbrowsermodel.cpp index d4bee4fcced..d0420163c3a 100644 --- a/src/plugins/qmldesigner/components/materialbrowser/materialbrowsermodel.cpp +++ b/src/plugins/qmldesigner/components/materialbrowser/materialbrowsermodel.cpp @@ -246,11 +246,14 @@ void MaterialBrowserModel::selectMaterial(int idx, bool force) } } -void MaterialBrowserModel::deleteMaterial(qint32 internalId) +void MaterialBrowserModel::duplicateMaterial(int idx) { - int idx = m_materialIndexHash.value(internalId); - if (isValidIndex(idx)) - m_materialList[idx].destroy(); + emit duplicateMaterialTriggered(m_materialList.at(idx)); +} + +void MaterialBrowserModel::deleteMaterial(int idx) +{ + m_materialList[idx].destroy(); } void MaterialBrowserModel::renameMaterial(int idx, const QString &newName) diff --git a/src/plugins/qmldesigner/components/materialbrowser/materialbrowsermodel.h b/src/plugins/qmldesigner/components/materialbrowser/materialbrowsermodel.h index 5f00596ef9e..32db357caeb 100644 --- a/src/plugins/qmldesigner/components/materialbrowser/materialbrowsermodel.h +++ b/src/plugins/qmldesigner/components/materialbrowser/materialbrowsermodel.h @@ -68,6 +68,7 @@ public: void resetModel(); Q_INVOKABLE void selectMaterial(int idx, bool force = false); + Q_INVOKABLE void duplicateMaterial(int idx); Q_INVOKABLE void deleteMaterial(int idx); Q_INVOKABLE void renameMaterial(int idx, const QString &newName); Q_INVOKABLE void addNewMaterial(); @@ -82,6 +83,7 @@ signals: void renameMaterialTriggered(const QmlDesigner::ModelNode &material, const QString &newName); void applyToSelectedTriggered(const QmlDesigner::ModelNode &material, bool add = false); void addNewMaterialTriggered(); + void duplicateMaterialTriggered(const QmlDesigner::ModelNode &material); private: bool isMaterialVisible(int idx) const; diff --git a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.cpp b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.cpp index 40f2d8f6217..5ee0dc1888d 100644 --- a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.cpp +++ b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.cpp @@ -54,16 +54,33 @@ WidgetInfo MaterialBrowserView::widgetInfo() { if (m_widget.isNull()) { m_widget = new MaterialBrowserWidget; - connect(m_widget->materialBrowserModel().data(), SIGNAL(selectedIndexChanged(int)), - this, SLOT(handleSelectedMaterialChanged(int))); - connect(m_widget->materialBrowserModel().data(), - SIGNAL(applyToSelectedTriggered(const QmlDesigner::ModelNode &, bool)), - this, SLOT(handleApplyToSelectedTriggered(const QmlDesigner::ModelNode &, bool))); - connect(m_widget->materialBrowserModel().data(), - SIGNAL(renameMaterialTriggered(const QmlDesigner::ModelNode &, const QString &)), - this, SLOT(handleRenameMaterial(const QmlDesigner::ModelNode &, const QString &))); - connect(m_widget->materialBrowserModel().data(), SIGNAL(addNewMaterialTriggered()), - this, SLOT(handleAddNewMaterial())); + MaterialBrowserModel *matBrowserModel = m_widget->materialBrowserModel().data(); + + // custom notifications below are sent to the MaterialEditor + + connect(matBrowserModel, &MaterialBrowserModel::selectedIndexChanged, this, [&] (int idx) { + ModelNode matNode = m_widget->materialBrowserModel()->materialAt(idx); + emitCustomNotification("selected_material_changed", {matNode}, {}); + }); + + connect(matBrowserModel, &MaterialBrowserModel::applyToSelectedTriggered, this, + [&] (const ModelNode &material, bool add) { + emitCustomNotification("apply_to_selected_triggered", {material}, {add}); + }); + + connect(matBrowserModel, &MaterialBrowserModel::renameMaterialTriggered, this, + [&] (const ModelNode &material, const QString &newName) { + emitCustomNotification("rename_material", {material}, {newName}); + }); + + connect(matBrowserModel, &MaterialBrowserModel::addNewMaterialTriggered, this, [&] { + emitCustomNotification("add_new_material"); + }); + + connect(matBrowserModel, &MaterialBrowserModel::duplicateMaterialTriggered, this, + [&] (const ModelNode &material) { + emitCustomNotification("duplicate_material", {material}); + }); } return createWidgetInfo(m_widget.data(), @@ -239,29 +256,4 @@ void MaterialBrowserView::customNotification(const AbstractView *view, const QSt } } -void MaterialBrowserView::handleSelectedMaterialChanged(int idx) -{ - ModelNode matNode = m_widget->materialBrowserModel()->materialAt(idx); - // to MaterialEditor... - emitCustomNotification("selected_material_changed", {matNode}, {}); -} - -void MaterialBrowserView::handleApplyToSelectedTriggered(const ModelNode &material, bool add) -{ - // to MaterialEditor... - emitCustomNotification("apply_to_selected_triggered", {material}, {add}); -} - -void MaterialBrowserView::handleRenameMaterial(const ModelNode &material, const QString &newName) -{ - // to MaterialEditor... - emitCustomNotification("rename_material", {material}, {newName}); -} - -void MaterialBrowserView::handleAddNewMaterial() -{ - // to MaterialEditor... - emitCustomNotification("add_new_material"); -} - } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.h b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.h index 28e4694cd65..e140eede136 100644 --- a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.h +++ b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.h @@ -68,12 +68,6 @@ private: QPointer m_widget; bool m_hasQuick3DImport = false; bool m_autoSelectModelMaterial = false; // TODO: wire this to some action - -private slots: - void handleSelectedMaterialChanged(int idx); - void handleApplyToSelectedTriggered(const QmlDesigner::ModelNode &material, bool add = false); - void handleRenameMaterial(const QmlDesigner::ModelNode &material, const QString &newName); - void handleAddNewMaterial(); }; } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/components/materialeditor/materialeditorview.cpp b/src/plugins/qmldesigner/components/materialeditor/materialeditorview.cpp index e91ed46f5d3..0bcefaec5fe 100644 --- a/src/plugins/qmldesigner/components/materialeditor/materialeditorview.cpp +++ b/src/plugins/qmldesigner/components/materialeditor/materialeditorview.cpp @@ -749,6 +749,41 @@ void MaterialEditorView::renameMaterial(ModelNode &material, const QString &newN }); } +void MaterialEditorView::duplicateMaterial(const ModelNode &material) +{ + QTC_ASSERT(material.isValid(), return); + + ensureMaterialLibraryNode(); + + TypeName matType = material.type(); + QmlObjectNode sourceMat(material); + + executeInTransaction(__FUNCTION__, [&] { + // create the duplicate material + NodeMetaInfo metaInfo = model()->metaInfo(matType); + QmlObjectNode duplicateMat = createModelNode(matType, metaInfo.majorVersion(), metaInfo.minorVersion()); + + // set name and id + QString newName = sourceMat.modelNode().variantProperty("objectName").value().toString() + " copy"; + duplicateMat.modelNode().variantProperty("objectName").setValue(newName); + duplicateMat.modelNode().setIdWithoutRefactoring(generateIdFromName(newName)); + + // sync properties + const QList props = material.properties(); + for (const AbstractProperty &prop : props) { + if (prop.name() == "objectName") + continue; + + if (prop.isVariantProperty()) + duplicateMat.setVariantProperty(prop.name(), prop.toVariantProperty().value()); + else if (prop.isBindingProperty()) + duplicateMat.setBindingProperty(prop.name(), prop.toBindingProperty().expression()); + } + + m_materialLibrary.defaultNodeListProperty().reparentHere(duplicateMat); + }); +} + void MaterialEditorView::customNotification(const AbstractView *view, const QString &identifier, const QList &nodeList, const QList &data) { @@ -762,6 +797,8 @@ void MaterialEditorView::customNotification(const AbstractView *view, const QStr renameMaterial(m_selectedMaterial, data.first().toString()); } else if (identifier == "add_new_material") { handleToolBarAction(MaterialEditorContextObject::AddNewMaterial); + } else if (identifier == "duplicate_material") { + duplicateMaterial(nodeList.first()); } } diff --git a/src/plugins/qmldesigner/components/materialeditor/materialeditorview.h b/src/plugins/qmldesigner/components/materialeditor/materialeditorview.h index 9d096064bc2..8ab30a63f44 100644 --- a/src/plugins/qmldesigner/components/materialeditor/materialeditorview.h +++ b/src/plugins/qmldesigner/components/materialeditor/materialeditorview.h @@ -106,6 +106,7 @@ private: void commitAuxValueToModel(const PropertyName &propertyName, const QVariant &value); void removePropertyFromModel(const PropertyName &propertyName); void renameMaterial(ModelNode &material, const QString &newName); + void duplicateMaterial(const ModelNode &material); bool noValidSelection() const; diff --git a/src/plugins/qmldesigner/components/navigator/navigatortreemodel.cpp b/src/plugins/qmldesigner/components/navigator/navigatortreemodel.cpp index 6106f901948..0a92f81d93f 100644 --- a/src/plugins/qmldesigner/components/navigator/navigatortreemodel.cpp +++ b/src/plugins/qmldesigner/components/navigator/navigatortreemodel.cpp @@ -229,11 +229,6 @@ QVariant NavigatorTreeModel::data(const QModelIndex &index, int role) const } else if (role == Qt::ToolTipRole) { if (currentQmlObjectNode.hasError()) { QString errorString = currentQmlObjectNode.error(); - if (QmlProjectManager::QmlProject::isQtDesignStudio() - && currentQmlObjectNode.isRootNode()) { - errorString.append(QString("\n%1").arg(tr("Changing the setting \"%1\" might solve the issue.").arg( - tr("Use QML emulation layer that is built with the selected Qt")))); - } return errorString; } diff --git a/src/plugins/qmldesigner/designercore/include/qml3dnode.h b/src/plugins/qmldesigner/designercore/include/qml3dnode.h index d52cacb49b5..87d06dca7e3 100644 --- a/src/plugins/qmldesigner/designercore/include/qml3dnode.h +++ b/src/plugins/qmldesigner/designercore/include/qml3dnode.h @@ -49,6 +49,7 @@ public: Qml3DNode(const ModelNode &modelNode) : QmlVisualNode(modelNode) {} bool isValid() const override; static bool isValidQml3DNode(const ModelNode &modelNode); + static bool isValidVisualRoot(const ModelNode &modelNode); // From QmlObjectNode void setVariantProperty(const PropertyName &name, const QVariant &value) override; diff --git a/src/plugins/qmldesigner/designercore/model/qml3dnode.cpp b/src/plugins/qmldesigner/designercore/model/qml3dnode.cpp index 7f6f07b0018..c6698df6e6f 100644 --- a/src/plugins/qmldesigner/designercore/model/qml3dnode.cpp +++ b/src/plugins/qmldesigner/designercore/model/qml3dnode.cpp @@ -58,6 +58,15 @@ bool Qml3DNode::isValidQml3DNode(const ModelNode &modelNode) && (modelNode.metaInfo().isSubclassOf("QtQuick3D.Node")); } +bool Qml3DNode::isValidVisualRoot(const ModelNode &modelNode) +{ + return isValidQmlObjectNode(modelNode) + && modelNode.metaInfo().isValid() + && ((modelNode.metaInfo().isSubclassOf("QtQuick3D.Node")) + || (modelNode.metaInfo().isSubclassOf("QtQuick3D.Material"))); + +} + void Qml3DNode::setVariantProperty(const PropertyName &name, const QVariant &value) { if (isBlocked(name)) diff --git a/src/plugins/qmldesigner/qtquickplugin/images/keyframe-16px.png b/src/plugins/qmldesigner/qtquickplugin/images/keyframe-16px.png new file mode 100644 index 00000000000..6e1c9f912a2 Binary files /dev/null and b/src/plugins/qmldesigner/qtquickplugin/images/keyframe-16px.png differ diff --git a/src/plugins/qmldesigner/qtquickplugin/images/timeline-16px.png b/src/plugins/qmldesigner/qtquickplugin/images/timeline-16px.png new file mode 100644 index 00000000000..d4ecf00031f Binary files /dev/null and b/src/plugins/qmldesigner/qtquickplugin/images/timeline-16px.png differ diff --git a/src/plugins/qmldesigner/qtquickplugin/images/timeline-animation-16px.png b/src/plugins/qmldesigner/qtquickplugin/images/timeline-animation-16px.png new file mode 100644 index 00000000000..d4ecf00031f Binary files /dev/null and b/src/plugins/qmldesigner/qtquickplugin/images/timeline-animation-16px.png differ diff --git a/src/plugins/qmldesigner/qtquickplugin/qtquickplugin.qrc b/src/plugins/qmldesigner/qtquickplugin/qtquickplugin.qrc index 0098d05a37d..7cdc3309cba 100644 --- a/src/plugins/qmldesigner/qtquickplugin/qtquickplugin.qrc +++ b/src/plugins/qmldesigner/qtquickplugin/qtquickplugin.qrc @@ -95,5 +95,8 @@ images/video-output-16px.png images/video-output-24px.png images/video-output-24px@2x.png + images/timeline-16px.png + images/keyframe-16px.png + images/timeline-animation-16px.png diff --git a/src/plugins/qmldesigner/qtquickplugin/quick.metainfo b/src/plugins/qmldesigner/qtquickplugin/quick.metainfo index d21d8420b4b..4b766f715c1 100644 --- a/src/plugins/qmldesigner/qtquickplugin/quick.metainfo +++ b/src/plugins/qmldesigner/qtquickplugin/quick.metainfo @@ -280,6 +280,61 @@ MetaInfo { } } + Type { + name: "QtQuick.Timeline.Timeline" + icon: ":/qtquickplugin/images/timeline-16px.png" + + Hints { + visibleNonDefaultProperties: "animations" + visibleInLibrary: false + visibleInNavigator: true + } + ItemLibraryEntry { + name: "Timeline" + category: "none" + version: "1.0" + } + } + + Type { + name: "QtQuick.Timeline.TimelineAnimation" + icon: ":/qtquickplugin/images/timeline-animation-16px.png" + + Hints { + visibleInLibrary: false + visibleInNavigator: true + } + ItemLibraryEntry { + name: "Animation" + category: "none" + version: "1.0" + } + } + + Type { + name: "QtQuick.Timeline.Keyframe" + icon: ":/qtquickplugin/images/keyframe-16px.png" + + ItemLibraryEntry { + name: "Keyframe" + category: "none" + version: "1.0" + requiredImport: "none" + } + } + + Type { + name: "QtQuick.Timeline.KeyframeGroup" + icon: ":/qtquickplugin/images/keyframe-16px.png" + + ItemLibraryEntry { + name: "KeyframeGroup" + category: "none" + version: "1.0" + requiredImport: "none" + } + } + Type { name: "QtQuick.PropertyAnimation" icon: ":/qtquickplugin/images/item-icon16.png" diff --git a/src/tools/qml2puppet/CMakeLists.txt b/src/tools/qml2puppet/CMakeLists.txt index a2866dabde0..ef8eb1eb512 100644 --- a/src/tools/qml2puppet/CMakeLists.txt +++ b/src/tools/qml2puppet/CMakeLists.txt @@ -231,7 +231,9 @@ extend_qtc_executable(qml2puppet qt5previewnodeinstanceserver.cpp qt5previewnodeinstanceserver.h qt5rendernodeinstanceserver.cpp qt5rendernodeinstanceserver.h qt5testnodeinstanceserver.cpp qt5testnodeinstanceserver.h + quick3dmaterialnodeinstance.cpp quick3dmaterialnodeinstance.h quick3dnodeinstance.cpp quick3dnodeinstance.h + quick3drenderablenodeinstance.cpp quick3drenderablenodeinstance.h quick3dtexturenodeinstance.cpp quick3dtexturenodeinstance.h quickitemnodeinstance.cpp quickitemnodeinstance.h servernodeinstance.cpp servernodeinstance.h diff --git a/src/tools/qml2puppet/qml2puppet.qbs b/src/tools/qml2puppet/qml2puppet.qbs index f51dd11b753..0031fe34c9d 100644 --- a/src/tools/qml2puppet/qml2puppet.qbs +++ b/src/tools/qml2puppet/qml2puppet.qbs @@ -223,8 +223,12 @@ QtcTool { "instances/qmlpropertychangesnodeinstance.h", "instances/qmlstatenodeinstance.cpp", "instances/qmlstatenodeinstance.h", + "instances/quick3dmaterialnodeinstance.cpp", + "instances/quick3dmaterialnodeinstance.h", "instances/quick3dnodeinstance.cpp", "instances/quick3dnodeinstance.h", + "instances/quick3drenderablenodeinstance.cpp", + "instances/quick3drenderablenodeinstance.h", "instances/quick3dtexturenodeinstance.cpp", "instances/quick3dtexturenodeinstance.h", "instances/qmltransitionnodeinstance.cpp",