QmlDesigner: Return placeholder preview image for non-visual components

Preview image is returned when a 2D item render results in a blank
image.

Also improved device pixel ratio handling. No longer always render
preview at 2x ratio, if not needed.

Change-Id: I67b7563dffea523ea85be23b6a0e8b802c0f03fb
Fixes: QDS-2893
Reviewed-by: Mahmoud Badri <mahmoud.badri@qt.io>
This commit is contained in:
Miikka Heikkinen
2020-10-05 13:23:54 +03:00
parent 22545933b6
commit 47714c38c6
5 changed files with 47 additions and 17 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.1 KiB

View File

@@ -101,6 +101,30 @@ static QVariant objectToVariant(QObject *object)
return QVariant::fromValue(object);
}
static QImage nonVisualComponentPreviewImage()
{
static double ratio = qgetenv("FORMEDITOR_DEVICE_PIXEL_RATIO").toDouble();
if (ratio == 1.) {
static const QImage image(":/qtquickplugin/images/non-visual-component.png");
return image;
} else {
static const QImage image(":/qtquickplugin/images/non-visual-component@2x.png");
return image;
}
}
static bool imageHasContent(const QImage &image)
{
// Check if any image pixel contains non-zero data
const uchar *pData = image.constBits();
const qsizetype size = image.sizeInBytes();
for (qsizetype i = 0; i < size; ++i) {
if (*(pData++) != 0)
return true;
}
return false;
}
QQuickView *Qt5InformationNodeInstanceServer::createAuxiliaryQuickView(const QUrl &url,
QQuickItem *&rootItem)
{
@@ -556,7 +580,7 @@ void Qt5InformationNodeInstanceServer::doRenderModelNode3DImageView()
ServerNodeInstance instance = instanceForId(m_modelNodePreviewImageCommand.instanceId());
instanceObj = instance.internalObject();
}
QSize renderSize = m_modelNodePreviewImageCommand.size() * 2;
QSize renderSize = m_modelNodePreviewImageCommand.size();
QMetaObject::invokeMethod(m_ModelNode3DImageViewRootItem, "createViewForObject",
Q_ARG(QVariant, objectToVariant(instanceObj)),
@@ -652,7 +676,7 @@ void Qt5InformationNodeInstanceServer::doRenderModelNode2DImageView()
// 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;
QSize finalSize = m_modelNodePreviewImageCommand.size();
QRectF renderRect = itemBoundingRect(instanceItem);
QSize renderSize = renderRect.size().toSize();
if (renderSize.isEmpty()) {
@@ -665,6 +689,9 @@ void Qt5InformationNodeInstanceServer::doRenderModelNode2DImageView()
renderImage = designerSupport()->renderImageForItem(m_ModelNode2DImageViewContentItem, renderRect, renderSize);
if (!imageHasContent(renderImage))
renderImage = nonVisualComponentPreviewImage();
if (renderSize != finalSize)
renderImage = renderImage.scaled(finalSize, Qt::KeepAspectRatio);

View File

@@ -3,6 +3,8 @@
<file>images/template_image.png</file>
<file>html/welcome.html</file>
<file>images/webkit.png</file>
<file>images/non-visual-component.png</file>
<file>images/non-visual-component@2x.png</file>
<file>mockfiles/Window.qml</file>
<file>mockfiles/SwipeView.qml</file>
<file>mockfiles/GenericBackend.qml</file>

View File

@@ -1496,7 +1496,11 @@ void NodeInstanceView::handlePuppetToCreatorCommand(const PuppetToCreatorCommand
if (hasModelNodeForInternalId(container.instanceId()) && !image.isNull()) {
auto node = modelNodeForInternalId(container.instanceId());
if (node.isValid()) {
image.setDevicePixelRatio(2.);
const double ratio = QmlDesignerPlugin::formEditorDevicePixelRatio();
const int dim = Constants::MODELNODE_PREVIEW_IMAGE_DIMENSIONS * ratio;
if (image.height() != dim || image.width() != dim)
image = image.scaled(dim, dim, Qt::KeepAspectRatio);
image.setDevicePixelRatio(ratio);
updatePreviewImageForNode(node, image);
}
}
@@ -1540,12 +1544,10 @@ void NodeInstanceView::requestModelNodePreviewImage(const ModelNode &node, const
} else if (node.isComponent()) {
componentPath = node.metaInfo().componentFileName();
}
const int dim = Constants::MODELNODE_PREVIEW_IMAGE_DIMENSIONS * QmlDesignerPlugin::formEditorDevicePixelRatio();
m_nodeInstanceServer->requestModelNodePreviewImage(
RequestModelNodePreviewImageCommand(
instance.instanceId(),
QSize(Constants::MODELNODE_PREVIEW_IMAGE_DIMENSIONS,
Constants::MODELNODE_PREVIEW_IMAGE_DIMENSIONS),
componentPath, renderItemId));
RequestModelNodePreviewImageCommand(instance.instanceId(), QSize(dim, dim),
componentPath, renderItemId));
}
}
}
@@ -1587,6 +1589,7 @@ QVariant NodeInstanceView::previewImageDataForImageNode(const ModelNode &modelNo
ModelNodePreviewImageData imageData;
imageData.id = modelNode.id();
imageData.type = QString::fromLatin1(modelNode.type());
const double ratio = QmlDesignerPlugin::formEditorDevicePixelRatio();
if (imageSource.isEmpty() && modelNode.isSubclassOf("QtQuick3D.Texture")) {
// Texture node may have sourceItem instead
@@ -1601,11 +1604,10 @@ QVariant NodeInstanceView::previewImageDataForImageNode(const ModelNode &modelNo
return previewImageDataForGenericNode(modelNode, boundNode);
} else {
QmlItemNode itemNode(boundNode);
imageData.pixmap = itemNode.instanceRenderPixmap().scaled(
Constants::MODELNODE_PREVIEW_IMAGE_DIMENSIONS * 2,
Constants::MODELNODE_PREVIEW_IMAGE_DIMENSIONS * 2,
Qt::KeepAspectRatio);
imageData.pixmap.setDevicePixelRatio(2.);
const int dim = Constants::MODELNODE_PREVIEW_IMAGE_DIMENSIONS * ratio;
imageData.pixmap = itemNode.instanceRenderPixmap().scaled(dim, dim, Qt::KeepAspectRatio);
imageData.pixmap.setDevicePixelRatio(ratio);
}
imageData.info = QObject::tr("Source item: %1").arg(boundNode.id());
}
@@ -1629,10 +1631,9 @@ QVariant NodeInstanceView::previewImageDataForImageNode(const ModelNode &modelNo
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.);
const int dim = Constants::MODELNODE_PREVIEW_IMAGE_DIMENSIONS * ratio;
imageData.pixmap = originalPixmap.scaled(dim, dim, Qt::KeepAspectRatio);
imageData.pixmap.setDevicePixelRatio(ratio);
double imgSize = double(imageFi.size());
static QStringList units({QObject::tr("B"), QObject::tr("KB"), QObject::tr("MB"), QObject::tr("GB")});