forked from qt-creator/qt-creator
QmlDesigner: Add user texture bundle
Fixes: QDS-12390 Change-Id: I512a8748bbb6a282589f05293507c110162e7f1d Reviewed-by: Qt CI Patch Build Bot <ci_patchbuild_bot@qt.io> Reviewed-by: Miikka Heikkinen <miikka.heikkinen@qt.io>
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
import QtQuick
|
||||
import Qt.labs.qmlmodels
|
||||
import HelperWidgets as HelperWidgets
|
||||
import StudioControls as StudioControls
|
||||
import StudioTheme as StudioTheme
|
||||
@@ -99,17 +100,33 @@ HelperWidgets.ScrollView {
|
||||
id: repeater
|
||||
model: categoryItems
|
||||
|
||||
delegate: ContentLibraryMaterial {
|
||||
width: root.cellWidth
|
||||
height: root.cellHeight
|
||||
delegate: DelegateChooser {
|
||||
role: "itemType"
|
||||
|
||||
importerRunning: ContentLibraryBackend.userModel.importerRunning
|
||||
DelegateChoice {
|
||||
roleValue: "material"
|
||||
ContentLibraryMaterial {
|
||||
width: root.cellWidth
|
||||
height: root.cellHeight
|
||||
|
||||
onShowContextMenu: ctxMenu.popupMenu(modelData)
|
||||
onAddToProject: ContentLibraryBackend.userModel.addToProject(modelData)
|
||||
importerRunning: ContentLibraryBackend.userModel.importerRunning
|
||||
|
||||
onVisibleChanged: {
|
||||
section.numVisibleItem += visible ? 1 : -1
|
||||
onShowContextMenu: ctxMenu.popupMenu(modelData)
|
||||
onAddToProject: ContentLibraryBackend.userModel.addToProject(modelData)
|
||||
|
||||
onVisibleChanged: {
|
||||
section.numVisibleItem += visible ? 1 : -1
|
||||
}
|
||||
}
|
||||
}
|
||||
DelegateChoice {
|
||||
roleValue: "texture"
|
||||
delegate: ContentLibraryTexture {
|
||||
width: root.cellWidth
|
||||
height: root.cellHeight
|
||||
|
||||
// onShowContextMenu: ctxMenu.popupMenu(modelData) // TODO
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -21,6 +21,7 @@ class ContentLibraryMaterial : public QObject
|
||||
Q_PROPERTY(QString bundleMaterialBaseWebUrl MEMBER m_baseWebUrl CONSTANT)
|
||||
Q_PROPERTY(QString bundleMaterialParentPath READ parentDirPath CONSTANT)
|
||||
Q_PROPERTY(QStringList bundleMaterialFiles READ allFiles CONSTANT)
|
||||
Q_PROPERTY(QString itemType MEMBER m_itemType CONSTANT)
|
||||
|
||||
public:
|
||||
ContentLibraryMaterial(QObject *parent,
|
||||
@@ -65,6 +66,7 @@ private:
|
||||
QString m_downloadPath;
|
||||
QString m_baseWebUrl;
|
||||
QStringList m_allFiles;
|
||||
const QString m_itemType = "material";
|
||||
};
|
||||
|
||||
} // namespace QmlDesigner
|
||||
|
@@ -12,10 +12,10 @@
|
||||
namespace QmlDesigner {
|
||||
|
||||
ContentLibraryTexture::ContentLibraryTexture(QObject *parent, const QFileInfo &iconFileInfo,
|
||||
const QString &dirPath, const QString &key,
|
||||
const QString &textureUrl, const QString &iconUrl,
|
||||
const QString &suffix, const QSize &dimensions,
|
||||
const qint64 sizeInBytes, bool hasUpdate, bool isNew)
|
||||
const QString &dirPath, const QString &suffix,
|
||||
const QSize &dimensions, const qint64 sizeInBytes,
|
||||
const QString &key, const QString &textureUrl,
|
||||
const QString &iconUrl, bool hasUpdate, bool isNew)
|
||||
: QObject(parent)
|
||||
, m_iconPath(iconFileInfo.filePath())
|
||||
, m_dirPath(dirPath)
|
||||
@@ -82,10 +82,10 @@ QString ContentLibraryTexture::resolveToolTipText()
|
||||
QString imageInfo;
|
||||
|
||||
if (!m_isDownloaded && m_sizeInBytes > 0 && !m_dimensions.isNull()) {
|
||||
imageInfo = ImageUtils::imageInfo(m_dimensions, m_sizeInBytes);
|
||||
imageInfo = ImageUtils::imageInfoString(m_dimensions, m_sizeInBytes);
|
||||
} else {
|
||||
QString fullDownloadPath = m_dirPath + '/' + fileName;
|
||||
imageInfo = ImageUtils::imageInfo(fullDownloadPath);
|
||||
imageInfo = ImageUtils::imageInfoString(fullDownloadPath);
|
||||
}
|
||||
|
||||
return QString("%1\n%2").arg(fileName, imageInfo);
|
||||
|
@@ -24,12 +24,13 @@ class ContentLibraryTexture : public QObject
|
||||
Q_PROPERTY(bool textureHasUpdate WRITE setHasUpdate READ hasUpdate NOTIFY hasUpdateChanged)
|
||||
Q_PROPERTY(bool textureIsNew MEMBER m_isNew CONSTANT)
|
||||
Q_PROPERTY(QString textureKey MEMBER m_textureKey CONSTANT)
|
||||
Q_PROPERTY(QString itemType MEMBER m_itemType CONSTANT)
|
||||
|
||||
public:
|
||||
ContentLibraryTexture(QObject *parent, const QFileInfo &iconFileInfo, const QString &dirPath,
|
||||
const QString &key, const QString &textureUrl, const QString &iconUrl,
|
||||
const QString &suffix, const QSize &dimensions, const qint64 sizeInBytes,
|
||||
bool hasUpdate = false, bool isNew = false);
|
||||
const QString &key = {}, const QString &textureUrl = {},
|
||||
const QString &iconUrl = {}, bool hasUpdate = false, bool isNew = false);
|
||||
|
||||
Q_INVOKABLE bool isDownloaded() const;
|
||||
Q_INVOKABLE void setDownloaded();
|
||||
@@ -71,6 +72,7 @@ private:
|
||||
bool m_visible = true;
|
||||
bool m_hasUpdate = false;
|
||||
bool m_isNew = false;
|
||||
const QString m_itemType = "texture";
|
||||
};
|
||||
|
||||
} // namespace QmlDesigner
|
||||
|
@@ -21,8 +21,8 @@ void ContentLibraryTexturesCategory::addTexture(const QFileInfo &texIcon, const
|
||||
bool hasUpdate, bool isNew)
|
||||
{
|
||||
m_categoryTextures.append(new ContentLibraryTexture(
|
||||
this, texIcon, downloadPath, key, webTextureUrl, iconUrl,
|
||||
suffix, dimensions, sizeInBytes, hasUpdate, isNew));
|
||||
this, texIcon, downloadPath, suffix, dimensions, sizeInBytes,
|
||||
key, webTextureUrl, iconUrl, hasUpdate, isNew));
|
||||
}
|
||||
|
||||
bool ContentLibraryTexturesCategory::filter(const QString &searchText)
|
||||
|
@@ -37,7 +37,7 @@ public:
|
||||
void setHasSceneEnv(bool b);
|
||||
|
||||
void resetModel();
|
||||
void loadTextureBundle(const QString &m_textureBundleUrl, const QString &bundlePath,
|
||||
void loadTextureBundle(const QString &textureBundleUrl, const QString &bundlePath,
|
||||
const QVariantMap &metaData);
|
||||
|
||||
signals:
|
||||
|
@@ -6,9 +6,11 @@
|
||||
#include "contentlibrarybundleimporter.h"
|
||||
#include "contentlibrarymaterial.h"
|
||||
#include "contentlibrarymaterialscategory.h"
|
||||
#include "contentlibrarytexture.h"
|
||||
#include "contentlibrarywidget.h"
|
||||
|
||||
#include <designerpaths.h>
|
||||
#include <imageutils.h>
|
||||
#include <qmldesignerplugin.h>
|
||||
|
||||
#include <utils/algorithm.h>
|
||||
@@ -16,6 +18,7 @@
|
||||
#include <utils/qtcassert.h>
|
||||
|
||||
#include <QCoreApplication>
|
||||
#include <QFileInfo>
|
||||
#include <QJsonArray>
|
||||
#include <QJsonDocument>
|
||||
#include <QQmlEngine>
|
||||
@@ -28,9 +31,10 @@ ContentLibraryUserModel::ContentLibraryUserModel(ContentLibraryWidget *parent)
|
||||
: QAbstractListModel(parent)
|
||||
, m_widget(parent)
|
||||
{
|
||||
m_userCategories = {tr("Materials")/*, tr("Textures"), tr("3D"), tr("Effects"), tr("2D components")*/}; // TODO
|
||||
m_userCategories = {tr("Materials"), tr("Textures")/*, tr("3D"), tr("Effects"), tr("2D components")*/}; // TODO
|
||||
|
||||
loadMaterialBundle();
|
||||
loadTextureBundle();
|
||||
}
|
||||
|
||||
int ContentLibraryUserModel::rowCount(const QModelIndex &) const
|
||||
@@ -262,6 +266,32 @@ void ContentLibraryUserModel::loadMaterialBundle()
|
||||
emit matBundleExistsChanged();
|
||||
}
|
||||
|
||||
void ContentLibraryUserModel::loadTextureBundle()
|
||||
{
|
||||
if (!m_userTextures.isEmpty())
|
||||
return;
|
||||
|
||||
QDir bundleDir{Paths::bundlesPathSetting() + "/User/textures"};
|
||||
bundleDir.mkpath(".");
|
||||
bundleDir.mkdir("icons");
|
||||
|
||||
const QFileInfoList fileInfos = bundleDir.entryInfoList(QDir::Files);
|
||||
for (const QFileInfo &fileInfo : fileInfos) {
|
||||
auto iconFileInfo = QFileInfo(fileInfo.path().append("/icons/").append(fileInfo.fileName()));
|
||||
QPair<QSize, qint64> info = ImageUtils::imageInfo(fileInfo.path());
|
||||
QString dirPath = fileInfo.path();
|
||||
QString suffix = '.' + fileInfo.suffix();
|
||||
QSize imgDims = info.first;
|
||||
qint64 imgFileSize = info.second;
|
||||
|
||||
auto tex = new ContentLibraryTexture(this, iconFileInfo, dirPath, suffix, imgDims, imgFileSize);
|
||||
m_userTextures.append(tex);
|
||||
}
|
||||
|
||||
int texSectionIdx = 1;
|
||||
emit dataChanged(index(texSectionIdx, 0), index(texSectionIdx, 0));
|
||||
}
|
||||
|
||||
bool ContentLibraryUserModel::hasRequiredQuick3DImport() const
|
||||
{
|
||||
return m_widget->hasQuick3DImport() && m_quick3dMajorVersion == 6 && m_quick3dMinorVersion >= 3;
|
||||
|
@@ -3,7 +3,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "nodemetainfo.h"
|
||||
#include "modelfwd.h"
|
||||
|
||||
#include <QAbstractListModel>
|
||||
#include <QJsonObject>
|
||||
@@ -16,6 +16,7 @@ class ContentLibraryEffect;
|
||||
class ContentLibraryMaterial;
|
||||
class ContentLibraryTexture;
|
||||
class ContentLibraryWidget;
|
||||
class NodeMetaInfo;
|
||||
|
||||
namespace Internal {
|
||||
class ContentLibraryBundleImporter;
|
||||
@@ -94,6 +95,7 @@ signals:
|
||||
|
||||
private:
|
||||
void loadMaterialBundle();
|
||||
void loadTextureBundle();
|
||||
bool isValidIndex(int idx) const;
|
||||
void createImporter(const QString &bundlePath, const QString &bundleId,
|
||||
const QStringList &sharedFiles);
|
||||
|
@@ -63,7 +63,7 @@ QVariant MaterialBrowserTexturesModel::data(const QModelIndex &index, int role)
|
||||
return tr("Texture has no source image.");
|
||||
|
||||
ModelNode texNode = m_textureList.at(index.row());
|
||||
QString info = ImageUtils::imageInfo(source);
|
||||
QString info = ImageUtils::imageInfoString(source);
|
||||
|
||||
if (info.isEmpty())
|
||||
return tr("Texture has no data.");
|
||||
|
@@ -1946,7 +1946,7 @@ QVariant NodeInstanceView::previewImageDataForImageNode(const ModelNode &modelNo
|
||||
imageData.pixmap = originalPixmap.scaled(dim, dim, Qt::KeepAspectRatio);
|
||||
imageData.pixmap.setDevicePixelRatio(ratio);
|
||||
imageData.time = modified;
|
||||
imageData.info = ImageUtils::imageInfo(imageSource);
|
||||
imageData.info = ImageUtils::imageInfoString(imageSource);
|
||||
m_imageDataMap.insert(imageData.id, imageData);
|
||||
}
|
||||
}
|
||||
|
@@ -11,7 +11,7 @@
|
||||
|
||||
namespace QmlDesigner {
|
||||
|
||||
QString ImageUtils::imageInfo(const QSize &dimensions, qint64 sizeInBytes)
|
||||
QString ImageUtils::imageInfoString(const QSize &dimensions, qint64 sizeInBytes)
|
||||
{
|
||||
return QLatin1String("%1 x %2\n%3")
|
||||
.arg(QString::number(dimensions.width()),
|
||||
@@ -20,7 +20,7 @@ QString ImageUtils::imageInfo(const QSize &dimensions, qint64 sizeInBytes)
|
||||
sizeInBytes, 2, QLocale::DataSizeTraditionalFormat));
|
||||
}
|
||||
|
||||
QString QmlDesigner::ImageUtils::imageInfo(const QString &path)
|
||||
QPair<QSize, qint64> QmlDesigner::ImageUtils::imageInfo(const QString &path)
|
||||
{
|
||||
QFileInfo info(path);
|
||||
if (!info.exists())
|
||||
@@ -52,7 +52,13 @@ QString QmlDesigner::ImageUtils::imageInfo(const QString &path)
|
||||
if (width <= 0 || height <= 0)
|
||||
return {};
|
||||
|
||||
return imageInfo(QSize(width, height), info.size());
|
||||
return {QSize(width, height), info.size()};
|
||||
}
|
||||
|
||||
QString ImageUtils::imageInfoString(const QString &path)
|
||||
{
|
||||
QPair<QSize, qint64> info = imageInfo(path);
|
||||
return imageInfoString(info.first, info.second);
|
||||
}
|
||||
|
||||
} // namespace QmlDesigner
|
||||
|
@@ -12,8 +12,9 @@ class ImageUtils
|
||||
public:
|
||||
ImageUtils();
|
||||
|
||||
static QString imageInfo(const QSize &dimensions, qint64 sizeInBytes);
|
||||
static QString imageInfo(const QString &path);
|
||||
static QPair<QSize, qint64> imageInfo(const QString &path);
|
||||
static QString imageInfoString(const QString &path);
|
||||
static QString imageInfoString(const QSize &dimensions, qint64 sizeInBytes);
|
||||
};
|
||||
|
||||
} // namespace QmlDesigner
|
||||
|
Reference in New Issue
Block a user