aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/quicktemplates2/qquickswitch.cpp123
-rw-r--r--src/quicktemplates2/qquickswitch_p.h6
-rw-r--r--tests/auto/controls/data/tst_switch.qml70
3 files changed, 108 insertions, 91 deletions
diff --git a/src/quicktemplates2/qquickswitch.cpp b/src/quicktemplates2/qquickswitch.cpp
index beb9a764..27043c8b 100644
--- a/src/quicktemplates2/qquickswitch.cpp
+++ b/src/quicktemplates2/qquickswitch.cpp
@@ -90,97 +90,28 @@ class QQuickSwitchPrivate : public QQuickAbstractButtonPrivate
public:
QQuickSwitchPrivate() : position(0) { }
- qreal positionAt(const QPoint &point) const;
-
- bool handleMousePressEvent(QQuickItem *child, QMouseEvent *event);
- bool handleMouseMoveEvent(QQuickItem *child, QMouseEvent *event);
- bool handleMouseReleaseEvent(QQuickItem *child, QMouseEvent *event);
- bool handleMouseUngrabEvent(QQuickItem *child);
+ qreal positionAt(const QPointF &point) const;
qreal position;
- QPoint pressPoint;
};
-qreal QQuickSwitchPrivate::positionAt(const QPoint &point) const
+qreal QQuickSwitchPrivate::positionAt(const QPointF &point) const
{
Q_Q(const QQuickSwitch);
- qreal pos = point.x() / indicator->width();
+ qreal pos = 0.0;
+ if (indicator)
+ pos = indicator->mapFromItem(q, point).x() / indicator->width();
if (q->isMirrored())
return 1.0 - pos;
return pos;
}
-bool QQuickSwitchPrivate::handleMousePressEvent(QQuickItem *child, QMouseEvent *event)
-{
- Q_Q(QQuickSwitch);
- Q_UNUSED(child);
- if ((focusPolicy & Qt::ClickFocus) == Qt::ClickFocus && !QGuiApplication::styleHints()->setFocusOnTouchRelease())
- q->forceActiveFocus(Qt::MouseFocusReason);
-
- pressPoint = event->pos();
- q->setPressed(true);
- emit q->pressed();
- event->accept();
- return true;
-}
-
-bool QQuickSwitchPrivate::handleMouseMoveEvent(QQuickItem *child, QMouseEvent *event)
-{
- Q_Q(QQuickSwitch);
- if (!child->keepMouseGrab())
- child->setKeepMouseGrab(QQuickWindowPrivate::dragOverThreshold(event->pos().x() - pressPoint.x(), Qt::XAxis, event));
- if (child->keepMouseGrab()) {
- q->setPosition(positionAt(event->pos()));
- event->accept();
- }
- return true;
-}
-
-bool QQuickSwitchPrivate::handleMouseReleaseEvent(QQuickItem *child, QMouseEvent *event)
-{
- Q_Q(QQuickSwitch);
- if ((focusPolicy & Qt::ClickFocus) == Qt::ClickFocus && QGuiApplication::styleHints()->setFocusOnTouchRelease())
- q->forceActiveFocus(Qt::MouseFocusReason);
-
- pressPoint = QPoint();
- q->setPressed(false);
- if (child->keepMouseGrab()) {
- bool wasChecked = checked;
- q->setChecked(position > 0.5);
- q->setPosition(checked ? 1.0 : 0.0);
- child->setKeepMouseGrab(false);
- if (wasChecked != checked) {
- emit q->released();
- emit q->clicked();
- }
- event->accept();
- } else {
- q->toggle();
- emit q->released();
- emit q->clicked();
- event->accept();
- }
- return true;
-}
-
-bool QQuickSwitchPrivate::handleMouseUngrabEvent(QQuickItem *child)
-{
- Q_Q(QQuickSwitch);
- Q_UNUSED(child);
- pressPoint = QPoint();
- q->setChecked(position > 0.5);
- q->setPosition(checked ? 1.0 : 0.0);
- q->setPressed(false);
- return true;
-}
-
QQuickSwitch::QQuickSwitch(QQuickItem *parent) :
QQuickAbstractButton(*(new QQuickSwitchPrivate), parent)
{
Q_D(QQuickSwitch);
d->keepPressed = true;
setCheckable(true);
- setFiltersChildMouseEvents(true);
}
/*!
@@ -221,30 +152,42 @@ qreal QQuickSwitch::visualPosition() const
return d->position;
}
+void QQuickSwitch::mousePressEvent(QMouseEvent *event)
+{
+ QQuickAbstractButton::mousePressEvent(event);
+}
+
+void QQuickSwitch::mouseMoveEvent(QMouseEvent *event)
+{
+ Q_D(QQuickSwitch);
+ QQuickAbstractButton::mouseMoveEvent(event);
+
+ const QPointF movePoint = event->localPos();
+ if (!keepMouseGrab())
+ setKeepMouseGrab(QQuickWindowPrivate::dragOverThreshold(movePoint.x() - d->pressPoint.x(), Qt::XAxis, event));
+ if (keepMouseGrab())
+ setPosition(d->positionAt(movePoint));
+}
+
+void QQuickSwitch::mouseReleaseEvent(QMouseEvent *event)
+{
+ QQuickAbstractButton::mouseReleaseEvent(event);
+ setKeepMouseGrab(false);
+}
+
void QQuickSwitch::mirrorChange()
{
QQuickAbstractButton::mirrorChange();
emit visualPositionChanged();
}
-bool QQuickSwitch::childMouseEventFilter(QQuickItem *child, QEvent *event)
+void QQuickSwitch::nextCheckState()
{
Q_D(QQuickSwitch);
- if (child == indicator()) {
- switch (event->type()) {
- case QEvent::MouseButtonPress:
- return d->handleMousePressEvent(child, static_cast<QMouseEvent *>(event));
- case QEvent::MouseMove:
- return d->handleMouseMoveEvent(child, static_cast<QMouseEvent *>(event));
- case QEvent::MouseButtonRelease:
- return d->handleMouseReleaseEvent(child, static_cast<QMouseEvent *>(event));
- case QEvent::UngrabMouse:
- return d->handleMouseUngrabEvent(child);
- default:
- return false;
- }
- }
- return false;
+ if (keepMouseGrab())
+ setChecked(d->position > 0.5);
+ else
+ QQuickAbstractButton::nextCheckState();
}
void QQuickSwitch::checkStateSet()
diff --git a/src/quicktemplates2/qquickswitch_p.h b/src/quicktemplates2/qquickswitch_p.h
index bfbcceed..27a065b4 100644
--- a/src/quicktemplates2/qquickswitch_p.h
+++ b/src/quicktemplates2/qquickswitch_p.h
@@ -73,9 +73,13 @@ Q_SIGNALS:
void visualPositionChanged();
protected:
+ void mousePressEvent(QMouseEvent *event) override;
+ void mouseMoveEvent(QMouseEvent *event) override;
+ void mouseReleaseEvent(QMouseEvent *event) override;
+
void mirrorChange() override;
- bool childMouseEventFilter(QQuickItem *child, QEvent *event) override;
+ void nextCheckState() override;
void checkStateSet() override;
private:
diff --git a/tests/auto/controls/data/tst_switch.qml b/tests/auto/controls/data/tst_switch.qml
index 1b77ff42..f854526c 100644
--- a/tests/auto/controls/data/tst_switch.qml
+++ b/tests/auto/controls/data/tst_switch.qml
@@ -200,6 +200,76 @@ TestCase {
control.destroy()
}
+ function test_drag() {
+ var control = swtch.createObject(testCase, {leftPadding: 100, rightPadding: 100})
+ verify(control)
+
+ var spy = signalSequenceSpy.createObject(control, {target: control})
+ compare(control.position, 0.0)
+ compare(control.checked, false)
+ compare(control.pressed, false)
+
+ // press-drag-release inside the indicator
+ spy.expectedSequence = [["pressedChanged", { "pressed": true, "checked": false }],
+ "pressed"]
+ mousePress(control.indicator, 0)
+ compare(control.position, 0.0)
+ compare(control.checked, false)
+ compare(control.pressed, true)
+ verify(spy.success)
+
+ mouseMove(control.indicator, control.width)
+ 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.indicator, control.indicator.width)
+ compare(control.position, 1.0)
+ compare(control.checked, true)
+ compare(control.pressed, false)
+ verify(spy.success)
+
+ // press-drag-release outside the indicator
+ spy.expectedSequence = [["pressedChanged", { "pressed": true, "checked": true }],
+ "pressed"]
+ mousePress(control, 0)
+ compare(control.position, 1.0)
+ compare(control.checked, true)
+ compare(control.pressed, true)
+ verify(spy.success)
+
+ mouseMove(control, control.width - control.rightPadding)
+ compare(control.position, 1.0)
+ compare(control.checked, true)
+ compare(control.pressed, true)
+
+ mouseMove(control, control.width / 2)
+ compare(control.position, 0.5)
+ compare(control.checked, true)
+ compare(control.pressed, true)
+
+ mouseMove(control, control.leftPadding)
+ compare(control.position, 0.0)
+ compare(control.checked, true)
+ compare(control.pressed, true)
+
+ spy.expectedSequence = [["pressedChanged", { "pressed": false, "checked": true }],
+ ["checkedChanged", { "pressed": false, "checked": false }],
+ "released",
+ "clicked"]
+ mouseRelease(control, control.width)
+ compare(control.position, 0.0)
+ compare(control.checked, false)
+ compare(control.pressed, false)
+ verify(spy.success)
+
+ control.destroy()
+ }
+
function test_keys() {
var control = swtch.createObject(testCase)
verify(control)