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.cpp246
1 files changed, 190 insertions, 56 deletions
diff --git a/src/quicktemplates2/qquickdial.cpp b/src/quicktemplates2/qquickdial.cpp
index fbc73c2a..198bd631 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);
@@ -87,27 +95,35 @@ class QQuickDialPrivate : public QQuickControlPrivate
Q_DECLARE_PUBLIC(QQuickDial)
public:
- QQuickDialPrivate() :
- from(0),
- to(1),
- value(0),
- position(0),
- angle(startAngle),
- stepSize(0),
- pressed(false),
- snapMode(QQuickDial::NoSnap),
- wrap(false),
- handle(nullptr)
+ QQuickDialPrivate()
+ : touchId(-1),
+ from(0),
+ to(1),
+ value(0),
+ position(0),
+ angle(startAngle),
+ stepSize(0),
+ pressed(false),
+ snapMode(QQuickDial::NoSnap),
+ wrap(false),
+ live(true),
+ 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,13 +192,71 @@ 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;
}
-QQuickDial::QQuickDial(QQuickItem *parent) :
- QQuickControl(*(new QQuickDialPrivate), parent)
+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() && !q->keepTouchGrab())
+ 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() || q->keepTouchGrab()) {
+ 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->setKeepTouchGrab(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)
{
setActiveFocusOnTab(true);
setAcceptedMouseButtons(Qt::LeftButton);
@@ -248,11 +323,7 @@ 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.
-
- \sa position
+ \sa position, live
*/
qreal QQuickDial::value() const
{
@@ -282,8 +353,6 @@ void QQuickDial::setValue(qreal value)
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}.
- Unlike the \l value property, the \c position is continuously updated while
- the handle is dragged.
\sa value, angle
*/
@@ -299,9 +368,6 @@ qreal QQuickDial::position() const
This property holds the angle of the handle.
- Like the \l position property, angle is continuously updated while the
- handle is dragged.
-
The range is from \c -140 degrees to \c 140 degrees.
\sa position
@@ -447,6 +513,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 true.
+
+ \sa value, valueAt()
+*/
+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.
@@ -495,7 +588,7 @@ void QQuickDial::setHandle(QQuickItem *handle)
if (handle == d->handle)
return;
- d->deleteDelegate(d->handle);
+ QQuickControlPrivate::destroyDelegate(d->handle, this);
d->handle = handle;
if (d->handle && !d->handle->parentItem())
d->handle->setParentItem(this);
@@ -505,6 +598,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 +633,8 @@ void QQuickDial::keyPressEvent(QKeyEvent *event)
QQuickControl::keyPressEvent(event);
break;
}
+ if (!qFuzzyCompare(d->value, oldValue))
+ emit moved();
}
void QQuickDial::keyReleaseEvent(QKeyEvent *event)
@@ -551,8 +647,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,52 +655,90 @@ 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());
+}
+
+void QQuickDial::mouseUngrabEvent()
+{
+ Q_D(QQuickDial);
+ QQuickControl::mouseUngrabEvent();
+ d->handleUngrab();
+}
+
+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;
- if (keepMouseGrab()) {
- qreal pos = d->positionAt(event->pos());
- if (d->snapMode != NoSnap)
- pos = d->snapPosition(pos);
+ case QEvent::TouchUpdate:
+ for (const QTouchEvent::TouchPoint &point : event->touchPoints()) {
+ if (point.id() != d->touchId)
+ continue;
+
+ if (!keepTouchGrab()) {
+ bool overXDragThreshold = QQuickWindowPrivate::dragOverThreshold(point.pos().x() - d->pressPoint.x(), Qt::XAxis, &point);
+ setKeepTouchGrab(overXDragThreshold);
+
+ if (!overXDragThreshold) {
+ bool overYDragThreshold = QQuickWindowPrivate::dragOverThreshold(point.pos().y() - d->pressPoint.y(), Qt::YAxis, &point);
+ setKeepTouchGrab(overYDragThreshold);
+ }
+ }
+ d->handleMove(point.pos());
+ }
+ break;
- if (d->wrap || (!d->wrap && !d->isLargeChange(event->pos(), pos)))
- setValue(d->valueAt(pos));
+ case QEvent::TouchEnd:
+ for (const QTouchEvent::TouchPoint &point : event->touchPoints()) {
+ if (point.id() != d->touchId)
+ continue;
- setKeepMouseGrab(false);
- }
+ d->handleRelease(point.pos());
+ }
+ break;
- setPressed(false);
- d->pressPoint = QPoint();
+ 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();
}
+#if QT_CONFIG(wheelevent)
void QQuickDial::wheelEvent(QWheelEvent *event)
{
Q_D(QQuickDial);
@@ -619,6 +752,7 @@ void QQuickDial::wheelEvent(QWheelEvent *event)
event->setAccepted(!qFuzzyCompare(d->value, oldValue));
}
}
+#endif
void QQuickDial::mirrorChange()
{
@@ -634,7 +768,7 @@ void QQuickDial::componentComplete()
d->updatePosition();
}
-#ifndef QT_NO_ACCESSIBILITY
+#if QT_CONFIG(accessibility)
void QQuickDial::accessibilityActiveChanged(bool active)
{
QQuickControl::accessibilityActiveChanged(active);