forked from qt-creator/qt-creator
QmlDesigner: Fix QML for bindings/properties
* Ensure a "node" is added to the model if missing, for e.g. Singletons * Expose targetNode of property Change-Id: Ifbb131c1d6efaaceb15a6e630ce56023ace63311 Reviewed-by: Henning Gründl <henning.gruendl@qt.io> Reviewed-by: Qt CI Patch Build Bot <ci_patchbuild_bot@qt.io>
This commit is contained in:
@@ -2,12 +2,38 @@
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
import QtQuick
|
||||
import StudioTheme 1.0 as StudioTheme
|
||||
|
||||
PopupDialog {
|
||||
property alias backend: form.backend
|
||||
titleBar: Row {
|
||||
spacing: 30 // TODO
|
||||
anchors.fill: parent
|
||||
|
||||
Text {
|
||||
color: StudioTheme.Values.themeTextColor
|
||||
text: qsTr("Owner")
|
||||
font.pixelSize: StudioTheme.Values.myFontSize
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
ToolTipArea {
|
||||
anchors.fill: parent
|
||||
tooltip: qsTr("The owner of the property")
|
||||
}
|
||||
}
|
||||
|
||||
Text {
|
||||
color: StudioTheme.Values.themeTextColor
|
||||
font.pixelSize: StudioTheme.Values.myFontSize
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
text: form.backend.targetNode
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
BindingsDialogForm {
|
||||
id: form
|
||||
y: 32
|
||||
height: 160
|
||||
}
|
||||
}
|
||||
|
@@ -3,86 +3,71 @@
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import StudioControls
|
||||
import StudioControls as StudioControls
|
||||
import StudioTheme as StudioTheme
|
||||
|
||||
Item {
|
||||
width: 400
|
||||
height: 800
|
||||
Column {
|
||||
id: root
|
||||
|
||||
readonly property real horizontalSpacing: 10
|
||||
readonly property real verticalSpacing: 16
|
||||
readonly property real columnWidth: (root.width - root.horizontalSpacing) / 2
|
||||
|
||||
property var backend
|
||||
|
||||
PopupLabel {
|
||||
x: 10
|
||||
y: 25
|
||||
text: qsTr("Target")
|
||||
y: StudioTheme.Values.popupMargin
|
||||
width: parent.width
|
||||
spacing: root.verticalSpacing
|
||||
|
||||
Row {
|
||||
spacing: root.horizontalSpacing
|
||||
|
||||
PopupLabel { text: qsTr("From") ; tooltip: qsTr("The Property to assign from.")}
|
||||
PopupLabel { text: qsTr("To"); tooltip: qsTr("The Property to assign to.") }
|
||||
}
|
||||
|
||||
PopupLabel {
|
||||
id: text111
|
||||
x: 80
|
||||
y: 25
|
||||
text: backend.targetNode
|
||||
font.pixelSize: 15
|
||||
Row {
|
||||
spacing: root.horizontalSpacing
|
||||
|
||||
StudioControls.TopLevelComboBox {
|
||||
id: sourceNode
|
||||
style: StudioTheme.Values.connectionPopupControlStyle
|
||||
width: root.columnWidth
|
||||
|
||||
model: backend.sourceNode.model ?? []
|
||||
onModelChanged: sourceNode.currentIndex = sourceNode.currentTypeIndex
|
||||
onActivated: backend.sourceNode.activateIndex(sourceNode.currentIndex)
|
||||
property int currentTypeIndex: backend.sourceNode.currentIndex ?? 0
|
||||
onCurrentTypeIndexChanged: sourceNode.currentIndex = sourceNode.currentTypeIndex
|
||||
}
|
||||
|
||||
PopupLabel {
|
||||
width: root.columnWidth
|
||||
text: backend.targetNode
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
TopLevelComboBox {
|
||||
id: target
|
||||
x: 101
|
||||
width: 210
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.verticalCenterOffset: -335
|
||||
model: backend.property.model ?? []
|
||||
enabled: false
|
||||
//I see no use case to actually change the property name
|
||||
//onActivated: backend.targetNode.activateIndex(target.currentIndex)
|
||||
property int currentTypeIndex: backend.property.currentIndex ?? 0
|
||||
onCurrentTypeIndexChanged: target.currentIndex = target.currentTypeIndex
|
||||
}
|
||||
Row {
|
||||
spacing: root.horizontalSpacing
|
||||
|
||||
PopupLabel {
|
||||
x: 13
|
||||
y: 111
|
||||
text: qsTr("Source Propety")
|
||||
}
|
||||
StudioControls.TopLevelComboBox {
|
||||
id: sourceProperty
|
||||
style: StudioTheme.Values.connectionPopupControlStyle
|
||||
width: root.columnWidth
|
||||
|
||||
TopLevelComboBox {
|
||||
id: sourceNode
|
||||
x: 135
|
||||
y: 98
|
||||
width: 156
|
||||
model: backend.sourceProperty.model ?? []
|
||||
onModelChanged: sourceProperty.currentIndex = sourceProperty.currentTypeIndex
|
||||
onActivated: backend.sourceProperty.activateIndex(
|
||||
sourceProperty.currentIndex)
|
||||
property int currentTypeIndex: backend.sourceProperty.currentIndex ?? 0
|
||||
onCurrentTypeIndexChanged: sourceProperty.currentIndex = sourceProperty.currentTypeIndex
|
||||
}
|
||||
|
||||
model: backend.sourceNode.model ?? []
|
||||
PopupLabel {
|
||||
width: root.columnWidth
|
||||
text: backend.property.currentText
|
||||
}
|
||||
|
||||
onModelChanged: sourceNode.currentIndex = sourceNode.currentTypeIndex
|
||||
|
||||
onActivated: backend.sourceNode.activateIndex(sourceNode.currentIndex)
|
||||
property int currentTypeIndex: backend.sourceNode.currentIndex ?? 0
|
||||
onCurrentTypeIndexChanged: sourceNode.currentIndex = sourceNode.currentTypeIndex
|
||||
}
|
||||
|
||||
PopupLabel {
|
||||
x: 13
|
||||
y: 88
|
||||
text: qsTr("Source Node")
|
||||
}
|
||||
|
||||
TopLevelComboBox {
|
||||
id: sourceProperty
|
||||
x: 140
|
||||
y: 121
|
||||
width: 156
|
||||
|
||||
model: backend.sourceProperty.model ?? []
|
||||
onModelChanged: sourceProperty.currentIndex = sourceProperty.currentTypeIndex
|
||||
onActivated: backend.sourceProperty.activateIndex(
|
||||
sourceProperty.currentIndex)
|
||||
property int currentTypeIndex: backend.sourceProperty.currentIndex ?? 0
|
||||
onCurrentTypeIndexChanged: sourceProperty.currentIndex = sourceProperty.currentTypeIndex
|
||||
}
|
||||
|
||||
PopupLabel {
|
||||
x: 10
|
||||
y: 55
|
||||
text: qsTr("Property")
|
||||
}
|
||||
}
|
||||
|
@@ -2,12 +2,38 @@
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
import QtQuick
|
||||
import StudioTheme 1.0 as StudioTheme
|
||||
|
||||
PopupDialog {
|
||||
property alias backend: form.backend
|
||||
|
||||
titleBar: Row {
|
||||
spacing: 30 // TODO
|
||||
anchors.fill: parent
|
||||
|
||||
Text {
|
||||
color: StudioTheme.Values.themeTextColor
|
||||
text: qsTr("Owner")
|
||||
font.pixelSize: StudioTheme.Values.myFontSize
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
ToolTipArea {
|
||||
anchors.fill: parent
|
||||
tooltip: qsTr("The owner of the property")
|
||||
}
|
||||
}
|
||||
|
||||
Text {
|
||||
color: StudioTheme.Values.themeTextColor
|
||||
font.pixelSize: StudioTheme.Values.myFontSize
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
text: form.backend.targetNode
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
PropertiesDialogForm {
|
||||
id: form
|
||||
y: 32
|
||||
height: 180
|
||||
}
|
||||
}
|
||||
|
@@ -1,68 +1,73 @@
|
||||
// Copyright (C) 2023 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
import QtQuick 2.15
|
||||
import QtQuick.Controls 2.15
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import StudioControls as StudioControls
|
||||
import StudioTheme as StudioTheme
|
||||
|
||||
import StudioControls
|
||||
Column {
|
||||
id: root
|
||||
|
||||
Item {
|
||||
width: 400
|
||||
height: 800
|
||||
readonly property real horizontalSpacing: 10
|
||||
readonly property real verticalSpacing: 16
|
||||
readonly property real columnWidth: (root.width - root.horizontalSpacing) / 2
|
||||
|
||||
property var backend
|
||||
|
||||
y: StudioTheme.Values.popupMargin
|
||||
width: parent.width
|
||||
spacing: root.verticalSpacing
|
||||
|
||||
PopupLabel {
|
||||
x: 10
|
||||
y: 25
|
||||
|
||||
text: qsTr("Type:")
|
||||
|
||||
text: qsTr("Type")
|
||||
tooltip: qsTr("The type of the property")
|
||||
}
|
||||
StudioControls.TopLevelComboBox {
|
||||
id: type
|
||||
style: StudioTheme.Values.connectionPopupControlStyle
|
||||
width: root.columnWidth
|
||||
//width: root.width
|
||||
|
||||
TopLevelComboBox {
|
||||
id: target
|
||||
x: 95
|
||||
width: 210
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.verticalCenterOffset: -367
|
||||
model: backend.type.model ?? []
|
||||
onActivated: backend.type.activateIndex(target.currentIndex)
|
||||
onActivated: backend.type.activateIndex(type.currentIndex)
|
||||
property int currentTypeIndex: backend.type.currentIndex ?? 0
|
||||
onCurrentTypeIndexChanged: target.currentIndex = target.currentTypeIndex
|
||||
onCurrentTypeIndexChanged: type.currentIndex = type.currentTypeIndex
|
||||
}
|
||||
|
||||
PopupLabel {
|
||||
x: 10
|
||||
y: 131
|
||||
text: qsTr("Name")
|
||||
Row {
|
||||
spacing: root.horizontalSpacing
|
||||
|
||||
PopupLabel { text: qsTr("Name") ; tooltip: qsTr("The name of the property.")}
|
||||
PopupLabel { text: qsTr("Value"); tooltip: qsTr("The value of the property.") }
|
||||
}
|
||||
|
||||
TextInput {
|
||||
id: name
|
||||
x: 70
|
||||
y: 131
|
||||
width: 156
|
||||
text: backend.name.text ?? ""
|
||||
onEditingFinished: {
|
||||
backend.name.activateText(name.text)
|
||||
Row {
|
||||
spacing: root.horizontalSpacing
|
||||
StudioControls.TextField {
|
||||
id: name
|
||||
|
||||
width: root.columnWidth
|
||||
actionIndicatorVisible: false
|
||||
translationIndicatorVisible: false
|
||||
|
||||
text: backend.name.text ?? ""
|
||||
onEditingFinished: {
|
||||
backend.name.activateText(name.text)
|
||||
}
|
||||
}
|
||||
}
|
||||
StudioControls.TextField {
|
||||
id: value
|
||||
|
||||
PopupLabel {
|
||||
x: 10
|
||||
y: 81
|
||||
text: qsTr("Value")
|
||||
}
|
||||
width: root.columnWidth
|
||||
actionIndicatorVisible: false
|
||||
translationIndicatorVisible: false
|
||||
|
||||
TextInput {
|
||||
id: value
|
||||
x: 70
|
||||
y: 81
|
||||
width: 156
|
||||
text: backend.value.text ?? ""
|
||||
onEditingFinished: {
|
||||
backend.value.activateText(value.text)
|
||||
|
||||
text: backend.value.text ?? ""
|
||||
onEditingFinished: {
|
||||
backend.value.activateText(value.text)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -553,12 +553,16 @@ void BindingModelBackendDelegate::setCurrentRow(int i)
|
||||
}
|
||||
|
||||
std::sort(sourceNodes.begin(), sourceNodes.end());
|
||||
m_sourceNode.setModel(sourceNodes);
|
||||
|
||||
QString sourceNodeName;
|
||||
QString sourcePropertyName;
|
||||
model->getExpressionStrings(bindingProperty, &sourceNodeName, &sourcePropertyName);
|
||||
|
||||
if (!sourceNodes.contains(sourceNodeName))
|
||||
sourceNodes.append(sourceNodeName);
|
||||
|
||||
m_sourceNode.setModel(sourceNodes);
|
||||
|
||||
m_sourceNode.setCurrentText(sourceNodeName);
|
||||
|
||||
m_sourceNodeProperty.setModel(model->possibleSourceProperties(bindingProperty));
|
||||
|
@@ -1022,6 +1022,10 @@ void DynamicPropertiesModelBackendDelegate::setCurrentRow(int i)
|
||||
m_value.setText(property.toVariantProperty().value().toString());
|
||||
else if (property.isBindingProperty())
|
||||
m_value.setText(property.toBindingProperty().expression());
|
||||
|
||||
m_targetNode = property.parentModelNode().id();
|
||||
|
||||
emit targetNodeChanged();
|
||||
}
|
||||
|
||||
void DynamicPropertiesModelBackendDelegate::handleTypeChanged()
|
||||
@@ -1077,9 +1081,10 @@ void DynamicPropertiesModelBackendDelegate::handleNameChanged()
|
||||
const QString expression = bindingProperty.expression();
|
||||
const PropertyName dynamicPropertyType = bindingProperty.dynamicTypeName();
|
||||
|
||||
targetNode.removeProperty(bindingProperty.name());
|
||||
|
||||
targetNode.bindingProperty(newName).setDynamicTypeNameAndExpression(dynamicPropertyType,
|
||||
expression);
|
||||
targetNode.removeProperty(bindingProperty.name());
|
||||
});
|
||||
|
||||
return;
|
||||
@@ -1093,9 +1098,10 @@ void DynamicPropertiesModelBackendDelegate::handleNameChanged()
|
||||
ModelNode targetNode = variantProperty.parentModelNode();
|
||||
|
||||
model->view()->executeInTransaction(__FUNCTION__, [=]() {
|
||||
targetNode.removeProperty(variantProperty.name());
|
||||
|
||||
targetNode.variantProperty(newName).setDynamicTypeNameAndValue(dynamicPropertyType,
|
||||
value);
|
||||
targetNode.removeProperty(variantProperty.name());
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1167,6 +1173,11 @@ QVariant DynamicPropertiesModelBackendDelegate::variantValue() const
|
||||
return m_value.text();
|
||||
}
|
||||
|
||||
QString DynamicPropertiesModelBackendDelegate::targetNode() const
|
||||
{
|
||||
return m_targetNode;
|
||||
}
|
||||
|
||||
StudioQmlComboBoxBackend *DynamicPropertiesModelBackendDelegate::type()
|
||||
{
|
||||
return &m_type;
|
||||
|
@@ -135,6 +135,7 @@ class DynamicPropertiesModelBackendDelegate : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
Q_PROPERTY(QString targetNode READ targetNode NOTIFY targetNodeChanged)
|
||||
Q_PROPERTY(StudioQmlComboBoxBackend *type READ type CONSTANT)
|
||||
Q_PROPERTY(int currentRow READ currentRow WRITE setCurrentRow NOTIFY currentRowChanged)
|
||||
Q_PROPERTY(StudioQmlTextBackend *name READ name CONSTANT)
|
||||
@@ -148,6 +149,7 @@ signals:
|
||||
void currentRowChanged();
|
||||
void nameChanged();
|
||||
void valueChanged();
|
||||
void targetNodeChanged();
|
||||
|
||||
private:
|
||||
int currentRow() const;
|
||||
@@ -157,6 +159,7 @@ private:
|
||||
void handleValueChanged();
|
||||
void handleException();
|
||||
QVariant variantValue() const;
|
||||
QString targetNode() const;
|
||||
|
||||
StudioQmlComboBoxBackend *type();
|
||||
|
||||
@@ -168,6 +171,7 @@ private:
|
||||
StudioQmlTextBackend m_value;
|
||||
int m_currentRow = -1;
|
||||
QString m_exceptionError;
|
||||
QString m_targetNode;
|
||||
};
|
||||
|
||||
} // namespace QmlDesigner
|
||||
|
Reference in New Issue
Block a user