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