Skip to content

Commit 4ca0db0

Browse files
authored
Fix GzSpinBox in cases where the value property has a binding (#656)
* Fix `GzSpinBox` in cases where the value property has a binding Before this fix, if the value property has a binding instead of a value, any modification from the GUI (e.g. hitting the up arrow on the spin box) would not actually change the displayed value because it is immediately reset back to the value set by the binding. This is the case in the `GzPose` module and the effect can be easily be seen in the `GridConfig` plugin. To test, run: `gz gui -c examples/config/grid_config.config` You will see that, before this change, modifying the x,y,z,roll,pitch, yaw values actually changes the grid configuration, but the updated values are not displayed in the spinbox. Signed-off-by: Addisu Z. Taddese <addisu@openrobotics.org>
1 parent 7395bff commit 4ca0db0

File tree

1 file changed

+31
-3
lines changed

1 file changed

+31
-3
lines changed

include/gz/gui/qml/GzSpinBox.qml

+31-3
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,13 @@ Item {
2828
property real stepSize: 1.0
2929
property int decimals: 0
3030

31+
onValueChanged: {
32+
if (!spinBox.__modifying)
33+
{
34+
spinBox.value = decimalToInt(root.value)
35+
}
36+
}
37+
3138
implicitHeight: spinBox.implicitHeight
3239

3340
readonly property int kMaxInt: Math.pow(2, 31) - 1
@@ -61,17 +68,34 @@ Item {
6168

6269
SpinBox {
6370
id: spinBox
71+
// This property is used to guard against binding loops. When
72+
// spinBox.value is modified through user input, (e.g. clicking on the
73+
// up arrow), we set the root.value. Without this guard condition, the
74+
// ValueChanged event of root.value would fire which would then try to
75+
// set spinBox.value, i.e a binding loop.
76+
property bool __modifying: false
6477

6578
anchors.fill : parent
6679
bottomPadding: 0
6780
topPadding: 0
6881
leftPadding: 5
6982
implicitHeight: 40
7083
clip: true
71-
72-
value: root.decimalToInt(root.value)
73-
84+
value: 0
85+
86+
// Keep the decimal representation of value so that we
87+
// can decimalFactor changes properly. This is different from
88+
// root.value because this does not have any bindings and thus
89+
// cannot be modified from outside of this SpinBox element.
90+
property real __valueAsDecimal: 0.0
91+
onValueChanged: {
92+
__valueAsDecimal = intToDecimal(value)
93+
}
94+
// Note that this is a different event than ValueChanged. The
95+
// ValueModified event only fires when the value is edited by user
96+
// input from the GUI.
7497
onValueModified: {
98+
__modifying = true
7599
// Set the "value" property without breaking/changing its bindings.
76100
// This is done by temporarily enabling the binding (valueUpdater),
77101
// emitting the editingFinished signal so users GzSpinBox can be
@@ -80,6 +104,7 @@ Item {
80104
valueUpdater.when = true
81105
root.editingFinished()
82106
valueUpdater.when = false
107+
__modifying = false
83108
}
84109

85110
from: decimalToInt(minimumValue)
@@ -90,6 +115,9 @@ Item {
90115
anchors.centerIn: parent
91116

92117
readonly property real decimalFactor: Math.pow(10, root.decimals)
118+
onDecimalFactorChanged: {
119+
value = decimalToInt(__valueAsDecimal)
120+
}
93121

94122
contentItem: TextInput {
95123
font.pointSize: 10

0 commit comments

Comments
 (0)