aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIgor Bugaev <freedbrt@gmail.com>2021-06-15 12:46:41 +0300
committerQt Cherry-pick Bot <cherrypick_bot@qt-project.org>2021-07-02 15:13:26 +0000
commitfb09279c010c35e1681030bd2d17ec21c5ab7b21 (patch)
treebbdc7db1a174a5ed22ef365a78dd73ba222fca74
parent884794fcf559f7afe8f9a64c42160955f779b02a (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.cpp12
-rw-r--r--src/quick/items/qquickitem_p.h1
-rw-r--r--tests/auto/quick/qquickitem/data/containsContainmentMask.qml40
-rw-r--r--tests/auto/quick/qquickitem/tst_qquickitem.cpp42
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;