From 36a8b8ad99e3cb7ac5b577617016824b40d37799 Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Thu, 24 Sep 2020 10:56:02 +0300 Subject: [PATCH] QmlDesigner: Add navigator tooltip for 2D components This enables showing preview tooltip for 2D (Item based) components. We render the component from scratch for this purpose instead of using existing renders done for form editor to ensure preview doesn't include any local changes to component. Also cache tooltips as QPixmaps in NodeInstanceView instead of QImages to avoid unnecessary image to pixmap conversions when using cached data. Change-Id: I3082c5c846f605a765a81408767266d1ff7a12d7 Fixes: QDS-2762 Reviewed-by: Thomas Hartmann Reviewed-by: Mahmoud Badri --- .../mockfiles/ModelNode2DImageView.qml | 39 +++ .../qt5informationnodeinstanceserver.cpp | 224 ++++++++++++------ .../qt5informationnodeinstanceserver.h | 11 +- share/qtcreator/qml/qmlpuppet/qmlpuppet.qrc | 1 + .../componentcore/designeractionmanager.cpp | 10 +- .../componentcore/modelnodeoperations.cpp | 4 +- .../componentcore/modelnodeoperations.h | 2 +- .../navigator/navigatortreemodel.cpp | 5 +- .../components/navigator/navigatortreemodel.h | 6 +- .../navigator/navigatortreeview.cpp | 8 +- .../components/navigator/navigatorview.cpp | 6 +- .../components/navigator/navigatorview.h | 4 +- .../components/navigator/previewtooltip.cpp | 4 +- .../components/navigator/previewtooltip.h | 4 +- .../designercore/include/abstractview.h | 5 +- .../designercore/include/nodeinstanceview.h | 2 +- .../instances/nodeinstanceview.cpp | 33 +-- .../designercore/model/abstractview.cpp | 6 +- .../qmldesigner/designercore/model/model.cpp | 4 +- .../qmldesigner/designercore/model/model_p.h | 3 +- 20 files changed, 262 insertions(+), 119 deletions(-) create mode 100644 share/qtcreator/qml/qmlpuppet/mockfiles/ModelNode2DImageView.qml diff --git a/share/qtcreator/qml/qmlpuppet/mockfiles/ModelNode2DImageView.qml b/share/qtcreator/qml/qmlpuppet/mockfiles/ModelNode2DImageView.qml new file mode 100644 index 00000000000..c4bd31d7e7e --- /dev/null +++ b/share/qtcreator/qml/qmlpuppet/mockfiles/ModelNode2DImageView.qml @@ -0,0 +1,39 @@ +/**************************************************************************** +** +** 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 + +Item { + id: root + width: 150 + height: 150 + + property alias contentItem: contentItem + + Item { + id: contentItem + anchors.fill: parent + } +} diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5informationnodeinstanceserver.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5informationnodeinstanceserver.cpp index 8d0d175453e..944bb63c548 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5informationnodeinstanceserver.cpp +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5informationnodeinstanceserver.cpp @@ -101,6 +101,26 @@ static QVariant objectToVariant(QObject *object) return QVariant::fromValue(object); } +QQuickView *Qt5InformationNodeInstanceServer::createAuxiliaryQuickView(const QUrl &url, + QQuickItem *&rootItem) +{ + auto view = new QQuickView(quickView()->engine(), quickView()); + view->setFormat(quickView()->format()); + DesignerSupport::createOpenGLContext(view); + QQmlComponent component(engine()); + component.loadUrl(url); + rootItem = qobject_cast(component.create()); + + if (!rootItem) { + qWarning() << "Could not create view for: " << url.toString() << component.errors(); + return nullptr; + } + + DesignerSupport::setRootItem(view, rootItem); + + return view; +} + void Qt5InformationNodeInstanceServer::createEditView3D() { #ifdef QUICK3D_MODULE @@ -120,58 +140,26 @@ void Qt5InformationNodeInstanceServer::createEditView3D() new QmlDesigner::Internal::IconGizmoImageProvider); m_3dHelper = helper; - m_editView3D = new QQuickView(quickView()->engine(), quickView()); - m_editView3D->setFormat(quickView()->format()); - DesignerSupport::createOpenGLContext(m_editView3D.data()); - QQmlComponent component(engine()); - component.loadUrl(QUrl("qrc:/qtquickplugin/mockfiles/EditView3D.qml")); - m_editView3DRootItem = qobject_cast(component.create()); + m_editView3D = createAuxiliaryQuickView(QUrl("qrc:/qtquickplugin/mockfiles/EditView3D.qml"), m_editView3DRootItem); - if (!m_editView3DRootItem) { - qWarning() << "Could not create edit view 3D: " << component.errors(); - return; + if (m_editView3DRootItem) { + QObject::connect(m_editView3DRootItem, SIGNAL(selectionChanged(QVariant)), + this, SLOT(handleSelectionChanged(QVariant))); + QObject::connect(m_editView3DRootItem, SIGNAL(commitObjectProperty(QVariant, QVariant)), + this, SLOT(handleObjectPropertyCommit(QVariant, QVariant))); + QObject::connect(m_editView3DRootItem, SIGNAL(changeObjectProperty(QVariant, QVariant)), + this, SLOT(handleObjectPropertyChange(QVariant, QVariant))); + QObject::connect(m_editView3DRootItem, SIGNAL(notifyActiveSceneChange()), + this, SLOT(handleActiveSceneChange())); + QObject::connect(&m_propertyChangeTimer, &QTimer::timeout, + this, &Qt5InformationNodeInstanceServer::handleObjectPropertyChangeTimeout); + QObject::connect(&m_selectionChangeTimer, &QTimer::timeout, + this, &Qt5InformationNodeInstanceServer::handleSelectionChangeTimeout); + QObject::connect(&m_render3DEditViewTimer, &QTimer::timeout, + this, &Qt5InformationNodeInstanceServer::doRender3DEditView); + + helper->setParent(m_editView3DRootItem); } - - DesignerSupport::setRootItem(m_editView3D, m_editView3DRootItem); - - QObject::connect(m_editView3DRootItem, SIGNAL(selectionChanged(QVariant)), - this, SLOT(handleSelectionChanged(QVariant))); - QObject::connect(m_editView3DRootItem, SIGNAL(commitObjectProperty(QVariant, QVariant)), - this, SLOT(handleObjectPropertyCommit(QVariant, QVariant))); - QObject::connect(m_editView3DRootItem, SIGNAL(changeObjectProperty(QVariant, QVariant)), - this, SLOT(handleObjectPropertyChange(QVariant, QVariant))); - QObject::connect(m_editView3DRootItem, SIGNAL(notifyActiveSceneChange()), - this, SLOT(handleActiveSceneChange())); - QObject::connect(&m_propertyChangeTimer, &QTimer::timeout, - this, &Qt5InformationNodeInstanceServer::handleObjectPropertyChangeTimeout); - QObject::connect(&m_selectionChangeTimer, &QTimer::timeout, - this, &Qt5InformationNodeInstanceServer::handleSelectionChangeTimeout); - QObject::connect(&m_render3DEditViewTimer, &QTimer::timeout, - this, &Qt5InformationNodeInstanceServer::doRender3DEditView); - QObject::connect(&m_renderModelNode3DImageViewTimer, &QTimer::timeout, - this, &Qt5InformationNodeInstanceServer::doRenderModelNode3DImageView); - - helper->setParent(m_editView3DRootItem); -#endif -} - -void Qt5InformationNodeInstanceServer::create3DPreviewView() -{ -#ifdef QUICK3D_MODULE - // This function assumes createEditView3D() has been called previously - m_ModelNode3DImageView = new QQuickView(quickView()->engine(), quickView()); - m_ModelNode3DImageView->setFormat(quickView()->format()); - DesignerSupport::createOpenGLContext(m_ModelNode3DImageView.data()); - QQmlComponent component(engine()); - component.loadUrl(QUrl("qrc:/qtquickplugin/mockfiles/ModelNode3DImageView.qml")); - m_ModelNode3DImageViewRootItem = qobject_cast(component.create()); - - if (!m_ModelNode3DImageViewRootItem) { - qWarning() << "Could not create ModelNode preview image 3D view: " << component.errors(); - return; - } - - DesignerSupport::setRootItem(m_ModelNode3DImageView, m_ModelNode3DImageViewRootItem); #endif } @@ -521,10 +509,20 @@ void Qt5InformationNodeInstanceServer::doRender3DEditView() } } -void Qt5InformationNodeInstanceServer::renderModelNode3DImageView() +void Qt5InformationNodeInstanceServer::renderModelNodeImageView() { - if (!m_renderModelNode3DImageViewTimer.isActive()) - m_renderModelNode3DImageViewTimer.start(0); + if (!m_renderModelNodeImageViewTimer.isActive()) + m_renderModelNodeImageViewTimer.start(0); +} + +void Qt5InformationNodeInstanceServer::doRenderModelNodeImageView() +{ + + ServerNodeInstance instance = instanceForId(m_modelNodePreviewImageCommand.instanceId()); + if (instance.isSubclassOf("QQuick3DObject")) + doRenderModelNode3DImageView(); + else if (instance.isSubclassOf("QQuickItem")) + doRenderModelNode2DImageView(); } void Qt5InformationNodeInstanceServer::doRenderModelNode3DImageView() @@ -542,13 +540,11 @@ void Qt5InformationNodeInstanceServer::doRenderModelNode3DImageView() } else { QObject *instanceObj = nullptr; if (!m_modelNodePreviewImageCommand.componentPath().isEmpty()) { - QQmlComponent *component = new QQmlComponent(engine()); - component->loadUrl(QUrl::fromLocalFile(m_modelNodePreviewImageCommand.componentPath())); - instanceObj = qobject_cast(component->create()); + QQmlComponent component(engine()); + component.loadUrl(QUrl::fromLocalFile(m_modelNodePreviewImageCommand.componentPath())); + instanceObj = qobject_cast(component.create()); if (!instanceObj) { - qWarning() << "Could not create preview component: " << component->errors(); - nodeInstanceClient()->handlePuppetToCreatorCommand({PuppetToCreatorCommand::RenderModelNodePreviewImage, - QVariant::fromValue(imgContainer)}); + qWarning() << "Could not create preview component: " << component.errors(); return; } } else { @@ -584,18 +580,105 @@ void Qt5InformationNodeInstanceServer::doRenderModelNode3DImageView() 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); + delete instanceObj; } } - imgContainer.setImage(renderImage); + if (!renderImage.isNull()) { + imgContainer.setImage(renderImage); - // send the rendered image to creator process - nodeInstanceClient()->handlePuppetToCreatorCommand({PuppetToCreatorCommand::RenderModelNodePreviewImage, - QVariant::fromValue(imgContainer)}); + // send the rendered image to creator process + nodeInstanceClient()->handlePuppetToCreatorCommand({PuppetToCreatorCommand::RenderModelNodePreviewImage, + QVariant::fromValue(imgContainer)}); + } } #endif } +static QRectF itemBoundingRect(QQuickItem *item) +{ + QRectF itemRect; + if (item) { + itemRect = item->boundingRect(); + if (item->clip()) { + return itemRect; + } else { + const auto childItems = item->childItems(); + for (const auto &childItem : childItems) { + QRectF mappedRect = childItem->mapRectToItem(item, itemBoundingRect(childItem)); + // Sanity check for size + if (mappedRect.isValid() && (mappedRect.width() < 10000) && (mappedRect.height() < 10000)) + itemRect = itemRect.united(mappedRect); + } + } + } + return itemRect; +} + +void Qt5InformationNodeInstanceServer::doRenderModelNode2DImageView() +{ + if (m_ModelNode2DImageViewRootItem) { + if (!m_ModelNode2DImageViewContentItem) + m_ModelNode2DImageViewContentItem = getContentItemForRendering(m_ModelNode2DImageViewRootItem); + + // Key number is the same as in 3D case as they produce image for same purpose + auto imgContainer = ImageContainer(m_modelNodePreviewImageCommand.instanceId(), {}, 2100000001); + QImage renderImage; + if (m_modelNodePreviewImageCache.contains(m_modelNodePreviewImageCommand.componentPath())) { + renderImage = m_modelNodePreviewImageCache[m_modelNodePreviewImageCommand.componentPath()]; + } else { + QQuickItem *instanceItem = nullptr; + + if (!m_modelNodePreviewImageCommand.componentPath().isEmpty()) { + QQmlComponent component(engine()); + component.loadUrl(QUrl::fromLocalFile(m_modelNodePreviewImageCommand.componentPath())); + instanceItem = qobject_cast(component.create()); + if (!instanceItem) { + qWarning() << "Could not create preview component: " << component.errors(); + return; + } + } else { + qWarning() << "2D image preview is not supported for non-components."; + return; + } + + instanceItem->setParentItem(m_ModelNode2DImageViewContentItem); + + // Some component may expect to always be shown at certain size, so their layouts may + // not support scaling, so let's always render at the default size if item has one and + // scale the resulting image instead. + QSize finalSize = m_modelNodePreviewImageCommand.size() * 2; + QRectF renderRect = itemBoundingRect(instanceItem); + QSize renderSize = renderRect.size().toSize(); + if (renderSize.isEmpty()) { + renderSize = finalSize; + renderRect = QRectF(QPointF(0., 0.), QSizeF(renderSize)); + instanceItem->setSize(renderSize); + } + + updateNodesRecursive(m_ModelNode2DImageViewContentItem); + + renderImage = designerSupport()->renderImageForItem(m_ModelNode2DImageViewContentItem, renderRect, renderSize); + + if (renderSize != finalSize) + renderImage = renderImage.scaled(finalSize, Qt::KeepAspectRatio); + + delete instanceItem; + + // If component changes, puppet will need a reset anyway, so we can cache the image + m_modelNodePreviewImageCache.insert(m_modelNodePreviewImageCommand.componentPath(), renderImage); + } + + if (!renderImage.isNull()) { + imgContainer.setImage(renderImage); + + // send the rendered image to creator process + nodeInstanceClient()->handlePuppetToCreatorCommand({PuppetToCreatorCommand::RenderModelNodePreviewImage, + QVariant::fromValue(imgContainer)}); + } + } +} + Qt5InformationNodeInstanceServer::Qt5InformationNodeInstanceServer(NodeInstanceClientInterface *nodeInstanceClient) : Qt5NodeInstanceServer(nodeInstanceClient) { @@ -603,7 +686,7 @@ Qt5InformationNodeInstanceServer::Qt5InformationNodeInstanceServer(NodeInstanceC m_propertyChangeTimer.setSingleShot(true); m_selectionChangeTimer.setSingleShot(true); m_render3DEditViewTimer.setSingleShot(true); - m_renderModelNode3DImageViewTimer.setSingleShot(true); + m_renderModelNodeImageViewTimer.setSingleShot(true); } void Qt5InformationNodeInstanceServer::sendTokenBack() @@ -919,7 +1002,8 @@ void Qt5InformationNodeInstanceServer::setup3DEditView(const QList(m_3dHelper); @@ -1095,6 +1179,11 @@ void Qt5InformationNodeInstanceServer::createScene(const CreateSceneCommand &com if (qEnvironmentVariableIsSet("QMLDESIGNER_QUICK3D_MODE")) setup3DEditView(instanceList, command.edit3dToolStates()); + + m_ModelNode2DImageView = createAuxiliaryQuickView(QUrl("qrc:/qtquickplugin/mockfiles/ModelNode2DImageView.qml"), + m_ModelNode2DImageViewRootItem); + QObject::connect(&m_renderModelNodeImageViewTimer, &QTimer::timeout, + this, &Qt5InformationNodeInstanceServer::doRenderModelNodeImageView); } void Qt5InformationNodeInstanceServer::sendChildrenChangedCommand(const QList &childList) @@ -1345,10 +1434,7 @@ void Qt5InformationNodeInstanceServer::view3DAction(const View3DActionCommand &c void Qt5InformationNodeInstanceServer::requestModelNodePreviewImage(const RequestModelNodePreviewImageCommand &command) { m_modelNodePreviewImageCommand = command; - - ServerNodeInstance instance = instanceForId(m_modelNodePreviewImageCommand.instanceId()); - if (instance.isSubclassOf("QQuick3DObject")) - renderModelNode3DImageView(); + renderModelNodeImageView(); } void Qt5InformationNodeInstanceServer::changeAuxiliaryValues(const ChangeAuxiliaryCommand &command) diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5informationnodeinstanceserver.h b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5informationnodeinstanceserver.h index d7abfa26a2a..881e6769156 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5informationnodeinstanceserver.h +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5informationnodeinstanceserver.h @@ -35,6 +35,7 @@ #include #include #include +#include QT_BEGIN_NAMESPACE class QDragMoveEvent; @@ -119,8 +120,11 @@ private: QQuickItem *getContentItemForRendering(QQuickItem *rootItem); void render3DEditView(int count = 1); void doRender3DEditView(); - void renderModelNode3DImageView(); + void renderModelNodeImageView(); + void doRenderModelNodeImageView(); void doRenderModelNode3DImageView(); + void doRenderModelNode2DImageView(); + QQuickView *createAuxiliaryQuickView(const QUrl &url, QQuickItem *&rootItem); QPointer m_editView3D; QQuickItem *m_editView3DRootItem = nullptr; @@ -128,6 +132,9 @@ private: QPointer m_ModelNode3DImageView; QQuickItem *m_ModelNode3DImageViewRootItem = nullptr; QQuickItem *m_ModelNode3DImageViewContentItem = nullptr; + QPointer m_ModelNode2DImageView; + QQuickItem *m_ModelNode2DImageViewRootItem = nullptr; + QQuickItem *m_ModelNode2DImageViewContentItem = nullptr; RequestModelNodePreviewImageCommand m_modelNodePreviewImageCommand; QHash m_modelNodePreviewImageCache; QSet m_view3Ds; @@ -141,7 +148,7 @@ private: QTimer m_propertyChangeTimer; QTimer m_selectionChangeTimer; QTimer m_render3DEditViewTimer; - QTimer m_renderModelNode3DImageViewTimer; + QTimer m_renderModelNodeImageViewTimer; QVariant m_changedNode; PropertyName m_changedProperty; ChangeSelectionCommand m_lastSelectionChangeCommand; diff --git a/share/qtcreator/qml/qmlpuppet/qmlpuppet.qrc b/share/qtcreator/qml/qmlpuppet/qmlpuppet.qrc index adbf6f58e8e..d5a50ed566e 100644 --- a/share/qtcreator/qml/qmlpuppet/qmlpuppet.qrc +++ b/share/qtcreator/qml/qmlpuppet/qmlpuppet.qrc @@ -41,6 +41,7 @@ mockfiles/AxisHelperArm.qml mockfiles/Line3D.qml mockfiles/ModelNode3DImageView.qml + mockfiles/ModelNode2DImageView.qml mockfiles/MaterialNodeView.qml mockfiles/EffectNodeView.qml mockfiles/ModelNodeView.qml diff --git a/src/plugins/qmldesigner/components/componentcore/designeractionmanager.cpp b/src/plugins/qmldesigner/components/componentcore/designeractionmanager.cpp index a24fed15927..f7487d8a3ff 100644 --- a/src/plugins/qmldesigner/components/componentcore/designeractionmanager.cpp +++ b/src/plugins/qmldesigner/components/componentcore/designeractionmanager.cpp @@ -1402,13 +1402,17 @@ void DesignerActionManager::createDefaultModelNodePreviewImageHandlers() ModelNodeOperations::previewImageDataForImageNode)); registerModelNodePreviewHandler( ModelNodePreviewImageHandler("QtQuick3D.Material", - ModelNodeOperations::previewImageDataFor3DNode)); + ModelNodeOperations::previewImageDataForGenericNode)); registerModelNodePreviewHandler( ModelNodePreviewImageHandler("QtQuick3D.Model", - ModelNodeOperations::previewImageDataFor3DNode)); + ModelNodeOperations::previewImageDataForGenericNode)); registerModelNodePreviewHandler( ModelNodePreviewImageHandler("QtQuick3D.Node", - ModelNodeOperations::previewImageDataFor3DNode, + ModelNodeOperations::previewImageDataForGenericNode, + true)); + registerModelNodePreviewHandler( + ModelNodePreviewImageHandler("QtQuick.Item", + ModelNodeOperations::previewImageDataForGenericNode, true)); // TODO - Disabled until QTBUG-86616 is fixed diff --git a/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.cpp b/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.cpp index 04794c72f38..e77fcb33561 100644 --- a/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.cpp +++ b/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.cpp @@ -1519,10 +1519,10 @@ void removeGroup(const SelectionContext &selectionContext) }); } -QVariant previewImageDataFor3DNode(const ModelNode &modelNode) +QVariant previewImageDataForGenericNode(const ModelNode &modelNode) { if (modelNode.isValid()) - return modelNode.model()->nodeInstanceView()->previewImageDataFor3DNode(modelNode); + return modelNode.model()->nodeInstanceView()->previewImageDataForGenericNode(modelNode); return {}; } diff --git a/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.h b/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.h index a829545748a..d22e673c801 100644 --- a/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.h +++ b/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.h @@ -85,7 +85,7 @@ void mergeWithTemplate(const SelectionContext &selectionContext); void removeGroup(const SelectionContext &selectionContext); // ModelNodePreviewImageOperations -QVariant previewImageDataFor3DNode(const ModelNode &modelNode); +QVariant previewImageDataForGenericNode(const ModelNode &modelNode); QVariant previewImageDataForImageNode(const ModelNode &modelNode); } // namespace ModelNodeOperationso diff --git a/src/plugins/qmldesigner/components/navigator/navigatortreemodel.cpp b/src/plugins/qmldesigner/components/navigator/navigatortreemodel.cpp index a2419a351f3..804d8c2d4be 100644 --- a/src/plugins/qmldesigner/components/navigator/navigatortreemodel.cpp +++ b/src/plugins/qmldesigner/components/navigator/navigatortreemodel.cpp @@ -54,6 +54,7 @@ #include #include #include +#include #include @@ -857,9 +858,9 @@ void NavigatorTreeModel::resetModel() endResetModel(); } -void NavigatorTreeModel::updateToolTipImage(const ModelNode &node, const QImage &image) +void NavigatorTreeModel::updateToolTipPixmap(const ModelNode &node, const QPixmap &pixmap) { - emit toolTipImageUpdated(node.id(), image); + emit toolTipPixmapUpdated(node.id(), pixmap); } } // QmlDesigner diff --git a/src/plugins/qmldesigner/components/navigator/navigatortreemodel.h b/src/plugins/qmldesigner/components/navigator/navigatortreemodel.h index 67c59b1aab6..d474ee98b9c 100644 --- a/src/plugins/qmldesigner/components/navigator/navigatortreemodel.h +++ b/src/plugins/qmldesigner/components/navigator/navigatortreemodel.h @@ -34,6 +34,8 @@ #include #include +QT_FORWARD_DECLARE_CLASS(QPixmap) + namespace QmlDesigner { class Model; @@ -94,10 +96,10 @@ public: void setOrder(bool reverseItemOrder) override; void resetModel() override; - void updateToolTipImage(const ModelNode &node, const QImage &image); + void updateToolTipPixmap(const ModelNode &node, const QPixmap &pixmap); signals: - void toolTipImageUpdated(const QString &id, const QImage &image) const; + void toolTipPixmapUpdated(const QString &id, const QPixmap &pixmap) const; private: void moveNodesInteractive(NodeAbstractProperty &parentProperty, const QList &modelNodes, diff --git a/src/plugins/qmldesigner/components/navigator/navigatortreeview.cpp b/src/plugins/qmldesigner/components/navigator/navigatortreeview.cpp index 183686a26b4..ddf8862c895 100644 --- a/src/plugins/qmldesigner/components/navigator/navigatortreeview.cpp +++ b/src/plugins/qmldesigner/components/navigator/navigatortreeview.cpp @@ -196,16 +196,16 @@ bool NavigatorTreeView::viewportEvent(QEvent *event) m_toolTipHideTimer.stop(); if (!m_previewToolTip) { m_previewToolTip = new PreviewToolTip(QApplication::activeWindow()); - connect(navModel, &NavigatorTreeModel::toolTipImageUpdated, - [this](const QString &id, const QImage &image) { + connect(navModel, &NavigatorTreeModel::toolTipPixmapUpdated, + [this](const QString &id, const QPixmap &pixmap) { if (m_previewToolTip && m_previewToolTip->id() == id) - m_previewToolTip->setImage(image); + m_previewToolTip->setPixmap(pixmap); }); } m_previewToolTip->setId(imgMap["id"].toString()); m_previewToolTip->setType(imgMap["type"].toString()); m_previewToolTip->setInfo(imgMap["info"].toString()); - m_previewToolTip->setImage(imgMap["image"].value()); + m_previewToolTip->setPixmap(imgMap["pixmap"].value()); m_previewToolTip->move(m_previewToolTip->parentWidget()->mapFromGlobal(helpEvent->globalPos()) + QPoint(15, 15)); if (!m_previewToolTip->isVisible()) diff --git a/src/plugins/qmldesigner/components/navigator/navigatorview.cpp b/src/plugins/qmldesigner/components/navigator/navigatorview.cpp index 90284fec0a6..87952613b1c 100644 --- a/src/plugins/qmldesigner/components/navigator/navigatorview.cpp +++ b/src/plugins/qmldesigner/components/navigator/navigatorview.cpp @@ -51,7 +51,7 @@ #include #include - +#include static inline void setScenePos(const QmlDesigner::ModelNode &modelNode,const QPointF &pos) { @@ -263,9 +263,9 @@ void NavigatorView::enableWidget() m_widget->enableNavigator(); } -void NavigatorView::modelNodePreviewImageChanged(const ModelNode &node, const QImage &image) +void NavigatorView::modelNodePreviewPixmapChanged(const ModelNode &node, const QPixmap &pixmap) { - m_treeModel->updateToolTipImage(node, image); + m_treeModel->updateToolTipPixmap(node, pixmap); } ModelNode NavigatorView::modelNodeForIndex(const QModelIndex &modelIndex) const diff --git a/src/plugins/qmldesigner/components/navigator/navigatorview.h b/src/plugins/qmldesigner/components/navigator/navigatorview.h index b237cb5ca6c..67042634e90 100644 --- a/src/plugins/qmldesigner/components/navigator/navigatorview.h +++ b/src/plugins/qmldesigner/components/navigator/navigatorview.h @@ -38,7 +38,7 @@ class QTreeView; class QItemSelection; class QModelIndex; class QAbstractItemModel; -class QImage; +class QPixmap; QT_END_NAMESPACE namespace QmlDesigner { @@ -96,7 +96,7 @@ public: void disableWidget() override; void enableWidget() override; - void modelNodePreviewImageChanged(const ModelNode &node, const QImage &image) override; + void modelNodePreviewPixmapChanged(const ModelNode &node, const QPixmap &pixmap) override; private: ModelNode modelNodeForIndex(const QModelIndex &modelIndex) const; diff --git a/src/plugins/qmldesigner/components/navigator/previewtooltip.cpp b/src/plugins/qmldesigner/components/navigator/previewtooltip.cpp index 38c91b3fb87..83d8ee44993 100644 --- a/src/plugins/qmldesigner/components/navigator/previewtooltip.cpp +++ b/src/plugins/qmldesigner/components/navigator/previewtooltip.cpp @@ -65,9 +65,9 @@ void PreviewToolTip::setInfo(const QString &info) m_ui->infoLabel->setText(info); } -void PreviewToolTip::setImage(const QImage &image) +void PreviewToolTip::setPixmap(const QPixmap &pixmap) { - m_ui->imageLabel->setPixmap(QPixmap::fromImage(image)); + m_ui->imageLabel->setPixmap(pixmap); } QString PreviewToolTip::id() const diff --git a/src/plugins/qmldesigner/components/navigator/previewtooltip.h b/src/plugins/qmldesigner/components/navigator/previewtooltip.h index 081d496adbe..b6387a414be 100644 --- a/src/plugins/qmldesigner/components/navigator/previewtooltip.h +++ b/src/plugins/qmldesigner/components/navigator/previewtooltip.h @@ -26,7 +26,7 @@ #pragma once #include -#include +#include namespace QmlDesigner { namespace Ui { @@ -44,7 +44,7 @@ public: void setId(const QString &id); void setType(const QString &type); void setInfo(const QString &info); - void setImage(const QImage &image); + void setPixmap(const QPixmap &pixmap); QString id() const; diff --git a/src/plugins/qmldesigner/designercore/include/abstractview.h b/src/plugins/qmldesigner/designercore/include/abstractview.h index b4475603385..a444c9fdfd0 100644 --- a/src/plugins/qmldesigner/designercore/include/abstractview.h +++ b/src/plugins/qmldesigner/designercore/include/abstractview.h @@ -45,6 +45,7 @@ QT_BEGIN_NAMESPACE class QStyle; class QToolButton; class QImage; +class QPixmap; QT_END_NAMESPACE namespace QmlDesigner { @@ -186,7 +187,7 @@ public: void emitInstanceToken(const QString &token, int number, const QVector &nodeVector); void emitRenderImage3DChanged(const QImage &image); void emitUpdateActiveScene3D(const QVariantMap &sceneState); - void emitModelNodelPreviewImageChanged(const ModelNode &node, const QImage &image); + void emitModelNodelPreviewPixmapChanged(const ModelNode &node, const QPixmap &pixmap); void sendTokenToInstances(const QString &token, int number, const QVector &nodeVector); @@ -246,7 +247,7 @@ public: virtual void renderImage3DChanged(const QImage &image); virtual void updateActiveScene3D(const QVariantMap &sceneState); - virtual void modelNodePreviewImageChanged(const ModelNode &node, const QImage &image); + virtual void modelNodePreviewPixmapChanged(const ModelNode &node, const QPixmap &pixmap); void changeRootNodeType(const TypeName &type, int majorVersion, int minorVersion); diff --git a/src/plugins/qmldesigner/designercore/include/nodeinstanceview.h b/src/plugins/qmldesigner/designercore/include/nodeinstanceview.h index fbb0a718f56..13818786974 100644 --- a/src/plugins/qmldesigner/designercore/include/nodeinstanceview.h +++ b/src/plugins/qmldesigner/designercore/include/nodeinstanceview.h @@ -143,7 +143,7 @@ public: void handlePuppetToCreatorCommand(const PuppetToCreatorCommand &command) override; - QVariant previewImageDataFor3DNode(const ModelNode &modelNode); + QVariant previewImageDataForGenericNode(const ModelNode &modelNode); QVariant previewImageDataForImageNode(const ModelNode &modelNode); protected: diff --git a/src/plugins/qmldesigner/designercore/instances/nodeinstanceview.cpp b/src/plugins/qmldesigner/designercore/instances/nodeinstanceview.cpp index c55d6561c2b..2afbffc3ddc 100644 --- a/src/plugins/qmldesigner/designercore/instances/nodeinstanceview.cpp +++ b/src/plugins/qmldesigner/designercore/instances/nodeinstanceview.cpp @@ -1553,7 +1553,7 @@ void NodeInstanceView::timerEvent(QTimerEvent *event) struct ImageData { QDateTime time; - QImage image; + QPixmap pixmap; QString type; QString id; QString info; @@ -1562,10 +1562,10 @@ static QHash> imageDataMap; static QVariant imageDataToVariant(const ImageData &imageData) { - if (!imageData.image.isNull()) { + if (!imageData.pixmap.isNull()) { QVariantMap map; map.insert("type", imageData.type); - map.insert("image", QVariant::fromValue(imageData.image)); + map.insert("pixmap", QVariant::fromValue(imageData.pixmap)); map.insert("id", imageData.id); map.insert("info", imageData.info); return map; @@ -1599,13 +1599,13 @@ QVariant NodeInstanceView::previewImageDataForImageNode(const ModelNode &modelNo } 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.); + QPixmap originalPixmap; + originalPixmap.load(imageSource); + if (!originalPixmap.isNull()) { + imageData.pixmap = originalPixmap.scaled(Constants::MODELNODE_PREVIEW_IMAGE_DIMENSIONS * 2, + Constants::MODELNODE_PREVIEW_IMAGE_DIMENSIONS * 2, + Qt::KeepAspectRatio); + imageData.pixmap.setDevicePixelRatio(2.); double imgSize = double(imageFi.size()); imageData.type = QStringLiteral("%1 (%2)").arg(QString::fromLatin1(modelNode.type())).arg(imageFi.suffix()); @@ -1616,7 +1616,7 @@ QVariant NodeInstanceView::previewImageDataForImageNode(const ModelNode &modelNo ++unitIndex; imgSize /= 1024.; } - imageData.info = QStringLiteral("%1 x %2 (%3%4)").arg(originalImage.width()).arg(originalImage.height()) + imageData.info = QStringLiteral("%1 x %2 (%3%4)").arg(originalPixmap.width()).arg(originalPixmap.height()) .arg(QString::number(imgSize, 'g', 3)).arg(units[unitIndex]); localDataMap.insert(imageSource, imageData); } @@ -1625,12 +1625,12 @@ QVariant NodeInstanceView::previewImageDataForImageNode(const ModelNode &modelNo return imageDataToVariant(imageData); } -QVariant NodeInstanceView::previewImageDataFor3DNode(const ModelNode &modelNode) +QVariant NodeInstanceView::previewImageDataForGenericNode(const ModelNode &modelNode) { QFileInfo docFi = QFileInfo(modelNode.model()->fileUrl().toLocalFile()); QHash &localDataMap = imageDataMap[docFi.absoluteFilePath()]; ImageData imageData; - static const QImage placeHolder(":/navigator/icon/tooltip_placeholder.png"); + static const QPixmap 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 @@ -1640,7 +1640,7 @@ QVariant NodeInstanceView::previewImageDataFor3DNode(const ModelNode &modelNode) } else { imageData.type = QString::fromLatin1(modelNode.type()); imageData.id = id; - imageData.image = placeHolder; + imageData.pixmap = placeHolder; localDataMap.insert(id, imageData); } requestModelNodePreviewImage(modelNode); @@ -1652,12 +1652,13 @@ void NodeInstanceView::updatePreviewImageForNode(const ModelNode &modelNode, con { QFileInfo docFi = QFileInfo(modelNode.model()->fileUrl().toLocalFile()); QString docPath = docFi.absoluteFilePath(); + QPixmap pixmap = QPixmap::fromImage(image); if (imageDataMap.contains(docPath)) { QHash &localDataMap = imageDataMap[docPath]; if (localDataMap.contains(modelNode.id())) - localDataMap[modelNode.id()].image = image; + localDataMap[modelNode.id()].pixmap = pixmap; } - emitModelNodelPreviewImageChanged(modelNode, image); + emitModelNodelPreviewPixmapChanged(modelNode, pixmap); } } diff --git a/src/plugins/qmldesigner/designercore/model/abstractview.cpp b/src/plugins/qmldesigner/designercore/model/abstractview.cpp index 6224ab50c0d..c2e6b8e9db0 100644 --- a/src/plugins/qmldesigner/designercore/model/abstractview.cpp +++ b/src/plugins/qmldesigner/designercore/model/abstractview.cpp @@ -382,7 +382,7 @@ void AbstractView::updateActiveScene3D(const QVariantMap & /*sceneState*/) { } -void AbstractView::modelNodePreviewImageChanged(const ModelNode & /*node*/, const QImage & /*image*/) +void AbstractView::modelNodePreviewPixmapChanged(const ModelNode & /*node*/, const QPixmap & /*pixmap*/) { } @@ -770,10 +770,10 @@ void AbstractView::emitUpdateActiveScene3D(const QVariantMap &sceneState) model()->d->notifyUpdateActiveScene3D(sceneState); } -void AbstractView::emitModelNodelPreviewImageChanged(const ModelNode &node, const QImage &image) +void AbstractView::emitModelNodelPreviewPixmapChanged(const ModelNode &node, const QPixmap &pixmap) { if (model()) - model()->d->notifyModelNodePreviewImageChanged(node, image); + model()->d->notifyModelNodePreviewPixmapChanged(node, pixmap); } void AbstractView::emitRewriterEndTransaction() diff --git a/src/plugins/qmldesigner/designercore/model/model.cpp b/src/plugins/qmldesigner/designercore/model/model.cpp index e2ce604ba2b..df730cfaa5d 100644 --- a/src/plugins/qmldesigner/designercore/model/model.cpp +++ b/src/plugins/qmldesigner/designercore/model/model.cpp @@ -700,11 +700,11 @@ void ModelPrivate::notifyUpdateActiveScene3D(const QVariantMap &sceneState) } } -void ModelPrivate::notifyModelNodePreviewImageChanged(const ModelNode &node, const QImage &image) +void ModelPrivate::notifyModelNodePreviewPixmapChanged(const ModelNode &node, const QPixmap &pixmap) { for (const QPointer &view : qAsConst(m_viewList)) { Q_ASSERT(view != nullptr); - view->modelNodePreviewImageChanged(node, image); + view->modelNodePreviewPixmapChanged(node, pixmap); } } diff --git a/src/plugins/qmldesigner/designercore/model/model_p.h b/src/plugins/qmldesigner/designercore/model/model_p.h index 2d6669aeb9e..a88a769560c 100644 --- a/src/plugins/qmldesigner/designercore/model/model_p.h +++ b/src/plugins/qmldesigner/designercore/model/model_p.h @@ -38,6 +38,7 @@ QT_BEGIN_NAMESPACE class QPlainTextEdit; +class QPixmap; QT_END_NAMESPACE namespace QmlDesigner { @@ -160,7 +161,7 @@ public: void notifyRenderImage3DChanged(const QImage &image); void notifyUpdateActiveScene3D(const QVariantMap &sceneState); - void notifyModelNodePreviewImageChanged(const ModelNode &node, const QImage &image); + void notifyModelNodePreviewPixmapChanged(const ModelNode &node, const QPixmap &pixmap); void setDocumentMessages(const QList &errors, const QList &warnings);