diff options
-rw-r--r-- | src/imports/templates/qtquicktemplates2plugin.cpp | 1 | ||||
-rw-r--r-- | src/quicktemplates2/qquickswipe_p.h | 117 | ||||
-rw-r--r-- | src/quicktemplates2/qquickswipedelegate.cpp | 51 | ||||
-rw-r--r-- | src/quicktemplates2/qquickswipedelegate_p.h | 56 | ||||
-rw-r--r-- | src/quicktemplates2/qquickswipedelegate_p_p.h | 76 | ||||
-rw-r--r-- | src/quicktemplates2/quicktemplates2.pri | 2 | ||||
-rw-r--r-- | tests/auto/controls/data/tst_swipedelegate.qml | 46 |
7 files changed, 269 insertions, 80 deletions
diff --git a/src/imports/templates/qtquicktemplates2plugin.cpp b/src/imports/templates/qtquicktemplates2plugin.cpp index 2c87fd45..e93b80c7 100644 --- a/src/imports/templates/qtquicktemplates2plugin.cpp +++ b/src/imports/templates/qtquicktemplates2plugin.cpp @@ -69,6 +69,7 @@ #include <QtQuickTemplates2/private/qquickslider_p.h> #include <QtQuickTemplates2/private/qquickspinbox_p.h> #include <QtQuickTemplates2/private/qquickstackview_p.h> +#include <QtQuickTemplates2/private/qquickswipe_p.h> #include <QtQuickTemplates2/private/qquickswipedelegate_p.h> #include <QtQuickTemplates2/private/qquickswipeview_p.h> #include <QtQuickTemplates2/private/qquickswitch_p.h> diff --git a/src/quicktemplates2/qquickswipe_p.h b/src/quicktemplates2/qquickswipe_p.h new file mode 100644 index 00000000..f701c63c --- /dev/null +++ b/src/quicktemplates2/qquickswipe_p.h @@ -0,0 +1,117 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKSWIPE_P_H +#define QQUICKSWIPE_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtCore/qobject.h> +#include <QtQuickTemplates2/private/qtquicktemplates2global_p.h> + +QT_BEGIN_NAMESPACE + +class QQmlComponent; +class QQuickItem; +class QQuickSwipeDelegate; +class QQuickSwipePrivate; + +class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickSwipe : public QObject +{ + Q_OBJECT + Q_PROPERTY(qreal position READ position NOTIFY positionChanged FINAL) + Q_PROPERTY(bool complete READ isComplete NOTIFY completeChanged FINAL) + Q_PROPERTY(QQmlComponent *left READ left WRITE setLeft NOTIFY leftChanged FINAL) + Q_PROPERTY(QQmlComponent *behind READ behind WRITE setBehind NOTIFY behindChanged FINAL) + Q_PROPERTY(QQmlComponent *right READ right WRITE setRight NOTIFY rightChanged FINAL) + Q_PROPERTY(QQuickItem *leftItem READ leftItem NOTIFY leftItemChanged FINAL) + Q_PROPERTY(QQuickItem *behindItem READ behindItem NOTIFY behindItemChanged FINAL) + Q_PROPERTY(QQuickItem *rightItem READ rightItem NOTIFY rightItemChanged FINAL) + +public: + explicit QQuickSwipe(QQuickSwipeDelegate *control); + + qreal position() const; + void setPosition(qreal position); + + bool isComplete() const; + void setComplete(bool complete); + + QQmlComponent *left() const; + void setLeft(QQmlComponent *left); + + QQmlComponent *behind() const; + void setBehind(QQmlComponent *behind); + + QQmlComponent *right() const; + void setRight(QQmlComponent *right); + + QQuickItem *leftItem() const; + void setLeftItem(QQuickItem *item); + + QQuickItem *behindItem() const; + void setBehindItem(QQuickItem *item); + + QQuickItem *rightItem() const; + void setRightItem(QQuickItem *item); + +Q_SIGNALS: + void positionChanged(); + void completeChanged(); + void leftChanged(); + void behindChanged(); + void rightChanged(); + void leftItemChanged(); + void behindItemChanged(); + void rightItemChanged(); + +private: + Q_DISABLE_COPY(QQuickSwipe) + Q_DECLARE_PRIVATE(QQuickSwipe) +}; + +QT_END_NAMESPACE + +#endif // QQUICKSWIPE_P_H diff --git a/src/quicktemplates2/qquickswipedelegate.cpp b/src/quicktemplates2/qquickswipedelegate.cpp index 3dec1f2e..0eac7fe1 100644 --- a/src/quicktemplates2/qquickswipedelegate.cpp +++ b/src/quicktemplates2/qquickswipedelegate.cpp @@ -35,6 +35,7 @@ ****************************************************************************/ #include "qquickswipedelegate_p.h" +#include "qquickswipedelegate_p_p.h" #include "qquickcontrol_p_p.h" #include "qquickitemdelegate_p_p.h" #include "qquickvelocitycalculator_p_p.h" @@ -142,6 +143,8 @@ public: void warnAboutMixingDelegates(); void warnAboutSettingDelegatesWhileVisible(); + bool hasDelegates() const; + QQuickSwipeDelegate *control; // Same range as position, but is set before press events so that we can // keep track of which direction the user must swipe when using left and right delegates. @@ -342,6 +345,11 @@ void QQuickSwipePrivate::warnAboutSettingDelegatesWhileVisible() qmlInfo(control) << "left/right/behind properties may only be set when swipe.position is 0"; } +bool QQuickSwipePrivate::hasDelegates() const +{ + return left || right || behind; +} + QQuickSwipe::QQuickSwipe(QQuickSwipeDelegate *control) : QObject(*(new QQuickSwipePrivate(control))) { @@ -376,6 +384,8 @@ void QQuickSwipe::setLeft(QQmlComponent *left) d->leftItem = nullptr; } + d->control->setFiltersChildMouseEvents(d->hasDelegates()); + emit leftChanged(); } @@ -408,6 +418,8 @@ void QQuickSwipe::setBehind(QQmlComponent *behind) d->behindItem = nullptr; } + d->control->setFiltersChildMouseEvents(d->hasDelegates()); + emit behindChanged(); } @@ -440,6 +452,8 @@ void QQuickSwipe::setRight(QQmlComponent *right) d->rightItem = nullptr; } + d->control->setFiltersChildMouseEvents(d->hasDelegates()); + emit rightChanged(); } @@ -552,24 +566,10 @@ void QQuickSwipe::setComplete(bool complete) emit completeChanged(); } -class QQuickSwipeDelegatePrivate : public QQuickItemDelegatePrivate +QQuickSwipeDelegatePrivate::QQuickSwipeDelegatePrivate(QQuickSwipeDelegate *control) : + swipe(control) { - Q_DECLARE_PUBLIC(QQuickSwipeDelegate) - -public: - QQuickSwipeDelegatePrivate(QQuickSwipeDelegate *control) : - swipe(control) - { - } - - bool handleMousePressEvent(QQuickItem *item, QMouseEvent *event); - bool handleMouseMoveEvent(QQuickItem *item, QMouseEvent *event); - bool handleMouseReleaseEvent(QQuickItem *item, QMouseEvent *event); - - void resizeContent() override; - - QQuickSwipe swipe; -}; +} bool QQuickSwipeDelegatePrivate::handleMousePressEvent(QQuickItem *item, QMouseEvent *event) { @@ -673,6 +673,13 @@ bool QQuickSwipeDelegatePrivate::handleMouseMoveEvent(QQuickItem *item, QMouseEv swipe.setPosition(position); } + } else { + // The swipe wasn't initiated. + if (event->pos().y() < 0 || event->pos().y() > height) { + // The mouse went outside the vertical bounds of the control, so + // we should no longer consider it pressed. + q->setPressed(false); + } } event->accept(); @@ -748,7 +755,6 @@ void QQuickSwipeDelegatePrivate::resizeContent() QQuickSwipeDelegate::QQuickSwipeDelegate(QQuickItem *parent) : QQuickItemDelegate(*(new QQuickSwipeDelegatePrivate(this)), parent) { - setFiltersChildMouseEvents(true); } /*! @@ -885,14 +891,17 @@ void QQuickSwipeDelegate::mousePressEvent(QMouseEvent *event) void QQuickSwipeDelegate::mouseMoveEvent(QMouseEvent *event) { Q_D(QQuickSwipeDelegate); - d->handleMouseMoveEvent(this, event); + if (filtersChildMouseEvents()) + d->handleMouseMoveEvent(this, event); + else + QQuickItemDelegate::mouseMoveEvent(event); } void QQuickSwipeDelegate::mouseReleaseEvent(QMouseEvent *event) { Q_D(QQuickSwipeDelegate); - QQuickItemDelegate::mouseReleaseEvent(event); - d->handleMouseReleaseEvent(this, event); + if (!filtersChildMouseEvents() || !d->handleMouseReleaseEvent(this, event)) + QQuickItemDelegate::mouseReleaseEvent(event); } void QQuickSwipeDelegate::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) diff --git a/src/quicktemplates2/qquickswipedelegate_p.h b/src/quicktemplates2/qquickswipedelegate_p.h index e71455b0..2e1c515d 100644 --- a/src/quicktemplates2/qquickswipedelegate_p.h +++ b/src/quicktemplates2/qquickswipedelegate_p.h @@ -84,62 +84,6 @@ private: Q_DECLARE_PRIVATE(QQuickSwipeDelegate) }; -class QQuickSwipePrivate; - -class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickSwipe : public QObject -{ - Q_OBJECT - Q_PROPERTY(qreal position READ position NOTIFY positionChanged FINAL) - Q_PROPERTY(bool complete READ isComplete NOTIFY completeChanged FINAL) - Q_PROPERTY(QQmlComponent *left READ left WRITE setLeft NOTIFY leftChanged FINAL) - Q_PROPERTY(QQmlComponent *behind READ behind WRITE setBehind NOTIFY behindChanged FINAL) - Q_PROPERTY(QQmlComponent *right READ right WRITE setRight NOTIFY rightChanged FINAL) - Q_PROPERTY(QQuickItem *leftItem READ leftItem NOTIFY leftItemChanged FINAL) - Q_PROPERTY(QQuickItem *behindItem READ behindItem NOTIFY behindItemChanged FINAL) - Q_PROPERTY(QQuickItem *rightItem READ rightItem NOTIFY rightItemChanged FINAL) - -public: - explicit QQuickSwipe(QQuickSwipeDelegate *control); - - qreal position() const; - void setPosition(qreal position); - - bool isComplete() const; - void setComplete(bool complete); - - QQmlComponent *left() const; - void setLeft(QQmlComponent *left); - - QQmlComponent *behind() const; - void setBehind(QQmlComponent *behind); - - QQmlComponent *right() const; - void setRight(QQmlComponent *right); - - QQuickItem *leftItem() const; - void setLeftItem(QQuickItem *item); - - QQuickItem *behindItem() const; - void setBehindItem(QQuickItem *item); - - QQuickItem *rightItem() const; - void setRightItem(QQuickItem *item); - -Q_SIGNALS: - void positionChanged(); - void completeChanged(); - void leftChanged(); - void behindChanged(); - void rightChanged(); - void leftItemChanged(); - void behindItemChanged(); - void rightItemChanged(); - -private: - Q_DISABLE_COPY(QQuickSwipe) - Q_DECLARE_PRIVATE(QQuickSwipe) -}; - QT_END_NAMESPACE QML_DECLARE_TYPE(QQuickSwipeDelegate) diff --git a/src/quicktemplates2/qquickswipedelegate_p_p.h b/src/quicktemplates2/qquickswipedelegate_p_p.h new file mode 100644 index 00000000..0387ad70 --- /dev/null +++ b/src/quicktemplates2/qquickswipedelegate_p_p.h @@ -0,0 +1,76 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKSWIPEDELEGATE_P_P_H +#define QQUICKSWIPEDELEGATE_P_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtQuickTemplates2/private/qquickitemdelegate_p_p.h> +#include <QtQuickTemplates2/private/qquickswipe_p.h> + +QT_BEGIN_NAMESPACE + +class QQuickSwipeDelegate; + +class QQuickSwipeDelegatePrivate : public QQuickItemDelegatePrivate +{ + Q_DECLARE_PUBLIC(QQuickSwipeDelegate) + +public: + QQuickSwipeDelegatePrivate(QQuickSwipeDelegate *control); + + bool handleMousePressEvent(QQuickItem *item, QMouseEvent *event); + bool handleMouseMoveEvent(QQuickItem *item, QMouseEvent *event); + bool handleMouseReleaseEvent(QQuickItem *item, QMouseEvent *event); + + void resizeContent() override; + + QQuickSwipe swipe; +}; + +QT_END_NAMESPACE + +#endif // QQUICKSWIPEDELEGATE_P_P_H diff --git a/src/quicktemplates2/quicktemplates2.pri b/src/quicktemplates2/quicktemplates2.pri index 5877b3d0..5caa1bd7 100644 --- a/src/quicktemplates2/quicktemplates2.pri +++ b/src/quicktemplates2/quicktemplates2.pri @@ -47,7 +47,9 @@ HEADERS += \ $$PWD/qquickspinbox_p.h \ $$PWD/qquickstackview_p.h \ $$PWD/qquickstackview_p_p.h \ + $$PWD/qquickswipe_p.h \ $$PWD/qquickswipedelegate_p.h \ + $$PWD/qquickswipedelegate_p_p.h \ $$PWD/qquickswipeview_p.h \ $$PWD/qquickswitch_p.h \ $$PWD/qquickswitchdelegate_p.h \ diff --git a/tests/auto/controls/data/tst_swipedelegate.qml b/tests/auto/controls/data/tst_swipedelegate.qml index 21bb1a37..0404fd86 100644 --- a/tests/auto/controls/data/tst_swipedelegate.qml +++ b/tests/auto/controls/data/tst_swipedelegate.qml @@ -361,7 +361,7 @@ TestCase { verify(control.swipe.rightItem); verify(!control.swipe.rightItem.visible); - mouseSignalSequenceSpy.expectedSequence = [["pressedChanged", { "pressed": false }], "released", "clicked"]; + mouseSignalSequenceSpy.expectedSequence = [["pressedChanged", { "pressed": false }], "canceled"]; mouseRelease(control, control.width / 2, control.height / 2); verify(!control.pressed); compare(control.swipe.position, 1.0); @@ -388,7 +388,8 @@ TestCase { verify(!control.swipe.complete); compare(control.swipe.position, 1.0 - overDragDistance / control.width); - mouseSignalSequenceSpy.expectedSequence = [["pressedChanged", { "pressed": false }], "released", "clicked"]; + // Since we went over the drag distance, we should expect canceled() to be emitted. + mouseSignalSequenceSpy.expectedSequence = [["pressedChanged", { "pressed": false }], "canceled"]; mouseRelease(control, control.width * 0.4, control.height / 2); verify(!control.pressed); compare(control.swipe.position, 1.0); @@ -409,7 +410,7 @@ TestCase { verify(!control.swipe.complete); compare(control.swipe.position, 0.4); - mouseSignalSequenceSpy.expectedSequence = [["pressedChanged", { "pressed": false }], "released", "clicked"]; + mouseSignalSequenceSpy.expectedSequence = [["pressedChanged", { "pressed": false }], "canceled"]; mouseRelease(control, control.width * -0.1, control.height / 2); verify(!control.pressed); compare(control.swipe.position, 0.0); @@ -1033,4 +1034,43 @@ TestCase { control.destroy(); } + + function test_releaseOutside_data() { + return [ + { tag: "no delegates", component: emptySwipeDelegateComponent }, + { tag: "delegates", component: swipeDelegateComponent }, + ]; + } + + function test_releaseOutside(data) { + var control = data.component.createObject(testCase); + verify(control); + + // Press and then release below the control. + mouseSignalSequenceSpy.target = control; + mouseSignalSequenceSpy.expectedSequence = [["pressedChanged", { "pressed": true }], "pressed", ["pressedChanged", { "pressed": false }]]; + mousePress(control, control.width / 2, control.height / 2, Qt.LeftButton); + mouseMove(control, control.width / 2, control.height + 10, Qt.LeftButton); + verify(mouseSignalSequenceSpy.success); + + mouseSignalSequenceSpy.expectedSequence = ["canceled"]; + mouseRelease(control, control.width / 2, control.height + 10, Qt.LeftButton); + verify(mouseSignalSequenceSpy.success); + + // Press and then release to the right of the control. + var hasDelegates = control.swipe.left || control.swipe.right || control.swipe.behind; + mouseSignalSequenceSpy.target = control; + mouseSignalSequenceSpy.expectedSequence = hasDelegates + ? [["pressedChanged", { "pressed": true }], "pressed"] + : [["pressedChanged", { "pressed": true }], "pressed", ["pressedChanged", { "pressed": false }]]; + mousePress(control, control.width / 2, control.height / 2, Qt.LeftButton); + mouseMove(control, control.width + 10, control.height / 2, Qt.LeftButton); + if (hasDelegates) + verify(control.swipe.position > 0); + verify(mouseSignalSequenceSpy.success); + + mouseSignalSequenceSpy.expectedSequence = hasDelegates ? [["pressedChanged", { "pressed": false }], "canceled"] : ["canceled"]; + mouseRelease(control, control.width + 10, control.height / 2, Qt.LeftButton); + verify(mouseSignalSequenceSpy.success); + } } |