aboutsummaryrefslogtreecommitdiffstats
path: root/src/quicktemplates/qquickslider.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/quicktemplates/qquickslider.cpp')
-rw-r--r--src/quicktemplates/qquickslider.cpp883
1 files changed, 883 insertions, 0 deletions
diff --git a/src/quicktemplates/qquickslider.cpp b/src/quicktemplates/qquickslider.cpp
new file mode 100644
index 0000000000..04b5589524
--- /dev/null
+++ b/src/quicktemplates/qquickslider.cpp
@@ -0,0 +1,883 @@
+// Copyright (C) 2017 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#include "qquickslider_p.h"
+#include "qquickcontrol_p_p.h"
+#include "qquickdeferredexecute_p_p.h"
+
+#include <QtQuick/private/qquickwindow_p.h>
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \qmltype Slider
+ \inherits Control
+//! \instantiates QQuickSlider
+ \inqmlmodule QtQuick.Controls
+ \since 5.7
+ \ingroup qtquickcontrols-input
+ \brief Used to select a value by sliding a handle along a track.
+
+ \image qtquickcontrols-slider.gif
+
+ Slider is used to select a value by sliding a handle along a track.
+
+ In the example below, custom \l from, \l value, and \l to values are set:
+
+ \code
+ Slider {
+ from: 1
+ value: 25
+ to: 100
+ }
+ \endcode
+
+ The \l position property is expressed as a fraction of the control's size,
+ in the range \c {0.0 - 1.0}. The \l visualPosition property is
+ the same, except that it is reversed in a
+ \l {Right-to-left User Interfaces}{right-to-left} application. The
+ visualPosition is useful for positioning the handle when styling Slider.
+ In the example above, \l visualPosition will be \c 0.24 in a left-to-right
+ application, and \c 0.76 in a right-to-left application.
+
+ For a slider that allows the user to select a range by providing two
+ handles, see \l RangeSlider.
+
+ \sa {Customizing Slider}, {Input Controls}
+*/
+
+/*!
+ \since QtQuick.Controls 2.2 (Qt 5.9)
+ \qmlsignal QtQuick.Controls::Slider::moved()
+
+ This signal is emitted when the slider has been interactively moved
+ by the user by either touch, mouse, wheel, or keys.
+*/
+
+class QQuickSliderPrivate : public QQuickControlPrivate
+{
+ Q_DECLARE_PUBLIC(QQuickSlider)
+
+public:
+ qreal snapPosition(qreal position) const;
+ qreal positionAt(const QPointF &point) const;
+ void setPosition(qreal position);
+ void updatePosition();
+
+ bool handlePress(const QPointF &point, ulong timestamp) override;
+ bool handleMove(const QPointF &point, ulong timestamp) override;
+ bool handleRelease(const QPointF &point, ulong timestamp) override;
+ void handleUngrab() override;
+
+ void cancelHandle();
+ void executeHandle(bool complete = false);
+
+ void itemImplicitWidthChanged(QQuickItem *item) override;
+ void itemImplicitHeightChanged(QQuickItem *item) override;
+ void itemDestroyed(QQuickItem *item) override;
+
+ qreal from = 0;
+ qreal to = 1;
+ qreal value = 0;
+ qreal position = 0;
+ qreal stepSize = 0;
+ qreal touchDragThreshold = -1; // in QQuickWindowPrivate::dragOverThreshold, '-1' implies using styleHints::startDragDistance()
+ bool live = true;
+ bool pressed = false;
+ QPointF pressPoint;
+ Qt::Orientation orientation = Qt::Horizontal;
+ QQuickSlider::SnapMode snapMode = QQuickSlider::NoSnap;
+ QQuickDeferredPointer<QQuickItem> handle;
+};
+
+qreal QQuickSliderPrivate::snapPosition(qreal position) const
+{
+ const qreal range = to - from;
+ if (qFuzzyIsNull(range))
+ return position;
+
+ const qreal effectiveStep = stepSize / range;
+ if (qFuzzyIsNull(effectiveStep))
+ return position;
+
+ return qRound(position / effectiveStep) * effectiveStep;
+}
+
+qreal QQuickSliderPrivate::positionAt(const QPointF &point) const
+{
+ Q_Q(const QQuickSlider);
+ qreal pos = 0.0;
+ if (orientation == Qt::Horizontal) {
+ const qreal hw = handle ? handle->width() : 0;
+ const qreal offset = hw / 2;
+ const qreal extent = q->availableWidth() - hw;
+ if (!qFuzzyIsNull(extent)) {
+ if (q->isMirrored())
+ pos = (q->width() - point.x() - q->rightPadding() - offset) / extent;
+ else
+ pos = (point.x() - q->leftPadding() - offset) / extent;
+ }
+ } else {
+ const qreal hh = handle ? handle->height() : 0;
+ const qreal offset = hh / 2;
+ const qreal extent = q->availableHeight() - hh;
+ if (!qFuzzyIsNull(extent))
+ pos = (q->height() - point.y() - q->bottomPadding() - offset) / extent;
+ }
+ return qBound<qreal>(0.0, pos, 1.0);
+}
+
+void QQuickSliderPrivate::setPosition(qreal pos)
+{
+ Q_Q(QQuickSlider);
+ pos = qBound<qreal>(0.0, pos, 1.0);
+ if (qFuzzyCompare(position, pos))
+ return;
+
+ position = pos;
+ emit q->positionChanged();
+ emit q->visualPositionChanged();
+}
+
+void QQuickSliderPrivate::updatePosition()
+{
+ qreal pos = 0;
+ if (!qFuzzyCompare(from, to))
+ pos = (value - from) / (to - from);
+ setPosition(pos);
+}
+
+bool QQuickSliderPrivate::handlePress(const QPointF &point, ulong timestamp)
+{
+ Q_Q(QQuickSlider);
+ QQuickControlPrivate::handlePress(point, timestamp);
+ pressPoint = point;
+ q->setPressed(true);
+ return true;
+}
+
+bool QQuickSliderPrivate::handleMove(const QPointF &point, ulong timestamp)
+{
+ Q_Q(QQuickSlider);
+ QQuickControlPrivate::handleMove(point, timestamp);
+ const qreal oldPos = position;
+ qreal pos = positionAt(point);
+ if (snapMode == QQuickSlider::SnapAlways)
+ pos = snapPosition(pos);
+ if (live)
+ q->setValue(q->valueAt(pos));
+ if (!live || snapMode == QQuickSlider::NoSnap || snapMode == QQuickSlider::SnapOnRelease)
+ setPosition(pos);
+ if (!qFuzzyCompare(pos, oldPos))
+ emit q->moved();
+ return true;
+}
+
+bool QQuickSliderPrivate::handleRelease(const QPointF &point, ulong timestamp)
+{
+ Q_Q(QQuickSlider);
+ QQuickControlPrivate::handleRelease(point, timestamp);
+ pressPoint = QPointF();
+ const qreal oldPos = position;
+ qreal pos = positionAt(point);
+ if (snapMode != QQuickSlider::NoSnap)
+ pos = snapPosition(pos);
+ qreal val = q->valueAt(pos);
+ if (!qFuzzyCompare(val, value))
+ q->setValue(val);
+ else if (snapMode != QQuickSlider::NoSnap)
+ setPosition(pos);
+ if (!qFuzzyCompare(pos, oldPos))
+ emit q->moved();
+ q->setKeepMouseGrab(false);
+ q->setKeepTouchGrab(false);
+ q->setPressed(false);
+ return true;
+}
+
+void QQuickSliderPrivate::handleUngrab()
+{
+ Q_Q(QQuickSlider);
+ QQuickControlPrivate::handleUngrab();
+ pressPoint = QPointF();
+ q->setPressed(false);
+}
+
+void QQuickSliderPrivate::cancelHandle()
+{
+ Q_Q(QQuickSlider);
+ quickCancelDeferred(q, handleName());
+}
+
+void QQuickSliderPrivate::executeHandle(bool complete)
+{
+ Q_Q(QQuickSlider);
+ if (handle.wasExecuted())
+ return;
+
+ if (!handle || complete)
+ quickBeginDeferred(q, handleName(), handle);
+ if (complete)
+ quickCompleteDeferred(q, handleName(), handle);
+}
+
+void QQuickSliderPrivate::itemImplicitWidthChanged(QQuickItem *item)
+{
+ Q_Q(QQuickSlider);
+ QQuickControlPrivate::itemImplicitWidthChanged(item);
+ if (item == handle)
+ emit q->implicitHandleWidthChanged();
+}
+
+void QQuickSliderPrivate::itemImplicitHeightChanged(QQuickItem *item)
+{
+ Q_Q(QQuickSlider);
+ QQuickControlPrivate::itemImplicitHeightChanged(item);
+ if (item == handle)
+ emit q->implicitHandleHeightChanged();
+}
+
+void QQuickSliderPrivate::itemDestroyed(QQuickItem *item)
+{
+ Q_Q(QQuickSlider);
+ QQuickControlPrivate::itemDestroyed(item);
+ if (item == handle) {
+ handle = nullptr;
+ emit q->handleChanged();
+ }
+}
+
+QQuickSlider::QQuickSlider(QQuickItem *parent)
+ : QQuickControl(*(new QQuickSliderPrivate), parent)
+{
+ Q_D(QQuickSlider);
+ d->setSizePolicy(QLayoutPolicy::Preferred, QLayoutPolicy::Fixed);
+ setActiveFocusOnTab(true);
+#ifdef Q_OS_MACOS
+ setFocusPolicy(Qt::TabFocus);
+#else
+ setFocusPolicy(Qt::StrongFocus);
+#endif
+ setAcceptedMouseButtons(Qt::LeftButton);
+#if QT_CONFIG(quicktemplates2_multitouch)
+ setAcceptTouchEvents(true);
+#endif
+#if QT_CONFIG(cursor)
+ setCursor(Qt::ArrowCursor);
+#endif
+}
+
+QQuickSlider::~QQuickSlider()
+{
+ Q_D(QQuickSlider);
+ d->removeImplicitSizeListener(d->handle);
+}
+
+/*!
+ \qmlproperty real QtQuick.Controls::Slider::from
+
+ This property holds the starting value for the range. The default value is \c 0.0.
+
+ \sa to, value
+*/
+qreal QQuickSlider::from() const
+{
+ Q_D(const QQuickSlider);
+ return d->from;
+}
+
+void QQuickSlider::setFrom(qreal from)
+{
+ Q_D(QQuickSlider);
+ if (qFuzzyCompare(d->from, from))
+ return;
+
+ d->from = from;
+ emit fromChanged();
+ if (isComponentComplete()) {
+ setValue(d->value);
+ d->updatePosition();
+ }
+}
+
+/*!
+ \qmlproperty real QtQuick.Controls::Slider::to
+
+ This property holds the end value for the range. The default value is \c 1.0.
+
+ \sa from, value
+*/
+qreal QQuickSlider::to() const
+{
+ Q_D(const QQuickSlider);
+ return d->to;
+}
+
+void QQuickSlider::setTo(qreal to)
+{
+ Q_D(QQuickSlider);
+ if (qFuzzyCompare(d->to, to))
+ return;
+
+ d->to = to;
+ emit toChanged();
+ if (isComponentComplete()) {
+ setValue(d->value);
+ d->updatePosition();
+ }
+}
+
+/*!
+ \qmlproperty real QtQuick.Controls::Slider::value
+
+ This property holds the value in the range \c from - \c to. The default value is \c 0.0.
+
+ \sa position
+*/
+qreal QQuickSlider::value() const
+{
+ Q_D(const QQuickSlider);
+ return d->value;
+}
+
+void QQuickSlider::setValue(qreal value)
+{
+ Q_D(QQuickSlider);
+ if (isComponentComplete())
+ value = d->from > d->to ? qBound(d->to, value, d->from) : qBound(d->from, value, d->to);
+
+ if (qFuzzyCompare(d->value, value))
+ return;
+
+ d->value = value;
+ d->updatePosition();
+ emit valueChanged();
+}
+
+/*!
+ \qmlproperty real QtQuick.Controls::Slider::position
+ \readonly
+
+ This property holds the logical position of the handle.
+
+ The position is expressed as a fraction of the control's size, in the range
+ \c {0.0 - 1.0}. For visualizing a slider, the right-to-left aware
+ \l visualPosition should be used instead.
+
+ \sa value, visualPosition, valueAt()
+*/
+qreal QQuickSlider::position() const
+{
+ Q_D(const QQuickSlider);
+ return d->position;
+}
+
+/*!
+ \qmlproperty real QtQuick.Controls::Slider::visualPosition
+ \readonly
+
+ This property holds the visual position of the handle.
+
+ The position is expressed as a fraction of the control's size, in the range
+ \c {0.0 - 1.0}. When the control is \l {Control::mirrored}{mirrored}, the
+ value is equal to \c {1.0 - position}. This makes the value suitable for
+ visualizing the slider, taking right-to-left support into account.
+
+ \sa position
+*/
+qreal QQuickSlider::visualPosition() const
+{
+ Q_D(const QQuickSlider);
+ if (d->orientation == Qt::Vertical || isMirrored())
+ return 1.0 - d->position;
+ return d->position;
+}
+
+/*!
+ \qmlproperty real QtQuick.Controls::Slider::stepSize
+
+ This property holds the step size. The default value is \c 0.0.
+
+ \sa snapMode, increase(), decrease()
+*/
+qreal QQuickSlider::stepSize() const
+{
+ Q_D(const QQuickSlider);
+ return d->stepSize;
+}
+
+void QQuickSlider::setStepSize(qreal step)
+{
+ Q_D(QQuickSlider);
+ if (qFuzzyCompare(d->stepSize, step))
+ return;
+
+ d->stepSize = step;
+ emit stepSizeChanged();
+}
+
+/*!
+ \qmlproperty enumeration QtQuick.Controls::Slider::snapMode
+
+ This property holds the snap mode.
+
+ The snap mode determines how the slider handle behaves with
+ regards to the \l stepSize.
+
+ Possible values:
+ \value Slider.NoSnap The slider does not snap (default).
+ \value Slider.SnapAlways The slider snaps while the handle is dragged.
+ \value Slider.SnapOnRelease The slider does not snap while being dragged, but only after the handle is released.
+
+ In the following table, the various modes are illustrated with animations.
+ The movement of the mouse cursor and the \l stepSize (\c 0.2) are identical
+ in each animation.
+
+ \table
+ \header
+ \row \li \b Value \li \b Example
+ \row \li \c Slider.NoSnap \li \image qtquickcontrols-slider-nosnap.gif
+ \row \li \c Slider.SnapAlways \li \image qtquickcontrols-slider-snapalways.gif
+ \row \li \c Slider.SnapOnRelease \li \image qtquickcontrols-slider-snaponrelease.gif
+ \endtable
+
+ \sa stepSize
+*/
+QQuickSlider::SnapMode QQuickSlider::snapMode() const
+{
+ Q_D(const QQuickSlider);
+ return d->snapMode;
+}
+
+void QQuickSlider::setSnapMode(SnapMode mode)
+{
+ Q_D(QQuickSlider);
+ if (d->snapMode == mode)
+ return;
+
+ d->snapMode = mode;
+ emit snapModeChanged();
+}
+
+/*!
+ \qmlproperty bool QtQuick.Controls::Slider::pressed
+
+ This property holds whether the slider is pressed by either touch, mouse,
+ or keys.
+*/
+bool QQuickSlider::isPressed() const
+{
+ Q_D(const QQuickSlider);
+ return d->pressed;
+}
+
+void QQuickSlider::setPressed(bool pressed)
+{
+ Q_D(QQuickSlider);
+ if (d->pressed == pressed)
+ return;
+
+ d->pressed = pressed;
+ setAccessibleProperty("pressed", pressed);
+ emit pressedChanged();
+}
+
+/*!
+ \since QtQuick.Controls 2.3 (Qt 5.10)
+ \qmlproperty bool QtQuick.Controls::Slider::horizontal
+ \readonly
+
+ This property holds whether the slider is horizontal.
+
+ \sa orientation
+*/
+bool QQuickSlider::isHorizontal() const
+{
+ Q_D(const QQuickSlider);
+ return d->orientation == Qt::Horizontal;
+}
+
+/*!
+ \since QtQuick.Controls 2.3 (Qt 5.10)
+ \qmlproperty bool QtQuick.Controls::Slider::vertical
+ \readonly
+
+ This property holds whether the slider is vertical.
+
+ \sa orientation
+*/
+bool QQuickSlider::isVertical() const
+{
+ Q_D(const QQuickSlider);
+ return d->orientation == Qt::Vertical;
+}
+
+/*!
+ \qmlproperty enumeration QtQuick.Controls::Slider::orientation
+
+ This property holds the orientation.
+
+ Possible values:
+ \value Qt.Horizontal Horizontal (default)
+ \value Qt.Vertical Vertical
+
+ \sa horizontal, vertical
+*/
+Qt::Orientation QQuickSlider::orientation() const
+{
+ Q_D(const QQuickSlider);
+ return d->orientation;
+}
+
+void QQuickSlider::setOrientation(Qt::Orientation orientation)
+{
+ Q_D(QQuickSlider);
+ if (d->orientation == orientation)
+ return;
+
+ if (orientation == Qt::Horizontal)
+ d->setSizePolicy(QLayoutPolicy::Preferred, QLayoutPolicy::Fixed);
+ else
+ d->setSizePolicy(QLayoutPolicy::Fixed, QLayoutPolicy::Preferred);
+
+ d->orientation = orientation;
+ emit orientationChanged();
+}
+
+/*!
+ \qmlproperty Item QtQuick.Controls::Slider::handle
+
+ This property holds the handle item.
+
+ \sa {Customizing Slider}
+*/
+QQuickItem *QQuickSlider::handle() const
+{
+ QQuickSliderPrivate *d = const_cast<QQuickSliderPrivate *>(d_func());
+ if (!d->handle)
+ d->executeHandle();
+ return d->handle;
+}
+
+void QQuickSlider::setHandle(QQuickItem *handle)
+{
+ Q_D(QQuickSlider);
+ if (d->handle == handle)
+ return;
+
+ QQuickControlPrivate::warnIfCustomizationNotSupported(this, handle, QStringLiteral("handle"));
+
+ if (!d->handle.isExecuting())
+ d->cancelHandle();
+
+ const qreal oldImplicitHandleWidth = implicitHandleWidth();
+ const qreal oldImplicitHandleHeight = implicitHandleHeight();
+
+ d->removeImplicitSizeListener(d->handle);
+ QQuickControlPrivate::hideOldItem(d->handle);
+ d->handle = handle;
+
+ if (handle) {
+ if (!handle->parentItem())
+ handle->setParentItem(this);
+ d->addImplicitSizeListener(handle);
+ }
+
+ if (!qFuzzyCompare(oldImplicitHandleWidth, implicitHandleWidth()))
+ emit implicitHandleWidthChanged();
+ if (!qFuzzyCompare(oldImplicitHandleHeight, implicitHandleHeight()))
+ emit implicitHandleHeightChanged();
+ if (!d->handle.isExecuting())
+ emit handleChanged();
+}
+
+/*!
+ \since QtQuick.Controls 2.1 (Qt 5.8)
+ \qmlmethod real QtQuick.Controls::Slider::valueAt(real position)
+
+ Returns the value for the given \a position.
+
+ \sa value, position
+*/
+qreal QQuickSlider::valueAt(qreal position) const
+{
+ Q_D(const QQuickSlider);
+ const qreal value = (d->to - d->from) * position;
+ if (qFuzzyIsNull(d->stepSize))
+ return d->from + value;
+ return d->from + qRound(value / d->stepSize) * d->stepSize;
+}
+
+/*!
+ \since QtQuick.Controls 2.2 (Qt 5.9)
+ \qmlproperty bool QtQuick.Controls::Slider::live
+
+ This property holds whether the slider provides live updates for the \l value
+ property while the handle is dragged.
+
+ The default value is \c true.
+
+ \sa value, valueAt()
+*/
+bool QQuickSlider::live() const
+{
+ Q_D(const QQuickSlider);
+ return d->live;
+}
+
+void QQuickSlider::setLive(bool live)
+{
+ Q_D(QQuickSlider);
+ if (d->live == live)
+ return;
+
+ d->live = live;
+ emit liveChanged();
+}
+
+/*!
+ \qmlmethod void QtQuick.Controls::Slider::increase()
+
+ Increases the value by \l stepSize or \c 0.1 if stepSize is not defined.
+
+ \sa stepSize
+*/
+void QQuickSlider::increase()
+{
+ Q_D(QQuickSlider);
+ qreal step = qFuzzyIsNull(d->stepSize) ? 0.1 : d->stepSize;
+ setValue(d->value + step);
+}
+
+/*!
+ \qmlmethod void QtQuick.Controls::Slider::decrease()
+
+ Decreases the value by \l stepSize or \c 0.1 if stepSize is not defined.
+
+ \sa stepSize
+*/
+void QQuickSlider::decrease()
+{
+ Q_D(QQuickSlider);
+ qreal step = qFuzzyIsNull(d->stepSize) ? 0.1 : d->stepSize;
+ setValue(d->value - step);
+}
+
+/*!
+ \since QtQuick.Controls 2.5 (Qt 5.12)
+ \qmlproperty qreal QtQuick.Controls::Slider::touchDragThreshold
+
+ This property holds the threshold (in logical pixels) at which a touch drag event will be initiated.
+ The mouse drag threshold won't be affected.
+ The default value is \c Qt.styleHints.startDragDistance.
+
+ \sa QStyleHints
+*/
+qreal QQuickSlider::touchDragThreshold() const
+{
+ Q_D(const QQuickSlider);
+ return d->touchDragThreshold;
+}
+
+void QQuickSlider::setTouchDragThreshold(qreal touchDragThreshold)
+{
+ Q_D(QQuickSlider);
+ if (d->touchDragThreshold == touchDragThreshold)
+ return;
+
+ d->touchDragThreshold = touchDragThreshold;
+ emit touchDragThresholdChanged();
+}
+
+void QQuickSlider::resetTouchDragThreshold()
+{
+ setTouchDragThreshold(-1);
+}
+
+/*!
+ \since QtQuick.Controls 2.5 (Qt 5.12)
+ \qmlproperty real QtQuick.Controls::Slider::implicitHandleWidth
+ \readonly
+
+ This property holds the implicit handle width.
+
+ The value is equal to \c {handle ? handle.implicitWidth : 0}.
+
+ This is typically used, together with \l {Control::}{implicitContentWidth} and
+ \l {Control::}{implicitBackgroundWidth}, to calculate the \l {Item::}{implicitWidth}.
+
+ \sa implicitHandleHeight
+*/
+qreal QQuickSlider::implicitHandleWidth() const
+{
+ Q_D(const QQuickSlider);
+ if (!d->handle)
+ return 0;
+ return d->handle->implicitWidth();
+}
+
+/*!
+ \since QtQuick.Controls 2.5 (Qt 5.12)
+ \qmlproperty real QtQuick.Controls::Slider::implicitHandleHeight
+ \readonly
+
+ This property holds the implicit handle height.
+
+ The value is equal to \c {handle ? handle.implicitHeight : 0}.
+
+ This is typically used, together with \l {Control::}{implicitContentHeight} and
+ \l {Control::}{implicitBackgroundHeight}, to calculate the \l {Item::}{implicitHeight}.
+
+ \sa implicitHandleWidth
+*/
+qreal QQuickSlider::implicitHandleHeight() const
+{
+ Q_D(const QQuickSlider);
+ if (!d->handle)
+ return 0;
+ return d->handle->implicitHeight();
+}
+
+void QQuickSlider::keyPressEvent(QKeyEvent *event)
+{
+ Q_D(QQuickSlider);
+ QQuickControl::keyPressEvent(event);
+
+ const qreal oldValue = d->value;
+ if (d->orientation == Qt::Horizontal) {
+ if (event->key() == Qt::Key_Left) {
+ setPressed(true);
+ if (isMirrored())
+ increase();
+ else
+ decrease();
+ event->accept();
+ } else if (event->key() == Qt::Key_Right) {
+ setPressed(true);
+ if (isMirrored())
+ decrease();
+ else
+ increase();
+ event->accept();
+ }
+ } else {
+ if (event->key() == Qt::Key_Up) {
+ setPressed(true);
+ increase();
+ event->accept();
+ } else if (event->key() == Qt::Key_Down) {
+ setPressed(true);
+ decrease();
+ event->accept();
+ }
+ }
+ if (!qFuzzyCompare(d->value, oldValue))
+ emit moved();
+}
+
+void QQuickSlider::keyReleaseEvent(QKeyEvent *event)
+{
+ QQuickControl::keyReleaseEvent(event);
+ setPressed(false);
+}
+
+void QQuickSlider::mousePressEvent(QMouseEvent *event)
+{
+ Q_D(QQuickSlider);
+ QQuickControl::mousePressEvent(event);
+ d->handleMove(event->position(), event->timestamp());
+ setKeepMouseGrab(true);
+}
+
+#if QT_CONFIG(quicktemplates2_multitouch)
+void QQuickSlider::touchEvent(QTouchEvent *event)
+{
+ Q_D(QQuickSlider);
+ switch (event->type()) {
+ case QEvent::TouchUpdate:
+ for (const QTouchEvent::TouchPoint &point : event->points()) {
+ if (!d->acceptTouch(point))
+ continue;
+
+ switch (point.state()) {
+ case QEventPoint::Pressed:
+ d->handlePress(point.position(), event->timestamp());
+ break;
+ case QEventPoint::Updated:
+ if (!keepTouchGrab()) {
+ if (d->orientation == Qt::Horizontal)
+ setKeepTouchGrab(QQuickWindowPrivate::dragOverThreshold(point.position().x() - d->pressPoint.x(), Qt::XAxis, &point, qRound(d->touchDragThreshold)));
+ else
+ setKeepTouchGrab(QQuickWindowPrivate::dragOverThreshold(point.position().y() - d->pressPoint.y(), Qt::YAxis, &point, qRound(d->touchDragThreshold)));
+ }
+ if (keepTouchGrab())
+ d->handleMove(point.position(), event->timestamp());
+ break;
+ case QEventPoint::Released:
+ d->handleRelease(point.position(), event->timestamp());
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+
+ default:
+ QQuickControl::touchEvent(event);
+ break;
+ }
+}
+#endif
+
+#if QT_CONFIG(wheelevent)
+void QQuickSlider::wheelEvent(QWheelEvent *event)
+{
+ Q_D(QQuickSlider);
+ QQuickControl::wheelEvent(event);
+ if (d->wheelEnabled) {
+ const qreal oldValue = d->value;
+ const QPointF angle = event->angleDelta();
+ const qreal delta = (qFuzzyIsNull(angle.y()) ? angle.x() : (event->inverted() ? -angle.y() : angle.y())) / int(QWheelEvent::DefaultDeltasPerStep);
+ const qreal step = qFuzzyIsNull(d->stepSize) ? 0.1 : d->stepSize;
+ setValue(oldValue + step * delta);
+ const bool wasMoved = !qFuzzyCompare(d->value, oldValue);
+ if (wasMoved)
+ emit moved();
+ }
+}
+#endif
+
+void QQuickSlider::mirrorChange()
+{
+ QQuickControl::mirrorChange();
+ emit visualPositionChanged();
+}
+
+void QQuickSlider::componentComplete()
+{
+ Q_D(QQuickSlider);
+ d->executeHandle(true);
+ QQuickControl::componentComplete();
+ setValue(d->value);
+ d->updatePosition();
+}
+
+#if QT_CONFIG(accessibility)
+void QQuickSlider::accessibilityActiveChanged(bool active)
+{
+ QQuickControl::accessibilityActiveChanged(active);
+
+ Q_D(QQuickSlider);
+ if (active)
+ setAccessibleProperty("pressed", d->pressed);
+}
+
+QAccessible::Role QQuickSlider::accessibleRole() const
+{
+ return QAccessible::Slider;
+}
+#endif
+
+QT_END_NAMESPACE
+
+#include "moc_qquickslider_p.cpp"