diff options
14 files changed, 751 insertions, 5 deletions
diff --git a/src/quick/handlers/qquicktaphandler.cpp b/src/quick/handlers/qquicktaphandler.cpp index f24b2bfd7e..c1658ec5d2 100644 --- a/src/quick/handlers/qquicktaphandler.cpp +++ b/src/quick/handlers/qquicktaphandler.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2019 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QtQuick module of the Qt Toolkit. @@ -315,6 +315,8 @@ void QQuickTapHandler::setPressed(bool press, bool cancel, QQuickEventPoint *poi if (cancel) { emit canceled(point); setExclusiveGrab(point, false); + // In case there is a filtering parent (Flickable), we should not give up the passive grab, + // so that it can continue to filter future events. reset(); emit pointChanged(); } diff --git a/src/quick/items/qquickflickable.cpp b/src/quick/items/qquickflickable.cpp index 85045be411..cf882e8c9e 100644 --- a/src/quick/items/qquickflickable.cpp +++ b/src/quick/items/qquickflickable.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2016 The Qt Company Ltd. +** Copyright (C) 2019 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QtQuick module of the Qt Toolkit. @@ -61,6 +61,8 @@ QT_BEGIN_NAMESPACE +Q_DECLARE_LOGGING_CATEGORY(lcHandlerParent) + // FlickThreshold determines how far the "mouse" must have moved // before we perform a flick. static const int FlickThreshold = 15; @@ -1897,6 +1899,8 @@ void QQuickFlickablePrivate::data_append(QQmlListProperty<QObject> *prop, QObjec { if (QQuickItem *i = qmlobject_cast<QQuickItem *>(o)) { i->setParentItem(static_cast<QQuickFlickablePrivate*>(prop->data)->contentItem); + } else if (QQuickPointerHandler *pointerHandler = qmlobject_cast<QQuickPointerHandler *>(o)) { + static_cast<QQuickFlickablePrivate*>(prop->data)->addPointerHandler(pointerHandler); } else { o->setParent(prop->object); // XXX todo - do we want this? } @@ -2356,6 +2360,14 @@ void QQuickFlickablePrivate::cancelInteraction() } } +void QQuickFlickablePrivate::addPointerHandler(QQuickPointerHandler *h) +{ + Q_Q(const QQuickFlickable); + qCDebug(lcHandlerParent) << "reparenting handler" << h << "to contentItem of" << q; + h->setParent(contentItem); + QQuickItemPrivate::get(contentItem)->addPointerHandler(h); +} + /*! QQuickFlickable::filterMouseEvent checks filtered mouse events and potentially steals them. diff --git a/src/quick/items/qquickflickable_p.h b/src/quick/items/qquickflickable_p.h index b7c4fa5b67..f21fe94177 100644 --- a/src/quick/items/qquickflickable_p.h +++ b/src/quick/items/qquickflickable_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2016 The Qt Company Ltd. +** Copyright (C) 2019 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QtQuick module of the Qt Toolkit. diff --git a/src/quick/items/qquickflickable_p_p.h b/src/quick/items/qquickflickable_p_p.h index c538cf7878..835c54170f 100644 --- a/src/quick/items/qquickflickable_p_p.h +++ b/src/quick/items/qquickflickable_p_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2016 The Qt Company Ltd. +** Copyright (C) 2019 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QtQuick module of the Qt Toolkit. @@ -206,6 +206,8 @@ public: void cancelInteraction(); + void addPointerHandler(QQuickPointerHandler *h) override; + public: QQuickItem *contentItem; diff --git a/src/quick/items/qquickitem_p.h b/src/quick/items/qquickitem_p.h index 4ca3a01d02..771228914b 100644 --- a/src/quick/items/qquickitem_p.h +++ b/src/quick/items/qquickitem_p.h @@ -281,7 +281,7 @@ public: bool hasPointerHandlers() const; bool hasHoverHandlers() const; - void addPointerHandler(QQuickPointerHandler *h); + virtual void addPointerHandler(QQuickPointerHandler *h); // data property static void data_append(QQmlListProperty<QObject> *, QObject *); diff --git a/tests/auto/quick/pointerhandlers/flickableinterop/data/dragOnFlickable.qml b/tests/auto/quick/pointerhandlers/flickableinterop/data/dragOnFlickable.qml new file mode 100644 index 0000000000..fd32baad10 --- /dev/null +++ b/tests/auto/quick/pointerhandlers/flickableinterop/data/dragOnFlickable.qml @@ -0,0 +1,70 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** 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 https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.12 + +Flickable { + id: root + objectName: "root" + width: 800 + height: 480 + contentWidth: 1000 + contentHeight: 600 + + Rectangle { + anchors.fill: parent + color: "transparent" + border.color: "black" + } + + Rectangle { + objectName: "button" + anchors.centerIn: parent + border.color: "tomato" + border.width: 10 + color: buttonDrag.active ? "goldenrod" : "beige" + width: 100 + height: 100 + DragHandler { + id: buttonDrag + objectName: "buttonDrag" + } + } + + DragHandler { + id: contentItemDrag + objectName: "contentItemDrag" + } + Text { + x: 100; y: 100 + text: "dragging contentItem" + visible: contentItemDrag.active + } + + Component.onCompleted: contentItem.objectName = "Flickable's contentItem" +} diff --git a/tests/auto/quick/pointerhandlers/flickableinterop/data/dragOnList.qml b/tests/auto/quick/pointerhandlers/flickableinterop/data/dragOnList.qml new file mode 100644 index 0000000000..bb39c2267c --- /dev/null +++ b/tests/auto/quick/pointerhandlers/flickableinterop/data/dragOnList.qml @@ -0,0 +1,74 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** 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 https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.12 + +ListView { + id: root + objectName: "root" + property Item buttonUnderTest: null + property Item delegateUnderTest: null + width: 800 + height: 480 + model: 10 + spacing: 2 + + delegate: Rectangle { + objectName: "itemview delegate" + color: delegateDrag.active ? "wheat" : "beige" + border.color: "black" + width: parent.width; height: 140 + Rectangle { + objectName: "button" + x: 350; y: 20 + border.color: "tomato" + border.width: 10 + color: buttonDrag.active ? "goldenrod" : "beige" + width: 100 + height: 100 + DragHandler { + id: buttonDrag + objectName: "buttonDrag" + } + Component.onCompleted: if (!root.buttonUnderTest) { + root.buttonUnderTest = this + root.delegateUnderTest = parent + } + } + DragHandler { + id: delegateDrag + objectName: "delegateDrag" + } + } + + DragHandler { + objectName: "contentItemDrag" + } + + Component.onCompleted: contentItem.objectName = "ListView's contentItem" +} diff --git a/tests/auto/quick/pointerhandlers/flickableinterop/data/dragOnTable.qml b/tests/auto/quick/pointerhandlers/flickableinterop/data/dragOnTable.qml new file mode 100644 index 0000000000..43cc44f62e --- /dev/null +++ b/tests/auto/quick/pointerhandlers/flickableinterop/data/dragOnTable.qml @@ -0,0 +1,79 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** 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 https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.12 + +TableView { + id: root + objectName: "root" + property Item buttonUnderTest: null + property Item delegateUnderTest: null + width: 800 + height: 480 + columnSpacing: 2 + rowSpacing: 2 + // TODO use TableModel when it's ready, to test with multiple columns + model: 10 + + delegate: Rectangle { + id: tableDelegate + objectName: "itemview delegate" + color: delegateDrag.active ? "wheat" : "beige" + implicitWidth: 200 + implicitHeight: 140 + + Rectangle { + objectName: "button" + x: 50; y: 20 + border.color: "tomato" + border.width: 10 + color: buttonDrag.active ? "goldenrod" : "beige" + width: 100 + height: 100 + DragHandler { + id: buttonDrag + objectName: "buttonDrag" + } + Component.onCompleted: if (!root.buttonUnderTest) { + root.buttonUnderTest = this + root.delegateUnderTest = parent + } + } + + DragHandler { + id: delegateDrag + objectName: "delegateDrag" + } + } + + DragHandler { + objectName: "contentItemDrag" + } + + Component.onCompleted: contentItem.objectName = "TableView's contentItem" +} diff --git a/tests/auto/quick/pointerhandlers/flickableinterop/data/tapOnFlickable.qml b/tests/auto/quick/pointerhandlers/flickableinterop/data/tapOnFlickable.qml new file mode 100644 index 0000000000..a71db0b4c2 --- /dev/null +++ b/tests/auto/quick/pointerhandlers/flickableinterop/data/tapOnFlickable.qml @@ -0,0 +1,57 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** 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 https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.12 + +Flickable { + id: root + objectName: "root" + width: 800 + height: 480 + contentWidth: 1000 + contentHeight: 600 + + Rectangle { + objectName: "button" + anchors.centerIn: parent + border.color: "tomato" + border.width: 10 + color: innerTap.pressed ? "wheat" : "transparent" + width: 100 + height: 100 + TapHandler { + id: innerTap + objectName: "buttonTap" + } + } + + TapHandler { + objectName: "contentItemTap" + } + Component.onCompleted: contentItem.objectName = "Flickable's contentItem" +} diff --git a/tests/auto/quick/pointerhandlers/flickableinterop/data/tapOnList.qml b/tests/auto/quick/pointerhandlers/flickableinterop/data/tapOnList.qml new file mode 100644 index 0000000000..ef27955043 --- /dev/null +++ b/tests/auto/quick/pointerhandlers/flickableinterop/data/tapOnList.qml @@ -0,0 +1,73 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** 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 https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.12 + +ListView { + id: root + objectName: "root" + property Item buttonUnderTest: null + property Item delegateUnderTest: null + width: 800 + height: 480 + model: 10 + spacing: 2 + + delegate: Rectangle { + objectName: "itemview delegate" + color: delegateTap.pressed ? "wheat" : "beige" + width: parent.width; height: 140 + Rectangle { + objectName: "button" + anchors.centerIn: parent + border.color: "tomato" + border.width: 10 + color: innerTap.pressed ? "goldenrod" : "beige" + width: 100 + height: 100 + TapHandler { + id: innerTap + objectName: "buttonTap" + } + Component.onCompleted: if (!root.buttonUnderTest) { + root.buttonUnderTest = this + root.delegateUnderTest = parent + } + } + TapHandler { + id: delegateTap + objectName: "delegateTap" + } + } + + TapHandler { + objectName: "contentItemTap" + } + + Component.onCompleted: contentItem.objectName = "ListView's contentItem" +} diff --git a/tests/auto/quick/pointerhandlers/flickableinterop/data/tapOnTable.qml b/tests/auto/quick/pointerhandlers/flickableinterop/data/tapOnTable.qml new file mode 100644 index 0000000000..6bf1054d7a --- /dev/null +++ b/tests/auto/quick/pointerhandlers/flickableinterop/data/tapOnTable.qml @@ -0,0 +1,79 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** 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 https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.12 + +TableView { + id: root + objectName: "root" + property Item buttonUnderTest: null + property Item delegateUnderTest: null + width: 800 + height: 480 + columnSpacing: 2 + rowSpacing: 2 + // TODO use TableModel when it's ready, to test with multiple columns + model: 10 + + delegate: Rectangle { + id: tableDelegate + objectName: "itemview delegate" + color: delegateTap.pressed ? "wheat" : "beige" + implicitWidth: 200 + implicitHeight: 140 + + Rectangle { + objectName: "button" + anchors.centerIn: parent + border.color: "tomato" + border.width: 10 + color: innerTap.pressed ? "goldenrod" : "beige" + width: 100 + height: 100 + TapHandler { + id: innerTap + objectName: "buttonTap" + } + Component.onCompleted: if (!root.buttonUnderTest) { + root.buttonUnderTest = this + root.delegateUnderTest = parent + } + } + + TapHandler { + id: delegateTap + objectName: "delegateTap" + } + } + + TapHandler { + objectName: "contentItemTap" + } + + Component.onCompleted: contentItem.objectName = "TableView's contentItem" +} diff --git a/tests/auto/quick/pointerhandlers/flickableinterop/tst_flickableinterop.cpp b/tests/auto/quick/pointerhandlers/flickableinterop/tst_flickableinterop.cpp index e544eedf05..e73588bdef 100644 --- a/tests/auto/quick/pointerhandlers/flickableinterop/tst_flickableinterop.cpp +++ b/tests/auto/quick/pointerhandlers/flickableinterop/tst_flickableinterop.cpp @@ -33,9 +33,11 @@ #include <QtQuick/qquickview.h> #include <QtQuick/qquickitem.h> #include <QtQuick/private/qquickflickable_p.h> +#include <QtQuick/private/qquickitemview_p.h> #include <QtQuick/private/qquickpointerhandler_p.h> #include <QtQuick/private/qquickdraghandler_p.h> #include <QtQuick/private/qquicktaphandler_p.h> +#include <QtQuick/private/qquicktableview_p.h> #include <qpa/qwindowsysteminterface.h> #include <private/qquickwindow_p.h> @@ -75,6 +77,8 @@ private slots: void mouseDragFlickableBehindItemWithHandlers_data(); void mouseDragFlickableBehindItemWithHandlers(); void touchDragSliderAndFlickable(); + void touchAndDragHandlerOnFlickable_data(); + void touchAndDragHandlerOnFlickable(); private: void createView(QScopedPointer<QQuickView> &window, const char *fileName); @@ -651,6 +655,140 @@ void tst_FlickableInterop::touchDragSliderAndFlickable() touchSeq.release(1, p1, window).release(2, p2, window).commit(); } +void tst_FlickableInterop::touchAndDragHandlerOnFlickable_data() +{ + QTest::addColumn<QByteArray>("qmlFile"); + QTest::addColumn<bool>("pressDelay"); + QTest::addColumn<bool>("targetNull"); + QTest::newRow("tapOnFlickable") << QByteArray("tapOnFlickable.qml") << false << false; + QTest::newRow("tapOnList") << QByteArray("tapOnList.qml") << false << false; + QTest::newRow("tapOnTable") << QByteArray("tapOnTable.qml") << false << false; + QTest::newRow("dragOnFlickable") << QByteArray("dragOnFlickable.qml") << false << false; + QTest::newRow("dragOnList") << QByteArray("dragOnList.qml") << false << false; + QTest::newRow("dragOnTable") << QByteArray("dragOnTable.qml") << false << false; + QTest::newRow("tapDelayOnFlickable") << QByteArray("tapOnFlickable.qml") << true << false; + QTest::newRow("tapDelayOnList") << QByteArray("tapOnList.qml") << true << false; + QTest::newRow("tapDelayOnTable") << QByteArray("tapOnTable.qml") << true << false; + QTest::newRow("dragDelayOnFlickable") << QByteArray("dragOnFlickable.qml") << true << false; + QTest::newRow("dragDelayOnList") << QByteArray("dragOnList.qml") << true << false; + QTest::newRow("dragDelayOnTable") << QByteArray("dragOnTable.qml") << true << false; + QTest::newRow("tapOnFlickableWithNullTargets") << QByteArray("tapOnFlickable.qml") << false << true; + QTest::newRow("tapOnListWithNullTargets") << QByteArray("tapOnList.qml") << false << true; + QTest::newRow("tapOnTableWithNullTargets") << QByteArray("tapOnTable.qml") << false << true; + QTest::newRow("dragOnFlickableWithNullTargets") << QByteArray("dragOnFlickable.qml") << false << true; + QTest::newRow("dragOnListWithNullTargets") << QByteArray("dragOnList.qml") << false << true; + QTest::newRow("dragOnTableWithNullTargets") << QByteArray("dragOnTable.qml") << false << true; + QTest::newRow("tapDelayOnFlickableWithNullTargets") << QByteArray("tapOnFlickable.qml") << true << true; + QTest::newRow("tapDelayOnListWithNullTargets") << QByteArray("tapOnList.qml") << true << true; + QTest::newRow("tapDelayOnTableWithNullTargets") << QByteArray("tapOnTable.qml") << true << true; + QTest::newRow("dragDelayOnFlickableWithNullTargets") << QByteArray("dragOnFlickable.qml") << true << true; + QTest::newRow("dragDelayOnListWithNullTargets") << QByteArray("dragOnList.qml") << true << true; + QTest::newRow("dragDelayOnTableWithNullTargets") << QByteArray("dragOnTable.qml") << true << true; +} + +void tst_FlickableInterop::touchAndDragHandlerOnFlickable() +{ + QFETCH(QByteArray, qmlFile); + QFETCH(bool, pressDelay); + QFETCH(bool, targetNull); + + const int dragThreshold = QGuiApplication::styleHints()->startDragDistance(); + QScopedPointer<QQuickView> windowPtr; + createView(windowPtr, qmlFile.constData()); + QQuickView * window = windowPtr.data(); + QQuickFlickable *flickable = qmlobject_cast<QQuickFlickable*>(window->rootObject()); + QVERIFY(flickable); + flickable->setPressDelay(pressDelay ? 5000 : 0); + QQuickItem *delegate = nullptr; + if (QQuickItemView *itemView = qmlobject_cast<QQuickItemView *>(flickable)) + delegate = itemView->currentItem(); + if (!delegate) + delegate = flickable->property("delegateUnderTest").value<QQuickItem*>(); + QQuickItem *button = delegate ? delegate->findChild<QQuickItem*>("button") + : flickable->findChild<QQuickItem*>("button"); + if (!button) + button = flickable->property("buttonUnderTest").value<QQuickItem*>(); + QVERIFY(button); + QQuickPointerHandler *buttonHandler = button->findChild<QQuickPointerHandler*>(); + QVERIFY(buttonHandler); + QQuickTapHandler *buttonTapHandler = qmlobject_cast<QQuickTapHandler *>(buttonHandler); + QQuickDragHandler *buttonDragHandler = qmlobject_cast<QQuickDragHandler *>(buttonHandler); + QQuickPointerHandler *delegateHandler = delegate ? delegate->findChild<QQuickPointerHandler*>() : nullptr; + QQuickPointerHandler *contentItemHandler = flickable->findChild<QQuickPointerHandler*>(); + QVERIFY(contentItemHandler); + // a handler declared directly in a Flickable (or item view) must actually be a child of the contentItem, + // just as Items declared inside are (QTBUG-71918 and QTBUG-73035) + QCOMPARE(contentItemHandler->parentItem(), flickable->contentItem()); + if (targetNull) { + buttonHandler->setTarget(nullptr); + if (delegateHandler) + delegateHandler->setTarget(nullptr); + contentItemHandler->setTarget(nullptr); + } + + // Drag one finger on the Flickable and make sure it flicks + QTest::QTouchEventSequence touchSeq = QTest::touchEvent(window, touchDevice, false); + QPoint p1(780, 460); + touchSeq.press(1, p1, window).commit(); + QQuickTouchUtils::flush(window); + for (int i = 0; i < 4; ++i) { + p1 -= QPoint(dragThreshold, dragThreshold); + touchSeq.move(1, p1, window).commit(); + QQuickTouchUtils::flush(window); + } + if (!(buttonDragHandler && !pressDelay)) + QVERIFY(flickable->contentY() >= dragThreshold); + if (buttonTapHandler) + QCOMPARE(buttonTapHandler->isPressed(), false); + touchSeq.release(1, p1, window).commit(); + QQuickTouchUtils::flush(window); + + // Drag one finger on the delegate and make sure Flickable flicks + if (delegate) { + flickable->setContentY(0); + QTRY_COMPARE(flickable->isMoving(), false); + QVERIFY(delegateHandler); + QQuickTapHandler *delegateTapHandler = qmlobject_cast<QQuickTapHandler *>(delegateHandler); + p1 = button->mapToScene(button->clipRect().bottomRight()).toPoint() + QPoint(10, 0); + touchSeq.press(1, p1, window).commit(); + QQuickTouchUtils::flush(window); + if (delegateTapHandler && !pressDelay) + QCOMPARE(delegateTapHandler->isPressed(), true); + for (int i = 0; i < 4; ++i) { + p1 -= QPoint(dragThreshold, dragThreshold); + touchSeq.move(1, p1, window).commit(); + QQuickTouchUtils::flush(window); + if (i > 1) + QTRY_VERIFY(delegateHandler->active() || flickable->isMoving()); + } + if (!(buttonDragHandler && !pressDelay)) + QVERIFY(flickable->contentY() > 0); + if (delegateTapHandler) + QCOMPARE(delegateTapHandler->isPressed(), false); + touchSeq.release(1, p1, window).commit(); + QQuickTouchUtils::flush(window); + } + + // Drag one finger on the button and make sure Flickable flicks + flickable->setContentY(0); + QTRY_COMPARE(flickable->isMoving(), false); + p1 = button->mapToScene(button->clipRect().center()).toPoint(); + touchSeq.press(1, p1, window).commit(); + QQuickTouchUtils::flush(window); + if (buttonTapHandler && !pressDelay) + QTRY_COMPARE(buttonTapHandler->isPressed(), true); + for (int i = 0; i < 4; ++i) { + p1 -= QPoint(dragThreshold, dragThreshold); + touchSeq.move(1, p1, window).commit(); + QQuickTouchUtils::flush(window); + } + if (!(buttonDragHandler && !pressDelay)) + QVERIFY(flickable->contentY() > 0); + if (buttonTapHandler) + QCOMPARE(buttonTapHandler->isPressed(), false); + touchSeq.release(1, p1, window).commit(); +} + QTEST_MAIN(tst_FlickableInterop) #include "tst_flickableinterop.moc" diff --git a/tests/manual/pointer/pointHandlerOnFlickable.qml b/tests/manual/pointer/pointHandlerOnFlickable.qml new file mode 100644 index 0000000000..bd39d545ca --- /dev/null +++ b/tests/manual/pointer/pointHandlerOnFlickable.qml @@ -0,0 +1,74 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** 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 https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.12 +import "content" + +Flickable { + id: root + objectName: "root" + width: 800 + height: 480 + contentWidth: 1000 + contentHeight: 600 + + Rectangle { + objectName: "button" + anchors.centerIn: parent + border.color: "tomato" + border.width: 10 + color: innerTap.pressed ? "wheat" : "transparent" + width: 100 + height: 100 + TapHandler { + id: innerTap + objectName: "buttonTap" + } + } + + TapHandler { + id: contentItemTap + objectName: "contentItemTap" + onLongPressed: longPressFeedback.createObject(root.contentItem, + {"x": point.position.x, "y": point.position.y, + "text": contentItemTap.timeHeld.toFixed(3) + " sec"}) + + } + TouchpointFeedbackSprite { } + TouchpointFeedbackSprite { } + TouchpointFeedbackSprite { } + TouchpointFeedbackSprite { } + TouchpointFeedbackSprite { } + + Component { + id: longPressFeedback + Text { } + } + + Component.onCompleted: contentItem.objectName = "Flickable's contentItem" +} diff --git a/tests/manual/pointer/rubberbandOnTable.qml b/tests/manual/pointer/rubberbandOnTable.qml new file mode 100644 index 0000000000..177568d41e --- /dev/null +++ b/tests/manual/pointer/rubberbandOnTable.qml @@ -0,0 +1,86 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the manual tests of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** 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 https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.12 + +TableView { + id: root + objectName: "root" + width: 480 + height: 480 + columnSpacing: 2 + rowSpacing: 2 + // TODO use TableModel when it's ready, to test with multiple columns + model: 10 + + delegate: Rectangle { + id: tableDelegate + objectName: "itemview delegate" + color: delegateTap.pressed ? "wheat" : "beige" + implicitWidth: 200 + implicitHeight: 140 + + Rectangle { + objectName: "button" + anchors.centerIn: parent + border.color: "tomato" + border.width: 10 + color: buttonTap.pressed ? "goldenrod" : "beige" + width: 100 + height: 100 + TapHandler { + id: buttonTap + objectName: "buttonTap" + } + } + + TapHandler { + id: delegateTap + objectName: "delegateTap" + } + } + + DragHandler { + id: rubberBandDrag + objectName: "rubberBandDrag" + target: null + acceptedDevices: PointerDevice.Mouse + } + Rectangle { + visible: rubberBandDrag.active + x: Math.min(rubberBandDrag.centroid.position.x, rubberBandDrag.centroid.pressPosition.x) + y: Math.min(rubberBandDrag.centroid.position.y, rubberBandDrag.centroid.pressPosition.y) + width: Math.abs(rubberBandDrag.centroid.position.x - rubberBandDrag.centroid.pressPosition.x) + height: Math.abs(rubberBandDrag.centroid.position.y - rubberBandDrag.centroid.pressPosition.y) + color: "transparent" + border.color: "black" + z: 1000 + } + + Component.onCompleted: contentItem.objectName = "TableView's contentItem" +} |