diff options
| author | 2 * r + 2 * t <61896496+soramanew@users.noreply.github.com> | 2026-01-03 17:53:06 +1100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-01-03 17:53:06 +1100 |
| commit | bdcd13222fc6edc77c779a396900ab909e7d5439 (patch) | |
| tree | f9457f3c91c05ec852f974f239d06aca52a3918e /components/controls/CustomSpinBox.qml | |
| parent | [CI] chore: update flake (diff) | |
| parent | Merge branch 'caelestia-dots:main' into main (diff) | |
| download | caelestia-shell-bdcd13222fc6edc77c779a396900ab909e7d5439.tar.gz caelestia-shell-bdcd13222fc6edc77c779a396900ab909e7d5439.tar.bz2 caelestia-shell-bdcd13222fc6edc77c779a396900ab909e7d5439.zip | |
Merge pull request #906 from atdma/main
controlcenter: many setting panes and minor features
Diffstat (limited to 'components/controls/CustomSpinBox.qml')
| -rw-r--r-- | components/controls/CustomSpinBox.qml | 74 |
1 files changed, 68 insertions, 6 deletions
diff --git a/components/controls/CustomSpinBox.qml b/components/controls/CustomSpinBox.qml index e2ed508..438dc08 100644 --- a/components/controls/CustomSpinBox.qml +++ b/components/controls/CustomSpinBox.qml @@ -9,19 +9,69 @@ import QtQuick.Layouts RowLayout { id: root - property int value + property real value property real max: Infinity property real min: -Infinity + property real step: 1 property alias repeatRate: timer.interval - signal valueModified(value: int) + signal valueModified(value: real) spacing: Appearance.spacing.small + property bool isEditing: false + property string displayText: root.value.toString() + + onValueChanged: { + if (!root.isEditing) { + root.displayText = root.value.toString(); + } + } + StyledTextField { + id: textField + inputMethodHints: Qt.ImhFormattedNumbersOnly - text: root.value - onAccepted: root.valueModified(text) + text: root.isEditing ? text : root.displayText + validator: DoubleValidator { + bottom: root.min + top: root.max + decimals: root.step < 1 ? Math.max(1, Math.ceil(-Math.log10(root.step))) : 0 + } + onActiveFocusChanged: { + if (activeFocus) { + root.isEditing = true; + } else { + root.isEditing = false; + root.displayText = root.value.toString(); + } + } + onAccepted: { + const numValue = parseFloat(text); + if (!isNaN(numValue)) { + const clampedValue = Math.max(root.min, Math.min(root.max, numValue)); + root.value = clampedValue; + root.displayText = clampedValue.toString(); + root.valueModified(clampedValue); + } else { + text = root.displayText; + } + root.isEditing = false; + } + onEditingFinished: { + if (text !== root.displayText) { + const numValue = parseFloat(text); + if (!isNaN(numValue)) { + const clampedValue = Math.max(root.min, Math.min(root.max, numValue)); + root.value = clampedValue; + root.displayText = clampedValue.toString(); + root.valueModified(clampedValue); + } else { + text = root.displayText; + } + } + root.isEditing = false; + } padding: Appearance.padding.small leftPadding: Appearance.padding.normal @@ -50,7 +100,13 @@ RowLayout { onReleased: timer.stop() function onClicked(): void { - root.valueModified(Math.min(root.max, root.value + 1)); + let newValue = Math.min(root.max, root.value + root.step); + // Round to avoid floating point precision errors + const decimals = root.step < 1 ? Math.max(1, Math.ceil(-Math.log10(root.step))) : 0; + newValue = Math.round(newValue * Math.pow(10, decimals)) / Math.pow(10, decimals); + root.value = newValue; + root.displayText = newValue.toString(); + root.valueModified(newValue); } } @@ -79,7 +135,13 @@ RowLayout { onReleased: timer.stop() function onClicked(): void { - root.valueModified(Math.max(root.min, root.value - 1)); + let newValue = Math.max(root.min, root.value - root.step); + // Round to avoid floating point precision errors + const decimals = root.step < 1 ? Math.max(1, Math.ceil(-Math.log10(root.step))) : 0; + newValue = Math.round(newValue * Math.pow(10, decimals)) / Math.pow(10, decimals); + root.value = newValue; + root.displayText = newValue.toString(); + root.valueModified(newValue); } } |