Add tst_qquickflickable::nestedSliderUsingTouch
to verify that when a touch-handling component is inside the Flickable, it can control whether the flickable can steal the grab by means of setKeepTouchGrab. Task-number: QTBUG-59416 Task-number: QTBUG-59707 Change-Id: I93cf3abb07a96a69290c3b5b055b688a62fe8fff Reviewed-by: J-P Nurmi <jpnurmi@qt.io>
This commit is contained in:
parent
6d7c3c0743
commit
1f9c7b065f
|
@ -0,0 +1,36 @@
|
|||
import QtQuick 2.0
|
||||
import Test 1.0
|
||||
|
||||
Flickable {
|
||||
width: 240
|
||||
height: 320
|
||||
contentWidth: width * 1.5
|
||||
contentHeight: height * 1.5
|
||||
contentY: height * 0.25
|
||||
|
||||
Rectangle {
|
||||
id: slider
|
||||
width: 50
|
||||
height: 200
|
||||
color: "lightgray"
|
||||
border.color: drag.active ? "green" : "black"
|
||||
anchors.centerIn: parent
|
||||
radius: 4
|
||||
|
||||
TouchDragArea {
|
||||
id: drag
|
||||
objectName: "drag"
|
||||
anchors.fill: parent
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
width: parent.width - 2
|
||||
height: 20
|
||||
radius: 5
|
||||
color: "darkgray"
|
||||
border.color: "black"
|
||||
x: 1
|
||||
y: Math.min(slider.height - height, Math.max(0, drag.pos.y - height / 2))
|
||||
}
|
||||
}
|
||||
}
|
|
@ -46,6 +46,99 @@
|
|||
using namespace QQuickViewTestUtil;
|
||||
using namespace QQuickVisualTestUtil;
|
||||
|
||||
// an abstract Slider which only handles touch events
|
||||
class TouchDragArea : public QQuickItem
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(QPointF pos READ pos NOTIFY posChanged)
|
||||
Q_PROPERTY(bool active READ active NOTIFY activeChanged)
|
||||
Q_PROPERTY(bool keepMouseGrab READ keepMouseGrab WRITE setKeepMouseGrab NOTIFY keepMouseGrabChanged)
|
||||
Q_PROPERTY(bool keepTouchGrab READ keepTouchGrab WRITE setKeepTouchGrab NOTIFY keepTouchGrabChanged)
|
||||
|
||||
public:
|
||||
TouchDragArea(QQuickItem *parent = 0)
|
||||
: QQuickItem(parent)
|
||||
, touchEvents(0)
|
||||
, touchUpdates(0)
|
||||
, touchReleases(0)
|
||||
, ungrabs(0)
|
||||
, m_active(false)
|
||||
{
|
||||
setFlags(ItemAcceptsDrops);
|
||||
}
|
||||
|
||||
QPointF pos() const { return m_pos; }
|
||||
|
||||
bool active() const { return m_active; }
|
||||
|
||||
void setKeepMouseGrab(bool keepMouseGrab)
|
||||
{
|
||||
QQuickItem::setKeepMouseGrab(keepMouseGrab);
|
||||
emit keepMouseGrabChanged();
|
||||
}
|
||||
|
||||
void setKeepTouchGrab(bool keepTouchGrab)
|
||||
{
|
||||
QQuickItem::setKeepTouchGrab(keepTouchGrab);
|
||||
emit keepTouchGrabChanged();
|
||||
}
|
||||
|
||||
int touchEvents;
|
||||
int touchUpdates;
|
||||
int touchReleases;
|
||||
int ungrabs;
|
||||
QVector<Qt::TouchPointState> touchPointStates;
|
||||
|
||||
protected:
|
||||
void touchEvent(QTouchEvent *ev) override
|
||||
{
|
||||
QCOMPARE(ev->touchPoints().count(), 1);
|
||||
auto touchpoint = ev->touchPoints().first();
|
||||
switch (touchpoint.state()) {
|
||||
case Qt::TouchPointPressed:
|
||||
QVERIFY(!m_active);
|
||||
m_active = true;
|
||||
emit activeChanged();
|
||||
grabTouchPoints(QVector<int>() << touchpoint.id());
|
||||
break;
|
||||
case Qt::TouchPointMoved:
|
||||
++touchUpdates;
|
||||
break;
|
||||
case Qt::TouchPointReleased:
|
||||
QVERIFY(m_active);
|
||||
m_active = false;
|
||||
++touchReleases;
|
||||
emit activeChanged();
|
||||
case Qt::TouchPointStationary:
|
||||
break;
|
||||
}
|
||||
touchPointStates << touchpoint.state();
|
||||
++touchEvents;
|
||||
m_pos = touchpoint.pos();
|
||||
emit posChanged();
|
||||
}
|
||||
|
||||
void touchUngrabEvent() override
|
||||
{
|
||||
++ungrabs;
|
||||
QVERIFY(m_active);
|
||||
emit ungrabbed();
|
||||
m_active = false;
|
||||
emit activeChanged();
|
||||
}
|
||||
|
||||
signals:
|
||||
void ungrabbed();
|
||||
void posChanged();
|
||||
void keepMouseGrabChanged();
|
||||
void keepTouchGrabChanged();
|
||||
void activeChanged();
|
||||
|
||||
private:
|
||||
QPointF m_pos;
|
||||
bool m_active;
|
||||
};
|
||||
|
||||
class tst_qquickflickable : public QQmlDataTest
|
||||
{
|
||||
Q_OBJECT
|
||||
|
@ -55,6 +148,7 @@ public:
|
|||
{}
|
||||
|
||||
private slots:
|
||||
void initTestCase() override;
|
||||
void create();
|
||||
void horizontalViewportSize();
|
||||
void verticalViewportSize();
|
||||
|
@ -92,6 +186,8 @@ private slots:
|
|||
void stopAtBounds();
|
||||
void stopAtBounds_data();
|
||||
void nestedMouseAreaUsingTouch();
|
||||
void nestedSliderUsingTouch();
|
||||
void nestedSliderUsingTouch_data();
|
||||
void pressDelayWithLoader();
|
||||
void movementFromProgrammaticFlick();
|
||||
void cleanup();
|
||||
|
@ -108,6 +204,12 @@ private:
|
|||
QTouchDevice *touchDevice;
|
||||
};
|
||||
|
||||
void tst_qquickflickable::initTestCase()
|
||||
{
|
||||
QQmlDataTest::initTestCase();
|
||||
qmlRegisterType<TouchDragArea>("Test",1,0,"TouchDragArea");
|
||||
}
|
||||
|
||||
void tst_qquickflickable::cleanup()
|
||||
{
|
||||
QVERIFY(QGuiApplication::topLevelWindows().isEmpty());
|
||||
|
@ -1889,6 +1991,65 @@ void tst_qquickflickable::nestedMouseAreaUsingTouch()
|
|||
QVERIFY(nested->y() < 100.0);
|
||||
}
|
||||
|
||||
void tst_qquickflickable::nestedSliderUsingTouch_data()
|
||||
{
|
||||
QTest::addColumn<bool>("keepMouseGrab");
|
||||
QTest::addColumn<bool>("keepTouchGrab");
|
||||
QTest::addColumn<int>("updates");
|
||||
QTest::addColumn<int>("releases");
|
||||
QTest::addColumn<int>("ungrabs");
|
||||
|
||||
QTest::newRow("keepBoth") << true << true << 8 << 1 << 0;
|
||||
QTest::newRow("keepMouse") << true << false << 8 << 1 << 0;
|
||||
QTest::newRow("keepTouch") << false << true << 8 << 1 << 0;
|
||||
QTest::newRow("keepNeither") << false << false << 6 << 0 << 1;
|
||||
}
|
||||
|
||||
void tst_qquickflickable::nestedSliderUsingTouch()
|
||||
{
|
||||
QFETCH(bool, keepMouseGrab);
|
||||
QFETCH(bool, keepTouchGrab);
|
||||
QFETCH(int, updates);
|
||||
QFETCH(int, releases);
|
||||
QFETCH(int, ungrabs);
|
||||
|
||||
QQuickView *window = new QQuickView;
|
||||
QScopedPointer<QQuickView> windowPtr(window);
|
||||
windowPtr->setSource(testFileUrl("nestedSlider.qml"));
|
||||
QTRY_COMPARE(window->status(), QQuickView::Ready);
|
||||
QQuickViewTestUtil::centerOnScreen(window);
|
||||
QQuickViewTestUtil::moveMouseAway(window);
|
||||
window->show();
|
||||
QVERIFY(QTest::qWaitForWindowActive(window));
|
||||
QVERIFY(window->rootObject() != 0);
|
||||
|
||||
QQuickFlickable *flickable = qobject_cast<QQuickFlickable*>(window->rootObject());
|
||||
QVERIFY(flickable);
|
||||
|
||||
TouchDragArea *tda = flickable->findChild<TouchDragArea*>("drag");
|
||||
QVERIFY(tda);
|
||||
|
||||
// Drag down and a little to the right: flickable will steal the grab only if tda allows it
|
||||
const int dragThreshold = qApp->styleHints()->startDragDistance();
|
||||
tda->setKeepMouseGrab(keepMouseGrab);
|
||||
tda->setKeepTouchGrab(keepTouchGrab);
|
||||
QPoint p0 = tda->mapToScene(QPoint(20, 20)).toPoint();
|
||||
QTest::touchEvent(window, touchDevice).press(0, p0, window);
|
||||
QQuickTouchUtils::flush(window);
|
||||
for (int i = 0; i < 8; ++i) {
|
||||
p0 += QPoint(dragThreshold / 6, dragThreshold / 4);
|
||||
QTest::touchEvent(window, touchDevice).move(0, p0, window);
|
||||
QQuickTouchUtils::flush(window);
|
||||
}
|
||||
QCOMPARE(tda->active(), !ungrabs);
|
||||
QTest::touchEvent(window, touchDevice).release(0, p0, window);
|
||||
QQuickTouchUtils::flush(window);
|
||||
QCOMPARE(tda->touchPointStates.first(), Qt::TouchPointPressed);
|
||||
QCOMPARE(tda->touchUpdates, updates);
|
||||
QCOMPARE(tda->touchReleases, releases);
|
||||
QCOMPARE(tda->ungrabs, ungrabs);
|
||||
}
|
||||
|
||||
// QTBUG-31328
|
||||
void tst_qquickflickable::pressDelayWithLoader()
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue