forked from qt-creator/qt-creator
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:
BIN
share/qtcreator/qml/qmlpuppet/images/non-visual-component.png
Normal file
BIN
share/qtcreator/qml/qmlpuppet/images/non-visual-component.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.2 KiB |
BIN
share/qtcreator/qml/qmlpuppet/images/non-visual-component@2x.png
Normal file
BIN
share/qtcreator/qml/qmlpuppet/images/non-visual-component@2x.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 7.1 KiB |
@@ -101,6 +101,30 @@ static QVariant objectToVariant(QObject *object)
|
|||||||
return QVariant::fromValue(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,
|
QQuickView *Qt5InformationNodeInstanceServer::createAuxiliaryQuickView(const QUrl &url,
|
||||||
QQuickItem *&rootItem)
|
QQuickItem *&rootItem)
|
||||||
{
|
{
|
||||||
@@ -556,7 +580,7 @@ void Qt5InformationNodeInstanceServer::doRenderModelNode3DImageView()
|
|||||||
ServerNodeInstance instance = instanceForId(m_modelNodePreviewImageCommand.instanceId());
|
ServerNodeInstance instance = instanceForId(m_modelNodePreviewImageCommand.instanceId());
|
||||||
instanceObj = instance.internalObject();
|
instanceObj = instance.internalObject();
|
||||||
}
|
}
|
||||||
QSize renderSize = m_modelNodePreviewImageCommand.size() * 2;
|
QSize renderSize = m_modelNodePreviewImageCommand.size();
|
||||||
|
|
||||||
QMetaObject::invokeMethod(m_ModelNode3DImageViewRootItem, "createViewForObject",
|
QMetaObject::invokeMethod(m_ModelNode3DImageViewRootItem, "createViewForObject",
|
||||||
Q_ARG(QVariant, objectToVariant(instanceObj)),
|
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
|
// 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
|
// not support scaling, so let's always render at the default size if item has one and
|
||||||
// scale the resulting image instead.
|
// scale the resulting image instead.
|
||||||
QSize finalSize = m_modelNodePreviewImageCommand.size() * 2;
|
QSize finalSize = m_modelNodePreviewImageCommand.size();
|
||||||
QRectF renderRect = itemBoundingRect(instanceItem);
|
QRectF renderRect = itemBoundingRect(instanceItem);
|
||||||
QSize renderSize = renderRect.size().toSize();
|
QSize renderSize = renderRect.size().toSize();
|
||||||
if (renderSize.isEmpty()) {
|
if (renderSize.isEmpty()) {
|
||||||
@@ -665,6 +689,9 @@ void Qt5InformationNodeInstanceServer::doRenderModelNode2DImageView()
|
|||||||
|
|
||||||
renderImage = designerSupport()->renderImageForItem(m_ModelNode2DImageViewContentItem, renderRect, renderSize);
|
renderImage = designerSupport()->renderImageForItem(m_ModelNode2DImageViewContentItem, renderRect, renderSize);
|
||||||
|
|
||||||
|
if (!imageHasContent(renderImage))
|
||||||
|
renderImage = nonVisualComponentPreviewImage();
|
||||||
|
|
||||||
if (renderSize != finalSize)
|
if (renderSize != finalSize)
|
||||||
renderImage = renderImage.scaled(finalSize, Qt::KeepAspectRatio);
|
renderImage = renderImage.scaled(finalSize, Qt::KeepAspectRatio);
|
||||||
|
|
||||||
|
@@ -3,6 +3,8 @@
|
|||||||
<file>images/template_image.png</file>
|
<file>images/template_image.png</file>
|
||||||
<file>html/welcome.html</file>
|
<file>html/welcome.html</file>
|
||||||
<file>images/webkit.png</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/Window.qml</file>
|
||||||
<file>mockfiles/SwipeView.qml</file>
|
<file>mockfiles/SwipeView.qml</file>
|
||||||
<file>mockfiles/GenericBackend.qml</file>
|
<file>mockfiles/GenericBackend.qml</file>
|
||||||
|
@@ -1496,7 +1496,11 @@ void NodeInstanceView::handlePuppetToCreatorCommand(const PuppetToCreatorCommand
|
|||||||
if (hasModelNodeForInternalId(container.instanceId()) && !image.isNull()) {
|
if (hasModelNodeForInternalId(container.instanceId()) && !image.isNull()) {
|
||||||
auto node = modelNodeForInternalId(container.instanceId());
|
auto node = modelNodeForInternalId(container.instanceId());
|
||||||
if (node.isValid()) {
|
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);
|
updatePreviewImageForNode(node, image);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1540,12 +1544,10 @@ void NodeInstanceView::requestModelNodePreviewImage(const ModelNode &node, const
|
|||||||
} else if (node.isComponent()) {
|
} else if (node.isComponent()) {
|
||||||
componentPath = node.metaInfo().componentFileName();
|
componentPath = node.metaInfo().componentFileName();
|
||||||
}
|
}
|
||||||
|
const int dim = Constants::MODELNODE_PREVIEW_IMAGE_DIMENSIONS * QmlDesignerPlugin::formEditorDevicePixelRatio();
|
||||||
m_nodeInstanceServer->requestModelNodePreviewImage(
|
m_nodeInstanceServer->requestModelNodePreviewImage(
|
||||||
RequestModelNodePreviewImageCommand(
|
RequestModelNodePreviewImageCommand(instance.instanceId(), QSize(dim, dim),
|
||||||
instance.instanceId(),
|
componentPath, renderItemId));
|
||||||
QSize(Constants::MODELNODE_PREVIEW_IMAGE_DIMENSIONS,
|
|
||||||
Constants::MODELNODE_PREVIEW_IMAGE_DIMENSIONS),
|
|
||||||
componentPath, renderItemId));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1587,6 +1589,7 @@ QVariant NodeInstanceView::previewImageDataForImageNode(const ModelNode &modelNo
|
|||||||
ModelNodePreviewImageData imageData;
|
ModelNodePreviewImageData imageData;
|
||||||
imageData.id = modelNode.id();
|
imageData.id = modelNode.id();
|
||||||
imageData.type = QString::fromLatin1(modelNode.type());
|
imageData.type = QString::fromLatin1(modelNode.type());
|
||||||
|
const double ratio = QmlDesignerPlugin::formEditorDevicePixelRatio();
|
||||||
|
|
||||||
if (imageSource.isEmpty() && modelNode.isSubclassOf("QtQuick3D.Texture")) {
|
if (imageSource.isEmpty() && modelNode.isSubclassOf("QtQuick3D.Texture")) {
|
||||||
// Texture node may have sourceItem instead
|
// Texture node may have sourceItem instead
|
||||||
@@ -1601,11 +1604,10 @@ QVariant NodeInstanceView::previewImageDataForImageNode(const ModelNode &modelNo
|
|||||||
return previewImageDataForGenericNode(modelNode, boundNode);
|
return previewImageDataForGenericNode(modelNode, boundNode);
|
||||||
} else {
|
} else {
|
||||||
QmlItemNode itemNode(boundNode);
|
QmlItemNode itemNode(boundNode);
|
||||||
imageData.pixmap = itemNode.instanceRenderPixmap().scaled(
|
const int dim = Constants::MODELNODE_PREVIEW_IMAGE_DIMENSIONS * ratio;
|
||||||
Constants::MODELNODE_PREVIEW_IMAGE_DIMENSIONS * 2,
|
imageData.pixmap = itemNode.instanceRenderPixmap().scaled(dim, dim, Qt::KeepAspectRatio);
|
||||||
Constants::MODELNODE_PREVIEW_IMAGE_DIMENSIONS * 2,
|
imageData.pixmap.setDevicePixelRatio(ratio);
|
||||||
Qt::KeepAspectRatio);
|
|
||||||
imageData.pixmap.setDevicePixelRatio(2.);
|
|
||||||
}
|
}
|
||||||
imageData.info = QObject::tr("Source item: %1").arg(boundNode.id());
|
imageData.info = QObject::tr("Source item: %1").arg(boundNode.id());
|
||||||
}
|
}
|
||||||
@@ -1629,10 +1631,9 @@ QVariant NodeInstanceView::previewImageDataForImageNode(const ModelNode &modelNo
|
|||||||
QPixmap originalPixmap;
|
QPixmap originalPixmap;
|
||||||
originalPixmap.load(imageSource);
|
originalPixmap.load(imageSource);
|
||||||
if (!originalPixmap.isNull()) {
|
if (!originalPixmap.isNull()) {
|
||||||
imageData.pixmap = originalPixmap.scaled(Constants::MODELNODE_PREVIEW_IMAGE_DIMENSIONS * 2,
|
const int dim = Constants::MODELNODE_PREVIEW_IMAGE_DIMENSIONS * ratio;
|
||||||
Constants::MODELNODE_PREVIEW_IMAGE_DIMENSIONS * 2,
|
imageData.pixmap = originalPixmap.scaled(dim, dim, Qt::KeepAspectRatio);
|
||||||
Qt::KeepAspectRatio);
|
imageData.pixmap.setDevicePixelRatio(ratio);
|
||||||
imageData.pixmap.setDevicePixelRatio(2.);
|
|
||||||
|
|
||||||
double imgSize = double(imageFi.size());
|
double imgSize = double(imageFi.size());
|
||||||
static QStringList units({QObject::tr("B"), QObject::tr("KB"), QObject::tr("MB"), QObject::tr("GB")});
|
static QStringList units({QObject::tr("B"), QObject::tr("KB"), QObject::tr("MB"), QObject::tr("GB")});
|
||||||
|
Reference in New Issue
Block a user