forked from qt-creator/qt-creator
QmlDesigner: Show form editor preview for 3D material root nodes
Fixes: QDS-6561 Change-Id: I62a06eb6c83b0a4813a1b20f91b09e17b04a1332 Reviewed-by: Mahmoud Badri <mahmoud.badri@qt.io> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Samuel Ghinet <samuel.ghinet@qt.io> Reviewed-by: <github-actions-qt-creator@cristianadam.eu>
This commit is contained in:
@@ -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
|
||||
|
@@ -202,6 +202,12 @@ QList<QQuickItem*> Qt5NodeInstanceServer::allItems() const
|
||||
return QList<QQuickItem*>();
|
||||
}
|
||||
|
||||
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);
|
||||
|
@@ -80,6 +80,7 @@ protected:
|
||||
void resetAllItems();
|
||||
void setupScene(const CreateSceneCommand &command) override;
|
||||
QList<QQuickItem*> allItems() const;
|
||||
bool rootIsRenderable3DObject() const;
|
||||
|
||||
struct RenderViewData {
|
||||
QPointer<QQuickWindow> window = nullptr;
|
||||
|
@@ -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) {
|
||||
|
@@ -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
|
||||
|
@@ -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 <QtGlobal>
|
||||
|
||||
#include "quick3drenderablenodeinstance.h"
|
||||
|
||||
QT_FORWARD_DECLARE_CLASS(QQuick3DMaterial)
|
||||
|
||||
namespace QmlDesigner {
|
||||
namespace Internal {
|
||||
|
||||
class Quick3DMaterialNodeInstance : public Quick3DRenderableNodeInstance
|
||||
{
|
||||
public:
|
||||
using Pointer = QSharedPointer<Quick3DMaterialNodeInstance>;
|
||||
|
||||
~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
|
@@ -26,45 +26,28 @@
|
||||
#include "quick3dnodeinstance.h"
|
||||
#include "qt5nodeinstanceserver.h"
|
||||
#include "qt5informationnodeinstanceserver.h"
|
||||
#include "quickitemnodeinstance.h"
|
||||
#include "../editor3d/generalhelper.h"
|
||||
|
||||
#include <qmlprivategate.h>
|
||||
|
||||
#include <QDebug>
|
||||
#include <QHash>
|
||||
#include <QQmlExpression>
|
||||
#include <QQmlProperty>
|
||||
|
||||
#include <cmath>
|
||||
|
||||
#ifdef QUICK3D_MODULE
|
||||
#include <private/qquick3dobject_p.h>
|
||||
#include <private/qquick3dnode_p.h>
|
||||
#include <private/qquick3dmodel_p.h>
|
||||
#include <private/qquick3dnode_p_p.h>
|
||||
#include <private/qquick3drepeater_p.h>
|
||||
#include <private/qquick3dloader_p.h>
|
||||
#if defined(QUICK3D_ASSET_UTILS_MODULE) && QT_VERSION > QT_VERSION_CHECK(6, 2, 0)
|
||||
#include <private/qquick3druntimeloader_p.h>
|
||||
#endif
|
||||
#include <private/qquickstategroup_p.h>
|
||||
#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<QQuickItem *>(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<ServerNodeInstance> Quick3DNodeInstance::stateInstances() const
|
||||
{
|
||||
QList<ServerNodeInstance> instanceList;
|
||||
#ifdef QUICK3D_MODULE
|
||||
if (auto obj3D = quick3DNode()) {
|
||||
const QList<QQuickState *> 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<Qt5NodeInstanceServer *>(nodeInstanceServer());
|
||||
}
|
||||
|
||||
QQuick3DNode *Quick3DNodeInstance::quick3DNode() const
|
||||
|
@@ -27,16 +27,14 @@
|
||||
|
||||
#include <QtGlobal>
|
||||
|
||||
#include "objectnodeinstance.h"
|
||||
|
||||
#include <designersupportdelegate.h>
|
||||
#include "quick3drenderablenodeinstance.h"
|
||||
|
||||
QT_FORWARD_DECLARE_CLASS(QQuick3DNode)
|
||||
|
||||
namespace QmlDesigner {
|
||||
namespace Internal {
|
||||
|
||||
class Quick3DNodeInstance : public ObjectNodeInstance
|
||||
class Quick3DNodeInstance : public Quick3DRenderableNodeInstance
|
||||
{
|
||||
public:
|
||||
using Pointer = QSharedPointer<Quick3DNodeInstance>;
|
||||
@@ -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<ServerNodeInstance> 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
|
||||
|
@@ -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 <private/qquick3dobject_p.h>
|
||||
#include <private/qquickstategroup_p.h>
|
||||
#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<QQuickItem *>(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<ServerNodeInstance> Quick3DRenderableNodeInstance::stateInstances() const
|
||||
{
|
||||
QList<ServerNodeInstance> instanceList;
|
||||
#ifdef QUICK3D_MODULE
|
||||
if (auto obj3D = qobject_cast<QQuick3DObject *>(object())) {
|
||||
const QList<QQuickState *> 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<Qt5NodeInstanceServer *>(nodeInstanceServer());
|
||||
}
|
||||
|
||||
} // namespace Internal
|
||||
} // namespace QmlDesigner
|
||||
|
@@ -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 <QtGlobal>
|
||||
|
||||
#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<ServerNodeInstance> 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
|
@@ -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"))
|
||||
|
@@ -659,7 +659,7 @@ static void updateTransitions(FormEditorScene *scene, const QmlItemNode &qmlItem
|
||||
|
||||
void FormEditorView::instancesCompleted(const QVector<ModelNode> &completedNodeList)
|
||||
{
|
||||
if (Qml3DNode::isValidQml3DNode(rootModelNode())) {
|
||||
if (Qml3DNode::isValidVisualRoot(rootModelNode())) {
|
||||
if (completedNodeList.contains(rootModelNode())) {
|
||||
FormEditorItem *item = scene()->itemForQmlItemNode(rootModelNode());
|
||||
if (item)
|
||||
@@ -736,7 +736,7 @@ void FormEditorView::instancesRenderImageChanged(const QVector<ModelNode> &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();
|
||||
}
|
||||
@@ -811,7 +811,7 @@ void FormEditorView::setupFormEditorWidget()
|
||||
if (QmlItemNode::isValidQmlItemNode(rootModelNode()))
|
||||
setupFormEditorItemTree(rootModelNode());
|
||||
|
||||
if (Qml3DNode::isValidQml3DNode(rootModelNode()))
|
||||
if (Qml3DNode::isValidVisualRoot(rootModelNode()))
|
||||
setupFormEditor3DView();
|
||||
|
||||
m_formEditorWidget->initialize();
|
||||
@@ -923,7 +923,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()))});
|
||||
|
@@ -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;
|
||||
|
@@ -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))
|
||||
|
@@ -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
|
||||
|
@@ -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",
|
||||
|
Reference in New Issue
Block a user