forked from qt-creator/qt-creator
EffectMaker: Block adding same effect node twice
The actual blocking is done at uniform level, as the problem of having same effect node twice is duplicate uniforms. Fixes: QDS-11470 Change-Id: I77b15b4a207efaebff39b4f6b1700d70262abcdb Reviewed-by: Mahmoud Badri <mahmoud.badri@qt.io> Reviewed-by: Qt CI Patch Build Bot <ci_patchbuild_bot@qt.io>
This commit is contained in:
@@ -15,20 +15,22 @@ Rectangle {
|
|||||||
width: 140
|
width: 140
|
||||||
height: 32
|
height: 32
|
||||||
|
|
||||||
color: mouseArea.containsMouse ? StudioTheme.Values.themeControlBackgroundInteraction
|
color: mouseArea.containsMouse && modelData.canBeAdded
|
||||||
: "transparent"
|
? StudioTheme.Values.themeControlBackgroundInteraction : "transparent"
|
||||||
|
|
||||||
signal addEffectNode(var nodeQenPath)
|
signal addEffectNode(var nodeQenPath)
|
||||||
|
|
||||||
MouseArea {
|
ToolTipArea {
|
||||||
id: mouseArea
|
id: mouseArea
|
||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
hoverEnabled: true
|
|
||||||
acceptedButtons: Qt.LeftButton
|
acceptedButtons: Qt.LeftButton
|
||||||
|
|
||||||
|
tooltip: modelData.canBeAdded ? "" : qsTr("Existing effect has conflicting properties, this effect cannot be added.")
|
||||||
|
|
||||||
onClicked: {
|
onClicked: {
|
||||||
root.addEffectNode(modelData.nodeQenPath)
|
if (modelData.canBeAdded)
|
||||||
|
root.addEffectNode(modelData.nodeQenPath)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -41,13 +43,15 @@ Rectangle {
|
|||||||
width: 32
|
width: 32
|
||||||
height: 32
|
height: 32
|
||||||
|
|
||||||
color: StudioTheme.Values.themeTextColor
|
color: modelData.canBeAdded ? StudioTheme.Values.themeTextColor
|
||||||
|
: StudioTheme.Values.themeTextColorDisabled
|
||||||
source: modelData.nodeIcon
|
source: modelData.nodeIcon
|
||||||
}
|
}
|
||||||
|
|
||||||
Text {
|
Text {
|
||||||
text: modelData.nodeName
|
text: modelData.nodeName
|
||||||
color: StudioTheme.Values.themeTextColor
|
color: modelData.canBeAdded ? StudioTheme.Values.themeTextColor
|
||||||
|
: StudioTheme.Values.themeTextColorDisabled
|
||||||
font.pointSize: StudioTheme.Values.smallFontSize
|
font.pointSize: StudioTheme.Values.smallFontSize
|
||||||
anchors.verticalCenter: nodeIcon.verticalCenter
|
anchors.verticalCenter: nodeIcon.verticalCenter
|
||||||
}
|
}
|
||||||
|
@@ -112,6 +112,8 @@ void EffectMakerModel::addNode(const QString &nodeQenPath)
|
|||||||
setIsEmpty(false);
|
setIsEmpty(false);
|
||||||
|
|
||||||
bakeShaders();
|
bakeShaders();
|
||||||
|
|
||||||
|
emit nodesChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
void EffectMakerModel::moveNode(int fromIdx, int toIdx)
|
void EffectMakerModel::moveNode(int fromIdx, int toIdx)
|
||||||
@@ -138,6 +140,8 @@ void EffectMakerModel::removeNode(int idx)
|
|||||||
setIsEmpty(true);
|
setIsEmpty(true);
|
||||||
else
|
else
|
||||||
bakeShaders();
|
bakeShaders();
|
||||||
|
|
||||||
|
emit nodesChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
void EffectMakerModel::clear()
|
void EffectMakerModel::clear()
|
||||||
@@ -148,6 +152,7 @@ void EffectMakerModel::clear()
|
|||||||
endResetModel();
|
endResetModel();
|
||||||
|
|
||||||
setIsEmpty(true);
|
setIsEmpty(true);
|
||||||
|
emit nodesChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
QString EffectMakerModel::fragmentShader() const
|
QString EffectMakerModel::fragmentShader() const
|
||||||
@@ -181,7 +186,7 @@ const QString &EffectMakerModel::qmlComponentString() const
|
|||||||
return m_qmlComponentString;
|
return m_qmlComponentString;
|
||||||
}
|
}
|
||||||
|
|
||||||
const QList<Uniform *> EffectMakerModel::allUniforms()
|
const QList<Uniform *> EffectMakerModel::allUniforms() const
|
||||||
{
|
{
|
||||||
QList<Uniform *> uniforms = {};
|
QList<Uniform *> uniforms = {};
|
||||||
for (const auto &node : std::as_const(m_nodes))
|
for (const auto &node : std::as_const(m_nodes))
|
||||||
@@ -604,10 +609,6 @@ void EffectMakerModel::openComposition(const QString &path)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get effects dir
|
|
||||||
const Utils::FilePath effectsResDir = QmlDesigner::ModelNodeOperations::getEffectsImportDirectory();
|
|
||||||
const QString effectsResPath = effectsResDir.pathAppended(effectName).toString();
|
|
||||||
|
|
||||||
if (json.contains("nodes") && json["nodes"].isArray()) {
|
if (json.contains("nodes") && json["nodes"].isArray()) {
|
||||||
const QJsonArray nodesArray = json["nodes"].toArray();
|
const QJsonArray nodesArray = json["nodes"].toArray();
|
||||||
for (const auto &nodeElement : nodesArray) {
|
for (const auto &nodeElement : nodesArray) {
|
||||||
@@ -620,6 +621,8 @@ void EffectMakerModel::openComposition(const QString &path)
|
|||||||
setIsEmpty(m_nodes.isEmpty());
|
setIsEmpty(m_nodes.isEmpty());
|
||||||
bakeShaders();
|
bakeShaders();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
emit nodesChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
void EffectMakerModel::exportResources(const QString &name)
|
void EffectMakerModel::exportResources(const QString &name)
|
||||||
@@ -1438,6 +1441,15 @@ void EffectMakerModel::setCurrentComposition(const QString &newCurrentCompositio
|
|||||||
emit currentCompositionChanged();
|
emit currentCompositionChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QStringList EffectMakerModel::uniformNames() const
|
||||||
|
{
|
||||||
|
QStringList usedList;
|
||||||
|
const QList<Uniform *> uniforms = allUniforms();
|
||||||
|
for (const auto uniform : uniforms)
|
||||||
|
usedList.append(uniform->name());
|
||||||
|
return usedList;
|
||||||
|
}
|
||||||
|
|
||||||
void EffectMakerModel::updateQmlComponent()
|
void EffectMakerModel::updateQmlComponent()
|
||||||
{
|
{
|
||||||
// Clear possible QML runtime errors
|
// Clear possible QML runtime errors
|
||||||
|
@@ -89,6 +89,8 @@ public:
|
|||||||
QString currentComposition() const;
|
QString currentComposition() const;
|
||||||
void setCurrentComposition(const QString &newCurrentComposition);
|
void setCurrentComposition(const QString &newCurrentComposition);
|
||||||
|
|
||||||
|
QStringList uniformNames() const;
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void isEmptyChanged();
|
void isEmptyChanged();
|
||||||
void selectedIndexChanged(int idx);
|
void selectedIndexChanged(int idx);
|
||||||
@@ -97,6 +99,7 @@ signals:
|
|||||||
void shadersBaked();
|
void shadersBaked();
|
||||||
|
|
||||||
void currentCompositionChanged();
|
void currentCompositionChanged();
|
||||||
|
void nodesChanged();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
enum Roles {
|
enum Roles {
|
||||||
@@ -116,7 +119,7 @@ private:
|
|||||||
|
|
||||||
bool isValidIndex(int idx) const;
|
bool isValidIndex(int idx) const;
|
||||||
|
|
||||||
const QList<Uniform *> allUniforms();
|
const QList<Uniform *> allUniforms() const;
|
||||||
|
|
||||||
const QString getBufUniform();
|
const QString getBufUniform();
|
||||||
const QString getVSUniforms();
|
const QString getVSUniforms();
|
||||||
|
@@ -52,6 +52,9 @@ QString EffectMakerNodesModel::nodesSourcesPath() const
|
|||||||
|
|
||||||
void EffectMakerNodesModel::loadModel()
|
void EffectMakerNodesModel::loadModel()
|
||||||
{
|
{
|
||||||
|
if (m_modelLoaded)
|
||||||
|
return;
|
||||||
|
|
||||||
auto nodesPath = Utils::FilePath::fromString(nodesSourcesPath());
|
auto nodesPath = Utils::FilePath::fromString(nodesSourcesPath());
|
||||||
|
|
||||||
if (!nodesPath.exists()) {
|
if (!nodesPath.exists()) {
|
||||||
@@ -88,6 +91,8 @@ void EffectMakerNodesModel::loadModel()
|
|||||||
return a->name() < b->name();
|
return a->name() < b->name();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
m_modelLoaded = true;
|
||||||
|
|
||||||
resetModel();
|
resetModel();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -97,4 +102,20 @@ void EffectMakerNodesModel::resetModel()
|
|||||||
endResetModel();
|
endResetModel();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EffectMakerNodesModel::updateCanBeAdded(const QStringList &uniforms)
|
||||||
|
{
|
||||||
|
for (const EffectNodesCategory *cat : std::as_const(m_categories)) {
|
||||||
|
const QList<EffectNode *> nodes = cat->nodes();
|
||||||
|
for (EffectNode *node : nodes) {
|
||||||
|
bool match = false;
|
||||||
|
for (const QString &uniform : uniforms) {
|
||||||
|
match = node->hasUniform(uniform);
|
||||||
|
if (match)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
node->setCanBeAdded(!match);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace EffectMaker
|
} // namespace EffectMaker
|
||||||
|
@@ -30,11 +30,14 @@ public:
|
|||||||
|
|
||||||
QList<EffectNodesCategory *> categories() const { return m_categories; }
|
QList<EffectNodesCategory *> categories() const { return m_categories; }
|
||||||
|
|
||||||
|
void updateCanBeAdded(const QStringList &uniforms);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QString nodesSourcesPath() const;
|
QString nodesSourcesPath() const;
|
||||||
|
|
||||||
QList<EffectNodesCategory *> m_categories;
|
QList<EffectNodesCategory *> m_categories;
|
||||||
bool m_probeNodesDir = false;
|
bool m_probeNodesDir = false;
|
||||||
|
bool m_modelLoaded = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace EffectMaker
|
} // namespace EffectMaker
|
||||||
|
@@ -76,6 +76,10 @@ EffectMakerWidget::EffectMakerWidget(EffectMakerView *view)
|
|||||||
{"rootView", QVariant::fromValue(this)}});
|
{"rootView", QVariant::fromValue(this)}});
|
||||||
QmlDesigner::QmlDesignerPlugin::trackWidgetFocusTime(
|
QmlDesigner::QmlDesignerPlugin::trackWidgetFocusTime(
|
||||||
this, QmlDesigner::Constants::EVENT_NEWEFFECTMAKER_TIME);
|
this, QmlDesigner::Constants::EVENT_NEWEFFECTMAKER_TIME);
|
||||||
|
|
||||||
|
connect(m_effectMakerModel.data(), &EffectMakerModel::nodesChanged, [this]() {
|
||||||
|
m_effectMakerNodesModel->updateCanBeAdded(m_effectMakerModel->uniformNames());
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -2,6 +2,8 @@
|
|||||||
// 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
|
||||||
|
|
||||||
#include "effectnode.h"
|
#include "effectnode.h"
|
||||||
|
#include "compositionnode.h"
|
||||||
|
#include "uniform.h"
|
||||||
|
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
#include <QFileInfo>
|
#include <QFileInfo>
|
||||||
@@ -22,6 +24,12 @@ EffectNode::EffectNode(const QString &qenPath)
|
|||||||
iconPath = QStringLiteral("%1/%2").arg(parentDir.path(), "placeholder.svg");
|
iconPath = QStringLiteral("%1/%2").arg(parentDir.path(), "placeholder.svg");
|
||||||
}
|
}
|
||||||
m_iconPath = QUrl::fromLocalFile(iconPath);
|
m_iconPath = QUrl::fromLocalFile(iconPath);
|
||||||
|
|
||||||
|
CompositionNode node({}, qenPath);
|
||||||
|
const QList<Uniform *> uniforms = node.uniforms();
|
||||||
|
|
||||||
|
for (const Uniform *uniform : uniforms)
|
||||||
|
m_uniformNames.insert(uniform->name());
|
||||||
}
|
}
|
||||||
|
|
||||||
QString EffectNode::name() const
|
QString EffectNode::name() const
|
||||||
@@ -39,5 +47,18 @@ QString EffectNode::qenPath() const
|
|||||||
return m_qenPath;
|
return m_qenPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EffectNode::setCanBeAdded(bool enabled)
|
||||||
|
{
|
||||||
|
if (enabled != m_canBeAdded) {
|
||||||
|
m_canBeAdded = enabled;
|
||||||
|
emit canBeAddedChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool EffectNode::hasUniform(const QString &name)
|
||||||
|
{
|
||||||
|
return m_uniformNames.contains(name);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace EffectMaker
|
} // namespace EffectMaker
|
||||||
|
|
||||||
|
@@ -4,6 +4,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
|
#include <QSet>
|
||||||
#include <QUrl>
|
#include <QUrl>
|
||||||
|
|
||||||
namespace EffectMaker {
|
namespace EffectMaker {
|
||||||
@@ -16,6 +17,7 @@ class EffectNode : public QObject
|
|||||||
Q_PROPERTY(QString nodeDescription MEMBER m_description CONSTANT)
|
Q_PROPERTY(QString nodeDescription MEMBER m_description CONSTANT)
|
||||||
Q_PROPERTY(QUrl nodeIcon MEMBER m_iconPath CONSTANT)
|
Q_PROPERTY(QUrl nodeIcon MEMBER m_iconPath CONSTANT)
|
||||||
Q_PROPERTY(QString nodeQenPath MEMBER m_qenPath CONSTANT)
|
Q_PROPERTY(QString nodeQenPath MEMBER m_qenPath CONSTANT)
|
||||||
|
Q_PROPERTY(bool canBeAdded MEMBER m_canBeAdded NOTIFY canBeAddedChanged)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
EffectNode(const QString &qenPath);
|
EffectNode(const QString &qenPath);
|
||||||
@@ -24,11 +26,20 @@ public:
|
|||||||
QString description() const;
|
QString description() const;
|
||||||
QString qenPath() const;
|
QString qenPath() const;
|
||||||
|
|
||||||
|
void setCanBeAdded(bool enabled);
|
||||||
|
|
||||||
|
bool hasUniform(const QString &name);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void canBeAddedChanged();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QString m_name;
|
QString m_name;
|
||||||
QString m_description;
|
QString m_description;
|
||||||
QString m_qenPath;
|
QString m_qenPath;
|
||||||
QUrl m_iconPath;
|
QUrl m_iconPath;
|
||||||
|
bool m_canBeAdded = true;
|
||||||
|
QSet<QString> m_uniformNames;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace EffectMaker
|
} // namespace EffectMaker
|
||||||
|
Reference in New Issue
Block a user