aboutsummaryrefslogtreecommitdiffstats
path: root/share/qtcreator
diff options
context:
space:
mode:
authorMiikka Heikkinen <miikka.heikkinen@qt.io>2020-09-22 11:30:05 +0300
committerMiikka Heikkinen <miikka.heikkinen@qt.io>2020-09-22 13:35:20 +0000
commit31ec38dba5efb731b0769a2d3e4d0232d9ba6e22 (patch)
tree76263b6b3e6260057da494c797ccac21c771eff0 /share/qtcreator
parent762addfbd0fe355bb0008d9af72bf317a05462c0 (diff)
QmlDesigner: Add navigator tooltip for 3D Components with Node root
This enables showing preview tooltip for all imported 3D models. Also moved the preview image handling out of the model and into NodeInstanceView, where it fits more naturally. Change-Id: I48135d06aa8d9313525dae618e22692563da78fd Fixes: QDS-2807 Reviewed-by: Mahmoud Badri <mahmoud.badri@qt.io> Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io>
Diffstat (limited to 'share/qtcreator')
-rw-r--r--share/qtcreator/qml/qmlpuppet/commands/requestmodelnodepreviewimagecommand.cpp13
-rw-r--r--share/qtcreator/qml/qmlpuppet/commands/requestmodelnodepreviewimagecommand.h4
-rw-r--r--share/qtcreator/qml/qmlpuppet/mockfiles/ModelNode3DImageView.qml17
-rw-r--r--share/qtcreator/qml/qmlpuppet/mockfiles/ModelNodeView.qml2
-rw-r--r--share/qtcreator/qml/qmlpuppet/mockfiles/NodeNodeView.qml96
-rw-r--r--share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5informationnodeinstanceserver.cpp83
-rw-r--r--share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5informationnodeinstanceserver.h4
-rw-r--r--share/qtcreator/qml/qmlpuppet/qmlpuppet.qrc1
8 files changed, 183 insertions, 37 deletions
diff --git a/share/qtcreator/qml/qmlpuppet/commands/requestmodelnodepreviewimagecommand.cpp b/share/qtcreator/qml/qmlpuppet/commands/requestmodelnodepreviewimagecommand.cpp
index c29ec216c8..17f3a65a13 100644
--- a/share/qtcreator/qml/qmlpuppet/commands/requestmodelnodepreviewimagecommand.cpp
+++ b/share/qtcreator/qml/qmlpuppet/commands/requestmodelnodepreviewimagecommand.cpp
@@ -32,9 +32,10 @@ namespace QmlDesigner {
RequestModelNodePreviewImageCommand::RequestModelNodePreviewImageCommand() = default;
-RequestModelNodePreviewImageCommand::RequestModelNodePreviewImageCommand(qint32 id, const QSize &size)
+RequestModelNodePreviewImageCommand::RequestModelNodePreviewImageCommand(qint32 id, const QSize &size, const QString &componentPath)
: m_instanceId(id)
, m_size(size)
+ , m_componentPath(componentPath)
{
}
@@ -48,10 +49,16 @@ QSize QmlDesigner::RequestModelNodePreviewImageCommand::size() const
return m_size;
}
+QString RequestModelNodePreviewImageCommand::componentPath() const
+{
+ return m_componentPath;
+}
+
QDataStream &operator<<(QDataStream &out, const RequestModelNodePreviewImageCommand &command)
{
out << int(command.instanceId());
out << command.size();
+ out << command.componentPath();
return out;
}
@@ -60,6 +67,7 @@ QDataStream &operator>>(QDataStream &in, RequestModelNodePreviewImageCommand &co
{
in >> command.m_instanceId;
in >> command.m_size;
+ in >> command.m_componentPath;
return in;
}
@@ -67,7 +75,8 @@ QDebug operator <<(QDebug debug, const RequestModelNodePreviewImageCommand &comm
{
return debug.nospace() << "RequestModelNodePreviewImageCommand("
<< "instanceId: " << command.instanceId() << ", "
- << "size: " << command.size() << ")";
+ << "size: " << command.size() << ", "
+ << "componentPath: " << command.componentPath() << ")";
}
} // namespace QmlDesigner
diff --git a/share/qtcreator/qml/qmlpuppet/commands/requestmodelnodepreviewimagecommand.h b/share/qtcreator/qml/qmlpuppet/commands/requestmodelnodepreviewimagecommand.h
index f18055695b..14ebe6156f 100644
--- a/share/qtcreator/qml/qmlpuppet/commands/requestmodelnodepreviewimagecommand.h
+++ b/share/qtcreator/qml/qmlpuppet/commands/requestmodelnodepreviewimagecommand.h
@@ -40,14 +40,16 @@ class RequestModelNodePreviewImageCommand
public:
RequestModelNodePreviewImageCommand();
- explicit RequestModelNodePreviewImageCommand(qint32 id, const QSize &size);
+ explicit RequestModelNodePreviewImageCommand(qint32 id, const QSize &size, const QString &componentPath);
qint32 instanceId() const;
QSize size() const;
+ QString componentPath() const;
private:
qint32 m_instanceId;
QSize m_size;
+ QString m_componentPath;
};
QDataStream &operator<<(QDataStream &out, const RequestModelNodePreviewImageCommand &command);
diff --git a/share/qtcreator/qml/qmlpuppet/mockfiles/ModelNode3DImageView.qml b/share/qtcreator/qml/qmlpuppet/mockfiles/ModelNode3DImageView.qml
index 44580a0b30..277bc8431f 100644
--- a/share/qtcreator/qml/qmlpuppet/mockfiles/ModelNode3DImageView.qml
+++ b/share/qtcreator/qml/qmlpuppet/mockfiles/ModelNode3DImageView.qml
@@ -41,6 +41,7 @@ Item {
property var materialViewComponent
property var effectViewComponent
property var modelViewComponent
+ property var nodeViewComponent
property bool ready: false
@@ -65,6 +66,8 @@ Item {
createViewForEffect(obj);
else if (obj instanceof Model)
createViewForModel(obj);
+ else if (obj instanceof Node)
+ createViewForNode(obj);
previewObject = obj;
}
@@ -99,10 +102,20 @@ Item {
view = modelViewComponent.createObject(viewRect, {"sourceModel": model});
}
+ function createViewForNode(node)
+ {
+ if (!nodeViewComponent)
+ nodeViewComponent = Qt.createComponent("NodeNodeView.qml");
+
+ // Always recreate the view to ensure node is up to date
+ if (nodeViewComponent.status === Component.Ready)
+ view = nodeViewComponent.createObject(viewRect, {"importScene": node});
+ }
+
function afterRender()
{
- if (previewObject instanceof Model) {
- view.fitModel();
+ if (previewObject instanceof Node) {
+ view.fitToViewPort();
ready = view.ready;
} else {
ready = true;
diff --git a/share/qtcreator/qml/qmlpuppet/mockfiles/ModelNodeView.qml b/share/qtcreator/qml/qmlpuppet/mockfiles/ModelNodeView.qml
index 1379a27a05..dc10f441e1 100644
--- a/share/qtcreator/qml/qmlpuppet/mockfiles/ModelNodeView.qml
+++ b/share/qtcreator/qml/qmlpuppet/mockfiles/ModelNodeView.qml
@@ -36,7 +36,7 @@ View3D {
property real prevZoomFactor: -1
property Model sourceModel
- function fitModel()
+ function fitToViewPort()
{
cameraControl.focusObject(model, theCamera.eulerRotation, true, false);
diff --git a/share/qtcreator/qml/qmlpuppet/mockfiles/NodeNodeView.qml b/share/qtcreator/qml/qmlpuppet/mockfiles/NodeNodeView.qml
new file mode 100644
index 0000000000..b41c74af54
--- /dev/null
+++ b/share/qtcreator/qml/qmlpuppet/mockfiles/NodeNodeView.qml
@@ -0,0 +1,96 @@
+/****************************************************************************
+**
+** 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.
+**
+****************************************************************************/
+
+import QtQuick 2.15
+import QtQuick3D 1.15
+
+View3D {
+ id: root
+ anchors.fill: parent
+ environment: sceneEnv
+ camera: theCamera
+
+ property bool ready: false
+ property bool first: true
+ property real prevZoomFactor: -1
+
+ function fitToViewPort()
+ {
+ if (first) {
+ first = false;
+ selectionBox.targetNode = root.importScene;
+ } else {
+ cameraControl.focusObject(selectionBox.model, theCamera.eulerRotation, true, false);
+
+ if (cameraControl._zoomFactor < 0.1) {
+ root.importScene.scale = root.importScene.scale.times(10);
+ } else if (cameraControl._zoomFactor > 10) {
+ root.importScene.scale = root.importScene.scale.times(0.1);
+ } else {
+ // We need one more render after zoom factor change, so only set ready when zoom factor
+ // or scaling hasn't changed from the previous frame
+ ready = _generalHelper.fuzzyCompare(cameraControl._zoomFactor, prevZoomFactor);
+ prevZoomFactor = cameraControl._zoomFactor;
+ selectionBox.visible = false;
+ }
+ }
+ }
+
+ SceneEnvironment {
+ id: sceneEnv
+ antialiasingMode: SceneEnvironment.MSAA
+ antialiasingQuality: SceneEnvironment.High
+ }
+
+ SelectionBox {
+ id: selectionBox
+ view3D: root
+ geometryName: "NodeNodeViewSB"
+ }
+
+ EditCameraController {
+ id: cameraControl
+ camera: theCamera
+ anchors.fill: parent
+ view3d: root
+ ignoreToolState: true
+ }
+
+ DirectionalLight {
+ eulerRotation.x: -30
+ eulerRotation.y: -30
+ }
+
+ PerspectiveCamera {
+ id: theCamera
+ z: 600
+ y: 600
+ x: 600
+ eulerRotation.x: -45
+ eulerRotation.y: -45
+ clipFar: 10000
+ clipNear: 1
+ }
+}
diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5informationnodeinstanceserver.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5informationnodeinstanceserver.cpp
index 05f86ae4d3..8b6fe9f582 100644
--- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5informationnodeinstanceserver.cpp
+++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5informationnodeinstanceserver.cpp
@@ -533,37 +533,60 @@ void Qt5InformationNodeInstanceServer::doRenderModelNode3DImageView()
if (!m_ModelNode3DImageViewContentItem)
m_ModelNode3DImageViewContentItem = getContentItemForRendering(m_ModelNode3DImageViewRootItem);
- ServerNodeInstance instance = instanceForId(m_modelNodelPreviewImageCommand.instanceId());
- QObject *instanceObj = instance.internalObject();
- QSize renderSize = m_modelNodelPreviewImageCommand.size() * 2;
- QMetaObject::invokeMethod(m_ModelNode3DImageViewRootItem, "createViewForObject",
- Q_ARG(QVariant, objectToVariant(instanceObj)),
- Q_ARG(QVariant, QVariant::fromValue(renderSize.width())),
- Q_ARG(QVariant, QVariant::fromValue(renderSize.height())));
-
+ // Key number is selected so that it is unlikely to conflict other ImageContainer use.
+ auto imgContainer = ImageContainer(m_modelNodePreviewImageCommand.instanceId(), {}, 2100000001);
QImage renderImage;
- bool ready = false;
- int count = 0; // Ensure we don't ever get stuck in an infinite loop
- while (!ready && ++count < 10) {
- updateNodesRecursive(m_ModelNode3DImageViewContentItem);
-
- // Fake render loop signaling to update things like QML items as 3D textures
- m_ModelNode3DImageView->beforeSynchronizing();
- m_ModelNode3DImageView->beforeRendering();
-
- QSizeF size = qobject_cast<QQuickItem *>(m_ModelNode3DImageViewContentItem)->size();
- QRectF renderRect(QPointF(0., 0.), size);
- renderImage = designerSupport()->renderImageForItem(m_ModelNode3DImageViewContentItem,
- renderRect, size.toSize());
- m_ModelNode3DImageView->afterRendering();
-
- QMetaObject::invokeMethod(m_ModelNode3DImageViewRootItem, "afterRender");
- ready = QQmlProperty::read(m_ModelNode3DImageViewRootItem, "ready").value<bool>();
+ if (m_modelNodePreviewImageCache.contains(m_modelNodePreviewImageCommand.componentPath())) {
+ renderImage = m_modelNodePreviewImageCache[m_modelNodePreviewImageCommand.componentPath()];
+ } else {
+ QObject *instanceObj = nullptr;
+ if (!m_modelNodePreviewImageCommand.componentPath().isEmpty()) {
+ QQmlComponent *component = new QQmlComponent(engine());
+ component->loadUrl(QUrl::fromLocalFile(m_modelNodePreviewImageCommand.componentPath()));
+ instanceObj = qobject_cast<QQuick3DObject *>(component->create());
+ if (!instanceObj) {
+ qWarning() << "Could not create preview component: " << component->errors();
+ nodeInstanceClient()->handlePuppetToCreatorCommand({PuppetToCreatorCommand::RenderModelNodePreviewImage,
+ QVariant::fromValue(imgContainer)});
+ return;
+ }
+ } else {
+ ServerNodeInstance instance = instanceForId(m_modelNodePreviewImageCommand.instanceId());
+ instanceObj = instance.internalObject();
+ }
+ QSize renderSize = m_modelNodePreviewImageCommand.size() * 2;
+
+ QMetaObject::invokeMethod(m_ModelNode3DImageViewRootItem, "createViewForObject",
+ Q_ARG(QVariant, objectToVariant(instanceObj)),
+ Q_ARG(QVariant, QVariant::fromValue(renderSize.width())),
+ Q_ARG(QVariant, QVariant::fromValue(renderSize.height())));
+
+ bool ready = false;
+ int count = 0; // Ensure we don't ever get stuck in an infinite loop
+ while (!ready && ++count < 10) {
+ updateNodesRecursive(m_ModelNode3DImageViewContentItem);
+
+ // Fake render loop signaling to update things like QML items as 3D textures
+ m_ModelNode3DImageView->beforeSynchronizing();
+ m_ModelNode3DImageView->beforeRendering();
+
+ QSizeF size = qobject_cast<QQuickItem *>(m_ModelNode3DImageViewContentItem)->size();
+ QRectF renderRect(QPointF(0., 0.), size);
+ renderImage = designerSupport()->renderImageForItem(m_ModelNode3DImageViewContentItem,
+ renderRect, size.toSize());
+ m_ModelNode3DImageView->afterRendering();
+
+ QMetaObject::invokeMethod(m_ModelNode3DImageViewRootItem, "afterRender");
+ ready = QQmlProperty::read(m_ModelNode3DImageViewRootItem, "ready").value<bool>();
+ }
+ QMetaObject::invokeMethod(m_ModelNode3DImageViewRootItem, "destroyView");
+ if (!m_modelNodePreviewImageCommand.componentPath().isEmpty()) {
+ // If component changes, puppet will need a reset anyway, so we can cache the image
+ m_modelNodePreviewImageCache.insert(m_modelNodePreviewImageCommand.componentPath(), renderImage);
+ }
}
- QMetaObject::invokeMethod(m_ModelNode3DImageViewRootItem, "destroyView");
- // Key number is selected so that it is unlikely to conflict other ImageContainer use.
- auto imgContainer = ImageContainer(m_modelNodelPreviewImageCommand.instanceId(), renderImage, 2100000001);
+ imgContainer.setImage(renderImage);
// send the rendered image to creator process
nodeInstanceClient()->handlePuppetToCreatorCommand({PuppetToCreatorCommand::RenderModelNodePreviewImage,
@@ -1319,9 +1342,9 @@ void Qt5InformationNodeInstanceServer::view3DAction(const View3DActionCommand &c
void Qt5InformationNodeInstanceServer::requestModelNodePreviewImage(const RequestModelNodePreviewImageCommand &command)
{
- m_modelNodelPreviewImageCommand = command;
+ m_modelNodePreviewImageCommand = command;
- ServerNodeInstance instance = instanceForId(m_modelNodelPreviewImageCommand.instanceId());
+ ServerNodeInstance instance = instanceForId(m_modelNodePreviewImageCommand.instanceId());
if (instance.isSubclassOf("QQuick3DObject"))
renderModelNode3DImageView();
}
diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5informationnodeinstanceserver.h b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5informationnodeinstanceserver.h
index f85d974e0f..fa073231eb 100644
--- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5informationnodeinstanceserver.h
+++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5informationnodeinstanceserver.h
@@ -34,6 +34,7 @@
#include <QTimer>
#include <QVariant>
#include <QPointer>
+#include <QImage>
QT_BEGIN_NAMESPACE
class QDragMoveEvent;
@@ -126,7 +127,8 @@ private:
QPointer<QQuickView> m_ModelNode3DImageView;
QQuickItem *m_ModelNode3DImageViewRootItem = nullptr;
QQuickItem *m_ModelNode3DImageViewContentItem = nullptr;
- RequestModelNodePreviewImageCommand m_modelNodelPreviewImageCommand;
+ RequestModelNodePreviewImageCommand m_modelNodePreviewImageCommand;
+ QHash<QString, QImage> m_modelNodePreviewImageCache;
QSet<QObject *> m_view3Ds;
QMultiHash<QObject *, QObject *> m_3DSceneMap; // key: scene root, value: node
QObject *m_active3DView = nullptr;
diff --git a/share/qtcreator/qml/qmlpuppet/qmlpuppet.qrc b/share/qtcreator/qml/qmlpuppet/qmlpuppet.qrc
index 9b01f0249d..adbf6f58e8 100644
--- a/share/qtcreator/qml/qmlpuppet/qmlpuppet.qrc
+++ b/share/qtcreator/qml/qmlpuppet/qmlpuppet.qrc
@@ -44,6 +44,7 @@
<file>mockfiles/MaterialNodeView.qml</file>
<file>mockfiles/EffectNodeView.qml</file>
<file>mockfiles/ModelNodeView.qml</file>
+ <file>mockfiles/NodeNodeView.qml</file>
<file>mockfiles/meshes/arrow.mesh</file>
<file>mockfiles/meshes/scalerod.mesh</file>
<file>mockfiles/meshes/ring.mesh</file>