9#include <QtCore/qscopedpointer.h>
10#include <QtQuick/private/qquickwindow_p.h>
11#include <QtQuickTemplates2/private/qtquicktemplates2math_p.h>
16
17
18
19
20
21
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
67 Q_DECLARE_PUBLIC(QQuickRangeSliderNode)
77 void setPosition(qreal position,
bool ignoreOtherPosition =
false);
98 return this ==
get(slider->first());
103 Q_Q(QQuickRangeSliderNode);
109 if (!slider->isCrossingEnabled() && !ignoreOtherPosition) {
110 min = isFirst() ? 0.0 : qMax<qreal>(0.0, slider->first()->position());
111 max = !isFirst() ? 1.0 : qMin<qreal>(1.0, slider->second()->position());
114 position = qBound(min, position, max);
115 if (!qFuzzyCompare(
this->position, position)) {
116 this->position = position;
117 emit q->positionChanged();
118 emit q->visualPositionChanged();
122 if (!ignoreOtherPosition)
123 q->updateHandleCrossing();
129 if (!qFuzzyCompare(slider->from(), slider->to()))
130 pos = (value - slider->from()) / (slider->to() - slider->from());
131 setPosition(pos, ignoreOtherPosition);
136 Q_Q(QQuickRangeSliderNode);
137 quickCancelDeferred(q, handleName());
142 Q_Q(QQuickRangeSliderNode);
143 if (handle.wasExecuted())
146 if (!handle || complete)
147 quickBeginDeferred(q, handleName(), handle);
149 quickCompleteDeferred(q, handleName(), handle);
154 return node->d_func();
157QQuickRangeSliderNode::QQuickRangeSliderNode(qreal value, QQuickRangeSlider *slider)
158 : QObject(*(
new QQuickRangeSliderNodePrivate(value, slider)), slider)
162QQuickRangeSliderNode::~QQuickRangeSliderNode()
166qreal QQuickRangeSliderNode::value()
const
168 Q_D(
const QQuickRangeSliderNode);
172void QQuickRangeSliderNode::setValue(qreal value)
174 Q_D(QQuickRangeSliderNode);
175 if (!d->slider->isComponentComplete()) {
176 d->pendingValue = value;
177 d->isPendingValue =
true;
182 const qreal smaller = qMin(d->slider->to(), d->slider->from());
183 const qreal larger = qMax(d->slider->to(), d->slider->from());
184 value = qBound(smaller, value, larger);
189 if (!d->slider->isCrossingEnabled()) {
190 const bool invertedRange = d->slider->from() > d->slider->to();
193 if (value < d->slider->second()->value())
194 value = d->slider->second()->value();
196 if (value > d->slider->second()->value())
197 value = d->slider->second()->value();
201 if (value > d->slider->first()->value())
202 value = d->slider->first()->value();
204 if (value < d->slider->first()->value())
205 value = d->slider->first()->value();
210 if (!qFuzzyCompare(d->value, value)) {
214 d->slider->effectiveValueChange(
this);
215 d->slider->updateFocusOrder();
219 updateHandleCrossing();
222qreal QQuickRangeSliderNode::position()
const
224 Q_D(
const QQuickRangeSliderNode);
228qreal QQuickRangeSliderNode::visualPosition()
const
230 Q_D(
const QQuickRangeSliderNode);
231 if (d->slider->orientation() == Qt::Vertical || d->slider->isMirrored())
232 return 1.0 - d->position;
236QQuickItem *QQuickRangeSliderNode::handle()
const
238 QQuickRangeSliderNodePrivate *d =
const_cast<QQuickRangeSliderNodePrivate *>(d_func());
244void QQuickRangeSliderNode::setHandle(QQuickItem *handle)
246 Q_D(QQuickRangeSliderNode);
247 if (d->handle == handle)
250 QQuickControlPrivate::warnIfCustomizationNotSupported(d->slider, handle, QStringLiteral(
"handle"));
252 if (!d->handle.isExecuting())
255 const qreal oldImplicitHandleWidth = implicitHandleWidth();
256 const qreal oldImplicitHandleHeight = implicitHandleHeight();
258 QQuickControlPrivate::get(d->slider)->removeImplicitSizeListener(d->handle);
259 QQuickControlPrivate::hideOldItem(d->handle);
263 if (!handle->parentItem())
264 handle->setParentItem(d->slider);
266 d->slider->updateFocusOrder();
268 handle->setActiveFocusOnTab(
true);
269 QQuickControlPrivate::get(d->slider)->addImplicitSizeListener(handle);
272 if (!qFuzzyCompare(oldImplicitHandleWidth, implicitHandleWidth()))
273 emit implicitHandleWidthChanged();
274 if (!qFuzzyCompare(oldImplicitHandleHeight, implicitHandleHeight()))
275 emit implicitHandleHeightChanged();
276 if (!d->handle.isExecuting())
277 emit handleChanged();
280bool QQuickRangeSliderNode::isPressed()
const
282 Q_D(
const QQuickRangeSliderNode);
286void QQuickRangeSliderNode::setPressed(
bool pressed)
288 Q_D(QQuickRangeSliderNode);
289 if (d->pressed == pressed)
292 d->pressed = pressed;
293 d->slider->setAccessibleProperty(
"pressed", pressed || d->slider->second()->isPressed());
294 emit pressedChanged();
297bool QQuickRangeSliderNode::isHovered()
const
299 Q_D(
const QQuickRangeSliderNode);
303void QQuickRangeSliderNode::setHovered(
bool hovered)
305 Q_D(QQuickRangeSliderNode);
306 if (d->hovered == hovered)
309 d->hovered = hovered;
310 emit hoveredChanged();
313qreal QQuickRangeSliderNode::implicitHandleWidth()
const
315 Q_D(
const QQuickRangeSliderNode);
318 return d->handle->implicitWidth();
321qreal QQuickRangeSliderNode::implicitHandleHeight()
const
323 Q_D(
const QQuickRangeSliderNode);
326 return d->handle->implicitHeight();
329void QQuickRangeSliderNode::increase()
331 Q_D(QQuickRangeSliderNode);
332 qreal step = qFuzzyIsNull(d->slider->stepSize()) ? 0.1 : d->slider->stepSize();
333 setValue(d->value + step);
336void QQuickRangeSliderNode::decrease()
338 Q_D(QQuickRangeSliderNode);
339 qreal step = qFuzzyIsNull(d->slider->stepSize()) ? 0.1 : d->slider->stepSize();
340 setValue(d->value - step);
343void QQuickRangeSliderNode::updateHandleCrossing()
345 Q_D(QQuickRangeSliderNode);
346 d->slider->updateHandleCrossing();
354 Q_DECLARE_PUBLIC(QQuickRangeSlider)
361#if QT_CONFIG(quicktemplates2_multitouch)
365 bool handleMove(
const QPointF &point, ulong timestamp)
override;
386 QQuickRangeSliderNode *
first =
nullptr;
399 qreal value = slider->from() + (slider->to() - slider->from()) * position;
402 if (QQuickRangeSliderPrivate::get(slider)->allValuesAreInteger)
403 value = qRound(value);
410 const qreal range = slider->to() - slider->from();
411 if (qFuzzyIsNull(range))
414 const qreal effectiveStep = slider->stepSize() / range;
415 if (qFuzzyIsNull(effectiveStep))
418 return qRound(position / effectiveStep) * effectiveStep;
421static qreal positionAt(
const QQuickRangeSlider *slider, QQuickItem *handle,
const QPointF &point)
423 if (slider->orientation() == Qt::Horizontal) {
424 const qreal hw = handle ? handle->width() : 0;
425 const qreal offset = hw / 2;
426 const qreal extent = slider->availableWidth() - hw;
427 if (!qFuzzyIsNull(extent)) {
428 if (slider->isMirrored())
429 return (slider->width() - point.x() - slider->rightPadding() - offset) / extent;
430 return (point.x() - slider->leftPadding() - offset) / extent;
433 const qreal hh = handle ? handle->height() : 0;
434 const qreal offset = hh / 2;
435 const qreal extent = slider->availableHeight() - hh;
436 if (!qFuzzyIsNull(extent))
437 return (slider->height() - point.y() - slider->bottomPadding() - offset) / extent;
444 return slider->d_func();
460 const bool invertedRange = from > to;
461 const qreal firstValue =
first->value();
462 const qreal secondValue =
second->value();
465 return firstValue < secondValue;
467 return firstValue > secondValue;
484 Q_Q(QQuickRangeSlider);
487 emit q->handlesCrossedChanged();
490 emit q->effectiveFirstValueChanged();
491 emit q->effectiveSecondValueChanged();
494#if QT_CONFIG(quicktemplates2_multitouch)
495bool QQuickRangeSliderPrivate::acceptTouch(
const QTouchEvent::TouchPoint &point)
497 int firstId = QQuickRangeSliderNodePrivate::get(first)->touchId;
498 int secondId = QQuickRangeSliderNodePrivate::get(second)->touchId;
500 if (((firstId == -1 || secondId == -1) && point.state() == QEventPoint::Pressed) || point.id() == firstId || point.id() == secondId) {
501 touchId = point.id();
511 Q_Q(QQuickRangeSlider);
512 QQuickControlPrivate::handlePress(point, timestamp);
515 QQuickItem *firstHandle =
first->handle();
516 QQuickItem *secondHandle =
second->handle();
517 const bool firstHit = firstHandle && !
first->isPressed() && firstHandle->contains(q->mapToItem(firstHandle, point));
518 const bool secondHit = secondHandle && !
second->isPressed() && secondHandle->contains(q->mapToItem(secondHandle, point));
519 QQuickRangeSliderNode *hitNode =
nullptr;
520 QQuickRangeSliderNode *otherNode =
nullptr;
522 if (firstHit && secondHit) {
524 hitNode = firstHandle->z() > secondHandle->z() ?
first :
second;
525 otherNode = firstHandle->z() > secondHandle->z() ?
second :
first;
526 }
else if (firstHit) {
529 }
else if (secondHit) {
534 const qreal firstPos = positionAt(q, firstHandle, point);
535 const qreal secondPos = positionAt(q, secondHandle, point);
536 const qreal firstDistance = qAbs(firstPos -
first->position());
537 const qreal secondDistance = qAbs(secondPos -
second->position());
539 if (qFuzzyCompare(firstDistance, secondDistance)) {
541 const bool inverted = from > to;
542 if ((!inverted && firstPos <
first->position()) || (inverted && firstPos >
first->position())) {
549 }
else if (firstDistance < secondDistance) {
559 hitNode->setPressed(
true);
560 if (QQuickItem *handle = hitNode->handle()) {
565 if (focusPolicy & Qt::ClickFocus)
566 handle->forceActiveFocus(Qt::MouseFocusReason);
568 QQuickRangeSliderNodePrivate::get(hitNode)->touchId = touchId;
571 if (QQuickItem *handle = otherNode->handle())
579 Q_Q(QQuickRangeSlider);
580 QQuickControlPrivate::handleMove(point, timestamp);
583 const qreal oldPos = pressedNode->position();
584 qreal pos = positionAt(q, pressedNode->handle(), point);
585 if (snapMode == QQuickRangeSlider::SnapAlways)
586 pos = snapPosition(q, pos);
588 pressedNode->setValue(valueAt(q, pos));
592 if (!qFuzzyCompare(pressedNode->position(), oldPos))
593 emit pressedNode->moved();
600 Q_Q(QQuickRangeSlider);
601 QQuickControlPrivate::handleRelease(point, timestamp);
602 pressPoint = QPointF();
609 const qreal oldPos = pressedNode->position();
610 qreal pos = positionAt(q, pressedNode->handle(), point);
611 if (snapMode != QQuickRangeSlider::NoSnap)
612 pos = snapPosition(q, pos);
613 qreal val = valueAt(q, pos);
614 if (!qFuzzyCompare(val, pressedNode->value()))
615 pressedNode->setValue(val);
616 else if (snapMode != QQuickRangeSlider::NoSnap)
617 pressedNodePrivate->setPosition(pos);
618 q->setKeepMouseGrab(
false);
619 q->setKeepTouchGrab(
false);
621 if (!qFuzzyCompare(pressedNode->position(), oldPos))
622 emit pressedNode->moved();
624 pressedNode->setPressed(
false);
631 QQuickControlPrivate::handleUngrab();
632 pressPoint = QPointF();
633 first->setPressed(
false);
634 second->setPressed(
false);
641 Q_Q(QQuickRangeSlider);
642 QQuickItem *firstHandle =
first->handle();
643 QQuickItem *secondHandle =
second->handle();
644 bool firstHandleHovered = firstHandle && firstHandle->isEnabled()
645 && firstHandle->contains(q->mapToItem(firstHandle, pos));
646 bool secondHandleHovered = secondHandle && secondHandle->isEnabled()
647 && secondHandle->contains(q->mapToItem(secondHandle, pos));
649 if (firstHandleHovered && secondHandleHovered) {
651 const bool firstHandleHasHigherZ = firstHandle->z() > secondHandle->z();
652 firstHandleHovered = firstHandleHasHigherZ;
653 secondHandleHovered = !firstHandleHasHigherZ;
655 first->setHovered(firstHandleHovered);
656 second->setHovered(secondHandleHovered);
661 QQuickControlPrivate::itemImplicitWidthChanged(item);
662 if (item ==
first->handle())
663 emit first->implicitHandleWidthChanged();
664 else if (item ==
second->handle())
665 emit second->implicitHandleWidthChanged();
670 QQuickControlPrivate::itemImplicitHeightChanged(item);
671 if (item ==
first->handle())
672 emit first->implicitHandleHeightChanged();
673 else if (item ==
second->handle())
674 emit second->implicitHandleHeightChanged();
679 QQuickControlPrivate::itemDestroyed(item);
680 if (item ==
first->handle())
681 first->setHandle(
nullptr);
682 else if (item ==
second->handle())
683 second->setHandle(
nullptr);
688 allValuesAreInteger = areRepresentableAsInteger(to, from, stepSize) && stepSize != 0.0;
691QQuickRangeSlider::QQuickRangeSlider(QQuickItem *parent)
692 : QQuickControl(*(
new QQuickRangeSliderPrivate), parent)
694 Q_D(QQuickRangeSlider);
695 d->first =
new QQuickRangeSliderNode(0.0,
this);
696 d->second =
new QQuickRangeSliderNode(1.0,
this);
697 d->setSizePolicy(QLayoutPolicy::Expanding, QLayoutPolicy::Fixed);
699 setFlag(QQuickItem::ItemIsFocusScope);
701 setFocusPolicy(Qt::TabFocus);
703 setFocusPolicy(Qt::StrongFocus);
705 setAcceptedMouseButtons(Qt::LeftButton);
706#if QT_CONFIG(quicktemplates2_multitouch)
707 setAcceptTouchEvents(
true);
710 setCursor(Qt::ArrowCursor);
714QQuickRangeSlider::~QQuickRangeSlider()
716 Q_D(QQuickRangeSlider);
717 d->removeImplicitSizeListener(d->first->handle());
718 d->removeImplicitSizeListener(d->second->handle());
722
723
724
725
726
727
728qreal QQuickRangeSlider::from()
const
730 Q_D(
const QQuickRangeSlider);
734void QQuickRangeSlider::setFrom(qreal from)
736 Q_D(QQuickRangeSlider);
737 if (qFuzzyCompare(d->from, from))
742 d->updateAllValuesAreInteger();
744 if (isComponentComplete()) {
745 d->first->setValue(d->first->value());
746 d->second->setValue(d->second->value());
747 auto *firstPrivate = QQuickRangeSliderNodePrivate::get(d->first);
748 auto *secondPrivate = QQuickRangeSliderNodePrivate::get(d->second);
749 firstPrivate->updatePosition(
true);
750 secondPrivate->updatePosition();
755
756
757
758
759
760
761qreal QQuickRangeSlider::to()
const
763 Q_D(
const QQuickRangeSlider);
767void QQuickRangeSlider::setTo(qreal to)
769 Q_D(QQuickRangeSlider);
770 if (qFuzzyCompare(d->to, to))
775 d->updateAllValuesAreInteger();
777 if (isComponentComplete()) {
778 d->first->setValue(d->first->value());
779 d->second->setValue(d->second->value());
780 auto *firstPrivate = QQuickRangeSliderNodePrivate::get(d->first);
781 auto *secondPrivate = QQuickRangeSliderNodePrivate::get(d->second);
782 firstPrivate->updatePosition(
true);
783 secondPrivate->updatePosition();
788
789
790
791
792
793
794
795
796
797
798qreal QQuickRangeSlider::touchDragThreshold()
const
800 Q_D(
const QQuickRangeSlider);
801 return d->touchDragThreshold;
804void QQuickRangeSlider::setTouchDragThreshold(qreal touchDragThreshold)
806 Q_D(QQuickRangeSlider);
807 if (d->touchDragThreshold == touchDragThreshold)
810 d->touchDragThreshold = touchDragThreshold;
811 emit touchDragThresholdChanged();
814void QQuickRangeSlider::resetTouchDragThreshold()
816 setTouchDragThreshold(-1);
820
821
822
823
824
825
826
827qreal QQuickRangeSlider::valueAt(qreal position)
const
829 Q_D(
const QQuickRangeSlider);
830 const qreal value = (d->to - d->from) * position;
831 if (qFuzzyIsNull(d->stepSize))
832 return d->from + value;
833 return d->from + qRound(value / d->stepSize) * d->stepSize;
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855bool QQuickRangeSlider::isCrossingEnabled()
const
857 Q_D(
const QQuickRangeSlider);
858 return d->crossingEnabled;
861void QQuickRangeSlider::setCrossingEnabled(
bool enabled)
863 Q_D(QQuickRangeSlider);
864 if (d->crossingEnabled == enabled)
867 d->crossingEnabled = enabled;
870 if (!enabled && d->handlesCrossed) {
871 if (d->shouldHandlesCross()) {
872 qreal temp = d->first->value();
873 d->first->setValue(d->second->value());
874 d->second->setValue(temp);
880 emit crossingEnabledChanged();
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899bool QQuickRangeSlider::handlesCrossed()
const
901 Q_D(
const QQuickRangeSlider);
902 return d->handlesCrossed;
905void QQuickRangeSlider::updateHandleCrossing()
907 Q_D(QQuickRangeSlider);
908 if (d->crossingEnabled)
909 d->updateHandleCrossing();
912void QQuickRangeSlider::effectiveValueChange(QQuickRangeSliderNode* node)
914 Q_D(QQuickRangeSlider);
915 if (node == d->first) {
918 if (d->handlesCrossed)
919 emit effectiveSecondValueChanged();
921 emit effectiveFirstValueChanged();
922 }
else if (node == d->second) {
925 if (d->handlesCrossed)
926 emit effectiveFirstValueChanged();
928 emit effectiveSecondValueChanged();
932void QQuickRangeSlider::updateFocusOrder()
934 Q_D(QQuickRangeSlider);
935 QQuickItem *firstHandle = QQuickRangeSliderNodePrivate::get(d->first)->handle;
936 QQuickItem *secondHandle = QQuickRangeSliderNodePrivate::get(d->second)->handle;
937 if (firstHandle && secondHandle) {
941 const QList<QQuickItem *> childItems =
this->childItems();
942 const int firstIndex = childItems.indexOf(firstHandle);
943 const int secondIndex = childItems.indexOf(secondHandle);
944 if (firstIndex != -1 && secondIndex != -1) {
945 if (!d->handlesCrossed && firstIndex > secondIndex) {
946 firstHandle->stackBefore(secondHandle);
950 secondHandle->setZ(firstHandle->z() + 1);
951 }
else if (d->handlesCrossed && firstIndex < secondIndex) {
952 secondHandle->stackBefore(firstHandle);
956 firstHandle->setZ(secondHandle->z() + 1);
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977qreal QQuickRangeSlider::effectiveFirstValue()
const
979 Q_D(
const QQuickRangeSlider);
982 return d->handlesCrossed ? (d->second ? d->second->value() : 1.0)
983 : (d->first ? d->first->value() : 0.0);
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001qreal QQuickRangeSlider::effectiveSecondValue()
const
1003 Q_D(
const QQuickRangeSlider);
1006 return d->handlesCrossed ? (d->first ? d->first->value() : 0.0)
1007 : (d->second ? d->second->value() : 1.0);
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071QQuickRangeSliderNode *QQuickRangeSlider::first()
const
1073 Q_D(
const QQuickRangeSlider);
1078
1079
1080
1081
1082
1083
1084
1085
1086
1089
1090
1091
1092
1093
1094
1095
1096
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159QQuickRangeSliderNode *QQuickRangeSlider::second()
const
1161 Q_D(
const QQuickRangeSlider);
1166
1167
1168
1169
1170
1171
1172qreal QQuickRangeSlider::stepSize()
const
1174 Q_D(
const QQuickRangeSlider);
1178void QQuickRangeSlider::setStepSize(qreal step)
1180 Q_D(QQuickRangeSlider);
1181 if (qFuzzyCompare(d->stepSize, step))
1185 emit stepSizeChanged();
1186 d->updateAllValuesAreInteger();
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207QQuickRangeSlider::SnapMode QQuickRangeSlider::snapMode()
const
1209 Q_D(
const QQuickRangeSlider);
1213void QQuickRangeSlider::setSnapMode(SnapMode mode)
1215 Q_D(QQuickRangeSlider);
1216 if (d->snapMode == mode)
1220 emit snapModeChanged();
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234Qt::Orientation QQuickRangeSlider::orientation()
const
1236 Q_D(
const QQuickRangeSlider);
1237 return d->orientation;
1240void QQuickRangeSlider::setOrientation(Qt::Orientation orientation)
1242 Q_D(QQuickRangeSlider);
1243 if (d->orientation == orientation)
1246 if (orientation == Qt::Horizontal)
1247 d->setSizePolicy(QLayoutPolicy::Expanding, QLayoutPolicy::Fixed);
1249 d->setSizePolicy(QLayoutPolicy::Fixed, QLayoutPolicy::Expanding);
1251 d->orientation = orientation;
1252 emit orientationChanged();
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273void QQuickRangeSlider::setValues(qreal firstValue, qreal secondValue)
1275 Q_D(QQuickRangeSlider);
1277 const qreal smaller = qMin(d->to, d->from);
1278 const qreal larger = qMax(d->to, d->from);
1279 firstValue = qBound(smaller, firstValue, larger);
1280 secondValue = qBound(smaller, secondValue, larger);
1283 if (!d->crossingEnabled) {
1284 if (d->from > d->to) {
1287 if (secondValue > firstValue)
1288 secondValue = firstValue;
1291 if (firstValue > secondValue)
1292 firstValue = secondValue;
1297 QQuickRangeSliderNodePrivate *firstPrivate = QQuickRangeSliderNodePrivate::get(d->first);
1298 if (firstValue != firstPrivate->value) {
1299 firstPrivate->value = firstValue;
1300 emit d->first->valueChanged();
1303 QQuickRangeSliderNodePrivate *secondPrivate = QQuickRangeSliderNodePrivate::get(d->second);
1304 if (secondValue != secondPrivate->value) {
1305 secondPrivate->value = secondValue;
1306 emit d->second->valueChanged();
1311 firstPrivate->updatePosition(
true);
1312 secondPrivate->updatePosition();
1315 if (d->crossingEnabled)
1316 d->updateHandleCrossing();
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330bool QQuickRangeSlider::live()
const
1332 Q_D(
const QQuickRangeSlider);
1336void QQuickRangeSlider::setLive(
bool live)
1338 Q_D(QQuickRangeSlider);
1339 if (d->live == live)
1347
1348
1349
1350
1351
1352
1353
1354
1355bool QQuickRangeSlider::isHorizontal()
const
1357 Q_D(
const QQuickRangeSlider);
1358 return d->orientation == Qt::Horizontal;
1362
1363
1364
1365
1366
1367
1368
1369
1370bool QQuickRangeSlider::isVertical()
const
1372 Q_D(
const QQuickRangeSlider);
1373 return d->orientation == Qt::Vertical;
1376void QQuickRangeSlider::focusInEvent(QFocusEvent *event)
1378 Q_D(QQuickRangeSlider);
1379 QQuickControl::focusInEvent(event);
1385 QQuickItem *handle = nextItemInFocusChain();
1388 if (!handle || handle ==
this)
1389 handle = !d->handlesCrossed ? d->first->handle() : d->second->handle();
1391 handle->forceActiveFocus(event->reason());
1394void QQuickRangeSlider::keyPressEvent(QKeyEvent *event)
1396 Q_D(QQuickRangeSlider);
1397 QQuickControl::keyPressEvent(event);
1399 QQuickRangeSliderNode *focusNode = d->first->handle()->hasActiveFocus()
1400 ? d->first : (d->second->handle()->hasActiveFocus() ? d->second :
nullptr);
1404 const qreal oldValue = focusNode->value();
1405 if (d->orientation == Qt::Horizontal) {
1406 if (event->key() == Qt::Key_Left) {
1407 focusNode->setPressed(
true);
1409 focusNode->increase();
1411 focusNode->decrease();
1413 }
else if (event->key() == Qt::Key_Right) {
1414 focusNode->setPressed(
true);
1416 focusNode->decrease();
1418 focusNode->increase();
1422 if (event->key() == Qt::Key_Up) {
1423 focusNode->setPressed(
true);
1424 focusNode->increase();
1426 }
else if (event->key() == Qt::Key_Down) {
1427 focusNode->setPressed(
true);
1428 focusNode->decrease();
1432 if (!qFuzzyCompare(focusNode->value(), oldValue))
1433 emit focusNode->moved();
1436void QQuickRangeSlider::hoverEnterEvent(QHoverEvent *event)
1438 Q_D(QQuickRangeSlider);
1439 QQuickControl::hoverEnterEvent(event);
1440 d->updateHover(event->position());
1444void QQuickRangeSlider::hoverMoveEvent(QHoverEvent *event)
1446 Q_D(QQuickRangeSlider);
1447 QQuickControl::hoverMoveEvent(event);
1448 d->updateHover(event->position());
1452void QQuickRangeSlider::hoverLeaveEvent(QHoverEvent *event)
1454 Q_D(QQuickRangeSlider);
1455 QQuickControl::hoverLeaveEvent(event);
1456 d->first->setHovered(
false);
1457 d->second->setHovered(
false);
1461void QQuickRangeSlider::keyReleaseEvent(QKeyEvent *event)
1463 Q_D(QQuickRangeSlider);
1464 QQuickControl::keyReleaseEvent(event);
1465 d->first->setPressed(
false);
1466 d->second->setPressed(
false);
1469void QQuickRangeSlider::mousePressEvent(QMouseEvent *event)
1471 Q_D(QQuickRangeSlider);
1472 QQuickControl::mousePressEvent(event);
1473 d->handleMove(event->position(), event->timestamp());
1474 setKeepMouseGrab(
true);
1477#if QT_CONFIG(quicktemplates2_multitouch)
1478void QQuickRangeSlider::touchEvent(QTouchEvent *event)
1480 Q_D(QQuickRangeSlider);
1481 switch (event->type()) {
1482 case QEvent::TouchUpdate:
1483 for (
const QTouchEvent::TouchPoint &point : event->points()) {
1484 if (!d->acceptTouch(point))
1487 switch (point.state()) {
1488 case QEventPoint::Pressed:
1489 d->handlePress(point.position(), event->timestamp());
1491 case QEventPoint::Updated:
1492 if (!keepTouchGrab()) {
1493 if (d->orientation == Qt::Horizontal) {
1494 setKeepTouchGrab(QQuickDeliveryAgentPrivate::dragOverThreshold(point.position().x() - point.pressPosition().x(),
1495 Qt::XAxis, point, qRound(d->touchDragThreshold)));
1497 setKeepTouchGrab(QQuickDeliveryAgentPrivate::dragOverThreshold(point.position().y() - point.pressPosition().y(),
1498 Qt::YAxis, point, qRound(d->touchDragThreshold)));
1501 if (keepTouchGrab())
1502 d->handleMove(point.position(), event->timestamp());
1504 case QEventPoint::Released:
1505 d->handleRelease(point.position(), event->timestamp());
1514 QQuickControl::touchEvent(event);
1520void QQuickRangeSlider::mirrorChange()
1522 Q_D(QQuickRangeSlider);
1523 QQuickControl::mirrorChange();
1524 emit d->first->visualPositionChanged();
1525 emit d->second->visualPositionChanged();
1528void QQuickRangeSlider::classBegin()
1530 Q_D(QQuickRangeSlider);
1531 QQuickControl::classBegin();
1533 QQmlContext *context = qmlContext(
this);
1535 QQmlEngine::setContextForObject(d->first, context);
1536 QQmlEngine::setContextForObject(d->second, context);
1540void QQuickRangeSlider::componentComplete()
1542 Q_D(QQuickRangeSlider);
1543 QQuickRangeSliderNodePrivate *firstPrivate = QQuickRangeSliderNodePrivate::get(d->first);
1544 QQuickRangeSliderNodePrivate *secondPrivate = QQuickRangeSliderNodePrivate::get(d->second);
1545 firstPrivate->executeHandle(
true);
1546 secondPrivate->executeHandle(
true);
1548 QQuickControl::componentComplete();
1550 if (firstPrivate->isPendingValue || secondPrivate->isPendingValue
1551 || !qFuzzyCompare(d->from, defaultFrom) || !qFuzzyCompare(d->to, defaultTo)) {
1555 setValues(firstPrivate->isPendingValue ? firstPrivate->pendingValue : firstPrivate->value,
1556 secondPrivate->isPendingValue ? secondPrivate->pendingValue : secondPrivate->value);
1558 firstPrivate->pendingValue = 0;
1559 firstPrivate->isPendingValue =
false;
1560 secondPrivate->pendingValue = 0;
1561 secondPrivate->isPendingValue =
false;
1567 firstPrivate->updatePosition();
1568 secondPrivate->updatePosition();
1571 d->updateAllValuesAreInteger();
1575
1576
1577
1578
1579
1580
1583
1584
1585
1586
1587
1588
1591
1592
1593
1594
1595
1596
1599
1600
1601
1602
1603
1604
1606#if QT_CONFIG(accessibility)
1607QAccessible::Role QQuickRangeSlider::accessibleRole()
const
1609 return QAccessible::Slider;
1615#include "moc_qquickrangeslider_p.cpp"
Used to select a range of values by sliding two handles along a track.
void setPosition(qreal position, bool ignoreOtherPosition=false)
void executeHandle(bool complete=false)
static QQuickRangeSliderNodePrivate * get(QQuickRangeSliderNode *node)
QQuickDeferredPointer< QQuickItem > handle
QQuickRangeSlider * slider
void updatePosition(bool ignoreOtherPosition=false)
bool shouldHandlesCross() const
void updateAllValuesAreInteger()
bool handleMove(const QPointF &point, ulong timestamp) override
Qt::Orientation orientation
void itemDestroyed(QQuickItem *item) override
void handleUngrab() override
bool handleRelease(const QPointF &point, ulong timestamp) override
QQuickRangeSliderNode * pressedNode(int touchId=-1) const
QQuickRangeSliderNode * first
void itemImplicitHeightChanged(QQuickItem *item) override
bool handlePress(const QPointF &point, ulong timestamp) override
void updateHover(const QPointF &pos)
QQuickRangeSliderNode * second
void updateHandleCrossing()
void itemImplicitWidthChanged(QQuickItem *item) override
Combined button and popup list for selecting options.
static const qreal defaultFrom
static const qreal defaultTo
static qreal valueAt(const QQuickRangeSlider *slider, qreal position)
static qreal positionAt(const QQuickRangeSlider *slider, QQuickItem *handle, const QPointF &point)
static qreal snapPosition(const QQuickRangeSlider *slider, qreal position)