Effect Maker: Make effects children of items they affect

...instead of being inlined into layer.effect. This fixes the issue
with dynamic properties not properly updating for inlined instances
at reset and in general makes the effect properties more accessible.

Task-number: QDS-11357
Change-Id: Ie372b99752ceda5bdfe248dd576352d2c6a4c4f7
Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io>
This commit is contained in:
Miikka Heikkinen
2023-12-22 16:56:11 +02:00
parent 8763a92274
commit fe6d2aef37
10 changed files with 163 additions and 46 deletions

View File

@@ -12,6 +12,7 @@ Item {
property alias blurSrc3: blurredItemSource3 property alias blurSrc3: blurredItemSource3
property alias blurSrc4: blurredItemSource4 property alias blurSrc4: blurredItemSource4
property alias blurSrc5: blurredItemSource5 property alias blurSrc5: blurredItemSource5
property Item source: null
component BlurItem: ShaderEffect { component BlurItem: ShaderEffect {
property vector2d offset: Qt.vector2d((1.0 + rootItem.blurMultiplier) / width, property vector2d offset: Qt.vector2d((1.0 + rootItem.blurMultiplier) / width,
@@ -37,8 +38,8 @@ Item {
// Size of the first blurred item is by default half of the source. // Size of the first blurred item is by default half of the source.
// Increase for quality and decrease for performance & more blur. // Increase for quality and decrease for performance & more blur.
readonly property int blurItemSize: 8 readonly property int blurItemSize: 8
width: Math.ceil(rootItem.width / 16) * blurItemSize width: Math.ceil((rootItem.source ? rootItem.source.width : 16) / 16) * blurItemSize
height: Math.ceil(rootItem.height / 16) * blurItemSize height: Math.ceil((rootItem.source ? rootItem.source.height : 16) / 16) * blurItemSize
} }
BlurItem { BlurItem {
id: blurredItemSource2 id: blurredItemSource2

View File

@@ -195,7 +195,7 @@ Column {
BlurHelper { BlurHelper {
id: blurHelper id: blurHelper
anchors.fill: parent source: source
property int blurMax: g_propertyData.blur_helper_max_level ? g_propertyData.blur_helper_max_level : 64 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 property real blurMultiplier: g_propertyData.blurMultiplier ? g_propertyData.blurMultiplier : 0
} }

View File

@@ -413,6 +413,7 @@ void EffectMakerModel::setEffectError(const QString &errorMessage, int type, int
QString additionalErrorInfo = detectErrorMessage(errorMessage); QString additionalErrorInfo = detectErrorMessage(errorMessage);
error.m_message = additionalErrorInfo + errorMessage; error.m_message = additionalErrorInfo + errorMessage;
m_effectErrors.insert(type, error); m_effectErrors.insert(type, error);
qWarning() << QString("Effect error (line: %2): %1").arg(error.m_message, error.m_line);
Q_EMIT effectErrorChanged(); Q_EMIT effectErrorChanged();
} }
@@ -556,13 +557,23 @@ QString EffectMakerModel::getQmlEffectString()
{ {
QString s; QString s;
s += QString("// Created with Qt Design Studio (version %1), %2\n\n") // _isEffectItem is type var to hide it from property view
.arg(qApp->applicationVersion(), QDateTime::currentDateTime().toString()); QString header{
s += "import QtQuick\n"; R"(
s += '\n'; // Created with Qt Design Studio (version %1), %2
s += "Item {\n";
s += " id: rootItem\n"; import QtQuick
s += '\n';
Item {
id: rootItem
property var _isEffectItem
property Item _oldParent: null
)"
};
s += header.arg(qApp->applicationVersion(), QDateTime::currentDateTime().toString());
if (m_shaderFeatures.enabled(ShaderFeatures::Source)) { if (m_shaderFeatures.enabled(ShaderFeatures::Source)) {
s += " // This is the main source for the effect\n"; s += " // This is the main source for the effect\n";
s += " property Item source: null\n"; s += " property Item source: null\n";
@@ -580,7 +591,33 @@ QString EffectMakerModel::getQmlEffectString()
s += " // When timeRunning is false, this can be used to control iFrame manually\n"; s += " // When timeRunning is false, this can be used to control iFrame manually\n";
s += " property int animatedFrame: frameAnimation.currentFrame\n"; s += " property int animatedFrame: frameAnimation.currentFrame\n";
} }
s += '\n';
QString parentChanged{
R"(
onParentChanged: {
if (_oldParent && _oldParent !== parent) {
_oldParent.layer.enabled = false
_oldParent.layer.effect = null
%2
_oldParent.update()
_oldParent = null
}
if (parent) {
_oldParent = parent
parent.layer.enabled = true
parent.layer.effect = effectComponent
%1
}
}
)"
};
parentChanged = parentChanged.arg(m_shaderFeatures.enabled(ShaderFeatures::Source)
? QString("source = parent") : QString(),
m_shaderFeatures.enabled(ShaderFeatures::Source)
? QString("source = null") : QString());
s += parentChanged;
// Custom properties // Custom properties
if (!m_exportedRootPropertiesString.isEmpty()) { if (!m_exportedRootPropertiesString.isEmpty()) {
s += m_exportedRootPropertiesString; s += m_exportedRootPropertiesString;
@@ -595,19 +632,14 @@ QString EffectMakerModel::getQmlEffectString()
s += '\n'; s += '\n';
} }
if (m_shaderFeatures.enabled(ShaderFeatures::BlurSources)) { QString customImagesString = getQmlImagesString(true);
s += " BlurHelper {\n"; if (!customImagesString.isEmpty())
s += " id: blurHelper\n"; s += customImagesString;
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 += " Component {\n";
s += " id: effectComponent\n";
s += getQmlComponentString(true); s += getQmlComponentString(true);
s += " }\n";
s += "}\n"; s += "}\n";
return s; return s;
} }
@@ -785,10 +817,10 @@ void EffectMakerModel::saveResources(const QString &name)
for (int i = 1; i < qmlStringList.size(); i++) { for (int i = 1; i < qmlStringList.size(); i++) {
QString line = qmlStringList.at(i).trimmed(); QString line = qmlStringList.at(i).trimmed();
if (line.startsWith("vertexShader")) { if (line.startsWith("vertexShader")) {
QString vsLine = " vertexShader: '" + vsFilename + "'"; QString vsLine = " vertexShader: '" + vsFilename + "'";
qmlStringList[i] = vsLine; qmlStringList[i] = vsLine;
} else if (line.startsWith("fragmentShader")) { } else if (line.startsWith("fragmentShader")) {
QString fsLine = " fragmentShader: '" + fsFilename + "'"; QString fsLine = " fragmentShader: '" + fsFilename + "'";
qmlStringList[i] = fsLine; qmlStringList[i] = fsLine;
} }
} }
@@ -1287,17 +1319,17 @@ void EffectMakerModel::updateCustomUniforms()
if (!uniform->description().isEmpty()) { if (!uniform->description().isEmpty()) {
const QStringList descriptionLines = uniform->description().split('\n'); const QStringList descriptionLines = uniform->description().split('\n');
for (const QString &line : descriptionLines) for (const QString &line : descriptionLines)
exportedEffectPropertiesString += QStringLiteral(" // ") + line + '\n'; exportedEffectPropertiesString += QStringLiteral(" // ") + line + '\n';
} }
exportedEffectPropertiesString += QStringLiteral(" ") + readOnly exportedEffectPropertiesString += QStringLiteral(" ") + readOnly
+ "property " + propertyType + " " + propertyName + "property " + propertyType + " " + propertyName
+ boundValueString + '\n'; + boundValueString + '\n';
} else { } else {
// Custom values are not added into root // Custom values are not added into root
exportedRootPropertiesString += " property " + propertyType + " " + propertyName exportedRootPropertiesString += " property " + propertyType + " " + propertyName
+ valueString + '\n'; + valueString + '\n';
exportedEffectPropertiesString += QStringLiteral(" ") exportedEffectPropertiesString += QStringLiteral(" ")
+ readOnly + "property alias " + propertyName + readOnly + "property " + propertyType + " " + propertyName
+ ": rootItem." + uniform->name() + '\n'; + ": rootItem." + uniform->name() + '\n';
} }
} }
@@ -1488,22 +1520,26 @@ QString EffectMakerModel::getQmlComponentString(bool localFiles)
{ {
if (localFiles) { if (localFiles) {
const QString parent = blurHelper ? QString("blurHelper.") : QString("rootItem."); const QString parent = blurHelper ? QString("blurHelper.") : QString("rootItem.");
return QString("readonly property alias %1: %2%3\n").arg(name, parent, var); return QString("readonly property %1 %2: %3%4\n").arg(type, name, parent, var);
} else { } else {
const QString parent = blurHelper ? "blurHelper." : QString(); const QString parent = blurHelper ? "blurHelper." : QString();
return QString("readonly property %1 %2: %3%4\n").arg(type, name, parent, var); return QString("readonly property %1 %2: %3%4\n").arg(type, name, parent, var);
} }
}; };
QString customImagesString = getQmlImagesString(localFiles);
QString s; QString s;
QString l1 = localFiles ? QStringLiteral(" ") : QStringLiteral(""); QString l1 = localFiles ? QStringLiteral(" ") : QStringLiteral("");
QString l2 = localFiles ? QStringLiteral(" ") : QStringLiteral(" "); QString l2 = localFiles ? QStringLiteral(" ") : QStringLiteral(" ");
QString l3 = localFiles ? QStringLiteral(" ") : QStringLiteral(" "); QString l3 = localFiles ? QStringLiteral(" ") : QStringLiteral(" ");
if (!localFiles) if (!localFiles)
s += "import QtQuick\n"; s += "import QtQuick\n";
s += l1 + "ShaderEffect {\n"; s += l1 + "ShaderEffect {\n";
if (localFiles) {
// Explicit "source" property is required for render puppet to detect effect correctly
s += l2 + "property Item source: null\n";
}
if (m_shaderFeatures.enabled(ShaderFeatures::Source)) if (m_shaderFeatures.enabled(ShaderFeatures::Source))
s += l2 + addProperty("iSource", "source", "Item"); s += l2 + addProperty("iSource", "source", "Item");
if (m_shaderFeatures.enabled(ShaderFeatures::Time)) if (m_shaderFeatures.enabled(ShaderFeatures::Time))
@@ -1529,15 +1565,18 @@ QString EffectMakerModel::getQmlComponentString(bool localFiles)
// and when in exported component, property with binding to root value. // and when in exported component, property with binding to root value.
s += localFiles ? m_exportedEffectPropertiesString : m_previewEffectPropertiesString; s += localFiles ? m_exportedEffectPropertiesString : m_previewEffectPropertiesString;
if (!customImagesString.isEmpty()) if (!localFiles) {
s += '\n' + customImagesString; QString customImagesString = getQmlImagesString(false);
if (!customImagesString.isEmpty())
s += '\n' + customImagesString;
}
s += '\n'; s += '\n';
const QString vertFile = localFiles ? m_vertexShaderFilename : m_vertexShaderPreviewFilename; const QString vertFile = localFiles ? m_vertexShaderFilename : m_vertexShaderPreviewFilename;
const QString fragFile = localFiles ? m_fragmentShaderFilename : m_fragmentShaderPreviewFilename; const QString fragFile = localFiles ? m_fragmentShaderFilename : m_fragmentShaderPreviewFilename;
s += l2 + "vertexShader: 'file:///" + vertFile + "'\n"; s += l2 + "vertexShader: 'file:///" + vertFile + "'\n";
s += l2 + "fragmentShader: 'file:///" + fragFile + "'\n"; s += l2 + "fragmentShader: 'file:///" + fragFile + "'\n";
s += l2 + "anchors.fill: parent\n"; s += l2 + "anchors.fill: " + (localFiles ? "rootItem.source" : "parent") + "\n";
if (m_shaderFeatures.enabled(ShaderFeatures::GridMesh)) { if (m_shaderFeatures.enabled(ShaderFeatures::GridMesh)) {
QString gridSize = QString("%1, %2").arg(m_shaderFeatures.gridMeshWidth()) QString gridSize = QString("%1, %2").arg(m_shaderFeatures.gridMeshWidth())
.arg(m_shaderFeatures.gridMeshHeight()); .arg(m_shaderFeatures.gridMeshHeight());
@@ -1545,6 +1584,18 @@ QString EffectMakerModel::getQmlComponentString(bool localFiles)
s += l3 + QString("resolution: Qt.size(%1)\n").arg(gridSize); s += l3 + QString("resolution: Qt.size(%1)\n").arg(gridSize);
s += l2 + "}\n"; s += l2 + "}\n";
} }
if (localFiles && m_shaderFeatures.enabled(ShaderFeatures::BlurSources)) {
s += l2 + "BlurHelper {\n";
s += l3 + "id: blurHelper\n";
s += l3 + "source: rootItem.source\n";
int blurMax = 32;
if (g_propertyData.contains("BLUR_HELPER_MAX_LEVEL"))
blurMax = g_propertyData["BLUR_HELPER_MAX_LEVEL"].toInt();
s += l3 + QString("property int blurMax: %1\n").arg(blurMax);
s += l3 + "property real blurMultiplier: rootItem.blurMultiplier\n";
s += l2 + "}\n";
}
s += l1 + "}\n"; s += l1 + "}\n";
return s; return s;
} }

