forked from qt-creator/qt-creator
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 <mahmoud.badri@qt.io>
This commit is contained in:
@@ -40,10 +40,10 @@ Rectangle {
|
|||||||
|
|
||||||
Image {
|
Image {
|
||||||
source: "image://materialBrowserTex/" + textureSource
|
source: "image://materialBrowserTex/" + textureSource
|
||||||
|
asynchronous: true
|
||||||
sourceSize.width: root.width - 10
|
sourceSize.width: root.width - 10
|
||||||
sourceSize.height: root.height - 10
|
sourceSize.height: root.height - 10
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
cache: false
|
|
||||||
smooth: true
|
smooth: true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -102,8 +102,8 @@ Row {
|
|||||||
|
|
||||||
Item {
|
Item {
|
||||||
visible: thumbnail.status === Image.Ready
|
visible: thumbnail.status === Image.Ready
|
||||||
Layout.preferredWidth: 100
|
Layout.preferredWidth: 96
|
||||||
Layout.preferredHeight: 100
|
Layout.preferredHeight: 96
|
||||||
|
|
||||||
Image {
|
Image {
|
||||||
id: checker
|
id: checker
|
||||||
@@ -116,7 +116,10 @@ Row {
|
|||||||
Image {
|
Image {
|
||||||
id: thumbnail
|
id: thumbnail
|
||||||
asynchronous: true
|
asynchronous: true
|
||||||
anchors.fill: parent
|
sourceSize.height: 96
|
||||||
|
sourceSize.width: 96
|
||||||
|
height: 96
|
||||||
|
width: 96
|
||||||
fillMode: Image.PreserveAspectFit
|
fillMode: Image.PreserveAspectFit
|
||||||
source: {
|
source: {
|
||||||
if (root.isBuiltInPrimitive(root.absoluteFilePath))
|
if (root.isBuiltInPrimitive(root.absoluteFilePath))
|
||||||
@@ -231,8 +234,8 @@ Row {
|
|||||||
|
|
||||||
Item {
|
Item {
|
||||||
visible: delegateThumbnail.status === Image.Ready
|
visible: delegateThumbnail.status === Image.Ready
|
||||||
Layout.preferredWidth: 100
|
Layout.preferredWidth: 96
|
||||||
Layout.preferredHeight: 100
|
Layout.preferredHeight: 96
|
||||||
|
|
||||||
Image {
|
Image {
|
||||||
id: delegateChecker
|
id: delegateChecker
|
||||||
@@ -245,7 +248,10 @@ Row {
|
|||||||
Image {
|
Image {
|
||||||
id: delegateThumbnail
|
id: delegateThumbnail
|
||||||
asynchronous: true
|
asynchronous: true
|
||||||
anchors.fill: parent
|
sourceSize.height: 96
|
||||||
|
sourceSize.width: 96
|
||||||
|
height: 96
|
||||||
|
width: 96
|
||||||
fillMode: Image.PreserveAspectFit
|
fillMode: Image.PreserveAspectFit
|
||||||
source: {
|
source: {
|
||||||
if (root.isBuiltInPrimitive(delegateRoot.name))
|
if (root.isBuiltInPrimitive(delegateRoot.name))
|
||||||
|
@@ -11,7 +11,7 @@ Column {
|
|||||||
function refreshPreview()
|
function refreshPreview()
|
||||||
{
|
{
|
||||||
texturePreview.source = ""
|
texturePreview.source = ""
|
||||||
texturePreview.source = "image://textureEditor/" + backendValues.source.valueToString
|
texturePreview.source = "image://qmldesigner_thumbnails/" + resolveResourcePath(backendValues.source.valueToString)
|
||||||
}
|
}
|
||||||
|
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
@@ -34,12 +34,11 @@ Column {
|
|||||||
|
|
||||||
Image {
|
Image {
|
||||||
id: texturePreview
|
id: texturePreview
|
||||||
|
asynchronous: true
|
||||||
sourceSize.width: 150
|
sourceSize.width: 150
|
||||||
sourceSize.height: 150
|
sourceSize.height: 150
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
source: "image://textureEditor/" + backendValues.source.valueToString
|
source: "image://qmldesigner_thumbnails/" + resolveResourcePath(backendValues.source.valueToString)
|
||||||
cache: false
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -69,8 +69,8 @@ public:
|
|||||||
, navigatorView{externalDependencies}
|
, navigatorView{externalDependencies}
|
||||||
, propertyEditorView(imageCache, externalDependencies)
|
, propertyEditorView(imageCache, externalDependencies)
|
||||||
, materialEditorView{externalDependencies}
|
, materialEditorView{externalDependencies}
|
||||||
, materialBrowserView{externalDependencies}
|
, materialBrowserView{imageCache, externalDependencies}
|
||||||
, textureEditorView{externalDependencies}
|
, textureEditorView{imageCache, externalDependencies}
|
||||||
, statesEditorView{externalDependencies}
|
, statesEditorView{externalDependencies}
|
||||||
, newStatesEditorView{externalDependencies}
|
, newStatesEditorView{externalDependencies}
|
||||||
{}
|
{}
|
||||||
|
@@ -41,8 +41,10 @@ static QString propertyEditorResourcesPath()
|
|||||||
return Core::ICore::resourcePath("qmldesigner/propertyEditorQmlSources").toString();
|
return Core::ICore::resourcePath("qmldesigner/propertyEditorQmlSources").toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
MaterialBrowserView::MaterialBrowserView(ExternalDependenciesInterface &externalDependencies)
|
MaterialBrowserView::MaterialBrowserView(AsynchronousImageCache &imageCache,
|
||||||
|
ExternalDependenciesInterface &externalDependencies)
|
||||||
: AbstractView{externalDependencies}
|
: AbstractView{externalDependencies}
|
||||||
|
, m_imageCache(imageCache)
|
||||||
{
|
{
|
||||||
m_previewTimer.setSingleShot(true);
|
m_previewTimer.setSingleShot(true);
|
||||||
connect(&m_previewTimer, &QTimer::timeout, this, &MaterialBrowserView::requestPreviews);
|
connect(&m_previewTimer, &QTimer::timeout, this, &MaterialBrowserView::requestPreviews);
|
||||||
@@ -59,12 +61,11 @@ bool MaterialBrowserView::hasWidget() const
|
|||||||
WidgetInfo MaterialBrowserView::widgetInfo()
|
WidgetInfo MaterialBrowserView::widgetInfo()
|
||||||
{
|
{
|
||||||
if (m_widget.isNull()) {
|
if (m_widget.isNull()) {
|
||||||
m_widget = new MaterialBrowserWidget(this);
|
m_widget = new MaterialBrowserWidget(m_imageCache, this);
|
||||||
|
|
||||||
auto matEditorContext = new Internal::MaterialBrowserContext(m_widget.data());
|
auto matEditorContext = new Internal::MaterialBrowserContext(m_widget.data());
|
||||||
Core::ICore::addContextObject(matEditorContext);
|
Core::ICore::addContextObject(matEditorContext);
|
||||||
|
|
||||||
|
|
||||||
// custom notifications below are sent to the MaterialEditor
|
// custom notifications below are sent to the MaterialEditor
|
||||||
MaterialBrowserModel *matBrowserModel = m_widget->materialBrowserModel().data();
|
MaterialBrowserModel *matBrowserModel = m_widget->materialBrowserModel().data();
|
||||||
|
|
||||||
|
@@ -22,7 +22,8 @@ class MaterialBrowserView : public AbstractView
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
MaterialBrowserView(ExternalDependenciesInterface &externalDependencies);
|
MaterialBrowserView(class AsynchronousImageCache &imageCache,
|
||||||
|
ExternalDependenciesInterface &externalDependencies);
|
||||||
~MaterialBrowserView() override;
|
~MaterialBrowserView() override;
|
||||||
|
|
||||||
bool hasWidget() const override;
|
bool hasWidget() const override;
|
||||||
@@ -64,6 +65,7 @@ private:
|
|||||||
void loadPropertyGroups();
|
void loadPropertyGroups();
|
||||||
void requestPreviews();
|
void requestPreviews();
|
||||||
|
|
||||||
|
AsynchronousImageCache &m_imageCache;
|
||||||
QPointer<MaterialBrowserWidget> m_widget;
|
QPointer<MaterialBrowserWidget> m_widget;
|
||||||
QList<ModelNode> m_selectedModels; // selected 3D model nodes
|
QList<ModelNode> m_selectedModels; // selected 3D model nodes
|
||||||
|
|
||||||
|
@@ -10,6 +10,7 @@
|
|||||||
#include <designeractionmanager.h>
|
#include <designeractionmanager.h>
|
||||||
#include <designermcumanager.h>
|
#include <designermcumanager.h>
|
||||||
#include <documentmanager.h>
|
#include <documentmanager.h>
|
||||||
|
#include <propertyeditorimageprovider.h>
|
||||||
#include <qmldesignerconstants.h>
|
#include <qmldesignerconstants.h>
|
||||||
#include <qmldesignerplugin.h>
|
#include <qmldesignerplugin.h>
|
||||||
#include <variantproperty.h>
|
#include <variantproperty.h>
|
||||||
@@ -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)
|
bool MaterialBrowserWidget::eventFilter(QObject *obj, QEvent *event)
|
||||||
{
|
{
|
||||||
if (event->type() == QEvent::FocusOut) {
|
if (event->type() == QEvent::FocusOut) {
|
||||||
@@ -145,9 +119,16 @@ bool MaterialBrowserWidget::eventFilter(QObject *obj, QEvent *event)
|
|||||||
QString iconPath = QLatin1String("%1/%2")
|
QString iconPath = QLatin1String("%1/%2")
|
||||||
.arg(DocumentManager::currentResourcePath().path(),
|
.arg(DocumentManager::currentResourcePath().path(),
|
||||||
m_textureToDrag.variantProperty("source").value().toString());
|
m_textureToDrag.variantProperty("source").value().toString());
|
||||||
model->startDrag(mimeData,
|
|
||||||
m_textureImageProvider->requestPixmap(iconPath, nullptr,
|
QPixmap pixmap;
|
||||||
{128, 128}));
|
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_materialToDrag = {};
|
||||||
m_textureToDrag = {};
|
m_textureToDrag = {};
|
||||||
@@ -161,14 +142,18 @@ bool MaterialBrowserWidget::eventFilter(QObject *obj, QEvent *event)
|
|||||||
return QObject::eventFilter(obj, event);
|
return QObject::eventFilter(obj, event);
|
||||||
}
|
}
|
||||||
|
|
||||||
MaterialBrowserWidget::MaterialBrowserWidget(MaterialBrowserView *view)
|
MaterialBrowserWidget::MaterialBrowserWidget(AsynchronousImageCache &imageCache,
|
||||||
|
MaterialBrowserView *view)
|
||||||
: m_materialBrowserView(view)
|
: m_materialBrowserView(view)
|
||||||
, m_materialBrowserModel(new MaterialBrowserModel(this))
|
, m_materialBrowserModel(new MaterialBrowserModel(this))
|
||||||
, m_materialBrowserTexturesModel(new MaterialBrowserTexturesModel(this))
|
, m_materialBrowserTexturesModel(new MaterialBrowserTexturesModel(this))
|
||||||
, m_quickWidget(new QQuickWidget(this))
|
, m_quickWidget(new QQuickWidget(this))
|
||||||
, m_previewImageProvider(new PreviewImageProvider())
|
, 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"));
|
setWindowTitle(tr("Material Browser", "Title of material browser widget"));
|
||||||
setMinimumWidth(120);
|
setMinimumWidth(120);
|
||||||
|
|
||||||
|
@@ -28,14 +28,14 @@ class MaterialBrowserView;
|
|||||||
class MaterialBrowserModel;
|
class MaterialBrowserModel;
|
||||||
class MaterialBrowserTexturesModel;
|
class MaterialBrowserTexturesModel;
|
||||||
class PreviewImageProvider;
|
class PreviewImageProvider;
|
||||||
class TextureImageProvider;
|
class PropertyEditorImageProvider;
|
||||||
|
|
||||||
class MaterialBrowserWidget : public QFrame
|
class MaterialBrowserWidget : public QFrame
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
MaterialBrowserWidget(MaterialBrowserView *view);
|
MaterialBrowserWidget(class AsynchronousImageCache &imageCache, MaterialBrowserView *view);
|
||||||
~MaterialBrowserWidget() = default;
|
~MaterialBrowserWidget() = default;
|
||||||
|
|
||||||
QList<QToolButton *> createToolBarWidgets();
|
QList<QToolButton *> createToolBarWidgets();
|
||||||
@@ -72,7 +72,7 @@ private:
|
|||||||
|
|
||||||
QShortcut *m_qmlSourceUpdateShortcut = nullptr;
|
QShortcut *m_qmlSourceUpdateShortcut = nullptr;
|
||||||
PreviewImageProvider *m_previewImageProvider = nullptr;
|
PreviewImageProvider *m_previewImageProvider = nullptr;
|
||||||
TextureImageProvider *m_textureImageProvider = nullptr;
|
PropertyEditorImageProvider *m_textureImageProvider = nullptr;
|
||||||
Core::IContext *m_context = nullptr;
|
Core::IContext *m_context = nullptr;
|
||||||
|
|
||||||
QString m_filterText;
|
QString m_filterText;
|
||||||
|
@@ -25,18 +25,25 @@ QQuickImageResponse *PropertyEditorImageProvider::requestImageResponse(const QSt
|
|||||||
return m_smallImageCacheProvider.requestImageResponse("#" + id.split('.').first(),
|
return m_smallImageCacheProvider.requestImageResponse("#" + id.split('.').first(),
|
||||||
requestedSize);
|
requestedSize);
|
||||||
|
|
||||||
QImage image;
|
auto response = std::make_unique<QmlDesigner::ImageResponse>(m_smallImageCacheProvider.defaultImage());
|
||||||
auto response = std::make_unique<QmlDesigner::ImageResponse>(image);
|
|
||||||
|
|
||||||
QMetaObject::invokeMethod(
|
QMetaObject::invokeMethod(
|
||||||
response.get(),
|
response.get(),
|
||||||
[response = QPointer<QmlDesigner::ImageResponse>(response.get()), image, suffix, id] {
|
[response = QPointer<QmlDesigner::ImageResponse>(response.get()), suffix, id, requestedSize] {
|
||||||
if (AssetsLibraryModel::supportedImageSuffixes().contains(suffix))
|
if (AssetsLibraryModel::supportedImageSuffixes().contains(suffix)) {
|
||||||
response->setImage(QImage(Utils::StyleHelper::dpiSpecificImageFile(id)));
|
QImage image = QImage(Utils::StyleHelper::dpiSpecificImageFile(id));
|
||||||
else if (AssetsLibraryModel::supportedTexture3DSuffixes().contains(suffix))
|
if (!image.isNull()) {
|
||||||
response->setImage(HdrImage{id}.image());
|
response->setImage(image.scaled(requestedSize, Qt::KeepAspectRatio));
|
||||||
else
|
return;
|
||||||
response->abort();
|
}
|
||||||
|
} 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);
|
Qt::QueuedConnection);
|
||||||
|
|
||||||
|
@@ -12,6 +12,7 @@
|
|||||||
|
|
||||||
#include <coreplugin/messagebox.h>
|
#include <coreplugin/messagebox.h>
|
||||||
#include <utils/algorithm.h>
|
#include <utils/algorithm.h>
|
||||||
|
#include <utils/filepath.h>
|
||||||
#include <utils/qtcassert.h>
|
#include <utils/qtcassert.h>
|
||||||
|
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
@@ -334,4 +335,11 @@ void TextureEditorContextObject::goIntoComponent()
|
|||||||
DocumentManager::goIntoComponent(m_selectedTexture);
|
DocumentManager::goIntoComponent(m_selectedTexture);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString TextureEditorContextObject::resolveResourcePath(const QString &path)
|
||||||
|
{
|
||||||
|
if (Utils::FilePath::fromString(path).isAbsolutePath())
|
||||||
|
return path;
|
||||||
|
return DocumentManager::currentResourcePath().path() + '/' + path;
|
||||||
|
}
|
||||||
|
|
||||||
} // QmlDesigner
|
} // QmlDesigner
|
||||||
|
@@ -73,6 +73,7 @@ public:
|
|||||||
|
|
||||||
Q_INVOKABLE bool isBlocked(const QString &propName) const;
|
Q_INVOKABLE bool isBlocked(const QString &propName) const;
|
||||||
Q_INVOKABLE void goIntoComponent();
|
Q_INVOKABLE void goIntoComponent();
|
||||||
|
Q_INVOKABLE QString resolveResourcePath(const QString &path);
|
||||||
|
|
||||||
enum ToolBarAction {
|
enum ToolBarAction {
|
||||||
ApplyToSelected,
|
ApplyToSelected,
|
||||||
|
@@ -6,6 +6,7 @@
|
|||||||
#include "bindingproperty.h"
|
#include "bindingproperty.h"
|
||||||
#include "documentmanager.h"
|
#include "documentmanager.h"
|
||||||
#include "nodemetainfo.h"
|
#include "nodemetainfo.h"
|
||||||
|
#include "propertyeditorimageprovider.h"
|
||||||
#include "propertyeditorvalue.h"
|
#include "propertyeditorvalue.h"
|
||||||
#include "qmldesignerconstants.h"
|
#include "qmldesignerconstants.h"
|
||||||
#include "qmlobjectnode.h"
|
#include "qmlobjectnode.h"
|
||||||
@@ -41,46 +42,17 @@ static QObject *variantToQObject(const QVariant &value)
|
|||||||
|
|
||||||
namespace QmlDesigner {
|
namespace QmlDesigner {
|
||||||
|
|
||||||
class TextureEditorImageProvider : public QQuickImageProvider
|
TextureEditorQmlBackend::TextureEditorQmlBackend(TextureEditorView *textureEditor, AsynchronousImageCache &imageCache)
|
||||||
{
|
|
||||||
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)
|
|
||||||
: m_view(new QQuickWidget)
|
: m_view(new QQuickWidget)
|
||||||
, m_textureEditorTransaction(new TextureEditorTransaction(textureEditor))
|
, m_textureEditorTransaction(new TextureEditorTransaction(textureEditor))
|
||||||
, m_contextObject(new TextureEditorContextObject(m_view->rootContext()))
|
, 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->setResizeMode(QQuickWidget::SizeRootObjectToView);
|
||||||
m_view->engine()->addImportPath(propertyEditorResourcesPath() + "/imports");
|
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->setBackendValues(&m_backendValuesPropertyMap);
|
||||||
m_contextObject->setModel(textureEditor->model());
|
m_contextObject->setModel(textureEditor->model());
|
||||||
context()->setContextObject(m_contextObject.data());
|
context()->setContextObject(m_contextObject.data());
|
||||||
|
@@ -17,6 +17,7 @@ QT_END_NAMESPACE
|
|||||||
|
|
||||||
namespace QmlDesigner {
|
namespace QmlDesigner {
|
||||||
|
|
||||||
|
class PropertyEditorImageProvider;
|
||||||
class TextureEditorContextObject;
|
class TextureEditorContextObject;
|
||||||
class TextureEditorImageProvider;
|
class TextureEditorImageProvider;
|
||||||
class TextureEditorTransaction;
|
class TextureEditorTransaction;
|
||||||
@@ -27,7 +28,8 @@ class TextureEditorQmlBackend
|
|||||||
Q_DISABLE_COPY(TextureEditorQmlBackend)
|
Q_DISABLE_COPY(TextureEditorQmlBackend)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
TextureEditorQmlBackend(TextureEditorView *materialEditor);
|
TextureEditorQmlBackend(TextureEditorView *materialEditor,
|
||||||
|
class AsynchronousImageCache &imageCache);
|
||||||
~TextureEditorQmlBackend();
|
~TextureEditorQmlBackend();
|
||||||
|
|
||||||
void setup(const QmlObjectNode &selectedTextureNode, const QString &stateName, const QUrl &qmlSpecificsFile,
|
void setup(const QmlObjectNode &selectedTextureNode, const QString &stateName, const QUrl &qmlSpecificsFile,
|
||||||
@@ -63,7 +65,7 @@ private:
|
|||||||
DesignerPropertyMap m_backendValuesPropertyMap;
|
DesignerPropertyMap m_backendValuesPropertyMap;
|
||||||
QScopedPointer<TextureEditorTransaction> m_textureEditorTransaction;
|
QScopedPointer<TextureEditorTransaction> m_textureEditorTransaction;
|
||||||
QScopedPointer<TextureEditorContextObject> m_contextObject;
|
QScopedPointer<TextureEditorContextObject> m_contextObject;
|
||||||
TextureEditorImageProvider *m_textureEditorImageProvider = nullptr;
|
PropertyEditorImageProvider *m_textureEditorImageProvider = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace QmlDesigner
|
} // namespace QmlDesigner
|
||||||
|
@@ -49,8 +49,10 @@
|
|||||||
|
|
||||||
namespace QmlDesigner {
|
namespace QmlDesigner {
|
||||||
|
|
||||||
TextureEditorView::TextureEditorView(ExternalDependenciesInterface &externalDependencies)
|
TextureEditorView::TextureEditorView(AsynchronousImageCache &imageCache,
|
||||||
|
ExternalDependenciesInterface &externalDependencies)
|
||||||
: AbstractView{externalDependencies}
|
: AbstractView{externalDependencies}
|
||||||
|
, m_imageCache(imageCache)
|
||||||
, m_stackedWidget(new QStackedWidget)
|
, m_stackedWidget(new QStackedWidget)
|
||||||
, m_dynamicPropertiesModel(new Internal::DynamicPropertiesModel(true, this))
|
, m_dynamicPropertiesModel(new Internal::DynamicPropertiesModel(true, this))
|
||||||
{
|
{
|
||||||
@@ -432,7 +434,7 @@ void TextureEditorView::setupQmlBackend()
|
|||||||
QString currentStateName = currentState().isBaseState() ? currentState().name() : "invalid state";
|
QString currentStateName = currentState().isBaseState() ? currentState().name() : "invalid state";
|
||||||
|
|
||||||
if (!currentQmlBackend) {
|
if (!currentQmlBackend) {
|
||||||
currentQmlBackend = new TextureEditorQmlBackend(this);
|
currentQmlBackend = new TextureEditorQmlBackend(this, m_imageCache);
|
||||||
|
|
||||||
m_stackedWidget->addWidget(currentQmlBackend->widget());
|
m_stackedWidget->addWidget(currentQmlBackend->widget());
|
||||||
m_qmlBackendHash.insert(qmlPaneUrl.toString(), currentQmlBackend);
|
m_qmlBackendHash.insert(qmlPaneUrl.toString(), currentQmlBackend);
|
||||||
|
@@ -31,7 +31,8 @@ class TextureEditorView : public AbstractView
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
TextureEditorView(ExternalDependenciesInterface &externalDependencies);
|
TextureEditorView(class AsynchronousImageCache &imageCache,
|
||||||
|
ExternalDependenciesInterface &externalDependencies);
|
||||||
~TextureEditorView() override;
|
~TextureEditorView() override;
|
||||||
|
|
||||||
bool hasWidget() const override;
|
bool hasWidget() const override;
|
||||||
@@ -105,6 +106,7 @@ private:
|
|||||||
|
|
||||||
bool noValidSelection() const;
|
bool noValidSelection() const;
|
||||||
|
|
||||||
|
AsynchronousImageCache &m_imageCache;
|
||||||
ModelNode m_selectedTexture;
|
ModelNode m_selectedTexture;
|
||||||
QTimer m_ensureMatLibTimer;
|
QTimer m_ensureMatLibTimer;
|
||||||
QShortcut *m_updateShortcut = nullptr;
|
QShortcut *m_updateShortcut = nullptr;
|
||||||
|
@@ -14,6 +14,7 @@
|
|||||||
#include <projectexplorer/target.h>
|
#include <projectexplorer/target.h>
|
||||||
#include <utils/fileutils.h>
|
#include <utils/fileutils.h>
|
||||||
|
|
||||||
|
#include <QGuiApplication>
|
||||||
#include <QPlainTextEdit>
|
#include <QPlainTextEdit>
|
||||||
|
|
||||||
namespace QmlDesigner {
|
namespace QmlDesigner {
|
||||||
@@ -103,7 +104,11 @@ void ImageCacheCollector::start(Utils::SmallStringView name,
|
|||||||
auto callback = [=, captureCallback = std::move(captureCallback)](const QImage &image) {
|
auto callback = [=, captureCallback = std::move(captureCallback)](const QImage &image) {
|
||||||
if (nullImageHandling == ImageCacheCollectorNullImageHandling::CaptureNullImage
|
if (nullImageHandling == ImageCacheCollectorNullImageHandling::CaptureNullImage
|
||||||
|| !image.isNull()) {
|
|| !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);
|
Qt::KeepAspectRatio);
|
||||||
QImage smallImage = image.isNull() ? QImage{}
|
QImage smallImage = image.isNull() ? QImage{}
|
||||||
: image.scaled(smallImageSize,
|
: image.scaled(smallImageSize,
|
||||||
|
@@ -20,6 +20,7 @@ public:
|
|||||||
QQuickTextureFactory *textureFactory() const override;
|
QQuickTextureFactory *textureFactory() const override;
|
||||||
|
|
||||||
void setImage(const QImage &image);
|
void setImage(const QImage &image);
|
||||||
|
QImage image() const { return m_image; }
|
||||||
|
|
||||||
void abort();
|
void abort();
|
||||||
|
|
||||||
@@ -37,6 +38,7 @@ public:
|
|||||||
|
|
||||||
QQuickImageResponse *requestImageResponse(const QString &id,
|
QQuickImageResponse *requestImageResponse(const QString &id,
|
||||||
const QSize &requestedSize) override;
|
const QSize &requestedSize) override;
|
||||||
|
QImage defaultImage() const { return m_defaultImage; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
AsynchronousImageCache &m_cache;
|
AsynchronousImageCache &m_cache;
|
||||||
|
Reference in New Issue
Block a user