diff options
author | J-P Nurmi <jpnurmi@qt.io> | 2016-09-26 14:10:14 +0200 |
---|---|---|
committer | J-P Nurmi <jpnurmi@qt.io> | 2016-09-26 14:13:35 +0200 |
commit | 11b066beb45e7da084c6f792cf9421d48d4b40bf (patch) | |
tree | 0a27017508682b812b9fa533a3cab95aeb3c33c6 | |
parent | f1eef22d0d1ddcc2ee48e45e522788eb97f429b0 (diff) | |
parent | d1efdcd2beac4d40d06ac7258b4d84e4376ab9d6 (diff) |
Merge remote-tracking branch 'origin/5.7' into 5.8
Conflicts:
examples/quickcontrols2/gallery/gallery.qrc
src/imports/controls/doc/src/qtquickcontrols2-styles.qdoc
src/quicktemplates2/qquickstackview_p.cpp
src/quicktemplates2/qquickstackview_p_p.h
tests/auto/controls/data/tst_stackview.qml
Change-Id: If451fe0e5653572d305b4de90a6d5cb878463e8d
25 files changed, 439 insertions, 43 deletions
diff --git a/examples/quickcontrols2/gallery/gallery.pro b/examples/quickcontrols2/gallery/gallery.pro index fbfc3df8..45496a35 100644 --- a/examples/quickcontrols2/gallery/gallery.pro +++ b/examples/quickcontrols2/gallery/gallery.pro @@ -9,6 +9,7 @@ RESOURCES += \ gallery.qml \ qtquickcontrols2.conf \ $$files(images/*.png) \ + $$files(images/+material/*.png) \ $$files(pages/*.qml) target.path = $$[QT_INSTALL_EXAMPLES]/quickcontrols2/gallery diff --git a/examples/quickcontrols2/gallery/gallery.qml b/examples/quickcontrols2/gallery/gallery.qml index 753a8c00..bead5434 100644 --- a/examples/quickcontrols2/gallery/gallery.qml +++ b/examples/quickcontrols2/gallery/gallery.qml @@ -69,14 +69,21 @@ ApplicationWindow { fillMode: Image.Pad horizontalAlignment: Image.AlignHCenter verticalAlignment: Image.AlignVCenter - source: "qrc:/images/drawer.png" + source: stackView.depth > 1 ? "images/back.png" : "images/drawer.png" + } + onClicked: { + if (stackView.depth > 1) { + stackView.pop() + listView.currentIndex = -1 + } else { + drawer.open() + } } - onClicked: drawer.open() } Label { id: titleLabel - text: "Gallery" + text: listView.currentItem ? listView.currentItem.text : "Gallery" font.pixelSize: 20 elide: Label.ElideRight horizontalAlignment: Qt.AlignHCenter @@ -115,6 +122,7 @@ ApplicationWindow { id: drawer width: Math.min(window.width, window.height) / 3 * 2 height: window.height + dragMargin: stackView.depth > 1 ? 0 : undefined ListView { id: listView @@ -128,8 +136,7 @@ ApplicationWindow { onClicked: { if (listView.currentIndex != index) { listView.currentIndex = index - titleLabel.text = model.title - stackView.replace(model.source) + stackView.push(model.source) } drawer.close() } diff --git a/examples/quickcontrols2/gallery/images/+material/back.png b/examples/quickcontrols2/gallery/images/+material/back.png Binary files differnew file mode 100644 index 00000000..ebc1000f --- /dev/null +++ b/examples/quickcontrols2/gallery/images/+material/back.png diff --git a/examples/quickcontrols2/gallery/images/+material/back@2x.png b/examples/quickcontrols2/gallery/images/+material/back@2x.png Binary files differnew file mode 100644 index 00000000..cf6163c8 --- /dev/null +++ b/examples/quickcontrols2/gallery/images/+material/back@2x.png diff --git a/examples/quickcontrols2/gallery/images/+material/back@3x.png b/examples/quickcontrols2/gallery/images/+material/back@3x.png Binary files differnew file mode 100644 index 00000000..96376a5a --- /dev/null +++ b/examples/quickcontrols2/gallery/images/+material/back@3x.png diff --git a/examples/quickcontrols2/gallery/images/+material/back@4x.png b/examples/quickcontrols2/gallery/images/+material/back@4x.png Binary files differnew file mode 100644 index 00000000..578ac14f --- /dev/null +++ b/examples/quickcontrols2/gallery/images/+material/back@4x.png diff --git a/examples/quickcontrols2/gallery/images/back.png b/examples/quickcontrols2/gallery/images/back.png Binary files differnew file mode 100644 index 00000000..db43e273 --- /dev/null +++ b/examples/quickcontrols2/gallery/images/back.png diff --git a/examples/quickcontrols2/gallery/images/back@2x.png b/examples/quickcontrols2/gallery/images/back@2x.png Binary files differnew file mode 100644 index 00000000..c55ab315 --- /dev/null +++ b/examples/quickcontrols2/gallery/images/back@2x.png diff --git a/examples/quickcontrols2/gallery/images/back@3x.png b/examples/quickcontrols2/gallery/images/back@3x.png Binary files differnew file mode 100644 index 00000000..b228eb87 --- /dev/null +++ b/examples/quickcontrols2/gallery/images/back@3x.png diff --git a/examples/quickcontrols2/gallery/images/back@4x.png b/examples/quickcontrols2/gallery/images/back@4x.png Binary files differnew file mode 100644 index 00000000..dd157e78 --- /dev/null +++ b/examples/quickcontrols2/gallery/images/back@4x.png diff --git a/src/imports/controls/doc/snippets/qtquickcontrols2-pageindicator-interactive.qml b/src/imports/controls/doc/snippets/qtquickcontrols2-pageindicator-interactive.qml new file mode 100644 index 00000000..88cadc27 --- /dev/null +++ b/src/imports/controls/doc/snippets/qtquickcontrols2-pageindicator-interactive.qml @@ -0,0 +1,58 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: http://www.gnu.org/copyleft/fdl.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick.Controls 2.0 + +Pane { +//! [1] +SwipeView { + id: view + currentIndex: pageIndicator.currentIndex + anchors.fill: parent + + Page { + title: qsTr("Home") + } + Page { + title: qsTr("Discover") + } + Page { + title: qsTr("Activity") + } +} + +PageIndicator { + id: pageIndicator + interactive: true + count: view.count + currentIndex: view.currentIndex + + anchors.bottom: parent.bottom + anchors.horizontalCenter: parent.horizontalCenter +} +//! [1] +} diff --git a/src/imports/controls/doc/src/qtquickcontrols2-styles.qdoc b/src/imports/controls/doc/src/qtquickcontrols2-styles.qdoc index 1a1b7b3c..a1c4eeef 100644 --- a/src/imports/controls/doc/src/qtquickcontrols2-styles.qdoc +++ b/src/imports/controls/doc/src/qtquickcontrols2-styles.qdoc @@ -135,9 +135,10 @@ The configuration file can specify the preferred style (may be overridden by either of the methods described earlier) and certain style-specific attributes. The following example specifies that the preferred style is the Material style. Furthermore, when the - application is run with the Material style, its theme is light and the accent color is - brown. However, if the application is run with the Universal style instead, the accent - color is red and the appropriate theme is chosen based on the system theme colors. + application is run with the Material style, its theme is light and the accent and primary + colors are teal and blue grey, respectively. However, if the application is run with the + Universal style instead, the accent color is red and the appropriate theme is chosen based + on the system theme colors. \code [Controls] @@ -149,7 +150,8 @@ [Material] Theme=Light - Accent=Brown + Accent=Teal + Primary=BlueGrey \endcode In order to make it possible for Qt Quick Controls 2 to find the configuration file, diff --git a/src/quickcontrols2/qquickstyleattached.cpp b/src/quickcontrols2/qquickstyleattached.cpp index 6683b018..7c9935ea 100644 --- a/src/quickcontrols2/qquickstyleattached.cpp +++ b/src/quickcontrols2/qquickstyleattached.cpp @@ -167,6 +167,18 @@ static QList<QQuickStyleAttached *> findChildStyles(const QMetaObject *type, QOb return children; } +static QString resolveConfigFile() +{ + QString filePath = QFile::decodeName(qgetenv("QT_QUICK_CONTROLS_CONF")); + if (!QFile::exists(filePath)) { + if (!filePath.isEmpty()) + qWarning("QT_QUICK_CONTROLS_CONF=%s: No such file", qPrintable(filePath)); + + filePath = QStringLiteral(":/qtquickcontrols2.conf"); + } + return filePath; +} + QQuickStyleAttached::QQuickStyleAttached(QObject *parent) : QObject(parent) { QQuickItem *item = qobject_cast<QQuickItem *>(parent); @@ -196,7 +208,7 @@ QQuickStyleAttached::~QQuickStyleAttached() QSharedPointer<QSettings> QQuickStyleAttached::settings(const QString &group) { #ifndef QT_NO_SETTINGS - const QString filePath = QStringLiteral(":/qtquickcontrols2.conf"); + static const QString filePath = resolveConfigFile(); if (QFile::exists(filePath)) { QFileSelector selector; QSettings *settings = new QSettings(selector.select(filePath), QSettings::IniFormat); diff --git a/src/quicktemplates2/qquickdrawer.cpp b/src/quicktemplates2/qquickdrawer.cpp index bc1636de..433ea590 100644 --- a/src/quicktemplates2/qquickdrawer.cpp +++ b/src/quicktemplates2/qquickdrawer.cpp @@ -369,8 +369,11 @@ bool QQuickDrawerPrivate::handleMousePressEvent(QQuickItem *item, QMouseEvent *e pressPoint = event->windowPos(); velocityCalculator.startMeasuring(pressPoint, event->timestamp()); - // don't block press events a) outside a non-modal drawer, or b) to drawer children - event->setAccepted(modal && !popupItem->isAncestorOf(item)); + // don't block press events + // a) outside a non-modal drawer, + // b) to drawer children, or + // c) outside a modal drawer's background dimming + event->setAccepted(modal && !popupItem->isAncestorOf(item) && (!dimmer || dimmer->contains(dimmer->mapFromScene(pressPoint)))); return event->isAccepted(); } diff --git a/src/quicktemplates2/qquickoverlay.cpp b/src/quicktemplates2/qquickoverlay.cpp index 9bdc9135..18500ae6 100644 --- a/src/quicktemplates2/qquickoverlay.cpp +++ b/src/quicktemplates2/qquickoverlay.cpp @@ -388,9 +388,19 @@ void QQuickOverlay::wheelEvent(QWheelEvent *event) bool QQuickOverlay::childMouseEventFilter(QQuickItem *item, QEvent *event) { Q_D(QQuickOverlay); - for (QQuickPopup *popup : qAsConst(d->allPopups)) { - QQuickItem *dimmer = QQuickPopupPrivate::get(popup)->dimmer; - if (item == dimmer) { + const auto popups = d->stackingOrderPopups(); + for (QQuickPopup *popup : popups) { + QQuickPopupPrivate *p = QQuickPopupPrivate::get(popup); + + // Stop filtering overlay events when reaching a popup item or an item + // that is inside the popup. Let the popup content handle its events. + if (item == p->popupItem || p->popupItem->isAncestorOf(item)) + break; + + // Let the popup try closing itself when pressing or releasing over its + // background dimming OR over another popup underneath, in case the popup + // does not have background dimming. + if (item == p->dimmer || !p->popupItem->isAncestorOf(item)) { switch (event->type()) { case QEvent::MouseButtonPress: emit pressed(); @@ -403,6 +413,7 @@ bool QQuickOverlay::childMouseEventFilter(QQuickItem *item, QEvent *event) return popup->overlayEvent(item, event); case QEvent::MouseButtonRelease: emit released(); + d->mouseGrabberPopup = nullptr; return popup->overlayEvent(item, event); default: break; diff --git a/src/quicktemplates2/qquickpageindicator.cpp b/src/quicktemplates2/qquickpageindicator.cpp index 04c6a344..0c1ed616 100644 --- a/src/quicktemplates2/qquickpageindicator.cpp +++ b/src/quicktemplates2/qquickpageindicator.cpp @@ -58,7 +58,28 @@ QT_BEGIN_NAMESPACE \image qtquickcontrols2-pageindicator.png - \snippet qtquickcontrols2-pageindicator.qml 1 + \code + Column { + StackLayout { + id: stackLayout + + Page { + // ... + } + Page { + // ... + } + Page { + // ... + } + } + + PageIndicator { + currentIndex: stackLayout.currentIndex + count: stackLayout.count + } + } + \endcode \sa SwipeView, {Customizing PageIndicator}, {Indicator Controls} */ @@ -199,6 +220,14 @@ void QQuickPageIndicator::setCurrentIndex(int index) reacts to presses and automatically changes the \l {currentIndex}{current index} appropriately. + \snippet qtquickcontrols2-pageindicator-interactive.qml 1 + + \note Page indicators are typically quite small (in order to avoid + distracting the user from the actual content of the user interface). They + can be hard to click, and might not be easily recognized as interactive by + the user. For these reasons, they are best used to complement primary + methods of navigation (such as \l SwipeView), not replace them. + The default value is \c false. */ bool QQuickPageIndicator::isInteractive() const diff --git a/src/quicktemplates2/qquickpane.cpp b/src/quicktemplates2/qquickpane.cpp index f2141619..9f9c139b 100644 --- a/src/quicktemplates2/qquickpane.cpp +++ b/src/quicktemplates2/qquickpane.cpp @@ -54,8 +54,10 @@ QT_BEGIN_NAMESPACE \l ColumnLayout. Items declared as children of a Pane are automatically parented to the - Pane's contentItem. Items created dynamically need to be explicitly - parented to the contentItem. + Pane's \l {Control::}{contentItem}. Items created dynamically need to be + explicitly parented to the contentItem. + + \section1 Content Sizing If only a single item is used within a Pane, it will resize to fit the implicit size of its contained item. This makes it particularly suitable @@ -65,6 +67,40 @@ QT_BEGIN_NAMESPACE \snippet qtquickcontrols2-pane.qml 1 + Sometimes there might be two items within the pane: + + \code + Pane { + SwipeView { + // ... + } + PageIndicator { + anchors.horizontalCenter: parent.horizontalCenter + anchors.bottom: parent.bottom + } + } + \endcode + + In this case, Pane cannot calculate a sensible implicit size. Since we're + anchoring the \l PageIndicator over the \l SwipeView, we can simply set the + content size to the view's implicit size: + + \code + Pane { + contentWidth: view.implicitWidth + contentHeight: view.implicitHeight + + SwipeView { + id: view + // ... + } + PageIndicator { + anchors.horizontalCenter: parent.horizontalCenter + anchors.bottom: parent.bottom + } + } + \endcode + \sa {Customizing Pane}, {Container Controls} */ @@ -89,11 +125,12 @@ QQuickPane::QQuickPane(QQuickPanePrivate &dd, QQuickItem *parent) : /*! \qmlproperty real QtQuick.Controls::Pane::contentWidth - This property holds the content width. It is used for calculating the - total implicit width of the pane. + This property holds the content width. It is used for calculating the total + implicit width of the pane. - \note If only a single item is used within the pane, the implicit width - of its contained item is used as the content width. + For more information, see \l {Content Sizing}. + + \sa contentHeight */ qreal QQuickPane::contentWidth() const { @@ -114,11 +151,12 @@ void QQuickPane::setContentWidth(qreal width) /*! \qmlproperty real QtQuick.Controls::Pane::contentHeight - This property holds the content height. It is used for calculating the - total implicit height of the pane. + This property holds the content height. It is used for calculating the total + implicit height of the pane. + + For more information, see \l {Content Sizing}. - \note If only a single item is used within the pane, the implicit height - of its contained item is used as the content height. + \sa contentWidth */ qreal QQuickPane::contentHeight() const { @@ -142,7 +180,13 @@ void QQuickPane::setContentHeight(qreal height) This property holds the list of content data. - \sa Item::data + The list contains all objects that have been declared in QML as children + of the pane. + + \note Unlike \c contentChildren, \c contentData does include non-visual QML + objects. + + \sa Item::data, contentChildren */ QQmlListProperty<QObject> QQuickPane::contentData() { @@ -159,7 +203,13 @@ QQmlListProperty<QObject> QQuickPane::contentData() This property holds the list of content children. - \sa Item::children + The list contains all items that have been declared in QML as children + of the pane. + + \note Unlike \c contentData, \c contentChildren does not include non-visual + QML objects. + + \sa Item::children, contentData */ QQmlListProperty<QQuickItem> QQuickPane::contentChildren() { diff --git a/src/quicktemplates2/qquickstackview_p.cpp b/src/quicktemplates2/qquickstackview_p.cpp index 438b4269..ad08df5a 100644 --- a/src/quicktemplates2/qquickstackview_p.cpp +++ b/src/quicktemplates2/qquickstackview_p.cpp @@ -270,8 +270,9 @@ bool QQuickStackElement::prepareTransition(QQuickItemViewTransitioner *transitio return false; } -void QQuickStackElement::startTransition(QQuickItemViewTransitioner *transitioner) +void QQuickStackElement::startTransition(QQuickItemViewTransitioner *transitioner, QQuickStackView::Status status) { + setStatus(status); if (transitioner) QQuickItemViewTransitionableItem::startTransition(transitioner, index); } @@ -432,26 +433,22 @@ void QQuickStackViewPrivate::ensureTransitioner() void QQuickStackViewPrivate::startTransition(const QQuickStackTransition &first, const QQuickStackTransition &second, bool immediate) { - if (first.element) { - first.element->setStatus(first.status); + if (first.element) first.element->transitionNextReposition(transitioner, first.type, first.target); - } - if (second.element) { - second.element->setStatus(second.status); + if (second.element) second.element->transitionNextReposition(transitioner, second.type, second.target); - } if (first.element) { if (immediate || !first.element->item || !first.element->prepareTransition(transitioner, first.viewBounds)) - completeTransition(first.element, transitioner->removeTransition); + completeTransition(first.element, transitioner->removeTransition, first.status); else - first.element->startTransition(transitioner); + first.element->startTransition(transitioner, first.status); } if (second.element) { if (immediate || !second.element->item || !second.element->prepareTransition(transitioner, second.viewBounds)) - completeTransition(second.element, transitioner->removeDisplacedTransition); + completeTransition(second.element, transitioner->removeDisplacedTransition, second.status); else - second.element->startTransition(transitioner); + second.element->startTransition(transitioner, second.status); } if (transitioner) { @@ -460,8 +457,9 @@ void QQuickStackViewPrivate::startTransition(const QQuickStackTransition &first, } } -void QQuickStackViewPrivate::completeTransition(QQuickStackElement *element, QQuickTransition *transition) +void QQuickStackViewPrivate::completeTransition(QQuickStackElement *element, QQuickTransition *transition, QQuickStackView::Status status) { + element->setStatus(status); if (transition) { // TODO: add a proper way to complete a transition QQmlListProperty<QQuickAbstractAnimation> animations = transition->animations(); diff --git a/src/quicktemplates2/qquickstackview_p_p.h b/src/quicktemplates2/qquickstackview_p_p.h index c7691c40..5b3b1445 100644 --- a/src/quicktemplates2/qquickstackview_p_p.h +++ b/src/quicktemplates2/qquickstackview_p_p.h @@ -80,7 +80,7 @@ public: void transitionNextReposition(QQuickItemViewTransitioner *transitioner, QQuickItemViewTransitioner::TransitionType type, bool asTarget); bool prepareTransition(QQuickItemViewTransitioner *transitioner, const QRectF &viewBounds); - void startTransition(QQuickItemViewTransitioner *transitioner); + void startTransition(QQuickItemViewTransitioner *transitioner, QQuickStackView::Status status); void itemDestroyed(QQuickItem *item) override; @@ -125,7 +125,7 @@ public: void ensureTransitioner(); void startTransition(const QQuickStackTransition &first, const QQuickStackTransition &second, bool immediate); - void completeTransition(QQuickStackElement *element, QQuickTransition *transition); + void completeTransition(QQuickStackElement *element, QQuickTransition *transition, QQuickStackView::Status status); void viewItemTransitionFinished(QQuickItemViewTransitionableItem *item) override; void setBusy(bool busy); diff --git a/tests/auto/controls/data/tst_stackview.qml b/tests/auto/controls/data/tst_stackview.qml index 4de8bed0..242c0699 100644 --- a/tests/auto/controls/data/tst_stackview.qml +++ b/tests/auto/controls/data/tst_stackview.qml @@ -1007,4 +1007,22 @@ TestCase { control.destroy() } + + // QTBUG-56158 + function test_repeatedPop() { + var control = stackView.createObject(testCase, {initialItem: component, width: testCase.width, height: testCase.height}) + verify(control) + + for (var i = 0; i < 12; ++i) + control.push(component) + tryCompare(control, "busy", false) + + while (control.depth > 1) { + control.pop() + wait(50) + } + tryCompare(control, "busy", false) + + control.destroy() + } } diff --git a/tests/auto/drawer/data/grabber.qml b/tests/auto/drawer/data/grabber.qml new file mode 100644 index 00000000..8b85f71a --- /dev/null +++ b/tests/auto/drawer/data/grabber.qml @@ -0,0 +1,63 @@ +/**************************************************************************** +** +** 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 { + width: 400 + height: 400 + + property alias drawer: drawer + property alias popup: popup + + Drawer { + id: drawer + width: 200 + height: parent.height + } + + Popup { + id: popup + x: 200 + width: 200 + height: parent.height + } +} diff --git a/tests/auto/drawer/data/header.qml b/tests/auto/drawer/data/header.qml index 9a352ffc..c74cc0c0 100644 --- a/tests/auto/drawer/data/header.qml +++ b/tests/auto/drawer/data/header.qml @@ -46,8 +46,14 @@ ApplicationWindow { height: 400 property alias drawer: drawer + property alias button: button - header: ToolBar { } + header: ToolBar { + ToolButton { + id: button + text: "=" + } + } Drawer { id: drawer diff --git a/tests/auto/drawer/tst_drawer.cpp b/tests/auto/drawer/tst_drawer.cpp index 1ded5bf4..4e9e1e67 100644 --- a/tests/auto/drawer/tst_drawer.cpp +++ b/tests/auto/drawer/tst_drawer.cpp @@ -82,6 +82,8 @@ private slots: void touch_data(); void touch(); + + void grabber(); }; void tst_Drawer::visible_data() @@ -402,6 +404,9 @@ void tst_Drawer::header() QVERIFY(drawer); QQuickItem *popupItem = drawer->popupItem(); + QQuickButton *button = window->property("button").value<QQuickButton*>(); + QVERIFY(button); + drawer->open(); QVERIFY(drawer->isVisible()); @@ -413,6 +418,12 @@ void tst_Drawer::header() QCOMPARE(drawer->parentItem(), content); QCOMPARE(drawer->height(), content->height()); QCOMPARE(popupItem->height(), content->height()); + + // must be possible to interact with the header when the drawer is below the header + QSignalSpy clickSpy(button, SIGNAL(clicked())); + QVERIFY(clickSpy.isValid()); + QTest::mouseClick(window, Qt::LeftButton, Qt::NoModifier, QPoint(button->x() + button->width() / 2, button->y() + button->height() / 2)); + QCOMPARE(clickSpy.count(), 1); } void tst_Drawer::hover_data() @@ -736,6 +747,42 @@ void tst_Drawer::touch() QTRY_COMPARE(drawer->position(), 0.0); } +void tst_Drawer::grabber() +{ + QQuickApplicationHelper helper(this, QStringLiteral("grabber.qml")); + QQuickWindow *window = helper.window; + window->show(); + QVERIFY(QTest::qWaitForWindowExposed(window)); + + QQuickDrawer *drawer = window->property("drawer").value<QQuickDrawer *>(); + QVERIFY(drawer); + + QSignalSpy drawerOpenedSpy(drawer, SIGNAL(opened())); + QSignalSpy drawerClosedSpy(drawer, SIGNAL(closed())); + QVERIFY(drawerOpenedSpy.isValid()); + QVERIFY(drawerClosedSpy.isValid()); + + drawer->open(); + QVERIFY(drawerOpenedSpy.wait()); + + QTest::mouseClick(window, Qt::LeftButton, Qt::NoModifier, QPoint(300, 100)); + QVERIFY(drawerClosedSpy.wait()); + + QQuickPopup *popup = window->property("popup").value<QQuickPopup *>(); + QVERIFY(popup); + + QSignalSpy popupOpenedSpy(popup, SIGNAL(opened())); + QSignalSpy popupClosedSpy(popup, SIGNAL(closed())); + QVERIFY(popupOpenedSpy.isValid()); + QVERIFY(popupClosedSpy.isValid()); + + popup->open(); + QTRY_COMPARE(popupOpenedSpy.count(), 1); + + QTest::mouseClick(window, Qt::LeftButton, Qt::NoModifier, QPoint(100, 300)); + QTRY_COMPARE(popupClosedSpy.count(), 1); +} + QTEST_MAIN(tst_Drawer) #include "tst_drawer.moc" diff --git a/tests/auto/popup/data/nested.qml b/tests/auto/popup/data/nested.qml new file mode 100644 index 00000000..bf9e86c5 --- /dev/null +++ b/tests/auto/popup/data/nested.qml @@ -0,0 +1,64 @@ +/**************************************************************************** +** +** 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 { + width: 400 + height: 400 + + property alias modalPopup: modalPopup + property alias modelessPopup: modelessPopup + + Popup { + id: modalPopup + modal: true + width: 200 + height: 200 + } + + Popup { + id: modelessPopup + modal: false + width: 100 + height: 100 + } +} diff --git a/tests/auto/popup/tst_popup.cpp b/tests/auto/popup/tst_popup.cpp index 298328de..6d1e1e3c 100644 --- a/tests/auto/popup/tst_popup.cpp +++ b/tests/auto/popup/tst_popup.cpp @@ -69,6 +69,7 @@ private slots: void wheel_data(); void wheel(); void parentDestroyed(); + void nested(); }; void tst_popup::visible_data() @@ -609,6 +610,32 @@ void tst_popup::parentDestroyed() QVERIFY(!popup.parentItem()); } +void tst_popup::nested() +{ + QQuickApplicationHelper helper(this, QStringLiteral("nested.qml")); + QQuickWindow *window = helper.window; + window->show(); + QVERIFY(QTest::qWaitForWindowExposed(window)); + + QQuickPopup *modalPopup = window->property("modalPopup").value<QQuickPopup *>(); + QVERIFY(modalPopup); + + QQuickPopup *modelessPopup = window->property("modelessPopup").value<QQuickPopup *>(); + QVERIFY(modelessPopup); + + modalPopup->open(); + QCOMPARE(modalPopup->isVisible(), true); + + modelessPopup->open(); + QCOMPARE(modelessPopup->isVisible(), true); + + // click outside the modeless popup on the top, but inside the modal popup below + QTest::mouseClick(window, Qt::LeftButton, Qt::NoModifier, QPoint(150, 150)); + + QTRY_COMPARE(modelessPopup->isVisible(), false); + QCOMPARE(modalPopup->isVisible(), true); +} + QTEST_MAIN(tst_popup) #include "tst_popup.moc" |