29 import QtQuick.Controls 2.3
78 property double value: 0.0
79 property double from: 0.0
80 property double to: 100.0
81 property double stepSize: 1.0
82 property bool editable:
true 83 property bool wrap:
true 84 property QtObject validator: doubleValidator
85 property int inputMethodHints: Qt.ImhFormattedNumbersOnly
86 readonly
property string displayText: textFromValue(value, effectiveLocale)
87 readonly
property bool inputMethodComposing: textInputItem ? textInputItem.inputMethodComposing :
false 90 property int decimals: 2
91 property int notation: DoubleValidator.StandardNotation
92 property string inputMask
93 property bool selectByMouse:
true 94 property bool useLocaleFormat:
true 95 property bool showGroupSeparator:
true 96 property bool trimExtraZeros:
true 97 property string prefix
98 property string suffix
99 property int pageSteps: 10
100 property int buttonRepeatDelay: 300
101 property int buttonRepeatInterval: 100
103 readonly
property string cleanText: getCleanText(displayText)
104 readonly
property bool acceptableInput: textInputItem && textInputItem.acceptableInput
105 readonly
property real topValue: Math.max(from, to)
106 readonly
property real botValue: Math.min(from, to)
110 readonly
property SpinBox spinBoxItem: contentItem
112 property Item textInputItem: spinBoxItem ? spinBoxItem.contentItem : null
115 readonly
property QtObject doubleValidator: DoubleValidator {
116 top: control.topValue
117 bottom: control.botValue
118 decimals: Math.max(control.decimals, 0)
119 notation: control.notation
120 locale: control.effectiveLocale.name
128 readonly
property QtObject regExpValidator: RegExpValidator { regExp: control.doubleValidationRegEx(); }
132 signal valueModified()
137 wheelEnabled: !editable || (textInputItem && textInputItem.activeFocus)
140 contentItem: SpinBox {
141 width: control.availableWidth
142 height: control.availableHeight
143 editable: control.editable
144 inputMethodHints: control.inputMethodHints
145 validator: control.validator
146 from: -0x7FFFFFFF; to: 0x7FFFFFFF;
153 function increase() {
158 function decrease() {
166 function stepBy(steps, noWrap) {
168 setValue(textValue() + (stepSize * steps), noWrap);
177 function setValue(newValue, noWrap, notModified)
180 newValue = Math.max(Math.min(newValue, control.topValue), control.botValue);
181 else if (newValue < control.botValue)
182 newValue = control.topValue;
183 else if (newValue > control.topValue)
184 newValue = control.botValue;
186 newValue = Number(newValue.toFixed(Math.max(decimals, 0)));
188 if (value !== newValue) {
195 spinBoxItem.value = 0;
203 function textFromValue(value, locale)
206 locale = effectiveLocale;
208 var text = value.toLocaleString(locale, (notation === DoubleValidator.StandardNotation ?
'f' :
'e'), Math.max(decimals, 0));
210 if (!showGroupSeparator && locale.name !==
"C")
211 text = text.replace(
new RegExp(
"\\" + locale.groupSeparator,
"g"),
"");
212 if (trimExtraZeros) {
213 var pt = locale.decimalPoint;
214 var ex =
new RegExp(
"\\" + pt +
"0*$|(\\" + pt +
"\\d*[1-9])(0+)$").exec(text);
216 text = text.replace(ex[0], ex[1] ||
"");
220 text = prefix + text;
222 text = text + suffix;
228 function valueFromText(text, locale)
231 locale = effectiveLocale;
233 text = getCleanText(text, locale);
235 var re =
"[^\\+\\-\\d\\" + locale.decimalPoint + locale.exponential +
"]+";
236 text = text.replace(
new RegExp(re,
"gi"),
"");
240 return Number.fromLocaleString(locale, text);
245 function getCleanText(text, locale)
249 text = text.replace(prefixRegEx,
"");
251 text = text.replace(suffixRegEx,
"");
256 function escapeRegExpChars(
string) {
257 return string.replace(/[.*+?^${}()|[\]\\]/g,
'\\$&');
261 function escapeInputMaskChars(
string) {
262 return string.replace(/[{}\[\]\\><!#09anxdhb]/gi,
'\\$&');
266 function doubleValidationRegEx()
268 var locale = effectiveLocale,
269 pnt = locale.decimalPoint,
270 grp = locale.groupSeparator,
271 exp = locale.exponential,
272 pfx = escapeRegExpChars(prefix),
273 sfx = escapeRegExpChars(suffix),
274 expRe =
"(?:" + exp +
"[+-]?[\\d]+)?",
275 re =
"^" + pfx +
"[+-]?(?:[\\d]{1,3}\\" + grp +
"?)+\\" + pnt +
"?[\\d]*" + expRe + sfx +
"$";
277 return new RegExp(re,
"i");
282 property bool isValidated:
false 283 property bool completed:
false 284 readonly
property var defaultLocale: Qt.locale(
"C")
285 readonly
property var effectiveLocale: useLocaleFormat ? locale : defaultLocale
286 readonly
property var prefixRegEx:
new RegExp(
"^" + escapeRegExpChars(prefix))
287 readonly
property var suffixRegEx:
new RegExp(escapeRegExpChars(suffix) +
"$")
291 function textValue() {
292 return textInputItem ? valueFromText(textInputItem.text, effectiveLocale) : 0;
296 function updateValueFromText() {
297 if (!setValue(textValue(),
true))
302 function handleKeyEvent(
event)
305 if (
event.key === Qt.Key_Up)
307 else if (
event.key === Qt.Key_Down)
309 else if (
event.key === Qt.Key_PageUp)
310 steps = control.pageSteps;
311 else if (
event.key === Qt.Key_PageDown)
312 steps = -control.pageSteps;
313 else if (
event.key !== Qt.Key_Enter &&
event.key !== Qt.Key_Return)
316 event.accepted =
true;
321 updateValueFromText();
325 function toggleButtonPress(press, increment)
328 btnRepeatTimer.stop();
336 btnRepeatTimer.increment = increment;
337 btnRepeatTimer.start();
347 textInputItem.text = textFromValue(value, effectiveLocale);
350 if (spinBoxItem.up && spinBoxItem.up.indicator)
351 spinBoxItem.up.indicator.enabled = (wrap || value < topValue);
352 if (spinBoxItem.down && spinBoxItem.down.indicator)
353 spinBoxItem.down.indicator.enabled = (wrap || value > botValue);
361 setValue(value,
true,
true);
366 onSpinBoxItemChanged: {
368 spinBoxItem.Keys.forwardTo = [control];
371 Component.onCompleted: {
374 if (!setValue(value,
true,
true))
378 onWrapChanged: updateUi()
379 onNotationChanged: updateUi()
380 onTrimExtraZerosChanged: updateUi()
381 onShowGroupSeparatorChanged: updateUi()
382 onEffectiveLocaleChanged: updateUi()
383 Keys.onPressed: handleKeyEvent(
event)
386 target: control.spinBoxItem ? control.spinBoxItem.up :
null 387 onPressedChanged: control.toggleButtonPress(control.spinBoxItem.up.pressed,
true)
391 target: control.spinBoxItem ? control.spinBoxItem.down :
null 392 onPressedChanged: control.toggleButtonPress(control.spinBoxItem.down.pressed,
false)
396 target: control.textInputItem
398 onActiveFocusChanged: {
399 if (!control.textInputItem.activeFocus)
400 control.updateValueFromText();
406 target: control.spinBoxItem
407 when: control.spinBoxItem && typeof control.spinBoxItem.wrap !==
"undefined" 413 target: control.textInputItem
415 value: control.selectByMouse
419 target: control.textInputItem
421 value: control.inputMask
427 property bool delay:
true 428 property bool increment:
true 429 interval: delay ? control.buttonRepeatDelay : control.buttonRepeatInterval
431 onRunningChanged: delay =
true 444 anchors.fill: control
445 z: control.contentItem.z + 1
446 acceptedButtons: Qt.NoButton
447 enabled: control.wheelEnabled
449 var delta = (wheel.angleDelta.y === 0.0 ? -wheel.angleDelta.x : wheel.angleDelta.y) / 120;
452 if (wheel.modifiers & Qt.ControlModifier)
453 delta *= control.pageSteps;
454 control.stepBy(delta);
virtual bool event(QEvent *e)
QVariant property(const char *name) const const
QString objectName() const const