forked from qt-creator/qt-creator
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 <thomas.hartmann@qt.io> Reviewed-by: Mahmoud Badri <mahmoud.badri@qt.io>
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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 {};
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -54,6 +54,7 @@
|
||||
#include <QPointF>
|
||||
#include <QDir>
|
||||
#include <QFileInfo>
|
||||
#include <QPixmap>
|
||||
|
||||
#include <coreplugin/messagebox.h>
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -34,6 +34,8 @@
|
||||
#include <QPointer>
|
||||
#include <QDateTime>
|
||||
|
||||
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<ModelNode> &modelNodes,
|
||||
|
||||
@@ -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<QImage>());
|
||||
m_previewToolTip->setPixmap(imgMap["pixmap"].value<QPixmap>());
|
||||
m_previewToolTip->move(m_previewToolTip->parentWidget()->mapFromGlobal(helpEvent->globalPos())
|
||||
+ QPoint(15, 15));
|
||||
if (!m_previewToolTip->isVisible())
|
||||
|
||||
@@ -51,7 +51,7 @@
|
||||
|
||||
#include <QHeaderView>
|
||||
#include <QTimer>
|
||||
|
||||
#include <QPixmap>
|
||||
|
||||
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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <QtWidgets/qwidget.h>
|
||||
#include <QtGui/qimage.h>
|
||||
#include <QtGui/qpixmap.h>
|
||||
|
||||
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;
|
||||
|
||||
|
||||
@@ -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<ModelNode> &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<ModelNode> &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);
|
||||
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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<QString, QHash<QString, ImageData>> 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<QImage>(imageData.image));
|
||||
map.insert("pixmap", QVariant::fromValue<QPixmap>(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<QString, ImageData> &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<QString, ImageData> &localDataMap = imageDataMap[docPath];
|
||||
if (localDataMap.contains(modelNode.id()))
|
||||
localDataMap[modelNode.id()].image = image;
|
||||
localDataMap[modelNode.id()].pixmap = pixmap;
|
||||
}
|
||||
emitModelNodelPreviewImageChanged(modelNode, image);
|
||||
emitModelNodelPreviewPixmapChanged(modelNode, pixmap);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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<AbstractView> &view : qAsConst(m_viewList)) {
|
||||
Q_ASSERT(view != nullptr);
|
||||
view->modelNodePreviewImageChanged(node, image);
|
||||
view->modelNodePreviewPixmapChanged(node, pixmap);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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<DocumentMessage> &errors, const QList<DocumentMessage> &warnings);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user