aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMiikka Heikkinen <miikka.heikkinen@qt.io>2024-02-02 13:08:01 +0200
committerMiikka Heikkinen <miikka.heikkinen@qt.io>2024-02-02 12:15:18 +0000
commitf985b1b09108efb5606771a447c1b5bcf7c9464a (patch)
tree1575d5477b812cc882e766b150218bdc59e3076d
parent7efab2c07ee544237ceb90fddc1a3c7dfd004bbb (diff)
EffectComposer: Allow 'define' properties to specify control type
Control type is used to determine the control presented for the property in UI. Currently only int and bool control types are supported. Also fixed the issue that changing define wouldn't update preview. This was because changing define requires rebaking shaders, which is not normally triggered on property change. Fixes: QDS-11770 Change-Id: I953d827195565f765df1a09550c4a49da9c93c29 Reviewed-by: Mahmoud Badri <mahmoud.badri@qt.io>
-rw-r--r--share/qtcreator/qmldesigner/effectComposerQmlSources/EffectCompositionNodeUniform.qml26
-rw-r--r--src/plugins/effectcomposer/compositionnode.cpp4
-rw-r--r--src/plugins/effectcomposer/compositionnode.h1
-rw-r--r--src/plugins/effectcomposer/effectcomposermodel.cpp72
-rw-r--r--src/plugins/effectcomposer/effectcomposermodel.h4
-rw-r--r--src/plugins/effectcomposer/effectcomposeruniformsmodel.cpp1
-rw-r--r--src/plugins/effectcomposer/effectcomposeruniformsmodel.h1
-rw-r--r--src/plugins/effectcomposer/uniform.cpp29
-rw-r--r--src/plugins/effectcomposer/uniform.h4
9 files changed, 108 insertions, 34 deletions
diff --git a/share/qtcreator/qmldesigner/effectComposerQmlSources/EffectCompositionNodeUniform.qml b/share/qtcreator/qmldesigner/effectComposerQmlSources/EffectCompositionNodeUniform.qml
index 8dc3b75c9b..bfe0d3e3b7 100644
--- a/share/qtcreator/qmldesigner/effectComposerQmlSources/EffectCompositionNodeUniform.qml
+++ b/share/qtcreator/qmldesigner/effectComposerQmlSources/EffectCompositionNodeUniform.qml
@@ -17,24 +17,30 @@ Item {
visible: !uniformUseCustomValue
Component.onCompleted: {
- if (uniformType === "int")
+ if (uniformType === "int") {
valueLoader.source = "ValueInt.qml"
- else if (uniformType === "vec2")
+ } else if (uniformType === "vec2") {
valueLoader.source = "ValueVec2.qml"
- else if (uniformType === "vec3")
+ } else if (uniformType === "vec3") {
valueLoader.source = "ValueVec3.qml"
- else if (uniformType === "vec4")
+ } else if (uniformType === "vec4") {
valueLoader.source = "ValueVec4.qml"
- else if (uniformType === "bool")
+ } else if (uniformType === "bool") {
valueLoader.source = "ValueBool.qml"
- else if (uniformType === "color")
+ } else if (uniformType === "color") {
valueLoader.source = "ValueColor.qml"
- else if (uniformType === "sampler2D")
+ } else if (uniformType === "sampler2D") {
valueLoader.source = "ValueImage.qml"
- else if (uniformType === "define")
- valueLoader.source = "ValueDefine.qml"
- else
+ } else if (uniformType === "define") {
+ if (uniformControlType === "int")
+ valueLoader.source = "ValueInt.qml"
+ else if (uniformControlType === "bool")
+ valueLoader.source = "ValueBool.qml"
+ else
+ valueLoader.source = "ValueDefine.qml"
+ } else {
valueLoader.source = "ValueFloat.qml"
+ }
}
RowLayout {
diff --git a/src/plugins/effectcomposer/compositionnode.cpp b/src/plugins/effectcomposer/compositionnode.cpp
index b63258e0af..108eb5801d 100644
--- a/src/plugins/effectcomposer/compositionnode.cpp
+++ b/src/plugins/effectcomposer/compositionnode.cpp
@@ -130,6 +130,10 @@ void CompositionNode::parse(const QString &effectName, const QString &qenPath, c
m_unifomrsModel.addUniform(uniform);
m_uniforms.append(uniform);
g_propertyData.insert(uniform->name(), uniform->value());
+ if (uniform->type() == Uniform::Type::Define) {
+ // Changing defines requires rebaking the shaders
+ connect(uniform, &Uniform::uniformValueChanged, this, &CompositionNode::rebakeRequested);
+ }
}
// Seek through code to get tags
diff --git a/src/plugins/effectcomposer/compositionnode.h b/src/plugins/effectcomposer/compositionnode.h
index 589954ec87..b3348bb38f 100644
--- a/src/plugins/effectcomposer/compositionnode.h
+++ b/src/plugins/effectcomposer/compositionnode.h
@@ -56,6 +56,7 @@ signals:
void uniformsModelChanged();
void isEnabledChanged();
void isDepencyChanged();
+ void rebakeRequested();
private:
void parse(const QString &effectName, const QString &qenPath, const QJsonObject &json);
diff --git a/src/plugins/effectcomposer/effectcomposermodel.cpp b/src/plugins/effectcomposer/effectcomposermodel.cpp
index ffa63a0353..9a3b8ca0af 100644
--- a/src/plugins/effectcomposer/effectcomposermodel.cpp
+++ b/src/plugins/effectcomposer/effectcomposermodel.cpp
@@ -49,6 +49,8 @@ static bool writeToFile(const QByteArray &buf, const QString &filename, FileType
EffectComposerModel::EffectComposerModel(QObject *parent)
: QAbstractListModel{parent}
{
+ m_rebakeTimer.setSingleShot(true);
+ connect(&m_rebakeTimer, &QTimer::timeout, this, &EffectComposerModel::bakeShaders);
}
QHash<int, QByteArray> EffectComposerModel::roleNames() const
@@ -107,10 +109,7 @@ void EffectComposerModel::addNode(const QString &nodeQenPath)
{
beginResetModel();
auto *node = new CompositionNode({}, nodeQenPath);
- connect(qobject_cast<EffectComposerUniformsModel *>(node->uniformsModel()),
- &EffectComposerUniformsModel::dataChanged, this, [this] {
- setHasUnsavedChanges(true);
- });
+ connectCompositionNode(node);
const QList<QString> requiredNodes = node->requiredNodes();
if (requiredNodes.size() > 0) {
@@ -122,10 +121,7 @@ void EffectComposerModel::addNode(const QString &nodeQenPath)
const QString path = EffectUtils::nodesSourcesPath() + "/common/" + requiredId + ".qen";
auto requiredNode = new CompositionNode({}, path);
- connect(qobject_cast<EffectComposerUniformsModel *>(requiredNode->uniformsModel()),
- &EffectComposerUniformsModel::dataChanged, this, [this] {
- setHasUnsavedChanges(true);
- });
+ connectCompositionNode(requiredNode);
requiredNode->setRefCount(1);
m_nodes.prepend(requiredNode);
}
@@ -167,6 +163,7 @@ void EffectComposerModel::moveNode(int fromIdx, int toIdx)
void EffectComposerModel::removeNode(int idx)
{
beginResetModel();
+ m_rebakeTimer.stop();
CompositionNode *node = m_nodes.takeAt(idx);
const QStringList reqNodes = node->requiredNodes();
@@ -193,6 +190,7 @@ void EffectComposerModel::removeNode(int idx)
void EffectComposerModel::clear(bool clearName)
{
beginResetModel();
+ m_rebakeTimer.stop();
qDeleteAll(m_nodes);
m_nodes.clear();
endResetModel();
@@ -418,7 +416,7 @@ void EffectComposerModel::setEffectError(const QString &errorMessage, int type,
Q_EMIT effectErrorChanged();
}
-QString variantAsDataString(const Uniform::Type type, const QVariant &variant)
+QString variantAsDataString(const Uniform::Type type, const Uniform::Type controlType, const QVariant &variant)
{
QString s;
switch (type) {
@@ -470,7 +468,12 @@ QString variantAsDataString(const Uniform::Type type, const QVariant &variant)
}
case Uniform::Type::Sampler:
case Uniform::Type::Define: {
- s = variant.toString();
+ if (controlType == Uniform::Type::Int)
+ s = QString::number(variant.toInt());
+ else if (controlType == Uniform::Type::Bool)
+ s = variant.toBool() ? QString("true") : QString("false");
+ else
+ s = variant.toString();
break;
}
}
@@ -495,16 +498,23 @@ QJsonObject nodeToJson(const CompositionNode &node)
uniformObject.insert("name", QString(uniform->name()));
QString type = Uniform::stringFromType(uniform->type());
uniformObject.insert("type", type);
+ if (uniform->type() == Uniform::Type::Define) {
+ QString controlType = Uniform::stringFromType(uniform->controlType());
+ if (controlType != type)
+ uniformObject.insert("controlType", controlType);
+ }
if (!uniform->displayName().isEmpty())
uniformObject.insert("displayName", QString(uniform->displayName()));
- QString value = variantAsDataString(uniform->type(), uniform->value());
+ QString value = variantAsDataString(uniform->type(), uniform->controlType(),
+ uniform->value());
if (uniform->type() == Uniform::Type::Sampler)
value = QFileInfo(value).fileName();
uniformObject.insert("value", value);
- QString defaultValue = variantAsDataString(uniform->type(), uniform->defaultValue());
+ QString defaultValue = variantAsDataString(uniform->type(), uniform->controlType(),
+ uniform->defaultValue());
if (uniform->type() == Uniform::Type::Sampler) {
defaultValue = QFileInfo(value).fileName();
if (uniform->enableMipmap())
@@ -517,9 +527,14 @@ QJsonObject nodeToJson(const CompositionNode &node)
|| uniform->type() == Uniform::Type::Int
|| uniform->type() == Uniform::Type::Vec2
|| uniform->type() == Uniform::Type::Vec3
- || uniform->type() == Uniform::Type::Vec4) {
- uniformObject.insert("minValue", variantAsDataString(uniform->type(), uniform->minValue()));
- uniformObject.insert("maxValue", variantAsDataString(uniform->type(), uniform->maxValue()));
+ || uniform->type() == Uniform::Type::Vec4
+ || uniform->controlType() == Uniform::Type::Int) {
+ uniformObject.insert("minValue", variantAsDataString(uniform->type(),
+ uniform->controlType(),
+ uniform->minValue()));
+ uniformObject.insert("maxValue", variantAsDataString(uniform->type(),
+ uniform->controlType(),
+ uniform->maxValue()));
}
if (!uniform->customValue().isEmpty())
uniformObject.insert("customValue", uniform->customValue());
@@ -754,10 +769,7 @@ void EffectComposerModel::openComposition(const QString &path)
for (const auto &nodeElement : nodesArray) {
auto *node = new CompositionNode(effectName, {}, nodeElement.toObject());
- connect(qobject_cast<EffectComposerUniformsModel *>(node->uniformsModel()),
- &EffectComposerUniformsModel::dataChanged, this, [this] {
- setHasUnsavedChanges(true);
- });
+ connectCompositionNode(node);
m_nodes.append(node);
const QStringList reqIds = node->requiredNodes();
for (const QString &reqId : reqIds)
@@ -922,6 +934,10 @@ QString EffectComposerModel::valueAsString(const Uniform &uniform)
} else if (uniform.type() == Uniform::Type::Color) {
return QString("\"%1\"").arg(uniform.value().toString());
} else if (uniform.type() == Uniform::Type::Define) {
+ if (uniform.controlType() == Uniform::Type::Int)
+ return QString::number(uniform.value().toInt());
+ else if (uniform.controlType() == Uniform::Type::Bool)
+ return uniform.value().toBool() ? QString("1") : QString("0");
return uniform.value().toString();
} else {
qWarning() << QString("Unhandled const variable type: %1").arg(int(uniform.type())).toLatin1();
@@ -1020,10 +1036,8 @@ const QString EffectComposerModel::getDefineProperties()
QString s;
for (Uniform *uniform : uniforms) {
// TODO: Check if uniform is already added.
- if (uniform->type() == Uniform::Type::Define) {
- QString defineValue = uniform->value().toString();
- s += QString("#define %1 %2\n").arg(uniform->name(), defineValue);
- }
+ if (uniform->type() == Uniform::Type::Define)
+ s += QString("#define %1 %2\n").arg(uniform->name(), valueAsString(*uniform));
}
if (!s.isEmpty())
s += '\n';
@@ -1620,6 +1634,18 @@ QString EffectComposerModel::getQmlComponentString(bool localFiles)
return s;
}
+void EffectComposerModel::connectCompositionNode(CompositionNode *node)
+{
+ connect(qobject_cast<EffectComposerUniformsModel *>(node->uniformsModel()),
+ &EffectComposerUniformsModel::dataChanged, this, [this] {
+ setHasUnsavedChanges(true);
+ });
+ connect(node, &CompositionNode::rebakeRequested, this, [this] {
+ // This can come multiple times in a row in response to property changes, so let's buffer it
+ m_rebakeTimer.start(200);
+ });
+}
+
QString EffectComposerModel::currentComposition() const
{
return m_currentComposition;
diff --git a/src/plugins/effectcomposer/effectcomposermodel.h b/src/plugins/effectcomposer/effectcomposermodel.h
index e8c7a5c61d..c0eb76f0b9 100644
--- a/src/plugins/effectcomposer/effectcomposermodel.h
+++ b/src/plugins/effectcomposer/effectcomposermodel.h
@@ -12,6 +12,7 @@
#include <QMap>
#include <QRegularExpression>
#include <QTemporaryFile>
+#include <QTimer>
namespace ProjectExplorer {
class Target;
@@ -172,6 +173,8 @@ private:
QString getQmlImagesString(bool localFiles);
QString getQmlComponentString(bool localFiles);
+ void connectCompositionNode(CompositionNode *node);
+
QList<CompositionNode *> m_nodes;
int m_selectedIndex = -1;
@@ -206,6 +209,7 @@ private:
bool m_loadComponentImages = true;
bool m_isEnabled = true;
QString m_currentComposition;
+ QTimer m_rebakeTimer;
const QRegularExpression m_spaceReg = QRegularExpression("\\s+");
};
diff --git a/src/plugins/effectcomposer/effectcomposeruniformsmodel.cpp b/src/plugins/effectcomposer/effectcomposeruniformsmodel.cpp
index e547883b9d..9d8c1a31a7 100644
--- a/src/plugins/effectcomposer/effectcomposeruniformsmodel.cpp
+++ b/src/plugins/effectcomposer/effectcomposeruniformsmodel.cpp
@@ -26,6 +26,7 @@ QHash<int, QByteArray> EffectComposerUniformsModel::roleNames() const
roles[MinValueRole] = "uniformMinValue";
roles[MaxValueRole] = "uniformMaxValue";
roles[TypeRole] = "uniformType";
+ roles[ControlTypeRole] = "uniformControlType";
roles[UseCustomValueRole] = "uniformUseCustomValue";
return roles;
}
diff --git a/src/plugins/effectcomposer/effectcomposeruniformsmodel.h b/src/plugins/effectcomposer/effectcomposeruniformsmodel.h
index 3e2d44c626..f60c016ed0 100644
--- a/src/plugins/effectcomposer/effectcomposeruniformsmodel.h
+++ b/src/plugins/effectcomposer/effectcomposeruniformsmodel.h
@@ -37,6 +37,7 @@ private:
MaxValueRole,
MinValueRole,
TypeRole,
+ ControlTypeRole,
UseCustomValueRole
};
diff --git a/src/plugins/effectcomposer/uniform.cpp b/src/plugins/effectcomposer/uniform.cpp
index e8fd77d631..4c8b994388 100644
--- a/src/plugins/effectcomposer/uniform.cpp
+++ b/src/plugins/effectcomposer/uniform.cpp
@@ -22,6 +22,7 @@ Uniform::Uniform(const QString &effectName, const QJsonObject &propObj, const QS
m_name = propObj.value("name").toString();
m_description = propObj.value("description").toString();
m_type = Uniform::typeFromString(propObj.value("type").toString());
+ m_controlType = m_type;
defaultValue = propObj.value("defaultValue").toString();
m_displayName = propObj.value("displayName").toString();
@@ -44,6 +45,12 @@ Uniform::Uniform(const QString &effectName, const QJsonObject &propObj, const QS
g_propertyData[mipmapProperty] = m_enableMipmap;
}
+ if (m_type == Type::Define) {
+ QString controlType = propObj.value("controlType").toString();
+ if (!controlType.isEmpty())
+ m_controlType = Uniform::typeFromString(controlType);
+ }
+
m_customValue = propObj.value("customValue").toString();
m_useCustomValue = getBoolValue(propObj.value("useCustomValue"), false);
@@ -61,12 +68,22 @@ Uniform::Type Uniform::type() const
return m_type;
}
+Uniform::Type Uniform::controlType() const
+{
+ return m_controlType;
+}
+
// String representation of the type for qml
QString Uniform::typeName() const
{
return Uniform::stringFromType(m_type);
}
+QString Uniform::controlTypeName() const
+{
+ return Uniform::stringFromType(m_controlType);
+}
+
QVariant Uniform::value() const
{
return m_value;
@@ -216,6 +233,13 @@ QVariant Uniform::getInitializedVariant(bool maxValue)
return maxValue ? QVector4D(1.0, 1.0, 1.0, 1.0) : QVector4D(0.0, 0.0, 0.0, 0.0);
case Uniform::Type::Color:
return maxValue ? QColor::fromRgbF(1.0f, 1.0f, 1.0f, 1.0f) : QColor::fromRgbF(0.0f, 0.0f, 0.0f, 0.0f);
+ case Uniform::Type::Define:
+ if (m_controlType == Uniform::Type::Bool)
+ return maxValue ? true : false;
+ else if (m_controlType == Uniform::Type::Int)
+ return maxValue ? 100 : 0;
+ else
+ return QVariant();
default:
return QVariant();
}
@@ -262,7 +286,10 @@ QVariant Uniform::valueStringToVariant(const QString &value)
variant = value;
break;
case Uniform::Type::Define:
- variant = value;
+ if (m_controlType == Uniform::Type::Bool)
+ variant = (value == "true");
+ else
+ variant = value;
break;
}
diff --git a/src/plugins/effectcomposer/uniform.h b/src/plugins/effectcomposer/uniform.h
index 83f15224ae..09081248c5 100644
--- a/src/plugins/effectcomposer/uniform.h
+++ b/src/plugins/effectcomposer/uniform.h
@@ -20,6 +20,7 @@ class Uniform : public QObject
Q_PROPERTY(QString uniformName MEMBER m_displayName CONSTANT)
Q_PROPERTY(QString uniformType READ typeName CONSTANT)
+ Q_PROPERTY(QString uniformControlType READ controlTypeName CONSTANT)
Q_PROPERTY(QString uniformDescription READ description CONSTANT)
Q_PROPERTY(QVariant uniformValue READ value WRITE setValue NOTIFY uniformValueChanged)
Q_PROPERTY(QVariant uniformBackendValue READ backendValue NOTIFY uniformBackendValueChanged)
@@ -45,7 +46,9 @@ public:
Uniform(const QString &effectName, const QJsonObject &props, const QString &qenPath);
Type type() const;
+ Type controlType() const;
QString typeName() const;
+ QString controlTypeName() const;
QVariant value() const;
void setValue(const QVariant &newValue);
@@ -90,6 +93,7 @@ private:
QString m_qenPath;
Type m_type;
+ Type m_controlType;
QVariant m_value;
QVariant m_defaultValue;
QVariant m_minValue;