forked from qt-creator/qt-creator
QmlDesigner: Enable content lib user 3D context menu
Also some relevant tweaks. Change-Id: I7bace9ce6bd7b45951cc18f7175b4646251196f0 Reviewed-by: Ali Kianian <ali.kianian@qt.io> Reviewed-by: Miikka Heikkinen <miikka.heikkinen@qt.io>
This commit is contained in:
@@ -1,43 +1,50 @@
|
|||||||
// Copyright (C) 2022 The Qt Company Ltd.
|
// Copyright (C) 2024 The Qt Company Ltd.
|
||||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||||
|
|
||||||
import QtQuick 2.15
|
import QtQuick
|
||||||
import HelperWidgets 2.0
|
import StudioControls as StudioControls
|
||||||
import StudioControls 1.0 as StudioControls
|
import StudioTheme as StudioTheme
|
||||||
import StudioTheme 1.0 as StudioTheme
|
import ContentLibraryBackend
|
||||||
|
|
||||||
StudioControls.Menu {
|
StudioControls.Menu {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
property var targetMaterial: null
|
property var targetItem: null
|
||||||
property bool hasModelSelection: false
|
property bool enableRemove: false // true: adds an option to remove targetItem
|
||||||
property bool importerRunning: false
|
|
||||||
property bool enableRemove: false // true: adds an option to remove targetMaterial
|
|
||||||
|
|
||||||
readonly property bool targetAvailable: targetMaterial && !importerRunning
|
readonly property bool targetAvailable: targetItem && !ContentLibraryBackend.rootView.importerRunning
|
||||||
|
|
||||||
signal unimport();
|
signal unimport();
|
||||||
signal addToProject()
|
signal addToProject()
|
||||||
signal applyToSelected(bool add)
|
signal applyToSelected(bool add)
|
||||||
signal removeFromContentLib()
|
signal removeFromContentLib()
|
||||||
|
|
||||||
function popupMenu(targetMaterial = null)
|
function popupMenu(item = null)
|
||||||
{
|
{
|
||||||
this.targetMaterial = targetMaterial
|
root.targetItem = item
|
||||||
|
|
||||||
|
let isMaterial = root.targetItem.itemType === "material"
|
||||||
|
applyToSelectedReplace.visible = isMaterial
|
||||||
|
applyToSelectedAdd.visible = isMaterial
|
||||||
|
|
||||||
popup()
|
popup()
|
||||||
}
|
}
|
||||||
|
|
||||||
closePolicy: StudioControls.Menu.CloseOnEscape | StudioControls.Menu.CloseOnPressOutside
|
closePolicy: StudioControls.Menu.CloseOnEscape | StudioControls.Menu.CloseOnPressOutside
|
||||||
|
|
||||||
StudioControls.MenuItem {
|
StudioControls.MenuItem {
|
||||||
|
id: applyToSelectedReplace
|
||||||
text: qsTr("Apply to selected (replace)")
|
text: qsTr("Apply to selected (replace)")
|
||||||
enabled: root.targetAvailable && root.hasModelSelection
|
height: visible ? implicitHeight : 0
|
||||||
|
enabled: root.targetAvailable && ContentLibraryBackend.rootView.hasModelSelection
|
||||||
onTriggered: root.applyToSelected(false)
|
onTriggered: root.applyToSelected(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
StudioControls.MenuItem {
|
StudioControls.MenuItem {
|
||||||
|
id: applyToSelectedAdd
|
||||||
text: qsTr("Apply to selected (add)")
|
text: qsTr("Apply to selected (add)")
|
||||||
enabled: root.targetAvailable && root.hasModelSelection
|
height: visible ? implicitHeight : 0
|
||||||
|
enabled: root.targetAvailable && ContentLibraryBackend.rootView.hasModelSelection
|
||||||
onTriggered: root.applyToSelected(true)
|
onTriggered: root.applyToSelected(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -46,16 +53,12 @@ StudioControls.Menu {
|
|||||||
StudioControls.MenuItem {
|
StudioControls.MenuItem {
|
||||||
enabled: root.targetAvailable
|
enabled: root.targetAvailable
|
||||||
text: qsTr("Add an instance to project")
|
text: qsTr("Add an instance to project")
|
||||||
|
onTriggered: root.addToProject()
|
||||||
onTriggered: {
|
|
||||||
root.addToProject()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
StudioControls.MenuItem {
|
StudioControls.MenuItem {
|
||||||
enabled: root.targetAvailable && root.targetMaterial.bundleMaterialImported
|
enabled: root.targetAvailable && root.targetItem.bundleItemImported
|
||||||
text: qsTr("Remove from project")
|
text: qsTr("Remove from project")
|
||||||
|
|
||||||
onTriggered: root.unimport()
|
onTriggered: root.unimport()
|
||||||
}
|
}
|
||||||
|
|
@@ -16,8 +16,6 @@ Item {
|
|||||||
// "failed"
|
// "failed"
|
||||||
property string downloadState: modelData.isDownloaded() ? "downloaded" : ""
|
property string downloadState: modelData.isDownloaded() ? "downloaded" : ""
|
||||||
|
|
||||||
property bool importerRunning: false
|
|
||||||
|
|
||||||
signal showContextMenu()
|
signal showContextMenu()
|
||||||
signal addToProject()
|
signal addToProject()
|
||||||
|
|
||||||
@@ -32,7 +30,7 @@ Item {
|
|||||||
acceptedButtons: Qt.LeftButton | Qt.RightButton
|
acceptedButtons: Qt.LeftButton | Qt.RightButton
|
||||||
|
|
||||||
onPressed: (mouse) => {
|
onPressed: (mouse) => {
|
||||||
if (mouse.button === Qt.LeftButton && !root.importerRunning) {
|
if (mouse.button === Qt.LeftButton && !ContentLibraryBackend.rootView.importerRunning) {
|
||||||
if (root.downloadState === "downloaded")
|
if (root.downloadState === "downloaded")
|
||||||
ContentLibraryBackend.rootView.startDragMaterial(modelData, mapToGlobal(mouse.x, mouse.y))
|
ContentLibraryBackend.rootView.startDragMaterial(modelData, mapToGlobal(mouse.x, mouse.y))
|
||||||
} else if (mouse.button === Qt.RightButton && root.downloadState === "downloaded") {
|
} else if (mouse.button === Qt.RightButton && root.downloadState === "downloaded") {
|
||||||
@@ -74,7 +72,7 @@ Item {
|
|||||||
color: "#00ff00"
|
color: "#00ff00"
|
||||||
border.color: "#555555"
|
border.color: "#555555"
|
||||||
border.width: 1
|
border.width: 1
|
||||||
visible: modelData.bundleMaterialImported
|
visible: modelData.bundleItemImported
|
||||||
|
|
||||||
ToolTip {
|
ToolTip {
|
||||||
visible: indicatorMouseArea.containsMouse
|
visible: indicatorMouseArea.containsMouse
|
||||||
@@ -99,7 +97,7 @@ Item {
|
|||||||
pressColor: Qt.hsla(c.hslHue, c.hslSaturation, c.hslLightness, .4)
|
pressColor: Qt.hsla(c.hslHue, c.hslSaturation, c.hslLightness, .4)
|
||||||
anchors.right: img.right
|
anchors.right: img.right
|
||||||
anchors.bottom: img.bottom
|
anchors.bottom: img.bottom
|
||||||
enabled: !root.importerRunning
|
enabled: !ContentLibraryBackend.rootView.importerRunning
|
||||||
visible: root.downloadState === "downloaded"
|
visible: root.downloadState === "downloaded"
|
||||||
&& (containsMouse || mouseArea.containsMouse)
|
&& (containsMouse || mouseArea.containsMouse)
|
||||||
|
|
||||||
|
@@ -46,16 +46,13 @@ HelperWidgets.ScrollView {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Column {
|
Column {
|
||||||
ContentLibraryMaterialContextMenu {
|
ContentLibraryItemContextMenu {
|
||||||
id: ctxMenu
|
id: ctxMenu
|
||||||
|
|
||||||
hasModelSelection: root.materialsModel.hasModelSelection
|
onApplyToSelected: (add) => root.materialsModel.applyToSelected(ctxMenu.targetItem, add)
|
||||||
importerRunning: ContentLibraryBackend.rootView.importerRunning
|
|
||||||
|
|
||||||
onApplyToSelected: (add) => root.materialsModel.applyToSelected(ctxMenu.targetMaterial, add)
|
onUnimport: root.unimport(ctxMenu.targetItem)
|
||||||
|
onAddToProject: root.materialsModel.addToProject(ctxMenu.targetItem)
|
||||||
onUnimport: root.unimport(ctxMenu.targetMaterial)
|
|
||||||
onAddToProject: root.materialsModel.addToProject(ctxMenu.targetMaterial)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Repeater {
|
Repeater {
|
||||||
@@ -103,8 +100,6 @@ HelperWidgets.ScrollView {
|
|||||||
width: root.cellWidth
|
width: root.cellWidth
|
||||||
height: root.cellHeight
|
height: root.cellHeight
|
||||||
|
|
||||||
importerRunning: ContentLibraryBackend.rootView.importerRunning
|
|
||||||
|
|
||||||
onShowContextMenu: ctxMenu.popupMenu(modelData)
|
onShowContextMenu: ctxMenu.popupMenu(modelData)
|
||||||
onAddToProject: root.materialsModel.addToProject(modelData)
|
onAddToProject: root.materialsModel.addToProject(modelData)
|
||||||
}
|
}
|
||||||
|
@@ -12,7 +12,7 @@ HelperWidgets.ScrollView {
|
|||||||
id: root
|
id: root
|
||||||
|
|
||||||
clip: true
|
clip: true
|
||||||
interactive: !ctxMenuMaterial.opened && !ctxMenuTexture.opened
|
interactive: !ctxMenuItem.opened && !ctxMenuTexture.opened
|
||||||
&& !ContentLibraryBackend.rootView.isDragging && !HelperWidgets.Controller.contextMenuOpened
|
&& !ContentLibraryBackend.rootView.isDragging && !HelperWidgets.Controller.contextMenuOpened
|
||||||
|
|
||||||
property real cellWidth: 100
|
property real cellWidth: 100
|
||||||
@@ -34,7 +34,7 @@ HelperWidgets.ScrollView {
|
|||||||
signal removeFromContentLib(var bundleItem);
|
signal removeFromContentLib(var bundleItem);
|
||||||
|
|
||||||
function closeContextMenu() {
|
function closeContextMenu() {
|
||||||
ctxMenuMaterial.close()
|
ctxMenuItem.close()
|
||||||
ctxMenuTexture.close()
|
ctxMenuTexture.close()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -47,18 +47,16 @@ HelperWidgets.ScrollView {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Column {
|
Column {
|
||||||
ContentLibraryMaterialContextMenu {
|
ContentLibraryItemContextMenu {
|
||||||
id: ctxMenuMaterial
|
id: ctxMenuItem
|
||||||
|
|
||||||
enableRemove: true
|
enableRemove: true
|
||||||
hasModelSelection: ContentLibraryBackend.userModel.hasModelSelection
|
|
||||||
importerRunning: ContentLibraryBackend.rootView.importerRunning
|
|
||||||
|
|
||||||
onApplyToSelected: (add) => ContentLibraryBackend.userModel.applyToSelected(ctxMenuMaterial.targetMaterial, add)
|
onApplyToSelected: (add) => ContentLibraryBackend.userModel.applyToSelected(ctxMenuItem.targetItem, add)
|
||||||
|
|
||||||
onUnimport: root.unimport(ctxMenuMaterial.targetMaterial)
|
onUnimport: root.unimport(ctxMenuItem.targetItem)
|
||||||
onAddToProject: ContentLibraryBackend.userModel.addToProject(ctxMenuMaterial.targetMaterial)
|
onAddToProject: ContentLibraryBackend.userModel.addToProject(ctxMenuItem.targetItem)
|
||||||
onRemoveFromContentLib: root.removeFromContentLib(ctxMenuMaterial.targetMaterial)
|
onRemoveFromContentLib: root.removeFromContentLib(ctxMenuItem.targetItem)
|
||||||
}
|
}
|
||||||
|
|
||||||
ContentLibraryTextureContextMenu {
|
ContentLibraryTextureContextMenu {
|
||||||
@@ -114,9 +112,7 @@ HelperWidgets.ScrollView {
|
|||||||
width: root.cellWidth
|
width: root.cellWidth
|
||||||
height: root.cellHeight
|
height: root.cellHeight
|
||||||
|
|
||||||
importerRunning: ContentLibraryBackend.rootView.importerRunning
|
onShowContextMenu: ctxMenuItem.popupMenu(modelData)
|
||||||
|
|
||||||
onShowContextMenu: ctxMenuMaterial.popupMenu(modelData)
|
|
||||||
onAddToProject: ContentLibraryBackend.userModel.addToProject(modelData)
|
onAddToProject: ContentLibraryBackend.userModel.addToProject(modelData)
|
||||||
|
|
||||||
onVisibleChanged: {
|
onVisibleChanged: {
|
||||||
@@ -139,7 +135,7 @@ HelperWidgets.ScrollView {
|
|||||||
width: root.cellWidth
|
width: root.cellWidth
|
||||||
height: root.cellHeight
|
height: root.cellHeight
|
||||||
|
|
||||||
// onShowContextMenu: ctxMenuTexture.popupMenu(modelData) // TODO
|
onShowContextMenu: ctxMenuItem.popupMenu(modelData)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -36,7 +36,6 @@ public:
|
|||||||
TypeName type() const;
|
TypeName type() const;
|
||||||
QStringList files() const;
|
QStringList files() const;
|
||||||
bool visible() const;
|
bool visible() const;
|
||||||
QString qmlFilePath() const;
|
|
||||||
|
|
||||||
bool setImported(bool imported);
|
bool setImported(bool imported);
|
||||||
bool imported() const;
|
bool imported() const;
|
||||||
|
@@ -17,7 +17,7 @@ class ContentLibraryMaterial : public QObject
|
|||||||
Q_PROPERTY(QString bundleMaterialName MEMBER m_name CONSTANT)
|
Q_PROPERTY(QString bundleMaterialName MEMBER m_name CONSTANT)
|
||||||
Q_PROPERTY(QUrl bundleMaterialIcon MEMBER m_icon CONSTANT)
|
Q_PROPERTY(QUrl bundleMaterialIcon MEMBER m_icon CONSTANT)
|
||||||
Q_PROPERTY(bool bundleMaterialVisible MEMBER m_visible NOTIFY materialVisibleChanged)
|
Q_PROPERTY(bool bundleMaterialVisible MEMBER m_visible NOTIFY materialVisibleChanged)
|
||||||
Q_PROPERTY(bool bundleMaterialImported READ imported WRITE setImported NOTIFY materialImportedChanged)
|
Q_PROPERTY(bool bundleItemImported READ imported WRITE setImported NOTIFY materialImportedChanged)
|
||||||
Q_PROPERTY(QString bundleMaterialBaseWebUrl MEMBER m_baseWebUrl CONSTANT)
|
Q_PROPERTY(QString bundleMaterialBaseWebUrl MEMBER m_baseWebUrl CONSTANT)
|
||||||
Q_PROPERTY(QString bundleMaterialDirPath READ dirPath CONSTANT)
|
Q_PROPERTY(QString bundleMaterialDirPath READ dirPath CONSTANT)
|
||||||
Q_PROPERTY(QStringList bundleMaterialFiles READ allFiles CONSTANT)
|
Q_PROPERTY(QStringList bundleMaterialFiles READ allFiles CONSTANT)
|
||||||
|
@@ -383,18 +383,4 @@ void ContentLibraryMaterialsModel::removeFromProject(ContentLibraryMaterial *mat
|
|||||||
qWarning() << __FUNCTION__ << err;
|
qWarning() << __FUNCTION__ << err;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ContentLibraryMaterialsModel::hasModelSelection() const
|
|
||||||
{
|
|
||||||
return m_hasModelSelection;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ContentLibraryMaterialsModel::setHasModelSelection(bool b)
|
|
||||||
{
|
|
||||||
if (b == m_hasModelSelection)
|
|
||||||
return;
|
|
||||||
|
|
||||||
m_hasModelSelection = b;
|
|
||||||
emit hasModelSelectionChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace QmlDesigner
|
} // namespace QmlDesigner
|
||||||
|
@@ -21,7 +21,6 @@ class ContentLibraryMaterialsModel : public QAbstractListModel
|
|||||||
Q_PROPERTY(bool matBundleExists READ matBundleExists NOTIFY matBundleExistsChanged)
|
Q_PROPERTY(bool matBundleExists READ matBundleExists NOTIFY matBundleExistsChanged)
|
||||||
Q_PROPERTY(bool isEmpty MEMBER m_isEmpty NOTIFY isEmptyChanged)
|
Q_PROPERTY(bool isEmpty MEMBER m_isEmpty NOTIFY isEmptyChanged)
|
||||||
Q_PROPERTY(bool hasRequiredQuick3DImport READ hasRequiredQuick3DImport NOTIFY hasRequiredQuick3DImportChanged)
|
Q_PROPERTY(bool hasRequiredQuick3DImport READ hasRequiredQuick3DImport NOTIFY hasRequiredQuick3DImportChanged)
|
||||||
Q_PROPERTY(bool hasModelSelection READ hasModelSelection NOTIFY hasModelSelectionChanged)
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ContentLibraryMaterialsModel(ContentLibraryWidget *parent = nullptr);
|
ContentLibraryMaterialsModel(ContentLibraryWidget *parent = nullptr);
|
||||||
@@ -33,16 +32,11 @@ public:
|
|||||||
|
|
||||||
void setSearchText(const QString &searchText);
|
void setSearchText(const QString &searchText);
|
||||||
void updateImportedState(const QStringList &importedItems);
|
void updateImportedState(const QStringList &importedItems);
|
||||||
|
|
||||||
void setQuick3DImportVersion(int major, int minor);
|
void setQuick3DImportVersion(int major, int minor);
|
||||||
|
|
||||||
bool hasRequiredQuick3DImport() const;
|
bool hasRequiredQuick3DImport() const;
|
||||||
|
|
||||||
bool matBundleExists() const;
|
bool matBundleExists() const;
|
||||||
|
|
||||||
bool hasModelSelection() const;
|
|
||||||
void setHasModelSelection(bool b);
|
|
||||||
|
|
||||||
void resetModel();
|
void resetModel();
|
||||||
void updateIsEmpty();
|
void updateIsEmpty();
|
||||||
void loadBundle();
|
void loadBundle();
|
||||||
@@ -56,7 +50,6 @@ public:
|
|||||||
signals:
|
signals:
|
||||||
void isEmptyChanged();
|
void isEmptyChanged();
|
||||||
void hasRequiredQuick3DImportChanged();
|
void hasRequiredQuick3DImportChanged();
|
||||||
void hasModelSelectionChanged();
|
|
||||||
void materialVisibleChanged();
|
void materialVisibleChanged();
|
||||||
void applyToSelectedTriggered(QmlDesigner::ContentLibraryMaterial *mat, bool add = false);
|
void applyToSelectedTriggered(QmlDesigner::ContentLibraryMaterial *mat, bool add = false);
|
||||||
void matBundleExistsChanged();
|
void matBundleExistsChanged();
|
||||||
@@ -77,7 +70,6 @@ private:
|
|||||||
|
|
||||||
bool m_isEmpty = true;
|
bool m_isEmpty = true;
|
||||||
bool m_bundleExists = false;
|
bool m_bundleExists = false;
|
||||||
bool m_hasModelSelection = false;
|
|
||||||
|
|
||||||
int m_quick3dMajorVersion = -1;
|
int m_quick3dMajorVersion = -1;
|
||||||
int m_quick3dMinorVersion = -1;
|
int m_quick3dMinorVersion = -1;
|
||||||
|
@@ -177,7 +177,15 @@ void ContentLibraryUserModel::removeTexture(ContentLibraryTexture *tex)
|
|||||||
emit dataChanged(index(texSectionIdx), index(texSectionIdx));
|
emit dataChanged(index(texSectionIdx), index(texSectionIdx));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ContentLibraryUserModel::removeFromContentLib(ContentLibraryMaterial *mat)
|
void ContentLibraryUserModel::removeFromContentLib(QObject *item)
|
||||||
|
{
|
||||||
|
if (auto mat = qobject_cast<ContentLibraryMaterial *>(item))
|
||||||
|
removeMaterialFromContentLib(mat);
|
||||||
|
else if (auto itm = qobject_cast<ContentLibraryItem *>(item))
|
||||||
|
remove3DFromContentLib(itm);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ContentLibraryUserModel::removeMaterialFromContentLib(ContentLibraryMaterial *mat)
|
||||||
{
|
{
|
||||||
auto bundlePath = Utils::FilePath::fromString(Paths::bundlesPathSetting() + "/User/materials/");
|
auto bundlePath = Utils::FilePath::fromString(Paths::bundlesPathSetting() + "/User/materials/");
|
||||||
|
|
||||||
@@ -215,6 +223,48 @@ void ContentLibraryUserModel::removeFromContentLib(ContentLibraryMaterial *mat)
|
|||||||
emit dataChanged(index(matSectionIdx), index(matSectionIdx));
|
emit dataChanged(index(matSectionIdx), index(matSectionIdx));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ContentLibraryUserModel::remove3DFromContentLib(ContentLibraryItem *item)
|
||||||
|
{
|
||||||
|
QJsonArray itemsArr = m_bundleObj3D.value("items").toArray();
|
||||||
|
|
||||||
|
// remove qml and icon files
|
||||||
|
m_bundlePath3D.pathAppended(item->qml()).removeFile();
|
||||||
|
Utils::FilePath::fromUrl(item->icon()).removeFile();
|
||||||
|
|
||||||
|
// remove from the bundle json file
|
||||||
|
for (int i = 0; i < itemsArr.size(); ++i) {
|
||||||
|
if (itemsArr.at(i).toObject().value("qml") == item->qml()) {
|
||||||
|
itemsArr.removeAt(i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m_bundleObj3D.insert("items", itemsArr);
|
||||||
|
|
||||||
|
auto result = m_bundlePath3D.pathAppended("user_3d_bundle.json")
|
||||||
|
.writeFileContents(QJsonDocument(m_bundleObj3D).toJson());
|
||||||
|
if (!result)
|
||||||
|
qWarning() << __FUNCTION__ << result.error();
|
||||||
|
|
||||||
|
// delete dependency files if they are only used by the deleted item
|
||||||
|
QStringList allFiles;
|
||||||
|
for (const QJsonValueConstRef &itemRef : std::as_const(itemsArr))
|
||||||
|
allFiles.append(itemRef.toObject().value("files").toVariant().toStringList());
|
||||||
|
|
||||||
|
const QStringList itemFiles = item->files();
|
||||||
|
for (const QString &file : itemFiles) {
|
||||||
|
if (allFiles.count(file) == 0) // only used by the deleted item
|
||||||
|
m_bundlePath3D.pathAppended(file).removeFile();
|
||||||
|
}
|
||||||
|
|
||||||
|
// remove from model
|
||||||
|
m_user3DItems.removeOne(item);
|
||||||
|
item->deleteLater();
|
||||||
|
|
||||||
|
// update model
|
||||||
|
int sectionIdx = 2;
|
||||||
|
emit dataChanged(index(sectionIdx), index(sectionIdx));
|
||||||
|
}
|
||||||
|
|
||||||
// returns unique library material's name and qml component
|
// returns unique library material's name and qml component
|
||||||
QPair<QString, QString> ContentLibraryUserModel::getUniqueLibMaterialNameAndQml(const QString &defaultName) const
|
QPair<QString, QString> ContentLibraryUserModel::getUniqueLibMaterialNameAndQml(const QString &defaultName) const
|
||||||
{
|
{
|
||||||
@@ -520,7 +570,7 @@ void ContentLibraryUserModel::setSearchText(const QString &searchText)
|
|||||||
updateIsEmpty3D();
|
updateIsEmpty3D();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ContentLibraryUserModel::updateImportedState(const QStringList &importedItems)
|
void ContentLibraryUserModel::updateMaterialsImportedState(const QStringList &importedItems)
|
||||||
{
|
{
|
||||||
bool changed = false;
|
bool changed = false;
|
||||||
for (ContentLibraryMaterial *mat : std::as_const(m_userMaterials))
|
for (ContentLibraryMaterial *mat : std::as_const(m_userMaterials))
|
||||||
@@ -532,6 +582,18 @@ void ContentLibraryUserModel::updateImportedState(const QStringList &importedIte
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ContentLibraryUserModel::update3DImportedState(const QStringList &importedItems)
|
||||||
|
{
|
||||||
|
bool changed = false;
|
||||||
|
for (ContentLibraryItem *item : std::as_const(m_user3DItems))
|
||||||
|
changed |= item->setImported(importedItems.contains(item->qml().chopped(4)));
|
||||||
|
|
||||||
|
if (changed) {
|
||||||
|
int sectionIdx = 2;
|
||||||
|
emit dataChanged(index(sectionIdx), index(sectionIdx));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ContentLibraryUserModel::setQuick3DImportVersion(int major, int minor)
|
void ContentLibraryUserModel::setQuick3DImportVersion(int major, int minor)
|
||||||
{
|
{
|
||||||
bool oldRequiredImport = hasRequiredQuick3DImport();
|
bool oldRequiredImport = hasRequiredQuick3DImport();
|
||||||
@@ -561,39 +623,56 @@ void ContentLibraryUserModel::applyToSelected(ContentLibraryMaterial *mat, bool
|
|||||||
emit applyToSelectedTriggered(mat, add);
|
emit applyToSelectedTriggered(mat, add);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ContentLibraryUserModel::addToProject(ContentLibraryMaterial *mat)
|
void ContentLibraryUserModel::addToProject(QObject *item)
|
||||||
{
|
{
|
||||||
QString err = m_widget->importer()->importComponent(mat->dirPath(), mat->type(), mat->qml(),
|
QString bundleDir;
|
||||||
mat->files() + m_bundleMaterialSharedFiles);
|
TypeName type;
|
||||||
|
QString qmlFile;
|
||||||
if (err.isEmpty())
|
QStringList files;
|
||||||
m_widget->setImporterRunning(true);
|
if (auto mat = qobject_cast<ContentLibraryMaterial *>(item)) {
|
||||||
else
|
bundleDir = mat->dirPath();
|
||||||
qWarning() << __FUNCTION__ << err;
|
type = mat->type();
|
||||||
}
|
qmlFile = mat->qml();
|
||||||
|
files = mat->files() + m_bundleMaterialSharedFiles;
|
||||||
void ContentLibraryUserModel::removeFromProject(ContentLibraryMaterial *mat)
|
} else if (auto itm = qobject_cast<ContentLibraryItem *>(item)) {
|
||||||
{
|
bundleDir = m_bundlePath3D.toString();
|
||||||
QString err = m_widget->importer()->unimportComponent(mat->type(), mat->qml());
|
type = itm->type();
|
||||||
|
qmlFile = itm->qml();
|
||||||
if (err.isEmpty())
|
files = itm->files() + m_bundle3DSharedFiles;
|
||||||
m_widget->setImporterRunning(true);
|
} else {
|
||||||
else
|
qWarning() << __FUNCTION__ << "Unsupported Item";
|
||||||
qWarning() << __FUNCTION__ << err;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ContentLibraryUserModel::hasModelSelection() const
|
|
||||||
{
|
|
||||||
return m_hasModelSelection;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ContentLibraryUserModel::setHasModelSelection(bool b)
|
|
||||||
{
|
|
||||||
if (b == m_hasModelSelection)
|
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
m_hasModelSelection = b;
|
QString err = m_widget->importer()->importComponent(bundleDir, type, qmlFile, files);
|
||||||
emit hasModelSelectionChanged();
|
|
||||||
|
if (err.isEmpty())
|
||||||
|
m_widget->setImporterRunning(true);
|
||||||
|
else
|
||||||
|
qWarning() << __FUNCTION__ << err;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ContentLibraryUserModel::removeFromProject(QObject *item)
|
||||||
|
{
|
||||||
|
TypeName type;
|
||||||
|
QString qml;
|
||||||
|
if (auto mat = qobject_cast<ContentLibraryMaterial *>(item)) {
|
||||||
|
type = mat->type();
|
||||||
|
qml = mat->qml();
|
||||||
|
} else if (auto itm = qobject_cast<ContentLibraryItem *>(item)) {
|
||||||
|
type = itm->type();
|
||||||
|
qml = itm->qml();
|
||||||
|
} else {
|
||||||
|
qWarning() << __FUNCTION__ << "Unsupported Item";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString err = m_widget->importer()->unimportComponent(type, qml);
|
||||||
|
|
||||||
|
if (err.isEmpty())
|
||||||
|
m_widget->setImporterRunning(true);
|
||||||
|
else
|
||||||
|
qWarning() << __FUNCTION__ << err;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace QmlDesigner
|
} // namespace QmlDesigner
|
||||||
|
@@ -27,7 +27,6 @@ class ContentLibraryUserModel : public QAbstractListModel
|
|||||||
Q_PROPERTY(bool isEmptyMaterials MEMBER m_isEmptyMaterials NOTIFY isEmptyMaterialsChanged)
|
Q_PROPERTY(bool isEmptyMaterials MEMBER m_isEmptyMaterials NOTIFY isEmptyMaterialsChanged)
|
||||||
Q_PROPERTY(bool isEmpty3D MEMBER m_isEmpty3D NOTIFY isEmpty3DChanged)
|
Q_PROPERTY(bool isEmpty3D MEMBER m_isEmpty3D NOTIFY isEmpty3DChanged)
|
||||||
Q_PROPERTY(bool hasRequiredQuick3DImport READ hasRequiredQuick3DImport NOTIFY hasRequiredQuick3DImportChanged)
|
Q_PROPERTY(bool hasRequiredQuick3DImport READ hasRequiredQuick3DImport NOTIFY hasRequiredQuick3DImportChanged)
|
||||||
Q_PROPERTY(bool hasModelSelection READ hasModelSelection NOTIFY hasModelSelectionChanged)
|
|
||||||
Q_PROPERTY(QList<ContentLibraryMaterial *> userMaterials MEMBER m_userMaterials NOTIFY userMaterialsChanged)
|
Q_PROPERTY(QList<ContentLibraryMaterial *> userMaterials MEMBER m_userMaterials NOTIFY userMaterialsChanged)
|
||||||
Q_PROPERTY(QList<ContentLibraryTexture *> userTextures MEMBER m_userTextures NOTIFY userTexturesChanged)
|
Q_PROPERTY(QList<ContentLibraryTexture *> userTextures MEMBER m_userTextures NOTIFY userTexturesChanged)
|
||||||
Q_PROPERTY(QList<ContentLibraryItem *> user3DItems MEMBER m_user3DItems NOTIFY user3DItemsChanged)
|
Q_PROPERTY(QList<ContentLibraryItem *> user3DItems MEMBER m_user3DItems NOTIFY user3DItemsChanged)
|
||||||
@@ -41,7 +40,8 @@ public:
|
|||||||
QHash<int, QByteArray> roleNames() const override;
|
QHash<int, QByteArray> roleNames() const override;
|
||||||
|
|
||||||
void setSearchText(const QString &searchText);
|
void setSearchText(const QString &searchText);
|
||||||
void updateImportedState(const QStringList &importedItems);
|
void updateMaterialsImportedState(const QStringList &importedItems);
|
||||||
|
void update3DImportedState(const QStringList &importedItems);
|
||||||
|
|
||||||
QPair<QString, QString> getUniqueLibMaterialNameAndQml(const QString &defaultName = {}) const;
|
QPair<QString, QString> getUniqueLibMaterialNameAndQml(const QString &defaultName = {}) const;
|
||||||
QString getUniqueLib3DQmlName(const QString &defaultName = {}) const;
|
QString getUniqueLib3DQmlName(const QString &defaultName = {}) const;
|
||||||
@@ -52,9 +52,6 @@ public:
|
|||||||
|
|
||||||
bool matBundleExists() const;
|
bool matBundleExists() const;
|
||||||
|
|
||||||
bool hasModelSelection() const;
|
|
||||||
void setHasModelSelection(bool b);
|
|
||||||
|
|
||||||
void resetModel();
|
void resetModel();
|
||||||
void updateIsEmptyMaterials();
|
void updateIsEmptyMaterials();
|
||||||
void updateIsEmpty3D();
|
void updateIsEmpty3D();
|
||||||
@@ -73,23 +70,20 @@ public:
|
|||||||
void loadBundles();
|
void loadBundles();
|
||||||
|
|
||||||
Q_INVOKABLE void applyToSelected(QmlDesigner::ContentLibraryMaterial *mat, bool add = false);
|
Q_INVOKABLE void applyToSelected(QmlDesigner::ContentLibraryMaterial *mat, bool add = false);
|
||||||
Q_INVOKABLE void addToProject(QmlDesigner::ContentLibraryMaterial *mat);
|
Q_INVOKABLE void addToProject(QObject *item);
|
||||||
Q_INVOKABLE void removeFromProject(QmlDesigner::ContentLibraryMaterial *mat);
|
Q_INVOKABLE void removeFromProject(QObject *item);
|
||||||
Q_INVOKABLE void removeTexture(QmlDesigner::ContentLibraryTexture *tex);
|
Q_INVOKABLE void removeTexture(QmlDesigner::ContentLibraryTexture *tex);
|
||||||
Q_INVOKABLE void removeFromContentLib(QmlDesigner::ContentLibraryMaterial *mat);
|
Q_INVOKABLE void removeFromContentLib(QObject *item);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void isEmptyMaterialsChanged();
|
void isEmptyMaterialsChanged();
|
||||||
void isEmpty3DChanged();
|
void isEmpty3DChanged();
|
||||||
void hasRequiredQuick3DImportChanged();
|
void hasRequiredQuick3DImportChanged();
|
||||||
void hasModelSelectionChanged();
|
|
||||||
void userMaterialsChanged();
|
void userMaterialsChanged();
|
||||||
void userTexturesChanged();
|
void userTexturesChanged();
|
||||||
void user3DItemsChanged();
|
void user3DItemsChanged();
|
||||||
void userEffectsChanged();
|
void userEffectsChanged();
|
||||||
|
|
||||||
void applyToSelectedTriggered(QmlDesigner::ContentLibraryMaterial *mat, bool add = false);
|
void applyToSelectedTriggered(QmlDesigner::ContentLibraryMaterial *mat, bool add = false);
|
||||||
|
|
||||||
void matBundleExistsChanged();
|
void matBundleExistsChanged();
|
||||||
void bundle3DExistsChanged();
|
void bundle3DExistsChanged();
|
||||||
|
|
||||||
@@ -98,6 +92,8 @@ private:
|
|||||||
void load3DBundle();
|
void load3DBundle();
|
||||||
void loadTextureBundle();
|
void loadTextureBundle();
|
||||||
bool isValidIndex(int idx) const;
|
bool isValidIndex(int idx) const;
|
||||||
|
void removeMaterialFromContentLib(ContentLibraryMaterial *mat);
|
||||||
|
void remove3DFromContentLib(ContentLibraryItem *item);
|
||||||
|
|
||||||
ContentLibraryWidget *m_widget = nullptr;
|
ContentLibraryWidget *m_widget = nullptr;
|
||||||
QString m_searchText;
|
QString m_searchText;
|
||||||
@@ -120,7 +116,6 @@ private:
|
|||||||
bool m_isEmpty3D = true;
|
bool m_isEmpty3D = true;
|
||||||
bool m_matBundleExists = false;
|
bool m_matBundleExists = false;
|
||||||
bool m_bundle3DExists = false;
|
bool m_bundle3DExists = false;
|
||||||
bool m_hasModelSelection = false;
|
|
||||||
|
|
||||||
int m_quick3dMajorVersion = -1;
|
int m_quick3dMajorVersion = -1;
|
||||||
int m_quick3dMinorVersion = -1;
|
int m_quick3dMinorVersion = -1;
|
||||||
|
@@ -306,8 +306,7 @@ void ContentLibraryView::selectedNodesChanged(const QList<ModelNode> &selectedNo
|
|||||||
return node.metaInfo().isQtQuick3DModel();
|
return node.metaInfo().isQtQuick3DModel();
|
||||||
});
|
});
|
||||||
|
|
||||||
m_widget->materialsModel()->setHasModelSelection(!m_selectedModels.isEmpty());
|
m_widget->setHasModelSelection(!m_selectedModels.isEmpty());
|
||||||
m_widget->userModel()->setHasModelSelection(!m_selectedModels.isEmpty());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ContentLibraryView::customNotification(const AbstractView *view,
|
void ContentLibraryView::customNotification(const AbstractView *view,
|
||||||
@@ -565,7 +564,7 @@ QStringList ContentLibraryView::writeLibItemQml(const ModelNode &node, const QSt
|
|||||||
|
|
||||||
qmlString.prepend("import QtQuick\nimport QtQuick3D\n\n");
|
qmlString.prepend("import QtQuick\nimport QtQuick3D\n\n");
|
||||||
|
|
||||||
QString itemType = QLatin1String(node.metaInfo().isQtQuick3DMaterial() ? "material" : "3d");
|
QString itemType = QLatin1String(node.metaInfo().isQtQuick3DMaterial() ? "materials" : "3d");
|
||||||
auto qmlPath = Utils::FilePath::fromString(QLatin1String("%1/User/%2/%3")
|
auto qmlPath = Utils::FilePath::fromString(QLatin1String("%1/User/%2/%3")
|
||||||
.arg(Paths::bundlesPathSetting(), itemType, qml));
|
.arg(Paths::bundlesPathSetting(), itemType, qml));
|
||||||
auto result = qmlPath.writeFileContents(qmlString.toUtf8());
|
auto result = qmlPath.writeFileContents(qmlString.toUtf8());
|
||||||
|
@@ -231,7 +231,9 @@ void ContentLibraryWidget::updateImportedState(const QString &bundleId)
|
|||||||
else if (bundleId == compUtils.effectsBundleId())
|
else if (bundleId == compUtils.effectsBundleId())
|
||||||
m_effectsModel->updateImportedState(importedItems);
|
m_effectsModel->updateImportedState(importedItems);
|
||||||
else if (bundleId == compUtils.userMaterialsBundleId())
|
else if (bundleId == compUtils.userMaterialsBundleId())
|
||||||
m_userModel->updateImportedState(importedItems);
|
m_userModel->updateMaterialsImportedState(importedItems);
|
||||||
|
else if (bundleId == compUtils.user3DBundleId())
|
||||||
|
m_userModel->update3DImportedState(importedItems);
|
||||||
}
|
}
|
||||||
|
|
||||||
ContentLibraryBundleImporter *ContentLibraryWidget::importer() const
|
ContentLibraryBundleImporter *ContentLibraryWidget::importer() const
|
||||||
@@ -865,4 +867,18 @@ QPointer<ContentLibraryUserModel> ContentLibraryWidget::userModel() const
|
|||||||
return m_userModel;
|
return m_userModel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ContentLibraryWidget::hasModelSelection() const
|
||||||
|
{
|
||||||
|
return m_hasModelSelection;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ContentLibraryWidget::setHasModelSelection(bool b)
|
||||||
|
{
|
||||||
|
if (b == m_hasModelSelection)
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_hasModelSelection = b;
|
||||||
|
emit hasModelSelectionChanged();
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace QmlDesigner
|
} // namespace QmlDesigner
|
||||||
|
@@ -41,6 +41,7 @@ class ContentLibraryWidget : public QFrame
|
|||||||
Q_PROPERTY(bool hasActive3DScene READ hasActive3DScene WRITE setHasActive3DScene NOTIFY hasActive3DSceneChanged)
|
Q_PROPERTY(bool hasActive3DScene READ hasActive3DScene WRITE setHasActive3DScene NOTIFY hasActive3DSceneChanged)
|
||||||
Q_PROPERTY(bool isQt6Project READ isQt6Project NOTIFY isQt6ProjectChanged)
|
Q_PROPERTY(bool isQt6Project READ isQt6Project NOTIFY isQt6ProjectChanged)
|
||||||
Q_PROPERTY(bool importerRunning READ importerRunning WRITE setImporterRunning NOTIFY importerRunningChanged)
|
Q_PROPERTY(bool importerRunning READ importerRunning WRITE setImporterRunning NOTIFY importerRunningChanged)
|
||||||
|
Q_PROPERTY(bool hasModelSelection READ hasModelSelection NOTIFY hasModelSelectionChanged)
|
||||||
|
|
||||||
// Needed for a workaround for a bug where after drag-n-dropping an item, the ScrollView scrolls to a random position
|
// Needed for a workaround for a bug where after drag-n-dropping an item, the ScrollView scrolls to a random position
|
||||||
Q_PROPERTY(bool isDragging MEMBER m_isDragging NOTIFY isDraggingChanged)
|
Q_PROPERTY(bool isDragging MEMBER m_isDragging NOTIFY isDraggingChanged)
|
||||||
@@ -68,7 +69,8 @@ public:
|
|||||||
bool importerRunning() const;
|
bool importerRunning() const;
|
||||||
void setImporterRunning(bool b);
|
void setImporterRunning(bool b);
|
||||||
|
|
||||||
Q_INVOKABLE void handleSearchFilterChanged(const QString &filterText);
|
bool hasModelSelection() const;
|
||||||
|
void setHasModelSelection(bool b);
|
||||||
|
|
||||||
void setMaterialsModel(QPointer<ContentLibraryMaterialsModel> newMaterialsModel);
|
void setMaterialsModel(QPointer<ContentLibraryMaterialsModel> newMaterialsModel);
|
||||||
void updateImportedState(const QString &bundleId);
|
void updateImportedState(const QString &bundleId);
|
||||||
@@ -79,6 +81,7 @@ public:
|
|||||||
QPointer<ContentLibraryEffectsModel> effectsModel() const;
|
QPointer<ContentLibraryEffectsModel> effectsModel() const;
|
||||||
QPointer<ContentLibraryUserModel> userModel() const;
|
QPointer<ContentLibraryUserModel> userModel() const;
|
||||||
|
|
||||||
|
Q_INVOKABLE void handleSearchFilterChanged(const QString &filterText);
|
||||||
Q_INVOKABLE void startDragItem(QmlDesigner::ContentLibraryItem *item, const QPointF &mousePos);
|
Q_INVOKABLE void startDragItem(QmlDesigner::ContentLibraryItem *item, const QPointF &mousePos);
|
||||||
Q_INVOKABLE void startDragMaterial(QmlDesigner::ContentLibraryMaterial *mat, const QPointF &mousePos);
|
Q_INVOKABLE void startDragMaterial(QmlDesigner::ContentLibraryMaterial *mat, const QPointF &mousePos);
|
||||||
Q_INVOKABLE void startDragTexture(QmlDesigner::ContentLibraryTexture *tex, const QPointF &mousePos);
|
Q_INVOKABLE void startDragTexture(QmlDesigner::ContentLibraryTexture *tex, const QPointF &mousePos);
|
||||||
@@ -105,6 +108,7 @@ signals:
|
|||||||
void isDraggingChanged();
|
void isDraggingChanged();
|
||||||
void isQt6ProjectChanged();
|
void isQt6ProjectChanged();
|
||||||
void importerRunningChanged();
|
void importerRunningChanged();
|
||||||
|
void hasModelSelectionChanged();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool eventFilter(QObject *obj, QEvent *event) override;
|
bool eventFilter(QObject *obj, QEvent *event) override;
|
||||||
@@ -148,6 +152,7 @@ private:
|
|||||||
bool m_isDragging = false;
|
bool m_isDragging = false;
|
||||||
bool m_isQt6Project = false;
|
bool m_isQt6Project = false;
|
||||||
bool m_importerRunning = false;
|
bool m_importerRunning = false;
|
||||||
|
bool m_hasModelSelection = false;
|
||||||
QString m_textureBundleUrl;
|
QString m_textureBundleUrl;
|
||||||
QString m_bundlePath;
|
QString m_bundlePath;
|
||||||
};
|
};
|
||||||
|
Reference in New Issue
Block a user