9#include <QtQuick/private/qquickwindow_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
53
54
55
56
57
58
60class QQuickSliderPrivate :
public QQuickControlPrivate
62 Q_DECLARE_PUBLIC(QQuickSlider)
65 qreal snapPosition(qreal position)
const;
66 qreal positionAt(
const QPointF &point)
const;
67 void setPosition(qreal position);
68 void updatePosition();
70 bool handlePress(
const QPointF &point, ulong timestamp) override;
71 bool handleMove(
const QPointF &point, ulong timestamp) override;
72 bool handleRelease(
const QPointF &point, ulong timestamp) override;
73 void handleUngrab() override;
76 void executeHandle(
bool complete =
false);
78 void itemImplicitWidthChanged(QQuickItem *item) override;
79 void itemImplicitHeightChanged(QQuickItem *item) override;
80 void itemDestroyed(QQuickItem *item) override;
87 qreal touchDragThreshold = -1;
91 Qt::Orientation orientation = Qt::Horizontal;
92 QQuickSlider::SnapMode snapMode = QQuickSlider::NoSnap;
93 QQuickDeferredPointer<QQuickItem> handle;
96qreal QQuickSliderPrivate::snapPosition(qreal position)
const
98 const qreal range = to - from;
99 if (qFuzzyIsNull(range))
102 const qreal effectiveStep = stepSize / range;
103 if (qFuzzyIsNull(effectiveStep))
106 return qRound(position / effectiveStep) * effectiveStep;
109qreal QQuickSliderPrivate::positionAt(
const QPointF &point)
const
111 Q_Q(
const QQuickSlider);
113 if (orientation == Qt::Horizontal) {
114 const qreal hw = handle ? handle->width() : 0;
115 const qreal offset = hw / 2;
116 const qreal extent = q->availableWidth() - hw;
117 if (!qFuzzyIsNull(extent)) {
119 pos = (q->width() - point.x() - q->rightPadding() - offset) / extent;
121 pos = (point.x() - q->leftPadding() - offset) / extent;
124 const qreal hh = handle ? handle->height() : 0;
125 const qreal offset = hh / 2;
126 const qreal extent = q->availableHeight() - hh;
127 if (!qFuzzyIsNull(extent))
128 pos = (q->height() - point.y() - q->bottomPadding() - offset) / extent;
130 return std::clamp(pos, qreal(0.0), qreal(1.0));
133void QQuickSliderPrivate::setPosition(qreal pos)
136 pos =
std::clamp(pos, qreal(0.0), qreal(1.0));
137 if (qFuzzyCompare(position, pos))
141 emit q->positionChanged();
142 emit q->visualPositionChanged();
145void QQuickSliderPrivate::updatePosition()
148 if (!qFuzzyCompare(from, to))
149 pos = (value - from) / (to - from);
153bool QQuickSliderPrivate::handlePress(
const QPointF &point, ulong timestamp)
156 QQuickControlPrivate::handlePress(point, timestamp);
162bool QQuickSliderPrivate::handleMove(
const QPointF &point, ulong timestamp)
165 QQuickControlPrivate::handleMove(point, timestamp);
166 const qreal oldPos = position;
167 qreal pos = positionAt(point);
168 if (snapMode == QQuickSlider::SnapAlways)
169 pos = snapPosition(pos);
171 q->setValue(q->valueAt(pos));
172 if (!live || snapMode == QQuickSlider::NoSnap || snapMode == QQuickSlider::SnapOnRelease)
174 if (!qFuzzyCompare(pos, oldPos))
179bool QQuickSliderPrivate::handleRelease(
const QPointF &point, ulong timestamp)
182 QQuickControlPrivate::handleRelease(point, timestamp);
183 pressPoint = QPointF();
184 const qreal oldPos = position;
185 qreal pos = positionAt(point);
186 if (snapMode != QQuickSlider::NoSnap)
187 pos = snapPosition(pos);
188 qreal val = q->valueAt(pos);
189 if (!qFuzzyCompare(val, value))
191 else if (snapMode != QQuickSlider::NoSnap)
193 if (!qFuzzyCompare(pos, oldPos))
195 q->setKeepMouseGrab(
false);
196 q->setKeepTouchGrab(
false);
197 q->setPressed(
false);
201void QQuickSliderPrivate::handleUngrab()
204 QQuickControlPrivate::handleUngrab();
205 pressPoint = QPointF();
206 q->setPressed(
false);
209void QQuickSliderPrivate::cancelHandle()
212 quickCancelDeferred(q, handleName());
215void QQuickSliderPrivate::executeHandle(
bool complete)
218 if (handle.wasExecuted())
221 if (!handle || complete)
222 quickBeginDeferred(q, handleName(), handle);
224 quickCompleteDeferred(q, handleName(), handle);
227void QQuickSliderPrivate::itemImplicitWidthChanged(QQuickItem *item)
230 QQuickControlPrivate::itemImplicitWidthChanged(item);
232 emit q->implicitHandleWidthChanged();
235void QQuickSliderPrivate::itemImplicitHeightChanged(QQuickItem *item)
238 QQuickControlPrivate::itemImplicitHeightChanged(item);
240 emit q->implicitHandleHeightChanged();
243void QQuickSliderPrivate::itemDestroyed(QQuickItem *item)
246 QQuickControlPrivate::itemDestroyed(item);
247 if (item == handle) {
249 emit q->handleChanged();
253QQuickSlider::QQuickSlider(QQuickItem *parent)
254 : QQuickControl(*(
new QQuickSliderPrivate), parent)
257 d->setSizePolicy(QLayoutPolicy::Expanding, QLayoutPolicy::Fixed);
258 setActiveFocusOnTab(
true);
260 setFocusPolicy(Qt::TabFocus);
262 setFocusPolicy(Qt::StrongFocus);
264 setAcceptedMouseButtons(Qt::LeftButton);
265#if QT_CONFIG(quicktemplates2_multitouch)
266 setAcceptTouchEvents(
true);
269 setCursor(Qt::ArrowCursor);
273QQuickSlider::~QQuickSlider()
276 d->removeImplicitSizeListener(d->handle);
280
281
282
283
284
285
286qreal QQuickSlider::from()
const
288 Q_D(
const QQuickSlider);
292void QQuickSlider::setFrom(qreal from)
295 if (qFuzzyCompare(d->from, from))
300 if (isComponentComplete()) {
307
308
309
310
311
312
313qreal QQuickSlider::to()
const
315 Q_D(
const QQuickSlider);
319void QQuickSlider::setTo(qreal to)
322 if (qFuzzyCompare(d->to, to))
327 if (isComponentComplete()) {
334
335
336
337
338
339
340qreal QQuickSlider::value()
const
342 Q_D(
const QQuickSlider);
346void QQuickSlider::setValue(qreal value)
349 if (isComponentComplete())
350 value = d->from > d->to ? qBound(d->to, value, d->from) : qBound(d->from, value, d->to);
352 if (qFuzzyIsNull(value))
355 if (qFuzzyCompare(d->value, value))
364
365
366
367
368
369
370
371
372
373
374
375qreal QQuickSlider::position()
const
377 Q_D(
const QQuickSlider);
382
383
384
385
386
387
388
389
390
391
392
393
394qreal QQuickSlider::visualPosition()
const
396 Q_D(
const QQuickSlider);
397 if (d->orientation == Qt::Vertical || isMirrored())
398 return 1.0 - d->position;
403
404
405
406
407
408
409qreal QQuickSlider::stepSize()
const
411 Q_D(
const QQuickSlider);
415void QQuickSlider::setStepSize(qreal step)
418 if (qFuzzyCompare(d->stepSize, step))
422 emit stepSizeChanged();
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452QQuickSlider::SnapMode QQuickSlider::snapMode()
const
454 Q_D(
const QQuickSlider);
458void QQuickSlider::setSnapMode(SnapMode mode)
461 if (d->snapMode == mode)
465 emit snapModeChanged();
469
470
471
472
473
474bool QQuickSlider::isPressed()
const
476 Q_D(
const QQuickSlider);
480void QQuickSlider::setPressed(
bool pressed)
483 if (d->pressed == pressed)
486 d->pressed = pressed;
487 setAccessibleProperty(
"pressed", pressed);
488 emit pressedChanged();
492
493
494
495
496
497
498
499
500bool QQuickSlider::isHorizontal()
const
502 Q_D(
const QQuickSlider);
503 return d->orientation == Qt::Horizontal;
507
508
509
510
511
512
513
514
515bool QQuickSlider::isVertical()
const
517 Q_D(
const QQuickSlider);
518 return d->orientation == Qt::Vertical;
522
523
524
525
526
527
528
529
530
531
532Qt::Orientation QQuickSlider::orientation()
const
534 Q_D(
const QQuickSlider);
535 return d->orientation;
538void QQuickSlider::setOrientation(Qt::Orientation orientation)
541 if (d->orientation == orientation)
544 if (orientation == Qt::Horizontal)
545 d->setSizePolicy(QLayoutPolicy::Expanding, QLayoutPolicy::Fixed);
547 d->setSizePolicy(QLayoutPolicy::Fixed, QLayoutPolicy::Expanding);
549 d->orientation = orientation;
550 emit orientationChanged();
554
555
556
557
558
559
560QQuickItem *QQuickSlider::handle()
const
562 QQuickSliderPrivate *d =
const_cast<QQuickSliderPrivate *>(d_func());
568void QQuickSlider::setHandle(QQuickItem *handle)
571 if (d->handle == handle)
574 QQuickControlPrivate::warnIfCustomizationNotSupported(
this, handle, QStringLiteral(
"handle"));
576 if (!d->handle.isExecuting())
579 const qreal oldImplicitHandleWidth = implicitHandleWidth();
580 const qreal oldImplicitHandleHeight = implicitHandleHeight();
582 d->removeImplicitSizeListener(d->handle);
583 QQuickControlPrivate::hideOldItem(d->handle);
587 if (!handle->parentItem())
588 handle->setParentItem(
this);
589 d->addImplicitSizeListener(handle);
592 if (!qFuzzyCompare(oldImplicitHandleWidth, implicitHandleWidth()))
593 emit implicitHandleWidthChanged();
594 if (!qFuzzyCompare(oldImplicitHandleHeight, implicitHandleHeight()))
595 emit implicitHandleHeightChanged();
596 if (!d->handle.isExecuting())
597 emit handleChanged();
601
602
603
604
605
606
607
608qreal QQuickSlider::valueAt(qreal position)
const
610 Q_D(
const QQuickSlider);
611 const qreal value = (d->to - d->from) * position;
612 if (qFuzzyIsNull(d->stepSize))
613 return d->from + value;
614 return d->from + qRound(value / d->stepSize) * d->stepSize;
618
619
620
621
622
623
624
625
626
627
628bool QQuickSlider::live()
const
630 Q_D(
const QQuickSlider);
634void QQuickSlider::setLive(
bool live)
645
646
647
648
649
650
651void QQuickSlider::increase()
654 qreal step = qFuzzyIsNull(d->stepSize) ? 0.1 : d->stepSize;
655 setValue(d->value + step);
659
660
661
662
663
664
665void QQuickSlider::decrease()
668 qreal step = qFuzzyIsNull(d->stepSize) ? 0.1 : d->stepSize;
669 setValue(d->value - step);
673
674
675
676
677
678
679
680
681
682qreal QQuickSlider::touchDragThreshold()
const
684 Q_D(
const QQuickSlider);
685 return d->touchDragThreshold;
688void QQuickSlider::setTouchDragThreshold(qreal touchDragThreshold)
691 if (d->touchDragThreshold == touchDragThreshold)
694 d->touchDragThreshold = touchDragThreshold;
695 emit touchDragThresholdChanged();
698void QQuickSlider::resetTouchDragThreshold()
700 setTouchDragThreshold(-1);
704
705
706
707
708
709
710
711
712
713
714
715
716
717qreal QQuickSlider::implicitHandleWidth()
const
719 Q_D(
const QQuickSlider);
722 return d->handle->implicitWidth();
726
727
728
729
730
731
732
733
734
735
736
737
738
739qreal QQuickSlider::implicitHandleHeight()
const
741 Q_D(
const QQuickSlider);
744 return d->handle->implicitHeight();
747void QQuickSlider::keyPressEvent(QKeyEvent *event)
750 QQuickControl::keyPressEvent(event);
752 const qreal oldValue = d->value;
753 if (d->orientation == Qt::Horizontal) {
754 if (event->key() == Qt::Key_Left) {
761 }
else if (event->key() == Qt::Key_Right) {
770 if (event->key() == Qt::Key_Up) {
774 }
else if (event->key() == Qt::Key_Down) {
780 if (!qFuzzyCompare(d->value, oldValue))
784void QQuickSlider::keyReleaseEvent(QKeyEvent *event)
786 QQuickControl::keyReleaseEvent(event);
790void QQuickSlider::mousePressEvent(QMouseEvent *event)
793 QQuickControl::mousePressEvent(event);
794 d->handleMove(event->position(), event->timestamp());
795 setKeepMouseGrab(
true);
798#if QT_CONFIG(quicktemplates2_multitouch)
799void QQuickSlider::touchEvent(QTouchEvent *event)
802 switch (event->type()) {
803 case QEvent::TouchUpdate:
804 for (
const QTouchEvent::TouchPoint &point : event->points()) {
805 if (!d->acceptTouch(point))
808 switch (point.state()) {
809 case QEventPoint::Pressed:
810 d->handlePress(point.position(), event->timestamp());
812 case QEventPoint::Updated:
813 if (!keepTouchGrab()) {
814 if (d->orientation == Qt::Horizontal) {
815 setKeepTouchGrab(QQuickDeliveryAgentPrivate::dragOverThreshold(point.position().x() - d->pressPoint.x(),
816 Qt::XAxis, point, qRound(d->touchDragThreshold)));
818 setKeepTouchGrab(QQuickDeliveryAgentPrivate::dragOverThreshold(point.position().y() - d->pressPoint.y(),
819 Qt::YAxis, point, qRound(d->touchDragThreshold)));
823 d->handleMove(point.position(), event->timestamp());
825 case QEventPoint::Released:
826 d->handleRelease(point.position(), event->timestamp());
835 QQuickControl::touchEvent(event);
841#if QT_CONFIG(wheelevent)
842void QQuickSlider::wheelEvent(QWheelEvent *event)
845 QQuickControl::wheelEvent(event);
846 if (d->wheelEnabled) {
847 const qreal oldValue = d->value;
848 const QPointF angle = event->angleDelta();
849 const qreal delta = (qAbs(angle.y()) < qAbs(angle.x()) ? angle.x() : (event->inverted() ? -angle.y() : angle.y())) /
int(QWheelEvent::DefaultDeltasPerStep);
850 const qreal step = qFuzzyIsNull(d->stepSize) ? 0.1 : d->stepSize;
851 setValue(oldValue + step * delta);
852 const bool wasMoved = !qFuzzyCompare(d->value, oldValue);
859void QQuickSlider::mirrorChange()
861 QQuickControl::mirrorChange();
862 emit visualPositionChanged();
865void QQuickSlider::componentComplete()
868 d->executeHandle(
true);
869 QQuickControl::componentComplete();
874#if QT_CONFIG(accessibility)
875void QQuickSlider::accessibilityActiveChanged(
bool active)
877 QQuickControl::accessibilityActiveChanged(active);
881 setAccessibleProperty(
"pressed", d->pressed);
884QAccessible::Role QQuickSlider::accessibleRole()
const
886 return QAccessible::Slider;
892#include "moc_qquickslider_p.cpp"