forked from qt-creator/qt-creator
QmlDesigner: Add tooltips to UrlChooser
* Add tooltips with thumbnails to UrlChooser enable preview of image formats and meshes * Add property editor image provider which makes use of the image cache * Add mesh image cache collector in order to create thumbnails for meshes and built-in primitves * Fix typo in explicit image cache image provider * Add return value in time stamp provider if provided file does not exist Change-Id: I2290d2ace87ddd90e9899e343f2ad1ecd2993fdf Reviewed-by: <github-actions-qt-creator@cristianadam.eu> Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io>
This commit is contained in:
committed by
Henning Gründl
parent
1c6fa83648
commit
bd51b4fdc2
@@ -44,6 +44,9 @@ Row {
|
|||||||
// by QtQuick3D to add built-in primitives to the model.
|
// by QtQuick3D to add built-in primitives to the model.
|
||||||
property var defaultItems
|
property var defaultItems
|
||||||
|
|
||||||
|
// Current item
|
||||||
|
property string absoluteFilePath: ""
|
||||||
|
|
||||||
FileResourcesModel {
|
FileResourcesModel {
|
||||||
id: fileModel
|
id: fileModel
|
||||||
modelNodeBackendProperty: modelNodeBackend
|
modelNodeBackendProperty: modelNodeBackend
|
||||||
@@ -74,16 +77,64 @@ Row {
|
|||||||
visible: comboBox.hover && toolTip.text !== ""
|
visible: comboBox.hover && toolTip.text !== ""
|
||||||
text: root.backendValue.valueToString
|
text: root.backendValue.valueToString
|
||||||
delay: StudioTheme.Values.toolTipDelay
|
delay: StudioTheme.Values.toolTipDelay
|
||||||
height: StudioTheme.Values.toolTipHeight
|
|
||||||
background: Rectangle {
|
background: Rectangle {
|
||||||
color: StudioTheme.Values.themeToolTipBackground
|
color: StudioTheme.Values.themeToolTipBackground
|
||||||
border.color: StudioTheme.Values.themeToolTipOutline
|
border.color: StudioTheme.Values.themeToolTipOutline
|
||||||
border.width: StudioTheme.Values.border
|
border.width: StudioTheme.Values.border
|
||||||
}
|
}
|
||||||
contentItem: Text {
|
|
||||||
|
contentItem: RowLayout {
|
||||||
|
spacing: 10
|
||||||
|
|
||||||
|
Item {
|
||||||
|
visible: thumbnail.status === Image.Ready
|
||||||
|
Layout.preferredWidth: 100
|
||||||
|
Layout.preferredHeight: 100
|
||||||
|
|
||||||
|
Image {
|
||||||
|
id: checker
|
||||||
|
visible: !root.isMesh(root.absoluteFilePath)
|
||||||
|
anchors.fill: parent
|
||||||
|
fillMode: Image.Tile
|
||||||
|
source: "images/checkers.png"
|
||||||
|
}
|
||||||
|
|
||||||
|
Image {
|
||||||
|
id: thumbnail
|
||||||
|
asynchronous: true
|
||||||
|
anchors.fill: parent
|
||||||
|
fillMode: Image.PreserveAspectFit
|
||||||
|
source: {
|
||||||
|
if (root.isBuiltInPrimitive(root.absoluteFilePath))
|
||||||
|
return "image://qmldesigner_thumbnails/"
|
||||||
|
+ root.absoluteFilePath.substring(1, root.absoluteFilePath.length)
|
||||||
|
+ ".builtin"
|
||||||
|
|
||||||
|
if (fileModel.isLocal(root.absoluteFilePath))
|
||||||
|
return "image://qmldesigner_thumbnails/" + root.absoluteFilePath
|
||||||
|
|
||||||
|
return root.absoluteFilePath
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
Text {
|
||||||
|
text: root.fileName(toolTip.text)
|
||||||
color: StudioTheme.Values.themeToolTipText
|
color: StudioTheme.Values.themeToolTipText
|
||||||
text: toolTip.text
|
font: toolTip.font
|
||||||
verticalAlignment: Text.AlignVCenter
|
}
|
||||||
|
|
||||||
|
Text {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
text: root.isBuiltInPrimitive(toolTip.text) ? qsTr("Built-in primitive")
|
||||||
|
: toolTip.text
|
||||||
|
font: toolTip.font
|
||||||
|
color: StudioTheme.Values.themeToolTipText
|
||||||
|
wrapMode: Text.WordWrap
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -155,16 +206,62 @@ Row {
|
|||||||
visible: delegateRoot.hovered
|
visible: delegateRoot.hovered
|
||||||
text: delegateRoot.relativeFilePath
|
text: delegateRoot.relativeFilePath
|
||||||
delay: StudioTheme.Values.toolTipDelay
|
delay: StudioTheme.Values.toolTipDelay
|
||||||
height: StudioTheme.Values.toolTipHeight
|
|
||||||
background: Rectangle {
|
background: Rectangle {
|
||||||
color: StudioTheme.Values.themeToolTipBackground
|
color: StudioTheme.Values.themeToolTipBackground
|
||||||
border.color: StudioTheme.Values.themeToolTipOutline
|
border.color: StudioTheme.Values.themeToolTipOutline
|
||||||
border.width: StudioTheme.Values.border
|
border.width: StudioTheme.Values.border
|
||||||
}
|
}
|
||||||
contentItem: Text {
|
|
||||||
|
contentItem: RowLayout {
|
||||||
|
spacing: 10
|
||||||
|
|
||||||
|
Item {
|
||||||
|
visible: delegateThumbnail.status === Image.Ready
|
||||||
|
Layout.preferredWidth: 100
|
||||||
|
Layout.preferredHeight: 100
|
||||||
|
|
||||||
|
Image {
|
||||||
|
id: delegateChecker
|
||||||
|
visible: !root.isMesh(delegateRoot.absoluteFilePath)
|
||||||
|
anchors.fill: parent
|
||||||
|
fillMode: Image.Tile
|
||||||
|
source: "images/checkers.png"
|
||||||
|
}
|
||||||
|
|
||||||
|
Image {
|
||||||
|
id: delegateThumbnail
|
||||||
|
asynchronous: true
|
||||||
|
anchors.fill: parent
|
||||||
|
fillMode: Image.PreserveAspectFit
|
||||||
|
source: {
|
||||||
|
if (root.isBuiltInPrimitive(delegateRoot.name))
|
||||||
|
return "image://qmldesigner_thumbnails/"
|
||||||
|
+ delegateRoot.name.substring(1, delegateRoot.name.length)
|
||||||
|
+ ".builtin"
|
||||||
|
|
||||||
|
return "image://qmldesigner_thumbnails/" + delegateRoot.absoluteFilePath
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
Text {
|
||||||
|
text: delegateRoot.name
|
||||||
color: StudioTheme.Values.themeToolTipText
|
color: StudioTheme.Values.themeToolTipText
|
||||||
text: itemToolTip.text
|
font: delegateToolTip.font
|
||||||
verticalAlignment: Text.AlignVCenter
|
}
|
||||||
|
|
||||||
|
Text {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
text: root.isBuiltInPrimitive(delegateToolTip.text)
|
||||||
|
? qsTr("Built-in primitive")
|
||||||
|
: delegateToolTip.text
|
||||||
|
font: delegateToolTip.font
|
||||||
|
color: StudioTheme.Values.themeToolTipText
|
||||||
|
wrapMode: Text.WordWrap
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -235,6 +332,10 @@ Row {
|
|||||||
inputValue = comboBox.items.get(index).model.relativeFilePath
|
inputValue = comboBox.items.get(index).model.relativeFilePath
|
||||||
|
|
||||||
root.backendValue.value = inputValue
|
root.backendValue.value = inputValue
|
||||||
|
|
||||||
|
if (!root.backendValue.isBound)
|
||||||
|
root.absoluteFilePath = fileModel.resolve(root.backendValue.value)
|
||||||
|
|
||||||
comboBox.dirty = false
|
comboBox.dirty = false
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -259,6 +360,9 @@ Row {
|
|||||||
if (root.backendValue.value !== inputValue)
|
if (root.backendValue.value !== inputValue)
|
||||||
root.backendValue.value = inputValue
|
root.backendValue.value = inputValue
|
||||||
|
|
||||||
|
if (!root.backendValue.isBound)
|
||||||
|
root.absoluteFilePath = fileModel.resolve(root.backendValue.value)
|
||||||
|
|
||||||
comboBox.dirty = false
|
comboBox.dirty = false
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -275,6 +379,23 @@ Row {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function isBuiltInPrimitive(value) {
|
||||||
|
return value.startsWith('#')
|
||||||
|
}
|
||||||
|
|
||||||
|
function isMesh(value) {
|
||||||
|
return root.isBuiltInPrimitive(value)
|
||||||
|
|| root.hasFileExtension(root.fileName(value), "mesh")
|
||||||
|
}
|
||||||
|
|
||||||
|
function hasFileExtension(fileName, extension) {
|
||||||
|
return fileName.split('.').pop() === extension
|
||||||
|
}
|
||||||
|
|
||||||
|
function fileName(filePath) {
|
||||||
|
return filePath.substr(filePath.lastIndexOf('/') + 1)
|
||||||
|
}
|
||||||
|
|
||||||
function createModel() {
|
function createModel() {
|
||||||
// Build the combobox model
|
// Build the combobox model
|
||||||
comboBox.listModel.clear()
|
comboBox.listModel.clear()
|
||||||
@@ -322,6 +443,9 @@ Row {
|
|||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
root.createModel()
|
root.createModel()
|
||||||
comboBox.updateTextValue()
|
comboBox.updateTextValue()
|
||||||
|
|
||||||
|
if (!root.backendValue.isBound)
|
||||||
|
root.absoluteFilePath = fileModel.resolve(root.backendValue.value)
|
||||||
}
|
}
|
||||||
|
|
||||||
function indexOf(model, criteria) {
|
function indexOf(model, criteria) {
|
||||||
@@ -340,7 +464,7 @@ Row {
|
|||||||
if (comboBox.popup.opened && !root.backendValue.isBound) {
|
if (comboBox.popup.opened && !root.backendValue.isBound) {
|
||||||
var index = root.indexOf(comboBox.items,
|
var index = root.indexOf(comboBox.items,
|
||||||
function(item) {
|
function(item) {
|
||||||
return item.fullPath === root.backendValue.value
|
return item.relativeFilePath === root.backendValue.value
|
||||||
})
|
})
|
||||||
|
|
||||||
if (index !== -1) {
|
if (index !== -1) {
|
||||||
@@ -359,8 +483,10 @@ Row {
|
|||||||
iconColor: root.textColor
|
iconColor: root.textColor
|
||||||
onClicked: {
|
onClicked: {
|
||||||
fileModel.openFileDialog()
|
fileModel.openFileDialog()
|
||||||
if (fileModel.fileName !== "")
|
if (fileModel.fileName !== "") {
|
||||||
root.backendValue.value = fileModel.fileName
|
root.backendValue.value = fileModel.fileName
|
||||||
|
root.absoluteFilePath = fileModel.resolve(root.backendValue.value)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -302,6 +302,7 @@ extend_qtc_plugin(QmlDesigner
|
|||||||
gradientpresetitem.cpp gradientpresetitem.h
|
gradientpresetitem.cpp gradientpresetitem.h
|
||||||
gradientpresetlistmodel.cpp gradientpresetlistmodel.h
|
gradientpresetlistmodel.cpp gradientpresetlistmodel.h
|
||||||
propertyeditorcontextobject.cpp propertyeditorcontextobject.h
|
propertyeditorcontextobject.cpp propertyeditorcontextobject.h
|
||||||
|
propertyeditorimageprovider.cpp propertyeditorimageprovider.h
|
||||||
propertyeditorqmlbackend.cpp propertyeditorqmlbackend.h
|
propertyeditorqmlbackend.cpp propertyeditorqmlbackend.h
|
||||||
propertyeditortransaction.cpp propertyeditortransaction.h
|
propertyeditortransaction.cpp propertyeditortransaction.h
|
||||||
propertyeditorvalue.cpp propertyeditorvalue.h
|
propertyeditorvalue.cpp propertyeditorvalue.h
|
||||||
@@ -389,7 +390,8 @@ extend_qtc_plugin(QmlDesigner
|
|||||||
SOURCES
|
SOURCES
|
||||||
explicitimagecacheimageprovider.cpp
|
explicitimagecacheimageprovider.cpp
|
||||||
explicitimagecacheimageprovider.h
|
explicitimagecacheimageprovider.h
|
||||||
|
smallimagecacheprovider.cpp
|
||||||
|
smallimagecacheprovider.h
|
||||||
)
|
)
|
||||||
|
|
||||||
extend_qtc_plugin(QmlDesigner
|
extend_qtc_plugin(QmlDesigner
|
||||||
|
|||||||
@@ -0,0 +1,68 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2022 The Qt Company Ltd.
|
||||||
|
** Contact: https://www.qt.io/licensing/
|
||||||
|
**
|
||||||
|
** This file is part of Qt Creator.
|
||||||
|
**
|
||||||
|
** Commercial License Usage
|
||||||
|
** Licensees holding valid commercial Qt licenses may use this file in
|
||||||
|
** accordance with the commercial license agreement provided with the
|
||||||
|
** Software or, alternatively, in accordance with the terms contained in
|
||||||
|
** a written agreement between you and The Qt Company. For licensing terms
|
||||||
|
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||||
|
** information use the contact form at https://www.qt.io/contact-us.
|
||||||
|
**
|
||||||
|
** GNU General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU
|
||||||
|
** General Public License version 3 as published by the Free Software
|
||||||
|
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||||
|
** included in the packaging of this file. Please review the following
|
||||||
|
** information to ensure the GNU General Public License requirements will
|
||||||
|
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#include "propertyeditorimageprovider.h"
|
||||||
|
#include "assetslibrarymodel.h"
|
||||||
|
|
||||||
|
#include <hdrimage.h>
|
||||||
|
#include <projectexplorer/target.h>
|
||||||
|
#include <utils/stylehelper.h>
|
||||||
|
|
||||||
|
#include <QMetaObject>
|
||||||
|
#include <QQuickImageResponse>
|
||||||
|
|
||||||
|
namespace QmlDesigner {
|
||||||
|
|
||||||
|
QQuickImageResponse *PropertyEditorImageProvider::requestImageResponse(const QString &id,
|
||||||
|
const QSize &requestedSize)
|
||||||
|
{
|
||||||
|
const QString suffix = "*." + id.split('.').last().toLower();
|
||||||
|
|
||||||
|
if (suffix == "*.mesh")
|
||||||
|
return m_smallImageCacheProvider.requestImageResponse(id, requestedSize);
|
||||||
|
|
||||||
|
if (suffix == "*.builtin")
|
||||||
|
return m_smallImageCacheProvider.requestImageResponse("#" + id.split('.').first(),
|
||||||
|
requestedSize);
|
||||||
|
|
||||||
|
QImage image;
|
||||||
|
auto response = std::make_unique<QmlDesigner::ImageResponse>(image);
|
||||||
|
|
||||||
|
QMetaObject::invokeMethod(
|
||||||
|
response.get(),
|
||||||
|
[response = QPointer<QmlDesigner::ImageResponse>(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();
|
||||||
|
},
|
||||||
|
Qt::QueuedConnection);
|
||||||
|
|
||||||
|
return response.release();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace QmlDesigner
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2022 The Qt Company Ltd.
|
||||||
|
** Contact: https://www.qt.io/licensing/
|
||||||
|
**
|
||||||
|
** This file is part of Qt Creator.
|
||||||
|
**
|
||||||
|
** Commercial License Usage
|
||||||
|
** Licensees holding valid commercial Qt licenses may use this file in
|
||||||
|
** accordance with the commercial license agreement provided with the
|
||||||
|
** Software or, alternatively, in accordance with the terms contained in
|
||||||
|
** a written agreement between you and The Qt Company. For licensing terms
|
||||||
|
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||||
|
** information use the contact form at https://www.qt.io/contact-us.
|
||||||
|
**
|
||||||
|
** GNU General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU
|
||||||
|
** General Public License version 3 as published by the Free Software
|
||||||
|
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||||
|
** included in the packaging of this file. Please review the following
|
||||||
|
** information to ensure the GNU General Public License requirements will
|
||||||
|
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "imagecache/smallimagecacheprovider.h"
|
||||||
|
|
||||||
|
#include <QQuickAsyncImageProvider>
|
||||||
|
|
||||||
|
namespace QmlDesigner {
|
||||||
|
|
||||||
|
class PropertyEditorImageProvider : public QQuickAsyncImageProvider
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
PropertyEditorImageProvider(AsynchronousImageCache &imageCache, const QImage &defaultImage = {})
|
||||||
|
: m_smallImageCacheProvider(imageCache, defaultImage)
|
||||||
|
{}
|
||||||
|
|
||||||
|
QQuickImageResponse *requestImageResponse(const QString &id,
|
||||||
|
const QSize &requestedSize) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
SmallImageCacheProvider m_smallImageCacheProvider;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace QmlDesigner
|
||||||
@@ -95,9 +95,12 @@ static QObject *variantToQObject(const QVariant &value)
|
|||||||
|
|
||||||
namespace QmlDesigner {
|
namespace QmlDesigner {
|
||||||
|
|
||||||
PropertyEditorQmlBackend::PropertyEditorQmlBackend(PropertyEditorView *propertyEditor) :
|
PropertyEditorQmlBackend::PropertyEditorQmlBackend(PropertyEditorView *propertyEditor,
|
||||||
m_view(new Quick2PropertyEditorView), m_propertyEditorTransaction(new PropertyEditorTransaction(propertyEditor)), m_dummyPropertyEditorValue(new PropertyEditorValue()),
|
AsynchronousImageCache &imageCache)
|
||||||
m_contextObject(new PropertyEditorContextObject())
|
: m_view(new Quick2PropertyEditorView(imageCache))
|
||||||
|
, m_propertyEditorTransaction(new PropertyEditorTransaction(propertyEditor))
|
||||||
|
, m_dummyPropertyEditorValue(new PropertyEditorValue())
|
||||||
|
, m_contextObject(new PropertyEditorContextObject())
|
||||||
{
|
{
|
||||||
m_view->engine()->setOutputWarningsToStandardError(QmlDesignerPlugin::instance()
|
m_view->engine()->setOutputWarningsToStandardError(QmlDesignerPlugin::instance()
|
||||||
->settings().value(DesignerSettingsKey::SHOW_PROPERTYEDITOR_WARNINGS).toBool());
|
->settings().value(DesignerSettingsKey::SHOW_PROPERTYEDITOR_WARNINGS).toBool());
|
||||||
@@ -115,7 +118,9 @@ PropertyEditorQmlBackend::PropertyEditorQmlBackend(PropertyEditorView *propertyE
|
|||||||
|
|
||||||
PropertyEditorQmlBackend::~PropertyEditorQmlBackend() = default;
|
PropertyEditorQmlBackend::~PropertyEditorQmlBackend() = default;
|
||||||
|
|
||||||
void PropertyEditorQmlBackend::setupPropertyEditorValue(const PropertyName &name, PropertyEditorView *propertyEditor, const QString &type)
|
void PropertyEditorQmlBackend::setupPropertyEditorValue(const PropertyName &name,
|
||||||
|
PropertyEditorView *propertyEditor,
|
||||||
|
const QString &type)
|
||||||
{
|
{
|
||||||
QmlDesigner::PropertyName propertyName(name);
|
QmlDesigner::PropertyName propertyName(name);
|
||||||
propertyName.replace('.', '_');
|
propertyName.replace('.', '_');
|
||||||
|
|||||||
@@ -50,7 +50,8 @@ class PropertyEditorQmlBackend
|
|||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
PropertyEditorQmlBackend(PropertyEditorView *propertyEditor);
|
PropertyEditorQmlBackend(PropertyEditorView *propertyEditor,
|
||||||
|
class AsynchronousImageCache &imageCache);
|
||||||
~PropertyEditorQmlBackend();
|
~PropertyEditorQmlBackend();
|
||||||
|
|
||||||
void setup(const QmlObjectNode &fxObjectNode, const QString &stateName, const QUrl &qmlSpecificsFile, PropertyEditorView *propertyEditor);
|
void setup(const QmlObjectNode &fxObjectNode, const QString &stateName, const QUrl &qmlSpecificsFile, PropertyEditorView *propertyEditor);
|
||||||
|
|||||||
@@ -69,16 +69,16 @@ static bool propertyIsAttachedLayoutProperty(const PropertyName &propertyName)
|
|||||||
return propertyName.contains("Layout.");
|
return propertyName.contains("Layout.");
|
||||||
}
|
}
|
||||||
|
|
||||||
PropertyEditorView::PropertyEditorView(QWidget *parent) :
|
PropertyEditorView::PropertyEditorView(AsynchronousImageCache &imageCache)
|
||||||
AbstractView(parent),
|
: AbstractView()
|
||||||
m_parent(parent),
|
, m_imageCache(imageCache)
|
||||||
m_updateShortcut(nullptr),
|
, m_updateShortcut(nullptr)
|
||||||
m_timerId(0),
|
, m_timerId(0)
|
||||||
m_stackedWidget(new PropertyEditorWidget(parent)),
|
, m_stackedWidget(new PropertyEditorWidget())
|
||||||
m_qmlBackEndForCurrentType(nullptr),
|
, m_qmlBackEndForCurrentType(nullptr)
|
||||||
m_locked(false),
|
, m_locked(false)
|
||||||
m_setupCompleted(false),
|
, m_setupCompleted(false)
|
||||||
m_singleShotTimer(new QTimer(this))
|
, m_singleShotTimer(new QTimer(this))
|
||||||
{
|
{
|
||||||
m_qmlDir = PropertyEditorQmlBackend::propertyEditorResourcesPath();
|
m_qmlDir = PropertyEditorQmlBackend::propertyEditorResourcesPath();
|
||||||
|
|
||||||
@@ -117,7 +117,7 @@ void PropertyEditorView::setupPane(const TypeName &typeName)
|
|||||||
PropertyEditorQmlBackend *qmlBackend = m_qmlBackendHash.value(qmlFile.toString());
|
PropertyEditorQmlBackend *qmlBackend = m_qmlBackendHash.value(qmlFile.toString());
|
||||||
|
|
||||||
if (!qmlBackend) {
|
if (!qmlBackend) {
|
||||||
qmlBackend = new PropertyEditorQmlBackend(this);
|
qmlBackend = new PropertyEditorQmlBackend(this, m_imageCache);
|
||||||
|
|
||||||
qmlBackend->initialSetup(typeName, qmlSpecificsFile, this);
|
qmlBackend->initialSetup(typeName, qmlSpecificsFile, this);
|
||||||
qmlBackend->setSource(qmlFile);
|
qmlBackend->setSource(qmlFile);
|
||||||
@@ -484,7 +484,7 @@ void PropertyEditorView::setupQmlBackend()
|
|||||||
QString currentStateName = currentState().isBaseState() ? currentState().name() : QStringLiteral("invalid state");
|
QString currentStateName = currentState().isBaseState() ? currentState().name() : QStringLiteral("invalid state");
|
||||||
|
|
||||||
if (!currentQmlBackend) {
|
if (!currentQmlBackend) {
|
||||||
currentQmlBackend = new PropertyEditorQmlBackend(this);
|
currentQmlBackend = new PropertyEditorQmlBackend(this, m_imageCache);
|
||||||
|
|
||||||
m_stackedWidget->addWidget(currentQmlBackend->widget());
|
m_stackedWidget->addWidget(currentQmlBackend->widget());
|
||||||
m_qmlBackendHash.insert(qmlFile.toString(), currentQmlBackend);
|
m_qmlBackendHash.insert(qmlFile.toString(), currentQmlBackend);
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ class PropertyEditorView: public AbstractView
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
PropertyEditorView(QWidget *parent = nullptr);
|
PropertyEditorView(class AsynchronousImageCache &imageCache);
|
||||||
~PropertyEditorView() override;
|
~PropertyEditorView() override;
|
||||||
|
|
||||||
bool hasWidget() const override;
|
bool hasWidget() const override;
|
||||||
@@ -119,8 +119,8 @@ private: //functions
|
|||||||
bool noValidSelection() const;
|
bool noValidSelection() const;
|
||||||
|
|
||||||
private: //variables
|
private: //variables
|
||||||
|
AsynchronousImageCache &m_imageCache;
|
||||||
ModelNode m_selectedNode;
|
ModelNode m_selectedNode;
|
||||||
QWidget *m_parent;
|
|
||||||
QShortcut *m_updateShortcut;
|
QShortcut *m_updateShortcut;
|
||||||
int m_timerId;
|
int m_timerId;
|
||||||
PropertyEditorWidget* m_stackedWidget;
|
PropertyEditorWidget* m_stackedWidget;
|
||||||
|
|||||||
@@ -36,6 +36,7 @@
|
|||||||
#include "gradientpresetdefaultlistmodel.h"
|
#include "gradientpresetdefaultlistmodel.h"
|
||||||
#include "itemfiltermodel.h"
|
#include "itemfiltermodel.h"
|
||||||
#include "propertyeditorcontextobject.h"
|
#include "propertyeditorcontextobject.h"
|
||||||
|
#include "propertyeditorimageprovider.h"
|
||||||
#include "propertyeditorqmlbackend.h"
|
#include "propertyeditorqmlbackend.h"
|
||||||
#include "propertyeditorvalue.h"
|
#include "propertyeditorvalue.h"
|
||||||
#include "qmlanchorbindingproxy.h"
|
#include "qmlanchorbindingproxy.h"
|
||||||
@@ -45,11 +46,13 @@
|
|||||||
|
|
||||||
namespace QmlDesigner {
|
namespace QmlDesigner {
|
||||||
|
|
||||||
Quick2PropertyEditorView::Quick2PropertyEditorView(QWidget *parent) :
|
Quick2PropertyEditorView::Quick2PropertyEditorView(AsynchronousImageCache &imageCache)
|
||||||
QQuickWidget(parent)
|
: QQuickWidget()
|
||||||
{
|
{
|
||||||
setResizeMode(QQuickWidget::SizeRootObjectToView);
|
setResizeMode(QQuickWidget::SizeRootObjectToView);
|
||||||
Theme::setupTheme(engine());
|
Theme::setupTheme(engine());
|
||||||
|
engine()->addImageProvider("qmldesigner_thumbnails",
|
||||||
|
new PropertyEditorImageProvider(imageCache));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Quick2PropertyEditorView::registerQmlTypes()
|
void Quick2PropertyEditorView::registerQmlTypes()
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ class Quick2PropertyEditorView : public QQuickWidget
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit Quick2PropertyEditorView(QWidget *parent = nullptr);
|
explicit Quick2PropertyEditorView(class AsynchronousImageCache &imageCache);
|
||||||
|
|
||||||
static void registerQmlTypes();
|
static void registerQmlTypes();
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -30,12 +30,12 @@
|
|||||||
#include <QMetaObject>
|
#include <QMetaObject>
|
||||||
#include <QQuickImageResponse>
|
#include <QQuickImageResponse>
|
||||||
|
|
||||||
namespace QmlDesigner {
|
namespace {
|
||||||
|
|
||||||
class ImageRespose : public QQuickImageResponse
|
class ImageResponse : public QQuickImageResponse
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ImageRespose(const QImage &defaultImage)
|
ImageResponse(const QImage &defaultImage)
|
||||||
: m_image(defaultImage)
|
: m_image(defaultImage)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
@@ -57,14 +57,18 @@ private:
|
|||||||
QImage m_image;
|
QImage m_image;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
namespace QmlDesigner {
|
||||||
|
|
||||||
QQuickImageResponse *ExplicitImageCacheImageProvider::requestImageResponse(const QString &id,
|
QQuickImageResponse *ExplicitImageCacheImageProvider::requestImageResponse(const QString &id,
|
||||||
const QSize &)
|
const QSize &)
|
||||||
{
|
{
|
||||||
auto response = std::make_unique<ImageRespose>(m_defaultImage);
|
auto response = std::make_unique<::ImageResponse>(m_defaultImage);
|
||||||
|
|
||||||
m_cache.requestImage(
|
m_cache.requestImage(
|
||||||
id,
|
id,
|
||||||
[response = QPointer<ImageRespose>(response.get())](const QImage &image) {
|
[response = QPointer<::ImageResponse>(response.get())](const QImage &image) {
|
||||||
QMetaObject::invokeMethod(
|
QMetaObject::invokeMethod(
|
||||||
response,
|
response,
|
||||||
[response, image] {
|
[response, image] {
|
||||||
@@ -73,7 +77,7 @@ QQuickImageResponse *ExplicitImageCacheImageProvider::requestImageResponse(const
|
|||||||
},
|
},
|
||||||
Qt::QueuedConnection);
|
Qt::QueuedConnection);
|
||||||
},
|
},
|
||||||
[response = QPointer<ImageRespose>(response.get())](ImageCache::AbortReason abortReason) {
|
[response = QPointer<::ImageResponse>(response.get())](ImageCache::AbortReason abortReason) {
|
||||||
QMetaObject::invokeMethod(
|
QMetaObject::invokeMethod(
|
||||||
response,
|
response,
|
||||||
[response, abortReason] {
|
[response, abortReason] {
|
||||||
|
|||||||
@@ -0,0 +1,112 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2022 The Qt Company Ltd.
|
||||||
|
** Contact: https://www.qt.io/licensing/
|
||||||
|
**
|
||||||
|
** This file is part of Qt Creator.
|
||||||
|
**
|
||||||
|
** Commercial License Usage
|
||||||
|
** Licensees holding valid commercial Qt licenses may use this file in
|
||||||
|
** accordance with the commercial license agreement provided with the
|
||||||
|
** Software or, alternatively, in accordance with the terms contained in
|
||||||
|
** a written agreement between you and The Qt Company. For licensing terms
|
||||||
|
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||||
|
** information use the contact form at https://www.qt.io/contact-us.
|
||||||
|
**
|
||||||
|
** GNU General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU
|
||||||
|
** General Public License version 3 as published by the Free Software
|
||||||
|
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||||
|
** included in the packaging of this file. Please review the following
|
||||||
|
** information to ensure the GNU General Public License requirements will
|
||||||
|
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#include "meshimagecachecollector.h"
|
||||||
|
#include "imagecacheconnectionmanager.h"
|
||||||
|
|
||||||
|
#include <projectexplorer/target.h>
|
||||||
|
#include <utils/smallstring.h>
|
||||||
|
#include <qtsupport/qtkitinformation.h>
|
||||||
|
|
||||||
|
#include <QTemporaryFile>
|
||||||
|
|
||||||
|
namespace QmlDesigner {
|
||||||
|
|
||||||
|
MeshImageCacheCollector::MeshImageCacheCollector(
|
||||||
|
ImageCacheConnectionManager &connectionManager,
|
||||||
|
QSize captureImageMinimumSize,
|
||||||
|
QSize captureImageMaximumSize,
|
||||||
|
ImageCacheCollectorNullImageHandling nullImageHandling)
|
||||||
|
: m_imageCacheCollector(connectionManager,
|
||||||
|
captureImageMinimumSize,
|
||||||
|
captureImageMaximumSize,
|
||||||
|
nullImageHandling)
|
||||||
|
{}
|
||||||
|
|
||||||
|
MeshImageCacheCollector::~MeshImageCacheCollector() = default;
|
||||||
|
|
||||||
|
void MeshImageCacheCollector::start(Utils::SmallStringView name,
|
||||||
|
Utils::SmallStringView state,
|
||||||
|
const ImageCache::AuxiliaryData &auxiliaryData,
|
||||||
|
CaptureCallback captureCallback,
|
||||||
|
AbortCallback abortCallback)
|
||||||
|
{
|
||||||
|
QTemporaryFile file(QDir::tempPath() + "/mesh-XXXXXX.qml");
|
||||||
|
if (file.open()) {
|
||||||
|
QString qtQuickVersion;
|
||||||
|
QString qtQuick3DVersion;
|
||||||
|
QtSupport::QtVersion *qtVersion = QtSupport::QtKitAspect::qtVersion(target()->kit());
|
||||||
|
if (qtVersion && qtVersion->qtVersion() < QtSupport::QtVersionNumber(6, 0, 0)) {
|
||||||
|
qtQuickVersion = "2.15";
|
||||||
|
qtQuick3DVersion = "1.15";
|
||||||
|
}
|
||||||
|
|
||||||
|
QString content{
|
||||||
|
R"(import QtQuick %1
|
||||||
|
import QtQuick3D %2
|
||||||
|
Node {
|
||||||
|
Model {
|
||||||
|
source: "%3"
|
||||||
|
DefaultMaterial { id: defaultMaterial; diffuseColor: "#ff999999" }
|
||||||
|
materials: [ defaultMaterial ]
|
||||||
|
}
|
||||||
|
})"};
|
||||||
|
|
||||||
|
content = content.arg(qtQuickVersion, qtQuick3DVersion, QString(name));
|
||||||
|
|
||||||
|
file.write(content.toUtf8());
|
||||||
|
file.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
Utils::PathString path{file.fileName()};
|
||||||
|
|
||||||
|
m_imageCacheCollector.start(path, state, auxiliaryData, captureCallback, abortCallback);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::pair<QImage, QImage> MeshImageCacheCollector::createImage(Utils::SmallStringView,
|
||||||
|
Utils::SmallStringView,
|
||||||
|
const ImageCache::AuxiliaryData &)
|
||||||
|
{
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
QIcon MeshImageCacheCollector::createIcon(Utils::SmallStringView,
|
||||||
|
Utils::SmallStringView,
|
||||||
|
const ImageCache::AuxiliaryData &)
|
||||||
|
{
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
void MeshImageCacheCollector::setTarget(ProjectExplorer::Target *target)
|
||||||
|
{
|
||||||
|
m_imageCacheCollector.setTarget(target);
|
||||||
|
}
|
||||||
|
|
||||||
|
ProjectExplorer::Target *MeshImageCacheCollector::target() const
|
||||||
|
{
|
||||||
|
return m_imageCacheCollector.target();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace QmlDesigner
|
||||||
@@ -0,0 +1,70 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2022 The Qt Company Ltd.
|
||||||
|
** Contact: https://www.qt.io/licensing/
|
||||||
|
**
|
||||||
|
** This file is part of Qt Creator.
|
||||||
|
**
|
||||||
|
** Commercial License Usage
|
||||||
|
** Licensees holding valid commercial Qt licenses may use this file in
|
||||||
|
** accordance with the commercial license agreement provided with the
|
||||||
|
** Software or, alternatively, in accordance with the terms contained in
|
||||||
|
** a written agreement between you and The Qt Company. For licensing terms
|
||||||
|
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||||
|
** information use the contact form at https://www.qt.io/contact-us.
|
||||||
|
**
|
||||||
|
** GNU General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU
|
||||||
|
** General Public License version 3 as published by the Free Software
|
||||||
|
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||||
|
** included in the packaging of this file. Please review the following
|
||||||
|
** information to ensure the GNU General Public License requirements will
|
||||||
|
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "imagecachecollectorinterface.h"
|
||||||
|
#include "imagecachecollector.h"
|
||||||
|
|
||||||
|
namespace ProjectExplorer {
|
||||||
|
class Target;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace QmlDesigner {
|
||||||
|
|
||||||
|
class ImageCacheConnectionManager;
|
||||||
|
|
||||||
|
class MeshImageCacheCollector final : public ImageCacheCollectorInterface
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
MeshImageCacheCollector(ImageCacheConnectionManager &connectionManager,
|
||||||
|
QSize captureImageMinimumSize,
|
||||||
|
QSize captureImageMaximumSize,
|
||||||
|
ImageCacheCollectorNullImageHandling nullImageHandling = {});
|
||||||
|
|
||||||
|
~MeshImageCacheCollector();
|
||||||
|
|
||||||
|
void start(Utils::SmallStringView filePath,
|
||||||
|
Utils::SmallStringView state,
|
||||||
|
const ImageCache::AuxiliaryData &auxiliaryData,
|
||||||
|
CaptureCallback captureCallback,
|
||||||
|
AbortCallback abortCallback) override;
|
||||||
|
|
||||||
|
std::pair<QImage, QImage> createImage(Utils::SmallStringView filePath,
|
||||||
|
Utils::SmallStringView state,
|
||||||
|
const ImageCache::AuxiliaryData &auxiliaryData) override;
|
||||||
|
|
||||||
|
QIcon createIcon(Utils::SmallStringView filePath,
|
||||||
|
Utils::SmallStringView state,
|
||||||
|
const ImageCache::AuxiliaryData &auxiliaryData) override;
|
||||||
|
|
||||||
|
void setTarget(ProjectExplorer::Target *target);
|
||||||
|
ProjectExplorer::Target *target() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
ImageCacheCollector m_imageCacheCollector;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace QmlDesigner
|
||||||
@@ -0,0 +1,87 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2022 The Qt Company Ltd.
|
||||||
|
** Contact: https://www.qt.io/licensing/
|
||||||
|
**
|
||||||
|
** This file is part of Qt Creator.
|
||||||
|
**
|
||||||
|
** Commercial License Usage
|
||||||
|
** Licensees holding valid commercial Qt licenses may use this file in
|
||||||
|
** accordance with the commercial license agreement provided with the
|
||||||
|
** Software or, alternatively, in accordance with the terms contained in
|
||||||
|
** a written agreement between you and The Qt Company. For licensing terms
|
||||||
|
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||||
|
** information use the contact form at https://www.qt.io/contact-us.
|
||||||
|
**
|
||||||
|
** GNU General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU
|
||||||
|
** General Public License version 3 as published by the Free Software
|
||||||
|
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||||
|
** included in the packaging of this file. Please review the following
|
||||||
|
** information to ensure the GNU General Public License requirements will
|
||||||
|
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#include "smallimagecacheprovider.h"
|
||||||
|
|
||||||
|
#include <asynchronousimagecache.h>
|
||||||
|
|
||||||
|
#include <QMetaObject>
|
||||||
|
|
||||||
|
namespace QmlDesigner {
|
||||||
|
|
||||||
|
QQuickTextureFactory *ImageResponse::textureFactory() const
|
||||||
|
{
|
||||||
|
return QQuickTextureFactory::textureFactoryForImage(m_image);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImageResponse::setImage(const QImage &image)
|
||||||
|
{
|
||||||
|
m_image = image;
|
||||||
|
|
||||||
|
emit finished();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImageResponse::abort()
|
||||||
|
{
|
||||||
|
emit finished();
|
||||||
|
}
|
||||||
|
|
||||||
|
QQuickImageResponse *SmallImageCacheProvider::requestImageResponse(const QString &id, const QSize &)
|
||||||
|
{
|
||||||
|
auto response = std::make_unique<QmlDesigner::ImageResponse>(m_defaultImage);
|
||||||
|
|
||||||
|
m_cache.requestSmallImage(
|
||||||
|
id,
|
||||||
|
[response = QPointer<QmlDesigner::ImageResponse>(response.get())](const QImage &image) {
|
||||||
|
QMetaObject::invokeMethod(
|
||||||
|
response,
|
||||||
|
[response, image] {
|
||||||
|
if (response)
|
||||||
|
response->setImage(image);
|
||||||
|
},
|
||||||
|
Qt::QueuedConnection);
|
||||||
|
},
|
||||||
|
[response = QPointer<QmlDesigner::ImageResponse>(response.get())](
|
||||||
|
ImageCache::AbortReason abortReason) {
|
||||||
|
QMetaObject::invokeMethod(
|
||||||
|
response,
|
||||||
|
[response, abortReason] {
|
||||||
|
switch (abortReason) {
|
||||||
|
case ImageCache::AbortReason::Failed:
|
||||||
|
if (response)
|
||||||
|
response->abort();
|
||||||
|
break;
|
||||||
|
case ImageCache::AbortReason::Abort:
|
||||||
|
response->cancel();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Qt::QueuedConnection);
|
||||||
|
});
|
||||||
|
|
||||||
|
return response.release();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace QmlDesigner
|
||||||
@@ -0,0 +1,68 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2022 The Qt Company Ltd.
|
||||||
|
** Contact: https://www.qt.io/licensing/
|
||||||
|
**
|
||||||
|
** This file is part of Qt Creator.
|
||||||
|
**
|
||||||
|
** Commercial License Usage
|
||||||
|
** Licensees holding valid commercial Qt licenses may use this file in
|
||||||
|
** accordance with the commercial license agreement provided with the
|
||||||
|
** Software or, alternatively, in accordance with the terms contained in
|
||||||
|
** a written agreement between you and The Qt Company. For licensing terms
|
||||||
|
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||||
|
** information use the contact form at https://www.qt.io/contact-us.
|
||||||
|
**
|
||||||
|
** GNU General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU
|
||||||
|
** General Public License version 3 as published by the Free Software
|
||||||
|
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||||
|
** included in the packaging of this file. Please review the following
|
||||||
|
** information to ensure the GNU General Public License requirements will
|
||||||
|
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QQuickAsyncImageProvider>
|
||||||
|
#include <QQuickImageResponse>
|
||||||
|
|
||||||
|
namespace QmlDesigner {
|
||||||
|
|
||||||
|
class AsynchronousImageCache;
|
||||||
|
|
||||||
|
class ImageResponse : public QQuickImageResponse
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ImageResponse(const QImage &defaultImage)
|
||||||
|
: m_image(defaultImage)
|
||||||
|
{}
|
||||||
|
|
||||||
|
QQuickTextureFactory *textureFactory() const override;
|
||||||
|
|
||||||
|
void setImage(const QImage &image);
|
||||||
|
|
||||||
|
void abort();
|
||||||
|
|
||||||
|
private:
|
||||||
|
QImage m_image;
|
||||||
|
};
|
||||||
|
|
||||||
|
class SmallImageCacheProvider : public QQuickAsyncImageProvider
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SmallImageCacheProvider(AsynchronousImageCache &imageCache, const QImage &defaultImage = {})
|
||||||
|
: m_cache{imageCache}
|
||||||
|
, m_defaultImage(defaultImage)
|
||||||
|
{}
|
||||||
|
|
||||||
|
QQuickImageResponse *requestImageResponse(const QString &id,
|
||||||
|
const QSize &requestedSize) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
AsynchronousImageCache &m_cache;
|
||||||
|
QImage m_defaultImage;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace QmlDesigner
|
||||||
@@ -28,11 +28,17 @@
|
|||||||
#include <QDateTime>
|
#include <QDateTime>
|
||||||
#include <QFileInfo>
|
#include <QFileInfo>
|
||||||
|
|
||||||
|
#include <limits>
|
||||||
|
|
||||||
namespace QmlDesigner {
|
namespace QmlDesigner {
|
||||||
|
|
||||||
Sqlite::TimeStamp TimeStampProvider::timeStamp(Utils::SmallStringView name) const
|
Sqlite::TimeStamp TimeStampProvider::timeStamp(Utils::SmallStringView name) const
|
||||||
{
|
{
|
||||||
return QFileInfo{QString{name}}.lastModified().toSecsSinceEpoch();
|
QFileInfo info{QString{name}};
|
||||||
|
if (info.exists())
|
||||||
|
return info.lastModified().toSecsSinceEpoch();
|
||||||
|
|
||||||
|
return {std::numeric_limits<long long>::max()};
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace QmlDesigner
|
} // namespace QmlDesigner
|
||||||
|
|||||||
@@ -51,7 +51,8 @@ class ViewManagerData;
|
|||||||
class QMLDESIGNERCORE_EXPORT ViewManager
|
class QMLDESIGNERCORE_EXPORT ViewManager
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ViewManager(class AsynchronousImageCache &imageCache);
|
ViewManager(class AsynchronousImageCache &imageCache,
|
||||||
|
class AsynchronousImageCache &meshImageCache);
|
||||||
~ViewManager();
|
~ViewManager();
|
||||||
|
|
||||||
void attachRewriterView();
|
void attachRewriterView();
|
||||||
|
|||||||
@@ -62,8 +62,9 @@ static Q_LOGGING_CATEGORY(viewBenchmark, "qtc.viewmanager.attach", QtWarningMsg)
|
|||||||
class ViewManagerData
|
class ViewManagerData
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ViewManagerData(AsynchronousImageCache &imageCache)
|
ViewManagerData(AsynchronousImageCache &imageCache, AsynchronousImageCache &meshImageCache)
|
||||||
: itemLibraryView(imageCache)
|
: itemLibraryView(imageCache)
|
||||||
|
, propertyEditorView(meshImageCache)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
InteractiveConnectionManager connectionManager;
|
InteractiveConnectionManager connectionManager;
|
||||||
@@ -94,8 +95,8 @@ static CrumbleBar *crumbleBar() {
|
|||||||
return QmlDesignerPlugin::instance()->mainWidget()->crumbleBar();
|
return QmlDesignerPlugin::instance()->mainWidget()->crumbleBar();
|
||||||
}
|
}
|
||||||
|
|
||||||
ViewManager::ViewManager(AsynchronousImageCache &imageCache)
|
ViewManager::ViewManager(AsynchronousImageCache &imageCache, AsynchronousImageCache &meshImageCache)
|
||||||
: d(std::make_unique<ViewManagerData>(imageCache))
|
: d(std::make_unique<ViewManagerData>(imageCache, meshImageCache))
|
||||||
{
|
{
|
||||||
d->formEditorView.setGotoErrorCallback([this](int line, int column) {
|
d->formEditorView.setGotoErrorCallback([this](int line, int column) {
|
||||||
d->textEditorView.gotoCursorPosition(line, column);
|
d->textEditorView.gotoCursorPosition(line, column);
|
||||||
|
|||||||
@@ -123,6 +123,8 @@ function(extend_with_qmldesigner_core target_name)
|
|||||||
imagecache/imagecachegeneratorinterface.h
|
imagecache/imagecachegeneratorinterface.h
|
||||||
imagecache/imagecachestorage.h
|
imagecache/imagecachestorage.h
|
||||||
imagecache/imagecachestorageinterface.h
|
imagecache/imagecachestorageinterface.h
|
||||||
|
imagecache/meshimagecachecollector.cpp
|
||||||
|
imagecache/meshimagecachecollector.h
|
||||||
imagecache/synchronousimagecache.cpp
|
imagecache/synchronousimagecache.cpp
|
||||||
imagecache/timestampprovider.cpp
|
imagecache/timestampprovider.cpp
|
||||||
imagecache/timestampprovider.h
|
imagecache/timestampprovider.h
|
||||||
|
|||||||
@@ -137,7 +137,8 @@ class QmlDesignerPluginPrivate
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
QmlDesignerProjectManager projectManager;
|
QmlDesignerProjectManager projectManager;
|
||||||
ViewManager viewManager{projectManager.asynchronousImageCache()};
|
ViewManager viewManager{projectManager.asynchronousImageCache(),
|
||||||
|
projectManager.asynchronousMeshImageCache()};
|
||||||
DocumentManager documentManager;
|
DocumentManager documentManager;
|
||||||
ShortCutManager shortCutManager;
|
ShortCutManager shortCutManager;
|
||||||
SettingsPage settingsPage;
|
SettingsPage settingsPage;
|
||||||
|
|||||||
@@ -442,6 +442,10 @@ Project {
|
|||||||
"imagecache/imagecachegenerator.h",
|
"imagecache/imagecachegenerator.h",
|
||||||
"imagecache/imagecachestorageinterface.h",
|
"imagecache/imagecachestorageinterface.h",
|
||||||
"imagecache/imagecachestorage.h",
|
"imagecache/imagecachestorage.h",
|
||||||
|
"imagecache/meshimagecachecollector.cpp",
|
||||||
|
"imagecache/meshimagecachecollector.h",
|
||||||
|
"imagecache/smallimagecacheprovider.cpp",
|
||||||
|
"imagecache/smallimagecacheprovider.h",
|
||||||
"imagecache/synchronousimagecache.cpp",
|
"imagecache/synchronousimagecache.cpp",
|
||||||
"imagecache/timestampproviderinterface.h",
|
"imagecache/timestampproviderinterface.h",
|
||||||
"imagecache/timestampprovider.h",
|
"imagecache/timestampprovider.h",
|
||||||
@@ -737,6 +741,8 @@ Project {
|
|||||||
"propertyeditor/gradientpresetlistmodel.h",
|
"propertyeditor/gradientpresetlistmodel.h",
|
||||||
"propertyeditor/propertyeditorcontextobject.cpp",
|
"propertyeditor/propertyeditorcontextobject.cpp",
|
||||||
"propertyeditor/propertyeditorcontextobject.h",
|
"propertyeditor/propertyeditorcontextobject.h",
|
||||||
|
"propertyeditor/propertyeditorimageprovider.cpp",
|
||||||
|
"propertyeditor/propertyeditorimageprovider.h",
|
||||||
"propertyeditor/propertyeditortransaction.cpp",
|
"propertyeditor/propertyeditortransaction.cpp",
|
||||||
"propertyeditor/propertyeditortransaction.h",
|
"propertyeditor/propertyeditortransaction.h",
|
||||||
"propertyeditor/propertyeditorvalue.cpp",
|
"propertyeditor/propertyeditorvalue.cpp",
|
||||||
|
|||||||
@@ -51,7 +51,8 @@
|
|||||||
#include <imagecache/imagecacheconnectionmanager.h>
|
#include <imagecache/imagecacheconnectionmanager.h>
|
||||||
#include <imagecache/imagecachegenerator.h>
|
#include <imagecache/imagecachegenerator.h>
|
||||||
#include <imagecache/imagecachestorage.h>
|
#include <imagecache/imagecachestorage.h>
|
||||||
#include <imagecache/timestampproviderinterface.h>
|
#include <imagecache/meshimagecachecollector.h>
|
||||||
|
#include <imagecache/timestampprovider.h>
|
||||||
|
|
||||||
#include <coreplugin/icore.h>
|
#include <coreplugin/icore.h>
|
||||||
|
|
||||||
@@ -79,7 +80,7 @@ QString defaultImagePath()
|
|||||||
return qobject_cast<::QmlProjectManager::QmlBuildSystem *>(target->buildSystem());
|
return qobject_cast<::QmlProjectManager::QmlBuildSystem *>(target->buildSystem());
|
||||||
}
|
}
|
||||||
|
|
||||||
class TimeStampProvider : public TimeStampProviderInterface
|
class PreviewTimeStampProvider : public TimeStampProviderInterface
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Sqlite::TimeStamp timeStamp(Utils::SmallStringView) const override
|
Sqlite::TimeStamp timeStamp(Utils::SmallStringView) const override
|
||||||
@@ -107,10 +108,13 @@ public:
|
|||||||
Sqlite::LockingMode::Normal};
|
Sqlite::LockingMode::Normal};
|
||||||
ImageCacheStorage<Sqlite::Database> storage{database};
|
ImageCacheStorage<Sqlite::Database> storage{database};
|
||||||
ImageCacheConnectionManager connectionManager;
|
ImageCacheConnectionManager connectionManager;
|
||||||
ImageCacheCollector collector{connectionManager, QSize{300, 300}, QSize{600, 600}};
|
MeshImageCacheCollector meshImageCollector{connectionManager, QSize{300, 300}, QSize{600, 600}};
|
||||||
ImageCacheGenerator generator{collector, storage};
|
ImageCacheGenerator meshGenerator{meshImageCollector, storage};
|
||||||
|
ImageCacheCollector nodeInstanceCollector{connectionManager, QSize{300, 300}, QSize{600, 600}};
|
||||||
|
ImageCacheGenerator nodeInstanceGenerator{nodeInstanceCollector, storage};
|
||||||
TimeStampProvider timeStampProvider;
|
TimeStampProvider timeStampProvider;
|
||||||
AsynchronousImageCache asynchronousImageCache{storage, generator, timeStampProvider};
|
AsynchronousImageCache asynchronousImageCache{storage, nodeInstanceGenerator, timeStampProvider};
|
||||||
|
AsynchronousImageCache asynchronousMeshImageCache{storage, meshGenerator, timeStampProvider};
|
||||||
};
|
};
|
||||||
|
|
||||||
class QmlDesignerProjectManager::PreviewImageCacheData
|
class QmlDesignerProjectManager::PreviewImageCacheData
|
||||||
@@ -135,7 +139,7 @@ public:
|
|||||||
QSize{300, 300},
|
QSize{300, 300},
|
||||||
QSize{1000, 1000},
|
QSize{1000, 1000},
|
||||||
ImageCacheCollectorNullImageHandling::DontCaptureNullImage};
|
ImageCacheCollectorNullImageHandling::DontCaptureNullImage};
|
||||||
TimeStampProvider timeStampProvider;
|
PreviewTimeStampProvider timeStampProvider;
|
||||||
AsynchronousImageFactory factory;
|
AsynchronousImageFactory factory;
|
||||||
::ProjectExplorer::Target *activeTarget = nullptr;
|
::ProjectExplorer::Target *activeTarget = nullptr;
|
||||||
};
|
};
|
||||||
@@ -180,6 +184,11 @@ AsynchronousImageCache &QmlDesignerProjectManager::asynchronousImageCache()
|
|||||||
return imageCacheData()->asynchronousImageCache;
|
return imageCacheData()->asynchronousImageCache;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AsynchronousImageCache &QmlDesignerProjectManager::asynchronousMeshImageCache()
|
||||||
|
{
|
||||||
|
return imageCacheData()->asynchronousMeshImageCache;
|
||||||
|
}
|
||||||
|
|
||||||
void QmlDesignerProjectManager::editorOpened(::Core::IEditor *) {}
|
void QmlDesignerProjectManager::editorOpened(::Core::IEditor *) {}
|
||||||
|
|
||||||
void QmlDesignerProjectManager::currentEditorChanged(::Core::IEditor *)
|
void QmlDesignerProjectManager::currentEditorChanged(::Core::IEditor *)
|
||||||
@@ -218,17 +227,21 @@ QmlDesignerProjectManager::ImageCacheData *QmlDesignerProjectManager::imageCache
|
|||||||
m_imageCacheData = std::make_unique<ImageCacheData>();
|
m_imageCacheData = std::make_unique<ImageCacheData>();
|
||||||
auto setTargetInImageCache =
|
auto setTargetInImageCache =
|
||||||
[imageCacheData = m_imageCacheData.get()](ProjectExplorer::Target *target) {
|
[imageCacheData = m_imageCacheData.get()](ProjectExplorer::Target *target) {
|
||||||
if (target == imageCacheData->collector.target())
|
if (target == imageCacheData->nodeInstanceCollector.target())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (target)
|
if (target)
|
||||||
imageCacheData->asynchronousImageCache.clean();
|
imageCacheData->asynchronousImageCache.clean();
|
||||||
|
|
||||||
imageCacheData->collector.setTarget(target);
|
// TODO wrap in function in image cache data
|
||||||
|
imageCacheData->meshImageCollector.setTarget(target);
|
||||||
|
imageCacheData->nodeInstanceCollector.setTarget(target);
|
||||||
};
|
};
|
||||||
|
|
||||||
if (auto project = ProjectExplorer::SessionManager::startupProject(); project) {
|
if (auto project = ProjectExplorer::SessionManager::startupProject(); project) {
|
||||||
m_imageCacheData->collector.setTarget(project->activeTarget());
|
// TODO wrap in function in image cache data
|
||||||
|
m_imageCacheData->meshImageCollector.setTarget(project->activeTarget());
|
||||||
|
m_imageCacheData->nodeInstanceCollector.setTarget(project->activeTarget());
|
||||||
QObject::connect(project,
|
QObject::connect(project,
|
||||||
&ProjectExplorer::Project::activeTargetChanged,
|
&ProjectExplorer::Project::activeTargetChanged,
|
||||||
this,
|
this,
|
||||||
|
|||||||
@@ -59,6 +59,7 @@ public:
|
|||||||
void registerPreviewImageProvider(QQmlEngine *engine) const;
|
void registerPreviewImageProvider(QQmlEngine *engine) const;
|
||||||
|
|
||||||
class AsynchronousImageCache &asynchronousImageCache();
|
class AsynchronousImageCache &asynchronousImageCache();
|
||||||
|
class AsynchronousImageCache &asynchronousMeshImageCache();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void editorOpened(::Core::IEditor *editor);
|
void editorOpened(::Core::IEditor *editor);
|
||||||
|
|||||||
Reference in New Issue
Block a user