From e4901286c801162d6b9b94b10d23dafca73c5068 Mon Sep 17 00:00:00 2001 From: Mitch Curtis Date: Tue, 6 Mar 2018 12:15:11 +0100 Subject: Doc: add an example of submenus and dynamically generated menu items Task-number: QTBUG-66874 Change-Id: I1e34039e4fa0344b1efdcb2977586d97ada6b31e Reviewed-by: J-P Nurmi --- src/imports/platform/qquickplatformmenu.cpp | 62 +++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/src/imports/platform/qquickplatformmenu.cpp b/src/imports/platform/qquickplatformmenu.cpp index ec5c4804..6168938c 100644 --- a/src/imports/platform/qquickplatformmenu.cpp +++ b/src/imports/platform/qquickplatformmenu.cpp @@ -100,6 +100,68 @@ QT_BEGIN_NAMESPACE } \endcode + \section2 Submenus + + To create submenus, declare a Menu as a child of another Menu: + + \qml + Menu { + title: qsTr("Edit") + + Menu { + title: qsTr("Advanced") + + MenuItem { + text: qsTr("Auto-indent Selection") + onTriggered: autoIndentSelection() + } + + MenuItem { + text: qsTr("Rewrap Paragraph") + onTriggered: rewrapParagraph() + } + } + } + \endqml + + \section2 Dynamically Generating Menu Items + + It is possible to dynamically generate menu items. One of the easiest ways + to do so is with \l Instantiator. For example, to implement a + "Recent Files" submenu, where the items are based on a list of files stored + in settings, the following code could be used: + + \qml + Menu { + title: qsTr("File") + + Menu { + id: recentFilesSubMenu + title: qsTr("Recent Files") + enabled: recentFilesInstantiator.count > 0 + + Instantiator { + id: recentFilesInstantiator + model: settings.recentFiles + delegate: MenuItem { + text: settings.displayableFilePath(modelData) + onTriggered: loadFile(modelData) + } + + onObjectAdded: recentFilesSubMenu.insertItem(index, object) + onObjectRemoved: recentFilesSubMenu.removeItem(object) + } + + MenuSeparator {} + + MenuItem { + text: qsTr("Clear Recent Files") + onTriggered: settings.clearRecentFiles() + } + } + } + \endqml + \section2 Availability A native platform menu is currently available on the following platforms: -- cgit v1.2.3 From c6bf75d7da46d35613db7f2e90ee4e4248d4501d Mon Sep 17 00:00:00 2001 From: Mitch Curtis Date: Tue, 6 Mar 2018 15:13:09 +0100 Subject: Doc: add a "Focus Management in Qt Quick Controls 2" page This will list each control that is a focus scope, and have some relevant information about focus in Qt Quick Controls 2. Change-Id: I3126452bf73f7d7730d0522d616d61ad0da0dd74 Reviewed-by: J-P Nurmi --- .../controls/doc/src/qtquickcontrols2-focus.qdoc | 47 ++++++++++++++++++++++ src/quicktemplates2/qquickapplicationwindow.cpp | 4 +- src/quicktemplates2/qquickcombobox.cpp | 3 +- src/quicktemplates2/qquickmenubar.cpp | 4 +- src/quicktemplates2/qquickpage.cpp | 4 +- src/quicktemplates2/qquickpane.cpp | 4 +- src/quicktemplates2/qquickpopup.cpp | 1 + src/quicktemplates2/qquickrangeslider.cpp | 4 +- src/quicktemplates2/qquickscrollview.cpp | 2 + src/quicktemplates2/qquickspinbox.cpp | 3 +- src/quicktemplates2/qquickstackview.cpp | 4 +- src/quicktemplates2/qquickswipeview.cpp | 4 +- src/quicktemplates2/qquicktabbar.cpp | 4 +- 13 files changed, 78 insertions(+), 10 deletions(-) create mode 100644 src/imports/controls/doc/src/qtquickcontrols2-focus.qdoc diff --git a/src/imports/controls/doc/src/qtquickcontrols2-focus.qdoc b/src/imports/controls/doc/src/qtquickcontrols2-focus.qdoc new file mode 100644 index 00000000..7883db71 --- /dev/null +++ b/src/imports/controls/doc/src/qtquickcontrols2-focus.qdoc @@ -0,0 +1,47 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://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 https://www.qt.io/terms-conditions. For further +** information use the contact form at https://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: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \page qtquickcontrols2-focus.html + \title Focus Management in Qt Quick Controls 2 + \brief Overview of focus handling with Qt Quick Controls 2 + + Qt Quick Controls 2 follows the standard + \l {Keyboard Focus in Qt Quick}{Qt Quick focus system}, while also + providing some added convenience. For example, the + \l {Control::}{focusPolicy} property can be used to control the ways in + which a control receives focus. + + \section1 Focus Scope Controls + + Qt Quick Controls 2 offers a selection of controls that act as + \l {Acquiring Focus and Focus Scopes}{focus scopes}: + + \annotatedlist qtquickcontrols2-focusscopes + + \sa {Keyboard Focus in Qt Quick} +*/ diff --git a/src/quicktemplates2/qquickapplicationwindow.cpp b/src/quicktemplates2/qquickapplicationwindow.cpp index 687b4233..77cf5465 100644 --- a/src/quicktemplates2/qquickapplicationwindow.cpp +++ b/src/quicktemplates2/qquickapplicationwindow.cpp @@ -59,6 +59,7 @@ QT_BEGIN_NAMESPACE \inqmlmodule QtQuick.Controls \since 5.7 \ingroup qtquickcontrols2-containers + \ingroup qtquickcontrols2-focusscopes \brief Styled top-level window with support for a header and footer. ApplicationWindow is a \l Window which makes it convenient to add @@ -110,7 +111,8 @@ QT_BEGIN_NAMESPACE certain window \c id. A QML component that uses the ApplicationWindow attached properties works in any window regardless of its \c id. - \sa {Customizing ApplicationWindow}, Overlay, Page, {Container Controls} + \sa {Customizing ApplicationWindow}, Overlay, Page, {Container Controls}, + {Focus Management in Qt Quick Controls 2} */ static const QQuickItemPrivate::ChangeTypes ItemChanges = QQuickItemPrivate::Visibility diff --git a/src/quicktemplates2/qquickcombobox.cpp b/src/quicktemplates2/qquickcombobox.cpp index b4d9bead..74efb6bb 100644 --- a/src/quicktemplates2/qquickcombobox.cpp +++ b/src/quicktemplates2/qquickcombobox.cpp @@ -63,6 +63,7 @@ QT_BEGIN_NAMESPACE \inqmlmodule QtQuick.Controls \since 5.7 \ingroup qtquickcontrols2-input + \ingroup qtquickcontrols2-focusscopes \brief Combined button and popup list for selecting options. \image qtquickcontrols2-combobox.gif @@ -133,7 +134,7 @@ QT_BEGIN_NAMESPACE \l textRole is not defined, ComboBox is unable to visualize it and throws a \c {ReferenceError: modelData is not defined}. - \sa {Customizing ComboBox}, {Input Controls} + \sa {Customizing ComboBox}, {Input Controls}, {Focus Management in Qt Quick Controls 2} */ /*! diff --git a/src/quicktemplates2/qquickmenubar.cpp b/src/quicktemplates2/qquickmenubar.cpp index de3cc9a7..8398633c 100644 --- a/src/quicktemplates2/qquickmenubar.cpp +++ b/src/quicktemplates2/qquickmenubar.cpp @@ -53,6 +53,7 @@ QT_BEGIN_NAMESPACE \inqmlmodule QtQuick.Controls \since 5.10 \ingroup qtquickcontrols2-menus + \ingroup qtquickcontrols2-focusscopes \brief Provides a window menu bar. \image qtquickcontrols2-menubar.png @@ -71,7 +72,8 @@ QT_BEGIN_NAMESPACE \l {removeMenu}{remove}, and \l {takeMenu}{take} menus dynamically. The menus in a menu bar can be accessed using \l menuAt(). - \sa {Customizing MenuBar}, Menu, MenuBarItem, {Menu Controls} + \sa {Customizing MenuBar}, Menu, MenuBarItem, {Menu Controls}, + {Focus Management in Qt Quick Controls 2} */ QQuickMenuBarPrivate::QQuickMenuBarPrivate() diff --git a/src/quicktemplates2/qquickpage.cpp b/src/quicktemplates2/qquickpage.cpp index 907b01e9..8f34dca9 100644 --- a/src/quicktemplates2/qquickpage.cpp +++ b/src/quicktemplates2/qquickpage.cpp @@ -47,6 +47,7 @@ QT_BEGIN_NAMESPACE \inqmlmodule QtQuick.Controls \since 5.7 \ingroup qtquickcontrols2-containers + \ingroup qtquickcontrols2-focusscopes \brief Styled page control with support for a header and footer. Page is a container control which makes it convenient to add @@ -79,7 +80,8 @@ QT_BEGIN_NAMESPACE } \endqml - \sa ApplicationWindow, {Container Controls} + \sa ApplicationWindow, {Container Controls}, + {Focus Management in Qt Quick Controls 2} */ class QQuickPagePrivate : public QQuickControlPrivate diff --git a/src/quicktemplates2/qquickpane.cpp b/src/quicktemplates2/qquickpane.cpp index 4c3e1422..8038f1b1 100644 --- a/src/quicktemplates2/qquickpane.cpp +++ b/src/quicktemplates2/qquickpane.cpp @@ -46,6 +46,7 @@ QT_BEGIN_NAMESPACE \inqmlmodule QtQuick.Controls \since 5.7 \ingroup qtquickcontrols2-containers + \ingroup qtquickcontrols2-focusscopes \brief Provides a background matching with the application style and theme. Pane provides a background color that matches with the application style @@ -101,7 +102,8 @@ QT_BEGIN_NAMESPACE } \endcode - \sa {Customizing Pane}, {Container Controls} + \sa {Customizing Pane}, {Container Controls}, + {Focus Management in Qt Quick Controls 2} */ QQuickPanePrivate::QQuickPanePrivate() diff --git a/src/quicktemplates2/qquickpopup.cpp b/src/quicktemplates2/qquickpopup.cpp index 03328b43..e3ab952d 100644 --- a/src/quicktemplates2/qquickpopup.cpp +++ b/src/quicktemplates2/qquickpopup.cpp @@ -57,6 +57,7 @@ QT_BEGIN_NAMESPACE \inqmlmodule QtQuick.Controls \since 5.7 \ingroup qtquickcontrols2-popups + \ingroup qtquickcontrols2-focusscopes \brief Base type of popup-like user interface controls. Popup is the base type of popup-like user interface controls. It can be diff --git a/src/quicktemplates2/qquickrangeslider.cpp b/src/quicktemplates2/qquickrangeslider.cpp index 075306cf..7205f26b 100644 --- a/src/quicktemplates2/qquickrangeslider.cpp +++ b/src/quicktemplates2/qquickrangeslider.cpp @@ -50,6 +50,7 @@ QT_BEGIN_NAMESPACE \inqmlmodule QtQuick.Controls \since 5.7 \ingroup qtquickcontrols2-input + \ingroup qtquickcontrols2-focusscopes \brief Used to select a range of values by sliding two handles along a track. \image qtquickcontrols2-rangeslider.gif @@ -85,7 +86,8 @@ QT_BEGIN_NAMESPACE RangeSlider. In the example above, \l {first.visualPosition} will be \c 0.24 in a left-to-right application, and \c 0.76 in a right-to-left application. - \sa {Customizing RangeSlider}, {Input Controls} + \sa {Customizing RangeSlider}, {Input Controls}, + {Focus Management in Qt Quick Controls 2} */ class QQuickRangeSliderNodePrivate : public QObjectPrivate diff --git a/src/quicktemplates2/qquickscrollview.cpp b/src/quicktemplates2/qquickscrollview.cpp index 254a90d7..30750aa8 100644 --- a/src/quicktemplates2/qquickscrollview.cpp +++ b/src/quicktemplates2/qquickscrollview.cpp @@ -49,6 +49,7 @@ QT_BEGIN_NAMESPACE \inqmlmodule QtQuick.Controls \since 5.9 \ingroup qtquickcontrols2-containers + \ingroup qtquickcontrols2-focusscopes \brief Scrollable view. ScrollView provides scrolling for user-defined content. It can be used to @@ -97,6 +98,7 @@ QT_BEGIN_NAMESPACE \snippet qtquickcontrols2-scrollview-interactive.qml file \sa ScrollBar, ScrollIndicator, {Customizing ScrollView}, {Container Controls}, + {Focus Management in Qt Quick Controls 2} */ class QQuickScrollViewPrivate : public QQuickControlPrivate diff --git a/src/quicktemplates2/qquickspinbox.cpp b/src/quicktemplates2/qquickspinbox.cpp index 525de945..04bdec43 100644 --- a/src/quicktemplates2/qquickspinbox.cpp +++ b/src/quicktemplates2/qquickspinbox.cpp @@ -59,6 +59,7 @@ static const int AUTO_REPEAT_INTERVAL = 100; \inqmlmodule QtQuick.Controls \since 5.7 \ingroup input + \ingroup qtquickcontrols2-focusscopes \brief Allows the user to select from a set of preset values. \image qtquickcontrols2-spinbox.png @@ -91,7 +92,7 @@ static const int AUTO_REPEAT_INTERVAL = 100; \snippet qtquickcontrols2-spinbox-double.qml 1 - \sa Tumbler, {Customizing SpinBox} + \sa Tumbler, {Customizing SpinBox}, {Focus Management in Qt Quick Controls 2} */ /*! diff --git a/src/quicktemplates2/qquickstackview.cpp b/src/quicktemplates2/qquickstackview.cpp index 090a6d74..1abc506b 100644 --- a/src/quicktemplates2/qquickstackview.cpp +++ b/src/quicktemplates2/qquickstackview.cpp @@ -57,6 +57,7 @@ QT_BEGIN_NAMESPACE \since 5.7 \ingroup qtquickcontrols2-navigation \ingroup qtquickcontrols2-containers + \ingroup qtquickcontrols2-focusscopes \brief Provides a stack-based navigation model. \image qtquickcontrols2-stackview-wireframe.png @@ -342,7 +343,8 @@ QT_BEGIN_NAMESPACE } \endqml - \sa {Customizing StackView}, {Navigation Controls}, {Container Controls} + \sa {Customizing StackView}, {Navigation Controls}, {Container Controls}, + {Focus Management in Qt Quick Controls 2} */ QQuickStackView::QQuickStackView(QQuickItem *parent) diff --git a/src/quicktemplates2/qquickswipeview.cpp b/src/quicktemplates2/qquickswipeview.cpp index 5f84f93e..60bc9477 100644 --- a/src/quicktemplates2/qquickswipeview.cpp +++ b/src/quicktemplates2/qquickswipeview.cpp @@ -49,6 +49,7 @@ QT_BEGIN_NAMESPACE \since 5.7 \ingroup qtquickcontrols2-navigation \ingroup qtquickcontrols2-containers + \ingroup qtquickcontrols2-focusscopes \brief Enables the user to navigate pages by swiping sideways. SwipeView provides a swipe-based navigation model. @@ -98,7 +99,8 @@ QT_BEGIN_NAMESPACE this only applies to the root of the item. Specifying width and height, or using anchors for its children works as expected. - \sa TabBar, PageIndicator, {Customizing SwipeView}, {Navigation Controls}, {Container Controls} + \sa TabBar, PageIndicator, {Customizing SwipeView}, {Navigation Controls}, {Container Controls}, + {Focus Management in Qt Quick Controls 2} */ class QQuickSwipeViewPrivate : public QQuickContainerPrivate diff --git a/src/quicktemplates2/qquicktabbar.cpp b/src/quicktemplates2/qquicktabbar.cpp index 814d14ea..cd0c5c45 100644 --- a/src/quicktemplates2/qquicktabbar.cpp +++ b/src/quicktemplates2/qquicktabbar.cpp @@ -48,6 +48,7 @@ QT_BEGIN_NAMESPACE \since 5.7 \ingroup qtquickcontrols2-navigation \ingroup qtquickcontrols2-containers + \ingroup qtquickcontrols2-focusscopes \brief Allows the user to switch between different views or subtasks. TabBar provides a tab-based navigation model. @@ -90,7 +91,8 @@ QT_BEGIN_NAMESPACE \snippet qtquickcontrols2-tabbar-flickable.qml 1 - \sa TabButton, {Customizing TabBar}, {Navigation Controls}, {Container Controls} + \sa TabButton, {Customizing TabBar}, {Navigation Controls}, {Container Controls}, + {Focus Management in Qt Quick Controls 2} */ class QQuickTabBarPrivate : public QQuickContainerPrivate -- cgit v1.2.3 From 923e7c26fde2bc42d04902441691b7f7667460a7 Mon Sep 17 00:00:00 2001 From: Mitch Curtis Date: Tue, 6 Mar 2018 14:48:21 +0100 Subject: QQuickPlatformMenu: fix submenu titles not being visible As with other properties in QQuickPlatformMenu, ensure that we set the relevant property on the internal QQuickPlatformMenuItem. Task-number: QTBUG-66876 Change-Id: Ie37d874426200014ea3bb4045bc6b566422221de Reviewed-by: J-P Nurmi --- src/imports/platform/qquickplatformmenu.cpp | 3 +++ tests/auto/platform/data/tst_menu.qml | 19 +++++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/src/imports/platform/qquickplatformmenu.cpp b/src/imports/platform/qquickplatformmenu.cpp index 6168938c..abbea4e7 100644 --- a/src/imports/platform/qquickplatformmenu.cpp +++ b/src/imports/platform/qquickplatformmenu.cpp @@ -522,6 +522,9 @@ void QQuickPlatformMenu::setTitle(const QString &title) if (m_title == title) return; + if (m_menuItem) + m_menuItem->setText(title); + m_title = title; sync(); emit titleChanged(); diff --git a/tests/auto/platform/data/tst_menu.qml b/tests/auto/platform/data/tst_menu.qml index 2b7a10ad..06b9a30f 100644 --- a/tests/auto/platform/data/tst_menu.qml +++ b/tests/auto/platform/data/tst_menu.qml @@ -242,4 +242,23 @@ TestCase { compare(Menu.DefaultMenu, 0) compare(Menu.EditMenu, 1) } + + function test_subMenus() { + var parentMenu = createTemporaryObject(menu, testCase) + verify(parentMenu) + + var subMenu = menu.createObject(parentMenu) + verify(subMenu) + + var subMenuItem = subMenu.menuItem + verify(subMenuItem) + + parentMenu.addMenu(subMenu) + compare(parentMenu.items.length, 1) + verify(parentMenu.items[0], subMenuItem) + + subMenu.title = "Title" + compare(subMenu.title, "Title") + compare(subMenuItem.text, "Title") + } } -- cgit v1.2.3 From 0dbfa219e704dbccadff9f305817bfd4ef37905b Mon Sep 17 00:00:00 2001 From: Mitch Curtis Date: Wed, 7 Mar 2018 11:54:53 +0100 Subject: QQuickPlatformMenu: fix crash on exit with submenus Ensure that we unparent submenus in destroy(), not just in the destructor. Task-number: QTBUG-66889 Change-Id: I18b5fc28ee47a50f511ef4f8cf55cfdcbae9bfec Reviewed-by: J-P Nurmi --- src/imports/platform/qquickplatformmenu.cpp | 19 +++++++++++++++---- src/imports/platform/qquickplatformmenu_p.h | 2 ++ 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/src/imports/platform/qquickplatformmenu.cpp b/src/imports/platform/qquickplatformmenu.cpp index abbea4e7..0a5ce8e4 100644 --- a/src/imports/platform/qquickplatformmenu.cpp +++ b/src/imports/platform/qquickplatformmenu.cpp @@ -216,15 +216,22 @@ QQuickPlatformMenu::~QQuickPlatformMenu() m_menuBar->removeMenu(this); if (m_parentMenu) m_parentMenu->removeMenu(this); + + unparentSubmenus(); + + delete m_iconLoader; + m_iconLoader = nullptr; + delete m_handle; + m_handle = nullptr; +} + +void QQuickPlatformMenu::unparentSubmenus() +{ for (QQuickPlatformMenuItem *item : qAsConst(m_items)) { if (QQuickPlatformMenu *subMenu = item->subMenu()) subMenu->setParentMenu(nullptr); item->setMenu(nullptr); } - delete m_iconLoader; - m_iconLoader = nullptr; - delete m_handle; - m_handle = nullptr; } QPlatformMenu *QQuickPlatformMenu::handle() const @@ -277,6 +284,10 @@ void QQuickPlatformMenu::destroy() if (!m_handle) return; + // Ensure that all submenus are unparented before we are destroyed, + // so that they don't try to access a destroyed menu. + unparentSubmenus(); + delete m_handle; m_handle = nullptr; } diff --git a/src/imports/platform/qquickplatformmenu_p.h b/src/imports/platform/qquickplatformmenu_p.h index b5c23b61..14f083dd 100644 --- a/src/imports/platform/qquickplatformmenu_p.h +++ b/src/imports/platform/qquickplatformmenu_p.h @@ -189,6 +189,8 @@ private Q_SLOTS: void updateIcon(); private: + void unparentSubmenus(); + bool m_complete; bool m_enabled; bool m_visible; -- cgit v1.2.3 From 031a1e89e1baa952225c0f036b605f591f554e9b Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Thu, 8 Mar 2018 16:32:59 +0100 Subject: QQuickDrawer: fix dragging Make sure to respect keepMouse|TouchGrab. This fixes dragging a horizontal Slider inside a Drawer on the left or right edge, for example. Task-number: QTBUG-66637 Change-Id: Ie3688744741378694f96abc608dad2630ecd1fb0 Reviewed-by: Mitch Curtis --- src/quicktemplates2/qquickdrawer.cpp | 18 ++++--- tests/auto/qquickdrawer/data/slider.qml | 74 ++++++++++++++++++++++++++++ tests/auto/qquickdrawer/tst_qquickdrawer.cpp | 55 +++++++++++++++++++++ 3 files changed, 139 insertions(+), 8 deletions(-) create mode 100644 tests/auto/qquickdrawer/data/slider.qml diff --git a/src/quicktemplates2/qquickdrawer.cpp b/src/quicktemplates2/qquickdrawer.cpp index 202d02d1..2d60e649 100644 --- a/src/quicktemplates2/qquickdrawer.cpp +++ b/src/quicktemplates2/qquickdrawer.cpp @@ -319,12 +319,17 @@ bool QQuickDrawerPrivate::startDrag(QEvent *event) return false; } +static inline bool keepGrab(QQuickItem *item) +{ + return item->keepMouseGrab() || item->keepTouchGrab(); +} + bool QQuickDrawerPrivate::grabMouse(QQuickItem *item, QMouseEvent *event) { Q_Q(QQuickDrawer); handleMouseEvent(item, event); - if (!window || !interactive || popupItem->keepMouseGrab() || popupItem->keepTouchGrab()) + if (!window || !interactive || keepGrab(popupItem) || keepGrab(item)) return false; const QPointF movePoint = event->windowPos(); @@ -352,12 +357,9 @@ bool QQuickDrawerPrivate::grabMouse(QQuickItem *item, QMouseEvent *event) } if (overThreshold) { - QQuickItem *grabber = window->mouseGrabberItem(); - if (!grabber || !grabber->keepMouseGrab()) { - popupItem->grabMouse(); - popupItem->setKeepMouseGrab(true); - offset = offsetAt(movePoint); - } + popupItem->grabMouse(); + popupItem->setKeepMouseGrab(true); + offset = offsetAt(movePoint); } return overThreshold; @@ -369,7 +371,7 @@ bool QQuickDrawerPrivate::grabTouch(QQuickItem *item, QTouchEvent *event) Q_Q(QQuickDrawer); bool handled = handleTouchEvent(item, event); - if (!window || !interactive || popupItem->keepTouchGrab() || !event->touchPointStates().testFlag(Qt::TouchPointMoved)) + if (!window || !interactive || keepGrab(popupItem) || keepGrab(item) || !event->touchPointStates().testFlag(Qt::TouchPointMoved)) return handled; bool overThreshold = false; diff --git a/tests/auto/qquickdrawer/data/slider.qml b/tests/auto/qquickdrawer/data/slider.qml new file mode 100644 index 00000000..595e7091 --- /dev/null +++ b/tests/auto/qquickdrawer/data/slider.qml @@ -0,0 +1,74 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** 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 https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, 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.9 +import QtQuick.Controls 2.0 + +ApplicationWindow { + width: 400 + height: 400 + + property alias drawer: drawer + property alias slider: slider + + Drawer { + id: drawer + width: 300 + height: 400 + position: 1.0 + visible: true + + Slider { + id: slider + value: 1 + width: parent.width + } + } +} diff --git a/tests/auto/qquickdrawer/tst_qquickdrawer.cpp b/tests/auto/qquickdrawer/tst_qquickdrawer.cpp index 60c5b189..bba1cf45 100644 --- a/tests/auto/qquickdrawer/tst_qquickdrawer.cpp +++ b/tests/auto/qquickdrawer/tst_qquickdrawer.cpp @@ -106,6 +106,9 @@ private slots: void nonModal_data(); void nonModal(); + void slider_data(); + void slider(); + private: struct TouchDeviceDeleter { @@ -1257,6 +1260,58 @@ void tst_QQuickDrawer::nonModal() QVERIFY(closedSpy.wait()); } +void tst_QQuickDrawer::slider_data() +{ + QTest::addColumn("mouse"); + QTest::newRow("mouse") << true; + QTest::newRow("touch") << false; +} + +void tst_QQuickDrawer::slider() +{ + QFETCH(bool, mouse); + + QQuickApplicationHelper helper(this, QStringLiteral("slider.qml")); + QQuickWindow *window = helper.window; + window->show(); + QVERIFY(QTest::qWaitForWindowActive(window)); + + QQuickDrawer *drawer = window->property("drawer").value(); + QVERIFY(drawer); + + QQuickSlider *slider = window->property("slider").value(); + QVERIFY(slider); + + QCOMPARE(slider->value(), 1.0); + QCOMPARE(drawer->position(), 1.0); + + const qreal y = slider->height() / 2; + const QPoint from(slider->width() - 1, y); + const QPoint to(1, y); + + if (mouse) + QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, from); + else + QTest::touchEvent(window, touchDevice.data()).press(0, from); + + int distance = qAbs(from.x() - to.x()); + for (int dx = 2; dx < distance; dx += 2) { + if (mouse) + QTest::mouseMove(window, from - QPoint(dx, 0)); + else + QTest::touchEvent(window, touchDevice.data()).move(0, from - QPoint(dx, 0)); + QTest::qWait(1); // avoid infinite velocity + } + + QCOMPARE(slider->value(), 0.0); + QCOMPARE(drawer->position(), 1.0); + + if (mouse) + QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, to); + else + QTest::touchEvent(window, touchDevice.data()).release(0, to); +} + QTEST_QUICKCONTROLS_MAIN(tst_QQuickDrawer) #include "tst_qquickdrawer.moc" -- cgit v1.2.3