diff options
author | J-P Nurmi <jpnurmi@qt.io> | 2016-09-20 10:02:44 +0200 |
---|---|---|
committer | J-P Nurmi <jpnurmi@qt.io> | 2016-09-20 11:50:39 +0000 |
commit | 7b9c4db132d03a24b63d1fb9f3d85c82b63089db (patch) | |
tree | c4cf2a7b35cc328eb8990b8676e0612059b880ff | |
parent | b3983692680a91023dc5f22608b4e84b46fae883 (diff) |
Switch/Delegate: improve dragging behavior
Don't start dragging the handle unless the initial press was at the
indicator, or the drag has reached the indicator area. This prevents
unnatural jumps when dragging far outside the indicator.
Change-Id: I2b31b319a347ab489f2de5c044e42d908827b425
Reviewed-by: Mitch Curtis <mitch.curtis@qt.io>
-rw-r--r-- | src/quicktemplates2/qquickswitch.cpp | 12 | ||||
-rw-r--r-- | src/quicktemplates2/qquickswitchdelegate.cpp | 12 | ||||
-rw-r--r-- | tests/auto/controls/data/tst_switch.qml | 34 | ||||
-rw-r--r-- | tests/auto/controls/data/tst_switchdelegate.qml | 34 |
4 files changed, 88 insertions, 4 deletions
diff --git a/src/quicktemplates2/qquickswitch.cpp b/src/quicktemplates2/qquickswitch.cpp index 27043c8b..a7d17e86 100644 --- a/src/quicktemplates2/qquickswitch.cpp +++ b/src/quicktemplates2/qquickswitch.cpp @@ -163,8 +163,16 @@ void QQuickSwitch::mouseMoveEvent(QMouseEvent *event) QQuickAbstractButton::mouseMoveEvent(event); const QPointF movePoint = event->localPos(); - if (!keepMouseGrab()) - setKeepMouseGrab(QQuickWindowPrivate::dragOverThreshold(movePoint.x() - d->pressPoint.x(), Qt::XAxis, event)); + if (!keepMouseGrab()) { + // don't start dragging the handle unless the initial press was at the indicator, + // or the drag has reached the indicator area. this prevents unnatural jumps when + // dragging far outside the indicator. + const qreal pressPos = d->positionAt(d->pressPoint); + const qreal movePos = d->positionAt(movePoint); + if ((pressPos >= 0.0 && pressPos <= 1.0) || (movePos >= 0.0 && movePos <= 1.0)) + setKeepMouseGrab(QQuickWindowPrivate::dragOverThreshold(movePoint.x() - d->pressPoint.x(), Qt::XAxis, event)); + } + if (keepMouseGrab()) setPosition(d->positionAt(movePoint)); } diff --git a/src/quicktemplates2/qquickswitchdelegate.cpp b/src/quicktemplates2/qquickswitchdelegate.cpp index e22d163a..62b677e5 100644 --- a/src/quicktemplates2/qquickswitchdelegate.cpp +++ b/src/quicktemplates2/qquickswitchdelegate.cpp @@ -153,8 +153,16 @@ void QQuickSwitchDelegate::mouseMoveEvent(QMouseEvent *event) QQuickItemDelegate::mouseMoveEvent(event); const QPointF movePoint = event->localPos(); - if (!keepMouseGrab()) - setKeepMouseGrab(QQuickWindowPrivate::dragOverThreshold(movePoint.x() - d->pressPoint.x(), Qt::XAxis, event)); + if (!keepMouseGrab()) { + // don't start dragging the handle unless the initial press was at the indicator, + // or the drag has reached the indicator area. this prevents unnatural jumps when + // dragging far outside the indicator. + const qreal pressPos = d->positionAt(d->pressPoint); + const qreal movePos = d->positionAt(movePoint); + if ((pressPos >= 0.0 && pressPos <= 1.0) || (movePos >= 0.0 && movePos <= 1.0)) + setKeepMouseGrab(QQuickWindowPrivate::dragOverThreshold(movePoint.x() - d->pressPoint.x(), Qt::XAxis, event)); + } + if (keepMouseGrab()) setPosition(d->positionAt(movePoint)); } diff --git a/tests/auto/controls/data/tst_switch.qml b/tests/auto/controls/data/tst_switch.qml index f854526c..93773e0d 100644 --- a/tests/auto/controls/data/tst_switch.qml +++ b/tests/auto/controls/data/tst_switch.qml @@ -267,6 +267,40 @@ TestCase { compare(control.pressed, false) verify(spy.success) + // press-drag-release from and to outside the indicator + spy.expectedSequence = [["pressedChanged", { "pressed": true, "checked": false }], + "pressed"] + mousePress(control, control.width) + compare(control.position, 0.0) + compare(control.checked, false) + compare(control.pressed, true) + verify(spy.success) + + mouseMove(control, control.width - control.rightPadding) + compare(control.position, 0.0) + compare(control.checked, false) + compare(control.pressed, true) + + mouseMove(control, control.width / 2) + compare(control.position, 0.5) + compare(control.checked, false) + compare(control.pressed, true) + + mouseMove(control, control.width - control.rightPadding) + compare(control.position, 1.0) + compare(control.checked, false) + compare(control.pressed, true) + + spy.expectedSequence = [["pressedChanged", { "pressed": false, "checked": false }], + ["checkedChanged", { "pressed": false, "checked": true }], + "released", + "clicked"] + mouseRelease(control, control.width) + compare(control.position, 1.0) + compare(control.checked, true) + compare(control.pressed, false) + verify(spy.success) + control.destroy() } diff --git a/tests/auto/controls/data/tst_switchdelegate.qml b/tests/auto/controls/data/tst_switchdelegate.qml index 6d23a403..8bc0e4c3 100644 --- a/tests/auto/controls/data/tst_switchdelegate.qml +++ b/tests/auto/controls/data/tst_switchdelegate.qml @@ -263,6 +263,40 @@ TestCase { compare(control.pressed, false) verify(spy.success) + // press-drag-release from and to outside the indicator + spy.expectedSequence = [["pressedChanged", { "pressed": true, "checked": false }], + "pressed"] + mousePress(control, control.width) + compare(control.position, 0.0) + compare(control.checked, false) + compare(control.pressed, true) + verify(spy.success) + + mouseMove(control, control.width - control.rightPadding) + compare(control.position, 0.0) + compare(control.checked, false) + compare(control.pressed, true) + + mouseMove(control, control.width / 2) + compare(control.position, 0.5) + compare(control.checked, false) + compare(control.pressed, true) + + mouseMove(control, control.width - control.rightPadding) + compare(control.position, 1.0) + compare(control.checked, false) + compare(control.pressed, true) + + spy.expectedSequence = [["pressedChanged", { "pressed": false, "checked": false }], + ["checkedChanged", { "pressed": false, "checked": true }], + "released", + "clicked"] + mouseRelease(control, control.width) + compare(control.position, 1.0) + compare(control.checked, true) + compare(control.pressed, false) + verify(spy.success) + control.destroy() } } |