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:
Mahmoud Badri
2024-04-09 17:50:11 +03:00
parent ece3a60cfa
commit 4591293fd9
12 changed files with 88 additions and 28 deletions

View File

@@ -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
}
}
}

View File

@@ -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

View File

@@ -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);

View File

@@ -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

View File

@@ -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)

View File

@@ -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:

View File

@@ -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;

View File

@@ -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);

View File

@@ -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.");

View File

@@ -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);
}
}

View File

@@ -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

View File

@@ -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