7#include <private/qquickcontrol_p_p.h>
8#include <private/qquickindicatorbutton_p.h>
9#include <private/qquicktextinput_p.h>
11#include <private/qqmlengine_p.h>
13#include <QtQml/qqmlinfo.h>
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
69
70
71
72
73
74
75
76
77
81 Q_DECLARE_PUBLIC(QQuickSpinBox)
86 bool setValue(
int value,
bool wrap,
bool modified);
87 bool stepBy(
int steps,
bool modified);
108 bool handleMove(
const QPointF &point, ulong timestamp)
override;
131 QQuickIndicatorButton *
up =
nullptr;
132 QQuickIndicatorButton *
down =
nullptr;
133#if QT_CONFIG(validator)
143 bool inverted =
from >
to;
145 return inverted ? qBound(
to, value,
from) : qBound(
from, value,
to);
147 int f = inverted ?
to :
from;
148 int t = inverted ?
from :
to;
160 QVariant text = contentItem->property(
"text");
161 if (text.isValid()) {
162 setValue(evaluateValueFromText(text.toString()),
false,
true);
174 int correctedValue = newValue;
175 if (q->isComponentComplete())
176 correctedValue = boundValue(newValue, allowWrap);
178 if (!modified && newValue == correctedValue && newValue ==
value)
181 const bool emitSignals = (
value != correctedValue);
182 value = correctedValue;
191 emit q->valueChanged();
193 emit q->valueModified();
220 setDisplayText(evaluateTextFromValue(value));
227 if (displayText == text)
231 emit q->displayTextChanged();
238 QQuickTextInput *inputTextItem = qobject_cast<QQuickTextInput *>(q->contentItem());
241 QString text = inputTextItem->text();
242#if QT_CONFIG(validator)
243 if (validator && live)
244 validator->fixup(text);
248 const int enteredVal = evaluateValueFromText(text);
249 const int correctedValue = boundValue(enteredVal,
false);
250 if (correctedValue == enteredVal && correctedValue !=
value) {
253 q->setValue(correctedValue);
258 setDisplayText(text);
263 const QQuickItem *upIndicator =
up->indicator();
264 return upIndicator && upIndicator->isEnabled();
269 QQuickItem *upIndicator =
up->indicator();
278 const QQuickItem *downIndicator =
down->indicator();
279 return downIndicator && downIndicator->isEnabled();
284 QQuickItem *downIndicator =
down->indicator();
294 QQuickItem *ui =
up->indicator();
295 QQuickItem *di =
down->indicator();
296 up->setHovered(ui && ui->isEnabled() && ui->contains(q->mapToItem(ui, pos)));
297 down->setHovered(di && di->isEnabled() && di->contains(q->mapToItem(di, pos)));
304 delayTimer = q->startTimer(AUTO_REPEAT_DELAY);
311 repeatTimer = q->startTimer(AUTO_REPEAT_INTERVAL);
318 q->killTimer(delayTimer);
322 q->killTimer(repeatTimer);
330 QQuickControlPrivate::handlePress(point, timestamp);
331 QQuickItem *ui =
up->indicator();
332 QQuickItem *di =
down->indicator();
333 up->setPressed(ui && ui->isEnabled() && ui->contains(ui->mapFromItem(q, point)));
334 down->setPressed(di && di->isEnabled() && di->contains(di->mapFromItem(q, point)));
336 bool pressed =
up->isPressed() ||
down->isPressed();
337 q->setAccessibleProperty(
"pressed", pressed);
346 QQuickControlPrivate::handleMove(point, timestamp);
347 QQuickItem *upIndicator =
up->indicator();
348 const bool upIndicatorContainsPoint = upIndicator && upIndicator->isEnabled()
349 && upIndicator->contains(upIndicator->mapFromItem(q, point));
350 up->setHovered(touchId == -1 && upIndicatorContainsPoint);
351 up->setPressed(upIndicatorContainsPoint);
353 QQuickItem *downIndicator =
down->indicator();
354 const bool downIndicatorContainsPoint = downIndicator && downIndicator->isEnabled()
355 && downIndicator->contains(downIndicator->mapFromItem(q, point));
356 down->setHovered(touchId == -1 && downIndicatorContainsPoint);
357 down->setPressed(downIndicatorContainsPoint);
359 bool pressed =
up->isPressed() ||
down->isPressed();
360 q->setAccessibleProperty(
"pressed", pressed);
369 QQuickControlPrivate::handleRelease(point, timestamp);
370 QQuickItem *ui =
up->indicator();
371 QQuickItem *di =
down->indicator();
373 int oldValue =
value;
374 if (
up->isPressed()) {
375 if (repeatTimer <= 0 && ui && ui->contains(ui->mapFromItem(q, point)))
379 up->setPressed(
false);
380 }
else if (
down->isPressed()) {
381 if (repeatTimer <= 0 && di && di->contains(di->mapFromItem(q, point)))
383 down->setPressed(
false);
385 if (
value != oldValue)
386 emit q->valueModified();
388 q->setAccessibleProperty(
"pressed",
false);
396 QQuickControlPrivate::handleUngrab();
397 up->setPressed(
false);
398 down->setPressed(
false);
400 q->setAccessibleProperty(
"pressed",
false);
406 QQuickControlPrivate::itemImplicitWidthChanged(item);
407 if (item ==
up->indicator())
408 emit up->implicitIndicatorWidthChanged();
409 else if (item ==
down->indicator())
410 emit down->implicitIndicatorWidthChanged();
415 QQuickControlPrivate::itemImplicitHeightChanged(item);
416 if (item ==
up->indicator())
417 emit up->implicitIndicatorHeightChanged();
418 else if (item ==
down->indicator())
419 emit down->implicitIndicatorHeightChanged();
424 QQuickControlPrivate::itemDestroyed(item);
425 if (item ==
up->indicator())
426 up->setIndicator(
nullptr);
427 else if (item ==
down->indicator())
428 down->setIndicator(
nullptr);
434 Q_Q(
const QQuickSpinBox);
437 QQmlEngine *engine = qmlEngine(q);
438 if (engine && textFromValue.isCallable()) {
440#if QT_CONFIG(qml_locale)
441 loc = QJSValuePrivate::fromReturnedValue(
442 engine->handle()->fromData(QMetaType::fromType<QLocale>(), &locale));
444 text = textFromValue.call(QJSValueList() << val << loc).toString();
446 text = locale.toString(val);
453 Q_Q(
const QQuickSpinBox);
455 QQmlEngine *engine = qmlEngine(q);
456 if (engine && valueFromText.isCallable()) {
458#if QT_CONFIG(qml_locale)
459 loc = QJSValuePrivate::fromReturnedValue(
460 engine->handle()->fromData(QMetaType::fromType<QLocale>(), &locale));
462 value = valueFromText.call(QJSValueList() << text << loc).toInt();
464 value = locale.toInt(text);
469QQuickSpinBox::QQuickSpinBox(QQuickItem *parent)
470 : QQuickControl(*(
new QQuickSpinBoxPrivate), parent)
473 d->up =
new QQuickIndicatorButton(
this);
474 d->down =
new QQuickIndicatorButton(
this);
475 d->setSizePolicy(QLayoutPolicy::Preferred, QLayoutPolicy::Fixed);
477 setFlag(ItemIsFocusScope);
478 setFiltersChildMouseEvents(
true);
479 setAcceptedMouseButtons(Qt::LeftButton);
481 setCursor(Qt::ArrowCursor);
483#if QT_CONFIG(quicktemplates2_multitouch)
484 setAcceptTouchEvents(
true);
488QQuickSpinBox::~QQuickSpinBox()
491 d->removeImplicitSizeListener(d->up->indicator());
492 d->removeImplicitSizeListener(d->down->indicator());
496
497
498
499
500
501
502int QQuickSpinBox::from()
const
504 Q_D(
const QQuickSpinBox);
508void QQuickSpinBox::setFrom(
int from)
516 if (isComponentComplete()) {
517 if (!d->setValue(d->value,
false,
false)) {
518 d->updateUpEnabled();
519 d->updateDownEnabled();
525
526
527
528
529
530
531int QQuickSpinBox::to()
const
533 Q_D(
const QQuickSpinBox);
537void QQuickSpinBox::setTo(
int to)
545 if (isComponentComplete()) {
546 if (!d->setValue(d->value,
false,
false)) {
547 d->updateUpEnabled();
548 d->updateDownEnabled();
554
555
556
557
558int QQuickSpinBox::value()
const
560 Q_D(
const QQuickSpinBox);
564void QQuickSpinBox::setValue(
int value)
567 d->setValue(value,
false,
false);
571
572
573
574
575
576
577int QQuickSpinBox::stepSize()
const
579 Q_D(
const QQuickSpinBox);
583void QQuickSpinBox::setStepSize(
int step)
586 if (d->stepSize == step)
590 emit stepSizeChanged();
594
595
596
597
598
599
600bool QQuickSpinBox::isEditable()
const
602 Q_D(
const QQuickSpinBox);
606void QQuickSpinBox::setEditable(
bool editable)
609 if (d->editable == editable)
613 if (d->contentItem) {
615 d->contentItem->setCursor(Qt::IBeamCursor);
617 d->contentItem->unsetCursor();
621 d->editable = editable;
622 setAccessibleProperty(
"editable", editable);
623 emit editableChanged();
627
628
629
630
631
632
633
634
635
636
637
638
639
640bool QQuickSpinBox::isLive()
const
642 Q_D(
const QQuickSpinBox);
646void QQuickSpinBox::setLive(
bool live)
656 d->contentItemTextChanged();
661#if QT_CONFIG(validator)
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682QValidator *QQuickSpinBox::validator()
const
684 Q_D(
const QQuickSpinBox);
688void QQuickSpinBox::setValidator(QValidator *validator)
691 if (d->validator == validator)
694 d->validator = validator;
695 emit validatorChanged();
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729QJSValue QQuickSpinBox::textFromValue()
const
731 Q_D(
const QQuickSpinBox);
732 if (!d->textFromValue.isCallable()) {
733 QQmlEngine *engine = qmlEngine(
this);
735 d->textFromValue = engine->evaluate(QStringLiteral(
"(function(value, locale) { return Number(value).toLocaleString(locale, 'f', 0); })"));
737 return d->textFromValue;
740void QQuickSpinBox::setTextFromValue(
const QJSValue &callback)
743 if (!callback.isCallable()) {
744 qmlWarning(
this) <<
"textFromValue must be a callable function";
747 d->textFromValue = callback;
748 emit textFromValueChanged();
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777QJSValue QQuickSpinBox::valueFromText()
const
779 Q_D(
const QQuickSpinBox);
780 if (!d->valueFromText.isCallable()) {
781 QQmlEngine *engine = qmlEngine(
this);
783 d->valueFromText = engine->evaluate(QStringLiteral(
"(function(text, locale) { return Number.fromLocaleString(locale, text); })"));
785 return d->valueFromText;
788void QQuickSpinBox::setValueFromText(
const QJSValue &callback)
791 if (!callback.isCallable()) {
792 qmlWarning(
this) <<
"valueFromText must be a callable function";
795 d->valueFromText = callback;
796 emit valueFromTextChanged();
800
801
802
803
804
805
806
807
808
809
810
811
812
813QQuickIndicatorButton *QQuickSpinBox::up()
const
815 Q_D(
const QQuickSpinBox);
820
821
822
823
824
825
826
827
828
829
830
831
832
833QQuickIndicatorButton *QQuickSpinBox::down()
const
835 Q_D(
const QQuickSpinBox);
840
841
842
843
844
845
846
847
848
849
850Qt::InputMethodHints QQuickSpinBox::inputMethodHints()
const
852 Q_D(
const QQuickSpinBox);
853 return d->inputMethodHints;
856void QQuickSpinBox::setInputMethodHints(Qt::InputMethodHints hints)
859 if (d->inputMethodHints == hints)
862 d->inputMethodHints = hints;
863 emit inputMethodHintsChanged();
867
868
869
870
871
872
873
874
875
876
877bool QQuickSpinBox::isInputMethodComposing()
const
879 Q_D(
const QQuickSpinBox);
880 return d->contentItem && d->contentItem->property(
"inputMethodComposing").toBool();
884
885
886
887
888
889
890
891bool QQuickSpinBox::wrap()
const
893 Q_D(
const QQuickSpinBox);
897void QQuickSpinBox::setWrap(
bool wrap)
904 if (d->value == d->from || d->value == d->to) {
905 d->updateUpEnabled();
906 d->updateDownEnabled();
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926QString QQuickSpinBox::displayText()
const
928 Q_D(
const QQuickSpinBox);
929 return d->displayText;
933
934
935
936
937
938
939void QQuickSpinBox::increase()
946
947
948
949
950
951
952void QQuickSpinBox::decrease()
958void QQuickSpinBox::focusInEvent(QFocusEvent *event)
961 QQuickControl::focusInEvent(event);
964 if (d->editable && d->contentItem && !d->contentItem->hasActiveFocus())
965 d->contentItem->forceActiveFocus(event->reason());
968void QQuickSpinBox::hoverEnterEvent(QHoverEvent *event)
971 QQuickControl::hoverEnterEvent(event);
972 d->updateHover(event->position());
976void QQuickSpinBox::hoverMoveEvent(QHoverEvent *event)
979 QQuickControl::hoverMoveEvent(event);
980 d->updateHover(event->position());
984void QQuickSpinBox::hoverLeaveEvent(QHoverEvent *event)
987 QQuickControl::hoverLeaveEvent(event);
988 d->down->setHovered(
false);
989 d->up->setHovered(
false);
993void QQuickSpinBox::keyPressEvent(QKeyEvent *event)
996 QQuickControl::keyPressEvent(event);
998 switch (event->key()) {
1000 if (d->upEnabled()) {
1003 d->up->setPressed(
true);
1010 if (d->downEnabled()) {
1011 d->down->setPressed(
true);
1021 setAccessibleProperty(
"pressed", d->up->isPressed() || d->down->isPressed());
1024void QQuickSpinBox::keyReleaseEvent(QKeyEvent *event)
1027 QQuickControl::keyReleaseEvent(event);
1029 if (d->editable && (event->key() == Qt::Key_Enter || event->key() == Qt::Key_Return))
1032 d->up->setPressed(
false);
1033 d->down->setPressed(
false);
1034 setAccessibleProperty(
"pressed",
false);
1037void QQuickSpinBox::timerEvent(QTimerEvent *event)
1040 QQuickControl::timerEvent(event);
1041 if (event->timerId() == d->delayTimer) {
1042 d->startPressRepeat();
1043 }
else if (event->timerId() == d->repeatTimer) {
1044 if (d->up->isPressed())
1046 else if (d->down->isPressed())
1051#if QT_CONFIG(wheelevent)
1052void QQuickSpinBox::wheelEvent(QWheelEvent *event)
1055 QQuickControl::wheelEvent(event);
1056 if (d->wheelEnabled) {
1057 const QPointF angle = event->angleDelta();
1058 const qreal delta = (qFuzzyIsNull(angle.y()) ? angle.x() : angle.y()) /
int(QWheelEvent::DefaultDeltasPerStep);
1059 d->stepBy(qRound(d->effectiveStepSize() * delta),
true);
1064void QQuickSpinBox::classBegin()
1067 QQuickControl::classBegin();
1069 QQmlContext *context = qmlContext(
this);
1071 QQmlEngine::setContextForObject(d->up, context);
1072 QQmlEngine::setContextForObject(d->down, context);
1076void QQuickSpinBox::componentComplete()
1079 QQuickIndicatorButtonPrivate::get(d->up)->executeIndicator(
true);
1080 QQuickIndicatorButtonPrivate::get(d->down)->executeIndicator(
true);
1082 QQuickControl::componentComplete();
1083 if (!d->setValue(d->value,
false,
false)) {
1084 d->updateDisplayText();
1085 d->updateUpEnabled();
1086 d->updateDownEnabled();
1090void QQuickSpinBox::itemChange(ItemChange change,
const ItemChangeData &value)
1093 QQuickControl::itemChange(change, value);
1094 if (d->editable && change == ItemActiveFocusHasChanged && !value.boolValue)
1098void QQuickSpinBox::contentItemChange(QQuickItem *newItem, QQuickItem *oldItem)
1101 if (QQuickTextInput *oldInput = qobject_cast<QQuickTextInput *>(oldItem)) {
1102 disconnect(oldInput, &QQuickTextInput::inputMethodComposingChanged,
this, &QQuickSpinBox::inputMethodComposingChanged);
1103 QObjectPrivate::disconnect(oldInput, &QQuickTextInput::textChanged, d, &QQuickSpinBoxPrivate::contentItemTextChanged);
1107 newItem->setActiveFocusOnTab(
true);
1109 newItem->forceActiveFocus(
static_cast<Qt::FocusReason>(d->focusReason));
1110#if QT_CONFIG(cursor)
1112 newItem->setCursor(Qt::IBeamCursor);
1115 if (QQuickTextInput *newInput = qobject_cast<QQuickTextInput *>(newItem)) {
1116 connect(newInput, &QQuickTextInput::inputMethodComposingChanged,
this, &QQuickSpinBox::inputMethodComposingChanged);
1117 QObjectPrivate::connect(newInput, &QQuickTextInput::textChanged, d, &QQuickSpinBoxPrivate::contentItemTextChanged);
1122void QQuickSpinBox::localeChange(
const QLocale &newLocale,
const QLocale &oldLocale)
1125 QQuickControl::localeChange(newLocale, oldLocale);
1126 d->updateDisplayText();
1129QFont QQuickSpinBox::defaultFont()
const
1131 return QQuickTheme::font(QQuickTheme::SpinBox);
1134#if QT_CONFIG(accessibility)
1135QAccessible::Role QQuickSpinBox::accessibleRole()
const
1137 return QAccessible::SpinBox;
1140void QQuickSpinBox::accessibilityActiveChanged(
bool active)
1143 QQuickControl::accessibilityActiveChanged(active);
1146 setAccessibleProperty(
"editable", d->editable);
1152#include "moc_qquickspinbox_p.cpp"
Allows the user to select from a set of preset values.
void contentItemTextChanged()
void handleUngrab() override
int evaluateValueFromText(const QString &text) const
void itemDestroyed(QQuickItem *item) override
QQuickIndicatorButton * down
bool handleMove(const QPointF &point, ulong timestamp) override
bool handleRelease(const QPointF &point, ulong timestamp) override
Qt::InputMethodHints inputMethodHints
void decrease(bool modified)
void itemImplicitWidthChanged(QQuickItem *item) override
bool handlePress(const QPointF &point, ulong timestamp) override
bool stepBy(int steps, bool modified)
int effectiveStepSize() const
bool setValue(int value, bool wrap, bool modified)
void itemImplicitHeightChanged(QQuickItem *item) override
QString evaluateTextFromValue(int val) const
QQuickIndicatorButton * up
void updateHover(const QPointF &pos)
void increase(bool modified)
QPalette defaultPalette() const override
void setDisplayText(const QString &displayText)
static QT_BEGIN_NAMESPACE const int AUTO_REPEAT_DELAY
static const int AUTO_REPEAT_INTERVAL