aboutsummaryrefslogtreecommitdiffstats
path: root/src/quicktemplates2/qquickdial.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/quicktemplates2/qquickdial.cpp')
-rw-r--r--src/quicktemplates2/qquickdial.cpp859
1 files changed, 859 insertions, 0 deletions
diff --git a/src/quicktemplates2/qquickdial.cpp b/src/quicktemplates2/qquickdial.cpp
new file mode 100644
index 0000000000..24783c9adb
--- /dev/null
+++ b/src/quicktemplates2/qquickdial.cpp
@@ -0,0 +1,859 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qquickdial_p.h"
+#include "qquickdeferredexecute_p_p.h"
+
+#include <QtCore/qmath.h>
+#include <QtQuick/private/qquickflickable_p.h>
+#include <QtQuickTemplates2/private/qquickcontrol_p_p.h>
+
+#include <cmath>
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \qmltype Dial
+ \inherits Control
+//! \instantiates QQuickDial
+ \inqmlmodule QtQuick.Controls
+ \since 5.7
+ \ingroup qtquickcontrols2-input
+ \brief Circular dial that is rotated to set a value.
+
+ The Dial is similar to a traditional dial knob that is found on devices
+ such as stereos or industrial equipment. It allows the user to specify a
+ value within a range.
+
+ \image qtquickcontrols2-dial-no-wrap.gif
+
+ The value of the dial is set with the \l value property. The range is
+ set with the \l from and \l to properties. To enable or disable wrapping,
+ use the \l wrap property.
+
+ The dial can be manipulated with a keyboard. It supports the following
+ actions:
+
+ \table
+ \header \li \b {Action} \li \b {Key}
+ \row \li Decrease \l value by \l stepSize \li \c Qt.Key_Left
+ \row \li Decrease \l value by \l stepSize \li \c Qt.Key_Down
+ \row \li Set \l value to \l from \li \c Qt.Key_Home
+ \row \li Increase \l value by \l stepSize \li \c Qt.Key_Right
+ \row \li Increase \l value by \l stepSize \li \c Qt.Key_Up
+ \row \li Set \l value to \l to \li \c Qt.Key_End
+ \endtable
+
+ \include qquickdial.qdocinc inputMode
+
+ \sa {Customizing Dial}, {Input Controls}
+*/
+
+/*!
+ \since QtQuick.Controls 2.2 (Qt 5.9)
+ \qmlsignal QtQuick.Controls::Dial::moved()
+
+ This signal is emitted when the dial has been interactively moved
+ by the user by either touch, mouse, or keys.
+*/
+
+static const qreal startAngleRadians = (M_PI * 2.0) * (4.0 / 6.0);
+static const qreal startAngle = -140;
+static const qreal endAngleRadians = (M_PI * 2.0) * (5.0 / 6.0);
+static const qreal endAngle = 140;
+
+class QQuickDialPrivate : public QQuickControlPrivate
+{
+ Q_DECLARE_PUBLIC(QQuickDial)
+
+public:
+ qreal valueAt(qreal position) const;
+ qreal snapPosition(qreal position) const;
+ qreal positionAt(const QPointF &point) const;
+ qreal circularPositionAt(const QPointF &point) const;
+ qreal linearPositionAt(const QPointF &point) const;
+ void setPosition(qreal position);
+ void updatePosition();
+ bool isLargeChange(const QPointF &eventPos, qreal proposedPosition) const;
+ bool isHorizontalOrVertical() const;
+
+ void handlePress(const QPointF &point, ulong timestamp) override;
+ void handleMove(const QPointF &point, ulong timestamp) override;
+ void handleRelease(const QPointF &point, ulong timestamp) override;
+ void handleUngrab() override;
+
+ void cancelHandle();
+ void executeHandle(bool complete = false);
+
+ void updateAllValuesAreInteger();
+
+ qreal from = 0;
+ qreal to = 1;
+ qreal value = 0;
+ qreal position = 0;
+ qreal angle = startAngle;
+ qreal stepSize = 0;
+ QPointF pressPoint;
+ qreal positionBeforePress = 0;
+ QQuickDial::SnapMode snapMode = QQuickDial::NoSnap;
+ QQuickDial::InputMode inputMode = QQuickDial::Circular;
+ QQuickDeferredPointer<QQuickItem> handle;
+ bool wrap = false;
+ bool live = true;
+ bool pressed = false;
+ bool allValuesAreInteger = false;
+};
+
+qreal QQuickDialPrivate::valueAt(qreal position) const
+{
+ qreal value = from + (to - from) * position;
+
+ /* play nice with users expecting that integer from, to and stepSize leads to
+ integer values - given that we are using floating point internally (and in
+ the API of value), this does not hold, but it is easy enough to handle
+ */
+ if (allValuesAreInteger)
+ value = qRound(value);
+
+ return value;
+}
+
+qreal QQuickDialPrivate::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 QQuickDialPrivate::positionAt(const QPointF &point) const
+{
+ return inputMode == QQuickDial::Circular ? circularPositionAt(point) : linearPositionAt(point);
+}
+
+qreal QQuickDialPrivate::circularPositionAt(const QPointF &point) const
+{
+ qreal yy = height / 2.0 - point.y();
+ qreal xx = point.x() - width / 2.0;
+ qreal angle = (xx || yy) ? std::atan2(yy, xx) : 0;
+
+ if (angle < M_PI / -2)
+ angle = angle + M_PI * 2;
+
+ qreal normalizedAngle = (startAngleRadians - angle) / endAngleRadians;
+ return normalizedAngle;
+}
+
+qreal QQuickDialPrivate::linearPositionAt(const QPointF &point) const
+{
+ // This value determines the range (either horizontal or vertical)
+ // within which the dial can be dragged.
+ // The larger this value is, the further the drag distance
+ // must be to go from a position of e.g. 0.0 to 1.0.
+ qreal dragArea = 0;
+
+ // The linear input mode uses a "relative" input system,
+ // where the distance from the press point is used to calculate
+ // the change in position. Moving the mouse above the press
+ // point increases the position (when inputMode is Vertical),
+ // and vice versa. This prevents the dial from jumping when clicked.
+ qreal dragDistance = 0;
+
+ if (inputMode == QQuickDial::Horizontal) {
+ dragArea = width * 2;
+ dragDistance = pressPoint.x() - point.x();
+ } else {
+ dragArea = height * 2;
+ dragDistance = point.y() - pressPoint.y();
+ }
+ const qreal normalisedDifference = dragDistance / dragArea;
+ return qBound(qreal(0), positionBeforePress - normalisedDifference, qreal(1));
+}
+
+void QQuickDialPrivate::setPosition(qreal pos)
+{
+ Q_Q(QQuickDial);
+ pos = qBound<qreal>(qreal(0), pos, qreal(1));
+ if (qFuzzyCompare(position, pos))
+ return;
+
+ position = pos;
+
+ angle = startAngle + position * qAbs(endAngle - startAngle);
+
+ emit q->positionChanged();
+ emit q->angleChanged();
+}
+
+void QQuickDialPrivate::updatePosition()
+{
+ qreal pos = 0;
+ if (!qFuzzyCompare(from, to))
+ pos = (value - from) / (to - from);
+ setPosition(pos);
+}
+
+bool QQuickDialPrivate::isLargeChange(const QPointF &eventPos, qreal proposedPosition) const
+{
+ return qAbs(proposedPosition - position) >= qreal(0.5) && eventPos.y() >= height / 2;
+}
+
+bool QQuickDialPrivate::isHorizontalOrVertical() const
+{
+ return inputMode == QQuickDial::Horizontal || inputMode == QQuickDial::Vertical;
+}
+
+void QQuickDialPrivate::handlePress(const QPointF &point, ulong timestamp)
+{
+ Q_Q(QQuickDial);
+ QQuickControlPrivate::handlePress(point, timestamp);
+ pressPoint = point;
+ positionBeforePress = position;
+ q->setPressed(true);
+}
+
+void QQuickDialPrivate::handleMove(const QPointF &point, ulong timestamp)
+{
+ Q_Q(QQuickDial);
+ QQuickControlPrivate::handleMove(point, timestamp);
+ const qreal oldPos = position;
+ qreal pos = positionAt(point);
+ if (snapMode == QQuickDial::SnapAlways)
+ pos = snapPosition(pos);
+
+ if (wrap || (!wrap && (isHorizontalOrVertical() || !isLargeChange(point, pos)))) {
+ if (live)
+ q->setValue(valueAt(pos));
+ else
+ setPosition(pos);
+ if (!qFuzzyCompare(pos, oldPos))
+ emit q->moved();
+ }
+}
+
+void QQuickDialPrivate::handleRelease(const QPointF &point, ulong timestamp)
+{
+ Q_Q(QQuickDial);
+ QQuickControlPrivate::handleRelease(point, timestamp);
+ if (q->keepMouseGrab() || q->keepTouchGrab()) {
+ const qreal oldPos = position;
+ qreal pos = positionAt(point);
+ if (snapMode != QQuickDial::NoSnap)
+ pos = snapPosition(pos);
+
+ if (wrap || (!wrap && (isHorizontalOrVertical() || !isLargeChange(point, pos))))
+ q->setValue(valueAt(pos));
+ if (!qFuzzyCompare(pos, oldPos))
+ emit q->moved();
+
+ q->setKeepMouseGrab(false);
+ q->setKeepTouchGrab(false);
+ }
+
+ q->setPressed(false);
+ pressPoint = QPointF();
+ positionBeforePress = 0;
+}
+
+void QQuickDialPrivate::handleUngrab()
+{
+ Q_Q(QQuickDial);
+ QQuickControlPrivate::handleUngrab();
+ pressPoint = QPointF();
+ positionBeforePress = 0;
+ q->setPressed(false);
+}
+
+static inline QString handleName() { return QStringLiteral("handle"); }
+
+void QQuickDialPrivate::cancelHandle()
+{
+ Q_Q(QQuickDial);
+ quickCancelDeferred(q, handleName());
+}
+
+void QQuickDialPrivate::executeHandle(bool complete)
+{
+ Q_Q(QQuickDial);
+ if (handle.wasExecuted())
+ return;
+
+ if (!handle || complete)
+ quickBeginDeferred(q, handleName(), handle);
+ if (complete)
+ quickCompleteDeferred(q, handleName(), handle);
+}
+
+template<typename ...Real>
+static bool areRepresentableAsInteger(Real... numbers) {
+ auto check = [](qreal number) -> bool { return std::nearbyint(number) == number; };
+ return (... && check(numbers));
+}
+
+void QQuickDialPrivate::updateAllValuesAreInteger()
+{
+ allValuesAreInteger = areRepresentableAsInteger(to, from, stepSize) && stepSize != 0.0;
+}
+
+QQuickDial::QQuickDial(QQuickItem *parent)
+ : QQuickControl(*(new QQuickDialPrivate), parent)
+{
+ setActiveFocusOnTab(true);
+ setAcceptedMouseButtons(Qt::LeftButton);
+#if QT_CONFIG(quicktemplates2_multitouch)
+ setAcceptTouchEvents(true);
+#endif
+#if QT_CONFIG(cursor)
+ setCursor(Qt::ArrowCursor);
+#endif
+}
+
+/*!
+ \qmlproperty real QtQuick.Controls::Dial::from
+
+ This property holds the starting value for the range. The default value is \c 0.0.
+
+ \sa to, value
+*/
+qreal QQuickDial::from() const
+{
+ Q_D(const QQuickDial);
+ return d->from;
+}
+
+void QQuickDial::setFrom(qreal from)
+{
+ Q_D(QQuickDial);
+ if (qFuzzyCompare(d->from, from))
+ return;
+
+ d->from = from;
+ emit fromChanged();
+ d->updateAllValuesAreInteger();
+ if (isComponentComplete()) {
+ setValue(d->value);
+ d->updatePosition();
+ }
+}
+
+/*!
+ \qmlproperty real QtQuick.Controls::Dial::to
+
+ This property holds the end value for the range. The default value is
+ \c 1.0.
+
+ \sa from, value
+*/
+qreal QQuickDial::to() const
+{
+ Q_D(const QQuickDial);
+ return d->to;
+}
+
+void QQuickDial::setTo(qreal to)
+{
+ Q_D(QQuickDial);
+ if (qFuzzyCompare(d->to, to))
+ return;
+
+ d->to = to;
+ d->updateAllValuesAreInteger();
+ emit toChanged();
+ if (isComponentComplete()) {
+ setValue(d->value);
+ d->updatePosition();
+ }
+}
+
+/*!
+ \qmlproperty real QtQuick.Controls::Dial::value
+
+ This property holds the value in the range \c from - \c to. The default
+ value is \c 0.0.
+
+ \sa position, live
+*/
+qreal QQuickDial::value() const
+{
+ Q_D(const QQuickDial);
+ return d->value;
+}
+
+void QQuickDial::setValue(qreal value)
+{
+ Q_D(QQuickDial);
+ 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::Dial::position
+ \readonly
+
+ This property holds the logical position of the handle.
+
+ The position is expressed as a fraction of the control's angle range (the
+ range within which the handle can be moved) in the range \c {0.0 - 1.0}.
+
+ \sa value, angle
+*/
+qreal QQuickDial::position() const
+{
+ Q_D(const QQuickDial);
+ return d->position;
+}
+
+/*!
+ \qmlproperty real QtQuick.Controls::Dial::angle
+ \readonly
+
+ This property holds the angle of the handle.
+
+ The range is from \c -140 degrees to \c 140 degrees.
+
+ \sa position
+*/
+qreal QQuickDial::angle() const
+{
+ Q_D(const QQuickDial);
+ return d->angle;
+}
+
+/*!
+ \qmlproperty real QtQuick.Controls::Dial::stepSize
+
+ This property holds the step size.
+
+ The step size determines the amount by which the dial's value
+ is increased and decreased when interacted with via the keyboard.
+ For example, a step size of \c 0.2, will result in the dial's
+ value increasing and decreasing in increments of \c 0.2.
+
+ The step size is only respected for touch and mouse interaction
+ when \l snapMode is set to a value other than \c Dial.NoSnap.
+
+ The default value is \c 0.0, which results in an effective step
+ size of \c 0.1 for keyboard interaction.
+
+ \sa snapMode, increase(), decrease()
+*/
+qreal QQuickDial::stepSize() const
+{
+ Q_D(const QQuickDial);
+ return d->stepSize;
+}
+
+void QQuickDial::setStepSize(qreal step)
+{
+ Q_D(QQuickDial);
+ if (qFuzzyCompare(d->stepSize, step))
+ return;
+
+ d->stepSize = step;
+ d->updateAllValuesAreInteger();
+ emit stepSizeChanged();
+}
+
+/*!
+ \qmlproperty enumeration QtQuick.Controls::Dial::snapMode
+
+ This property holds the snap mode.
+
+ The snap mode works with the \l stepSize to allow the handle to snap to
+ certain points along the dial.
+
+ Possible values:
+ \value Dial.NoSnap The dial does not snap (default).
+ \value Dial.SnapAlways The dial snaps while the handle is dragged.
+ \value Dial.SnapOnRelease The dial does not snap while being dragged, but only after the handle is released.
+
+ \sa stepSize
+*/
+QQuickDial::SnapMode QQuickDial::snapMode() const
+{
+ Q_D(const QQuickDial);
+ return d->snapMode;
+}
+
+void QQuickDial::setSnapMode(SnapMode mode)
+{
+ Q_D(QQuickDial);
+ if (d->snapMode == mode)
+ return;
+
+ d->snapMode = mode;
+ emit snapModeChanged();
+}
+
+/*!
+ \since QtQuick.Controls 2.5 (Qt 5.12)
+ \qmlproperty enumeration QtQuick.Controls::Dial::inputMode
+
+ This property holds the input mode.
+
+ \include qquickdial.qdocinc inputMode
+
+ The default value is \c Dial.Circular.
+*/
+QQuickDial::InputMode QQuickDial::inputMode() const
+{
+ Q_D(const QQuickDial);
+ return d->inputMode;
+}
+
+void QQuickDial::setInputMode(QQuickDial::InputMode mode)
+{
+ Q_D(QQuickDial);
+ if (d->inputMode == mode)
+ return;
+
+ d->inputMode = mode;
+ emit inputModeChanged();
+}
+
+/*!
+ \qmlproperty bool QtQuick.Controls::Dial::wrap
+
+ This property holds whether the dial wraps when dragged.
+
+ For example, when this property is set to \c true, dragging the dial past
+ the \l to position will result in the handle being positioned at the
+ \l from position, and vice versa:
+
+ \image qtquickcontrols2-dial-wrap.gif
+
+ When this property is \c false, it's not possible to drag the dial across
+ the from and to values.
+
+ \image qtquickcontrols2-dial-no-wrap.gif
+
+ The default value is \c false.
+*/
+bool QQuickDial::wrap() const
+{
+ Q_D(const QQuickDial);
+ return d->wrap;
+}
+
+void QQuickDial::setWrap(bool wrap)
+{
+ Q_D(QQuickDial);
+ if (d->wrap == wrap)
+ return;
+
+ d->wrap = wrap;
+ emit wrapChanged();
+}
+
+/*!
+ \qmlproperty bool QtQuick.Controls::Dial::pressed
+
+ This property holds whether the dial is pressed.
+
+ The dial will be pressed when either the mouse is pressed over it, or a key
+ such as \c Qt.Key_Left is held down. If you'd prefer not to have the dial
+ be pressed upon key presses (due to styling reasons, for example), you can
+ use the \l {Keys}{Keys attached property}:
+
+ \code
+ Dial {
+ Keys.onLeftPressed: {}
+ }
+ \endcode
+
+ This will result in pressed only being \c true upon mouse presses.
+*/
+bool QQuickDial::isPressed() const
+{
+ Q_D(const QQuickDial);
+ return d->pressed;
+}
+
+void QQuickDial::setPressed(bool pressed)
+{
+ Q_D(QQuickDial);
+ if (d->pressed == pressed)
+ return;
+
+ d->pressed = pressed;
+ setAccessibleProperty("pressed", pressed);
+ emit pressedChanged();
+}
+
+/*!
+ \qmlproperty Item QtQuick.Controls::Dial::handle
+
+ This property holds the handle of the dial.
+
+ The handle acts as a visual indicator of the position of the dial.
+
+ \sa {Customizing Dial}
+*/
+QQuickItem *QQuickDial::handle() const
+{
+ QQuickDialPrivate *d = const_cast<QQuickDialPrivate *>(d_func());
+ if (!d->handle)
+ d->executeHandle();
+ return d->handle;
+}
+
+void QQuickDial::setHandle(QQuickItem *handle)
+{
+ Q_D(QQuickDial);
+ if (handle == d->handle)
+ return;
+
+ if (!d->handle.isExecuting())
+ d->cancelHandle();
+
+ QQuickControlPrivate::hideOldItem(d->handle);
+ d->handle = handle;
+ if (d->handle && !d->handle->parentItem())
+ d->handle->setParentItem(this);
+ if (!d->handle.isExecuting())
+ emit handleChanged();
+}
+
+/*!
+ \since QtQuick.Controls 2.2 (Qt 5.9)
+ \qmlproperty bool QtQuick.Controls::Dial::live
+
+ This property holds whether the dial provides live updates for the \l value
+ property while the handle is dragged.
+
+ The default value is \c true.
+
+ \sa value
+*/
+bool QQuickDial::live() const
+{
+ Q_D(const QQuickDial);
+ return d->live;
+}
+
+void QQuickDial::setLive(bool live)
+{
+ Q_D(QQuickDial);
+ if (d->live == live)
+ return;
+
+ d->live = live;
+ emit liveChanged();
+}
+
+/*!
+ \qmlmethod void QtQuick.Controls::Dial::increase()
+
+ Increases the value by \l stepSize, or \c 0.1 if stepSize is not defined.
+
+ \sa stepSize
+*/
+void QQuickDial::increase()
+{
+ Q_D(QQuickDial);
+ qreal step = qFuzzyIsNull(d->stepSize) ? 0.1 : d->stepSize;
+ setValue(d->value + step);
+}
+
+/*!
+ \qmlmethod void QtQuick.Controls::Dial::decrease()
+
+ Decreases the value by \l stepSize, or \c 0.1 if stepSize is not defined.
+
+ \sa stepSize
+*/
+void QQuickDial::decrease()
+{
+ Q_D(QQuickDial);
+ qreal step = qFuzzyIsNull(d->stepSize) ? 0.1 : d->stepSize;
+ setValue(d->value - step);
+}
+
+void QQuickDial::keyPressEvent(QKeyEvent *event)
+{
+ Q_D(QQuickDial);
+ const qreal oldValue = d->value;
+ switch (event->key()) {
+ case Qt::Key_Left:
+ case Qt::Key_Down:
+ setPressed(true);
+ if (isMirrored())
+ increase();
+ else
+ decrease();
+ break;
+
+ case Qt::Key_Right:
+ case Qt::Key_Up:
+ setPressed(true);
+ if (isMirrored())
+ decrease();
+ else
+ increase();
+ break;
+
+ case Qt::Key_Home:
+ setPressed(true);
+ setValue(isMirrored() ? d->to : d->from);
+ break;
+
+ case Qt::Key_End:
+ setPressed(true);
+ setValue(isMirrored() ? d->from : d->to);
+ break;
+
+ default:
+ event->ignore();
+ QQuickControl::keyPressEvent(event);
+ break;
+ }
+ if (!qFuzzyCompare(d->value, oldValue))
+ emit moved();
+}
+
+void QQuickDial::keyReleaseEvent(QKeyEvent *event)
+{
+ QQuickControl::keyReleaseEvent(event);
+ setPressed(false);
+}
+
+void QQuickDial::mousePressEvent(QMouseEvent *event)
+{
+ Q_D(QQuickDial);
+ QQuickControl::mousePressEvent(event);
+ d->handleMove(event->position(), event->timestamp());
+ setKeepMouseGrab(true);
+}
+
+#if QT_CONFIG(quicktemplates2_multitouch)
+void QQuickDial::touchEvent(QTouchEvent *event)
+{
+ Q_D(QQuickDial);
+ switch (event->type()) {
+ case QEvent::TouchUpdate:
+ for (const QTouchEvent::TouchPoint &point : event->points()) {
+ if (!d->acceptTouch(point))
+ continue;
+
+ switch (point.state()) {
+ case QEventPoint::Updated:
+ if (!keepTouchGrab()) {
+ bool overXDragThreshold = QQuickWindowPrivate::dragOverThreshold(point.position().x() - d->pressPoint.x(), Qt::XAxis, &point);
+ setKeepTouchGrab(overXDragThreshold);
+
+ if (!overXDragThreshold) {
+ bool overYDragThreshold = QQuickWindowPrivate::dragOverThreshold(point.position().y() - d->pressPoint.y(), Qt::YAxis, &point);
+ setKeepTouchGrab(overYDragThreshold);
+ }
+ }
+ if (keepTouchGrab())
+ d->handleMove(point.position(), event->timestamp());
+ break;
+
+ default:
+ QQuickControl::touchEvent(event);
+ break;
+ }
+ }
+ break;
+
+ default:
+ QQuickControl::touchEvent(event);
+ break;
+ }
+}
+#endif
+
+#if QT_CONFIG(wheelevent)
+void QQuickDial::wheelEvent(QWheelEvent *event)
+{
+ Q_D(QQuickDial);
+ 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())) / QWheelEvent::DefaultDeltasPerStep;
+ const qreal step = qFuzzyIsNull(d->stepSize) ? 0.1 : d->stepSize;
+ setValue(oldValue + step * delta);
+ event->setAccepted(!qFuzzyCompare(d->value, oldValue));
+ }
+}
+#endif
+
+void QQuickDial::mirrorChange()
+{
+ QQuickControl::mirrorChange();
+ emit angleChanged();
+}
+
+void QQuickDial::componentComplete()
+{
+ Q_D(QQuickDial);
+ d->executeHandle(true);
+ QQuickControl::componentComplete();
+ setValue(d->value);
+ d->updatePosition();
+}
+
+#if QT_CONFIG(accessibility)
+void QQuickDial::accessibilityActiveChanged(bool active)
+{
+ QQuickControl::accessibilityActiveChanged(active);
+
+ Q_D(QQuickDial);
+ if (active)
+ setAccessibleProperty("pressed", d->pressed);
+}
+
+QAccessible::Role QQuickDial::accessibleRole() const
+{
+ return QAccessible::Dial;
+}
+#endif
+
+QT_END_NAMESPACE