From 3f2cb85ac10b000a33781e5fa61b607f7effde07 Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Tue, 29 Nov 2016 11:32:34 +0100 Subject: Add Slider::moved() signal [ChangeLog][Controls][Slider] Added a moved() signal that is emitted whenever the slider is interactively moved by the user by using either touch, mouse, wheel, or keys. Task-number: QTBUG-57203 Change-Id: Iec1ed1342b004e396881e6eb48d694afdd10b648 Reviewed-by: Mitch Curtis --- src/quicktemplates2/qquickslider.cpp | 33 +++++++++++++--- src/quicktemplates2/qquickslider_p.h | 1 + tests/auto/controls/data/tst_slider.qml | 70 ++++++++++++++++++++++++++++----- 3 files changed, 90 insertions(+), 14 deletions(-) diff --git a/src/quicktemplates2/qquickslider.cpp b/src/quicktemplates2/qquickslider.cpp index d2d5da89..09a3a59c 100644 --- a/src/quicktemplates2/qquickslider.cpp +++ b/src/quicktemplates2/qquickslider.cpp @@ -75,6 +75,14 @@ QT_BEGIN_NAMESPACE \sa {Customizing Slider}, {Input Controls} */ +/*! + \since QtQuick.Controls 2.2 + \qmlsignal QtQuick.Controls::Slider::moved() + + This signal is emitted when the slider has been interactively moved + by the user by using either touch, mouse, wheel, or keys. +*/ + class QQuickSliderPrivate : public QQuickControlPrivate { Q_DECLARE_PUBLIC(QQuickSlider) @@ -120,23 +128,25 @@ qreal QQuickSliderPrivate::snapPosition(qreal position) const qreal QQuickSliderPrivate::positionAt(const QPoint &point) const { Q_Q(const QQuickSlider); + qreal pos = 0.0; if (orientation == Qt::Horizontal) { const qreal hw = handle ? handle->width() : 0; const qreal offset = hw / 2; const qreal extent = q->availableWidth() - hw; if (!qFuzzyIsNull(extent)) { if (q->isMirrored()) - return (q->width() - point.x() - q->rightPadding() - offset) / extent; - return (point.x() - q->leftPadding() - offset) / extent; + pos = (q->width() - point.x() - q->rightPadding() - offset) / extent; + else + pos = (point.x() - q->leftPadding() - offset) / extent; } } else { const qreal hh = handle ? handle->height() : 0; const qreal offset = hh / 2; const qreal extent = q->availableHeight() - hh; if (!qFuzzyIsNull(extent)) - return (q->height() - point.y() - q->bottomPadding() - offset) / extent; + pos = (q->height() - point.y() - q->bottomPadding() - offset) / extent; } - return 0; + return qBound(0.0, pos, 1.0); } void QQuickSliderPrivate::setPosition(qreal pos) @@ -507,6 +517,8 @@ void QQuickSlider::keyPressEvent(QKeyEvent *event) { Q_D(QQuickSlider); QQuickControl::keyPressEvent(event); + + const qreal oldValue = d->value; if (d->orientation == Qt::Horizontal) { if (event->key() == Qt::Key_Left) { setPressed(true); @@ -534,6 +546,8 @@ void QQuickSlider::keyPressEvent(QKeyEvent *event) event->accept(); } } + if (!qFuzzyCompare(d->value, oldValue)) + emit moved(); } void QQuickSlider::keyReleaseEvent(QKeyEvent *event) @@ -561,6 +575,7 @@ void QQuickSlider::mouseMoveEvent(QMouseEvent *event) setKeepMouseGrab(QQuickWindowPrivate::dragOverThreshold(event->pos().y() - d->pressPoint.y(), Qt::YAxis, event)); } if (keepMouseGrab()) { + const qreal oldPos = d->position; qreal pos = d->positionAt(event->pos()); if (d->snapMode == SnapAlways) pos = d->snapPosition(pos); @@ -568,6 +583,8 @@ void QQuickSlider::mouseMoveEvent(QMouseEvent *event) setValue(valueAt(pos)); else d->setPosition(pos); + if (!qFuzzyCompare(pos, oldPos)) + emit moved(); } } @@ -576,6 +593,7 @@ void QQuickSlider::mouseReleaseEvent(QMouseEvent *event) Q_D(QQuickSlider); QQuickControl::mouseReleaseEvent(event); d->pressPoint = QPoint(); + const qreal oldPos = d->position; qreal pos = d->positionAt(event->pos()); if (d->snapMode != NoSnap) pos = d->snapPosition(pos); @@ -584,6 +602,8 @@ void QQuickSlider::mouseReleaseEvent(QMouseEvent *event) setValue(val); else if (d->snapMode != NoSnap) d->setPosition(pos); + if (!qFuzzyCompare(pos, oldPos)) + emit moved(); setKeepMouseGrab(false); setPressed(false); } @@ -606,7 +626,10 @@ void QQuickSlider::wheelEvent(QWheelEvent *event) const qreal delta = (qFuzzyIsNull(angle.y()) ? angle.x() : angle.y()) / QWheelEvent::DefaultDeltasPerStep; const qreal step = qFuzzyIsNull(d->stepSize) ? 0.1 : d->stepSize; setValue(oldValue + step * delta); - event->setAccepted(!qFuzzyCompare(d->value, oldValue)); + const bool wasMoved = !qFuzzyCompare(d->value, oldValue); + if (wasMoved) + emit moved(); + event->setAccepted(wasMoved); } } diff --git a/src/quicktemplates2/qquickslider_p.h b/src/quicktemplates2/qquickslider_p.h index 7ddffc7e..7b96168a 100644 --- a/src/quicktemplates2/qquickslider_p.h +++ b/src/quicktemplates2/qquickslider_p.h @@ -127,6 +127,7 @@ Q_SIGNALS: void pressedChanged(); void orientationChanged(); void handleChanged(); + Q_REVISION(2) void moved(); protected: void keyPressEvent(QKeyEvent *event) override; diff --git a/tests/auto/controls/data/tst_slider.qml b/tests/auto/controls/data/tst_slider.qml index c5884273..a5d6d36d 100644 --- a/tests/auto/controls/data/tst_slider.qml +++ b/tests/auto/controls/data/tst_slider.qml @@ -224,55 +224,69 @@ TestCase { var control = slider.createObject(testCase, {orientation: data.orientation, live: data.live}) verify(control) + var pressedCount = 0 + var movedCount = 0 + var pressedSpy = signalSpy.createObject(control, {target: control, signalName: "pressedChanged"}) verify(pressedSpy.valid) + var movedSpy = signalSpy.createObject(control, {target: control, signalName: "moved"}) + verify(movedSpy.valid) + mousePress(control, 0, 0, Qt.LeftButton) - compare(pressedSpy.count, 1) + compare(pressedSpy.count, ++pressedCount) + compare(movedSpy.count, movedCount) compare(control.pressed, true) compare(control.value, 0.0) compare(control.position, 0.0) // mininum on the left in horizontal vs. at the bottom in vertical mouseMove(control, -control.width, 2 * control.height, 0, Qt.LeftButton) - compare(pressedSpy.count, 1) + compare(pressedSpy.count, pressedCount) + compare(movedSpy.count, movedCount) compare(control.pressed, true) compare(control.value, 0.0) compare(control.position, 0.0) mouseMove(control, control.width * 0.5, control.height * 0.5, 0, Qt.LeftButton) - compare(pressedSpy.count, 1) + compare(pressedSpy.count, pressedCount) + compare(movedSpy.count, ++movedCount) compare(control.pressed, true) compare(control.value, data.live ? 0.5 : 0.0) compare(control.position, 0.5) mouseRelease(control, control.width * 0.5, control.height * 0.5, Qt.LeftButton) - compare(pressedSpy.count, 2) + compare(pressedSpy.count, ++pressedCount) + compare(movedSpy.count, movedCount) compare(control.pressed, false) compare(control.value, 0.5) compare(control.position, 0.5) mousePress(control, control.width, control.height, Qt.LeftButton) - compare(pressedSpy.count, 3) + compare(pressedSpy.count, ++pressedCount) + compare(movedSpy.count, movedCount) compare(control.pressed, true) compare(control.value, 0.5) compare(control.position, 0.5) // maximum on the right in horizontal vs. at the top in vertical mouseMove(control, control.width * 2, -control.height, 0, Qt.LeftButton) - compare(pressedSpy.count, 3) + compare(pressedSpy.count, pressedCount) + compare(movedSpy.count, ++movedCount) compare(control.pressed, true) compare(control.value, data.live ? 1.0 : 0.5) compare(control.position, 1.0) mouseMove(control, control.width * 0.75, control.height * 0.25, 0, Qt.LeftButton) - compare(pressedSpy.count, 3) + compare(pressedSpy.count, pressedCount) + compare(movedSpy.count, ++movedCount) compare(control.pressed, true) compare(control.value, data.live ? control.position : 0.5) verify(control.position >= 0.75) mouseRelease(control, control.width * 0.25, control.height * 0.75, Qt.LeftButton) - compare(pressedSpy.count, 4) + compare(pressedSpy.count, ++pressedCount) + compare(movedSpy.count, ++movedCount) compare(control.pressed, false) compare(control.value, control.position) verify(control.value <= 0.25 && control.value >= 0.0) @@ -280,7 +294,8 @@ TestCase { // QTBUG-53846 mouseClick(control, control.width * 0.5, control.height * 0.5, Qt.LeftButton) - compare(pressedSpy.count, 6) + compare(movedSpy.count, ++movedCount) + compare(pressedSpy.count, pressedCount += 2) compare(control.value, 0.5) compare(control.position, 0.5) @@ -299,19 +314,27 @@ TestCase { verify(control) var pressedCount = 0 + var movedCount = 0 var pressedSpy = signalSpy.createObject(control, {target: control, signalName: "pressedChanged"}) verify(pressedSpy.valid) + var movedSpy = signalSpy.createObject(control, {target: control, signalName: "moved"}) + verify(movedSpy.valid) + control.forceActiveFocus() verify(control.activeFocus) + var oldValue = 0.0 control.value = 0.5 for (var d1 = 1; d1 <= 10; ++d1) { + oldValue = control.value keyPress(data.decrease) compare(control.pressed, true) compare(pressedSpy.count, ++pressedCount) + if (oldValue !== control.value) + compare(movedSpy.count, ++movedCount) compare(control.value, Math.max(0.0, 0.5 - d1 * 0.1)) compare(control.value, control.position) @@ -319,12 +342,16 @@ TestCase { keyRelease(data.decrease) compare(control.pressed, false) compare(pressedSpy.count, ++pressedCount) + compare(movedSpy.count, movedCount) } for (var i1 = 1; i1 <= 20; ++i1) { + oldValue = control.value keyPress(data.increase) compare(control.pressed, true) compare(pressedSpy.count, ++pressedCount) + if (oldValue !== control.value) + compare(movedSpy.count, ++movedCount) compare(control.value, Math.min(1.0, 0.0 + i1 * 0.1)) compare(control.value, control.position) @@ -332,14 +359,18 @@ TestCase { keyRelease(data.increase) compare(control.pressed, false) compare(pressedSpy.count, ++pressedCount) + compare(movedSpy.count, movedCount) } control.stepSize = 0.25 for (var d2 = 1; d2 <= 10; ++d2) { + oldValue = control.value keyPress(data.decrease) compare(control.pressed, true) compare(pressedSpy.count, ++pressedCount) + if (oldValue !== control.value) + compare(movedSpy.count, ++movedCount) compare(control.value, Math.max(0.0, 1.0 - d2 * 0.25)) compare(control.value, control.position) @@ -347,12 +378,16 @@ TestCase { keyRelease(data.decrease) compare(control.pressed, false) compare(pressedSpy.count, ++pressedCount) + compare(movedSpy.count, movedCount) } for (var i2 = 1; i2 <= 10; ++i2) { + oldValue = control.value keyPress(data.increase) compare(control.pressed, true) compare(pressedSpy.count, ++pressedCount) + if (oldValue !== control.value) + compare(movedSpy.count, ++movedCount) compare(control.value, Math.min(1.0, 0.0 + i2 * 0.25)) compare(control.value, control.position) @@ -360,6 +395,7 @@ TestCase { keyRelease(data.increase) compare(control.pressed, false) compare(pressedSpy.count, ++pressedCount) + compare(movedSpy.count, movedCount) } control.destroy() @@ -487,21 +523,34 @@ TestCase { var control = slider.createObject(testCase, {wheelEnabled: true, orientation: data.orientation}) verify(control) + var movedCount = 0 + var movedSpy = signalSpy.createObject(control, {target: control, signalName: "moved"}) + verify(movedSpy.valid) + compare(control.value, 0.0) mouseWheel(control, control.width / 2, control.height / 2, data.dx, data.dy) + compare(movedSpy.count, ++movedCount) compare(control.value, 0.1) compare(control.position, 0.1) control.stepSize = 0.2 mouseWheel(control, control.width / 2, control.height / 2, data.dx, data.dy) + compare(movedSpy.count, ++movedCount) compare(control.value, 0.3) compare(control.position, 0.3) control.stepSize = 10.0 mouseWheel(control, control.width / 2, control.height / 2, -data.dx, -data.dy) + compare(movedSpy.count, ++movedCount) + compare(control.value, 0.0) + compare(control.position, 0.0) + + // no change + mouseWheel(control, control.width / 2, control.height / 2, -data.dx, -data.dy) + compare(movedSpy.count, movedCount) compare(control.value, 0.0) compare(control.position, 0.0) @@ -509,14 +558,17 @@ TestCase { control.stepSize = 5.0 mouseWheel(control, control.width / 2, control.height / 2, data.dx, data.dy) + compare(movedSpy.count, ++movedCount) compare(control.value, 5.0) compare(control.position, 0.5) mouseWheel(control, control.width / 2, control.height / 2, 0.5 * data.dx, 0.5 * data.dy) + compare(movedSpy.count, ++movedCount) compare(control.value, 7.5) compare(control.position, 0.75) mouseWheel(control, control.width / 2, control.height / 2, -data.dx, -data.dy) + compare(movedSpy.count, ++movedCount) compare(control.value, 2.5) compare(control.position, 0.25) -- cgit v1.2.3