Add mergePointerTargets to create pointer delivery list

This code joins lists of "target item" which are joins of where several
touch points should be delivered.

Change-Id: I15ab4b7f70b8930d15368bf4cba0893ab339fa2a
Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
This commit is contained in:
Frederik Gladhorn 2016-07-12 16:16:28 +02:00 committed by Shawn Rutledge
parent b4f05d7010
commit bf2c880b2b
3 changed files with 84 additions and 0 deletions

View File

@ -2169,6 +2169,28 @@ QVector<QQuickItem *> QQuickWindowPrivate::pointerTargets(QQuickItem *item, cons
return targets;
}
// return the joined lists
// list1 has priority, common items come last
QVector<QQuickItem *> QQuickWindowPrivate::mergePointerTargets(const QVector<QQuickItem *> &list1, const QVector<QQuickItem *> &list2) const
{
QVector<QQuickItem *> targets = list1;
// start at the end of list2
// if item not in list, append it
// if item found, move to next one, inserting before the last found one
int insertPosition = targets.length();
for (int i = list2.length() - 1; i >= 0; --i) {
int newInsertPosition = targets.lastIndexOf(list2.at(i), insertPosition);
if (newInsertPosition >= 0) {
Q_ASSERT(newInsertPosition <= insertPosition);
insertPosition = newInsertPosition;
}
// check for duplicates, only insert if the item isn't there already
if (insertPosition == targets.size() || list2.at(i) != targets.at(insertPosition))
targets.insert(insertPosition, list2.at(i));
}
return targets;
}
void QQuickWindowPrivate::deliverTouchEvent(QQuickPointerTouchEvent *event)
{
qCDebug(DBG_TOUCH) << " - delivering" << event->asTouchEvent();

View File

@ -175,6 +175,8 @@ public:
bool sendFilteredTouchEvent(QQuickItem *target, QQuickItem *item, QTouchEvent *event, QSet<QQuickItem*> *filtered);
QVector<QQuickItem *> pointerTargets(QQuickItem *, const QPointF &) const;
QVector<QQuickItem *> mergePointerTargets(const QVector<QQuickItem *> &list1, const QVector<QQuickItem *> &list2) const;
// hover delivery
bool deliverHoverEvent(QQuickItem *, const QPointF &scenePos, const QPointF &lastScenePos, Qt::KeyboardModifiers modifiers, bool &accepted);
bool sendHoverEvent(QEvent::Type, QQuickItem *, const QPointF &scenePos, const QPointF &lastScenePos,

View File

@ -303,6 +303,9 @@ private slots:
void touchEvent_reentrant();
void touchEvent_velocity();
void mergeTouchPointLists_data();
void mergeTouchPointLists();
void mouseFromTouch_basic();
void clearWindow();
@ -903,6 +906,63 @@ void tst_qquickwindow::touchEvent_velocity()
delete item;
}
void tst_qquickwindow::mergeTouchPointLists_data()
{
QTest::addColumn<QVector<QQuickItem*>>("list1");
QTest::addColumn<QVector<QQuickItem*>>("list2");
QTest::addColumn<QVector<QQuickItem*>>("expected");
QTest::addColumn<bool>("showItem");
// FIXME: do not leak all these items
auto item1 = new QQuickItem();
auto item2 = new QQuickItem();
auto item3 = new QQuickItem();
auto item4 = new QQuickItem();
auto item5 = new QQuickItem();
QTest::newRow("empty") << QVector<QQuickItem*>() << QVector<QQuickItem*>() << QVector<QQuickItem*>();
QTest::newRow("single list left")
<< (QVector<QQuickItem*>() << item1 << item2 << item3)
<< QVector<QQuickItem*>()
<< (QVector<QQuickItem*>() << item1 << item2 << item3);
QTest::newRow("single list right")
<< QVector<QQuickItem*>()
<< (QVector<QQuickItem*>() << item1 << item2 << item3)
<< (QVector<QQuickItem*>() << item1 << item2 << item3);
QTest::newRow("two lists identical")
<< (QVector<QQuickItem*>() << item1 << item2 << item3)
<< (QVector<QQuickItem*>() << item1 << item2 << item3)
<< (QVector<QQuickItem*>() << item1 << item2 << item3);
QTest::newRow("two lists 1")
<< (QVector<QQuickItem*>() << item1 << item2 << item5)
<< (QVector<QQuickItem*>() << item3 << item4 << item5)
<< (QVector<QQuickItem*>() << item1 << item2 << item3 << item4 << item5);
QTest::newRow("two lists 2")
<< (QVector<QQuickItem*>() << item1 << item2 << item5)
<< (QVector<QQuickItem*>() << item3 << item4 << item5)
<< (QVector<QQuickItem*>() << item1 << item2 << item3 << item4 << item5);
QTest::newRow("two lists 3")
<< (QVector<QQuickItem*>() << item1 << item2 << item3)
<< (QVector<QQuickItem*>() << item1 << item4 << item5)
<< (QVector<QQuickItem*>() << item1 << item2 << item3 << item4 << item5);
QTest::newRow("two lists 3")
<< (QVector<QQuickItem*>() << item1 << item3 << item4)
<< (QVector<QQuickItem*>() << item2 << item3 << item5)
<< (QVector<QQuickItem*>() << item1 << item2 << item3 << item4 << item5);
}
void tst_qquickwindow::mergeTouchPointLists()
{
QFETCH(QVector<QQuickItem*>, list1);
QFETCH(QVector<QQuickItem*>, list2);
QFETCH(QVector<QQuickItem*>, expected);
QQuickWindow win;
auto windowPrivate = QQuickWindowPrivate::get(&win);
auto targetList = windowPrivate->mergePointerTargets(list1, list2);
QCOMPARE(targetList, expected);
}
void tst_qquickwindow::mouseFromTouch_basic()
{
// Turn off accepting touch events with acceptTouchEvents. This