diff --git a/share/qtcreator/qmldesigner/effectComposerQmlSources/EffectCompositionNodeUniform.qml b/share/qtcreator/qmldesigner/effectComposerQmlSources/EffectCompositionNodeUniform.qml index c353f8260aa..71cbf94f8bc 100644 --- a/share/qtcreator/qmldesigner/effectComposerQmlSources/EffectCompositionNodeUniform.qml +++ b/share/qtcreator/qmldesigner/effectComposerQmlSources/EffectCompositionNodeUniform.qml @@ -18,7 +18,10 @@ Item { Component.onCompleted: { if (uniformType === "int") { - valueLoader.source = "ValueInt.qml" + if (uniformControlType === "channel") + valueLoader.source = "ValueChannel.qml" + else + valueLoader.source = "ValueInt.qml" } else if (uniformType === "vec2") { valueLoader.source = "ValueVec2.qml" } else if (uniformType === "vec3") { diff --git a/share/qtcreator/qmldesigner/effectComposerQmlSources/ValueChannel.qml b/share/qtcreator/qmldesigner/effectComposerQmlSources/ValueChannel.qml new file mode 100644 index 00000000000..a089caf3efb --- /dev/null +++ b/share/qtcreator/qmldesigner/effectComposerQmlSources/ValueChannel.qml @@ -0,0 +1,15 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +import QtQuick +import StudioTheme as StudioTheme +import StudioControls as StudioControls + +Row { + StudioControls.ComboBox { + model: ["R", "G", "B", "A"] + actionIndicatorVisible: false + Component.onCompleted: currentIndex = uniformValue ?? 3 + onActivated: uniformValue = currentIndex + } +} diff --git a/src/plugins/effectcomposer/effectcomposermodel.cpp b/src/plugins/effectcomposer/effectcomposermodel.cpp index 5c2b1fc3cd6..5f782c7cbe7 100644 --- a/src/plugins/effectcomposer/effectcomposermodel.cpp +++ b/src/plugins/effectcomposer/effectcomposermodel.cpp @@ -424,6 +424,7 @@ QString variantAsDataString(const Uniform::Type type, const Uniform::Type contro s = variant.toBool() ? QString("true") : QString("false"); break; case Uniform::Type::Int: + case Uniform::Type::Channel: s = QString::number(variant.toInt()); break; case Uniform::Type::Float: @@ -497,8 +498,10 @@ QJsonObject nodeToJson(const CompositionNode &node) QJsonObject uniformObject; uniformObject.insert("name", QString(uniform->name())); QString type = Uniform::stringFromType(uniform->type()); + uniformObject.insert("type", type); - if (uniform->type() == Uniform::Type::Define) { + + if (uniform->type() == Uniform::Type::Define || uniform->type() == Uniform::Type::Channel) { QString controlType = Uniform::stringFromType(uniform->controlType()); if (controlType != type) uniformObject.insert("controlType", controlType); @@ -1140,6 +1143,8 @@ QString EffectComposerModel::valueAsString(const Uniform &uniform) return getImageElementName(uniform, true); } else if (uniform.type() == Uniform::Type::Color) { return QString("\"%1\"").arg(uniform.value().toString()); + } else if (uniform.type() == Uniform::Type::Channel) { + return QString::number(uniform.value().toInt()); } else if (uniform.type() == Uniform::Type::Define) { if (uniform.controlType() == Uniform::Type::Int) return QString::number(uniform.value().toInt()); @@ -1159,6 +1164,7 @@ QString EffectComposerModel::valueAsBinding(const Uniform &uniform) || uniform.type() == Uniform::Type::Int || uniform.type() == Uniform::Type::Float || uniform.type() == Uniform::Type::Color + || uniform.type() == Uniform::Type::Channel || uniform.type() == Uniform::Type::Define) { return "g_propertyData." + uniform.name(); } else if (uniform.type() == Uniform::Type::Vec2) { @@ -1205,6 +1211,8 @@ QString EffectComposerModel::valueAsVariable(const Uniform &uniform) } else if (uniform.type() == Uniform::Type::Color) { QColor c = uniform.value().value(); return QString("vec4(%1, %2, %3, %4)").arg(c.redF(), c.greenF(), c.blueF(), c.alphaF()); + } else if (uniform.type() == Uniform::Type::Channel) { + return QString::number(uniform.value().toInt()); } else { qWarning() << QString("Unhandled const variable type: %1").arg(int(uniform.type())).toLatin1(); return QString(); diff --git a/src/plugins/effectcomposer/uniform.cpp b/src/plugins/effectcomposer/uniform.cpp index 2fe6bfd2f5f..98d5ffd336f 100644 --- a/src/plugins/effectcomposer/uniform.cpp +++ b/src/plugins/effectcomposer/uniform.cpp @@ -22,7 +22,6 @@ 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(); @@ -45,11 +44,8 @@ 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); - } + QString controlType = propObj.value("controlType").toString(); + m_controlType = controlType.isEmpty() ? m_type : Uniform::typeFromString(controlType); m_customValue = propObj.value("customValue").toString(); m_useCustomValue = getBoolValue(propObj.value("useCustomValue"), false); @@ -245,8 +241,9 @@ R"( break; } case Type::Int: { - QString typeSpec = -R"( + if (m_controlType == Uniform::Type::Int) { + QString typeSpec = + R"( SpinBox { minimumValue: %1 maximumValue: %2 @@ -257,10 +254,25 @@ R"( implicitWidth: StudioTheme.Values.singleControlColumnWidth + StudioTheme.Values.actionIndicatorWidth } -)"; - specs += typeSpec.arg(m_minValue.toString(), m_maxValue.toString(), m_name); - break; + )"; + specs += typeSpec.arg(m_minValue.toString(), m_maxValue.toString(), m_name); + } else if (m_controlType == Uniform::Type::Channel) { + QString typeSpec = + R"( + ComboBox { + model: ["R", "G", "B", "A"] + backendValue: backendValues.%1 + manualMapping: true + + onCompressedActivated: backendValue.value = currentIndex + onValueFromBackendChanged: currentIndex = backendValue.value + Component.onCompleted: currentIndex = backendValue.value + } + )"; + specs += typeSpec.arg(m_name); + } } + break; case Type::Float: { QString typeSpec = R"( @@ -410,6 +422,8 @@ 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::Channel: + return 3; // sets default channel to alpha case Uniform::Type::Define: if (m_controlType == Uniform::Type::Bool) return maxValue ? true : false; @@ -460,6 +474,7 @@ QVariant Uniform::valueStringToVariant(const QString &value) } break; case Type::Sampler: + case Type::Channel: variant = value; break; case Uniform::Type::Define: @@ -491,6 +506,8 @@ QString Uniform::stringFromType(Uniform::Type type, bool isShader) return isShader ? QString("vec4") : QString("color"); else if (type == Type::Sampler) return "sampler2D"; + else if (type == Type::Channel) + return "channel"; else if (type == Type::Define) return "define"; @@ -516,6 +533,8 @@ Uniform::Type Uniform::typeFromString(const QString &typeString) return Uniform::Type::Color; else if (typeString == "sampler2D" || typeString == "image") //TODO: change image to sample2D in all QENs return Uniform::Type::Sampler; + else if (typeString == "channel") + return Uniform::Type::Channel; else if (typeString == "define") return Uniform::Type::Define; @@ -539,6 +558,8 @@ QString Uniform::typeToProperty(Uniform::Type type) return "vector4d"; else if (type == Uniform::Type::Color) return "color"; + else if (type == Uniform::Type::Channel) + return "channel"; else if (type == Uniform::Type::Sampler || type == Uniform::Type::Define) return "var"; diff --git a/src/plugins/effectcomposer/uniform.h b/src/plugins/effectcomposer/uniform.h index b478b2bed89..d3a39006510 100644 --- a/src/plugins/effectcomposer/uniform.h +++ b/src/plugins/effectcomposer/uniform.h @@ -41,6 +41,7 @@ public: Vec4, Color, Sampler, + Channel, Define };