View File

@@ -1731,7 +1731,7 @@ bool useLayerEffect()
QtcSettings *settings = Core::ICore::settings(); QtcSettings *settings = Core::ICore::settings();
const Key layerEffectEntry = "QML/Designer/UseLayerEffect"; const Key layerEffectEntry = "QML/Designer/UseLayerEffect";
return settings->value(layerEffectEntry, true).toBool(); return settings->value(layerEffectEntry, false).toBool();
} }
bool validateEffect(const QString &effectPath) bool validateEffect(const QString &effectPath)

View File

@@ -262,6 +262,27 @@ void FormEditorItem::setFrameColor(const QColor &color)
update(); update();
} }
void FormEditorItem::setHasEffect(bool hasEffect)
{
m_hasEffect = hasEffect;
}
bool FormEditorItem::hasEffect() const
{
return m_hasEffect;
}
bool FormEditorItem::parentHasEffect() const
{
FormEditorItem *pi = parentItem();
while (pi) {
if (pi->hasEffect())
return true;
pi = pi->parentItem();
}
return false;
}
FormEditorItem::~FormEditorItem() FormEditorItem::~FormEditorItem()
{ {
scene()->removeItemFromHash(this); scene()->removeItemFromHash(this);
@@ -421,7 +442,7 @@ void FormEditorItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *,
painter->setClipRegion(boundingRect().toRect()); painter->setClipRegion(boundingRect().toRect());
painter->setClipping(true); painter->setClipping(true);
if (!hideCompletely) { if (!hideCompletely && !parentHasEffect()) {
if (showPlaceHolder) { if (showPlaceHolder) {
if (scene()->showBoundingRects() && m_boundingRect.width() > 15 && m_boundingRect.height() > 15) if (scene()->showBoundingRects() && m_boundingRect.width() > 15 && m_boundingRect.height() > 15)
paintPlaceHolderForInvisbleItem(painter); paintPlaceHolderForInvisbleItem(painter);

View File

@@ -98,6 +98,10 @@ public:
void setFrameColor(const QColor &color); void setFrameColor(const QColor &color);
void setHasEffect(bool hasEffect);
bool hasEffect() const;
bool parentHasEffect() const;
protected: protected:
AbstractFormEditorTool* tool() const; AbstractFormEditorTool* tool() const;
void paintBoundingRect(QPainter *painter) const; void paintBoundingRect(QPainter *painter) const;
@@ -129,6 +133,7 @@ private: // variables
bool m_highlightBoundingRect; bool m_highlightBoundingRect;
bool m_blurContent; bool m_blurContent;
bool m_isContentVisible; bool m_isContentVisible;
bool m_hasEffect;
}; };
class FormEditorFlowItem : public FormEditorItem class FormEditorFlowItem : public FormEditorItem

View File

@@ -140,7 +140,7 @@ void FormEditorView::setupFormEditorItemTree(const QmlItemNode &qmlItemNode)
setupFormEditorItemTree(childNode.toQmlItemNode()); setupFormEditorItemTree(childNode.toQmlItemNode());
} }
} }
} else { } else if (!qmlItemNode.isEffectItem()) {
m_scene->addFormEditorItem(qmlItemNode, FormEditorScene::Default); m_scene->addFormEditorItem(qmlItemNode, FormEditorScene::Default);
for (const QmlObjectNode &nextNode : qmlItemNode.allDirectSubNodes()) //TODO instance children for (const QmlObjectNode &nextNode : qmlItemNode.allDirectSubNodes()) //TODO instance children
//If the node has source for components/custom parsers we ignore it. //If the node has source for components/custom parsers we ignore it.
@@ -280,6 +280,13 @@ void FormEditorView::nodeAboutToBeRemoved(const ModelNode &removedNode)
removeNodeFromScene(qmlItemNode); removeNodeFromScene(qmlItemNode);
} }
void FormEditorView::nodeRemoved(const ModelNode &/*removedNode*/,
const NodeAbstractProperty &/*parentProperty*/,
PropertyChangeFlags /*propertyChange*/)
{
updateHasEffects();
}
void FormEditorView::rootNodeTypeChanged(const QString &/*type*/, int /*majorVersion*/, int /*minorVersion*/) void FormEditorView::rootNodeTypeChanged(const QString &/*type*/, int /*majorVersion*/, int /*minorVersion*/)
{ {
const QList<FormEditorItem *> items = m_scene->allFormEditorItems(); const QList<FormEditorItem *> items = m_scene->allFormEditorItems();
@@ -343,6 +350,8 @@ static inline bool hasNodeSourceOrNonItemParent(const ModelNode &node)
void FormEditorView::nodeReparented(const ModelNode &node, const NodeAbstractProperty &/*newPropertyParent*/, const NodeAbstractProperty &/*oldPropertyParent*/, AbstractView::PropertyChangeFlags /*propertyChange*/) void FormEditorView::nodeReparented(const ModelNode &node, const NodeAbstractProperty &/*newPropertyParent*/, const NodeAbstractProperty &/*oldPropertyParent*/, AbstractView::PropertyChangeFlags /*propertyChange*/)
{ {
addOrRemoveFormEditorItem(node); addOrRemoveFormEditorItem(node);
updateHasEffects();
} }
void FormEditorView::nodeSourceChanged(const ModelNode &node, void FormEditorView::nodeSourceChanged(const ModelNode &node,
@@ -830,6 +839,8 @@ void FormEditorView::setupFormEditorWidget()
m_formEditorWidget->showWarningMessageBox(rewriterView()->warnings()); m_formEditorWidget->showWarningMessageBox(rewriterView()->warnings());
checkRootModelNode(); checkRootModelNode();
updateHasEffects();
} }
QmlItemNode findRecursiveQmlItemNode(const QmlObjectNode &firstQmlObjectNode) QmlItemNode findRecursiveQmlItemNode(const QmlObjectNode &firstQmlObjectNode)
@@ -991,6 +1002,23 @@ void FormEditorView::setupRootItemSize()
} }
} }
void FormEditorView::updateHasEffects()
{
if (model()) {
const QList<ModelNode> nodes = allModelNodes();
for (const auto &node : nodes) {
QmlItemNode qmlNode(node);
FormEditorItem *item = m_scene->itemForQmlItemNode(qmlNode);
if (item)
item->setHasEffect(false);
if (qmlNode.isEffectItem()) {
FormEditorItem *parentItem = m_scene->itemForQmlItemNode(qmlNode.modelParentItem());
parentItem->setHasEffect(true);
}
}
}
}
void FormEditorView::reset() void FormEditorView::reset()
{ {
QTimer::singleShot(200, this, &FormEditorView::delayedReset); QTimer::singleShot(200, this, &FormEditorView::delayedReset);

View File

@@ -52,6 +52,8 @@ public:
void nodeCreated(const ModelNode &createdNode) override; void nodeCreated(const ModelNode &createdNode) override;
void nodeAboutToBeRemoved(const ModelNode &removedNode) override; void nodeAboutToBeRemoved(const ModelNode &removedNode) override;
void nodeRemoved(const ModelNode &removedNode, const NodeAbstractProperty &parentProperty,
PropertyChangeFlags propertyChange) override;
void nodeReparented(const ModelNode &node, const NodeAbstractProperty &newPropertyParent, const NodeAbstractProperty &oldPropertyParent, AbstractView::PropertyChangeFlags propertyChange) override; void nodeReparented(const ModelNode &node, const NodeAbstractProperty &newPropertyParent, const NodeAbstractProperty &oldPropertyParent, AbstractView::PropertyChangeFlags propertyChange) override;
void nodeSourceChanged(const ModelNode &node, const QString &newNodeSource) override; void nodeSourceChanged(const ModelNode &node, const QString &newNodeSource) override;
void nodeIdChanged(const ModelNode& node, const QString& newId, const QString& oldId) override; void nodeIdChanged(const ModelNode& node, const QString& newId, const QString& oldId) override;
@@ -138,6 +140,7 @@ private:
void checkRootModelNode(); void checkRootModelNode();
void setupFormEditor3DView(); void setupFormEditor3DView();
void setupRootItemSize(); void setupRootItemSize();
void updateHasEffects();
QPointer<FormEditorWidget> m_formEditorWidget; QPointer<FormEditorWidget> m_formEditorWidget;
QPointer<FormEditorScene> m_scene; QPointer<FormEditorScene> m_scene;

View File

@@ -139,6 +139,8 @@ public:
bool isFlowActionArea() const; bool isFlowActionArea() const;
ModelNode rootModelNode() const; ModelNode rootModelNode() const;
bool isEffectItem() const;
friend auto qHash(const QmlItemNode &node) { return qHash(node.modelNode()); } friend auto qHash(const QmlItemNode &node) { return qHash(node.modelNode()); }
}; };

