diff options
-rw-r--r-- | src/quicktemplates2/qquickdrawer.cpp | 2 | ||||
-rw-r--r-- | src/quicktemplates2/qquickoverlay.cpp | 16 | ||||
-rw-r--r-- | src/quicktemplates2/qquickoverlay_p.h | 1 | ||||
-rw-r--r-- | tests/auto/drawer/data/applicationwindow-wheel.qml | 70 | ||||
-rw-r--r-- | tests/auto/drawer/data/window-wheel.qml | 71 | ||||
-rw-r--r-- | tests/auto/drawer/tst_drawer.cpp | 88 | ||||
-rw-r--r-- | tests/auto/popup/data/applicationwindow-wheel.qml | 71 | ||||
-rw-r--r-- | tests/auto/popup/data/window-wheel.qml | 71 | ||||
-rw-r--r-- | tests/auto/popup/tst_popup.cpp | 87 |
9 files changed, 476 insertions, 1 deletions
diff --git a/src/quicktemplates2/qquickdrawer.cpp b/src/quicktemplates2/qquickdrawer.cpp index 15b53914..be4d624d 100644 --- a/src/quicktemplates2/qquickdrawer.cpp +++ b/src/quicktemplates2/qquickdrawer.cpp @@ -527,7 +527,7 @@ bool QQuickDrawer::overlayEvent(QQuickItem *item, QEvent *event) d->tryClose(item, static_cast<QMouseEvent *>(event)); return d->handleMouseReleaseEvent(item, static_cast<QMouseEvent *>(event)); default: - return false; + return QQuickPopup::overlayEvent(item, event); } } diff --git a/src/quicktemplates2/qquickoverlay.cpp b/src/quicktemplates2/qquickoverlay.cpp index 19677cb7..c6e34ee2 100644 --- a/src/quicktemplates2/qquickoverlay.cpp +++ b/src/quicktemplates2/qquickoverlay.cpp @@ -379,6 +379,22 @@ void QQuickOverlay::mouseReleaseEvent(QMouseEvent *event) } } +void QQuickOverlay::wheelEvent(QWheelEvent *event) +{ + Q_D(QQuickOverlay); + if (d->mouseGrabberPopup) { + d->mouseGrabberPopup->overlayEvent(this, event); + return; + } else { + const auto popups = d->stackingOrderPopups(); + for (QQuickPopup *popup : popups) { + if (popup->overlayEvent(this, event)) + return; + } + } + event->ignore(); +} + bool QQuickOverlay::childMouseEventFilter(QQuickItem *item, QEvent *event) { Q_D(QQuickOverlay); diff --git a/src/quicktemplates2/qquickoverlay_p.h b/src/quicktemplates2/qquickoverlay_p.h index 07f7daec..af16900f 100644 --- a/src/quicktemplates2/qquickoverlay_p.h +++ b/src/quicktemplates2/qquickoverlay_p.h @@ -87,6 +87,7 @@ protected: void mousePressEvent(QMouseEvent *event) override; void mouseMoveEvent(QMouseEvent *event) override; void mouseReleaseEvent(QMouseEvent *event) override; + void wheelEvent(QWheelEvent *event) override; bool childMouseEventFilter(QQuickItem *item, QEvent *event) override; private: diff --git a/tests/auto/drawer/data/applicationwindow-wheel.qml b/tests/auto/drawer/data/applicationwindow-wheel.qml new file mode 100644 index 00000000..9c8b4a83 --- /dev/null +++ b/tests/auto/drawer/data/applicationwindow-wheel.qml @@ -0,0 +1,70 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.6 +import QtQuick.Controls 2.0 + +ApplicationWindow { + id: window + width: 400 + height: 400 + + property alias drawer: drawer + property alias drawerSlider: drawerSlider + property alias contentSlider: contentSlider + + Slider { + id: contentSlider + anchors.fill: parent + wheelEnabled: true + } + + Drawer { + id: drawer + edge: Qt.RightEdge + width: window.width * 0.8 + height: window.height + clip: true + contentItem: Slider { + id: drawerSlider + wheelEnabled: true + } + } +} diff --git a/tests/auto/drawer/data/window-wheel.qml b/tests/auto/drawer/data/window-wheel.qml new file mode 100644 index 00000000..18ca2ace --- /dev/null +++ b/tests/auto/drawer/data/window-wheel.qml @@ -0,0 +1,71 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.6 +import QtQuick.Window 2.2 +import QtQuick.Controls 2.0 + +Window { + id: window + width: 400 + height: 400 + + property alias drawer: drawer + property alias drawerSlider: drawerSlider + property alias contentSlider: contentSlider + + Slider { + id: contentSlider + anchors.fill: parent + wheelEnabled: true + } + + Drawer { + id: drawer + edge: Qt.RightEdge + width: window.width * 0.8 + height: window.height + clip: true + contentItem: Slider { + id: drawerSlider + wheelEnabled: true + } + } +} diff --git a/tests/auto/drawer/tst_drawer.cpp b/tests/auto/drawer/tst_drawer.cpp index 8f023c29..8b02e95c 100644 --- a/tests/auto/drawer/tst_drawer.cpp +++ b/tests/auto/drawer/tst_drawer.cpp @@ -45,6 +45,7 @@ #include <QtQuickTemplates2/private/qquickoverlay_p.h> #include <QtQuickTemplates2/private/qquickdrawer_p.h> #include <QtQuickTemplates2/private/qquickbutton_p.h> +#include <QtQuickTemplates2/private/qquickslider_p.h> using namespace QQuickVisualTestUtil; @@ -69,6 +70,9 @@ private slots: void hover_data(); void hover(); + void wheel_data(); + void wheel(); + void multiple(); }; @@ -406,6 +410,90 @@ void tst_Drawer::hover() QVERIFY(backgroundButton->isHovered()); } +void tst_Drawer::wheel_data() +{ + QTest::addColumn<QString>("source"); + QTest::addColumn<bool>("modal"); + + QTest::newRow("Window:modal") << "window-wheel.qml" << true; + QTest::newRow("Window:modeless") << "window-wheel.qml" << false; + QTest::newRow("ApplicationWindow:modal") << "applicationwindow-wheel.qml" << true; + QTest::newRow("ApplicationWindow:modeless") << "applicationwindow-wheel.qml" << false; +} + +static bool sendWheelEvent(QQuickItem *item, const QPoint &localPos, int degrees) +{ + QQuickWindow *window = item->window(); + QWheelEvent wheelEvent(localPos, item->window()->mapToGlobal(localPos), QPoint(0, 0), QPoint(0, 8 * degrees), 0, Qt::Vertical, Qt::NoButton, 0); + QSpontaneKeyEvent::setSpontaneous(&wheelEvent); + return qGuiApp->notify(window, &wheelEvent); +} + +void tst_Drawer::wheel() +{ + QFETCH(QString, source); + QFETCH(bool, modal); + + QQuickApplicationHelper helper(this, source); + QQuickWindow *window = helper.window; + window->show(); + QVERIFY(QTest::qWaitForWindowExposed(window)); + + QQuickSlider *contentSlider = window->property("contentSlider").value<QQuickSlider*>(); + QVERIFY(contentSlider); + + QQuickDrawer *drawer = window->property("drawer").value<QQuickDrawer*>(); + QVERIFY(drawer && drawer->contentItem()); + drawer->setModal(modal); + + QQuickSlider *drawerSlider = window->property("drawerSlider").value<QQuickSlider*>(); + QVERIFY(drawerSlider); + + { + // wheel over the content + qreal oldContentValue = contentSlider->value(); + qreal oldDrawerValue = drawerSlider->value(); + + QVERIFY(sendWheelEvent(contentSlider, QPoint(contentSlider->width() / 2, contentSlider->height() / 2), 15)); + + QVERIFY(!qFuzzyCompare(contentSlider->value(), oldContentValue)); // must have moved + QVERIFY(qFuzzyCompare(drawerSlider->value(), oldDrawerValue)); // must not have moved + } + + QSignalSpy openedSpy(drawer, SIGNAL(opened())); + QVERIFY(openedSpy.isValid()); + drawer->open(); + QVERIFY(openedSpy.count() == 1 || openedSpy.wait()); + + { + // wheel over the drawer content + qreal oldContentValue = contentSlider->value(); + qreal oldDrawerValue = drawerSlider->value(); + + QVERIFY(sendWheelEvent(drawerSlider, QPoint(drawerSlider->width() / 2, drawerSlider->height() / 2), 15)); + + QVERIFY(qFuzzyCompare(contentSlider->value(), oldContentValue)); // must not have moved + QVERIFY(!qFuzzyCompare(drawerSlider->value(), oldDrawerValue)); // must have moved + } + + { + // wheel over the overlay + qreal oldContentValue = contentSlider->value(); + qreal oldDrawerValue = drawerSlider->value(); + + QVERIFY(sendWheelEvent(QQuickOverlay::overlay(window), QPoint(0, 0), 15)); + + if (modal) { + // the content below a modal overlay must not move + QVERIFY(qFuzzyCompare(contentSlider->value(), oldContentValue)); + } else { + // the content below a modeless overlay must move + QVERIFY(!qFuzzyCompare(contentSlider->value(), oldContentValue)); + } + QVERIFY(qFuzzyCompare(drawerSlider->value(), oldDrawerValue)); // must not have moved + } +} + void tst_Drawer::multiple() { QQuickApplicationHelper helper(this, QStringLiteral("multiple.qml")); diff --git a/tests/auto/popup/data/applicationwindow-wheel.qml b/tests/auto/popup/data/applicationwindow-wheel.qml new file mode 100644 index 00000000..a655713e --- /dev/null +++ b/tests/auto/popup/data/applicationwindow-wheel.qml @@ -0,0 +1,71 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.6 +import QtQuick.Window 2.2 +import QtQuick.Controls 2.0 + +ApplicationWindow { + id: window + width: 400 + height: 400 + + property alias popup: popup + property alias popupSlider: popupSlider + property alias contentSlider: contentSlider + + Slider { + id: contentSlider + anchors.fill: parent + wheelEnabled: true + } + + Popup { + id: popup + x: 50; y: 50 + implicitWidth: parent.width - 100 + implicitHeight: parent.height - 100 + clip: true + contentItem: Slider { + id: popupSlider + wheelEnabled: true + } + } +} diff --git a/tests/auto/popup/data/window-wheel.qml b/tests/auto/popup/data/window-wheel.qml new file mode 100644 index 00000000..2ffe4bf6 --- /dev/null +++ b/tests/auto/popup/data/window-wheel.qml @@ -0,0 +1,71 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.6 +import QtQuick.Window 2.2 +import QtQuick.Controls 2.0 + +Window { + id: window + width: 400 + height: 400 + + property alias popup: popup + property alias popupSlider: popupSlider + property alias contentSlider: contentSlider + + Slider { + id: contentSlider + anchors.fill: parent + wheelEnabled: true + } + + Popup { + id: popup + x: 50; y: 50 + implicitWidth: parent.width - 100 + implicitHeight: parent.height - 100 + clip: true + contentItem: Slider { + id: popupSlider + wheelEnabled: true + } + } +} diff --git a/tests/auto/popup/tst_popup.cpp b/tests/auto/popup/tst_popup.cpp index a6848fc8..298328de 100644 --- a/tests/auto/popup/tst_popup.cpp +++ b/tests/auto/popup/tst_popup.cpp @@ -43,6 +43,7 @@ #include <QtQuickTemplates2/private/qquickoverlay_p.h> #include <QtQuickTemplates2/private/qquickpopup_p.h> #include <QtQuickTemplates2/private/qquickbutton_p.h> +#include <QtQuickTemplates2/private/qquickslider_p.h> using namespace QQuickVisualTestUtil; @@ -65,6 +66,8 @@ private slots: void activeFocusOnClose2(); void hover_data(); void hover(); + void wheel_data(); + void wheel(); void parentDestroyed(); }; @@ -514,6 +517,90 @@ void tst_popup::hover() QVERIFY(parentButton->isHovered()); } +void tst_popup::wheel_data() +{ + QTest::addColumn<QString>("source"); + QTest::addColumn<bool>("modal"); + + QTest::newRow("Window:modal") << "window-wheel.qml" << true; + QTest::newRow("Window:modeless") << "window-wheel.qml" << false; + QTest::newRow("ApplicationWindow:modal") << "applicationwindow-wheel.qml" << true; + QTest::newRow("ApplicationWindow:modeless") << "applicationwindow-wheel.qml" << false; +} + +static bool sendWheelEvent(QQuickItem *item, const QPoint &localPos, int degrees) +{ + QQuickWindow *window = item->window(); + QWheelEvent wheelEvent(localPos, item->window()->mapToGlobal(localPos), QPoint(0, 0), QPoint(0, 8 * degrees), 0, Qt::Vertical, Qt::NoButton, 0); + QSpontaneKeyEvent::setSpontaneous(&wheelEvent); + return qGuiApp->notify(window, &wheelEvent); +} + +void tst_popup::wheel() +{ + QFETCH(QString, source); + QFETCH(bool, modal); + + QQuickApplicationHelper helper(this, source); + QQuickWindow *window = helper.window; + window->show(); + QVERIFY(QTest::qWaitForWindowExposed(window)); + + QQuickSlider *contentSlider = window->property("contentSlider").value<QQuickSlider*>(); + QVERIFY(contentSlider); + + QQuickPopup *popup = window->property("popup").value<QQuickPopup*>(); + QVERIFY(popup && popup->contentItem()); + popup->setModal(modal); + + QQuickSlider *popupSlider = window->property("popupSlider").value<QQuickSlider*>(); + QVERIFY(popupSlider); + + { + // wheel over the content + qreal oldContentValue = contentSlider->value(); + qreal oldPopupValue = popupSlider->value(); + + QVERIFY(sendWheelEvent(contentSlider, QPoint(contentSlider->width() / 2, contentSlider->height() / 2), 15)); + + QVERIFY(!qFuzzyCompare(contentSlider->value(), oldContentValue)); // must have moved + QVERIFY(qFuzzyCompare(popupSlider->value(), oldPopupValue)); // must not have moved + } + + QSignalSpy openedSpy(popup, SIGNAL(opened())); + QVERIFY(openedSpy.isValid()); + popup->open(); + QVERIFY(openedSpy.count() == 1 || openedSpy.wait()); + + { + // wheel over the popup content + qreal oldContentValue = contentSlider->value(); + qreal oldPopupValue = popupSlider->value(); + + QVERIFY(sendWheelEvent(popupSlider, QPoint(popupSlider->width() / 2, popupSlider->height() / 2), 15)); + + QVERIFY(qFuzzyCompare(contentSlider->value(), oldContentValue)); // must not have moved + QVERIFY(!qFuzzyCompare(popupSlider->value(), oldPopupValue)); // must have moved + } + + { + // wheel over the overlay + qreal oldContentValue = contentSlider->value(); + qreal oldPopupValue = popupSlider->value(); + + QVERIFY(sendWheelEvent(QQuickOverlay::overlay(window), QPoint(0, 0), 15)); + + if (modal) { + // the content below a modal overlay must not move + QVERIFY(qFuzzyCompare(contentSlider->value(), oldContentValue)); + } else { + // the content below a modeless overlay must move + QVERIFY(!qFuzzyCompare(contentSlider->value(), oldContentValue)); + } + QVERIFY(qFuzzyCompare(popupSlider->value(), oldPopupValue)); // must not have moved + } +} + void tst_popup::parentDestroyed() { QQuickPopup popup; |