diff options
author | Igor Bugaev <freedbrt@gmail.com> | 2021-06-15 12:46:41 +0300 |
---|---|---|
committer | Qt Cherry-pick Bot <cherrypick_bot@qt-project.org> | 2021-07-02 15:13:26 +0000 |
commit | fb09279c010c35e1681030bd2d17ec21c5ab7b21 (patch) | |
tree | bbdc7db1a174a5ed22ef365a78dd73ba222fca74 | |
parent | 884794fcf559f7afe8f9a64c42160955f779b02a (diff) |
Make QQuickItem containmentMask be dependent on position
[ChangeLog][QQuickItem] Previously, containmentMask's position was
ignored. If containmentMask parent inherit from QQuickItem, then
position will take into account. In some cases, this is useful, for
example, to make click on button larger than the size of the button
itself, in all directions, not just to the right and bottom.
Fixes: QTBUG-82678
Change-Id: Iec70352db2d866198713a72d4d589a06105f30bc
Reviewed-by: Mitch Curtis <mitch.curtis@qt.io>
(cherry picked from commit c7297de660d44e2948a3488029a81063b462f364)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
-rw-r--r-- | src/quick/items/qquickitem.cpp | 12 | ||||
-rw-r--r-- | src/quick/items/qquickitem_p.h | 1 | ||||
-rw-r--r-- | tests/auto/quick/qquickitem/data/containsContainmentMask.qml | 40 | ||||
-rw-r--r-- | tests/auto/quick/qquickitem/tst_qquickitem.cpp | 42 |
4 files changed, 91 insertions, 4 deletions
diff --git a/src/quick/items/qquickitem.cpp b/src/quick/items/qquickitem.cpp index 2b81b2c5d0..c7540afce4 100644 --- a/src/quick/items/qquickitem.cpp +++ b/src/quick/items/qquickitem.cpp @@ -8082,17 +8082,20 @@ bool QQuickItem::contains(const QPointF &point) const { Q_D(const QQuickItem); if (d->mask) { + if (d->quickMask) + return d->quickMask->contains(point - d->quickMask->position()); + bool res = false; d->extra->maskContains.invoke(d->mask, Qt::DirectConnection, Q_RETURN_ARG(bool, res), Q_ARG(QPointF, point)); return res; - } else { - qreal x = point.x(); - qreal y = point.y(); - return x >= 0 && y >= 0 && x < d->width && y < d->height; } + + qreal x = point.x(); + qreal y = point.y(); + return x >= 0 && y >= 0 && x < d->width && y < d->height; } /*! @@ -8145,6 +8148,7 @@ void QQuickItem::setContainmentMask(QObject *mask) } d->mask = mask; quickMask = qobject_cast<QQuickItem *>(mask); + d->quickMask = quickMask; if (quickMask) { QQuickItemPrivate *maskPrivate = QQuickItemPrivate::get(quickMask); maskPrivate->registerAsContainmentMask(this, true); // telling maskPrivate that "this" is using it as mask diff --git a/src/quick/items/qquickitem_p.h b/src/quick/items/qquickitem_p.h index 6be0f10c6d..d8a7c1dfdc 100644 --- a/src/quick/items/qquickitem_p.h +++ b/src/quick/items/qquickitem_p.h @@ -418,6 +418,7 @@ public: QLazilyAllocated<ExtraData, ExtraDataTags> extra; // Contains mask QPointer<QObject> mask; + QPointer<QQuickItem> quickMask; // If the mask is an Item, inform it that it's being used as a mask (true) or is no longer being used (false) virtual void registerAsContainmentMask(QQuickItem * /* maskedItem */, bool /* set */) { } diff --git a/tests/auto/quick/qquickitem/data/containsContainmentMask.qml b/tests/auto/quick/qquickitem/data/containsContainmentMask.qml new file mode 100644 index 0000000000..cbf7f9222f --- /dev/null +++ b/tests/auto/quick/qquickitem/data/containsContainmentMask.qml @@ -0,0 +1,40 @@ +import QtQuick 2.11 + +Item { + width: 200 + height: 200 + + Item { + id: firstItem + + objectName: "firstItem" + x: 6 + y: 6 + width: 1000 + height: 1000 + + containmentMask: Item { + x: -5 + y: -5 + width: 10 + height: 10 + } + } + + Item { + id: secondItem + + objectName: "secondItem" + x: 6 + y: 6 + width: 0 + height: 0 + + containmentMask: Item { + parent: secondItem + anchors.centerIn: parent + width: 10 + height: 10 + } + } +} diff --git a/tests/auto/quick/qquickitem/tst_qquickitem.cpp b/tests/auto/quick/qquickitem/tst_qquickitem.cpp index f1680de331..79e2925f91 100644 --- a/tests/auto/quick/qquickitem/tst_qquickitem.cpp +++ b/tests/auto/quick/qquickitem/tst_qquickitem.cpp @@ -220,6 +220,8 @@ private slots: void contains_data(); void contains(); + void containsContainmentMask_data(); + void containsContainmentMask(); void childAt(); @@ -2081,6 +2083,46 @@ void tst_qquickitem::contains() QCOMPARE(result.toBool(), contains); } +void tst_qquickitem::containsContainmentMask_data() +{ + QTest::addColumn<QPointF>("point"); + QTest::addColumn<bool>("contains"); + + QTest::newRow("(-6, -6) = false") << QPointF(-6, -6) << false; + QTest::newRow("(-5, -5) = true") << QPointF(-5, -5) << true; + QTest::newRow("(-4, -4) = true") << QPointF(-4, -4) << true; + QTest::newRow("(-3, -3) = true") << QPointF(-3, -3) << true; + QTest::newRow("(-2, -2) = true") << QPointF(-2, -2) << true; + QTest::newRow("(-1, -1) = true") << QPointF(-1, -1) << true; + QTest::newRow("(0, 0) = true") << QPointF(0, 0) << true; + QTest::newRow("(1, 1) = true") << QPointF(1, 1) << true; + QTest::newRow("(2, 2) = true") << QPointF(2, 2) << true; + QTest::newRow("(3, 3) = true") << QPointF(3, 3) << true; + QTest::newRow("(4, 4) = true") << QPointF(4, 4) << true; + QTest::newRow("(5, 5) = false") << QPointF(5, 5) << false; +} + +void tst_qquickitem::containsContainmentMask() +{ + QFETCH(QPointF, point); + QFETCH(bool, contains); + + QQuickView view; + view.setSource(testFileUrl("containsContainmentMask.qml")); + + QQuickItem *root = qobject_cast<QQuickItem*>(view.rootObject()); + QVERIFY(root); + + QQuickItem *firstItem = root->findChild<QQuickItem*>("firstItem"); + QVERIFY(firstItem); + + QQuickItem *secondItem = root->findChild<QQuickItem*>("secondItem"); + QVERIFY(secondItem); + + QCOMPARE(firstItem->contains(point), contains); + QCOMPARE(secondItem->contains(point), contains); +} + void tst_qquickitem::childAt() { QQuickView view; |