diff options
-rw-r--r-- | examples/quickcontrols2/gallery/gallery.qml | 4 | ||||
-rw-r--r-- | src/imports/controls/material/Drawer.qml | 2 | ||||
-rw-r--r-- | src/imports/templates/qtquicktemplates2plugin.cpp | 1 | ||||
-rw-r--r-- | src/quicktemplates2/qquickdrawer.cpp | 34 | ||||
-rw-r--r-- | src/quicktemplates2/qquickdrawer_p.h | 5 | ||||
-rw-r--r-- | src/quicktemplates2/qquickpopup.cpp | 4 | ||||
-rw-r--r-- | src/quicktemplates2/qquickpopup_p_p.h | 1 | ||||
-rw-r--r-- | src/quicktemplates2/qquickpopupitem.cpp | 7 | ||||
-rw-r--r-- | tests/auto/drawer/tst_drawer.cpp | 57 |
9 files changed, 108 insertions, 7 deletions
diff --git a/examples/quickcontrols2/gallery/gallery.qml b/examples/quickcontrols2/gallery/gallery.qml index 06e7fc06..a8cc2629 100644 --- a/examples/quickcontrols2/gallery/gallery.qml +++ b/examples/quickcontrols2/gallery/gallery.qml @@ -40,7 +40,7 @@ import QtQuick 2.6 import QtQuick.Layouts 1.3 -import QtQuick.Controls 2.1 +import QtQuick.Controls 2.2 import QtQuick.Controls.Material 2.1 import QtQuick.Controls.Universal 2.1 import Qt.labs.settings 1.0 @@ -131,7 +131,7 @@ ApplicationWindow { id: drawer width: Math.min(window.width, window.height) / 3 * 2 height: window.height - dragMargin: stackView.depth > 1 ? 0 : undefined + interactive: stackView.depth === 1 ListView { id: listView diff --git a/src/imports/controls/material/Drawer.qml b/src/imports/controls/material/Drawer.qml index 55cabc9a..b5ceefce 100644 --- a/src/imports/controls/material/Drawer.qml +++ b/src/imports/controls/material/Drawer.qml @@ -58,7 +58,7 @@ T.Drawer { enter: Transition { SmoothedAnimation { velocity: 5 } } exit: Transition { SmoothedAnimation { velocity: 5 } } - Material.elevation: 16 + Material.elevation: !interactive && !dim ? 0 : 16 background: Rectangle { color: control.Material.dialogColor diff --git a/src/imports/templates/qtquicktemplates2plugin.cpp b/src/imports/templates/qtquicktemplates2plugin.cpp index 76cce2d3..ef6787f4 100644 --- a/src/imports/templates/qtquicktemplates2plugin.cpp +++ b/src/imports/templates/qtquicktemplates2plugin.cpp @@ -225,6 +225,7 @@ void QtQuickTemplates2Plugin::registerTypes(const char *uri) // QtQuick.Templates 2.2 (new types and revisions in Qt 5.9) qmlRegisterType<QQuickComboBox, 2>(uri, 2, 2, "ComboBox"); qmlRegisterType<QQuickDial, 2>(uri, 2, 2, "Dial"); + qmlRegisterType<QQuickDrawer, 2>(uri, 2, 2, "Drawer"); qmlRegisterType<QQuickRangeSlider, 2>(uri, 2, 2, "RangeSlider"); qmlRegisterType<QQuickSlider, 2>(uri, 2, 2, "Slider"); qmlRegisterType<QQuickSwipeDelegate, 2>(uri, 2, 2, "SwipeDelegate"); diff --git a/src/quicktemplates2/qquickdrawer.cpp b/src/quicktemplates2/qquickdrawer.cpp index 59caa230..a465a13e 100644 --- a/src/quicktemplates2/qquickdrawer.cpp +++ b/src/quicktemplates2/qquickdrawer.cpp @@ -239,7 +239,7 @@ static bool dragOverThreshold(qreal d, Qt::Axis axis, QMouseEvent *event, int th bool QQuickDrawerPrivate::startDrag(QQuickWindow *window, QMouseEvent *event) { - if (!window || dragMargin < 0.0 || qFuzzyIsNull(dragMargin)) + if (!window || !interactive || dragMargin < 0.0 || qFuzzyIsNull(dragMargin)) return false; bool drag = false; @@ -272,7 +272,7 @@ bool QQuickDrawerPrivate::startDrag(QQuickWindow *window, QMouseEvent *event) bool QQuickDrawerPrivate::grabMouse(QMouseEvent *event) { Q_Q(QQuickDrawer); - if (!window || popupItem->keepMouseGrab()) + if (!window || !interactive || popupItem->keepMouseGrab()) return false; const QPointF movePoint = event->windowPos(); @@ -542,6 +542,8 @@ void QQuickDrawer::setPosition(qreal position) prevents opening the drawer by dragging. The default value is \c Qt.styleHints.startDragDistance. + + \sa interactive */ qreal QQuickDrawer::dragMargin() const { @@ -564,6 +566,34 @@ void QQuickDrawer::resetDragMargin() setDragMargin(QGuiApplication::styleHints()->startDragDistance()); } +/*! + \since QtQuick.Controls 2.2 + \qmlproperty bool QtQuick.Controls::Drawer::interactive + + This property holds whether the drawer is interactive. A non-interactive + drawer does not react to swipes. + + The default value is \c true. + + \sa dragMargin +*/ +bool QQuickDrawer::isInteractive() const +{ + Q_D(const QQuickDrawer); + return d->interactive; +} + +void QQuickDrawer::setInteractive(bool interactive) +{ + Q_D(QQuickDrawer); + if (d->interactive == interactive) + return; + + setFiltersChildMouseEvents(interactive); + d->interactive = interactive; + emit interactiveChanged(); +} + bool QQuickDrawer::childMouseEventFilter(QQuickItem *child, QEvent *event) { Q_D(QQuickDrawer); diff --git a/src/quicktemplates2/qquickdrawer_p.h b/src/quicktemplates2/qquickdrawer_p.h index bada1344..6a7d8b6d 100644 --- a/src/quicktemplates2/qquickdrawer_p.h +++ b/src/quicktemplates2/qquickdrawer_p.h @@ -60,6 +60,7 @@ class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickDrawer : public QQuickPopup Q_PROPERTY(Qt::Edge edge READ edge WRITE setEdge NOTIFY edgeChanged FINAL) Q_PROPERTY(qreal position READ position WRITE setPosition NOTIFY positionChanged FINAL) Q_PROPERTY(qreal dragMargin READ dragMargin WRITE setDragMargin RESET resetDragMargin NOTIFY dragMarginChanged FINAL) + Q_PROPERTY(bool interactive READ isInteractive WRITE setInteractive NOTIFY interactiveChanged FINAL REVISION 2) public: explicit QQuickDrawer(QObject *parent = nullptr); @@ -74,10 +75,14 @@ public: void setDragMargin(qreal margin); void resetDragMargin(); + bool isInteractive() const; + void setInteractive(bool interactive); + Q_SIGNALS: void edgeChanged(); void positionChanged(); void dragMarginChanged(); + Q_REVISION(2) void interactiveChanged(); protected: bool childMouseEventFilter(QQuickItem *child, QEvent *event) override; diff --git a/src/quicktemplates2/qquickpopup.cpp b/src/quicktemplates2/qquickpopup.cpp index 7ff99c49..95d1a7e2 100644 --- a/src/quicktemplates2/qquickpopup.cpp +++ b/src/quicktemplates2/qquickpopup.cpp @@ -209,6 +209,7 @@ QQuickPopupPrivate::QQuickPopupPrivate() , allowVerticalResize(true) , allowHorizontalResize(true) , hadActiveFocusBeforeExitTransition(false) + , interactive(true) , x(0) , y(0) , effectiveX(0) @@ -257,6 +258,9 @@ void QQuickPopupPrivate::closeOrReject() bool QQuickPopupPrivate::tryClose(QQuickItem *item, QMouseEvent *event) { + if (!interactive) + return false; + const bool isPress = event->type() == QEvent::MouseButtonPress; const bool onOutside = closePolicy.testFlag(isPress ? QQuickPopup::CloseOnPressOutside : QQuickPopup::CloseOnReleaseOutside); const bool onOutsideParent = closePolicy.testFlag(isPress ? QQuickPopup::CloseOnPressOutsideParent : QQuickPopup::CloseOnReleaseOutsideParent); diff --git a/src/quicktemplates2/qquickpopup_p_p.h b/src/quicktemplates2/qquickpopup_p_p.h index 2cf92864..4aa62d23 100644 --- a/src/quicktemplates2/qquickpopup_p_p.h +++ b/src/quicktemplates2/qquickpopup_p_p.h @@ -138,6 +138,7 @@ public: bool allowVerticalResize; bool allowHorizontalResize; bool hadActiveFocusBeforeExitTransition; + bool interactive; qreal x; qreal y; qreal effectiveX; diff --git a/src/quicktemplates2/qquickpopupitem.cpp b/src/quicktemplates2/qquickpopupitem.cpp index de8a9de2..8a84cc20 100644 --- a/src/quicktemplates2/qquickpopupitem.cpp +++ b/src/quicktemplates2/qquickpopupitem.cpp @@ -152,8 +152,11 @@ bool QQuickPopupItem::event(QEvent *event) if (event->type() == QEvent::Shortcut) { QShortcutEvent *se = static_cast<QShortcutEvent *>(event); if (se->shortcutId() == d->escapeId || se->shortcutId() == d->backId) { - QQuickPopupPrivate::get(d->popup)->closeOrReject(); - return true; + QQuickPopupPrivate *p = QQuickPopupPrivate::get(d->popup); + if (p->interactive) { + p->closeOrReject(); + return true; + } } } return QQuickItem::event(event); diff --git a/tests/auto/drawer/tst_drawer.cpp b/tests/auto/drawer/tst_drawer.cpp index 4743a8cd..7098ddc4 100644 --- a/tests/auto/drawer/tst_drawer.cpp +++ b/tests/auto/drawer/tst_drawer.cpp @@ -84,6 +84,9 @@ private slots: void touch(); void grabber(); + + void interactive_data(); + void interactive(); }; void tst_Drawer::visible_data() @@ -799,6 +802,60 @@ void tst_Drawer::grabber() QTRY_COMPARE(popupClosedSpy.count(), 1); } +void tst_Drawer::interactive_data() +{ + QTest::addColumn<QString>("source"); + QTest::newRow("Window") << "window.qml"; + QTest::newRow("ApplicationWindow") << "applicationwindow.qml"; +} + +void tst_Drawer::interactive() +{ + QFETCH(QString, source); + QQuickApplicationHelper helper(this, source); + + QQuickWindow *window = helper.window; + window->show(); + QVERIFY(QTest::qWaitForWindowActive(window)); + + QQuickDrawer *drawer = window->property("drawer").value<QQuickDrawer*>(); + QVERIFY(drawer); + + drawer->setInteractive(false); + + QSignalSpy openedSpy(drawer, SIGNAL(opened())); + QSignalSpy aboutToHideSpy(drawer, SIGNAL(aboutToHide())); + QVERIFY(openedSpy.isValid()); + QVERIFY(aboutToHideSpy.isValid()); + + drawer->open(); + QVERIFY(openedSpy.wait()); + + // click outside + QTest::mouseClick(window, Qt::LeftButton, Qt::NoModifier, QPoint(300, 100)); + QCOMPARE(aboutToHideSpy.count(), 0); + + // drag inside + QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, QPoint(drawer->width(), 0)); + QTest::mouseMove(window, QPoint(0, 0)); + QCOMPARE(drawer->position(), 1.0); + QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, QPoint(0, 0)); + QCOMPARE(drawer->position(), 1.0); + QCOMPARE(aboutToHideSpy.count(), 0); + + // drag outside + QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, QPoint(window->width() - 1, 0)); + QTest::mouseMove(window, QPoint(0, 0)); + QCOMPARE(drawer->position(), 1.0); + QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, QPoint(0, 0)); + QCOMPARE(drawer->position(), 1.0); + QCOMPARE(aboutToHideSpy.count(), 0); + + // close on escape + QTest::keyClick(window, Qt::Key_Escape); + QCOMPARE(aboutToHideSpy.count(), 0); +} + QTEST_MAIN(tst_Drawer) #include "tst_drawer.moc" |