Allow mouse interaction with 0 opacity items.
authorAndrew den Exter <andrew.den-exter@nokia.com>
Tue, 3 Jul 2012 02:29:57 +0000 (12:29 +1000)
committerQt by Nokia <qt-info@nokia.com>
Wed, 4 Jul 2012 00:45:03 +0000 (02:45 +0200)
Don't filter event delivery to items with 0 opacity, and update the
documentation the for opacity, visible and enabled properties and how
each affects event delivery.

Task-number: QTBUG-19193
Change-Id: Id48e4af763c9a7bbcc13b303342d303155dcadc9
Reviewed-by: Jan-Arve Sæther <jan-arve.saether@nokia.com>
Reviewed-by: Martin Jones <martin.jones@nokia.com>
src/plugins/accessible/quick/qaccessiblequickview.cpp
src/quick/items/qquickcanvas.cpp
src/quick/items/qquickitem.cpp
src/quick/items/qquickmousearea.cpp
tests/auto/quick/qquickcanvas/tst_qquickcanvas.cpp
tests/auto/quick/qquickdrag/tst_qquickdrag.cpp

index 5f66f00..c82c4e8 100644 (file)
@@ -118,7 +118,7 @@ QString QAccessibleQuickView::text(QAccessible::Text text) const
   */
 static QQuickItem *childAt_helper(QQuickItem *item, int x, int y)
 {
   */
 static QQuickItem *childAt_helper(QQuickItem *item, int x, int y)
 {
-    if (item->opacity() == 0.0 || !item->isVisible() || !item->isEnabled())
+    if (!item->isVisible() || !item->isEnabled())
         return 0;
 
     if (item->flags() & QQuickItem::ItemClipsChildrenToShape) {
         return 0;
 
     if (item->flags() & QQuickItem::ItemClipsChildrenToShape) {
index a242ca1..7e0f482 100644 (file)
@@ -1146,8 +1146,6 @@ bool QQuickCanvasPrivate::deliverInitialMousePressEvent(QQuickItem *item, QMouse
     Q_Q(QQuickCanvas);
 
     QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item);
     Q_Q(QQuickCanvas);
 
     QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item);
-    if (itemPrivate->opacity() == 0.0)
-        return false;
 
     if (itemPrivate->flags & QQuickItem::ItemClipsChildrenToShape) {
         QPointF p = item->mapFromScene(event->windowPos());
 
     if (itemPrivate->flags & QQuickItem::ItemClipsChildrenToShape) {
         QPointF p = item->mapFromScene(event->windowPos());
@@ -1306,8 +1304,6 @@ bool QQuickCanvasPrivate::deliverHoverEvent(QQuickItem *item, const QPointF &sce
                                          Qt::KeyboardModifiers modifiers, bool &accepted)
 {
     QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item);
                                          Qt::KeyboardModifiers modifiers, bool &accepted)
 {
     QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item);
-    if (itemPrivate->opacity() == 0.0)
-        return false;
 
     if (itemPrivate->flags & QQuickItem::ItemClipsChildrenToShape) {
         QPointF p = item->mapFromScene(scenePos);
 
     if (itemPrivate->flags & QQuickItem::ItemClipsChildrenToShape) {
         QPointF p = item->mapFromScene(scenePos);
@@ -1374,8 +1370,6 @@ bool QQuickCanvasPrivate::deliverWheelEvent(QQuickItem *item, QWheelEvent *event
 {
     Q_Q(QQuickCanvas);
     QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item);
 {
     Q_Q(QQuickCanvas);
     QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item);
-    if (itemPrivate->opacity() == 0.0)
-        return false;
 
     if (itemPrivate->flags & QQuickItem::ItemClipsChildrenToShape) {
         QPointF p = item->mapFromScene(event->posF());
 
     if (itemPrivate->flags & QQuickItem::ItemClipsChildrenToShape) {
         QPointF p = item->mapFromScene(event->posF());
@@ -1514,9 +1508,6 @@ bool QQuickCanvasPrivate::deliverTouchPoints(QQuickItem *item, QTouchEvent *even
 {
     QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item);
 
 {
     QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item);
 
-    if (qFuzzyIsNull(itemPrivate->opacity()))
-        return false;
-
     if (itemPrivate->flags & QQuickItem::ItemClipsChildrenToShape) {
         for (int i=0; i<newPoints.count(); i++) {
             QPointF p = item->mapFromScene(newPoints[i].scenePos());
     if (itemPrivate->flags & QQuickItem::ItemClipsChildrenToShape) {
         for (int i=0; i<newPoints.count(); i++) {
             QPointF p = item->mapFromScene(newPoints[i].scenePos());
@@ -1770,7 +1761,7 @@ bool QQuickCanvasPrivate::deliverDragEvent(QQuickDragGrabber *grabber, QQuickIte
     Q_Q(QQuickCanvas);
     bool accepted = false;
     QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item);
     Q_Q(QQuickCanvas);
     bool accepted = false;
     QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item);
-    if (itemPrivate->opacity() == 0.0 || !item->isVisible() || !item->isEnabled())
+    if (!item->isVisible() || !item->isEnabled())
         return false;
 
     QPointF p = item->mapFromScene(event->pos());
         return false;
 
     QPointF p = item->mapFromScene(event->pos());
index df557f1..9c43645 100644 (file)
@@ -2818,16 +2818,31 @@ void QQuickItemPrivate::transform_clear(QQmlListProperty<QQuickTransform> *prop)
     explicit property changes. In such cases it may be better to use the
     \l opacity property instead.)
 
     explicit property changes. In such cases it may be better to use the
     \l opacity property instead.)
 
-    Setting this property to \c false automatically causes \l focus to be set
-    to \c false, and this item will longer receive mouse and keyboard events.
-    (In contrast, setting the \l opacity to 0 does not affect the \l focus
-    property and the receiving of key events.)
+    If this property is set to \c false, the item will no longer receive mouse
+    events, but will continue to receive key events and will retain the keyboard
+    \l focus if it has been set. (In contrast, setting the \l enabled property
+    to \c false stops both mouse and keyboard events, and also removes focus
+    from the item.)
 
     \note This property's value is only affected by changes to this property or
     the parent's \c visible property. It does not change, for example, if this
     item moves off-screen, or if the \l opacity changes to 0.
 */
 
 
     \note This property's value is only affected by changes to this property or
     the parent's \c visible property. It does not change, for example, if this
     item moves off-screen, or if the \l opacity changes to 0.
 */
 
+/*!
+    \qmlproperty bool QtQuick2::Item::enabled
+
+    This property holds whether the item receives mouse and keyboard events.
+    By default this is true.
+
+    Setting this property directly affects the \c enabled value of child
+    items. When set to \c false, the \c enabled values of all child items also
+    become \c false. When set to \c true, the \c enabled values of child items
+    are returned to \c true, unless they have explicitly been set to \c false.
+
+    Setting this property to \c false automatically causes \l activeFocus to be
+    set to \c false, and this item will longer receive keyboard events.
+*/
 
 /*!
   \qmlproperty AnchorLine QtQuick2::Item::anchors.top
 
 /*!
   \qmlproperty AnchorLine QtQuick2::Item::anchors.top
@@ -4063,11 +4078,10 @@ void QQuickItem::setZ(qreal v)
   \endqml
   \endtable
 
   \endqml
   \endtable
 
-  If an item's opacity is set to 0, the item will no longer receive mouse
-  events, but will continue to receive key events and will retain the keyboard
-  \l focus if it has been set. (In contrast, setting the \l visible property
-  to \c false stops both mouse and keyboard events, and also removes focus
-  from the item.)
+  Changing an items opacity will not affect delivery of input events.  (In contrast
+  setting \l visible property to \c false stops mouse events, and setting the
+  \l enabled property to \c false stops mouse and keyboard events, and also removes
+  active focus from the item.)
 */
 
 /*!
 */
 
 /*!
index 17458ab..6897e3d 100644 (file)
@@ -271,8 +271,6 @@ bool QQuickMouseAreaPrivate::propagateHelper(QQuickMouseEvent *ev, QQuickItem *i
     //But specific to MouseArea, so doesn't belong in canvas
     Q_Q(const QQuickMouseArea);
     QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item);
     //But specific to MouseArea, so doesn't belong in canvas
     Q_Q(const QQuickMouseArea);
     QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item);
-    if (itemPrivate->opacity() == 0.0)
-        return false;
 
     if (itemPrivate->flags & QQuickItem::ItemClipsChildrenToShape) {
         QPointF p = item->mapFromScene(sp);
 
     if (itemPrivate->flags & QQuickItem::ItemClipsChildrenToShape) {
         QPointF p = item->mapFromScene(sp);
index 83c5b62..badec53 100644 (file)
@@ -157,7 +157,7 @@ public:
     void reset() {
         acceptTouchEvents = acceptMouseEvents = true;
         setEnabled(true);
     void reset() {
         acceptTouchEvents = acceptMouseEvents = true;
         setEnabled(true);
-        setOpacity(1.0);
+        setVisible(true);
 
         lastEvent = makeTouchData(QEvent::None, canvas(), 0, QList<QTouchEvent::TouchPoint>());//CHECK_VALID
 
 
         lastEvent = makeTouchData(QEvent::None, canvas(), 0, QList<QTouchEvent::TouchPoint>());//CHECK_VALID
 
@@ -456,7 +456,7 @@ void tst_qquickcanvas::touchEvent_propagation()
     QFETCH(bool, acceptTouchEvents);
     QFETCH(bool, acceptMouseEvents);
     QFETCH(bool, enableItem);
     QFETCH(bool, acceptTouchEvents);
     QFETCH(bool, acceptMouseEvents);
     QFETCH(bool, enableItem);
-    QFETCH(qreal, itemOpacity);
+    QFETCH(bool, showItem);
 
     QQuickCanvas *canvas = new QQuickCanvas;
     canvas->resize(250, 250);
 
     QQuickCanvas *canvas = new QQuickCanvas;
     canvas->resize(250, 250);
@@ -487,7 +487,7 @@ void tst_qquickcanvas::touchEvent_propagation()
     topItem->acceptTouchEvents = acceptTouchEvents;
     topItem->acceptMouseEvents = acceptMouseEvents;
     topItem->setEnabled(enableItem);
     topItem->acceptTouchEvents = acceptTouchEvents;
     topItem->acceptMouseEvents = acceptMouseEvents;
     topItem->setEnabled(enableItem);
-    topItem->setOpacity(itemOpacity);
+    topItem->setVisible(showItem);
 
     // single touch to top item, should be received by middle item
     QTest::touchEvent(canvas, touchDevice).press(0, pointInTopItem, canvas);
 
     // single touch to top item, should be received by middle item
     QTest::touchEvent(canvas, touchDevice).press(0, pointInTopItem, canvas);
@@ -514,7 +514,7 @@ void tst_qquickcanvas::touchEvent_propagation()
     middleItem->acceptTouchEvents = acceptTouchEvents;
     middleItem->acceptMouseEvents = acceptMouseEvents;
     middleItem->setEnabled(enableItem);
     middleItem->acceptTouchEvents = acceptTouchEvents;
     middleItem->acceptMouseEvents = acceptMouseEvents;
     middleItem->setEnabled(enableItem);
-    middleItem->setOpacity(itemOpacity);
+    middleItem->setVisible(showItem);
 
     // touch top and middle items, bottom item should get all events
     QTest::touchEvent(canvas, touchDevice).press(0, pointInTopItem, canvas)
 
     // touch top and middle items, bottom item should get all events
     QTest::touchEvent(canvas, touchDevice).press(0, pointInTopItem, canvas)
@@ -531,7 +531,7 @@ void tst_qquickcanvas::touchEvent_propagation()
     // disable bottom item as well
     bottomItem->acceptTouchEvents = acceptTouchEvents;
     bottomItem->setEnabled(enableItem);
     // disable bottom item as well
     bottomItem->acceptTouchEvents = acceptTouchEvents;
     bottomItem->setEnabled(enableItem);
-    bottomItem->setOpacity(itemOpacity);
+    bottomItem->setVisible(showItem);
 
     // no events should be received
     QTest::touchEvent(canvas, touchDevice).press(0, pointInTopItem, canvas)
 
     // no events should be received
     QTest::touchEvent(canvas, touchDevice).press(0, pointInTopItem, canvas)
@@ -549,10 +549,10 @@ void tst_qquickcanvas::touchEvent_propagation()
     // disable middle item, touch on top item
     middleItem->acceptTouchEvents = acceptTouchEvents;
     middleItem->setEnabled(enableItem);
     // disable middle item, touch on top item
     middleItem->acceptTouchEvents = acceptTouchEvents;
     middleItem->setEnabled(enableItem);
-    middleItem->setOpacity(itemOpacity);
+    middleItem->setVisible(showItem);
     QTest::touchEvent(canvas, touchDevice).press(0, pointInTopItem, canvas);
     QTest::qWait(50);
     QTest::touchEvent(canvas, touchDevice).press(0, pointInTopItem, canvas);
     QTest::qWait(50);
-    if (!enableItem || itemOpacity == 0) {
+    if (!enableItem || !showItem) {
         // middle item is disabled or has 0 opacity, bottom item receives the event
         QVERIFY(topItem->lastEvent.touchPoints.isEmpty());
         QVERIFY(middleItem->lastEvent.touchPoints.isEmpty());
         // middle item is disabled or has 0 opacity, bottom item receives the event
         QVERIFY(topItem->lastEvent.touchPoints.isEmpty());
         QVERIFY(middleItem->lastEvent.touchPoints.isEmpty());
@@ -579,11 +579,11 @@ void tst_qquickcanvas::touchEvent_propagation_data()
     QTest::addColumn<bool>("acceptTouchEvents");
     QTest::addColumn<bool>("acceptMouseEvents");
     QTest::addColumn<bool>("enableItem");
     QTest::addColumn<bool>("acceptTouchEvents");
     QTest::addColumn<bool>("acceptMouseEvents");
     QTest::addColumn<bool>("enableItem");
-    QTest::addColumn<qreal>("itemOpacity");
+    QTest::addColumn<bool>("showItem");
 
 
-    QTest::newRow("disable events") << false << false << true << 1.0;
-    QTest::newRow("disable item") << true << true << false << 1.0;
-    QTest::newRow("opacity of 0") << true << true << true << 0.0;
+    QTest::newRow("disable events") << false << false << true << true;
+    QTest::newRow("disable item") << true << true << false << true;
+    QTest::newRow("hide item") << true << true << true << false;
 }
 
 void tst_qquickcanvas::touchEvent_cancel()
 }
 
 void tst_qquickcanvas::touchEvent_cancel()
index 0ebfa81..12c1a03 100644 (file)
@@ -345,9 +345,9 @@ void tst_QQuickDrag::active()
     evaluate<void>(item, "Drag.active = true");
     QCOMPARE(evaluate<bool>(item, "Drag.active"), true);
     QCOMPARE(evaluate<bool>(item, "dragActive"), true);
     evaluate<void>(item, "Drag.active = true");
     QCOMPARE(evaluate<bool>(item, "Drag.active"), true);
     QCOMPARE(evaluate<bool>(item, "dragActive"), true);
-    QCOMPARE(evaluate<QObject *>(item, "Drag.target"), static_cast<QObject *>(0));
-    QCOMPARE(evaluate<QObject *>(item, "dragTarget"), static_cast<QObject *>(0));
-    QCOMPARE(dropTarget.enterEvents, 0); QCOMPARE(dropTarget.leaveEvents, 0);
+    QCOMPARE(evaluate<QObject *>(item, "Drag.target"), static_cast<QObject *>(&dropTarget));
+    QCOMPARE(evaluate<QObject *>(item, "dragTarget"), static_cast<QObject *>(&dropTarget));
+    QCOMPARE(dropTarget.enterEvents, 1); QCOMPARE(dropTarget.leaveEvents, 0);
 
     evaluate<void>(item, "Drag.active = false");
     dropTarget.setOpacity(1.0);
 
     evaluate<void>(item, "Drag.active = false");
     dropTarget.setOpacity(1.0);