View File

@@ -182,14 +182,19 @@ QmlItemNode QmlItemNode::createQmlItemNodeForEffect(AbstractView *view,
const QString effectName = QFileInfo(effectPath).baseName(); const QString effectName = QFileInfo(effectPath).baseName();
Import import = Import::createLibraryImport("Effects." + effectName, "1.0"); Import import = Import::createLibraryImport("Effects." + effectName, "1.0");
try { try {
if (!view->model()->hasImport(import, true, true)) if (!view->model()->hasImport(import, true, true)) {
view->model()->changeImports({import}, {}); view->model()->changeImports({import}, {});
// Trigger async reset puppet to ensure full transaction is done before reset
view->resetPuppet();
}
} catch (const Exception &) { } catch (const Exception &) {
QTC_ASSERT(false, return); QTC_ASSERT(false, return);
} }
TypeName type(effectName.toUtf8()); TypeName type(effectName.toUtf8());
newQmlItemNode = QmlItemNode(view->createModelNode(type, -1, -1)); ModelNode newModelNode = view->createModelNode(type, -1, -1);
newModelNode.setIdWithoutRefactoring(view->model()->generateNewId(effectName));
newQmlItemNode = QmlItemNode(newModelNode);
placeEffectNode(parentProperty, newQmlItemNode, isLayerEffect); placeEffectNode(parentProperty, newQmlItemNode, isLayerEffect);
}; };
@@ -206,12 +211,8 @@ void QmlItemNode::placeEffectNode(NodeAbstractProperty &parentProperty, const Qm
parentProperty.reparentHere(effectNode); parentProperty.reparentHere(effectNode);
if (!isLayerEffect) { if (isLayerEffect)
effectNode.modelNode().bindingProperty("source").setExpression("parent");
effectNode.modelNode().bindingProperty("anchors.fill").setExpression("parent");
} else {
parentProperty.parentModelNode().variantProperty("layer.enabled").setValue(true); parentProperty.parentModelNode().variantProperty("layer.enabled").setValue(true);
}
if (effectNode.modelNode().metaInfo().hasProperty("timeRunning")) if (effectNode.modelNode().metaInfo().hasProperty("timeRunning"))
effectNode.modelNode().variantProperty("timeRunning").setValue(true); effectNode.modelNode().variantProperty("timeRunning").setValue(true);
@@ -617,6 +618,11 @@ ModelNode QmlItemNode::rootModelNode() const
return {}; return {};
} }
bool QmlItemNode::isEffectItem() const
{
return modelNode().metaInfo().hasProperty("_isEffectItem");
}
void QmlItemNode::setSize(const QSizeF &size) void QmlItemNode::setSize(const QSizeF &size)
{ {
if (!hasBindingProperty("width") && !(anchors().instanceHasAnchor(AnchorLineRight) if (!hasBindingProperty("width") && !(anchors().instanceHasAnchor(AnchorLineRight)