forked from qt-creator/qt-creator
QmlDesigner: Implement unimporting bundle materials
Fixes: QDS-7904 Change-Id: I08642c25a2844547d0104a7b3d9fda6afe47cd38 Reviewed-by: <github-actions-qt-creator@cristianadam.eu> Reviewed-by: Miikka Heikkinen <miikka.heikkinen@qt.io>
This commit is contained in:
@@ -27,6 +27,8 @@ import QtQuick 2.15
|
|||||||
import QtQuick.Layouts 1.15
|
import QtQuick.Layouts 1.15
|
||||||
import QtQuickDesignerTheme 1.0
|
import QtQuickDesignerTheme 1.0
|
||||||
import HelperWidgets 2.0
|
import HelperWidgets 2.0
|
||||||
|
import QtQuick.Controls
|
||||||
|
|
||||||
import StudioTheme 1.0 as StudioTheme
|
import StudioTheme 1.0 as StudioTheme
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
@@ -43,7 +45,7 @@ Item {
|
|||||||
acceptedButtons: Qt.LeftButton | Qt.RightButton
|
acceptedButtons: Qt.LeftButton | Qt.RightButton
|
||||||
|
|
||||||
onPressed: (mouse) => {
|
onPressed: (mouse) => {
|
||||||
if (mouse.button === Qt.LeftButton)
|
if (mouse.button === Qt.LeftButton && !materialBrowserBundleModel.importerRunning)
|
||||||
rootView.startDragBundleMaterial(modelData, mapToGlobal(mouse.x, mouse.y))
|
rootView.startDragBundleMaterial(modelData, mapToGlobal(mouse.x, mouse.y))
|
||||||
else if (mouse.button === Qt.RightButton)
|
else if (mouse.button === Qt.RightButton)
|
||||||
root.showContextMenu()
|
root.showContextMenu()
|
||||||
@@ -64,6 +66,48 @@ Item {
|
|||||||
anchors.horizontalCenter: parent.horizontalCenter
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
source: modelData.bundleMaterialIcon
|
source: modelData.bundleMaterialIcon
|
||||||
cache: false
|
cache: false
|
||||||
|
|
||||||
|
Rectangle { // circular indicator for imported bundle materials
|
||||||
|
width: 10
|
||||||
|
height: 10
|
||||||
|
radius: 5
|
||||||
|
anchors.right: img.right
|
||||||
|
anchors.top: img.top
|
||||||
|
anchors.margins: 5
|
||||||
|
color: "#00ff00"
|
||||||
|
border.color: "#555555"
|
||||||
|
border.width: 1
|
||||||
|
visible: modelData.bundleMaterialImported
|
||||||
|
|
||||||
|
ToolTip {
|
||||||
|
visible: indicatorMouseArea.containsMouse
|
||||||
|
text: qsTr("Material is imported to project")
|
||||||
|
delay: 1000
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
id: indicatorMouseArea
|
||||||
|
anchors.fill: parent
|
||||||
|
hoverEnabled: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
IconButton {
|
||||||
|
icon: StudioTheme.Constants.plus
|
||||||
|
tooltip: qsTr("Add an instance to project")
|
||||||
|
buttonSize: 22
|
||||||
|
property color c: StudioTheme.Values.themeIconColor
|
||||||
|
normalColor: Qt.hsla(c.hslHue, c.hslSaturation, c.hslLightness, .2)
|
||||||
|
hoverColor: Qt.hsla(c.hslHue, c.hslSaturation, c.hslLightness, .3)
|
||||||
|
pressColor: Qt.hsla(c.hslHue, c.hslSaturation, c.hslLightness, .4)
|
||||||
|
anchors.right: img.right
|
||||||
|
anchors.bottom: img.bottom
|
||||||
|
enabled: !materialBrowserBundleModel.importerRunning
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
materialBrowserBundleModel.addToProject(modelData)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TextInput {
|
TextInput {
|
||||||
|
@@ -46,8 +46,8 @@ Item {
|
|||||||
// Called also from C++ to close context menu on focus out
|
// Called also from C++ to close context menu on focus out
|
||||||
function closeContextMenu()
|
function closeContextMenu()
|
||||||
{
|
{
|
||||||
cxtMenu.close()
|
ctxMenu.close()
|
||||||
cxtMenuBundle.close()
|
ctxMenuBundle.close()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Called from C++ to refresh a preview material after it changes
|
// Called from C++ to refresh a preview material after it changes
|
||||||
@@ -79,7 +79,7 @@ Item {
|
|||||||
if (!materialBrowserModel.hasMaterialRoot && (!materialBrowserBundleModel.matBundleExists
|
if (!materialBrowserModel.hasMaterialRoot && (!materialBrowserBundleModel.matBundleExists
|
||||||
|| mouse.y < userMatsSecBottom)) {
|
|| mouse.y < userMatsSecBottom)) {
|
||||||
root.currentMaterial = null
|
root.currentMaterial = null
|
||||||
cxtMenu.popup()
|
ctxMenu.popup()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -97,8 +97,12 @@ Item {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UnimportBundleMaterialDialog {
|
||||||
|
id: unimportBundleMaterialDialog
|
||||||
|
}
|
||||||
|
|
||||||
StudioControls.Menu {
|
StudioControls.Menu {
|
||||||
id: cxtMenu
|
id: ctxMenu
|
||||||
|
|
||||||
closePolicy: StudioControls.Menu.CloseOnEscape | StudioControls.Menu.CloseOnPressOutside
|
closePolicy: StudioControls.Menu.CloseOnEscape | StudioControls.Menu.CloseOnPressOutside
|
||||||
|
|
||||||
@@ -205,7 +209,7 @@ Item {
|
|||||||
}
|
}
|
||||||
|
|
||||||
StudioControls.Menu {
|
StudioControls.Menu {
|
||||||
id: cxtMenuBundle
|
id: ctxMenuBundle
|
||||||
|
|
||||||
closePolicy: StudioControls.Menu.CloseOnEscape | StudioControls.Menu.CloseOnPressOutside
|
closePolicy: StudioControls.Menu.CloseOnEscape | StudioControls.Menu.CloseOnPressOutside
|
||||||
|
|
||||||
@@ -224,9 +228,22 @@ Item {
|
|||||||
StudioControls.MenuSeparator {}
|
StudioControls.MenuSeparator {}
|
||||||
|
|
||||||
StudioControls.MenuItem {
|
StudioControls.MenuItem {
|
||||||
text: qsTr("Add to project")
|
enabled: !materialBrowserBundleModel.importerRunning
|
||||||
|
text: qsTr("Add an instance to project")
|
||||||
|
|
||||||
onTriggered: materialBrowserBundleModel.addMaterial(root.currentBundleMaterial)
|
onTriggered: {
|
||||||
|
materialBrowserBundleModel.addToProject(root.currentBundleMaterial)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
StudioControls.MenuItem {
|
||||||
|
enabled: !materialBrowserBundleModel.importerRunning && root.currentBundleMaterial.bundleMaterialImported
|
||||||
|
text: qsTr("Remove from project")
|
||||||
|
|
||||||
|
onTriggered: {
|
||||||
|
unimportBundleMaterialDialog.targetBundleMaterial = root.currentBundleMaterial
|
||||||
|
unimportBundleMaterialDialog.open()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -301,13 +318,14 @@ Item {
|
|||||||
height: root.height - searchBox.height
|
height: root.height - searchBox.height
|
||||||
clip: true
|
clip: true
|
||||||
visible: materialBrowserModel.hasQuick3DImport && !materialBrowserModel.hasMaterialRoot
|
visible: materialBrowserModel.hasQuick3DImport && !materialBrowserModel.hasMaterialRoot
|
||||||
|
interactive: !ctxMenu.opened && !ctxMenuBundle.opened
|
||||||
|
|
||||||
Column {
|
Column {
|
||||||
Section {
|
Section {
|
||||||
id: userMaterialsSection
|
id: userMaterialsSection
|
||||||
|
|
||||||
width: root.width
|
width: root.width
|
||||||
caption: qsTr("User materials")
|
caption: qsTr("Materials")
|
||||||
hideHeader: !materialBrowserBundleModel.matBundleExists
|
hideHeader: !materialBrowserBundleModel.matBundleExists
|
||||||
|
|
||||||
Grid {
|
Grid {
|
||||||
@@ -329,7 +347,7 @@ Item {
|
|||||||
|
|
||||||
onShowContextMenu: {
|
onShowContextMenu: {
|
||||||
root.currentMaterial = model
|
root.currentMaterial = model
|
||||||
cxtMenu.popup()
|
ctxMenu.popup()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -392,7 +410,7 @@ Item {
|
|||||||
|
|
||||||
onShowContextMenu: {
|
onShowContextMenu: {
|
||||||
root.currentBundleMaterial = modelData
|
root.currentBundleMaterial = modelData
|
||||||
cxtMenuBundle.popup()
|
ctxMenuBundle.popup()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,85 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** 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.
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
import QtQuick
|
||||||
|
import QtQuick.Controls
|
||||||
|
import QtQuick.Layouts
|
||||||
|
import QtQuickDesignerTheme
|
||||||
|
import HelperWidgets
|
||||||
|
import StudioControls as StudioControls
|
||||||
|
import StudioTheme as StudioTheme
|
||||||
|
|
||||||
|
Dialog {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
title: qsTr("Bundle material might be in use")
|
||||||
|
anchors.centerIn: parent
|
||||||
|
closePolicy: Popup.CloseOnEscape
|
||||||
|
implicitWidth: 300
|
||||||
|
modal: true
|
||||||
|
|
||||||
|
property var targetBundleMaterial
|
||||||
|
|
||||||
|
contentItem: Column {
|
||||||
|
spacing: 20
|
||||||
|
width: parent.width
|
||||||
|
|
||||||
|
Text {
|
||||||
|
id: folderNotEmpty
|
||||||
|
|
||||||
|
text: qsTr("If the material you are removing is in use, it might cause the project to malfunction.\n\nAre you sure you want to remove the material?")
|
||||||
|
color: StudioTheme.Values.themeTextColor
|
||||||
|
wrapMode: Text.WordWrap
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.left: parent.left
|
||||||
|
leftPadding: 10
|
||||||
|
rightPadding: 10
|
||||||
|
|
||||||
|
Keys.onEnterPressed: btnRemove.onClicked()
|
||||||
|
Keys.onReturnPressed: btnRemove.onClicked()
|
||||||
|
}
|
||||||
|
|
||||||
|
Row {
|
||||||
|
anchors.right: parent.right
|
||||||
|
Button {
|
||||||
|
id: btnRemove
|
||||||
|
|
||||||
|
text: qsTr("Remove")
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
materialBrowserBundleModel.removeFromProject(root.targetBundleMaterial)
|
||||||
|
root.accept()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Button {
|
||||||
|
text: qsTr("Cancel")
|
||||||
|
onClicked: root.reject()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onOpened: folderNotEmpty.forceActiveFocus()
|
||||||
|
}
|
@@ -51,6 +51,7 @@ public:
|
|||||||
QString importComponent(const QString &qmlFile,
|
QString importComponent(const QString &qmlFile,
|
||||||
const QStringList &files);
|
const QStringList &files);
|
||||||
QString unimportComponent(const QString &qmlFile);
|
QString unimportComponent(const QString &qmlFile);
|
||||||
|
Utils::FilePath resolveBundleImportPath();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
// The metaInfo parameter will be invalid if an error was encountered during
|
// The metaInfo parameter will be invalid if an error was encountered during
|
||||||
@@ -63,7 +64,6 @@ private:
|
|||||||
void handleImportTimer();
|
void handleImportTimer();
|
||||||
QVariantHash loadAssetRefMap(const Utils::FilePath &bundlePath);
|
QVariantHash loadAssetRefMap(const Utils::FilePath &bundlePath);
|
||||||
void writeAssetRefMap(const Utils::FilePath &bundlePath, const QVariantHash &assetRefMap);
|
void writeAssetRefMap(const Utils::FilePath &bundlePath, const QVariantHash &assetRefMap);
|
||||||
Utils::FilePath resolveBundleImportPath();
|
|
||||||
|
|
||||||
Utils::FilePath m_bundleDir;
|
Utils::FilePath m_bundleDir;
|
||||||
QString m_bundleId;
|
QString m_bundleId;
|
||||||
|
@@ -70,4 +70,20 @@ bool BundleMaterial::visible() const
|
|||||||
return m_visible;
|
return m_visible;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool BundleMaterial::setImported(bool imported)
|
||||||
|
{
|
||||||
|
if (m_imported != imported) {
|
||||||
|
m_imported = imported;
|
||||||
|
emit materialImportedChanged();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool BundleMaterial::imported() const
|
||||||
|
{
|
||||||
|
return m_imported;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace QmlDesigner
|
} // namespace QmlDesigner
|
||||||
|
@@ -40,6 +40,7 @@ class BundleMaterial : 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)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
BundleMaterial(QObject *parent,
|
BundleMaterial(QObject *parent,
|
||||||
@@ -57,8 +58,12 @@ public:
|
|||||||
QStringList files() const;
|
QStringList files() const;
|
||||||
bool visible() const;
|
bool visible() const;
|
||||||
|
|
||||||
|
bool setImported(bool imported);
|
||||||
|
bool imported() const;
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void materialVisibleChanged();
|
void materialVisibleChanged();
|
||||||
|
void materialImportedChanged();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QString m_name;
|
QString m_name;
|
||||||
@@ -68,6 +73,7 @@ private:
|
|||||||
QStringList m_files;
|
QStringList m_files;
|
||||||
|
|
||||||
bool m_visible = true;
|
bool m_visible = true;
|
||||||
|
bool m_imported = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace QmlDesigner
|
} // namespace QmlDesigner
|
||||||
|
@@ -37,6 +37,16 @@ void BundleMaterialCategory::addBundleMaterial(BundleMaterial *bundleMat)
|
|||||||
m_categoryMaterials.append(bundleMat);
|
m_categoryMaterials.append(bundleMat);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool BundleMaterialCategory::updateImportedState(const QStringList &importedMats)
|
||||||
|
{
|
||||||
|
bool changed = false;
|
||||||
|
|
||||||
|
for (BundleMaterial *mat : std::as_const(m_categoryMaterials))
|
||||||
|
changed |= mat->setImported(importedMats.contains(mat->qml().chopped(4)));
|
||||||
|
|
||||||
|
return changed;
|
||||||
|
}
|
||||||
|
|
||||||
bool BundleMaterialCategory::filter(const QString &searchText)
|
bool BundleMaterialCategory::filter(const QString &searchText)
|
||||||
{
|
{
|
||||||
bool visible = false;
|
bool visible = false;
|
||||||
|
@@ -42,6 +42,7 @@ public:
|
|||||||
BundleMaterialCategory(QObject *parent, const QString &name);
|
BundleMaterialCategory(QObject *parent, const QString &name);
|
||||||
|
|
||||||
void addBundleMaterial(BundleMaterial *bundleMat);
|
void addBundleMaterial(BundleMaterial *bundleMat);
|
||||||
|
bool updateImportedState(const QStringList &importedMats);
|
||||||
bool filter(const QString &searchText);
|
bool filter(const QString &searchText);
|
||||||
|
|
||||||
QString name() const;
|
QString name() const;
|
||||||
|
@@ -122,7 +122,7 @@ void MaterialBrowserBundleModel::loadMaterialBundle()
|
|||||||
|
|
||||||
m_matBundleExists = true;
|
m_matBundleExists = true;
|
||||||
|
|
||||||
const QString bundleId = m_matBundleObj.value("id").toString();
|
QString bundleId = m_matBundleObj.value("id").toString();
|
||||||
|
|
||||||
const QJsonObject catsObj = m_matBundleObj.value("categories").toObject();
|
const QJsonObject catsObj = m_matBundleObj.value("categories").toObject();
|
||||||
const QStringList categories = catsObj.keys();
|
const QStringList categories = catsObj.keys();
|
||||||
@@ -160,8 +160,17 @@ void MaterialBrowserBundleModel::loadMaterialBundle()
|
|||||||
|
|
||||||
m_importer = new Internal::BundleImporter(matBundleDir.path(), bundleId, sharedFiles);
|
m_importer = new Internal::BundleImporter(matBundleDir.path(), bundleId, sharedFiles);
|
||||||
connect(m_importer, &Internal::BundleImporter::importFinished, this, [&](const QmlDesigner::NodeMetaInfo &metaInfo) {
|
connect(m_importer, &Internal::BundleImporter::importFinished, this, [&](const QmlDesigner::NodeMetaInfo &metaInfo) {
|
||||||
|
m_importerRunning = false;
|
||||||
|
emit importerRunningChanged();
|
||||||
if (metaInfo.isValid())
|
if (metaInfo.isValid())
|
||||||
emit addBundleMaterialToProjectRequested(metaInfo);
|
emit bundleMaterialImported(metaInfo);
|
||||||
|
});
|
||||||
|
|
||||||
|
connect(m_importer, &Internal::BundleImporter::unimportFinished, this, [&](const QmlDesigner::NodeMetaInfo &metaInfo) {
|
||||||
|
Q_UNUSED(metaInfo)
|
||||||
|
m_importerRunning = false;
|
||||||
|
emit importerRunningChanged();
|
||||||
|
emit bundleMaterialUnimported(metaInfo);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -193,6 +202,11 @@ void MaterialBrowserBundleModel::setHasMaterialRoot(bool b)
|
|||||||
emit hasMaterialRootChanged();
|
emit hasMaterialRootChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Internal::BundleImporter *MaterialBrowserBundleModel::bundleImporter() const
|
||||||
|
{
|
||||||
|
return m_importer;
|
||||||
|
}
|
||||||
|
|
||||||
void MaterialBrowserBundleModel::setSearchText(const QString &searchText)
|
void MaterialBrowserBundleModel::setSearchText(const QString &searchText)
|
||||||
{
|
{
|
||||||
QString lowerSearchText = searchText.toLower();
|
QString lowerSearchText = searchText.toLower();
|
||||||
@@ -219,6 +233,16 @@ void MaterialBrowserBundleModel::setSearchText(const QString &searchText)
|
|||||||
resetModel();
|
resetModel();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MaterialBrowserBundleModel::updateImportedState(const QStringList &importedMats)
|
||||||
|
{
|
||||||
|
bool changed = false;
|
||||||
|
for (BundleMaterialCategory *cat : std::as_const(m_bundleCategories))
|
||||||
|
changed |= cat->updateImportedState(importedMats);
|
||||||
|
|
||||||
|
if (changed)
|
||||||
|
resetModel();
|
||||||
|
}
|
||||||
|
|
||||||
void MaterialBrowserBundleModel::resetModel()
|
void MaterialBrowserBundleModel::resetModel()
|
||||||
{
|
{
|
||||||
beginResetModel();
|
beginResetModel();
|
||||||
@@ -230,12 +254,30 @@ void MaterialBrowserBundleModel::applyToSelected(BundleMaterial *mat, bool add)
|
|||||||
emit applyToSelectedTriggered(mat, add);
|
emit applyToSelectedTriggered(mat, add);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MaterialBrowserBundleModel::addMaterial(BundleMaterial *mat)
|
void MaterialBrowserBundleModel::addToProject(BundleMaterial *mat)
|
||||||
{
|
{
|
||||||
QString err = m_importer->importComponent(mat->qml(), mat->files());
|
QString err = m_importer->importComponent(mat->qml(), mat->files());
|
||||||
|
|
||||||
if (!err.isEmpty())
|
if (err.isEmpty()) {
|
||||||
|
m_importerRunning = true;
|
||||||
|
emit importerRunningChanged();
|
||||||
|
} else {
|
||||||
qWarning() << __FUNCTION__ << err;
|
qWarning() << __FUNCTION__ << err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MaterialBrowserBundleModel::removeFromProject(BundleMaterial *mat)
|
||||||
|
{
|
||||||
|
emit bundleMaterialAboutToUnimport(mat->type());
|
||||||
|
|
||||||
|
QString err = m_importer->unimportComponent(mat->qml());
|
||||||
|
|
||||||
|
if (err.isEmpty()) {
|
||||||
|
m_importerRunning = true;
|
||||||
|
emit importerRunningChanged();
|
||||||
|
} else {
|
||||||
|
qWarning() << __FUNCTION__ << err;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace QmlDesigner
|
} // namespace QmlDesigner
|
||||||
|
@@ -50,6 +50,7 @@ class MaterialBrowserBundleModel : public QAbstractListModel
|
|||||||
Q_PROPERTY(bool isEmpty MEMBER m_isEmpty NOTIFY isEmptyChanged)
|
Q_PROPERTY(bool isEmpty MEMBER m_isEmpty NOTIFY isEmptyChanged)
|
||||||
Q_PROPERTY(bool hasQuick3DImport READ hasQuick3DImport WRITE setHasQuick3DImport NOTIFY hasQuick3DImportChanged)
|
Q_PROPERTY(bool hasQuick3DImport READ hasQuick3DImport WRITE setHasQuick3DImport NOTIFY hasQuick3DImportChanged)
|
||||||
Q_PROPERTY(bool hasMaterialRoot READ hasMaterialRoot WRITE setHasMaterialRoot NOTIFY hasMaterialRootChanged)
|
Q_PROPERTY(bool hasMaterialRoot READ hasMaterialRoot WRITE setHasMaterialRoot NOTIFY hasMaterialRootChanged)
|
||||||
|
Q_PROPERTY(bool importerRunning MEMBER m_importerRunning NOTIFY importerRunningChanged)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
MaterialBrowserBundleModel(QObject *parent = nullptr);
|
MaterialBrowserBundleModel(QObject *parent = nullptr);
|
||||||
@@ -59,6 +60,7 @@ 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 &importedMats);
|
||||||
|
|
||||||
bool hasQuick3DImport() const;
|
bool hasQuick3DImport() const;
|
||||||
void setHasQuick3DImport(bool b);
|
void setHasQuick3DImport(bool b);
|
||||||
@@ -66,10 +68,13 @@ public:
|
|||||||
bool hasMaterialRoot() const;
|
bool hasMaterialRoot() const;
|
||||||
void setHasMaterialRoot(bool b);
|
void setHasMaterialRoot(bool b);
|
||||||
|
|
||||||
|
Internal::BundleImporter *bundleImporter() const;
|
||||||
|
|
||||||
void resetModel();
|
void resetModel();
|
||||||
|
|
||||||
Q_INVOKABLE void applyToSelected(QmlDesigner::BundleMaterial *mat, bool add = false);
|
Q_INVOKABLE void applyToSelected(QmlDesigner::BundleMaterial *mat, bool add = false);
|
||||||
Q_INVOKABLE void addMaterial(QmlDesigner::BundleMaterial *mat);
|
Q_INVOKABLE void addToProject(QmlDesigner::BundleMaterial *mat);
|
||||||
|
Q_INVOKABLE void removeFromProject(QmlDesigner::BundleMaterial *mat);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void isEmptyChanged();
|
void isEmptyChanged();
|
||||||
@@ -77,7 +82,10 @@ signals:
|
|||||||
void hasMaterialRootChanged();
|
void hasMaterialRootChanged();
|
||||||
void materialVisibleChanged();
|
void materialVisibleChanged();
|
||||||
void applyToSelectedTriggered(QmlDesigner::BundleMaterial *mat, bool add = false);
|
void applyToSelectedTriggered(QmlDesigner::BundleMaterial *mat, bool add = false);
|
||||||
void addBundleMaterialToProjectRequested(const QmlDesigner::NodeMetaInfo &metaInfo);
|
void bundleMaterialImported(const QmlDesigner::NodeMetaInfo &metaInfo);
|
||||||
|
void bundleMaterialAboutToUnimport(const QmlDesigner::TypeName &type);
|
||||||
|
void bundleMaterialUnimported(const QmlDesigner::NodeMetaInfo &metaInfo);
|
||||||
|
void importerRunningChanged();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void loadMaterialBundle();
|
void loadMaterialBundle();
|
||||||
@@ -93,6 +101,7 @@ private:
|
|||||||
bool m_hasMaterialRoot = false;
|
bool m_hasMaterialRoot = false;
|
||||||
bool m_matBundleExists = false;
|
bool m_matBundleExists = false;
|
||||||
bool m_probeMatBundleDir = false;
|
bool m_probeMatBundleDir = false;
|
||||||
|
bool m_importerRunning = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace QmlDesigner
|
} // namespace QmlDesigner
|
||||||
|
@@ -27,6 +27,7 @@
|
|||||||
|
|
||||||
#include "bindingproperty.h"
|
#include "bindingproperty.h"
|
||||||
#include "bundlematerial.h"
|
#include "bundlematerial.h"
|
||||||
|
#include "bundleimporter.h"
|
||||||
#include "materialbrowserwidget.h"
|
#include "materialbrowserwidget.h"
|
||||||
#include "materialbrowsermodel.h"
|
#include "materialbrowsermodel.h"
|
||||||
#include "materialbrowserbundlemodel.h"
|
#include "materialbrowserbundlemodel.h"
|
||||||
@@ -178,13 +179,28 @@ WidgetInfo MaterialBrowserView::widgetInfo()
|
|||||||
if (defaultMat.isValid())
|
if (defaultMat.isValid())
|
||||||
applyBundleMaterialToDropTarget(defaultMat);
|
applyBundleMaterialToDropTarget(defaultMat);
|
||||||
else
|
else
|
||||||
m_widget->materialBrowserBundleModel()->addMaterial(bundleMat);
|
m_widget->materialBrowserBundleModel()->addToProject(bundleMat);
|
||||||
});
|
});
|
||||||
|
|
||||||
connect(matBrowserBundleModel, &MaterialBrowserBundleModel::addBundleMaterialToProjectRequested, this,
|
connect(matBrowserBundleModel, &MaterialBrowserBundleModel::bundleMaterialImported, this,
|
||||||
[&] (const QmlDesigner::NodeMetaInfo &metaInfo) {
|
[&] (const QmlDesigner::NodeMetaInfo &metaInfo) {
|
||||||
applyBundleMaterialToDropTarget({}, metaInfo);
|
applyBundleMaterialToDropTarget({}, metaInfo);
|
||||||
|
updateBundleMaterialsImportedState();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
connect(matBrowserBundleModel, &MaterialBrowserBundleModel::bundleMaterialAboutToUnimport, this,
|
||||||
|
[&] (const QmlDesigner::TypeName &type) {
|
||||||
|
// delete instances of the bundle material that is about to be unimported
|
||||||
|
executeInTransaction("MaterialBrowserView::widgetInfo", [&] {
|
||||||
|
Utils::reverseForeach(m_widget->materialBrowserModel()->materials(), [&](const ModelNode &mat) {
|
||||||
|
if (mat.isValid() && mat.type() == type)
|
||||||
|
QmlObjectNode(mat).destroy();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
connect(matBrowserBundleModel, &MaterialBrowserBundleModel::bundleMaterialUnimported, this,
|
||||||
|
&MaterialBrowserView::updateBundleMaterialsImportedState);
|
||||||
}
|
}
|
||||||
|
|
||||||
return createWidgetInfo(m_widget.data(),
|
return createWidgetInfo(m_widget.data(),
|
||||||
@@ -273,6 +289,7 @@ void MaterialBrowserView::modelAttached(Model *model)
|
|||||||
m_widget->materialBrowserModel()->setHasMaterialRoot(rootModelNode().isSubclassOf("QtQuick3D.Material"));
|
m_widget->materialBrowserModel()->setHasMaterialRoot(rootModelNode().isSubclassOf("QtQuick3D.Material"));
|
||||||
m_hasQuick3DImport = model->hasImport("QtQuick3D");
|
m_hasQuick3DImport = model->hasImport("QtQuick3D");
|
||||||
|
|
||||||
|
updateBundleMaterialsImportedState();
|
||||||
|
|
||||||
// Project load is already very busy and may even trigger puppet reset, so let's wait a moment
|
// Project load is already very busy and may even trigger puppet reset, so let's wait a moment
|
||||||
// before refreshing the model
|
// before refreshing the model
|
||||||
@@ -440,6 +457,22 @@ void QmlDesigner::MaterialBrowserView::loadPropertyGroups()
|
|||||||
m_propertyGroupsLoaded = m_widget->materialBrowserModel()->loadPropertyGroups(matPropsPath);
|
m_propertyGroupsLoaded = m_widget->materialBrowserModel()->loadPropertyGroups(matPropsPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MaterialBrowserView::updateBundleMaterialsImportedState()
|
||||||
|
{
|
||||||
|
using namespace Utils;
|
||||||
|
|
||||||
|
QStringList importedBundleMats;
|
||||||
|
|
||||||
|
FilePath materialBundlePath = m_widget->materialBrowserBundleModel()->bundleImporter()->resolveBundleImportPath();
|
||||||
|
|
||||||
|
if (materialBundlePath.exists()) {
|
||||||
|
importedBundleMats = transform(materialBundlePath.dirEntries({{"*.qml"}, QDir::Files}),
|
||||||
|
[](const FilePath &f) { return f.fileName().chopped(4); });
|
||||||
|
}
|
||||||
|
|
||||||
|
m_widget->materialBrowserBundleModel()->updateImportedState(importedBundleMats);
|
||||||
|
}
|
||||||
|
|
||||||
ModelNode MaterialBrowserView::getBundleMaterialDefaultInstance(const TypeName &type)
|
ModelNode MaterialBrowserView::getBundleMaterialDefaultInstance(const TypeName &type)
|
||||||
{
|
{
|
||||||
const QList<ModelNode> materials = m_widget->materialBrowserModel()->materials();
|
const QList<ModelNode> materials = m_widget->materialBrowserModel()->materials();
|
||||||
@@ -505,7 +538,7 @@ void MaterialBrowserView::customNotification(const AbstractView *view, const QSt
|
|||||||
if (defaultMat.isValid())
|
if (defaultMat.isValid())
|
||||||
applyBundleMaterialToDropTarget(defaultMat);
|
applyBundleMaterialToDropTarget(defaultMat);
|
||||||
else
|
else
|
||||||
m_widget->materialBrowserBundleModel()->addMaterial(m_draggedBundleMaterial);
|
m_widget->materialBrowserBundleModel()->addToProject(m_draggedBundleMaterial);
|
||||||
|
|
||||||
m_draggedBundleMaterial = nullptr;
|
m_draggedBundleMaterial = nullptr;
|
||||||
}
|
}
|
||||||
|
@@ -68,6 +68,7 @@ private:
|
|||||||
void refreshModel(bool updateImages);
|
void refreshModel(bool updateImages);
|
||||||
bool isMaterial(const ModelNode &node) const;
|
bool isMaterial(const ModelNode &node) const;
|
||||||
void loadPropertyGroups();
|
void loadPropertyGroups();
|
||||||
|
void updateBundleMaterialsImportedState();
|
||||||
void applyBundleMaterialToDropTarget(const ModelNode &bundleMat, const NodeMetaInfo &metaInfo = {});
|
void applyBundleMaterialToDropTarget(const ModelNode &bundleMat, const NodeMetaInfo &metaInfo = {});
|
||||||
ModelNode getBundleMaterialDefaultInstance(const TypeName &type);
|
ModelNode getBundleMaterialDefaultInstance(const TypeName &type);
|
||||||
|
|
||||||
@@ -75,6 +76,7 @@ private:
|
|||||||
QList<ModelNode> m_bundleMaterialTargets;
|
QList<ModelNode> m_bundleMaterialTargets;
|
||||||
QList<ModelNode> m_selectedModels; // selected 3D model nodes
|
QList<ModelNode> m_selectedModels; // selected 3D model nodes
|
||||||
BundleMaterial *m_draggedBundleMaterial = nullptr;
|
BundleMaterial *m_draggedBundleMaterial = nullptr;
|
||||||
|
|
||||||
bool m_bundleMaterialAddToSelected = false;
|
bool m_bundleMaterialAddToSelected = false;
|
||||||
bool m_hasQuick3DImport = false;
|
bool m_hasQuick3DImport = false;
|
||||||
bool m_autoSelectModelMaterial = false; // TODO: wire this to some action
|
bool m_autoSelectModelMaterial = false; // TODO: wire this to some action
|
||||||
|
Reference in New Issue
Block a user