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.cpp211
1 files changed, 176 insertions, 35 deletions
diff --git a/src/quicktemplates2/qquickdial.cpp b/src/quicktemplates2/qquickdial.cpp
index fbc73c2a..bb939dd9 100644
--- a/src/quicktemplates2/qquickdial.cpp
+++ b/src/quicktemplates2/qquickdial.cpp
@@ -77,6 +77,14 @@ QT_BEGIN_NAMESPACE
\sa {Customizing Dial}, {Input Controls}
*/
+/*!
+ \since QtQuick.Controls 2.2
+ \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);
@@ -88,6 +96,7 @@ class QQuickDialPrivate : public QQuickControlPrivate
public:
QQuickDialPrivate() :
+ touchId(-1),
from(0),
to(1),
value(0),
@@ -97,17 +106,24 @@ public:
pressed(false),
snapMode(QQuickDial::NoSnap),
wrap(false),
+ live(false),
handle(nullptr)
{
}
qreal valueAt(qreal position) const;
qreal snapPosition(qreal position) const;
- qreal positionAt(const QPoint &point) const;
+ qreal positionAt(const QPointF &point) const;
void setPosition(qreal position);
void updatePosition();
- bool isLargeChange(const QPoint &eventPos, qreal proposedPosition) const;
+ bool isLargeChange(const QPointF &eventPos, qreal proposedPosition) const;
+
+ void handlePress(const QPointF &point);
+ void handleMove(const QPointF &point);
+ void handleRelease(const QPointF &point);
+ void handleUngrab();
+ int touchId;
qreal from;
qreal to;
qreal value;
@@ -115,9 +131,10 @@ public:
qreal angle;
qreal stepSize;
bool pressed;
- QPoint pressPoint;
+ QPointF pressPoint;
QQuickDial::SnapMode snapMode;
bool wrap;
+ bool live;
QQuickItem *handle;
};
@@ -139,7 +156,7 @@ qreal QQuickDialPrivate::snapPosition(qreal position) const
return qRound(position / effectiveStep) * effectiveStep;
}
-qreal QQuickDialPrivate::positionAt(const QPoint &point) const
+qreal QQuickDialPrivate::positionAt(const QPointF &point) const
{
qreal yy = height / 2.0 - point.y();
qreal xx = point.x() - width / 2.0;
@@ -175,11 +192,68 @@ void QQuickDialPrivate::updatePosition()
setPosition(pos);
}
-bool QQuickDialPrivate::isLargeChange(const QPoint &eventPos, qreal proposedPosition) const
+bool QQuickDialPrivate::isLargeChange(const QPointF &eventPos, qreal proposedPosition) const
{
return qAbs(proposedPosition - position) >= 0.5 && eventPos.y() >= height / 2;
}
+void QQuickDialPrivate::handlePress(const QPointF &point)
+{
+ Q_Q(QQuickDial);
+ pressPoint = point;
+ q->setPressed(true);
+}
+
+void QQuickDialPrivate::handleMove(const QPointF &point)
+{
+ Q_Q(QQuickDial);
+ if (!q->keepMouseGrab())
+ return;
+ const qreal oldPos = position;
+ qreal pos = positionAt(point);
+ if (snapMode == QQuickDial::SnapAlways)
+ pos = snapPosition(pos);
+
+ if (wrap || (!wrap && !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)
+{
+ Q_Q(QQuickDial);
+ if (q->keepMouseGrab()) {
+ const qreal oldPos = position;
+ qreal pos = positionAt(point);
+ if (snapMode != QQuickDial::NoSnap)
+ pos = snapPosition(pos);
+
+ if (wrap || (!wrap && !isLargeChange(point, pos)))
+ q->setValue(valueAt(pos));
+ if (!qFuzzyCompare(pos, oldPos))
+ emit q->moved();
+
+ q->setKeepMouseGrab(false);
+ }
+
+ q->setPressed(false);
+ pressPoint = QPointF();
+ touchId = -1;
+}
+
+void QQuickDialPrivate::handleUngrab()
+{
+ Q_Q(QQuickDial);
+ pressPoint = QPointF();
+ touchId = -1;
+ q->setPressed(false);
+}
+
QQuickDial::QQuickDial(QQuickItem *parent) :
QQuickControl(*(new QQuickDialPrivate), parent)
{
@@ -248,11 +322,12 @@ void QQuickDial::setTo(qreal to)
This property holds the value in the range \c from - \c to. The default
value is \c 0.0.
- Unlike the \l position property, the \c value is not updated while the
- handle is dragged. The value is updated after the value has been chosen
- and the dial has been released.
+ Unlike the \l position property, the \c value is not updated by default
+ while the handle is dragged. The value is updated after the value has
+ been chosen and the dial has been released. The \l live property can be
+ used to make the dial provide live updates for the \c value property.
- \sa position
+ \sa position, live
*/
qreal QQuickDial::value() const
{
@@ -447,6 +522,33 @@ void QQuickDial::setPressed(bool pressed)
}
/*!
+ \since QtQuick.Controls 2.2
+ \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 false.
+
+ \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.
@@ -505,6 +607,7 @@ void QQuickDial::setHandle(QQuickItem *handle)
void QQuickDial::keyPressEvent(QKeyEvent *event)
{
Q_D(QQuickDial);
+ const qreal oldValue = d->value;
switch (event->key()) {
case Qt::Key_Left:
case Qt::Key_Down:
@@ -539,6 +642,8 @@ void QQuickDial::keyPressEvent(QKeyEvent *event)
QQuickControl::keyPressEvent(event);
break;
}
+ if (!qFuzzyCompare(d->value, oldValue))
+ emit moved();
}
void QQuickDial::keyReleaseEvent(QKeyEvent *event)
@@ -551,8 +656,7 @@ void QQuickDial::mousePressEvent(QMouseEvent *event)
{
Q_D(QQuickDial);
QQuickControl::mousePressEvent(event);
- d->pressPoint = event->pos();
- setPressed(true);
+ d->handlePress(event->localPos());
}
void QQuickDial::mouseMoveEvent(QMouseEvent *event)
@@ -560,50 +664,87 @@ void QQuickDial::mouseMoveEvent(QMouseEvent *event)
Q_D(QQuickDial);
QQuickControl::mouseMoveEvent(event);
if (!keepMouseGrab()) {
- bool overXDragThreshold = QQuickWindowPrivate::dragOverThreshold(event->pos().x() - d->pressPoint.x(), Qt::XAxis, event);
+ bool overXDragThreshold = QQuickWindowPrivate::dragOverThreshold(event->localPos().x() - d->pressPoint.x(), Qt::XAxis, event);
setKeepMouseGrab(overXDragThreshold);
if (!overXDragThreshold) {
- bool overYDragThreshold = QQuickWindowPrivate::dragOverThreshold(event->pos().y() - d->pressPoint.y(), Qt::YAxis, event);
+ bool overYDragThreshold = QQuickWindowPrivate::dragOverThreshold(event->localPos().y() - d->pressPoint.y(), Qt::YAxis, event);
setKeepMouseGrab(overYDragThreshold);
}
}
- if (keepMouseGrab()) {
- qreal pos = d->positionAt(event->pos());
- if (d->snapMode == SnapAlways)
- pos = d->snapPosition(pos);
-
- if (d->wrap || (!d->wrap && !d->isLargeChange(event->pos(), pos)))
- d->setPosition(pos);
- }
+ d->handleMove(event->localPos());
}
void QQuickDial::mouseReleaseEvent(QMouseEvent *event)
{
Q_D(QQuickDial);
QQuickControl::mouseReleaseEvent(event);
+ d->handleRelease(event->localPos());
+}
- if (keepMouseGrab()) {
- qreal pos = d->positionAt(event->pos());
- if (d->snapMode != NoSnap)
- pos = d->snapPosition(pos);
+void QQuickDial::mouseUngrabEvent()
+{
+ Q_D(QQuickDial);
+ QQuickControl::mouseUngrabEvent();
+ d->handleUngrab();
+}
- if (d->wrap || (!d->wrap && !d->isLargeChange(event->pos(), pos)))
- setValue(d->valueAt(pos));
+void QQuickDial::touchEvent(QTouchEvent *event)
+{
+ Q_D(QQuickDial);
+ switch (event->type()) {
+ case QEvent::TouchBegin:
+ if (d->touchId == -1) {
+ const QTouchEvent::TouchPoint point = event->touchPoints().first();
+ d->touchId = point.id();
+ d->handlePress(point.pos());
+ } else {
+ event->ignore();
+ }
+ break;
- setKeepMouseGrab(false);
- }
+ case QEvent::TouchUpdate:
+ for (const QTouchEvent::TouchPoint &point : event->touchPoints()) {
+ if (point.id() != d->touchId)
+ continue;
+
+ if (!keepMouseGrab()) {
+ bool overXDragThreshold = QQuickWindowPrivate::dragOverThreshold(point.pos().x() - d->pressPoint.x(), Qt::XAxis, &point);
+ setKeepMouseGrab(overXDragThreshold);
+
+ if (!overXDragThreshold) {
+ bool overYDragThreshold = QQuickWindowPrivate::dragOverThreshold(point.pos().y() - d->pressPoint.y(), Qt::YAxis, &point);
+ setKeepMouseGrab(overYDragThreshold);
+ }
+ }
+ d->handleMove(point.pos());
+ }
+ break;
- setPressed(false);
- d->pressPoint = QPoint();
+ case QEvent::TouchEnd:
+ for (const QTouchEvent::TouchPoint &point : event->touchPoints()) {
+ if (point.id() != d->touchId)
+ continue;
+
+ d->handleRelease(point.pos());
+ }
+ break;
+
+ case QEvent::TouchCancel:
+ d->handleUngrab();
+ break;
+
+ default:
+ QQuickControl::touchEvent(event);
+ break;
+ }
}
-void QQuickDial::mouseUngrabEvent()
+void QQuickDial::touchUngrabEvent()
{
Q_D(QQuickDial);
- QQuickControl::mouseUngrabEvent();
- d->pressPoint = QPoint();
- setPressed(false);
+ QQuickControl::touchUngrabEvent();
+ d->handleUngrab();
}
void QQuickDial::wheelEvent(QWheelEvent *event)