AssetExport: Export reference assets of components

Task-number: QDS-2868
Change-Id: Ib5d3875e009bde972a30b0a90216bad6ef6e38ea
Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io>
This commit is contained in:
Vikas Pachdha
2021-01-12 19:06:05 +01:00
parent e2c808f576
commit 55cbe717a9
6 changed files with 81 additions and 12 deletions

View File

@@ -23,6 +23,7 @@
** **
****************************************************************************/ ****************************************************************************/
#include "assetexporter.h" #include "assetexporter.h"
#include "assetexportpluginconstants.h"
#include "componentexporter.h" #include "componentexporter.h"
#include "exportnotification.h" #include "exportnotification.h"
@@ -154,21 +155,47 @@ bool AssetExporter::isBusy() const
m_currentState == AssetExporter::ParsingState::WritingJson; m_currentState == AssetExporter::ParsingState::WritingJson;
} }
Utils::FilePath AssetExporter::exportAsset(const QmlObjectNode &node, const Component *component, const QPixmap &AssetExporter::generateAsset(const ModelNode &node)
const QString &uuid)
{ {
static QPixmap nullPixmap;
if (m_cancelled) if (m_cancelled)
return nullPixmap;
const QString uuid = node.auxiliaryData(Constants::UuidAuxTag).toString();
QTC_ASSERT(!uuid.isEmpty(), return nullPixmap);
if (!m_assets.contains(uuid)) {
// Generate asset.
QmlObjectNode objectNode(node);
QPixmap asset = objectNode.toQmlItemNode().instanceRenderPixmap();
m_assets[uuid] = asset;
}
return m_assets[uuid];
}
Utils::FilePath AssetExporter::assetPath(const ModelNode &node, const Component *component,
const QString &suffix) const
{
const QString uuid = node.auxiliaryData(Constants::UuidAuxTag).toString();
if (!component || uuid.isEmpty())
return {}; return {};
const Utils::FilePath assetExportDir = m_perComponentExport ? componentExportDir(component) :
m_exportPath; const Utils::FilePath assetExportDir =
const QString fileName = uuid + ".png"; m_perComponentExport ? componentExportDir(component) : m_exportPath;
const Utils::FilePath assetPath = assetExportDir.pathAppended("assets").pathAppended(fileName); const Utils::FilePath assetPath = assetExportDir.pathAppended("assets")
if (m_assetDumper) .pathAppended(uuid + suffix + ".png");
m_assetDumper->dumpAsset(node.toQmlItemNode().instanceRenderPixmap(), assetPath);
return assetPath; return assetPath;
} }
void AssetExporter::exportAsset(const QPixmap &asset, const Utils::FilePath &path)
{
if (m_cancelled || !m_assetDumper)
return;
m_assetDumper->dumpAsset(asset, path);
}
void AssetExporter::exportComponent(const ModelNode &rootNode) void AssetExporter::exportComponent(const ModelNode &rootNode)
{ {
qCDebug(loggerInfo) << "Exporting component" << rootNode.id(); qCDebug(loggerInfo) << "Exporting component" << rootNode.id();

View File

@@ -71,8 +71,10 @@ public:
void cancel(); void cancel();
bool isBusy() const; bool isBusy() const;
Utils::FilePath exportAsset(const QmlObjectNode& node, const Component *component, const QPixmap &generateAsset(const ModelNode &node);
const QString &uuid); Utils::FilePath assetPath(const ModelNode &node, const Component *component,
const QString &suffix = {}) const;
void exportAsset(const QPixmap &asset, const Utils::FilePath &path);
QByteArray generateUuid(const ModelNode &node); QByteArray generateUuid(const ModelNode &node);
signals: signals:
@@ -108,6 +110,7 @@ private:
bool m_perComponentExport = false; bool m_perComponentExport = false;
std::vector<std::unique_ptr<Component>> m_components; std::vector<std::unique_ptr<Component>> m_components;
QSet<QByteArray> m_usedHashes; QSet<QByteArray> m_usedHashes;
QHash<QString, QPixmap> m_assets;
std::unique_ptr<AssetDumper> m_assetDumper; std::unique_ptr<AssetDumper> m_assetDumper;
bool m_cancelled = false; bool m_cancelled = false;
}; };

View File

@@ -63,6 +63,7 @@ const char ImportsTag[] = "extraImports";
const char UuidTag[] = "uuid"; const char UuidTag[] = "uuid";
const char ClipTag[] = "clip"; const char ClipTag[] = "clip";
const char AssetDataTag[] = "assetData"; const char AssetDataTag[] = "assetData";
const char ReferenceAssetTag[] = "referenceAsset";
const char AssetPathTag[] = "assetPath"; const char AssetPathTag[] = "assetPath";
const char AssetBoundsTag[] = "assetBounds"; const char AssetBoundsTag[] = "assetBounds";
const char OpacityTag[] = "opacity"; const char OpacityTag[] = "opacity";

