From 112efda64ba24e7d9255a36065223e9800a50c21 Mon Sep 17 00:00:00 2001 From: Martin Jones Date: Fri, 11 Jul 2014 14:10:49 +1000 Subject: Add containsPress property to MouseArea It is very common to use pressed and containsMouse properties together to highlight a pressed item, e.g. property bool highlighted: pressed && containsMouse The containsPress property allows simplification and optimization of user code. [ChangeLog][QtQuick] Add containsPress property to MouseArea Task-number: QTBUG-40130 Change-Id: Ie286d431154eb37a99e57e4cf881d68d7cbbe31d Reviewed-by: Martin Jones --- examples/quick/mousearea/doc/src/mousearea.qdoc | 4 +- examples/quick/mousearea/mousearea.qml | 4 +- src/quick/items/qquickitemsmodule.cpp | 1 + src/quick/items/qquickmousearea.cpp | 30 +++++++++- src/quick/items/qquickmousearea_p.h | 3 + .../quick/qquickmousearea/data/containsPress.qml | 20 +++++++ .../quick/qquickmousearea/tst_qquickmousearea.cpp | 65 ++++++++++++++++++++++ 7 files changed, 123 insertions(+), 4 deletions(-) create mode 100644 tests/auto/quick/qquickmousearea/data/containsPress.qml diff --git a/examples/quick/mousearea/doc/src/mousearea.qdoc b/examples/quick/mousearea/doc/src/mousearea.qdoc index 827e5497ee..b1dd549a8e 100644 --- a/examples/quick/mousearea/doc/src/mousearea.qdoc +++ b/examples/quick/mousearea/doc/src/mousearea.qdoc @@ -40,7 +40,9 @@ \section1 MouseArea Behavior When you click inside the red square, the \l Text type will list several - properties of that click which are available to QML. + properties of that click which are available to QML. The opacity of the + red square will be reduced while the mouse is pressed and remains inside + the MouseArea. Signals are emitted by the MouseArea when clicks or other discrete operations occur within it. diff --git a/examples/quick/mousearea/mousearea.qml b/examples/quick/mousearea/mousearea.qml index dac891d729..8958391715 100644 --- a/examples/quick/mousearea/mousearea.qml +++ b/examples/quick/mousearea/mousearea.qml @@ -38,7 +38,7 @@ ** ****************************************************************************/ -import QtQuick 2.0 +import QtQuick 2.4 Rectangle { id: box @@ -49,10 +49,12 @@ Rectangle { width: 120; height: 120 anchors.top: parent.top; anchors.left: parent.left; anchors.margins: 10 color: "red" + opacity: redSquareMouseArea.containsPress ? 0.6 : 1.0 Text { text: "Click"; font.pixelSize: 16; anchors.centerIn: parent } MouseArea { + id: redSquareMouseArea anchors.fill: parent hoverEnabled: true property string buttonID diff --git a/src/quick/items/qquickitemsmodule.cpp b/src/quick/items/qquickitemsmodule.cpp index 2f20dd763b..22a6eeb4a5 100644 --- a/src/quick/items/qquickitemsmodule.cpp +++ b/src/quick/items/qquickitemsmodule.cpp @@ -270,6 +270,7 @@ static void qt_quickitems_defineModule(const char *uri, int major, int minor) qmlRegisterType(uri, 2, 3,"Image"); qmlRegisterType(uri, 2, 4, "Item"); + qmlRegisterType(uri, 2, 4, "MouseArea"); } static void initResources() diff --git a/src/quick/items/qquickmousearea.cpp b/src/quick/items/qquickmousearea.cpp index 2bb9158d51..d0c362456f 100644 --- a/src/quick/items/qquickmousearea.cpp +++ b/src/quick/items/qquickmousearea.cpp @@ -860,6 +860,7 @@ void QQuickMouseArea::ungrabMouse() emit canceled(); emit pressedChanged(); + emit containsPressChanged(); emit pressedButtonsChanged(); if (d->hovered && !isUnderMouse()) { @@ -917,6 +918,7 @@ bool QQuickMouseArea::sendMouseEvent(QMouseEvent *event) ungrabMouse(); emit canceled(); emit pressedChanged(); + emit containsPressChanged(); if (d->hovered) { d->hovered = false; emit hoveredChanged(); @@ -1062,6 +1064,24 @@ bool QQuickMouseArea::pressed() const return d->pressed; } +/*! + \qmlproperty bool QtQuick::MouseArea::containsPress + \since 5.4 + This is a convenience property equivalent to \c {pressed && containsMouse}, + i.e. it holds whether any of the \l acceptedButtons are currently pressed + and the mouse is currently within the MouseArea. + + This property is particularly useful for highlighting an item while the mouse + is pressed within its bounds. + + \sa pressed, containsMouse +*/ +bool QQuickMouseArea::containsPress() const +{ + Q_D(const QQuickMouseArea); + return d->pressed && d->hovered; +} + void QQuickMouseArea::setHovered(bool h) { Q_D(QQuickMouseArea); @@ -1069,6 +1089,8 @@ void QQuickMouseArea::setHovered(bool h) d->hovered = h; emit hoveredChanged(); d->hovered ? emit entered() : emit exited(); + if (d->pressed) + emit containsPressChanged(); } } @@ -1128,15 +1150,19 @@ bool QQuickMouseArea::setPressed(Qt::MouseButton button, bool p) emit mouseXChanged(&me); me.setPosition(d->lastPos); emit mouseYChanged(&me); - if (!oldPressed) + if (!oldPressed) { emit pressedChanged(); + emit containsPressChanged(); + } emit pressedButtonsChanged(); } else { d->pressed &= ~button; emit released(&me); me.setPosition(d->lastPos); - if (!d->pressed) + if (!d->pressed) { emit pressedChanged(); + emit containsPressChanged(); + } emit pressedButtonsChanged(); if (isclick && !d->longPress && !d->doubleClick){ me.setAccepted(d->isClickConnected()); diff --git a/src/quick/items/qquickmousearea_p.h b/src/quick/items/qquickmousearea_p.h index c564a78c3c..d303852311 100644 --- a/src/quick/items/qquickmousearea_p.h +++ b/src/quick/items/qquickmousearea_p.h @@ -73,6 +73,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickMouseArea : public QQuickItem #ifndef QT_NO_CURSOR Q_PROPERTY(Qt::CursorShape cursorShape READ cursorShape WRITE setCursorShape RESET unsetCursor NOTIFY cursorShapeChanged) #endif + Q_PROPERTY(bool containsPress READ containsPress NOTIFY containsPressChanged REVISION 1) public: QQuickMouseArea(QQuickItem *parent=0); @@ -86,6 +87,7 @@ public: bool hovered() const; bool pressed() const; + bool containsPress() const; Qt::MouseButtons pressedButtons() const; @@ -135,6 +137,7 @@ Q_SIGNALS: void entered(); void exited(); void canceled(); + Q_REVISION(1) void containsPressChanged(); protected: void setHovered(bool); diff --git a/tests/auto/quick/qquickmousearea/data/containsPress.qml b/tests/auto/quick/qquickmousearea/data/containsPress.qml new file mode 100644 index 0000000000..367c73c175 --- /dev/null +++ b/tests/auto/quick/qquickmousearea/data/containsPress.qml @@ -0,0 +1,20 @@ +import QtQuick 2.4 + +Item { + width: 500 + height: 500 + + Rectangle { + width: 300 + height: 300 + color: mouseArea.containsPress ? "red" : "grey" + x: 100 + y: 100 + + MouseArea { + id: mouseArea + objectName: "mouseArea" + anchors.fill: parent + } + } +} diff --git a/tests/auto/quick/qquickmousearea/tst_qquickmousearea.cpp b/tests/auto/quick/qquickmousearea/tst_qquickmousearea.cpp index ee29ed2075..75497a4b5f 100644 --- a/tests/auto/quick/qquickmousearea/tst_qquickmousearea.cpp +++ b/tests/auto/quick/qquickmousearea/tst_qquickmousearea.cpp @@ -123,6 +123,8 @@ private slots: void moveAndReleaseWithoutPress(); void nestedStopAtBounds(); void nestedStopAtBounds_data(); + void containsPress_data(); + void containsPress(); private: void acceptedButton_data(); @@ -1684,6 +1686,69 @@ void tst_QQuickMouseArea::nestedStopAtBounds() QTest::mouseRelease(&view, Qt::LeftButton, 0, position); } +void tst_QQuickMouseArea::containsPress_data() +{ + QTest::addColumn("hoverEnabled"); + + QTest::newRow("hover enabled") << true; + QTest::newRow("hover disaabled") << false; +} + +void tst_QQuickMouseArea::containsPress() +{ + QFETCH(bool, hoverEnabled); + + QQuickView window; + QByteArray errorMessage; + QVERIFY2(initView(window, testFileUrl("containsPress.qml"), true, &errorMessage), errorMessage.constData()); + window.show(); + window.requestActivate(); + QVERIFY(QTest::qWaitForWindowExposed(&window)); + QQuickItem *root = window.rootObject(); + QVERIFY(root != 0); + + QQuickMouseArea *mouseArea = window.rootObject()->findChild("mouseArea"); + QVERIFY(mouseArea != 0); + + QSignalSpy containsPressSpy(mouseArea, SIGNAL(containsPressChanged())); + + mouseArea->setHoverEnabled(hoverEnabled); + + QTest::mouseMove(&window, QPoint(22,33)); + QCOMPARE(mouseArea->hovered(), false); + QCOMPARE(mouseArea->pressed(), false); + QCOMPARE(mouseArea->containsPress(), false); + + QTest::mouseMove(&window, QPoint(200,200)); + QCOMPARE(mouseArea->hovered(), hoverEnabled); + QCOMPARE(mouseArea->pressed(), false); + QCOMPARE(mouseArea->containsPress(), false); + + QTest::mousePress(&window, Qt::LeftButton, Qt::NoModifier, QPoint(200,200)); + QCOMPARE(mouseArea->hovered(), true); + QTRY_COMPARE(mouseArea->pressed(), true); + QCOMPARE(mouseArea->containsPress(), true); + QCOMPARE(containsPressSpy.count(), 1); + + QTest::mouseMove(&window, QPoint(22,33)); + QCOMPARE(mouseArea->hovered(), false); + QCOMPARE(mouseArea->pressed(), true); + QCOMPARE(mouseArea->containsPress(), false); + QCOMPARE(containsPressSpy.count(), 2); + + QTest::mouseMove(&window, QPoint(200,200)); + QCOMPARE(mouseArea->hovered(), true); + QCOMPARE(mouseArea->pressed(), true); + QCOMPARE(mouseArea->containsPress(), true); + QCOMPARE(containsPressSpy.count(), 3); + + QTest::mouseRelease(&window, Qt::LeftButton, Qt::NoModifier, QPoint(200,200)); + QCOMPARE(mouseArea->hovered(), hoverEnabled); + QCOMPARE(mouseArea->pressed(), false); + QCOMPARE(mouseArea->containsPress(), false); + QCOMPARE(containsPressSpy.count(), 4); +} + QTEST_MAIN(tst_QQuickMouseArea) #include "tst_qquickmousearea.moc" -- cgit v1.2.3