From ddecd338a8d0c7a446b23fc4076570734131a8cd Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Thu, 24 Nov 2022 17:30:12 +0200 Subject: [PATCH] QmlDesigner: Unify texture image providers Texture editor, material browser, and UrlChooser all had separate texture providers that served nearly identical purpose. Unified all use cases to use same PropertyEditorImageProvider. This provider is asynchronous, which combined with enabling caching on Image elements, significantly improves responsiveness of the material browser UI when there are many textures shown in the browser. Fixes: QDS-8387 Change-Id: I2888aee2f4320dba9456fa046c9ede319673a3d9 Reviewed-by: Mahmoud Badri --- .../materialBrowserQmlSource/TextureItem.qml | 2 +- .../imports/HelperWidgets/UrlChooser.qml | 18 ++++--- .../TextureEditorTopSection.qml | 7 ++- .../components/componentcore/viewmanager.cpp | 4 +- .../materialbrowser/materialbrowserview.cpp | 7 +-- .../materialbrowser/materialbrowserview.h | 4 +- .../materialbrowser/materialbrowserwidget.cpp | 49 +++++++------------ .../materialbrowser/materialbrowserwidget.h | 6 +-- .../propertyeditorimageprovider.cpp | 25 ++++++---- .../textureeditorcontextobject.cpp | 8 +++ .../textureeditorcontextobject.h | 1 + .../textureeditor/textureeditorqmlbackend.cpp | 40 +++------------ .../textureeditor/textureeditorqmlbackend.h | 6 ++- .../textureeditor/textureeditorview.cpp | 6 ++- .../textureeditor/textureeditorview.h | 4 +- .../imagecache/imagecachecollector.cpp | 7 ++- .../imagecache/smallimagecacheprovider.h | 2 + 17 files changed, 95 insertions(+), 101 deletions(-) diff --git a/share/qtcreator/qmldesigner/materialBrowserQmlSource/TextureItem.qml b/share/qtcreator/qmldesigner/materialBrowserQmlSource/TextureItem.qml index a666354b832..00bb835826e 100644 --- a/share/qtcreator/qmldesigner/materialBrowserQmlSource/TextureItem.qml +++ b/share/qtcreator/qmldesigner/materialBrowserQmlSource/TextureItem.qml @@ -40,10 +40,10 @@ Rectangle { Image { source: "image://materialBrowserTex/" + textureSource + asynchronous: true sourceSize.width: root.width - 10 sourceSize.height: root.height - 10 anchors.centerIn: parent - cache: false smooth: true } } diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/UrlChooser.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/UrlChooser.qml index b87005fe4bb..d6373f790ab 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/UrlChooser.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/UrlChooser.qml @@ -102,8 +102,8 @@ Row { Item { visible: thumbnail.status === Image.Ready - Layout.preferredWidth: 100 - Layout.preferredHeight: 100 + Layout.preferredWidth: 96 + Layout.preferredHeight: 96 Image { id: checker @@ -116,7 +116,10 @@ Row { Image { id: thumbnail asynchronous: true - anchors.fill: parent + sourceSize.height: 96 + sourceSize.width: 96 + height: 96 + width: 96 fillMode: Image.PreserveAspectFit source: { if (root.isBuiltInPrimitive(root.absoluteFilePath)) @@ -231,8 +234,8 @@ Row { Item { visible: delegateThumbnail.status === Image.Ready - Layout.preferredWidth: 100 - Layout.preferredHeight: 100 + Layout.preferredWidth: 96 + Layout.preferredHeight: 96 Image { id: delegateChecker @@ -245,7 +248,10 @@ Row { Image { id: delegateThumbnail asynchronous: true - anchors.fill: parent + sourceSize.height: 96 + sourceSize.width: 96 + height: 96 + width: 96 fillMode: Image.PreserveAspectFit source: { if (root.isBuiltInPrimitive(delegateRoot.name)) diff --git a/share/qtcreator/qmldesigner/textureEditorQmlSource/TextureEditorTopSection.qml b/share/qtcreator/qmldesigner/textureEditorQmlSource/TextureEditorTopSection.qml index 287278d9548..016049df102 100644 --- a/share/qtcreator/qmldesigner/textureEditorQmlSource/TextureEditorTopSection.qml +++ b/share/qtcreator/qmldesigner/textureEditorQmlSource/TextureEditorTopSection.qml @@ -11,7 +11,7 @@ Column { function refreshPreview() { texturePreview.source = "" - texturePreview.source = "image://textureEditor/" + backendValues.source.valueToString + texturePreview.source = "image://qmldesigner_thumbnails/" + resolveResourcePath(backendValues.source.valueToString) } anchors.left: parent.left @@ -34,12 +34,11 @@ Column { Image { id: texturePreview - + asynchronous: true sourceSize.width: 150 sourceSize.height: 150 anchors.centerIn: parent - source: "image://textureEditor/" + backendValues.source.valueToString - cache: false + source: "image://qmldesigner_thumbnails/" + resolveResourcePath(backendValues.source.valueToString) } } } diff --git a/src/plugins/qmldesigner/components/componentcore/viewmanager.cpp b/src/plugins/qmldesigner/components/componentcore/viewmanager.cpp index 08ee673ff16..7ac6d44877e 100644 --- a/src/plugins/qmldesigner/components/componentcore/viewmanager.cpp +++ b/src/plugins/qmldesigner/components/componentcore/viewmanager.cpp @@ -69,8 +69,8 @@ public: , navigatorView{externalDependencies} , propertyEditorView(imageCache, externalDependencies) , materialEditorView{externalDependencies} - , materialBrowserView{externalDependencies} - , textureEditorView{externalDependencies} + , materialBrowserView{imageCache, externalDependencies} + , textureEditorView{imageCache, externalDependencies} , statesEditorView{externalDependencies} , newStatesEditorView{externalDependencies} {} diff --git a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.cpp b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.cpp index 79fc5cb4b61..0445db3ba6d 100644 --- a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.cpp +++ b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.cpp @@ -41,8 +41,10 @@ static QString propertyEditorResourcesPath() return Core::ICore::resourcePath("qmldesigner/propertyEditorQmlSources").toString(); } -MaterialBrowserView::MaterialBrowserView(ExternalDependenciesInterface &externalDependencies) +MaterialBrowserView::MaterialBrowserView(AsynchronousImageCache &imageCache, + ExternalDependenciesInterface &externalDependencies) : AbstractView{externalDependencies} + , m_imageCache(imageCache) { m_previewTimer.setSingleShot(true); connect(&m_previewTimer, &QTimer::timeout, this, &MaterialBrowserView::requestPreviews); @@ -59,12 +61,11 @@ bool MaterialBrowserView::hasWidget() const WidgetInfo MaterialBrowserView::widgetInfo() { if (m_widget.isNull()) { - m_widget = new MaterialBrowserWidget(this); + m_widget = new MaterialBrowserWidget(m_imageCache, this); auto matEditorContext = new Internal::MaterialBrowserContext(m_widget.data()); Core::ICore::addContextObject(matEditorContext); - // custom notifications below are sent to the MaterialEditor MaterialBrowserModel *matBrowserModel = m_widget->materialBrowserModel().data(); diff --git a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.h b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.h index 53ee5821b99..e8f1160f2f3 100644 --- a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.h +++ b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.h @@ -22,7 +22,8 @@ class MaterialBrowserView : public AbstractView Q_OBJECT public: - MaterialBrowserView(ExternalDependenciesInterface &externalDependencies); + MaterialBrowserView(class AsynchronousImageCache &imageCache, + ExternalDependenciesInterface &externalDependencies); ~MaterialBrowserView() override; bool hasWidget() const override; @@ -64,6 +65,7 @@ private: void loadPropertyGroups(); void requestPreviews(); + AsynchronousImageCache &m_imageCache; QPointer m_widget; QList m_selectedModels; // selected 3D model nodes diff --git a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserwidget.cpp b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserwidget.cpp index 541bb385f67..d6e990761b8 100644 --- a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserwidget.cpp +++ b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserwidget.cpp @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -89,33 +90,6 @@ public: } }; -class TextureImageProvider : public QQuickImageProvider -{ -public: - TextureImageProvider() : QQuickImageProvider(Pixmap) {} - - QPixmap requestPixmap(const QString &id, QSize *size, const QSize &requestedSize) override - { - QPixmap pixmap; - const QString suffix = id.split('.').last().toLower(); - if (suffix == "hdr") - pixmap = HdrImage{id}.toPixmap(); - else - pixmap = Utils::StyleHelper::dpiSpecificImageFile(id); - - if (pixmap.isNull()) - pixmap = Utils::StyleHelper::dpiSpecificImageFile(":/textureeditor/images/texture_default.png"); - - if (size) - *size = pixmap.size(); - - if (requestedSize.isValid()) - return pixmap.scaled(requestedSize, Qt::KeepAspectRatio); - - return pixmap; - } -}; - bool MaterialBrowserWidget::eventFilter(QObject *obj, QEvent *event) { if (event->type() == QEvent::FocusOut) { @@ -145,9 +119,16 @@ bool MaterialBrowserWidget::eventFilter(QObject *obj, QEvent *event) QString iconPath = QLatin1String("%1/%2") .arg(DocumentManager::currentResourcePath().path(), m_textureToDrag.variantProperty("source").value().toString()); - model->startDrag(mimeData, - m_textureImageProvider->requestPixmap(iconPath, nullptr, - {128, 128})); + + QPixmap pixmap; + const QString suffix = iconPath.split('.').last().toLower(); + if (suffix == "hdr") + pixmap = HdrImage{iconPath}.toPixmap(); + else + pixmap = Utils::StyleHelper::dpiSpecificImageFile(iconPath); + if (pixmap.isNull()) + pixmap = Utils::StyleHelper::dpiSpecificImageFile(":/textureeditor/images/texture_default.png"); + model->startDrag(mimeData, pixmap.scaled({128, 128})); } m_materialToDrag = {}; m_textureToDrag = {}; @@ -161,14 +142,18 @@ bool MaterialBrowserWidget::eventFilter(QObject *obj, QEvent *event) return QObject::eventFilter(obj, event); } -MaterialBrowserWidget::MaterialBrowserWidget(MaterialBrowserView *view) +MaterialBrowserWidget::MaterialBrowserWidget(AsynchronousImageCache &imageCache, + MaterialBrowserView *view) : m_materialBrowserView(view) , m_materialBrowserModel(new MaterialBrowserModel(this)) , m_materialBrowserTexturesModel(new MaterialBrowserTexturesModel(this)) , m_quickWidget(new QQuickWidget(this)) , m_previewImageProvider(new PreviewImageProvider()) - , m_textureImageProvider(new TextureImageProvider()) { + QImage defaultImage; + defaultImage.load(Utils::StyleHelper::dpiSpecificImageFile(":/textureeditor/images/texture_default.png")); + m_textureImageProvider = new PropertyEditorImageProvider(imageCache, defaultImage); + setWindowTitle(tr("Material Browser", "Title of material browser widget")); setMinimumWidth(120); diff --git a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserwidget.h b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserwidget.h index 929900d52bb..a236ce14714 100644 --- a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserwidget.h +++ b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserwidget.h @@ -28,14 +28,14 @@ class MaterialBrowserView; class MaterialBrowserModel; class MaterialBrowserTexturesModel; class PreviewImageProvider; -class TextureImageProvider; +class PropertyEditorImageProvider; class MaterialBrowserWidget : public QFrame { Q_OBJECT public: - MaterialBrowserWidget(MaterialBrowserView *view); + MaterialBrowserWidget(class AsynchronousImageCache &imageCache, MaterialBrowserView *view); ~MaterialBrowserWidget() = default; QList createToolBarWidgets(); @@ -72,7 +72,7 @@ private: QShortcut *m_qmlSourceUpdateShortcut = nullptr; PreviewImageProvider *m_previewImageProvider = nullptr; - TextureImageProvider *m_textureImageProvider = nullptr; + PropertyEditorImageProvider *m_textureImageProvider = nullptr; Core::IContext *m_context = nullptr; QString m_filterText; diff --git a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorimageprovider.cpp b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorimageprovider.cpp index 90dd2caaebe..e7ff48450d1 100644 --- a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorimageprovider.cpp +++ b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorimageprovider.cpp @@ -25,18 +25,25 @@ QQuickImageResponse *PropertyEditorImageProvider::requestImageResponse(const QSt return m_smallImageCacheProvider.requestImageResponse("#" + id.split('.').first(), requestedSize); - QImage image; - auto response = std::make_unique(image); + auto response = std::make_unique(m_smallImageCacheProvider.defaultImage()); QMetaObject::invokeMethod( response.get(), - [response = QPointer(response.get()), image, suffix, id] { - if (AssetsLibraryModel::supportedImageSuffixes().contains(suffix)) - response->setImage(QImage(Utils::StyleHelper::dpiSpecificImageFile(id))); - else if (AssetsLibraryModel::supportedTexture3DSuffixes().contains(suffix)) - response->setImage(HdrImage{id}.image()); - else - response->abort(); + [response = QPointer(response.get()), suffix, id, requestedSize] { + if (AssetsLibraryModel::supportedImageSuffixes().contains(suffix)) { + QImage image = QImage(Utils::StyleHelper::dpiSpecificImageFile(id)); + if (!image.isNull()) { + response->setImage(image.scaled(requestedSize, Qt::KeepAspectRatio)); + return; + } + } else if (AssetsLibraryModel::supportedTexture3DSuffixes().contains(suffix)) { + HdrImage hdr{id}; + if (!hdr.image().isNull()) { + response->setImage(hdr.image().scaled(requestedSize, Qt::KeepAspectRatio)); + return; + } + } + response->setImage(response->image().scaled(requestedSize, Qt::KeepAspectRatio)); }, Qt::QueuedConnection); diff --git a/src/plugins/qmldesigner/components/textureeditor/textureeditorcontextobject.cpp b/src/plugins/qmldesigner/components/textureeditor/textureeditorcontextobject.cpp index d358425a1a3..690e78db0a5 100644 --- a/src/plugins/qmldesigner/components/textureeditor/textureeditorcontextobject.cpp +++ b/src/plugins/qmldesigner/components/textureeditor/textureeditorcontextobject.cpp @@ -12,6 +12,7 @@ #include #include +#include #include #include @@ -334,4 +335,11 @@ void TextureEditorContextObject::goIntoComponent() DocumentManager::goIntoComponent(m_selectedTexture); } +QString TextureEditorContextObject::resolveResourcePath(const QString &path) +{ + if (Utils::FilePath::fromString(path).isAbsolutePath()) + return path; + return DocumentManager::currentResourcePath().path() + '/' + path; +} + } // QmlDesigner diff --git a/src/plugins/qmldesigner/components/textureeditor/textureeditorcontextobject.h b/src/plugins/qmldesigner/components/textureeditor/textureeditorcontextobject.h index cc479e5092e..56249382724 100644 --- a/src/plugins/qmldesigner/components/textureeditor/textureeditorcontextobject.h +++ b/src/plugins/qmldesigner/components/textureeditor/textureeditorcontextobject.h @@ -73,6 +73,7 @@ public: Q_INVOKABLE bool isBlocked(const QString &propName) const; Q_INVOKABLE void goIntoComponent(); + Q_INVOKABLE QString resolveResourcePath(const QString &path); enum ToolBarAction { ApplyToSelected, diff --git a/src/plugins/qmldesigner/components/textureeditor/textureeditorqmlbackend.cpp b/src/plugins/qmldesigner/components/textureeditor/textureeditorqmlbackend.cpp index b385afe4f37..c3bcdd7d5e7 100644 --- a/src/plugins/qmldesigner/components/textureeditor/textureeditorqmlbackend.cpp +++ b/src/plugins/qmldesigner/components/textureeditor/textureeditorqmlbackend.cpp @@ -6,6 +6,7 @@ #include "bindingproperty.h" #include "documentmanager.h" #include "nodemetainfo.h" +#include "propertyeditorimageprovider.h" #include "propertyeditorvalue.h" #include "qmldesignerconstants.h" #include "qmlobjectnode.h" @@ -41,46 +42,17 @@ static QObject *variantToQObject(const QVariant &value) namespace QmlDesigner { -class TextureEditorImageProvider : public QQuickImageProvider -{ - QPixmap m_previewPixmap; - -public: - TextureEditorImageProvider() - : QQuickImageProvider(Pixmap) {} - - QPixmap requestPixmap(const QString &id, QSize *size, const QSize &requestedSize) override - { - QPixmap pixmap; - const QString suffix = id.split('.').last().toLower(); - const QString path = DocumentManager::currentResourcePath().path() + '/' + id; - if (suffix == "hdr") - pixmap = HdrImage{path}.toPixmap(); - else - pixmap = Utils::StyleHelper::dpiSpecificImageFile(path); - - if (pixmap.isNull()) - pixmap = Utils::StyleHelper::dpiSpecificImageFile(":/textureeditor/images/texture_default.png"); - - if (size) - *size = pixmap.size(); - - if (requestedSize.isValid()) - return pixmap.scaled(requestedSize, Qt::KeepAspectRatio); - - return pixmap; - } -}; - -TextureEditorQmlBackend::TextureEditorQmlBackend(TextureEditorView *textureEditor) +TextureEditorQmlBackend::TextureEditorQmlBackend(TextureEditorView *textureEditor, AsynchronousImageCache &imageCache) : m_view(new QQuickWidget) , m_textureEditorTransaction(new TextureEditorTransaction(textureEditor)) , m_contextObject(new TextureEditorContextObject(m_view->rootContext())) - , m_textureEditorImageProvider(new TextureEditorImageProvider()) { + QImage defaultImage; + defaultImage.load(Utils::StyleHelper::dpiSpecificImageFile(":/textureeditor/images/texture_default.png")); + m_textureEditorImageProvider = new PropertyEditorImageProvider(imageCache, defaultImage); m_view->setResizeMode(QQuickWidget::SizeRootObjectToView); m_view->engine()->addImportPath(propertyEditorResourcesPath() + "/imports"); - m_view->engine()->addImageProvider("textureEditor", m_textureEditorImageProvider); + m_view->engine()->addImageProvider("qmldesigner_thumbnails", m_textureEditorImageProvider); m_contextObject->setBackendValues(&m_backendValuesPropertyMap); m_contextObject->setModel(textureEditor->model()); context()->setContextObject(m_contextObject.data()); diff --git a/src/plugins/qmldesigner/components/textureeditor/textureeditorqmlbackend.h b/src/plugins/qmldesigner/components/textureeditor/textureeditorqmlbackend.h index fab25c6d586..2d0131cc9fc 100644 --- a/src/plugins/qmldesigner/components/textureeditor/textureeditorqmlbackend.h +++ b/src/plugins/qmldesigner/components/textureeditor/textureeditorqmlbackend.h @@ -17,6 +17,7 @@ QT_END_NAMESPACE namespace QmlDesigner { +class PropertyEditorImageProvider; class TextureEditorContextObject; class TextureEditorImageProvider; class TextureEditorTransaction; @@ -27,7 +28,8 @@ class TextureEditorQmlBackend Q_DISABLE_COPY(TextureEditorQmlBackend) public: - TextureEditorQmlBackend(TextureEditorView *materialEditor); + TextureEditorQmlBackend(TextureEditorView *materialEditor, + class AsynchronousImageCache &imageCache); ~TextureEditorQmlBackend(); void setup(const QmlObjectNode &selectedTextureNode, const QString &stateName, const QUrl &qmlSpecificsFile, @@ -63,7 +65,7 @@ private: DesignerPropertyMap m_backendValuesPropertyMap; QScopedPointer m_textureEditorTransaction; QScopedPointer m_contextObject; - TextureEditorImageProvider *m_textureEditorImageProvider = nullptr; + PropertyEditorImageProvider *m_textureEditorImageProvider = nullptr; }; } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/components/textureeditor/textureeditorview.cpp b/src/plugins/qmldesigner/components/textureeditor/textureeditorview.cpp index 67779743da6..b1d3c210ecb 100644 --- a/src/plugins/qmldesigner/components/textureeditor/textureeditorview.cpp +++ b/src/plugins/qmldesigner/components/textureeditor/textureeditorview.cpp @@ -49,8 +49,10 @@ namespace QmlDesigner { -TextureEditorView::TextureEditorView(ExternalDependenciesInterface &externalDependencies) +TextureEditorView::TextureEditorView(AsynchronousImageCache &imageCache, + ExternalDependenciesInterface &externalDependencies) : AbstractView{externalDependencies} + , m_imageCache(imageCache) , m_stackedWidget(new QStackedWidget) , m_dynamicPropertiesModel(new Internal::DynamicPropertiesModel(true, this)) { @@ -432,7 +434,7 @@ void TextureEditorView::setupQmlBackend() QString currentStateName = currentState().isBaseState() ? currentState().name() : "invalid state"; if (!currentQmlBackend) { - currentQmlBackend = new TextureEditorQmlBackend(this); + currentQmlBackend = new TextureEditorQmlBackend(this, m_imageCache); m_stackedWidget->addWidget(currentQmlBackend->widget()); m_qmlBackendHash.insert(qmlPaneUrl.toString(), currentQmlBackend); diff --git a/src/plugins/qmldesigner/components/textureeditor/textureeditorview.h b/src/plugins/qmldesigner/components/textureeditor/textureeditorview.h index 8e5c175e853..39586cd8425 100644 --- a/src/plugins/qmldesigner/components/textureeditor/textureeditorview.h +++ b/src/plugins/qmldesigner/components/textureeditor/textureeditorview.h @@ -31,7 +31,8 @@ class TextureEditorView : public AbstractView Q_OBJECT public: - TextureEditorView(ExternalDependenciesInterface &externalDependencies); + TextureEditorView(class AsynchronousImageCache &imageCache, + ExternalDependenciesInterface &externalDependencies); ~TextureEditorView() override; bool hasWidget() const override; @@ -105,6 +106,7 @@ private: bool noValidSelection() const; + AsynchronousImageCache &m_imageCache; ModelNode m_selectedTexture; QTimer m_ensureMatLibTimer; QShortcut *m_updateShortcut = nullptr; diff --git a/src/plugins/qmldesigner/designercore/imagecache/imagecachecollector.cpp b/src/plugins/qmldesigner/designercore/imagecache/imagecachecollector.cpp index be176760491..d762299f1cb 100644 --- a/src/plugins/qmldesigner/designercore/imagecache/imagecachecollector.cpp +++ b/src/plugins/qmldesigner/designercore/imagecache/imagecachecollector.cpp @@ -14,6 +14,7 @@ #include #include +#include #include namespace QmlDesigner { @@ -103,7 +104,11 @@ void ImageCacheCollector::start(Utils::SmallStringView name, auto callback = [=, captureCallback = std::move(captureCallback)](const QImage &image) { if (nullImageHandling == ImageCacheCollectorNullImageHandling::CaptureNullImage || !image.isNull()) { - QSize smallImageSize = image.size().scaled(QSize{96, 96}.boundedTo(image.size()), + QSize targetSize {96, 96}; + const qreal ratio = qGuiApp->devicePixelRatio(); + if (ratio > 1.0) + targetSize *= qRound(ratio); + QSize smallImageSize = image.size().scaled(targetSize.boundedTo(image.size()), Qt::KeepAspectRatio); QImage smallImage = image.isNull() ? QImage{} : image.scaled(smallImageSize, diff --git a/src/plugins/qmldesigner/designercore/imagecache/smallimagecacheprovider.h b/src/plugins/qmldesigner/designercore/imagecache/smallimagecacheprovider.h index 1a608c626c9..54b3b63f1d5 100644 --- a/src/plugins/qmldesigner/designercore/imagecache/smallimagecacheprovider.h +++ b/src/plugins/qmldesigner/designercore/imagecache/smallimagecacheprovider.h @@ -20,6 +20,7 @@ public: QQuickTextureFactory *textureFactory() const override; void setImage(const QImage &image); + QImage image() const { return m_image; } void abort(); @@ -37,6 +38,7 @@ public: QQuickImageResponse *requestImageResponse(const QString &id, const QSize &requestedSize) override; + QImage defaultImage() const { return m_defaultImage; } private: AsynchronousImageCache &m_cache;