View File

@@ -31,6 +31,7 @@
#include "model.h" #include "model.h"
#include "nodeabstractproperty.h" #include "nodeabstractproperty.h"
#include "nodemetainfo.h" #include "nodemetainfo.h"
#include "qmlitemnode.h"
#include "rewriterview.h" #include "rewriterview.h"
#include "utils/qtcassert.h" #include "utils/qtcassert.h"
@@ -38,6 +39,7 @@
#include <QJsonArray> #include <QJsonArray>
#include <QJsonObject> #include <QJsonObject>
#include <QLoggingCategory> #include <QLoggingCategory>
#include <QPainter>
namespace { namespace {
Q_LOGGING_CATEGORY(loggerInfo, "qtc.designer.assetExportPlugin.modelExporter", QtInfoMsg) Q_LOGGING_CATEGORY(loggerInfo, "qtc.designer.assetExportPlugin.modelExporter", QtInfoMsg)
@@ -86,6 +88,7 @@ void Component::exportComponent()
// Change the export type to component // Change the export type to component
QJsonObject metadata = m_json.value(MetadataTag).toObject(); QJsonObject metadata = m_json.value(MetadataTag).toObject();
metadata.insert(ExportTypeTag, ExportTypeComponent); metadata.insert(ExportTypeTag, ExportTypeComponent);
addReferenceAsset(metadata);
m_json.insert(MetadataTag, metadata); m_json.insert(MetadataTag, metadata);
addImports(); addImports();
} }
@@ -152,6 +155,37 @@ QJsonObject Component::nodeToJson(const ModelNode &node)
return jsonObject; return jsonObject;
} }
void Component::addReferenceAsset(QJsonObject &metadataObject) const
{
QPixmap refAsset = m_exporter.generateAsset(m_rootNode);
stichChildrendAssets(m_rootNode, refAsset);
Utils::FilePath refAssetPath = m_exporter.assetPath(m_rootNode, this, "_ref");
m_exporter.exportAsset(refAsset, refAssetPath);
QJsonObject assetData;
if (metadataObject.contains(AssetDataTag))
assetData = metadataObject[AssetDataTag].toObject();
assetData.insert(ReferenceAssetTag, refAssetPath.toString());
metadataObject.insert(AssetDataTag, assetData);
}
void Component::stichChildrendAssets(const ModelNode &node, QPixmap &parentPixmap) const
{
if (!node.hasAnySubModelNodes())
return;
QPainter painter(&parentPixmap);
for (const ModelNode &child : node.directSubModelNodes()) {
QPixmap childPixmap = m_exporter.generateAsset(child);
if (childPixmap.isNull())
continue;
stichChildrendAssets(child, childPixmap);
QTransform cTransform = QmlObjectNode(child).toQmlItemNode().instanceTransform();
painter.setTransform(cTransform);
painter.drawPixmap(QPoint(0, 0), childPixmap);
}
painter.end();
}
void Component::addImports() void Component::addImports()
{ {
QJsonArray importsArray; QJsonArray importsArray;

View File

@@ -88,6 +88,8 @@ public:
private: private:
ModelNodeParser* createNodeParser(const ModelNode &node) const; ModelNodeParser* createNodeParser(const ModelNode &node) const;
QJsonObject nodeToJson(const ModelNode &node); QJsonObject nodeToJson(const ModelNode &node);
void addReferenceAsset(QJsonObject &metadataObject) const;
void stichChildrendAssets(const ModelNode &node, QPixmap &parentPixmap) const;
void addImports(); void addImports();
private: private:

View File

@@ -54,10 +54,12 @@ QJsonObject AssetNodeParser::json(Component &component) const
{ {
QJsonObject jsonObject = ItemNodeParser::json(component); QJsonObject jsonObject = ItemNodeParser::json(component);
Utils::FilePath assetPath = component.exporter().exportAsset(objectNode(), &component, uuid()); AssetExporter &exporter = component.exporter();
const Utils::FilePath assetPath = exporter.assetPath(m_node, &component);
exporter.exportAsset(exporter.generateAsset(m_node), assetPath);
QJsonObject assetData; QJsonObject assetData;
assetData.insert(AssetPathTag, assetPath.toString()); assetData.insert(AssetPathTag, assetPath.toString());
QJsonObject metadata = jsonObject.value(MetadataTag).toObject(); QJsonObject metadata = jsonObject.value(MetadataTag).toObject();
metadata.insert(AssetDataTag, assetData); metadata.insert(AssetDataTag, assetData);
jsonObject.insert(MetadataTag, metadata); jsonObject.insert(MetadataTag, metadata);