forked from qt-creator/qt-creator
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>
This commit is contained in:
@@ -32,9 +32,10 @@ namespace QmlDesigner {
|
|||||||
|
|
||||||
RequestModelNodePreviewImageCommand::RequestModelNodePreviewImageCommand() = default;
|
RequestModelNodePreviewImageCommand::RequestModelNodePreviewImageCommand() = default;
|
||||||
|
|
||||||
RequestModelNodePreviewImageCommand::RequestModelNodePreviewImageCommand(qint32 id, const QSize &size)
|
RequestModelNodePreviewImageCommand::RequestModelNodePreviewImageCommand(qint32 id, const QSize &size, const QString &componentPath)
|
||||||
: m_instanceId(id)
|
: m_instanceId(id)
|
||||||
, m_size(size)
|
, m_size(size)
|
||||||
|
, m_componentPath(componentPath)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -48,10 +49,16 @@ QSize QmlDesigner::RequestModelNodePreviewImageCommand::size() const
|
|||||||
return m_size;
|
return m_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString RequestModelNodePreviewImageCommand::componentPath() const
|
||||||
|
{
|
||||||
|
return m_componentPath;
|
||||||
|
}
|
||||||
|
|
||||||
QDataStream &operator<<(QDataStream &out, const RequestModelNodePreviewImageCommand &command)
|
QDataStream &operator<<(QDataStream &out, const RequestModelNodePreviewImageCommand &command)
|
||||||
{
|
{
|
||||||
out << int(command.instanceId());
|
out << int(command.instanceId());
|
||||||
out << command.size();
|
out << command.size();
|
||||||
|
out << command.componentPath();
|
||||||
|
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
@@ -60,6 +67,7 @@ QDataStream &operator>>(QDataStream &in, RequestModelNodePreviewImageCommand &co
|
|||||||
{
|
{
|
||||||
in >> command.m_instanceId;
|
in >> command.m_instanceId;
|
||||||
in >> command.m_size;
|
in >> command.m_size;
|
||||||
|
in >> command.m_componentPath;
|
||||||
return in;
|
return in;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -67,7 +75,8 @@ QDebug operator <<(QDebug debug, const RequestModelNodePreviewImageCommand &comm
|
|||||||
{
|
{
|
||||||
return debug.nospace() << "RequestModelNodePreviewImageCommand("
|
return debug.nospace() << "RequestModelNodePreviewImageCommand("
|
||||||
<< "instanceId: " << command.instanceId() << ", "
|
<< "instanceId: " << command.instanceId() << ", "
|
||||||
<< "size: " << command.size() << ")";
|
<< "size: " << command.size() << ", "
|
||||||
|
<< "componentPath: " << command.componentPath() << ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace QmlDesigner
|
} // namespace QmlDesigner
|
||||||
|
@@ -40,14 +40,16 @@ class RequestModelNodePreviewImageCommand
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
RequestModelNodePreviewImageCommand();
|
RequestModelNodePreviewImageCommand();
|
||||||
explicit RequestModelNodePreviewImageCommand(qint32 id, const QSize &size);
|
explicit RequestModelNodePreviewImageCommand(qint32 id, const QSize &size, const QString &componentPath);
|
||||||
|
|
||||||
qint32 instanceId() const;
|
qint32 instanceId() const;
|
||||||
QSize size() const;
|
QSize size() const;
|
||||||
|
QString componentPath() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
qint32 m_instanceId;
|
qint32 m_instanceId;
|
||||||
QSize m_size;
|
QSize m_size;
|
||||||
|
QString m_componentPath;
|
||||||
};
|
};
|
||||||
|
|
||||||
QDataStream &operator<<(QDataStream &out, const RequestModelNodePreviewImageCommand &command);
|
QDataStream &operator<<(QDataStream &out, const RequestModelNodePreviewImageCommand &command);
|
||||||
|
@@ -41,6 +41,7 @@ Item {
|
|||||||
property var materialViewComponent
|
property var materialViewComponent
|
||||||
property var effectViewComponent
|
property var effectViewComponent
|
||||||
property var modelViewComponent
|
property var modelViewComponent
|
||||||
|
property var nodeViewComponent
|
||||||
|
|
||||||
property bool ready: false
|
property bool ready: false
|
||||||
|
|
||||||
@@ -65,6 +66,8 @@ Item {
|
|||||||
createViewForEffect(obj);
|
createViewForEffect(obj);
|
||||||
else if (obj instanceof Model)
|
else if (obj instanceof Model)
|
||||||
createViewForModel(obj);
|
createViewForModel(obj);
|
||||||
|
else if (obj instanceof Node)
|
||||||
|
createViewForNode(obj);
|
||||||
|
|
||||||
previewObject = obj;
|
previewObject = obj;
|
||||||
}
|
}
|
||||||
@@ -99,10 +102,20 @@ Item {
|
|||||||
view = modelViewComponent.createObject(viewRect, {"sourceModel": model});
|
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()
|
function afterRender()
|
||||||
{
|
{
|
||||||
if (previewObject instanceof Model) {
|
if (previewObject instanceof Node) {
|
||||||
view.fitModel();
|
view.fitToViewPort();
|
||||||
ready = view.ready;
|
ready = view.ready;
|
||||||
} else {
|
} else {
|
||||||
ready = true;
|
ready = true;
|
||||||
|
@@ -36,7 +36,7 @@ View3D {
|
|||||||
property real prevZoomFactor: -1
|
property real prevZoomFactor: -1
|
||||||
property Model sourceModel
|
property Model sourceModel
|
||||||
|
|
||||||
function fitModel()
|
function fitToViewPort()
|
||||||
{
|
{
|
||||||
cameraControl.focusObject(model, theCamera.eulerRotation, true, false);
|
cameraControl.focusObject(model, theCamera.eulerRotation, true, false);
|
||||||
|
|
||||||
|
96
share/qtcreator/qml/qmlpuppet/mockfiles/NodeNodeView.qml
Normal file
96
share/qtcreator/qml/qmlpuppet/mockfiles/NodeNodeView.qml
Normal file
@@ -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
|
||||||
|
}
|
||||||
|
}
|
@@ -533,37 +533,60 @@ void Qt5InformationNodeInstanceServer::doRenderModelNode3DImageView()
|
|||||||
if (!m_ModelNode3DImageViewContentItem)
|
if (!m_ModelNode3DImageViewContentItem)
|
||||||
m_ModelNode3DImageViewContentItem = getContentItemForRendering(m_ModelNode3DImageViewRootItem);
|
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())));
|
|
||||||
|
|
||||||
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>();
|
|
||||||
}
|
|
||||||
QMetaObject::invokeMethod(m_ModelNode3DImageViewRootItem, "destroyView");
|
|
||||||
|
|
||||||
// Key number is selected so that it is unlikely to conflict other ImageContainer use.
|
// Key number is selected so that it is unlikely to conflict other ImageContainer use.
|
||||||
auto imgContainer = ImageContainer(m_modelNodelPreviewImageCommand.instanceId(), renderImage, 2100000001);
|
auto imgContainer = ImageContainer(m_modelNodePreviewImageCommand.instanceId(), {}, 2100000001);
|
||||||
|
QImage renderImage;
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
imgContainer.setImage(renderImage);
|
||||||
|
|
||||||
// send the rendered image to creator process
|
// send the rendered image to creator process
|
||||||
nodeInstanceClient()->handlePuppetToCreatorCommand({PuppetToCreatorCommand::RenderModelNodePreviewImage,
|
nodeInstanceClient()->handlePuppetToCreatorCommand({PuppetToCreatorCommand::RenderModelNodePreviewImage,
|
||||||
@@ -1319,9 +1342,9 @@ void Qt5InformationNodeInstanceServer::view3DAction(const View3DActionCommand &c
|
|||||||
|
|
||||||
void Qt5InformationNodeInstanceServer::requestModelNodePreviewImage(const RequestModelNodePreviewImageCommand &command)
|
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"))
|
if (instance.isSubclassOf("QQuick3DObject"))
|
||||||
renderModelNode3DImageView();
|
renderModelNode3DImageView();
|
||||||
}
|
}
|
||||||
|
@@ -34,6 +34,7 @@
|
|||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
#include <QVariant>
|
#include <QVariant>
|
||||||
#include <QPointer>
|
#include <QPointer>
|
||||||
|
#include <QImage>
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
class QDragMoveEvent;
|
class QDragMoveEvent;
|
||||||
@@ -126,7 +127,8 @@ private:
|
|||||||
QPointer<QQuickView> m_ModelNode3DImageView;
|
QPointer<QQuickView> m_ModelNode3DImageView;
|
||||||
QQuickItem *m_ModelNode3DImageViewRootItem = nullptr;
|
QQuickItem *m_ModelNode3DImageViewRootItem = nullptr;
|
||||||
QQuickItem *m_ModelNode3DImageViewContentItem = nullptr;
|
QQuickItem *m_ModelNode3DImageViewContentItem = nullptr;
|
||||||
RequestModelNodePreviewImageCommand m_modelNodelPreviewImageCommand;
|
RequestModelNodePreviewImageCommand m_modelNodePreviewImageCommand;
|
||||||
|
QHash<QString, QImage> m_modelNodePreviewImageCache;
|
||||||
QSet<QObject *> m_view3Ds;
|
QSet<QObject *> m_view3Ds;
|
||||||
QMultiHash<QObject *, QObject *> m_3DSceneMap; // key: scene root, value: node
|
QMultiHash<QObject *, QObject *> m_3DSceneMap; // key: scene root, value: node
|
||||||
QObject *m_active3DView = nullptr;
|
QObject *m_active3DView = nullptr;
|
||||||
|
@@ -44,6 +44,7 @@
|
|||||||
<file>mockfiles/MaterialNodeView.qml</file>
|
<file>mockfiles/MaterialNodeView.qml</file>
|
||||||
<file>mockfiles/EffectNodeView.qml</file>
|
<file>mockfiles/EffectNodeView.qml</file>
|
||||||
<file>mockfiles/ModelNodeView.qml</file>
|
<file>mockfiles/ModelNodeView.qml</file>
|
||||||
|
<file>mockfiles/NodeNodeView.qml</file>
|
||||||
<file>mockfiles/meshes/arrow.mesh</file>
|
<file>mockfiles/meshes/arrow.mesh</file>
|
||||||
<file>mockfiles/meshes/scalerod.mesh</file>
|
<file>mockfiles/meshes/scalerod.mesh</file>
|
||||||
<file>mockfiles/meshes/ring.mesh</file>
|
<file>mockfiles/meshes/ring.mesh</file>
|
||||||
|
@@ -207,42 +207,31 @@ QMultiHash<TypeName, ModelNodePreviewImageHandler> DesignerActionManager::modelN
|
|||||||
void DesignerActionManager::registerModelNodePreviewHandler(const ModelNodePreviewImageHandler &handler)
|
void DesignerActionManager::registerModelNodePreviewHandler(const ModelNodePreviewImageHandler &handler)
|
||||||
{
|
{
|
||||||
m_modelNodePreviewImageHandlers.insert(handler.type, handler);
|
m_modelNodePreviewImageHandlers.insert(handler.type, handler);
|
||||||
|
|
||||||
// Registering a new handler potentially invalidates no-handler set
|
|
||||||
m_noModelNodePreviewImageHandlers.clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DesignerActionManager::hasModelNodePreviewHandler(const ModelNode &node) const
|
bool DesignerActionManager::hasModelNodePreviewHandler(const ModelNode &node) const
|
||||||
{
|
{
|
||||||
if (m_modelNodePreviewImageHandlers.contains(node.type()))
|
const bool isComponent = node.isComponent();
|
||||||
return true;
|
|
||||||
|
|
||||||
if (m_noModelNodePreviewImageHandlers.contains(node.type()))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// Node may be a subclass of a registered type
|
|
||||||
for (const auto &handler : qAsConst(m_modelNodePreviewImageHandlers)) {
|
for (const auto &handler : qAsConst(m_modelNodePreviewImageHandlers)) {
|
||||||
if (node.isSubclassOf(handler.type)) {
|
if ((isComponent || !handler.componentOnly) && node.isSubclassOf(handler.type)) {
|
||||||
ModelNodePreviewImageHandler subClassHandler = handler;
|
ModelNodePreviewImageHandler subClassHandler = handler;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_noModelNodePreviewImageHandlers.insert(node.type());
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
ModelNodePreviewImageOperation DesignerActionManager::modelNodePreviewOperation(const ModelNode &node) const
|
ModelNodePreviewImageOperation DesignerActionManager::modelNodePreviewOperation(const ModelNode &node) const
|
||||||
{
|
{
|
||||||
ModelNodePreviewImageOperation op = nullptr;
|
ModelNodePreviewImageOperation op = nullptr;
|
||||||
if (!m_noModelNodePreviewImageHandlers.contains(node.type())) {
|
int prio = -1;
|
||||||
int prio = -1;
|
const bool isComponent = node.isComponent();
|
||||||
for (const auto &handler : qAsConst(m_modelNodePreviewImageHandlers)) {
|
for (const auto &handler : qAsConst(m_modelNodePreviewImageHandlers)) {
|
||||||
if (node.isSubclassOf(handler.type) && handler.priority > prio)
|
if ((isComponent || !handler.componentOnly) && handler.priority > prio
|
||||||
op = handler.operation;
|
&& node.isSubclassOf(handler.type)) {
|
||||||
|
op = handler.operation;
|
||||||
|
prio = handler.priority;
|
||||||
}
|
}
|
||||||
if (!op)
|
|
||||||
m_noModelNodePreviewImageHandlers.insert(node.type());
|
|
||||||
}
|
}
|
||||||
return op;
|
return op;
|
||||||
}
|
}
|
||||||
@@ -1415,6 +1404,10 @@ void DesignerActionManager::createDefaultModelNodePreviewImageHandlers()
|
|||||||
registerModelNodePreviewHandler(
|
registerModelNodePreviewHandler(
|
||||||
ModelNodePreviewImageHandler("QtQuick3D.Model",
|
ModelNodePreviewImageHandler("QtQuick3D.Model",
|
||||||
ModelNodeOperations::previewImageDataFor3DNode));
|
ModelNodeOperations::previewImageDataFor3DNode));
|
||||||
|
registerModelNodePreviewHandler(
|
||||||
|
ModelNodePreviewImageHandler("QtQuick3D.Node",
|
||||||
|
ModelNodeOperations::previewImageDataFor3DNode,
|
||||||
|
true));
|
||||||
|
|
||||||
// TODO - Disabled until QTBUG-86616 is fixed
|
// TODO - Disabled until QTBUG-86616 is fixed
|
||||||
// registerModelNodePreviewHandler(
|
// registerModelNodePreviewHandler(
|
||||||
|
@@ -72,15 +72,18 @@ struct ModelNodePreviewImageHandler
|
|||||||
public:
|
public:
|
||||||
ModelNodePreviewImageHandler(const TypeName &t,
|
ModelNodePreviewImageHandler(const TypeName &t,
|
||||||
ModelNodePreviewImageOperation op,
|
ModelNodePreviewImageOperation op,
|
||||||
|
bool compOnly = false,
|
||||||
int prio = 0)
|
int prio = 0)
|
||||||
: type(t)
|
: type(t)
|
||||||
, operation(op)
|
, operation(op)
|
||||||
|
, componentOnly(compOnly)
|
||||||
, priority(prio)
|
, priority(prio)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
TypeName type;
|
TypeName type;
|
||||||
ModelNodePreviewImageOperation operation = nullptr;
|
ModelNodePreviewImageOperation operation = nullptr;
|
||||||
|
bool componentOnly = false;
|
||||||
int priority = 0;
|
int priority = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -137,7 +140,6 @@ private:
|
|||||||
DesignerActionManagerView *m_designerActionManagerView;
|
DesignerActionManagerView *m_designerActionManagerView;
|
||||||
QList<AddResourceHandler> m_addResourceHandler;
|
QList<AddResourceHandler> m_addResourceHandler;
|
||||||
QMultiHash<TypeName, ModelNodePreviewImageHandler> m_modelNodePreviewImageHandlers;
|
QMultiHash<TypeName, ModelNodePreviewImageHandler> m_modelNodePreviewImageHandlers;
|
||||||
mutable QSet<TypeName> m_noModelNodePreviewImageHandlers;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} //QmlDesigner
|
} //QmlDesigner
|
||||||
|
@@ -46,6 +46,7 @@
|
|||||||
#include <nodelistproperty.h>
|
#include <nodelistproperty.h>
|
||||||
#include <nodeproperty.h>
|
#include <nodeproperty.h>
|
||||||
#include <signalhandlerproperty.h>
|
#include <signalhandlerproperty.h>
|
||||||
|
#include <nodeinstanceview.h>
|
||||||
|
|
||||||
#include <componentcore_constants.h>
|
#include <componentcore_constants.h>
|
||||||
#include <stylesheetmerger.h>
|
#include <stylesheetmerger.h>
|
||||||
@@ -1521,14 +1522,14 @@ void removeGroup(const SelectionContext &selectionContext)
|
|||||||
QVariant previewImageDataFor3DNode(const ModelNode &modelNode)
|
QVariant previewImageDataFor3DNode(const ModelNode &modelNode)
|
||||||
{
|
{
|
||||||
if (modelNode.isValid())
|
if (modelNode.isValid())
|
||||||
return modelNode.model()->previewImageDataFor3DNode(modelNode);
|
return modelNode.model()->nodeInstanceView()->previewImageDataFor3DNode(modelNode);
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
QVariant previewImageDataForImageNode(const ModelNode &modelNode)
|
QVariant previewImageDataForImageNode(const ModelNode &modelNode)
|
||||||
{
|
{
|
||||||
if (modelNode.isValid())
|
if (modelNode.isValid())
|
||||||
return modelNode.model()->previewImageDataForImageNode(modelNode);
|
return modelNode.model()->nodeInstanceView()->previewImageDataForImageNode(modelNode);
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -118,9 +118,6 @@ public:
|
|||||||
|
|
||||||
QList<ModelNode> selectedNodes(AbstractView *view) const;
|
QList<ModelNode> selectedNodes(AbstractView *view) const;
|
||||||
|
|
||||||
QVariant previewImageDataFor3DNode(const ModelNode &modelNode);
|
|
||||||
QVariant previewImageDataForImageNode(const ModelNode &modelNode);
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Model();
|
Model();
|
||||||
|
|
||||||
|
@@ -143,6 +143,9 @@ public:
|
|||||||
|
|
||||||
void handlePuppetToCreatorCommand(const PuppetToCreatorCommand &command) override;
|
void handlePuppetToCreatorCommand(const PuppetToCreatorCommand &command) override;
|
||||||
|
|
||||||
|
QVariant previewImageDataFor3DNode(const ModelNode &modelNode);
|
||||||
|
QVariant previewImageDataForImageNode(const ModelNode &modelNode);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void timerEvent(QTimerEvent *event) override;
|
void timerEvent(QTimerEvent *event) override;
|
||||||
|
|
||||||
@@ -201,6 +204,8 @@ private: // functions
|
|||||||
// puppet to creator command handlers
|
// puppet to creator command handlers
|
||||||
void handlePuppetKeyPress(int key, Qt::KeyboardModifiers modifiers);
|
void handlePuppetKeyPress(int key, Qt::KeyboardModifiers modifiers);
|
||||||
|
|
||||||
|
void updatePreviewImageForNode(const ModelNode &modelNode, const QImage &image);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
NodeInstance m_rootNodeInstance;
|
NodeInstance m_rootNodeInstance;
|
||||||
NodeInstance m_activeStateInstance;
|
NodeInstance m_activeStateInstance;
|
||||||
|
@@ -1495,7 +1495,7 @@ void NodeInstanceView::handlePuppetToCreatorCommand(const PuppetToCreatorCommand
|
|||||||
auto node = modelNodeForInternalId(container.instanceId());
|
auto node = modelNodeForInternalId(container.instanceId());
|
||||||
if (node.isValid()) {
|
if (node.isValid()) {
|
||||||
image.setDevicePixelRatio(2.);
|
image.setDevicePixelRatio(2.);
|
||||||
emitModelNodelPreviewImageChanged(node, image);
|
updatePreviewImageForNode(node, image);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1527,11 +1527,15 @@ void NodeInstanceView::requestModelNodePreviewImage(const ModelNode &node)
|
|||||||
if (node.isValid()) {
|
if (node.isValid()) {
|
||||||
auto instance = instanceForModelNode(node);
|
auto instance = instanceForModelNode(node);
|
||||||
if (instance.isValid()) {
|
if (instance.isValid()) {
|
||||||
|
QString componentPath;
|
||||||
|
if (node.isComponent())
|
||||||
|
componentPath = node.metaInfo().componentFileName();
|
||||||
m_nodeInstanceServer->requestModelNodePreviewImage(
|
m_nodeInstanceServer->requestModelNodePreviewImage(
|
||||||
RequestModelNodePreviewImageCommand(
|
RequestModelNodePreviewImageCommand(
|
||||||
instance.instanceId(),
|
instance.instanceId(),
|
||||||
QSize(Constants::MODELNODE_PREVIEW_IMAGE_DIMENSIONS,
|
QSize(Constants::MODELNODE_PREVIEW_IMAGE_DIMENSIONS,
|
||||||
Constants::MODELNODE_PREVIEW_IMAGE_DIMENSIONS)));
|
Constants::MODELNODE_PREVIEW_IMAGE_DIMENSIONS),
|
||||||
|
componentPath));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1547,4 +1551,113 @@ void NodeInstanceView::timerEvent(QTimerEvent *event)
|
|||||||
restartProcess();
|
restartProcess();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct ImageData {
|
||||||
|
QDateTime time;
|
||||||
|
QImage image;
|
||||||
|
QString type;
|
||||||
|
QString id;
|
||||||
|
QString info;
|
||||||
|
};
|
||||||
|
static QHash<QString, QHash<QString, ImageData>> imageDataMap;
|
||||||
|
|
||||||
|
static QVariant imageDataToVariant(const ImageData &imageData)
|
||||||
|
{
|
||||||
|
if (!imageData.image.isNull()) {
|
||||||
|
QVariantMap map;
|
||||||
|
map.insert("type", imageData.type);
|
||||||
|
map.insert("image", QVariant::fromValue<QImage>(imageData.image));
|
||||||
|
map.insert("id", imageData.id);
|
||||||
|
map.insert("info", imageData.info);
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant NodeInstanceView::previewImageDataForImageNode(const ModelNode &modelNode)
|
||||||
|
{
|
||||||
|
if (!modelNode.isValid())
|
||||||
|
return {};
|
||||||
|
|
||||||
|
// Images on file system can be cached globally as they are found by absolute paths
|
||||||
|
QHash<QString, ImageData> &localDataMap = imageDataMap[{}];
|
||||||
|
|
||||||
|
VariantProperty prop = modelNode.variantProperty("source");
|
||||||
|
QString imageSource = prop.value().toString();
|
||||||
|
QFileInfo imageFi(imageSource);
|
||||||
|
if (imageFi.isRelative())
|
||||||
|
imageSource = QFileInfo(modelNode.model()->fileUrl().toLocalFile()).dir().absoluteFilePath(imageSource);
|
||||||
|
|
||||||
|
imageFi = QFileInfo(imageSource);
|
||||||
|
QDateTime modified = imageFi.lastModified();
|
||||||
|
|
||||||
|
ImageData imageData;
|
||||||
|
bool reload = true;
|
||||||
|
if (localDataMap.contains(imageSource)) {
|
||||||
|
imageData = localDataMap[imageSource];
|
||||||
|
if (modified == imageData.time)
|
||||||
|
reload = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (reload) {
|
||||||
|
QImage originalImage;
|
||||||
|
originalImage.load(imageSource);
|
||||||
|
if (!originalImage.isNull()) {
|
||||||
|
imageData.image = originalImage.scaled(Constants::MODELNODE_PREVIEW_IMAGE_DIMENSIONS * 2,
|
||||||
|
Constants::MODELNODE_PREVIEW_IMAGE_DIMENSIONS * 2,
|
||||||
|
Qt::KeepAspectRatio);
|
||||||
|
imageData.image.setDevicePixelRatio(2.);
|
||||||
|
|
||||||
|
double imgSize = double(imageFi.size());
|
||||||
|
imageData.type = QStringLiteral("%1 (%2)").arg(QString::fromLatin1(modelNode.type())).arg(imageFi.suffix());
|
||||||
|
imageData.id = modelNode.id();
|
||||||
|
static QStringList units({QObject::tr("B"), QObject::tr("KB"), QObject::tr("MB"), QObject::tr("GB")});
|
||||||
|
int unitIndex = 0;
|
||||||
|
while (imgSize > 1024. && unitIndex < units.size() - 1) {
|
||||||
|
++unitIndex;
|
||||||
|
imgSize /= 1024.;
|
||||||
|
}
|
||||||
|
imageData.info = QStringLiteral("%1 x %2 (%3%4)").arg(originalImage.width()).arg(originalImage.height())
|
||||||
|
.arg(QString::number(imgSize, 'g', 3)).arg(units[unitIndex]);
|
||||||
|
localDataMap.insert(imageSource, imageData);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return imageDataToVariant(imageData);
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant NodeInstanceView::previewImageDataFor3DNode(const ModelNode &modelNode)
|
||||||
|
{
|
||||||
|
QFileInfo docFi = QFileInfo(modelNode.model()->fileUrl().toLocalFile());
|
||||||
|
QHash<QString, ImageData> &localDataMap = imageDataMap[docFi.absoluteFilePath()];
|
||||||
|
ImageData imageData;
|
||||||
|
static const QImage placeHolder(":/navigator/icon/tooltip_placeholder.png");
|
||||||
|
|
||||||
|
// We need puppet to generate the image, which needs to be asynchronous.
|
||||||
|
// Until the image is ready, we show a placeholder
|
||||||
|
const QString id = modelNode.id();
|
||||||
|
if (localDataMap.contains(id)) {
|
||||||
|
imageData = localDataMap[id];
|
||||||
|
} else {
|
||||||
|
imageData.type = QString::fromLatin1(modelNode.type());
|
||||||
|
imageData.id = id;
|
||||||
|
imageData.image = placeHolder;
|
||||||
|
localDataMap.insert(id, imageData);
|
||||||
|
}
|
||||||
|
requestModelNodePreviewImage(modelNode);
|
||||||
|
|
||||||
|
return imageDataToVariant(imageData);
|
||||||
|
}
|
||||||
|
|
||||||
|
void NodeInstanceView::updatePreviewImageForNode(const ModelNode &modelNode, const QImage &image)
|
||||||
|
{
|
||||||
|
QFileInfo docFi = QFileInfo(modelNode.model()->fileUrl().toLocalFile());
|
||||||
|
QString docPath = docFi.absoluteFilePath();
|
||||||
|
if (imageDataMap.contains(docPath)) {
|
||||||
|
QHash<QString, ImageData> &localDataMap = imageDataMap[docPath];
|
||||||
|
if (localDataMap.contains(modelNode.id()))
|
||||||
|
localDataMap[modelNode.id()].image = image;
|
||||||
|
}
|
||||||
|
emitModelNodelPreviewImageChanged(modelNode, image);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -26,7 +26,6 @@
|
|||||||
#include "model.h"
|
#include "model.h"
|
||||||
#include "model_p.h"
|
#include "model_p.h"
|
||||||
#include <modelnode.h>
|
#include <modelnode.h>
|
||||||
#include <qmldesignerconstants.h>
|
|
||||||
#include "internalnode_p.h"
|
#include "internalnode_p.h"
|
||||||
#include "invalidpropertyexception.h"
|
#include "invalidpropertyexception.h"
|
||||||
#include "invalidargumentexception.h"
|
#include "invalidargumentexception.h"
|
||||||
@@ -286,111 +285,6 @@ void ModelPrivate::removeNodeFromModel(const InternalNodePointer &internalNodePo
|
|||||||
m_internalIdNodeHash.remove(internalNodePointer->internalId());
|
m_internalIdNodeHash.remove(internalNodePointer->internalId());
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ImageData {
|
|
||||||
QDateTime time;
|
|
||||||
QImage image;
|
|
||||||
QString type;
|
|
||||||
QString id;
|
|
||||||
QString info;
|
|
||||||
};
|
|
||||||
static QHash<QString, QHash<QString, ImageData>> imageDataMap;
|
|
||||||
|
|
||||||
static QVariant imageDataToVariant(const ImageData &imageData)
|
|
||||||
{
|
|
||||||
if (!imageData.image.isNull()) {
|
|
||||||
QVariantMap map;
|
|
||||||
map.insert("type", imageData.type);
|
|
||||||
map.insert("image", QVariant::fromValue<QImage>(imageData.image));
|
|
||||||
map.insert("id", imageData.id);
|
|
||||||
map.insert("info", imageData.info);
|
|
||||||
return map;
|
|
||||||
}
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
QVariant ModelPrivate::previewImageDataForImageNode(const ModelNode &modelNode)
|
|
||||||
{
|
|
||||||
// Images on file system can be cached globally as they are found by absolute paths
|
|
||||||
QHash<QString, ImageData> &localDataMap = imageDataMap[{}];
|
|
||||||
|
|
||||||
VariantProperty prop = modelNode.variantProperty("source");
|
|
||||||
QString imageSource = prop.value().toString();
|
|
||||||
QFileInfo imageFi(imageSource);
|
|
||||||
if (imageFi.isRelative())
|
|
||||||
imageSource = QFileInfo(m_fileUrl.toLocalFile()).dir().absoluteFilePath(imageSource);
|
|
||||||
|
|
||||||
imageFi = QFileInfo(imageSource);
|
|
||||||
QDateTime modified = imageFi.lastModified();
|
|
||||||
|
|
||||||
ImageData imageData;
|
|
||||||
bool reload = true;
|
|
||||||
if (localDataMap.contains(imageSource)) {
|
|
||||||
imageData = localDataMap[imageSource];
|
|
||||||
if (modified == imageData.time)
|
|
||||||
reload = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (reload) {
|
|
||||||
QImage originalImage;
|
|
||||||
originalImage.load(imageSource);
|
|
||||||
if (!originalImage.isNull()) {
|
|
||||||
imageData.image = originalImage.scaled(Constants::MODELNODE_PREVIEW_IMAGE_DIMENSIONS * 2,
|
|
||||||
Constants::MODELNODE_PREVIEW_IMAGE_DIMENSIONS * 2,
|
|
||||||
Qt::KeepAspectRatio);
|
|
||||||
imageData.image.setDevicePixelRatio(2.);
|
|
||||||
|
|
||||||
double imgSize = double(imageFi.size());
|
|
||||||
imageData.type = QStringLiteral("%1 (%2)").arg(QString::fromLatin1(modelNode.type())).arg(imageFi.suffix());
|
|
||||||
imageData.id = modelNode.id();
|
|
||||||
static QStringList units({QObject::tr("B"), QObject::tr("KB"), QObject::tr("MB"), QObject::tr("GB")});
|
|
||||||
int unitIndex = 0;
|
|
||||||
while (imgSize > 1024. && unitIndex < units.size() - 1) {
|
|
||||||
++unitIndex;
|
|
||||||
imgSize /= 1024.;
|
|
||||||
}
|
|
||||||
imageData.info = QStringLiteral("%1 x %2 (%3%4)").arg(originalImage.width()).arg(originalImage.height())
|
|
||||||
.arg(QString::number(imgSize, 'g', 3)).arg(units[unitIndex]);
|
|
||||||
localDataMap.insert(imageSource, imageData);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return imageDataToVariant(imageData);
|
|
||||||
}
|
|
||||||
|
|
||||||
QVariant ModelPrivate::previewImageDataFor3DNode(const ModelNode &modelNode)
|
|
||||||
{
|
|
||||||
QFileInfo docFi = QFileInfo(m_fileUrl.toLocalFile());
|
|
||||||
QHash<QString, Internal::ImageData> &localDataMap = Internal::imageDataMap[docFi.absoluteFilePath()];
|
|
||||||
Internal::ImageData imageData;
|
|
||||||
static const QImage placeHolder(":/navigator/icon/tooltip_placeholder.png");
|
|
||||||
|
|
||||||
// We need puppet to generate the image, which needs to be asynchronous.
|
|
||||||
// Until the image is ready, we show a placeholder
|
|
||||||
const QString id = modelNode.id();
|
|
||||||
if (localDataMap.contains(id)) {
|
|
||||||
imageData = localDataMap[id];
|
|
||||||
} else {
|
|
||||||
imageData.type = QString::fromLatin1(modelNode.type());
|
|
||||||
imageData.id = id;
|
|
||||||
imageData.image = placeHolder;
|
|
||||||
localDataMap.insert(id, imageData);
|
|
||||||
}
|
|
||||||
modelNode.model()->nodeInstanceView()->requestModelNodePreviewImage(modelNode);
|
|
||||||
|
|
||||||
return imageDataToVariant(imageData);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ModelPrivate::updatePreviewImageForNode(const ModelNode &modelNode, const QImage &image)
|
|
||||||
{
|
|
||||||
QFileInfo docFi = QFileInfo(m_fileUrl.toLocalFile());
|
|
||||||
QString docPath = docFi.absoluteFilePath();
|
|
||||||
if (imageDataMap.contains(docPath)) {
|
|
||||||
QHash<QString, ImageData> &localDataMap = imageDataMap[docPath];
|
|
||||||
if (localDataMap.contains(modelNode.id()))
|
|
||||||
localDataMap[modelNode.id()].image = image;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ModelPrivate::removeAllSubNodes(const InternalNode::Pointer &internalNodePointer)
|
void ModelPrivate::removeAllSubNodes(const InternalNode::Pointer &internalNodePointer)
|
||||||
{
|
{
|
||||||
foreach (const InternalNodePointer &subNode, internalNodePointer->allSubNodes()) {
|
foreach (const InternalNodePointer &subNode, internalNodePointer->allSubNodes()) {
|
||||||
@@ -808,8 +702,6 @@ void ModelPrivate::notifyUpdateActiveScene3D(const QVariantMap &sceneState)
|
|||||||
|
|
||||||
void ModelPrivate::notifyModelNodePreviewImageChanged(const ModelNode &node, const QImage &image)
|
void ModelPrivate::notifyModelNodePreviewImageChanged(const ModelNode &node, const QImage &image)
|
||||||
{
|
{
|
||||||
updatePreviewImageForNode(node, image);
|
|
||||||
|
|
||||||
for (const QPointer<AbstractView> &view : qAsConst(m_viewList)) {
|
for (const QPointer<AbstractView> &view : qAsConst(m_viewList)) {
|
||||||
Q_ASSERT(view != nullptr);
|
Q_ASSERT(view != nullptr);
|
||||||
view->modelNodePreviewImageChanged(node, image);
|
view->modelNodePreviewImageChanged(node, image);
|
||||||
@@ -2183,16 +2075,6 @@ QList<ModelNode> Model::selectedNodes(AbstractView *view) const
|
|||||||
return d->toModelNodeList(d->selectedNodes(), view);
|
return d->toModelNodeList(d->selectedNodes(), view);
|
||||||
}
|
}
|
||||||
|
|
||||||
QVariant Model::previewImageDataFor3DNode(const ModelNode &modelNode)
|
|
||||||
{
|
|
||||||
return d->previewImageDataFor3DNode(modelNode);
|
|
||||||
}
|
|
||||||
|
|
||||||
QVariant Model::previewImageDataForImageNode(const ModelNode &modelNode)
|
|
||||||
{
|
|
||||||
return d->previewImageDataForImageNode(modelNode);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\brief Returns the URL against which relative URLs within the model should be resolved.
|
\brief Returns the URL against which relative URLs within the model should be resolved.
|
||||||
\return The base URL.
|
\return The base URL.
|
||||||
|
@@ -243,10 +243,6 @@ private: //functions
|
|||||||
QVector<ModelNode> toModelNodeVector(const QVector<InternalNodePointer> &internalNodeVector, AbstractView *view) const;
|
QVector<ModelNode> toModelNodeVector(const QVector<InternalNodePointer> &internalNodeVector, AbstractView *view) const;
|
||||||
QVector<InternalNodePointer> toInternalNodeVector(const QVector<ModelNode> &internalNodeVector) const;
|
QVector<InternalNodePointer> toInternalNodeVector(const QVector<ModelNode> &internalNodeVector) const;
|
||||||
|
|
||||||
QVariant previewImageDataFor3DNode(const ModelNode &modelNode);
|
|
||||||
QVariant previewImageDataForImageNode(const ModelNode &modelNode);
|
|
||||||
void updatePreviewImageForNode(const ModelNode &modelNode, const QImage &image);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Model *m_q;
|
Model *m_q;
|
||||||
MetaInfo m_metaInfo;
|
MetaInfo m_metaInfo;
|
||||||
|
Reference in New Issue
Block a user