Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qquickslider.cpp
Go to the documentation of this file.
1// Copyright (C) 2017 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3// Qt-Security score:significant reason:default
4
8
9#include <QtQuick/private/qquickwindow_p.h>
10
11#include <algorithm>
12
13QT_BEGIN_NAMESPACE
14
15/*!
16 \qmltype Slider
17 \inherits Control
18//! \nativetype QQuickSlider
19 \inqmlmodule QtQuick.Controls
20 \since 5.7
21 \ingroup qtquickcontrols-input
22 \brief Used to select a value by sliding a handle along a track.
23
24 \image qtquickcontrols-slider.gif
25
26 Slider is used to select a value by sliding a handle along a track.
27
28 In the example below, custom \l from, \l value, and \l to values are set:
29
30 \code
31 Slider {
32 from: 1
33 value: 25
34 to: 100
35 }
36 \endcode
37
38 The \l position property is expressed as a fraction of the control's size,
39 in the range \c {0.0 - 1.0}. The \l visualPosition property is
40 the same, except that it is reversed in a
41 \l {Right-to-left User Interfaces}{right-to-left} application. The
42 visualPosition is useful for positioning the handle when styling Slider.
43 In the example above, \l visualPosition will be \c 0.24 in a left-to-right
44 application, and \c 0.76 in a right-to-left application.
45
46 For a slider that allows the user to select a range by providing two
47 handles, see \l RangeSlider.
48
49 \sa {Customizing Slider}, {Input Controls}
50*/
51
52/*!
53 \since QtQuick.Controls 2.2 (Qt 5.9)
54 \qmlsignal QtQuick.Controls::Slider::moved()
55
56 This signal is emitted when the slider has been interactively moved
57 by the user by either touch, mouse, wheel, or keys.
58*/
59
60class QQuickSliderPrivate : public QQuickControlPrivate
61{
62 Q_DECLARE_PUBLIC(QQuickSlider)
63
64public:
65 qreal snapPosition(qreal position) const;
66 qreal positionAt(const QPointF &point) const;
67 void setPosition(qreal position);
68 void updatePosition();
69
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;
74
75 void cancelHandle();
76 void executeHandle(bool complete = false);
77
78 void itemImplicitWidthChanged(QQuickItem *item) override;
79 void itemImplicitHeightChanged(QQuickItem *item) override;
80 void itemDestroyed(QQuickItem *item) override;
81
82 qreal from = 0;
83 qreal to = 1;
84 qreal value = 0;
85 qreal position = 0;
86 qreal stepSize = 0;
87 qreal touchDragThreshold = -1; // in QQuickWindowPrivate::dragOverThreshold, '-1' implies using styleHints::startDragDistance()
88 bool live = true;
89 bool pressed = false;
90 QPointF pressPoint;
91 Qt::Orientation orientation = Qt::Horizontal;
92 QQuickSlider::SnapMode snapMode = QQuickSlider::NoSnap;
93 QQuickDeferredPointer<QQuickItem> handle;
94};
95
96qreal QQuickSliderPrivate::snapPosition(qreal position) const
97{
98 const qreal range = to - from;
99 if (qFuzzyIsNull(range))
100 return position;
101
102 const qreal effectiveStep = stepSize / range;
103 if (qFuzzyIsNull(effectiveStep))
104 return position;
105
106 return qRound(position / effectiveStep) * effectiveStep;
107}
108
109qreal QQuickSliderPrivate::positionAt(const QPointF &point) const
110{
111 Q_Q(const QQuickSlider);
112 qreal pos = 0.0;
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)) {
118 if (q->isMirrored())
119 pos = (q->width() - point.x() - q->rightPadding() - offset) / extent;
120 else
121 pos = (point.x() - q->leftPadding() - offset) / extent;
122 }
123 } else {
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;
129 }
130 return std::clamp(pos, qreal(0.0), qreal(1.0));
131}
132
133void QQuickSliderPrivate::setPosition(qreal pos)
134{
135 Q_Q(QQuickSlider);
136 pos = std::clamp(pos, qreal(0.0), qreal(1.0));
137 if (qFuzzyCompare(position, pos))
138 return;
139
140 position = pos;
141 emit q->positionChanged();
142 emit q->visualPositionChanged();
143}
144
145void QQuickSliderPrivate::updatePosition()
146{
147 qreal pos = 0;
148 if (!qFuzzyCompare(from, to))
149 pos = (value - from) / (to - from);
150 setPosition(pos);
151}
152
153bool QQuickSliderPrivate::handlePress(const QPointF &point, ulong timestamp)
154{
155 Q_Q(QQuickSlider);
156 QQuickControlPrivate::handlePress(point, timestamp);
157 pressPoint = point;
158 q->setPressed(true);
159 return true;
160}
161
162bool QQuickSliderPrivate::handleMove(const QPointF &point, ulong timestamp)
163{
164 Q_Q(QQuickSlider);
165 QQuickControlPrivate::handleMove(point, timestamp);
166 const qreal oldPos = position;
167 qreal pos = positionAt(point);
168 if (snapMode == QQuickSlider::SnapAlways)
169 pos = snapPosition(pos);
170 if (live)
171 q->setValue(q->valueAt(pos));
172 if (!live || snapMode == QQuickSlider::NoSnap || snapMode == QQuickSlider::SnapOnRelease)
173 setPosition(pos);
174 if (!qFuzzyCompare(pos, oldPos))
175 emit q->moved();
176 return true;
177}
178
179bool QQuickSliderPrivate::handleRelease(const QPointF &point, ulong timestamp)
180{
181 Q_Q(QQuickSlider);
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))
190 q->setValue(val);
191 else if (snapMode != QQuickSlider::NoSnap)
192 setPosition(pos);
193 if (!qFuzzyCompare(pos, oldPos))
194 emit q->moved();
195 q->setKeepMouseGrab(false);
196 q->setKeepTouchGrab(false);
197 q->setPressed(false);
198 return true;
199}
200
201void QQuickSliderPrivate::handleUngrab()
202{
203 Q_Q(QQuickSlider);
204 QQuickControlPrivate::handleUngrab();
205 pressPoint = QPointF();
206 q->setPressed(false);
207}
208
209void QQuickSliderPrivate::cancelHandle()
210{
211 Q_Q(QQuickSlider);
212 quickCancelDeferred(q, handleName());
213}
214
215void QQuickSliderPrivate::executeHandle(bool complete)
216{
217 Q_Q(QQuickSlider);
218 if (handle.wasExecuted())
219 return;
220
221 if (!handle || complete)
222 quickBeginDeferred(q, handleName(), handle);
223 if (complete)
224 quickCompleteDeferred(q, handleName(), handle);
225}
226
227void QQuickSliderPrivate::itemImplicitWidthChanged(QQuickItem *item)
228{
229 Q_Q(QQuickSlider);
230 QQuickControlPrivate::itemImplicitWidthChanged(item);
231 if (item == handle)
232 emit q->implicitHandleWidthChanged();
233}
234
235void QQuickSliderPrivate::itemImplicitHeightChanged(QQuickItem *item)
236{
237 Q_Q(QQuickSlider);
238 QQuickControlPrivate::itemImplicitHeightChanged(item);
239 if (item == handle)
240 emit q->implicitHandleHeightChanged();
241}
242
243void QQuickSliderPrivate::itemDestroyed(QQuickItem *item)
244{
245 Q_Q(QQuickSlider);
246 QQuickControlPrivate::itemDestroyed(item);
247 if (item == handle) {
248 handle = nullptr;
249 emit q->handleChanged();
250 }
251}
252
253QQuickSlider::QQuickSlider(QQuickItem *parent)
254 : QQuickControl(*(new QQuickSliderPrivate), parent)
255{
256 Q_D(QQuickSlider);
257 d->setSizePolicy(QLayoutPolicy::Expanding, QLayoutPolicy::Fixed);
258 setActiveFocusOnTab(true);
259#ifdef Q_OS_MACOS
260 setFocusPolicy(Qt::TabFocus);
261#else
262 setFocusPolicy(Qt::StrongFocus);
263#endif
264 setAcceptedMouseButtons(Qt::LeftButton);
265#if QT_CONFIG(quicktemplates2_multitouch)
266 setAcceptTouchEvents(true);
267#endif
268#if QT_CONFIG(cursor)
269 setCursor(Qt::ArrowCursor);
270#endif
271}
272
273QQuickSlider::~QQuickSlider()
274{
275 Q_D(QQuickSlider);
276 d->removeImplicitSizeListener(d->handle);
277}
278
279/*!
280 \qmlproperty real QtQuick.Controls::Slider::from
281
282 This property holds the starting value for the range. The default value is \c 0.0.
283
284 \sa to, value
285*/
286qreal QQuickSlider::from() const
287{
288 Q_D(const QQuickSlider);
289 return d->from;
290}
291
292void QQuickSlider::setFrom(qreal from)
293{
294 Q_D(QQuickSlider);
295 if (qFuzzyCompare(d->from, from))
296 return;
297
298 d->from = from;
299 emit fromChanged();
300 if (isComponentComplete()) {
301 setValue(d->value);
302 d->updatePosition();
303 }
304}
305
306/*!
307 \qmlproperty real QtQuick.Controls::Slider::to
308
309 This property holds the end value for the range. The default value is \c 1.0.
310
311 \sa from, value
312*/
313qreal QQuickSlider::to() const
314{
315 Q_D(const QQuickSlider);
316 return d->to;
317}
318
319void QQuickSlider::setTo(qreal to)
320{
321 Q_D(QQuickSlider);
322 if (qFuzzyCompare(d->to, to))
323 return;
324
325 d->to = to;
326 emit toChanged();
327 if (isComponentComplete()) {
328 setValue(d->value);
329 d->updatePosition();
330 }
331}
332
333/*!
334 \qmlproperty real QtQuick.Controls::Slider::value
335
336 This property holds the value in the range \c from - \c to. The default value is \c 0.0.
337
338 \sa position
339*/
340qreal QQuickSlider::value() const
341{
342 Q_D(const QQuickSlider);
343 return d->value;
344}
345
346void QQuickSlider::setValue(qreal value)
347{
348 Q_D(QQuickSlider);
349 if (isComponentComplete())
350 value = d->from > d->to ? qBound(d->to, value, d->from) : qBound(d->from, value, d->to);
351
352 if (qFuzzyIsNull(value))
353 value = 0.0;
354
355 if (qFuzzyCompare(d->value, value))
356 return;
357
358 d->value = value;
359 d->updatePosition();
360 emit valueChanged();
361}
362
363/*!
364 \qmlproperty real QtQuick.Controls::Slider::position
365 \readonly
366
367 This property holds the logical position of the handle.
368
369 The position is expressed as a fraction of the control's size, in the range
370 \c {0.0 - 1.0}. For visualizing a slider, the right-to-left aware
371 \l visualPosition should be used instead.
372
373 \sa value, visualPosition, valueAt()
374*/
375qreal QQuickSlider::position() const
376{
377 Q_D(const QQuickSlider);
378 return d->position;
379}
380
381/*!
382 \qmlproperty real QtQuick.Controls::Slider::visualPosition
383 \readonly
384
385 This property holds the visual position of the handle.
386
387 The position is expressed as a fraction of the control's size, in the range
388 \c {0.0 - 1.0}. When the control is \l {Control::mirrored}{mirrored}, the
389 value is equal to \c {1.0 - position}. This makes the value suitable for
390 visualizing the slider, taking right-to-left support into account.
391
392 \sa position
393*/
394qreal QQuickSlider::visualPosition() const
395{
396 Q_D(const QQuickSlider);
397 if (d->orientation == Qt::Vertical || isMirrored())
398 return 1.0 - d->position;
399 return d->position;
400}
401
402/*!
403 \qmlproperty real QtQuick.Controls::Slider::stepSize
404
405 This property holds the step size. The default value is \c 0.0.
406
407 \sa snapMode, increase(), decrease()
408*/
409qreal QQuickSlider::stepSize() const
410{
411 Q_D(const QQuickSlider);
412 return d->stepSize;
413}
414
415void QQuickSlider::setStepSize(qreal step)
416{
417 Q_D(QQuickSlider);
418 if (qFuzzyCompare(d->stepSize, step))
419 return;
420
421 d->stepSize = step;
422 emit stepSizeChanged();
423}
424
425/*!
426 \qmlproperty enumeration QtQuick.Controls::Slider::snapMode
427
428 This property holds the snap mode.
429
430 The snap mode determines how the slider handle behaves with
431 regards to the \l stepSize.
432
433 Possible values:
434 \value Slider.NoSnap The slider does not snap (default).
435 \value Slider.SnapAlways The slider snaps while the handle is dragged.
436 \value Slider.SnapOnRelease The slider does not snap while being dragged, but only after the handle is released.
437
438 In the following table, the various modes are illustrated with animations.
439 The movement of the mouse cursor and the \l stepSize (\c 0.2) are identical
440 in each animation.
441
442 \table
443 \header
444 \row \li \b Value \li \b Example
445 \row \li \c Slider.NoSnap \li \image qtquickcontrols-slider-nosnap.gif
446 \row \li \c Slider.SnapAlways \li \image qtquickcontrols-slider-snapalways.gif
447 \row \li \c Slider.SnapOnRelease \li \image qtquickcontrols-slider-snaponrelease.gif
448 \endtable
449
450 \sa stepSize
451*/
452QQuickSlider::SnapMode QQuickSlider::snapMode() const
453{
454 Q_D(const QQuickSlider);
455 return d->snapMode;
456}
457
458void QQuickSlider::setSnapMode(SnapMode mode)
459{
460 Q_D(QQuickSlider);
461 if (d->snapMode == mode)
462 return;
463
464 d->snapMode = mode;
465 emit snapModeChanged();
466}
467
468/*!
469 \qmlproperty bool QtQuick.Controls::Slider::pressed
470
471 This property holds whether the slider is pressed by either touch, mouse,
472 or keys.
473*/
474bool QQuickSlider::isPressed() const
475{
476 Q_D(const QQuickSlider);
477 return d->pressed;
478}
479
480void QQuickSlider::setPressed(bool pressed)
481{
482 Q_D(QQuickSlider);
483 if (d->pressed == pressed)
484 return;
485
486 d->pressed = pressed;
487 setAccessibleProperty("pressed", pressed);
488 emit pressedChanged();
489}
490
491/*!
492 \since QtQuick.Controls 2.3 (Qt 5.10)
493 \qmlproperty bool QtQuick.Controls::Slider::horizontal
494 \readonly
495
496 This property holds whether the slider is horizontal.
497
498 \sa orientation
499*/
500bool QQuickSlider::isHorizontal() const
501{
502 Q_D(const QQuickSlider);
503 return d->orientation == Qt::Horizontal;
504}
505
506/*!
507 \since QtQuick.Controls 2.3 (Qt 5.10)
508 \qmlproperty bool QtQuick.Controls::Slider::vertical
509 \readonly
510
511 This property holds whether the slider is vertical.
512
513 \sa orientation
514*/
515bool QQuickSlider::isVertical() const
516{
517 Q_D(const QQuickSlider);
518 return d->orientation == Qt::Vertical;
519}
520
521/*!
522 \qmlproperty enumeration QtQuick.Controls::Slider::orientation
523
524 This property holds the orientation.
525
526 Possible values:
527 \value Qt.Horizontal Horizontal (default)
528 \value Qt.Vertical Vertical
529
530 \sa horizontal, vertical
531*/
532Qt::Orientation QQuickSlider::orientation() const
533{
534 Q_D(const QQuickSlider);
535 return d->orientation;
536}
537
538void QQuickSlider::setOrientation(Qt::Orientation orientation)
539{
540 Q_D(QQuickSlider);
541 if (d->orientation == orientation)
542 return;
543
544 if (orientation == Qt::Horizontal)
545 d->setSizePolicy(QLayoutPolicy::Expanding, QLayoutPolicy::Fixed);
546 else
547 d->setSizePolicy(QLayoutPolicy::Fixed, QLayoutPolicy::Expanding);
548
549 d->orientation = orientation;
550 emit orientationChanged();
551}
552
553/*!
554 \qmlproperty Item QtQuick.Controls::Slider::handle
555
556 This property holds the handle item.
557
558 \sa {Customizing Slider}
559*/
560QQuickItem *QQuickSlider::handle() const
561{
562 QQuickSliderPrivate *d = const_cast<QQuickSliderPrivate *>(d_func());
563 if (!d->handle)
564 d->executeHandle();
565 return d->handle;
566}
567
568void QQuickSlider::setHandle(QQuickItem *handle)
569{
570 Q_D(QQuickSlider);
571 if (d->handle == handle)
572 return;
573
574 QQuickControlPrivate::warnIfCustomizationNotSupported(this, handle, QStringLiteral("handle"));
575
576 if (!d->handle.isExecuting())
577 d->cancelHandle();
578
579 const qreal oldImplicitHandleWidth = implicitHandleWidth();
580 const qreal oldImplicitHandleHeight = implicitHandleHeight();
581
582 d->removeImplicitSizeListener(d->handle);
583 QQuickControlPrivate::hideOldItem(d->handle);
584 d->handle = handle;
585
586 if (handle) {
587 if (!handle->parentItem())
588 handle->setParentItem(this);
589 d->addImplicitSizeListener(handle);
590 }
591
592 if (!qFuzzyCompare(oldImplicitHandleWidth, implicitHandleWidth()))
593 emit implicitHandleWidthChanged();
594 if (!qFuzzyCompare(oldImplicitHandleHeight, implicitHandleHeight()))
595 emit implicitHandleHeightChanged();
596 if (!d->handle.isExecuting())
597 emit handleChanged();
598}
599
600/*!
601 \since QtQuick.Controls 2.1 (Qt 5.8)
602 \qmlmethod real QtQuick.Controls::Slider::valueAt(real position)
603
604 Returns the value for the given \a position.
605
606 \sa value, position
607*/
608qreal QQuickSlider::valueAt(qreal position) const
609{
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;
615}
616
617/*!
618 \since QtQuick.Controls 2.2 (Qt 5.9)
619 \qmlproperty bool QtQuick.Controls::Slider::live
620
621 This property holds whether the slider provides live updates for the \l value
622 property while the handle is dragged.
623
624 The default value is \c true.
625
626 \sa value, valueAt()
627*/
628bool QQuickSlider::live() const
629{
630 Q_D(const QQuickSlider);
631 return d->live;
632}
633
634void QQuickSlider::setLive(bool live)
635{
636 Q_D(QQuickSlider);
637 if (d->live == live)
638 return;
639
640 d->live = live;
641 emit liveChanged();
642}
643
644/*!
645 \qmlmethod void QtQuick.Controls::Slider::increase()
646
647 Increases the value by \l stepSize or \c 0.1 if stepSize is not defined.
648
649 \sa stepSize
650*/
651void QQuickSlider::increase()
652{
653 Q_D(QQuickSlider);
654 qreal step = qFuzzyIsNull(d->stepSize) ? 0.1 : d->stepSize;
655 setValue(d->value + step);
656}
657
658/*!
659 \qmlmethod void QtQuick.Controls::Slider::decrease()
660
661 Decreases the value by \l stepSize or \c 0.1 if stepSize is not defined.
662
663 \sa stepSize
664*/
665void QQuickSlider::decrease()
666{
667 Q_D(QQuickSlider);
668 qreal step = qFuzzyIsNull(d->stepSize) ? 0.1 : d->stepSize;
669 setValue(d->value - step);
670}
671
672/*!
673 \since QtQuick.Controls 2.5 (Qt 5.12)
674 \qmlproperty real QtQuick.Controls::Slider::touchDragThreshold
675
676 This property holds the threshold (in logical pixels) at which a touch drag event will be initiated.
677 The mouse drag threshold won't be affected.
678 The default value is \c Application.styleHints.startDragDistance.
679
680 \sa QStyleHints
681*/
682qreal QQuickSlider::touchDragThreshold() const
683{
684 Q_D(const QQuickSlider);
685 return d->touchDragThreshold;
686}
687
688void QQuickSlider::setTouchDragThreshold(qreal touchDragThreshold)
689{
690 Q_D(QQuickSlider);
691 if (d->touchDragThreshold == touchDragThreshold)
692 return;
693
694 d->touchDragThreshold = touchDragThreshold;
695 emit touchDragThresholdChanged();
696}
697
698void QQuickSlider::resetTouchDragThreshold()
699{
700 setTouchDragThreshold(-1);
701}
702
703/*!
704 \since QtQuick.Controls 2.5 (Qt 5.12)
705 \qmlproperty real QtQuick.Controls::Slider::implicitHandleWidth
706 \readonly
707
708 This property holds the implicit handle width.
709
710 The value is equal to \c {handle ? handle.implicitWidth : 0}.
711
712 This is typically used, together with \l {Control::}{implicitContentWidth} and
713 \l {Control::}{implicitBackgroundWidth}, to calculate the \l {Item::}{implicitWidth}.
714
715 \sa implicitHandleHeight
716*/
717qreal QQuickSlider::implicitHandleWidth() const
718{
719 Q_D(const QQuickSlider);
720 if (!d->handle)
721 return 0;
722 return d->handle->implicitWidth();
723}
724
725/*!
726 \since QtQuick.Controls 2.5 (Qt 5.12)
727 \qmlproperty real QtQuick.Controls::Slider::implicitHandleHeight
728 \readonly
729
730 This property holds the implicit handle height.
731
732 The value is equal to \c {handle ? handle.implicitHeight : 0}.
733
734 This is typically used, together with \l {Control::}{implicitContentHeight} and
735 \l {Control::}{implicitBackgroundHeight}, to calculate the \l {Item::}{implicitHeight}.
736
737 \sa implicitHandleWidth
738*/
739qreal QQuickSlider::implicitHandleHeight() const
740{
741 Q_D(const QQuickSlider);
742 if (!d->handle)
743 return 0;
744 return d->handle->implicitHeight();
745}
746
747void QQuickSlider::keyPressEvent(QKeyEvent *event)
748{
749 Q_D(QQuickSlider);
750 QQuickControl::keyPressEvent(event);
751
752 const qreal oldValue = d->value;
753 if (d->orientation == Qt::Horizontal) {
754 if (event->key() == Qt::Key_Left) {
755 setPressed(true);
756 if (isMirrored())
757 increase();
758 else
759 decrease();
760 event->accept();
761 } else if (event->key() == Qt::Key_Right) {
762 setPressed(true);
763 if (isMirrored())
764 decrease();
765 else
766 increase();
767 event->accept();
768 }
769 } else {
770 if (event->key() == Qt::Key_Up) {
771 setPressed(true);
772 increase();
773 event->accept();
774 } else if (event->key() == Qt::Key_Down) {
775 setPressed(true);
776 decrease();
777 event->accept();
778 }
779 }
780 if (!qFuzzyCompare(d->value, oldValue))
781 emit moved();
782}
783
784void QQuickSlider::keyReleaseEvent(QKeyEvent *event)
785{
786 QQuickControl::keyReleaseEvent(event);
787 setPressed(false);
788}
789
790void QQuickSlider::mousePressEvent(QMouseEvent *event)
791{
792 Q_D(QQuickSlider);
793 QQuickControl::mousePressEvent(event);
794 d->handleMove(event->position(), event->timestamp());
795 setKeepMouseGrab(true);
796}
797
798#if QT_CONFIG(quicktemplates2_multitouch)
799void QQuickSlider::touchEvent(QTouchEvent *event)
800{
801 Q_D(QQuickSlider);
802 switch (event->type()) {
803 case QEvent::TouchUpdate:
804 for (const QTouchEvent::TouchPoint &point : event->points()) {
805 if (!d->acceptTouch(point))
806 continue;
807
808 switch (point.state()) {
809 case QEventPoint::Pressed:
810 d->handlePress(point.position(), event->timestamp());
811 break;
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)));
817 } else {
818 setKeepTouchGrab(QQuickDeliveryAgentPrivate::dragOverThreshold(point.position().y() - d->pressPoint.y(),
819 Qt::YAxis, point, qRound(d->touchDragThreshold)));
820 }
821 }
822 if (keepTouchGrab())
823 d->handleMove(point.position(), event->timestamp());
824 break;
825 case QEventPoint::Released:
826 d->handleRelease(point.position(), event->timestamp());
827 break;
828 default:
829 break;
830 }
831 }
832 break;
833
834 default:
835 QQuickControl::touchEvent(event);
836 break;
837 }
838}
839#endif
840
841#if QT_CONFIG(wheelevent)
842void QQuickSlider::wheelEvent(QWheelEvent *event)
843{
844 Q_D(QQuickSlider);
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);
853 if (wasMoved)
854 emit moved();
855 }
856}
857#endif
858
859void QQuickSlider::mirrorChange()
860{
861 QQuickControl::mirrorChange();
862 emit visualPositionChanged();
863}
864
865void QQuickSlider::componentComplete()
866{
867 Q_D(QQuickSlider);
868 d->executeHandle(true);
869 QQuickControl::componentComplete();
870 setValue(d->value);
871 d->updatePosition();
872}
873
874#if QT_CONFIG(accessibility)
875void QQuickSlider::accessibilityActiveChanged(bool active)
876{
877 QQuickControl::accessibilityActiveChanged(active);
878
879 Q_D(QQuickSlider);
880 if (active)
881 setAccessibleProperty("pressed", d->pressed);
882}
883
884QAccessible::Role QQuickSlider::accessibleRole() const
885{
886 return QAccessible::Slider;
887}
888#endif
889
890QT_END_NAMESPACE
891
892#include "moc_qquickslider_p.cpp"