forked from qt-creator/qt-creator
Effect Maker: Enable helper nodes
Helper nodes are nodes that another node depends on and are added automatically when the depending node is added. Helper nodes are placed before all other nodes. Helper nodes that do not contain any properties are not shown. Helper nodes keep reference count and are removed when last referring node is removed. Task-number: QDS-11193 Change-Id: I036019afb1414ec6e98b2f949a18bd217753a910 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:
committed by
Miikka Heikkinen
parent
6b6f74ccad
commit
dc42b62ddf
@@ -0,0 +1,68 @@
|
|||||||
|
// Copyright (C) 2023 The Qt Company Ltd.
|
||||||
|
// SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
|
||||||
|
// This file should match the BlurHelper.qml in qtquickdesigner repository, except for shader paths
|
||||||
|
|
||||||
|
import QtQuick
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: rootItem
|
||||||
|
property alias blurSrc1: blurredItemSource1
|
||||||
|
property alias blurSrc2: blurredItemSource2
|
||||||
|
property alias blurSrc3: blurredItemSource3
|
||||||
|
property alias blurSrc4: blurredItemSource4
|
||||||
|
property alias blurSrc5: blurredItemSource5
|
||||||
|
|
||||||
|
component BlurItem: ShaderEffect {
|
||||||
|
property vector2d offset: Qt.vector2d((1.0 + rootItem.blurMultiplier) / width,
|
||||||
|
(1.0 + rootItem.blurMultiplier) / height)
|
||||||
|
visible: false
|
||||||
|
layer.enabled: true
|
||||||
|
layer.smooth: true
|
||||||
|
vertexShader: g_propertyData.blur_vs_path
|
||||||
|
fragmentShader: g_propertyData.blur_fs_path
|
||||||
|
}
|
||||||
|
|
||||||
|
QtObject {
|
||||||
|
id: priv
|
||||||
|
property bool useBlurItem1: true
|
||||||
|
property bool useBlurItem2: rootItem.blurMax > 2
|
||||||
|
property bool useBlurItem3: rootItem.blurMax > 8
|
||||||
|
property bool useBlurItem4: rootItem.blurMax > 16
|
||||||
|
property bool useBlurItem5: rootItem.blurMax > 32
|
||||||
|
}
|
||||||
|
|
||||||
|
BlurItem {
|
||||||
|
id: blurredItemSource1
|
||||||
|
property Item src: priv.useBlurItem1 ? source : null
|
||||||
|
// Size of the first blurred item is by default half of the source.
|
||||||
|
// Increase for quality and decrease for performance & more blur.
|
||||||
|
readonly property int blurItemSize: 8
|
||||||
|
width: src ? Math.ceil(src.width / 16) * blurItemSize : 0
|
||||||
|
height: src ? Math.ceil(src.height / 16) * blurItemSize : 0
|
||||||
|
}
|
||||||
|
BlurItem {
|
||||||
|
id: blurredItemSource2
|
||||||
|
property Item src: priv.useBlurItem2 ? blurredItemSource1 : null
|
||||||
|
width: blurredItemSource1.width * 0.5
|
||||||
|
height: blurredItemSource1.height * 0.5
|
||||||
|
}
|
||||||
|
BlurItem {
|
||||||
|
id: blurredItemSource3
|
||||||
|
property Item src: priv.useBlurItem3 ? blurredItemSource2 : null
|
||||||
|
width: blurredItemSource2.width * 0.5
|
||||||
|
height: blurredItemSource2.height * 0.5
|
||||||
|
}
|
||||||
|
BlurItem {
|
||||||
|
id: blurredItemSource4
|
||||||
|
property Item src: priv.useBlurItem4 ? blurredItemSource3 : null
|
||||||
|
width: blurredItemSource3.width * 0.5
|
||||||
|
height: blurredItemSource3.height * 0.5
|
||||||
|
}
|
||||||
|
BlurItem {
|
||||||
|
id: blurredItemSource5
|
||||||
|
property Item src: priv.useBlurItem5 ? blurredItemSource4 : null
|
||||||
|
width: blurredItemSource4.width * 0.5
|
||||||
|
height: blurredItemSource4.height * 0.5
|
||||||
|
}
|
||||||
|
}
|
@@ -17,16 +17,17 @@ HelperWidgets.Section {
|
|||||||
caption: nodeName
|
caption: nodeName
|
||||||
category: "EffectMaker"
|
category: "EffectMaker"
|
||||||
|
|
||||||
draggable: true
|
draggable: !isDependency
|
||||||
fillBackground: true
|
fillBackground: true
|
||||||
showCloseButton: true
|
showCloseButton: !isDependency
|
||||||
closeButtonToolTip: qsTr("Remove")
|
closeButtonToolTip: qsTr("Remove")
|
||||||
|
visible: repeater.count > 0 || !isDependency
|
||||||
|
|
||||||
onCloseButtonClicked: {
|
onCloseButtonClicked: {
|
||||||
EffectMakerBackend.effectMakerModel.removeNode(root.modelIndex)
|
EffectMakerBackend.effectMakerModel.removeNode(root.modelIndex)
|
||||||
}
|
}
|
||||||
|
|
||||||
showEyeButton: true
|
showEyeButton: !isDependency
|
||||||
eyeEnabled: nodeEnabled
|
eyeEnabled: nodeEnabled
|
||||||
eyeButtonToolTip: qsTr("Enable/Disable Node")
|
eyeButtonToolTip: qsTr("Enable/Disable Node")
|
||||||
|
|
||||||
@@ -38,6 +39,7 @@ HelperWidgets.Section {
|
|||||||
spacing: 10
|
spacing: 10
|
||||||
|
|
||||||
Repeater {
|
Repeater {
|
||||||
|
id: repeater
|
||||||
model: nodeUniformsModel
|
model: nodeUniformsModel
|
||||||
|
|
||||||
EffectCompositionNodeUniform {
|
EffectCompositionNodeUniform {
|
||||||
|
@@ -213,7 +213,8 @@ Item {
|
|||||||
currItem.y = root.secsY[i]
|
currItem.y = root.secsY[i]
|
||||||
}
|
}
|
||||||
} else if (i < root.moveFromIdx) {
|
} else if (i < root.moveFromIdx) {
|
||||||
if (root.draggedSec.y < currItem.y + (currItem.height - root.draggedSec.height) * .5) {
|
if (!repeater.model.isDependencyNode(i)
|
||||||
|
&& root.draggedSec.y < currItem.y + (currItem.height - root.draggedSec.height) * .5) {
|
||||||
currItem.y = root.secsY[i] + root.draggedSec.height
|
currItem.y = root.secsY[i] + root.draggedSec.height
|
||||||
root.moveToIdx = Math.min(root.moveToIdx, i)
|
root.moveToIdx = Math.min(root.moveToIdx, i)
|
||||||
} else {
|
} else {
|
||||||
|
@@ -194,6 +194,13 @@ Column {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BlurHelper {
|
||||||
|
id: blurHelper
|
||||||
|
anchors.fill: parent
|
||||||
|
property int blurMax: g_propertyData.blur_helper_max_level ? g_propertyData.blur_helper_max_level : 64
|
||||||
|
property real blurMultiplier: g_propertyData.blurMultiplier ? g_propertyData.blurMultiplier : 0
|
||||||
|
}
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
id: componentParent
|
id: componentParent
|
||||||
width: source.width
|
width: source.width
|
||||||
|
@@ -14,7 +14,8 @@
|
|||||||
|
|
||||||
namespace EffectMaker {
|
namespace EffectMaker {
|
||||||
|
|
||||||
CompositionNode::CompositionNode(const QString &effectName, const QString &qenPath, const QJsonObject &jsonObject)
|
CompositionNode::CompositionNode(const QString &effectName, const QString &qenPath,
|
||||||
|
const QJsonObject &jsonObject)
|
||||||
{
|
{
|
||||||
QJsonObject json;
|
QJsonObject json;
|
||||||
if (jsonObject.isEmpty()) {
|
if (jsonObject.isEmpty()) {
|
||||||
@@ -58,6 +59,11 @@ QString CompositionNode::description() const
|
|||||||
return m_description;
|
return m_description;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString CompositionNode::id() const
|
||||||
|
{
|
||||||
|
return m_id;
|
||||||
|
}
|
||||||
|
|
||||||
QObject *CompositionNode::uniformsModel()
|
QObject *CompositionNode::uniformsModel()
|
||||||
{
|
{
|
||||||
return &m_unifomrsModel;
|
return &m_unifomrsModel;
|
||||||
@@ -81,6 +87,11 @@ void CompositionNode::setIsEnabled(bool newIsEnabled)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CompositionNode::isDependency() const
|
||||||
|
{
|
||||||
|
return m_refCount > 0;
|
||||||
|
}
|
||||||
|
|
||||||
CompositionNode::NodeType CompositionNode::type() const
|
CompositionNode::NodeType CompositionNode::type() const
|
||||||
{
|
{
|
||||||
return m_type;
|
return m_type;
|
||||||
@@ -102,6 +113,13 @@ void CompositionNode::parse(const QString &effectName, const QString &qenPath, c
|
|||||||
m_fragmentCode = EffectUtils::codeFromJsonArray(json.value("fragmentCode").toArray());
|
m_fragmentCode = EffectUtils::codeFromJsonArray(json.value("fragmentCode").toArray());
|
||||||
m_vertexCode = EffectUtils::codeFromJsonArray(json.value("vertexCode").toArray());
|
m_vertexCode = EffectUtils::codeFromJsonArray(json.value("vertexCode").toArray());
|
||||||
|
|
||||||
|
m_id = json.value("id").toString();
|
||||||
|
if (m_id.isEmpty() && !qenPath.isEmpty()) {
|
||||||
|
QString fileName = qenPath.split('/').last();
|
||||||
|
fileName.chop(4); // remove ".qen"
|
||||||
|
m_id = fileName;
|
||||||
|
}
|
||||||
|
|
||||||
// parse properties
|
// parse properties
|
||||||
QJsonArray jsonProps = json.value("properties").toArray();
|
QJsonArray jsonProps = json.value("properties").toArray();
|
||||||
for (const auto /*QJsonValueRef*/ &prop : jsonProps) {
|
for (const auto /*QJsonValueRef*/ &prop : jsonProps) {
|
||||||
@@ -118,8 +136,7 @@ void CompositionNode::parse(const QString &effectName, const QString &qenPath, c
|
|||||||
for (const QString &codeLine : std::as_const(shaderCodeLines)) {
|
for (const QString &codeLine : std::as_const(shaderCodeLines)) {
|
||||||
QString trimmedLine = codeLine.trimmed();
|
QString trimmedLine = codeLine.trimmed();
|
||||||
if (trimmedLine.startsWith("@requires")) {
|
if (trimmedLine.startsWith("@requires")) {
|
||||||
// Get the required node, remove "@requires"
|
// Get the required node, remove "@requires "
|
||||||
QString l = trimmedLine.sliced(9).trimmed();
|
|
||||||
QString nodeName = trimmedLine.sliced(10);
|
QString nodeName = trimmedLine.sliced(10);
|
||||||
if (!nodeName.isEmpty() && !m_requiredNodes.contains(nodeName))
|
if (!nodeName.isEmpty() && !m_requiredNodes.contains(nodeName))
|
||||||
m_requiredNodes << nodeName;
|
m_requiredNodes << nodeName;
|
||||||
@@ -132,6 +149,36 @@ QList<Uniform *> CompositionNode::uniforms() const
|
|||||||
return m_uniforms;
|
return m_uniforms;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int CompositionNode::incRefCount()
|
||||||
|
{
|
||||||
|
++m_refCount;
|
||||||
|
|
||||||
|
if (m_refCount == 1)
|
||||||
|
emit isDepencyChanged();
|
||||||
|
|
||||||
|
return m_refCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
int CompositionNode::decRefCount()
|
||||||
|
{
|
||||||
|
--m_refCount;
|
||||||
|
|
||||||
|
if (m_refCount == 0)
|
||||||
|
emit isDepencyChanged();
|
||||||
|
|
||||||
|
return m_refCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CompositionNode::setRefCount(int count)
|
||||||
|
{
|
||||||
|
bool notifyChange = (m_refCount > 0 && count == 0) || (m_refCount <= 0 && count > 0);
|
||||||
|
|
||||||
|
m_refCount = count;
|
||||||
|
|
||||||
|
if (notifyChange)
|
||||||
|
emit isDepencyChanged();
|
||||||
|
}
|
||||||
|
|
||||||
QString CompositionNode::name() const
|
QString CompositionNode::name() const
|
||||||
{
|
{
|
||||||
return m_name;
|
return m_name;
|
||||||
|
@@ -15,7 +15,8 @@ class CompositionNode : public QObject
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
Q_PROPERTY(QString nodeName MEMBER m_name CONSTANT)
|
Q_PROPERTY(QString nodeName MEMBER m_name CONSTANT)
|
||||||
Q_PROPERTY(bool nodeEnabled READ isEnabled WRITE setIsEnabled NOTIFY isEnabledChanged)
|
Q_PROPERTY(bool nodeEnabled READ isEnabled WRITE setIsEnabled NOTIFY isEnabledChanged)
|
||||||
|
Q_PROPERTY(bool isDependency READ isDependency NOTIFY isDepencyChanged)
|
||||||
Q_PROPERTY(QObject *nodeUniformsModel READ uniformsModel NOTIFY uniformsModelChanged)
|
Q_PROPERTY(QObject *nodeUniformsModel READ uniformsModel NOTIFY uniformsModelChanged)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@@ -30,6 +31,7 @@ public:
|
|||||||
QString fragmentCode() const;
|
QString fragmentCode() const;
|
||||||
QString vertexCode() const;
|
QString vertexCode() const;
|
||||||
QString description() const;
|
QString description() const;
|
||||||
|
QString id() const;
|
||||||
|
|
||||||
QObject *uniformsModel();
|
QObject *uniformsModel();
|
||||||
|
|
||||||
@@ -40,13 +42,20 @@ public:
|
|||||||
bool isEnabled() const;
|
bool isEnabled() const;
|
||||||
void setIsEnabled(bool newIsEnabled);
|
void setIsEnabled(bool newIsEnabled);
|
||||||
|
|
||||||
|
bool isDependency() const;
|
||||||
|
|
||||||
QString name() const;
|
QString name() const;
|
||||||
|
|
||||||
QList<Uniform *> uniforms() const;
|
QList<Uniform *> uniforms() const;
|
||||||
|
|
||||||
|
int incRefCount();
|
||||||
|
int decRefCount();
|
||||||
|
void setRefCount(int count);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void uniformsModelChanged();
|
void uniformsModelChanged();
|
||||||
void isEnabledChanged();
|
void isEnabledChanged();
|
||||||
|
void isDepencyChanged();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void parse(const QString &effectName, const QString &qenPath, const QJsonObject &json);
|
void parse(const QString &effectName, const QString &qenPath, const QJsonObject &json);
|
||||||
@@ -57,7 +66,9 @@ private:
|
|||||||
QString m_vertexCode;
|
QString m_vertexCode;
|
||||||
QString m_description;
|
QString m_description;
|
||||||
QStringList m_requiredNodes;
|
QStringList m_requiredNodes;
|
||||||
|
QString m_id;
|
||||||
bool m_isEnabled = true;
|
bool m_isEnabled = true;
|
||||||
|
int m_refCount = 0;
|
||||||
|
|
||||||
QList<Uniform*> m_uniforms;
|
QList<Uniform*> m_uniforms;
|
||||||
|
|
||||||
|
@@ -4,6 +4,8 @@
|
|||||||
#include "effectmakermodel.h"
|
#include "effectmakermodel.h"
|
||||||
|
|
||||||
#include "compositionnode.h"
|
#include "compositionnode.h"
|
||||||
|
#include "effectutils.h"
|
||||||
|
#include "propertyhandler.h"
|
||||||
#include "syntaxhighlighterdata.h"
|
#include "syntaxhighlighterdata.h"
|
||||||
#include "uniform.h"
|
#include "uniform.h"
|
||||||
|
|
||||||
@@ -58,6 +60,7 @@ QHash<int, QByteArray> EffectMakerModel::roleNames() const
|
|||||||
roles[NameRole] = "nodeName";
|
roles[NameRole] = "nodeName";
|
||||||
roles[EnabledRole] = "nodeEnabled";
|
roles[EnabledRole] = "nodeEnabled";
|
||||||
roles[UniformsRole] = "nodeUniformsModel";
|
roles[UniformsRole] = "nodeUniformsModel";
|
||||||
|
roles[Dependency] = "isDependency";
|
||||||
return roles;
|
return roles;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -104,14 +107,29 @@ void EffectMakerModel::setIsEmpty(bool val)
|
|||||||
|
|
||||||
void EffectMakerModel::addNode(const QString &nodeQenPath)
|
void EffectMakerModel::addNode(const QString &nodeQenPath)
|
||||||
{
|
{
|
||||||
beginInsertRows({}, m_nodes.size(), m_nodes.size());
|
beginResetModel();
|
||||||
auto *node = new CompositionNode("", nodeQenPath);
|
auto *node = new CompositionNode({}, nodeQenPath);
|
||||||
connect(qobject_cast<EffectMakerUniformsModel *>(node->uniformsModel()),
|
connect(qobject_cast<EffectMakerUniformsModel *>(node->uniformsModel()),
|
||||||
&EffectMakerUniformsModel::dataChanged, this, [this] {
|
&EffectMakerUniformsModel::dataChanged, this, [this] {
|
||||||
setHasUnsavedChanges(true);
|
setHasUnsavedChanges(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const QList<QString> requiredNodes = node->requiredNodes();
|
||||||
|
if (requiredNodes.size() > 0) {
|
||||||
|
for (const QString &requiredId : requiredNodes) {
|
||||||
|
if (auto reqNode = findNodeById(requiredId)) {
|
||||||
|
reqNode->incRefCount();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const QString path = EffectUtils::nodesSourcesPath() + "/common/" + requiredId + ".qen";
|
||||||
|
auto requiredNode = new CompositionNode({}, path);
|
||||||
|
requiredNode->setRefCount(1);
|
||||||
|
m_nodes.prepend(requiredNode);
|
||||||
|
}
|
||||||
|
}
|
||||||
m_nodes.append(node);
|
m_nodes.append(node);
|
||||||
endInsertRows();
|
endResetModel();
|
||||||
|
|
||||||
setIsEmpty(false);
|
setIsEmpty(false);
|
||||||
|
|
||||||
@@ -121,6 +139,15 @@ void EffectMakerModel::addNode(const QString &nodeQenPath)
|
|||||||
emit nodesChanged();
|
emit nodesChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CompositionNode *EffectMakerModel::findNodeById(const QString &id) const
|
||||||
|
{
|
||||||
|
for (CompositionNode *node : std::as_const(m_nodes)) {
|
||||||
|
if (node->id() == id)
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
void EffectMakerModel::moveNode(int fromIdx, int toIdx)
|
void EffectMakerModel::moveNode(int fromIdx, int toIdx)
|
||||||
{
|
{
|
||||||
if (fromIdx == toIdx)
|
if (fromIdx == toIdx)
|
||||||
@@ -137,10 +164,20 @@ void EffectMakerModel::moveNode(int fromIdx, int toIdx)
|
|||||||
|
|
||||||
void EffectMakerModel::removeNode(int idx)
|
void EffectMakerModel::removeNode(int idx)
|
||||||
{
|
{
|
||||||
beginRemoveRows({}, idx, idx);
|
beginResetModel();
|
||||||
CompositionNode *node = m_nodes.takeAt(idx);
|
CompositionNode *node = m_nodes.takeAt(idx);
|
||||||
|
|
||||||
|
const QStringList reqNodes = node->requiredNodes();
|
||||||
|
for (const QString &reqId : reqNodes) {
|
||||||
|
CompositionNode *depNode = findNodeById(reqId);
|
||||||
|
if (depNode && depNode->decRefCount() <= 0) {
|
||||||
|
m_nodes.removeOne(depNode);
|
||||||
|
delete depNode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
delete node;
|
delete node;
|
||||||
endRemoveRows();
|
endResetModel();
|
||||||
|
|
||||||
if (m_nodes.isEmpty())
|
if (m_nodes.isEmpty())
|
||||||
setIsEmpty(true);
|
setIsEmpty(true);
|
||||||
@@ -442,6 +479,8 @@ QJsonObject nodeToJson(const CompositionNode &node)
|
|||||||
nodeObject.insert("description", node.description());
|
nodeObject.insert("description", node.description());
|
||||||
nodeObject.insert("enabled", node.isEnabled());
|
nodeObject.insert("enabled", node.isEnabled());
|
||||||
nodeObject.insert("version", 1);
|
nodeObject.insert("version", 1);
|
||||||
|
nodeObject.insert("id", node.id());
|
||||||
|
|
||||||
// Add properties
|
// Add properties
|
||||||
QJsonArray propertiesArray;
|
QJsonArray propertiesArray;
|
||||||
const QList<Uniform *> uniforms = node.uniforms();
|
const QList<Uniform *> uniforms = node.uniforms();
|
||||||
@@ -549,7 +588,17 @@ QString EffectMakerModel::getQmlEffectString()
|
|||||||
s += '\n';
|
s += '\n';
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO: Blue stuff goes here
|
if (m_shaderFeatures.enabled(ShaderFeatures::BlurSources)) {
|
||||||
|
s += " BlurHelper {\n";
|
||||||
|
s += " id: blurHelper\n";
|
||||||
|
s += " anchors.fill: parent\n";
|
||||||
|
int blurMax = 32;
|
||||||
|
if (g_propertyData.contains("BLUR_HELPER_MAX_LEVEL"))
|
||||||
|
blurMax = g_propertyData["BLUR_HELPER_MAX_LEVEL"].toInt();
|
||||||
|
s += QString(" property int blurMax: %1\n").arg(blurMax);
|
||||||
|
s += " property real blurMultiplier: rootItem.blurMultiplier\n";
|
||||||
|
s += " }\n";
|
||||||
|
}
|
||||||
|
|
||||||
s += getQmlComponentString(true);
|
s += getQmlComponentString(true);
|
||||||
s += "}\n";
|
s += "}\n";
|
||||||
@@ -643,18 +692,30 @@ void EffectMakerModel::openComposition(const QString &path)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (json.contains("nodes") && json["nodes"].isArray()) {
|
if (json.contains("nodes") && json["nodes"].isArray()) {
|
||||||
|
beginResetModel();
|
||||||
|
QHash<QString, int> refCounts;
|
||||||
const QJsonArray nodesArray = json["nodes"].toArray();
|
const QJsonArray nodesArray = json["nodes"].toArray();
|
||||||
|
|
||||||
for (const auto &nodeElement : nodesArray) {
|
for (const auto &nodeElement : nodesArray) {
|
||||||
beginInsertRows({}, m_nodes.size(), m_nodes.size());
|
auto *node = new CompositionNode(effectName, {}, nodeElement.toObject());
|
||||||
auto *node = new CompositionNode(effectName, "", nodeElement.toObject());
|
|
||||||
connect(qobject_cast<EffectMakerUniformsModel *>(node->uniformsModel()),
|
connect(qobject_cast<EffectMakerUniformsModel *>(node->uniformsModel()),
|
||||||
&EffectMakerUniformsModel::dataChanged, this, [this] {
|
&EffectMakerUniformsModel::dataChanged, this, [this] {
|
||||||
setHasUnsavedChanges(true);
|
setHasUnsavedChanges(true);
|
||||||
});
|
});
|
||||||
m_nodes.append(node);
|
m_nodes.append(node);
|
||||||
endInsertRows();
|
const QStringList reqIds = node->requiredNodes();
|
||||||
|
for (const QString &reqId : reqIds)
|
||||||
|
++refCounts[reqId];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (auto it = refCounts.cbegin(), end = refCounts.cend(); it != end; ++it) {
|
||||||
|
CompositionNode *depNode = findNodeById(it.key());
|
||||||
|
if (depNode)
|
||||||
|
depNode->setRefCount(it.value());
|
||||||
|
}
|
||||||
|
|
||||||
|
endResetModel();
|
||||||
|
|
||||||
setIsEmpty(m_nodes.isEmpty());
|
setIsEmpty(m_nodes.isEmpty());
|
||||||
bakeShaders();
|
bakeShaders();
|
||||||
}
|
}
|
||||||
@@ -748,6 +809,19 @@ void EffectMakerModel::saveResources(const QString &name)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (m_shaderFeatures.enabled(ShaderFeatures::BlurSources)) {
|
||||||
|
QString blurHelperFilename("BlurHelper.qml");
|
||||||
|
QString blurFsFilename("bluritems.frag.qsb");
|
||||||
|
QString blurVsFilename("bluritems.vert.qsb");
|
||||||
|
QString blurHelperPath(EffectUtils::nodesSourcesPath() + "/common/");
|
||||||
|
sources.append(blurHelperPath + blurHelperFilename);
|
||||||
|
sources.append(blurHelperPath + blurFsFilename);
|
||||||
|
sources.append(blurHelperPath + blurVsFilename);
|
||||||
|
dests.append(blurHelperFilename);
|
||||||
|
dests.append(blurFsFilename);
|
||||||
|
dests.append(blurVsFilename);
|
||||||
|
}
|
||||||
|
|
||||||
for (int i = 0; i < sources.count(); ++i) {
|
for (int i = 0; i < sources.count(); ++i) {
|
||||||
Utils::FilePath source = Utils::FilePath::fromString(sources[i]);
|
Utils::FilePath source = Utils::FilePath::fromString(sources[i]);
|
||||||
Utils::FilePath target = Utils::FilePath::fromString(effectsResPath + dests[i]);
|
Utils::FilePath target = Utils::FilePath::fromString(effectsResPath + dests[i]);
|
||||||
@@ -1505,6 +1579,13 @@ QStringList EffectMakerModel::uniformNames() const
|
|||||||
return usedList;
|
return usedList;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool EffectMakerModel::isDependencyNode(int index) const
|
||||||
|
{
|
||||||
|
if (m_nodes.size() > index)
|
||||||
|
return m_nodes[index]->isDependency();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void EffectMakerModel::updateQmlComponent()
|
void EffectMakerModel::updateQmlComponent()
|
||||||
{
|
{
|
||||||
// Clear possible QML runtime errors
|
// Clear possible QML runtime errors
|
||||||
|
@@ -7,10 +7,10 @@
|
|||||||
|
|
||||||
#include <utils/filepath.h>
|
#include <utils/filepath.h>
|
||||||
|
|
||||||
|
#include <QAbstractListModel>
|
||||||
#include <QFileSystemWatcher>
|
#include <QFileSystemWatcher>
|
||||||
#include <QMap>
|
#include <QMap>
|
||||||
#include <QRegularExpression>
|
#include <QRegularExpression>
|
||||||
#include <QStandardItemModel>
|
|
||||||
#include <QTemporaryFile>
|
#include <QTemporaryFile>
|
||||||
|
|
||||||
namespace ProjectExplorer {
|
namespace ProjectExplorer {
|
||||||
@@ -62,6 +62,8 @@ public:
|
|||||||
|
|
||||||
void addNode(const QString &nodeQenPath);
|
void addNode(const QString &nodeQenPath);
|
||||||
|
|
||||||
|
CompositionNode *findNodeById(const QString &id) const;
|
||||||
|
|
||||||
Q_INVOKABLE void moveNode(int fromIdx, int toIdx);
|
Q_INVOKABLE void moveNode(int fromIdx, int toIdx);
|
||||||
Q_INVOKABLE void removeNode(int idx);
|
Q_INVOKABLE void removeNode(int idx);
|
||||||
Q_INVOKABLE void clear();
|
Q_INVOKABLE void clear();
|
||||||
@@ -96,6 +98,8 @@ public:
|
|||||||
|
|
||||||
QStringList uniformNames() const;
|
QStringList uniformNames() const;
|
||||||
|
|
||||||
|
Q_INVOKABLE bool isDependencyNode(int index) const;
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void isEmptyChanged();
|
void isEmptyChanged();
|
||||||
void selectedIndexChanged(int idx);
|
void selectedIndexChanged(int idx);
|
||||||
@@ -112,7 +116,8 @@ private:
|
|||||||
enum Roles {
|
enum Roles {
|
||||||
NameRole = Qt::UserRole + 1,
|
NameRole = Qt::UserRole + 1,
|
||||||
EnabledRole,
|
EnabledRole,
|
||||||
UniformsRole
|
UniformsRole,
|
||||||
|
Dependency
|
||||||
};
|
};
|
||||||
|
|
||||||
enum ErrorTypes {
|
enum ErrorTypes {
|
||||||
|
@@ -2,8 +2,7 @@
|
|||||||
// 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 "effectmakernodesmodel.h"
|
#include "effectmakernodesmodel.h"
|
||||||
|
#include "effectutils.h"
|
||||||
#include <coreplugin/icore.h>
|
|
||||||
|
|
||||||
#include <utils/filepath.h>
|
#include <utils/filepath.h>
|
||||||
#include <utils/hostosinfo.h>
|
#include <utils/hostosinfo.h>
|
||||||
@@ -41,21 +40,12 @@ QVariant EffectMakerNodesModel::data(const QModelIndex &index, int role) const
|
|||||||
return m_categories.at(index.row())->property(roleNames().value(role));
|
return m_categories.at(index.row())->property(roleNames().value(role));
|
||||||
}
|
}
|
||||||
|
|
||||||
QString EffectMakerNodesModel::nodesSourcesPath() const
|
|
||||||
{
|
|
||||||
#ifdef SHARE_QML_PATH
|
|
||||||
if (Utils::qtcEnvironmentVariableIsSet("LOAD_QML_FROM_SOURCE"))
|
|
||||||
return QLatin1String(SHARE_QML_PATH) + "/effectMakerNodes";
|
|
||||||
#endif
|
|
||||||
return Core::ICore::resourcePath("qmldesigner/effectMakerNodes").toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
void EffectMakerNodesModel::loadModel()
|
void EffectMakerNodesModel::loadModel()
|
||||||
{
|
{
|
||||||
if (m_modelLoaded)
|
if (m_modelLoaded)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
auto nodesPath = Utils::FilePath::fromString(nodesSourcesPath());
|
auto nodesPath = Utils::FilePath::fromString(EffectUtils::nodesSourcesPath());
|
||||||
|
|
||||||
if (!nodesPath.exists()) {
|
if (!nodesPath.exists()) {
|
||||||
qWarning() << __FUNCTION__ << "Effects not found.";
|
qWarning() << __FUNCTION__ << "Effects not found.";
|
||||||
|
@@ -7,6 +7,7 @@
|
|||||||
#include "effectmakermodel.h"
|
#include "effectmakermodel.h"
|
||||||
#include "effectmakernodesmodel.h"
|
#include "effectmakernodesmodel.h"
|
||||||
#include "effectmakerview.h"
|
#include "effectmakerview.h"
|
||||||
|
#include "effectutils.h"
|
||||||
#include "propertyhandler.h"
|
#include "propertyhandler.h"
|
||||||
|
|
||||||
//#include "qmldesigner/designercore/imagecache/midsizeimagecacheprovider.h"
|
//#include "qmldesigner/designercore/imagecache/midsizeimagecacheprovider.h"
|
||||||
@@ -61,6 +62,7 @@ EffectMakerWidget::EffectMakerWidget(EffectMakerView *view)
|
|||||||
m_quickWidget->setResizeMode(QQuickWidget::SizeRootObjectToView);
|
m_quickWidget->setResizeMode(QQuickWidget::SizeRootObjectToView);
|
||||||
QmlDesigner::Theme::setupTheme(m_quickWidget->engine());
|
QmlDesigner::Theme::setupTheme(m_quickWidget->engine());
|
||||||
m_quickWidget->engine()->addImportPath(propertyEditorResourcesPath() + "/imports");
|
m_quickWidget->engine()->addImportPath(propertyEditorResourcesPath() + "/imports");
|
||||||
|
m_quickWidget->engine()->addImportPath(EffectUtils::nodesSourcesPath() + "/common");
|
||||||
m_quickWidget->setClearColor(QmlDesigner::Theme::getColor(
|
m_quickWidget->setClearColor(QmlDesigner::Theme::getColor(
|
||||||
QmlDesigner::Theme::Color::QmlDesigner_BackgroundColorDarkAlternate));
|
QmlDesigner::Theme::Color::QmlDesigner_BackgroundColorDarkAlternate));
|
||||||
|
|
||||||
@@ -76,6 +78,10 @@ EffectMakerWidget::EffectMakerWidget(EffectMakerView *view)
|
|||||||
|
|
||||||
m_quickWidget->rootContext()->setContextProperty("g_propertyData", &g_propertyData);
|
m_quickWidget->rootContext()->setContextProperty("g_propertyData", &g_propertyData);
|
||||||
|
|
||||||
|
QString blurPath = "file:" + EffectUtils::nodesSourcesPath() + "/common/";
|
||||||
|
g_propertyData.insert(QString("blur_vs_path"), QString(blurPath + "bluritems.vert.qsb"));
|
||||||
|
g_propertyData.insert(QString("blur_fs_path"), QString(blurPath + "bluritems.frag.qsb"));
|
||||||
|
|
||||||
auto map = m_quickWidget->registerPropertyMap("EffectMakerBackend");
|
auto map = m_quickWidget->registerPropertyMap("EffectMakerBackend");
|
||||||
map->setProperties({{"effectMakerNodesModel", QVariant::fromValue(m_effectMakerNodesModel.data())},
|
map->setProperties({{"effectMakerNodesModel", QVariant::fromValue(m_effectMakerNodesModel.data())},
|
||||||
{"effectMakerModel", QVariant::fromValue(m_effectMakerModel.data())},
|
{"effectMakerModel", QVariant::fromValue(m_effectMakerModel.data())},
|
||||||
|
@@ -3,6 +3,8 @@
|
|||||||
|
|
||||||
#include "effectutils.h"
|
#include "effectutils.h"
|
||||||
|
|
||||||
|
#include <coreplugin/icore.h>
|
||||||
|
|
||||||
#include <QJsonArray>
|
#include <QJsonArray>
|
||||||
|
|
||||||
namespace EffectMaker {
|
namespace EffectMaker {
|
||||||
@@ -20,5 +22,14 @@ QString EffectUtils::codeFromJsonArray(const QJsonArray &codeArray)
|
|||||||
return codeString;
|
return codeString;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString EffectUtils::nodesSourcesPath()
|
||||||
|
{
|
||||||
|
#ifdef SHARE_QML_PATH
|
||||||
|
if (Utils::qtcEnvironmentVariableIsSet("LOAD_QML_FROM_SOURCE"))
|
||||||
|
return QLatin1String(SHARE_QML_PATH) + "/effectMakerNodes";
|
||||||
|
#endif
|
||||||
|
return Core::ICore::resourcePath("qmldesigner/effectMakerNodes").toString();
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace EffectMaker
|
} // namespace EffectMaker
|
||||||
|
|
||||||
|
@@ -15,6 +15,8 @@ public:
|
|||||||
EffectUtils() = delete;
|
EffectUtils() = delete;
|
||||||
|
|
||||||
static QString codeFromJsonArray(const QJsonArray &codeArray);
|
static QString codeFromJsonArray(const QJsonArray &codeArray);
|
||||||
|
|
||||||
|
static QString nodesSourcesPath();
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace EffectMaker
|
} // namespace EffectMaker
|
||||||
|
Reference in New Issue
Block a user