Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update GzSpinBox to use the SpinBox QML module from QtQuick.Controls2 #654

Merged
merged 4 commits into from
Feb 6, 2025
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
148 changes: 138 additions & 10 deletions include/gz/gui/qml/GzSpinBox.qml
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,144 @@
* limitations under the License.
*
*/
import QtQuick 2.9
import QtQuick.Controls 1.4
import QtQuick.Controls.Styles 1.4

SpinBox {
style: SpinBoxStyle{
background: Rectangle {
implicitWidth: 70
import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQml 2.15


Item {
id: root
signal editingFinished
property real minimumValue: 0
property real maximumValue: 100
property real value: 0.0
property real stepSize: 1.0
property int decimals: 0

implicitHeight: spinBox.implicitHeight

readonly property int kMaxInt: Math.pow(2, 31) - 1

function decimalToInt(decimal) {
var result = decimal * spinBox.decimalFactor
if (result >= kMaxInt) {
return kMaxInt
}
else if (result <= -kMaxInt) {
return -kMaxInt
}
return result
}

function intToDecimal(intVal) {
return intVal / spinBox.decimalFactor
}

// Used to update root.value without breaking existing bindings
// TODO(azeey) When migrating to Qt6, we might need to set
// the restoreMode property
Binding on value {
id: valueUpdater
target: root
property: 'value'
value: intToDecimal(spinBox.value)
when: false
restoreMode: Binding.RestoreBinding
}

SpinBox {
id: spinBox

anchors.fill : parent
bottomPadding: 0
topPadding: 0
leftPadding: 5
implicitHeight: 40
border.color: "gray"
clip: true

value: root.decimalToInt(root.value)

onValueModified: {
// Set the "value" property without breaking/changing its bindings.
// This is done by temporarily enabling the binding (valueUpdater),
// emitting the editingFinished signal so users GzSpinBox can be
// notified and take the new value of the spinbox, and finally
// disabling valueUpdater to restore the original bindings.
valueUpdater.when = true
root.editingFinished()
valueUpdater.when = false
}

from: decimalToInt(minimumValue)
to: decimalToInt(root.maximumValue)

stepSize: decimalToInt(root.stepSize)
editable: true
anchors.centerIn: parent

readonly property real decimalFactor: Math.pow(10, root.decimals)

contentItem: TextInput {
font.pointSize: 10
text: spinBox.textFromValue(spinBox.value, spinBox.locale)
horizontalAlignment: Qt.AlignRight
verticalAlignment: Qt.AlignVCenter
readOnly: !spinBox.editable
validator: spinBox.validator
inputMethodHints: Qt.ImhFormattedNumbersOnly
selectByMouse: true
clip: true
}

up.indicator: Rectangle {
x: spinBox.mirrored ? 0 : parent.width - width
implicitWidth: 20
implicitHeight: 20
color: "transparent"

Text {
text: "⏶"
opacity: spinBox.up.pressed ? 1: 0.6
anchors.fill: parent
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignBottom
}
}
down.indicator: Rectangle {
x: spinBox.mirrored ? 0 : parent.width - width
y: 20
implicitWidth: 20
implicitHeight: 20
color: "transparent"

Text {
text: "⏷"
opacity: spinBox.down.pressed ? 1: 0.6
anchors.fill: parent
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignTop
}
}

validator: DoubleValidator {
bottom: Math.min(spinBox.from, spinBox.to)
top: Math.max(spinBox.from, spinBox.to)
decimals: root.decimals
notation: DoubleValidator.StandardNotation
}

textFromValue: function(value, locale) {
return intToDecimal(value).toLocaleString(locale, 'f', parent.decimals)
}

valueFromText: function(text, locale) {
return Math.round(decimalToInt(Number.fromLocaleString(locale, text)))
}

background: Rectangle {
implicitWidth: 40
implicitHeight: parent.implicitHeight
border.color: "gray"
}
}
}
}