aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlan Alpert <alan.alpert@nokia.com>2011-11-15 11:51:50 +1000
committerQt by Nokia <qt-info@nokia.com>2011-11-15 05:39:36 +0100
commit520f9bebac742f885dc398533d91924de8793064 (patch)
treeb0b5e2361de765d6e193220f8189b92451829b5b
parent077c7eb97c822e70fdb2bfe88e3ddec46897ef6e (diff)
Add propagateComposedEvents property to MouseArea
While necessary, advanced event propagation isn't the common use case. Now needs to be explicitly enabled. Task-number: QTBUG-21081 Change-Id: Ibd8b4974934116dbfa32cc5e72037fd9b11015b4 Reviewed-by: Michael Brasser <michael.brasser@nokia.com>
-rw-r--r--doc/src/declarative/whatsnew.qdoc5
-rw-r--r--src/declarative/items/qquickmousearea.cpp49
-rw-r--r--src/declarative/items/qquickmousearea_p.h5
-rw-r--r--src/declarative/items/qquickmousearea_p_p.h1
-rw-r--r--tests/auto/declarative/qquickmousearea/data/clickThrough.qml2
-rw-r--r--tests/auto/declarative/qquickmousearea/data/clickThrough2.qml3
-rw-r--r--tests/auto/declarative/qquickmousearea/tst_qquickmousearea.cpp20
7 files changed, 77 insertions, 8 deletions
diff --git a/doc/src/declarative/whatsnew.qdoc b/doc/src/declarative/whatsnew.qdoc
index 749392a143..3a26b3737c 100644
--- a/doc/src/declarative/whatsnew.qdoc
+++ b/doc/src/declarative/whatsnew.qdoc
@@ -86,9 +86,10 @@ The \l{QtQuick.Particles 2}{QtQuick.Particles} module contains elements that can
New \l SpriteImage element renders animated sprites and can transition between animations.
It uses the \l Sprite element to represent each animation.
-MouseArea now propagates clicked, doubleClicked and pressAndHold differently to pressed.
-These will now be propagated to the highest-stacking-order enabled MouseArea which has a handler for them.
+MouseArea can now propagate clicked, doubleClicked and pressAndHold differently to pressed.
+These can now be propagated to the highest-stacking-order enabled MouseArea which has a handler for them.
You can still ignore these events in the handler to let them pass through.
+This behavior is triggered with the new property propagateComposedEvents.
The Binding element can now be used as a value source, and will also restore any previously
set binding when its \i when clause becomes false.
diff --git a/src/declarative/items/qquickmousearea.cpp b/src/declarative/items/qquickmousearea.cpp
index 19e7fd457b..8d4f3e86b0 100644
--- a/src/declarative/items/qquickmousearea.cpp
+++ b/src/declarative/items/qquickmousearea.cpp
@@ -184,7 +184,7 @@ QQuickDragAttached *QQuickDrag::qmlAttachedProperties(QObject *obj)
QQuickMouseAreaPrivate::QQuickMouseAreaPrivate()
: absorb(true), hovered(false), pressed(false), longPress(false),
moved(false), stealMouse(false), doubleClick(false), preventStealing(false),
- drag(0)
+ propagateComposedEvents(false), drag(0)
{
}
@@ -233,6 +233,8 @@ bool QQuickMouseAreaPrivate::isClickConnected()
void QQuickMouseAreaPrivate::propagate(QQuickMouseEvent* event, PropagateType t)
{
Q_Q(QQuickMouseArea);
+ if (!propagateComposedEvents)
+ return;
QPointF scenePos = q->mapToScene(QPointF(event->x(), event->y()));
propagateHelper(event, canvas->rootItem(), scenePos, t);
}
@@ -357,14 +359,11 @@ bool QQuickMouseAreaPrivate::propagateHelper(QQuickMouseEvent *ev, QQuickItem *i
Behavioral Change in QtQuick 2.0
From QtQuick 2.0, the signals clicked, doubleClicked and pressAndHold have a different interaction
- model with regards to the delivery of events to multiple overlapping MouseAreas. These signals will now propagate
+ model with regards to the delivery of events to multiple overlapping MouseAreas. These signals can now propagate
to all MouseAreas in the area, in painting order, until accepted by one of them. A signal is accepted by
default if there is a signal handler for it, use mouse.accepted = false; to ignore. This propagation
can send the signal to MouseAreas other than the one which accepted the press event, although that MouseArea
- will receive the signal first.
-
- Note that to get the same behavior as a QtQuick 1.0 MouseArea{} with regard to absorbing all mouse events, you will
- now need to add empty signal handlers for these three signals.
+ will receive the signal first. This behavior can be enabled by setting propagateComposedEvents to true.
\sa MouseEvent, {declarative/touchinteraction/mousearea}{MouseArea example}
*/
@@ -603,6 +602,44 @@ void QQuickMouseArea::setPreventStealing(bool prevent)
}
}
+
+/*!
+ \qmlproperty bool QtQuick2::MouseArea::propagateComposedEvents
+ This property holds whether composed mouse events will automatically propagate to
+ other MouseAreas.
+
+ MouseArea contains several composed events, clicked, doubleClicked,
+ and pressAndHold. These can propagate via a separate mechanism to basic
+ mouse events, like pressed, which they are composed of.
+
+ If propagateComposedEvents is set to true, then composed events will be automatically
+ propagated to other MouseAreas in the same location in the scene. They are propagated
+ in painting order until an item accepts them. Unlike pressed handling, events will
+ not be automatically accepted if no handler is present.
+
+ This property greatly simplifies the usecase of when you want to have overlapping MouseAreas
+ handling the composed events together. For example: if you want one MouseArea to handle click
+ signals and the other to handle pressAndHold, or if you want one MouseArea to handle click most
+ of the time, but pass it through when certain conditions are met.
+
+ By default this property is false.
+*/
+bool QQuickMouseArea::propagateComposedEvents() const
+{
+ Q_D(const QQuickMouseArea);
+ return d->propagateComposedEvents;
+}
+
+void QQuickMouseArea::setPropagateComposedEvents(bool prevent)
+{
+ Q_D(QQuickMouseArea);
+ if (prevent != d->propagateComposedEvents) {
+ d->propagateComposedEvents = prevent;
+ setKeepMouseGrab(d->propagateComposedEvents && d->absorb);
+ emit propagateComposedEventsChanged();
+ }
+}
+
/*!
\qmlproperty MouseButtons QtQuick2::MouseArea::pressedButtons
This property holds the mouse buttons currently pressed.
diff --git a/src/declarative/items/qquickmousearea_p.h b/src/declarative/items/qquickmousearea_p.h
index 6f15ff6eb4..b8fa7d5ce8 100644
--- a/src/declarative/items/qquickmousearea_p.h
+++ b/src/declarative/items/qquickmousearea_p.h
@@ -137,6 +137,7 @@ class Q_DECLARATIVE_EXPORT QQuickMouseArea : public QQuickItem
Q_PROPERTY(bool hoverEnabled READ hoverEnabled WRITE setHoverEnabled NOTIFY hoverEnabledChanged)
Q_PROPERTY(QQuickDrag *drag READ drag CONSTANT) //### add flicking to QQuickDrag or add a QDeclarativeFlick ???
Q_PROPERTY(bool preventStealing READ preventStealing WRITE setPreventStealing NOTIFY preventStealingChanged)
+ Q_PROPERTY(bool propagateComposedEvents READ propagateComposedEvents WRITE setPropagateComposedEvents NOTIFY propagateComposedEventsChanged)
public:
QQuickMouseArea(QQuickItem *parent=0);
@@ -164,6 +165,9 @@ public:
bool preventStealing() const;
void setPreventStealing(bool prevent);
+ bool propagateComposedEvents() const;
+ void setPropagateComposedEvents(bool propagate);
+
Q_SIGNALS:
void hoveredChanged();
void pressedChanged();
@@ -174,6 +178,7 @@ Q_SIGNALS:
void mouseXChanged(QQuickMouseEvent *mouse);
void mouseYChanged(QQuickMouseEvent *mouse);
void preventStealingChanged();
+ void propagateComposedEventsChanged();
void pressed(QQuickMouseEvent *mouse);
void pressAndHold(QQuickMouseEvent *mouse);
diff --git a/src/declarative/items/qquickmousearea_p_p.h b/src/declarative/items/qquickmousearea_p_p.h
index 9f81bf976f..c1c53c4302 100644
--- a/src/declarative/items/qquickmousearea_p_p.h
+++ b/src/declarative/items/qquickmousearea_p_p.h
@@ -95,6 +95,7 @@ public:
bool stealMouse : 1;
bool doubleClick : 1;
bool preventStealing : 1;
+ bool propagateComposedEvents : 1;
QQuickDrag *drag;
QPointF startScene;
QPointF targetStartPos;
diff --git a/tests/auto/declarative/qquickmousearea/data/clickThrough.qml b/tests/auto/declarative/qquickmousearea/data/clickThrough.qml
index 0d954f8511..3c03161faa 100644
--- a/tests/auto/declarative/qquickmousearea/data/clickThrough.qml
+++ b/tests/auto/declarative/qquickmousearea/data/clickThrough.qml
@@ -10,6 +10,7 @@ Item{
MouseArea{
z: 0
anchors.fill: parent
+ propagateComposedEvents: true
onPressed: presses++
onClicked: clicks++
onPressAndHold: pressAndHolds++
@@ -17,6 +18,7 @@ Item{
}
MouseArea{
z: 1
+ propagateComposedEvents: true
enabled: true
anchors.fill: parent
}
diff --git a/tests/auto/declarative/qquickmousearea/data/clickThrough2.qml b/tests/auto/declarative/qquickmousearea/data/clickThrough2.qml
index bc73a1bf8a..2624108225 100644
--- a/tests/auto/declarative/qquickmousearea/data/clickThrough2.qml
+++ b/tests/auto/declarative/qquickmousearea/data/clickThrough2.qml
@@ -8,6 +8,7 @@ Item{
property int pressAndHolds: 0
property int presses: 0
property bool letThrough: false
+ property bool noPropagation: false
Rectangle{
z: 0
color: "lightsteelblue"
@@ -15,6 +16,7 @@ Item{
height: 150
MouseArea{
anchors.fill: parent
+ propagateComposedEvents: true
onPressed: presses++
onClicked: clicks++
onPressAndHold: pressAndHolds++
@@ -25,6 +27,7 @@ Item{
z: 1
enabled: true
anchors.fill: parent
+ propagateComposedEvents: !noPropagation
onClicked: mouse.accepted = !letThrough;
onDoubleClicked: mouse.accepted = !letThrough;
onPressAndHold: mouse.accepted = !letThrough;
diff --git a/tests/auto/declarative/qquickmousearea/tst_qquickmousearea.cpp b/tests/auto/declarative/qquickmousearea/tst_qquickmousearea.cpp
index af4dc610c7..23b5fa022b 100644
--- a/tests/auto/declarative/qquickmousearea/tst_qquickmousearea.cpp
+++ b/tests/auto/declarative/qquickmousearea/tst_qquickmousearea.cpp
@@ -716,6 +716,26 @@ void tst_QQuickMouseArea::clickThrough()
QCOMPARE(canvas->rootObject()->property("doubleClicks").toInt(), 1);
QCOMPARE(canvas->rootObject()->property("pressAndHolds").toInt(), 1);
+ canvas->rootObject()->setProperty("noPropagation", QVariant(true));
+
+ QTest::qWait(800); // to avoid generating a double click.
+ QTest::mousePress(canvas, Qt::LeftButton, 0, QPoint(100,100));
+ QTest::mouseRelease(canvas, Qt::LeftButton, 0, QPoint(100,100));
+
+ QTest::qWait(800); // to avoid generating a double click.
+ QTest::mousePress(canvas, Qt::LeftButton, 0, QPoint(100,100));
+ QTest::qWait(1000);
+ QTest::mouseRelease(canvas, Qt::LeftButton, 0, QPoint(100,100));
+ QTest::qWait(100);
+
+ QTest::mouseDClick(canvas, Qt::LeftButton, 0, QPoint(100,100));
+ QTest::qWait(100);
+
+ QCOMPARE(canvas->rootObject()->property("presses").toInt(), 0);
+ QTRY_COMPARE(canvas->rootObject()->property("clicks").toInt(), 2);
+ QCOMPARE(canvas->rootObject()->property("doubleClicks").toInt(), 1);
+ QCOMPARE(canvas->rootObject()->property("pressAndHolds").toInt(), 1);
+
delete canvas;
}