diff options
Diffstat (limited to 'src/quicktemplates2/qquickdial.cpp')
-rw-r--r-- | src/quicktemplates2/qquickdial.cpp | 246 |
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); |