Make SpinBox a reusable component

Forgot to update Readonly `SpinBox`es to Qt 2 when implementing Cura
8684. As the spinbox is used in various places with the same
functionality it made sense to create a reusable component.

There is still a feature gap in the implementation; The `SpinBox`es
from QtControls 2.x value is defined as an integer. For some use-cases
we do require a fractional value in the `SpinBox`. The only two places
where this is required are the `material_diameter` and
`material_density` fields in the material prefference page.

Cura 8684
This commit is contained in:
casper 2022-02-07 19:59:57 +01:00
parent b18582e1fb
commit 1746e24dd9
3 changed files with 63 additions and 105 deletions

View file

@ -234,30 +234,31 @@ Item
Label { width: parent.width; height: parent.rowHeight; font.bold: true; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Properties") }
Label { width: informationPage.columnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Density") }
ReadOnlySpinBox
Cura.SpinBox
{
enabled: base.editingEnabled
id: densitySpinBox
width: informationPage.columnWidth
value: properties.density
decimals: 2
suffix: " g/cm³"
stepSize: 0.01
readOnly: !base.editingEnabled
stepSize: 0.01 // spinboxes can only cointain reals, a non-integer value can not be entered as the step size
onEditingFinished: base.setMetaDataEntry("properties/density", properties.density, value)
onValueChanged: updateCostPerMeter()
}
Label { width: informationPage.columnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Diameter") }
ReadOnlySpinBox
Cura.SpinBox
{
enabled: base.editingEnabled
id: diameterSpinBox
width: informationPage.columnWidth
value: properties.diameter
decimals: 2
suffix: " mm"
stepSize: 0.01
readOnly: !base.editingEnabled
stepSize: 0.01 // spinboxes can only cointain reals, a non-integer value can not be entered as the step size
onEditingFinished:
{
@ -283,44 +284,26 @@ Item
}
Label { width: informationPage.columnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Filament Cost") }
SpinBox
Cura.SpinBox
{
id: spoolCostSpinBox
width: informationPage.columnWidth
value: base.getMaterialPreferenceValue(properties.guid, "spool_cost")
to: 100000000
editable: true
contentItem: TextField
{
text: spoolCostSpinBox.textFromValue(spoolCostSpinBox.value, spoolCostSpinBox.locale)
selectByMouse: true
background: Item {}
validator: RegExpValidator { regExp: new RegExp("^" + base.currency + " ([0-9]+[.]?[0-9]*)?$") }
}
property int decimals: 2
valueFromText: function(text) {
// remove all non-number tokens from input string so value can be parsed correctly
var value = Number(text.replace(",", ".").replace(/[^0-9.]+/g, ""));
var precision = Math.pow(10, spoolCostSpinBox.decimals);
return Math.round(value * precision) / precision;
}
textFromValue: function(value) {
return base.currency + " " + value.toFixed(spoolCostSpinBox.decimals)
}
prefix: base.currency + " "
decimals: 2
onValueChanged:
{
base.setMaterialPreferenceValue(properties.guid, "spool_cost", parseFloat(value, decimals))
base.setMaterialPreferenceValue(properties.guid, "spool_cost", parseFloat(value))
updateCostPerMeter()
}
}
Label { width: informationPage.columnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Filament weight") }
SpinBox
Cura.SpinBox
{
id: spoolWeightSpinBox
width: informationPage.columnWidth
@ -328,24 +311,7 @@ Item
stepSize: 100
to: 10000
editable: true
contentItem: TextField
{
text: spoolWeightSpinBox.textFromValue(spoolWeightSpinBox.value, spoolWeightSpinBox.locale)
selectByMouse: true
background: Item {}
validator: RegExpValidator { regExp: new RegExp("^([0-9]+[.]?[0-9]*)? g$") }
}
valueFromText: function(text, locale) {
// remove all non-number tokens from input string so value can be parsed correctly
var value = Number(text.replace(",", ".").replace(/[^0-9.]+/g, ""));
return Math.round(value);
}
textFromValue: function(value, locale) {
return value + " g"
}
suffix: " g"
onValueChanged:
{
@ -465,7 +431,7 @@ Item
elide: Text.ElideRight
verticalAlignment: Qt.AlignVCenter
}
ReadOnlySpinBox
Cura.SpinBox
{
id: spinBox
anchors.left: label.right
@ -489,9 +455,8 @@ Item
return 0;
}
width: base.secondColumnWidth
readOnly: !base.editingEnabled
suffix: " " + model.unit
maximumValue: 99999
to: 99999
decimals: model.unit == "mm" ? 2 : 0
onEditingFinished: materialPropertyProvider.setPropertyValue("value", value)

View file

@ -1,54 +0,0 @@
// Copyright (c) 2016 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.1
import QtQuick.Controls 1.1
import QtQuick.Dialogs 1.2
Item
{
id: base
property alias value: spinBox.value
property alias minimumValue: spinBox.minimumValue
property alias maximumValue: spinBox.maximumValue
property alias stepSize: spinBox.stepSize
property alias prefix: spinBox.prefix
property alias suffix: spinBox.suffix
property alias decimals: spinBox.decimals
signal editingFinished();
property bool readOnly: false
width: spinBox.width
height: spinBox.height
SpinBox
{
id: spinBox
enabled: !base.readOnly
opacity: base.readOnly ? 0.5 : 1.0
anchors.fill: parent
onEditingFinished: base.editingFinished()
Keys.onEnterPressed: spinBox.focus = false
Keys.onReturnPressed: spinBox.focus = false
}
Label
{
visible: base.readOnly
text: base.prefix + base.value.toFixed(spinBox.decimals) + base.suffix
anchors.verticalCenter: parent.verticalCenter
anchors.left: parent.left
anchors.leftMargin: spinBox.__style ? spinBox.__style.padding.left : 0
color: palette.buttonText
}
SystemPalette { id: palette }
}

47
resources/qml/SpinBox.qml Normal file
View file

@ -0,0 +1,47 @@
// Copyright (c) 2022 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.2
import QtQuick.Controls 2.15
SpinBox
{
id: base
property string prefix: ""
property string suffix: ""
property int decimals: 0
signal editingFinished()
valueFromText: function(text)
{
return parseFloat(text.substring(prefix.length, text.length - suffix.length), decimals);
}
textFromValue: function(value)
{
return prefix + value.toFixed(decimals) + suffix
}
validator: RegExpValidator
{
regExp: new RegExp("^" + prefix + "([0-9]+[.|,]?[0-9]*)?" + suffix + "$")
}
contentItem: TextField
{
text: base.textFromValue(base.value, base.locale)
selectByMouse: true
background: Item {}
validator: base.validator
onActiveFocusChanged:
{
if(!activeFocus)
{
base.editingFinished()
}
}
}
}