diff options
author | Mitch Curtis <mitch.curtis@theqtcompany.com> | 2016-04-15 16:41:26 +0200 |
---|---|---|
committer | Mitch Curtis <mitch.curtis@theqtcompany.com> | 2016-04-19 10:41:44 +0000 |
commit | e253427f93248983d18055c5020094799a2c6b3b (patch) | |
tree | 6daec4a792e0a68b236f0c11a891e7cb72e08907 /src/quicktemplates2/qquickdial.cpp | |
parent | 30b2d62262e4ecfadf89dc0ee34644bebe5194fc (diff) |
Dial: add wrap property
This works by preventing changes in position that are considered
too large. A change is considered too large when the difference
between the old and new positions is greater than or equal to 0.5
*and* the position of the mouse is below the center of the dial.
This effectively makes it impossible to drag the dial from left
to right when the mouse is below its center, but still allows
doing so above its center.
This is useful for applications such as volume dials, where a
large change can be dangerous.
Change-Id: I1d7800e5ba16dbe0642974b8e53d8fcd921a01d7
Reviewed-by: J-P Nurmi <jpnurmi@qt.io>
Diffstat (limited to 'src/quicktemplates2/qquickdial.cpp')
-rw-r--r-- | src/quicktemplates2/qquickdial.cpp | 48 |
1 files changed, 45 insertions, 3 deletions
diff --git a/src/quicktemplates2/qquickdial.cpp b/src/quicktemplates2/qquickdial.cpp index 7f73d399..e1084978 100644 --- a/src/quicktemplates2/qquickdial.cpp +++ b/src/quicktemplates2/qquickdial.cpp @@ -94,6 +94,7 @@ public: stepSize(0), pressed(false), snapMode(QQuickDial::NoSnap), + wrap(true), handle(nullptr) { } @@ -103,6 +104,7 @@ public: qreal positionAt(const QPoint &point) const; void setPosition(qreal position); void updatePosition(); + bool isLargeChange(const QPoint &eventPos, qreal proposedPosition) const; qreal from; qreal to; @@ -113,6 +115,7 @@ public: bool pressed; QPoint pressPoint; QQuickDial::SnapMode snapMode; + bool wrap; QQuickItem *handle; }; @@ -164,6 +167,11 @@ void QQuickDialPrivate::updatePosition() setPosition(pos); } +bool QQuickDialPrivate::isLargeChange(const QPoint &eventPos, qreal proposedPosition) const +{ + return qAbs(proposedPosition - position) >= 0.5 && eventPos.y() >= height / 2; +} + QQuickDial::QQuickDial(QQuickItem *parent) : QQuickControl(*(new QQuickDialPrivate), parent) { @@ -349,6 +357,33 @@ void QQuickDial::setSnapMode(SnapMode mode) } /*! + \qmlproperty bool Qt.labs.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 \e "zero" position will result in the handle being positioned at the + opposite side, and vice versa. + + The default value is \c true. +*/ +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 Qt.labs.controls::Dial::pressed This property holds whether the dial is pressed. @@ -508,7 +543,9 @@ void QQuickDial::mouseMoveEvent(QMouseEvent *event) qreal pos = d->positionAt(event->pos()); if (d->snapMode == SnapAlways) pos = d->snapPosition(pos); - d->setPosition(pos); + + if (d->wrap || (!d->wrap && !d->isLargeChange(event->pos(), pos))) + d->setPosition(pos); } } @@ -516,15 +553,20 @@ void QQuickDial::mouseReleaseEvent(QMouseEvent *event) { Q_D(QQuickDial); QQuickControl::mouseReleaseEvent(event); - d->pressPoint = QPoint(); + if (keepMouseGrab()) { qreal pos = d->positionAt(event->pos()); if (d->snapMode != NoSnap) pos = d->snapPosition(pos); - setValue(d->valueAt(pos)); + + if (d->wrap || (!d->wrap && !d->isLargeChange(event->pos(), pos))) + setValue(d->valueAt(pos)); + setKeepMouseGrab(false); } + setPressed(false); + d->pressPoint = QPoint(); } void QQuickDial::mouseUngrabEvent() |