Warning, /graphics/spectacle/src/Gui/DelaySpinBox.qml is written in an unsupported language. File is not indexed.
0001 /* SPDX-FileCopyrightText: 2022 Noah Davis <noahadvs@gmail.com> 0002 * SPDX-License-Identifier: LGPL-2.0-or-later 0003 */ 0004 0005 import QtQuick 0006 import QtQuick.Controls as QQC 0007 import QtQuick.Templates as T 0008 import org.kde.spectacle.private 0009 0010 /** 0011 * Meant to mimic the behavior of SmartSpinBox, a custom Qt Widget spinbox created for Spectacle. 0012 */ 0013 QQC.SpinBox { 0014 id: root 0015 readonly property string noDelayString: i18nc("0 second delay", "No Delay") 0016 0017 function getDisplayText(value) { 0018 if (value === 0) { 0019 return noDelayString 0020 } 0021 const text = textFromValue(value) 0022 if (value % 100 === 0) { 0023 return i18ncp("Integer number of seconds", 0024 "%2 second", "%2 seconds", value / 100, text) 0025 } else { 0026 return i18nc("Decimal number of seconds", "%2 seconds", text) 0027 } 0028 } 0029 0030 // QQC Spinbox uses ints for some reason, 0031 // so I need to multiply by 10^decimals to get n decimal places of precision. 0032 from: 0 0033 to: 9900 // not 9999 to prevent stepping up by 1 at 99 from going to 99.99 0034 stepSize: 100 0035 value: Settings.captureDelay * 100 0036 onValueModified: Settings.captureDelay = value / 100 0037 onValueChanged: contentItem.text = getDisplayText(value) 0038 0039 Connections { 0040 target: Settings 0041 function onCaptureDelayChanged() { 0042 root.value = Settings.captureDelay * 100 0043 } 0044 } 0045 0046 validator: DoubleValidator { 0047 locale: root.locale.name 0048 bottom: root.from 0049 top: root.to / 100 0050 decimals: 2 0051 notation: DoubleValidator.StandardNotation 0052 } 0053 0054 textFromValue: (value, locale = root.locale) => { 0055 let precision = 2 0056 if (value % 100 === 0) { 0057 precision = 0 0058 } else if (value % 10 === 0) { 0059 precision = 1 0060 } 0061 return Number(value / 100).toLocaleString(locale, 'f', precision) 0062 } 0063 0064 valueFromText: (text, locale = root.locale) => { 0065 if (text === noDelayString) { 0066 return 0 0067 } 0068 let decimal = locale.decimalPoint 0069 if (decimal === '.') { 0070 decimal = "\\." 0071 } 0072 let t = text.replace(RegExp(`[^0-9${decimal}]+`, 'g'), ' ') 0073 let filtered = t.match(RegExp(`\\d{0,2}${decimal}\\d{1,2}`, 'g')) 0074 if (filtered === null) { 0075 filtered = t.match(/\d{1,2}/g) 0076 } 0077 if (filtered === null) { 0078 return -1 // unaccepted input 0079 } 0080 return Number.fromLocaleString(locale, filtered[0]) * 100 0081 } 0082 0083 contentItem: T.TextField { 0084 text: root.getDisplayText(root.value) 0085 color: palette.text 0086 selectionColor: palette.highlight 0087 selectedTextColor: palette.highlightedText 0088 selectByMouse: true 0089 readOnly: !root.editable 0090 validator: root.validator 0091 inputMethodHints: root.inputMethodHints 0092 leftPadding: QmlUtils.fontMetrics.descent 0093 rightPadding: QmlUtils.fontMetrics.descent 0094 horizontalAlignment: TextInput.AlignLeft 0095 verticalAlignment: TextInput.AlignVCenter 0096 implicitWidth: { 0097 const noDelay = QmlUtils.fontMetrics.boundingRect(root.noDelayString).width 0098 const largest = QmlUtils.fontMetrics.boundingRect(root.getDisplayText(9999)).width 0099 return Math.max(noDelay, largest) + leftPadding + rightPadding 0100 } 0101 implicitHeight: QmlUtils.fontMetrics.height 0102 onTextEdited: { 0103 validator.changed() 0104 if (cursorPosition > 2) { 0105 const pos1 = cursorPosition - 1 0106 const char1 = text[pos1] 0107 if (char1 === '.' || char1 === ',') { 0108 const pos2 = cursorPosition - 2 0109 const char2 = text[pos2] 0110 if (char2 === '.' || char2 === ',') { 0111 remove(pos2, pos1) 0112 } else { 0113 let index = text.indexOf('.') 0114 if (index === -1) { 0115 index = text.indexOf(',') 0116 } 0117 if (index !== -1 && index < pos2) { 0118 remove(index, pos1) 0119 } 0120 } 0121 } 0122 } 0123 let seconds = root.valueFromText(text) / 100 0124 if (acceptableInput || seconds >= 0) { 0125 const oldCursorPos = cursorPosition 0126 Settings.captureDelay = seconds 0127 cursorPosition = oldCursorPos 0128 } 0129 } 0130 } 0131 }