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
51
54
55
56
57
58
59
61class QQuickSliderPrivate :
public QQuickControlPrivate
63 Q_DECLARE_PUBLIC(QQuickSlider)
66 qreal snapPosition(qreal position)
const;
67 qreal positionAt(
const QPointF &point)
const;
68 void setPosition(qreal position);
69 void updatePosition();
71 bool handlePress(
const QPointF &point, ulong timestamp) override;
72 bool handleMove(
const QPointF &point, ulong timestamp) override;
73 bool handleRelease(
const QPointF &point, ulong timestamp) override;
74 void handleUngrab() override;
77 void executeHandle(
bool complete =
false);
79 void itemImplicitWidthChanged(QQuickItem *item) override;
80 void itemImplicitHeightChanged(QQuickItem *item) override;
81 void itemDestroyed(QQuickItem *item) override;
88 qreal touchDragThreshold = -1;
92 Qt::Orientation orientation = Qt::Horizontal;
93 QQuickSlider::SnapMode snapMode = QQuickSlider::NoSnap;
94 QQuickDeferredPointer<QQuickItem> handle;
97qreal QQuickSliderPrivate::snapPosition(qreal position)
const
99 const qreal range = to - from;
100 if (qFuzzyIsNull(range))
103 const qreal effectiveStep = stepSize / range;
104 if (qFuzzyIsNull(effectiveStep))
107 return qRound(position / effectiveStep) * effectiveStep;
110qreal QQuickSliderPrivate::positionAt(
const QPointF &point)
const
112 Q_Q(
const QQuickSlider);
114 if (orientation == Qt::Horizontal) {
115 const qreal hw = handle ? handle->width() : 0;
116 const qreal offset = hw / 2;
117 const qreal extent = q->availableWidth() - hw;
118 if (!qFuzzyIsNull(extent)) {
120 pos = (q->width() - point.x() - q->rightPadding() - offset) / extent;
122 pos = (point.x() - q->leftPadding() - offset) / extent;
125 const qreal hh = handle ? handle->height() : 0;
126 const qreal offset = hh / 2;
127 const qreal extent = q->availableHeight() - hh;
128 if (!qFuzzyIsNull(extent))
129 pos = (q->height() - point.y() - q->bottomPadding() - offset) / extent;
131 return std::clamp(pos, qreal(0.0), qreal(1.0));
134void QQuickSliderPrivate::setPosition(qreal pos)
137 pos =
std::clamp(pos, qreal(0.0), qreal(1.0));
138 if (qFuzzyCompare(position, pos))
142 emit q->positionChanged();
143 emit q->visualPositionChanged();
146void QQuickSliderPrivate::updatePosition()
149 if (!qFuzzyCompare(from, to))
150 pos = (value - from) / (to - from);
154bool QQuickSliderPrivate::handlePress(
const QPointF &point, ulong timestamp)
157 QQuickControlPrivate::handlePress(point, timestamp);
163bool QQuickSliderPrivate::handleMove(
const QPointF &point, ulong timestamp)
166 QQuickControlPrivate::handleMove(point, timestamp);
167 const qreal oldPos = position;
168 qreal pos = positionAt(point);
169 if (snapMode == QQuickSlider::SnapAlways)
170 pos = snapPosition(pos);
172 q->setValue(q->valueAt(pos));
173 if (!live || snapMode == QQuickSlider::NoSnap || snapMode == QQuickSlider::SnapOnRelease)
175 if (!qFuzzyCompare(pos, oldPos))
180bool QQuickSliderPrivate::handleRelease(
const QPointF &point, ulong timestamp)
183 QQuickControlPrivate::handleRelease(point, timestamp);
184 pressPoint = QPointF();
185 const qreal oldPos = position;
186 qreal pos = positionAt(point);
187 if (snapMode != QQuickSlider::NoSnap)
188 pos = snapPosition(pos);
189 qreal val = q->valueAt(pos);
190 if (!qFuzzyCompare(val, value))
192 else if (snapMode != QQuickSlider::NoSnap)
194 if (!qFuzzyCompare(pos, oldPos))
196 q->setKeepMouseGrab(
false);
197 q->setKeepTouchGrab(
false);
198 q->setPressed(
false);
202void QQuickSliderPrivate::handleUngrab()
205 QQuickControlPrivate::handleUngrab();
206 pressPoint = QPointF();
207 q->setPressed(
false);
210void QQuickSliderPrivate::cancelHandle()
213 quickCancelDeferred(q, handleName());
216void QQuickSliderPrivate::executeHandle(
bool complete)
219 if (handle.wasExecuted())
222 if (!handle || complete)
223 quickBeginDeferred(q, handleName(), handle);
225 quickCompleteDeferred(q, handleName(), handle);
228void QQuickSliderPrivate::itemImplicitWidthChanged(QQuickItem *item)
231 QQuickControlPrivate::itemImplicitWidthChanged(item);
233 emit q->implicitHandleWidthChanged();
236void QQuickSliderPrivate::itemImplicitHeightChanged(QQuickItem *item)
239 QQuickControlPrivate::itemImplicitHeightChanged(item);
241 emit q->implicitHandleHeightChanged();
244void QQuickSliderPrivate::itemDestroyed(QQuickItem *item)
247 QQuickControlPrivate::itemDestroyed(item);
248 if (item == handle) {
250 emit q->handleChanged();
254QQuickSlider::QQuickSlider(QQuickItem *parent)
255 : QQuickControl(*(
new QQuickSliderPrivate), parent)
258 d->setSizePolicy(QLayoutPolicy::Expanding, QLayoutPolicy::Fixed);
259 setActiveFocusOnTab(
true);
261 setFocusPolicy(Qt::TabFocus);
263 setFocusPolicy(Qt::StrongFocus);
265 setAcceptedMouseButtons(Qt::LeftButton);
266#if QT_CONFIG(quicktemplates2_multitouch)
267 setAcceptTouchEvents(
true);
270 setCursor(Qt::ArrowCursor);
274QQuickSlider::~QQuickSlider()
277 d->removeImplicitSizeListener(d->handle);
281
282
283
284
285
286
287qreal QQuickSlider::from()
const
289 Q_D(
const QQuickSlider);
293void QQuickSlider::setFrom(qreal from)
296 if (qFuzzyCompare(d->from, from))
301 if (isComponentComplete()) {
308
309
310
311
312
313
314qreal QQuickSlider::to()
const
316 Q_D(
const QQuickSlider);
320void QQuickSlider::setTo(qreal to)
323 if (qFuzzyCompare(d->to, to))
328 if (isComponentComplete()) {
335
336
337
338
339
340
341qreal QQuickSlider::value()
const
343 Q_D(
const QQuickSlider);
347void QQuickSlider::setValue(qreal value)
350 if (isComponentComplete())
351 value = d->from > d->to ? qBound(d->to, value, d->from) : qBound(d->from, value, d->to);
353 if (qFuzzyIsNull(value))
356 if (qFuzzyCompare(d->value, value))
365
366
367
368
369
370
371
372
373
374
375
376qreal QQuickSlider::position()
const
378 Q_D(
const QQuickSlider);
383
384
385
386
387
388
389
390
391
392
393
394
395qreal QQuickSlider::visualPosition()
const
397 Q_D(
const QQuickSlider);
398 if (d->orientation == Qt::Vertical || isMirrored())
399 return 1.0 - d->position;
404
405
406
407
408
409
410qreal QQuickSlider::stepSize()
const
412 Q_D(
const QQuickSlider);
416void QQuickSlider::setStepSize(qreal step)
419 if (qFuzzyCompare(d->stepSize, step))
423 emit stepSizeChanged();
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
452
453
454
455
456
457
458
459QQuickSlider::SnapMode QQuickSlider::snapMode()
const
461 Q_D(
const QQuickSlider);
465void QQuickSlider::setSnapMode(SnapMode mode)
468 if (d->snapMode == mode)
472 emit snapModeChanged();
476
477
478
479
480
481bool QQuickSlider::isPressed()
const
483 Q_D(
const QQuickSlider);
487void QQuickSlider::setPressed(
bool pressed)
490 if (d->pressed == pressed)
493 d->pressed = pressed;
494 setAccessibleProperty(
"pressed", pressed);
495 emit pressedChanged();
499
500
501
502
503
504
505
506
507bool QQuickSlider::isHorizontal()
const
509 Q_D(
const QQuickSlider);
510 return d->orientation == Qt::Horizontal;
514
515
516
517
518
519
520
521
522bool QQuickSlider::isVertical()
const
524 Q_D(
const QQuickSlider);
525 return d->orientation == Qt::Vertical;
529
530
531
532
533
534
535
536
537
538
539Qt::Orientation QQuickSlider::orientation()
const
541 Q_D(
const QQuickSlider);
542 return d->orientation;
545void QQuickSlider::setOrientation(Qt::Orientation orientation)
548 if (d->orientation == orientation)
551 if (orientation == Qt::Horizontal)
552 d->setSizePolicy(QLayoutPolicy::Expanding, QLayoutPolicy::Fixed);
554 d->setSizePolicy(QLayoutPolicy::Fixed, QLayoutPolicy::Expanding);
556 d->orientation = orientation;
557 emit orientationChanged();
561
562
563
564
565
566
567QQuickItem *QQuickSlider::handle()
const
569 QQuickSliderPrivate *d =
const_cast<QQuickSliderPrivate *>(d_func());
575void QQuickSlider::setHandle(QQuickItem *handle)
578 if (d->handle == handle)
581 QQuickControlPrivate::warnIfCustomizationNotSupported(
this, handle, QStringLiteral(
"handle"));
583 if (!d->handle.isExecuting())
586 const qreal oldImplicitHandleWidth = implicitHandleWidth();
587 const qreal oldImplicitHandleHeight = implicitHandleHeight();
589 d->removeImplicitSizeListener(d->handle);
590 QQuickControlPrivate::hideOldItem(d->handle);
594 if (!handle->parentItem())
595 handle->setParentItem(
this);
596 d->addImplicitSizeListener(handle);
599 if (!qFuzzyCompare(oldImplicitHandleWidth, implicitHandleWidth()))
600 emit implicitHandleWidthChanged();
601 if (!qFuzzyCompare(oldImplicitHandleHeight, implicitHandleHeight()))
602 emit implicitHandleHeightChanged();
603 if (!d->handle.isExecuting())
604 emit handleChanged();
608
609
610
611
612
613
614
615qreal QQuickSlider::valueAt(qreal position)
const
617 Q_D(
const QQuickSlider);
618 const qreal value = (d->to - d->from) * position;
619 if (qFuzzyIsNull(d->stepSize))
620 return d->from + value;
621 return d->from + qRound(value / d->stepSize) * d->stepSize;
625
626
627
628
629
630
631
632
633
634
635bool QQuickSlider::live()
const
637 Q_D(
const QQuickSlider);
641void QQuickSlider::setLive(
bool live)
652
653
654
655
656
657
658void QQuickSlider::increase()
661 qreal step = qFuzzyIsNull(d->stepSize) ? 0.1 : d->stepSize;
662 setValue(d->value + step);
666
667
668
669
670
671
672void QQuickSlider::decrease()
675 qreal step = qFuzzyIsNull(d->stepSize) ? 0.1 : d->stepSize;
676 setValue(d->value - step);
680
681
682
683
684
685
686
687
688
689qreal QQuickSlider::touchDragThreshold()
const
691 Q_D(
const QQuickSlider);
692 return d->touchDragThreshold;
695void QQuickSlider::setTouchDragThreshold(qreal touchDragThreshold)
698 if (d->touchDragThreshold == touchDragThreshold)
701 d->touchDragThreshold = touchDragThreshold;
702 emit touchDragThresholdChanged();
705void QQuickSlider::resetTouchDragThreshold()
707 setTouchDragThreshold(-1);
711
712
713
714
715
716
717
718
719
720
721
722
723
724qreal QQuickSlider::implicitHandleWidth()
const
726 Q_D(
const QQuickSlider);
729 return d->handle->implicitWidth();
733
734
735
736
737
738
739
740
741
742
743
744
745
746qreal QQuickSlider::implicitHandleHeight()
const
748 Q_D(
const QQuickSlider);
751 return d->handle->implicitHeight();
754void QQuickSlider::keyPressEvent(QKeyEvent *event)
757 QQuickControl::keyPressEvent(event);
759 const qreal oldValue = d->value;
760 if (d->orientation == Qt::Horizontal) {
761 if (event->key() == Qt::Key_Left) {
768 }
else if (event->key() == Qt::Key_Right) {
777 if (event->key() == Qt::Key_Up) {
781 }
else if (event->key() == Qt::Key_Down) {
787 if (!qFuzzyCompare(d->value, oldValue))
791void QQuickSlider::keyReleaseEvent(QKeyEvent *event)
793 QQuickControl::keyReleaseEvent(event);
797void QQuickSlider::mousePressEvent(QMouseEvent *event)
800 QQuickControl::mousePressEvent(event);
801 d->handleMove(event->position(), event->timestamp());
802 setKeepMouseGrab(
true);
805#if QT_CONFIG(quicktemplates2_multitouch)
806void QQuickSlider::touchEvent(QTouchEvent *event)
809 switch (event->type()) {
810 case QEvent::TouchUpdate:
811 for (
const QTouchEvent::TouchPoint &point : event->points()) {
812 if (!d->acceptTouch(point))
815 switch (point.state()) {
816 case QEventPoint::Pressed:
817 d->handlePress(point.position(), event->timestamp());
819 case QEventPoint::Updated:
820 if (!keepTouchGrab()) {
821 if (d->orientation == Qt::Horizontal) {
822 setKeepTouchGrab(QQuickDeliveryAgentPrivate::dragOverThreshold(point.position().x() - d->pressPoint.x(),
823 Qt::XAxis, point, qRound(d->touchDragThreshold)));
825 setKeepTouchGrab(QQuickDeliveryAgentPrivate::dragOverThreshold(point.position().y() - d->pressPoint.y(),
826 Qt::YAxis, point, qRound(d->touchDragThreshold)));
830 d->handleMove(point.position(), event->timestamp());
832 case QEventPoint::Released:
833 d->handleRelease(point.position(), event->timestamp());
842 QQuickControl::touchEvent(event);
848#if QT_CONFIG(wheelevent)
849void QQuickSlider::wheelEvent(QWheelEvent *event)
852 QQuickControl::wheelEvent(event);
853 if (d->wheelEnabled) {
854 const qreal oldValue = d->value;
855 const QPointF angle = event->angleDelta();
856 const qreal delta = (qAbs(angle.y()) < qAbs(angle.x()) ? angle.x() : (event->inverted() ? -angle.y() : angle.y())) /
int(QWheelEvent::DefaultDeltasPerStep);
857 const qreal step = qFuzzyIsNull(d->stepSize) ? 0.1 : d->stepSize;
858 setValue(oldValue + step * delta);
859 const bool wasMoved = !qFuzzyCompare(d->value, oldValue);
866void QQuickSlider::mirrorChange()
868 QQuickControl::mirrorChange();
869 emit visualPositionChanged();
872void QQuickSlider::componentComplete()
875 d->executeHandle(
true);
876 QQuickControl::componentComplete();
881#if QT_CONFIG(accessibility)
882void QQuickSlider::accessibilityActiveChanged(
bool active)
884 QQuickControl::accessibilityActiveChanged(active);
888 setAccessibleProperty(
"pressed", d->pressed);
891QAccessible::Role QQuickSlider::accessibleRole()
const
893 return QAccessible::Slider;
899#include "moc_qquickslider_p.cpp"