aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.qmake.conf1
-rw-r--r--examples/quickcontrols2/texteditor/qml/+touch/texteditor.qml17
-rw-r--r--examples/quickcontrols2/texteditor/texteditor.cpp11
-rw-r--r--src/imports/controls/Container.qml47
-rw-r--r--src/imports/controls/Control.qml47
-rw-r--r--src/imports/controls/RoundButton.qml77
-rw-r--r--src/imports/controls/TextField.qml6
-rw-r--r--src/imports/controls/controls.pri3
-rw-r--r--src/imports/controls/doc/images/qtquickcontrols2-roundbutton.pngbin0 -> 1001 bytes
-rw-r--r--src/imports/controls/doc/snippets/qtquickcontrols2-roundbutton.qml36
-rw-r--r--src/imports/controls/doc/src/qtquickcontrols2-customize.qdoc6
-rw-r--r--src/imports/controls/doc/src/qtquickcontrols2-material.qdoc11
-rw-r--r--src/imports/controls/material/RoundButton.qml115
-rw-r--r--src/imports/controls/material/TextField.qml8
-rw-r--r--src/imports/controls/material/ToolBar.qml2
-rw-r--r--src/imports/controls/material/material.pri1
-rw-r--r--src/imports/controls/material/qquickmaterialstyle.cpp23
-rw-r--r--src/imports/controls/material/qquickmaterialstyle_p.h4
-rw-r--r--src/imports/controls/plugins.qmltypes81
-rw-r--r--src/imports/controls/qtquickcontrols2plugin.cpp5
-rw-r--r--src/imports/controls/universal/RoundButton.qml87
-rw-r--r--src/imports/controls/universal/TextField.qml6
-rw-r--r--src/imports/controls/universal/universal.pri1
-rw-r--r--src/imports/templates/plugins.qmltypes17
-rw-r--r--src/imports/templates/qtquicktemplates2plugin.cpp2
-rw-r--r--src/quickcontrols2/qquickstyle.cpp50
-rw-r--r--src/quicktemplates2/qquickapplicationwindow.cpp11
-rw-r--r--src/quicktemplates2/qquickbutton.cpp18
-rw-r--r--src/quicktemplates2/qquickbutton_p.h2
-rw-r--r--src/quicktemplates2/qquickbutton_p_p.h68
-rw-r--r--src/quicktemplates2/qquickdrawer.cpp258
-rw-r--r--src/quicktemplates2/qquickdrawer_p.h2
-rw-r--r--src/quicktemplates2/qquickdrawer_p_p.h93
-rw-r--r--src/quicktemplates2/qquickoverlay.cpp283
-rw-r--r--src/quicktemplates2/qquickoverlay_p.h7
-rw-r--r--src/quicktemplates2/qquickoverlay_p_p.h98
-rw-r--r--src/quicktemplates2/qquickpopup.cpp109
-rw-r--r--src/quicktemplates2/qquickpopup_p.h1
-rw-r--r--src/quicktemplates2/qquickpopup_p_p.h16
-rw-r--r--src/quicktemplates2/qquickroundbutton.cpp143
-rw-r--r--src/quicktemplates2/qquickroundbutton_p.h84
-rw-r--r--src/quicktemplates2/qquickscrollindicator.cpp13
-rw-r--r--src/quicktemplates2/qquickstackview.cpp17
-rw-r--r--src/quicktemplates2/qquickstackview_p.cpp5
-rw-r--r--src/quicktemplates2/qquickstackview_p.h1
-rw-r--r--src/quicktemplates2/qquickswitch.cpp14
-rw-r--r--src/quicktemplates2/quicktemplates2.pri5
-rw-r--r--tests/auto/controls/data/tst_container.qml85
-rw-r--r--tests/auto/controls/data/tst_control.qml29
-rw-r--r--tests/auto/controls/data/tst_popup.qml74
-rw-r--r--tests/auto/controls/data/tst_roundbutton.qml79
-rw-r--r--tests/auto/controls/data/tst_scrollindicator.qml34
-rw-r--r--tests/auto/controls/data/tst_stackview.qml54
-rw-r--r--tests/auto/controls/data/tst_switch.qml149
-rw-r--r--tests/auto/controls/data/tst_textfield.qml19
-rw-r--r--tests/auto/drawer/data/applicationwindow-hover.qml (renamed from tests/auto/drawer/data/hover.qml)0
-rw-r--r--tests/auto/drawer/data/applicationwindow.qml7
-rw-r--r--tests/auto/drawer/data/multiple.qml85
-rw-r--r--tests/auto/drawer/data/window-hover.qml73
-rw-r--r--tests/auto/drawer/data/window.qml56
-rw-r--r--tests/auto/drawer/tst_drawer.cpp332
-rw-r--r--tests/auto/focus/tst_focus.cpp2
-rw-r--r--tests/auto/menu/tst_menu.cpp12
-rw-r--r--tests/auto/popup/data/applicationwindow-hover.qml (renamed from tests/auto/popup/data/hover.qml)0
-rw-r--r--tests/auto/popup/data/window-hover.qml70
-rw-r--r--tests/auto/popup/data/window.qml84
-rw-r--r--tests/auto/popup/tst_popup.cpp169
-rw-r--r--tests/auto/qquickmaterialstyle/data/tst_material.qml77
-rw-r--r--tests/auto/qquickmaterialstyleconf/tst_qquickmaterialstyleconf.cpp2
-rw-r--r--tests/auto/qquickuniversalstyleconf/tst_qquickuniversalstyleconf.cpp2
-rw-r--r--tests/auto/sanity/tst_sanity.cpp12
-rw-r--r--tests/auto/shared/visualtestutil.h8
-rw-r--r--tests/auto/snippets/tst_snippets.cpp2
-rw-r--r--tests/benchmarks/creationtime/tst_creationtime.cpp7
-rw-r--r--tests/benchmarks/objectcount/tst_objectcount.cpp11
-rw-r--r--tests/manual/buttons/ButtonLoader.qml91
-rw-r--r--tests/manual/buttons/buttons.pro2
-rw-r--r--tests/manual/buttons/buttons.qml43
-rw-r--r--tests/manual/gifs/eventcapturer.cpp3
-rw-r--r--tests/manual/gifs/tst_gifs.cpp3
-rw-r--r--tests/manual/testbench/main.qml102
81 files changed, 3046 insertions, 644 deletions
diff --git a/.qmake.conf b/.qmake.conf
index c66a9cce..8114dfd7 100644
--- a/.qmake.conf
+++ b/.qmake.conf
@@ -1,5 +1,6 @@
load(qt_build_config)
CONFIG += warning_clean
+DEFINES += QT_NO_FOREACH
QQC2_SOURCE_TREE = $$PWD
diff --git a/examples/quickcontrols2/texteditor/qml/+touch/texteditor.qml b/examples/quickcontrols2/texteditor/qml/+touch/texteditor.qml
index a7f176a9..11d153f5 100644
--- a/examples/quickcontrols2/texteditor/qml/+touch/texteditor.qml
+++ b/examples/quickcontrols2/texteditor/qml/+touch/texteditor.qml
@@ -38,7 +38,6 @@
**
****************************************************************************/
-import QtGraphicalEffects 1.0
import QtQuick 2.8
import QtQuick.Controls 2.1
import QtQuick.Controls.Material 2.1
@@ -226,7 +225,7 @@ ApplicationWindow {
}
}
- Button {
+ RoundButton {
id: editButton
font.family: "fontello"
text: "\uE809" // icon-pencil
@@ -245,20 +244,6 @@ ApplicationWindow {
// Force focus on the text area so the cursor and footer show up.
textArea.forceActiveFocus()
}
-
- background: Rectangle {
- implicitWidth: parent.width
- implicitHeight: parent.height
- radius: width / 2
- color: parent.down ? Qt.darker(Material.accent) : Material.accent
-
- layer.enabled: editButton.enabled
- layer.effect: DropShadow {
- color: "#44000000"
- verticalOffset: 2
- samples: 16
- }
- }
}
Dialog {
diff --git a/examples/quickcontrols2/texteditor/texteditor.cpp b/examples/quickcontrols2/texteditor/texteditor.cpp
index 7fda4fa9..10ba675c 100644
--- a/examples/quickcontrols2/texteditor/texteditor.cpp
+++ b/examples/quickcontrols2/texteditor/texteditor.cpp
@@ -70,10 +70,17 @@ int main(int argc, char *argv[])
qmlRegisterType<DocumentHandler>("io.qt.examples.texteditor", 1, 0, "DocumentHandler");
- QQmlApplicationEngine engine;
+ QStringList selectors;
#ifdef QT_EXTRA_FILE_SELECTOR
- QQmlFileSelector::get(&engine)->setExtraSelectors(QStringList() << QT_EXTRA_FILE_SELECTOR);
+ selectors += QT_EXTRA_FILE_SELECTOR;
+#else
+ if (app.arguments().contains("-touch"))
+ selectors += "touch";
#endif
+
+ QQmlApplicationEngine engine;
+ QQmlFileSelector::get(&engine)->setExtraSelectors(selectors);
+
engine.load(QUrl("qrc:/qml/texteditor.qml"));
if (engine.rootObjects().isEmpty())
return -1;
diff --git a/src/imports/controls/Container.qml b/src/imports/controls/Container.qml
new file mode 100644
index 00000000..9e9215f8
--- /dev/null
+++ b/src/imports/controls/Container.qml
@@ -0,0 +1,47 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.6
+import QtQuick.Templates 2.0 as T
+
+T.Container {
+ id: control
+
+ implicitWidth: Math.max(background ? background.implicitWidth : 0,
+ (contentItem ? contentItem.implicitWidth : 0) + leftPadding + rightPadding)
+ implicitHeight: Math.max(background ? background.implicitHeight : 0,
+ (contentItem ? contentItem.implicitHeight : 0) + topPadding + bottomPadding)
+}
diff --git a/src/imports/controls/Control.qml b/src/imports/controls/Control.qml
new file mode 100644
index 00000000..a4bb95fe
--- /dev/null
+++ b/src/imports/controls/Control.qml
@@ -0,0 +1,47 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.6
+import QtQuick.Templates 2.0 as T
+
+T.Control {
+ id: control
+
+ implicitWidth: Math.max(background ? background.implicitWidth : 0,
+ (contentItem ? contentItem.implicitWidth : 0) + leftPadding + rightPadding)
+ implicitHeight: Math.max(background ? background.implicitHeight : 0,
+ (contentItem ? contentItem.implicitHeight : 0) + topPadding + bottomPadding)
+}
diff --git a/src/imports/controls/RoundButton.qml b/src/imports/controls/RoundButton.qml
new file mode 100644
index 00000000..102774e0
--- /dev/null
+++ b/src/imports/controls/RoundButton.qml
@@ -0,0 +1,77 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.6
+import QtQuick.Templates 2.1 as T
+
+T.RoundButton {
+ id: control
+
+ implicitWidth: Math.max(background ? background.implicitWidth : 0,
+ contentItem.implicitWidth + leftPadding + rightPadding)
+ implicitHeight: Math.max(background ? background.implicitHeight : 0,
+ contentItem.implicitHeight + topPadding + bottomPadding)
+ baselineOffset: contentItem.y + contentItem.baselineOffset
+
+ padding: 6
+
+ //! [contentItem]
+ contentItem: Text {
+ text: control.text
+ font: control.font
+ opacity: enabled || control.highlighted || control.checked ? 1 : 0.3
+ color: control.checked || control.highlighted ? "#ffffff" : (control.visualFocus ? "#0066ff" : (control.down ? "#26282a" : "#353637"))
+ horizontalAlignment: Text.AlignHCenter
+ verticalAlignment: Text.AlignVCenter
+ elide: Text.ElideRight
+ }
+ //! [contentItem]
+
+ //! [background]
+ background: Rectangle {
+ implicitWidth: 40
+ implicitHeight: 40
+ radius: control.radius
+ opacity: enabled ? 1 : 0.3
+ visible: !control.flat || control.down || control.checked || control.highlighted
+ color: control.checked || control.highlighted ?
+ (control.visualFocus ? (control.down ? "#599bff" : "#0066ff") : (control.down ? "#585a5c" : "#353637")) :
+ (control.visualFocus ? (control.down ? "#cce0ff" : "#f0f6ff") : (control.down ? "#d0d0d0" : "#e0e0e0"))
+ border.color: "#0066ff"
+ border.width: control.visualFocus ? 2 : 0
+ }
+ //! [background]
+}
diff --git a/src/imports/controls/TextField.qml b/src/imports/controls/TextField.qml
index 5fdb6fc9..540a8da4 100644
--- a/src/imports/controls/TextField.qml
+++ b/src/imports/controls/TextField.qml
@@ -41,8 +41,10 @@ T.TextField {
id: control
implicitWidth: Math.max(background ? background.implicitWidth : 0,
- placeholder.implicitWidth + leftPadding + rightPadding)
- implicitHeight: Math.max(background ? background.implicitHeight : 0,
+ placeholderText ? placeholder.implicitWidth + leftPadding + rightPadding : 0)
+ || contentWidth + leftPadding + rightPadding
+ implicitHeight: Math.max(contentHeight + topPadding + bottomPadding,
+ background ? background.implicitHeight : 0,
placeholder.implicitHeight + topPadding + bottomPadding)
padding: 6
diff --git a/src/imports/controls/controls.pri b/src/imports/controls/controls.pri
index 9eeb2c1f..f84c59bc 100644
--- a/src/imports/controls/controls.pri
+++ b/src/imports/controls/controls.pri
@@ -16,6 +16,8 @@ QML_CONTROLS = \
CheckDelegate.qml \
CheckIndicator.qml \
ComboBox.qml \
+ Container.qml \
+ Control.qml \
Dial.qml \
Dialog.qml \
DialogButtonBox.qml \
@@ -36,6 +38,7 @@ QML_CONTROLS = \
RadioDelegate.qml \
RadioIndicator.qml \
RangeSlider.qml \
+ RoundButton.qml \
ScrollBar.qml \
ScrollIndicator.qml \
Slider.qml \
diff --git a/src/imports/controls/doc/images/qtquickcontrols2-roundbutton.png b/src/imports/controls/doc/images/qtquickcontrols2-roundbutton.png
new file mode 100644
index 00000000..9f1d44fc
--- /dev/null
+++ b/src/imports/controls/doc/images/qtquickcontrols2-roundbutton.png
Binary files differ
diff --git a/src/imports/controls/doc/snippets/qtquickcontrols2-roundbutton.qml b/src/imports/controls/doc/snippets/qtquickcontrols2-roundbutton.qml
new file mode 100644
index 00000000..fa926302
--- /dev/null
+++ b/src/imports/controls/doc/snippets/qtquickcontrols2-roundbutton.qml
@@ -0,0 +1,36 @@
+/****************************************************************************
+**
+** 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 2.0
+import QtQuick.Controls 2.1
+
+//! [1]
+RoundButton {
+ text: "\u2713" // Unicode Character 'CHECK MARK'
+ onClicked: textArea.readOnly = true
+}
+//! [1]
diff --git a/src/imports/controls/doc/src/qtquickcontrols2-customize.qdoc b/src/imports/controls/doc/src/qtquickcontrols2-customize.qdoc
index d98b70d1..3e804bd4 100644
--- a/src/imports/controls/doc/src/qtquickcontrols2-customize.qdoc
+++ b/src/imports/controls/doc/src/qtquickcontrols2-customize.qdoc
@@ -548,6 +548,12 @@
\snippet qtquickcontrols2-rangeslider-custom.qml file
+ \section2 Customizing RoundButton
+
+ RoundButton can be customized in the same manner as
+ \l {Customizing Button}{Button}.
+
+
\section2 Customizing ScrollBar
ScrollBar consists of two visual items: \l {Control::background}{background}
diff --git a/src/imports/controls/doc/src/qtquickcontrols2-material.qdoc b/src/imports/controls/doc/src/qtquickcontrols2-material.qdoc
index 74a7ece1..5685a852 100644
--- a/src/imports/controls/doc/src/qtquickcontrols2-material.qdoc
+++ b/src/imports/controls/doc/src/qtquickcontrols2-material.qdoc
@@ -39,6 +39,7 @@
\list
\li \l {material-accent-attached-prop}{\b accent} : color
\li \l {material-background-attached-prop}{\b background} : color
+ \li \l {material-elevation-attached-prop}{\b elevation} : int
\li \l {material-foreground-attached-prop}{\b foreground} : color
\li \l {material-primary-attached-prop}{\b primary} : color
\li \l {material-theme-attached-prop}{\b theme} : enumeration
@@ -280,6 +281,16 @@
\endstyleproperty
+ \styleproperty {Material.elevation} {int} {material-elevation-attached-prop}
+ \target material-elevation-attached-prop
+ This attached property holds the elevation of the control. The higher the
+ elevation, the deeper the shadow. The property can be attached to any control,
+ but not all controls visualize elevation.
+
+ The default value is control-specific.
+
+ \endstyleproperty
+
\styleproperty {Material.foreground} {color} {material-foreground-attached-prop}
\target material-foreground-attached-prop
This attached property holds the foreground color of the theme. The property
diff --git a/src/imports/controls/material/RoundButton.qml b/src/imports/controls/material/RoundButton.qml
new file mode 100644
index 00000000..57f30e30
--- /dev/null
+++ b/src/imports/controls/material/RoundButton.qml
@@ -0,0 +1,115 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.6
+import QtQuick.Templates 2.1 as T
+import QtQuick.Controls.Material 2.1
+import QtQuick.Controls.Material.impl 2.1
+
+T.RoundButton {
+ id: control
+
+ implicitWidth: Math.max(background ? background.implicitWidth : 0,
+ contentItem.implicitWidth + leftPadding + rightPadding)
+ implicitHeight: Math.max(background ? background.implicitHeight : 0,
+ contentItem.implicitHeight + topPadding + bottomPadding)
+ baselineOffset: contentItem.y + contentItem.baselineOffset
+
+ // external vertical padding is 6 (to increase touch area)
+ padding: 12
+
+ hoverEnabled: Qt.styleHints.useHoverEffects
+
+ Material.elevation: flat ? control.down || control.hovered ? 2 : 0
+ : control.down ? 8 : 2
+ Material.background: flat ? "transparent" : undefined
+
+ contentItem: Text {
+ text: control.text
+ font: control.font
+ color: !control.enabled ? control.Material.hintTextColor :
+ control.flat && control.highlighted ? control.Material.accentColor :
+ control.highlighted ? control.Material.primaryHighlightedTextColor : control.Material.primaryTextColor
+ horizontalAlignment: Text.AlignHCenter
+ verticalAlignment: Text.AlignVCenter
+ elide: Text.ElideRight
+ }
+
+ // TODO: Add a proper ripple/ink effect for mouse/touch input and focus state
+ background: Rectangle {
+ implicitWidth: 48
+ implicitHeight: 48
+
+ // external vertical padding is 6 (to increase touch area)
+ x: 6
+ y: 6
+ width: parent.width - 12
+ height: parent.height - 12
+ radius: control.radius
+ color: !control.enabled ? control.Material.buttonDisabledColor
+ : control.checked || control.highlighted ? control.Material.highlightedButtonColor : control.Material.buttonColor
+
+ Rectangle {
+ width: parent.width
+ height: parent.height
+ radius: control.radius
+ visible: control.hovered || control.visualFocus
+ color: control.Material.rippleColor
+ }
+
+ Rectangle {
+ width: parent.width
+ height: parent.height
+ radius: control.radius
+ visible: control.down
+ color: control.Material.rippleColor
+ }
+
+ Behavior on color {
+ ColorAnimation {
+ duration: 400
+ }
+ }
+
+ // The layer is disabled when the button color is transparent so that you can do
+ // Material.background: "transparent" and get a proper flat button without needing
+ // to set Material.elevation as well
+ layer.enabled: control.enabled && control.Material.buttonColor.a > 0
+ layer.effect: ElevationEffect {
+ elevation: control.Material.elevation
+ }
+ }
+}
diff --git a/src/imports/controls/material/TextField.qml b/src/imports/controls/material/TextField.qml
index a6406afa..25811322 100644
--- a/src/imports/controls/material/TextField.qml
+++ b/src/imports/controls/material/TextField.qml
@@ -42,9 +42,11 @@ T.TextField {
id: control
implicitWidth: Math.max(background ? background.implicitWidth : 0,
- placeholder.implicitWidth + leftPadding + rightPadding)
- implicitHeight: Math.max(background ? background.implicitHeight : 0,
- placeholder.implicitHeight + 1 + topPadding + bottomPadding)
+ placeholderText ? placeholder.implicitWidth + leftPadding + rightPadding : 0)
+ || contentWidth + leftPadding + rightPadding
+ implicitHeight: Math.max(contentHeight + topPadding + bottomPadding,
+ background ? background.implicitHeight : 0,
+ placeholder.implicitHeight + topPadding + bottomPadding)
topPadding: 8
bottomPadding: 16
diff --git a/src/imports/controls/material/ToolBar.qml b/src/imports/controls/material/ToolBar.qml
index ce4f64ec..0da814f1 100644
--- a/src/imports/controls/material/ToolBar.qml
+++ b/src/imports/controls/material/ToolBar.qml
@@ -56,7 +56,7 @@ T.ToolBar {
background: Rectangle {
implicitHeight: 48
- color: control.Material.primaryColor
+ color: control.Material.toolBarColor
layer.enabled: control.Material.elevation > 0
layer.effect: ElevationEffect {
diff --git a/src/imports/controls/material/material.pri b/src/imports/controls/material/material.pri
index 437edeee..3170a695 100644
--- a/src/imports/controls/material/material.pri
+++ b/src/imports/controls/material/material.pri
@@ -42,6 +42,7 @@ QML_FILES += \
$$PWD/RadioDelegate.qml \
$$PWD/RadioIndicator.qml \
$$PWD/RangeSlider.qml \
+ $$PWD/RoundButton.qml \
$$PWD/RectangularGlow.qml \
$$PWD/ScrollBar.qml \
$$PWD/ScrollIndicator.qml \
diff --git a/src/imports/controls/material/qquickmaterialstyle.cpp b/src/imports/controls/material/qquickmaterialstyle.cpp
index 76332c51..0e9f31df 100644
--- a/src/imports/controls/material/qquickmaterialstyle.cpp
+++ b/src/imports/controls/material/qquickmaterialstyle.cpp
@@ -706,6 +706,7 @@ void QQuickMaterialStyle::setBackground(const QVariant &var)
m_background = background;
propagateBackground();
emit backgroundChanged();
+ emit paletteChanged();
}
void QQuickMaterialStyle::inheritBackground(uint background, bool custom, bool has)
@@ -854,7 +855,7 @@ QColor QQuickMaterialStyle::buttonColor(bool highlighted) const
QColor color = Qt::transparent;
- if (m_hasBackground) {
+ if (m_explicitBackground) {
color = backgroundColor(shade);
} else if (highlighted) {
color = accentColor(shade);
@@ -950,16 +951,11 @@ QColor QQuickMaterialStyle::scrollBarPressedColor() const
return QColor::fromRgba(m_theme == Light ? 0x80000000 : 0x80FFFFFF);
}
-QColor QQuickMaterialStyle::drawerBackgroundColor() const
-{
- return QColor::fromRgba(dividerColorLight);
-}
-
QColor QQuickMaterialStyle::dialogColor() const
{
- if (!m_hasBackground)
- return QColor::fromRgba(m_theme == Light ? dialogColorLight : dialogColorDark);
- return backgroundColor();
+ if (m_hasBackground)
+ return backgroundColor();
+ return QColor::fromRgba(m_theme == Light ? dialogColorLight : dialogColorDark);
}
QColor QQuickMaterialStyle::backgroundDimColor() const
@@ -974,9 +970,18 @@ QColor QQuickMaterialStyle::listHighlightColor() const
QColor QQuickMaterialStyle::tooltipColor() const
{
+ if (m_explicitBackground)
+ return backgroundColor();
return color(Grey, Shade700);
}
+QColor QQuickMaterialStyle::toolBarColor() const
+{
+ if (m_explicitBackground)
+ return backgroundColor();
+ return primaryColor();
+}
+
QColor QQuickMaterialStyle::toolTextColor() const
{
if (m_hasForeground || m_customPrimary)
diff --git a/src/imports/controls/material/qquickmaterialstyle_p.h b/src/imports/controls/material/qquickmaterialstyle_p.h
index 78ba88da..e6e4fe05 100644
--- a/src/imports/controls/material/qquickmaterialstyle_p.h
+++ b/src/imports/controls/material/qquickmaterialstyle_p.h
@@ -91,11 +91,11 @@ class QQuickMaterialStyle : public QQuickStyleAttached
Q_PROPERTY(QColor scrollBarColor READ scrollBarColor NOTIFY paletteChanged FINAL)
Q_PROPERTY(QColor scrollBarHoveredColor READ scrollBarHoveredColor NOTIFY paletteChanged FINAL)
Q_PROPERTY(QColor scrollBarPressedColor READ scrollBarPressedColor NOTIFY paletteChanged FINAL)
- Q_PROPERTY(QColor drawerBackgroundColor READ drawerBackgroundColor NOTIFY paletteChanged FINAL)
Q_PROPERTY(QColor dialogColor READ dialogColor NOTIFY paletteChanged FINAL)
Q_PROPERTY(QColor backgroundDimColor READ backgroundDimColor NOTIFY paletteChanged FINAL)
Q_PROPERTY(QColor listHighlightColor READ listHighlightColor NOTIFY paletteChanged FINAL)
Q_PROPERTY(QColor tooltipColor READ tooltipColor NOTIFY paletteChanged FINAL)
+ Q_PROPERTY(QColor toolBarColor READ toolBarColor NOTIFY paletteChanged FINAL)
Q_PROPERTY(QColor toolTextColor READ toolTextColor NOTIFY paletteChanged FINAL)
Q_PROPERTY(QColor spinBoxDisabledIconColor READ spinBoxDisabledIconColor NOTIFY paletteChanged FINAL)
@@ -213,11 +213,11 @@ public:
QColor scrollBarColor() const;
QColor scrollBarHoveredColor() const;
QColor scrollBarPressedColor() const;
- QColor drawerBackgroundColor() const;
QColor dialogColor() const;
QColor backgroundDimColor() const;
QColor listHighlightColor() const;
QColor tooltipColor() const;
+ QColor toolBarColor() const;
QColor toolTextColor() const;
QColor spinBoxDisabledIconColor() const;
diff --git a/src/imports/controls/plugins.qmltypes b/src/imports/controls/plugins.qmltypes
index 0700e7bf..a1ca509b 100644
--- a/src/imports/controls/plugins.qmltypes
+++ b/src/imports/controls/plugins.qmltypes
@@ -16,14 +16,14 @@ Module {
name: "QQuickBusyIndicatorRing"
defaultProperty: "data"
prototype: "QQuickItem"
- exports: ["QtQuick.Controls.impl/BusyRing 2.1"]
+ exports: ["QtQuick.Controls.impl/BusyRing 2.0"]
exportMetaObjectRevisions: [0]
}
Component {
name: "QQuickDialRing"
defaultProperty: "data"
prototype: "QQuickPaintedItem"
- exports: ["QtQuick.Controls.impl/DialRing 2.1"]
+ exports: ["QtQuick.Controls.impl/DialRing 2.0"]
exportMetaObjectRevisions: [0]
Property { name: "progress"; type: "double" }
Property { name: "color"; type: "QColor" }
@@ -32,7 +32,7 @@ Module {
name: "QQuickProgressStrip"
defaultProperty: "data"
prototype: "QQuickItem"
- exports: ["QtQuick.Controls.impl/ProgressStrip 2.1"]
+ exports: ["QtQuick.Controls.impl/ProgressStrip 2.0"]
exportMetaObjectRevisions: [0]
Property { name: "indeterminate"; type: "bool" }
Property { name: "progress"; type: "double" }
@@ -89,9 +89,9 @@ Module {
}
Component {
prototype: "QQuickRectangle"
- name: "QtQuick.Controls.impl/CheckIndicator 2.1"
- exports: ["QtQuick.Controls.impl/CheckIndicator 2.1"]
- exportMetaObjectRevisions: [1]
+ name: "QtQuick.Controls.impl/CheckIndicator 2.0"
+ exports: ["QtQuick.Controls.impl/CheckIndicator 2.0"]
+ exportMetaObjectRevisions: [0]
isComposite: true
defaultProperty: "data"
Property { name: "control"; type: "QQuickItem"; isPointer: true }
@@ -105,6 +105,22 @@ Module {
defaultProperty: "data"
}
Component {
+ prototype: "QQuickContainer"
+ name: "QtQuick.Controls/Container 2.0"
+ exports: ["QtQuick.Controls/Container 2.0"]
+ exportMetaObjectRevisions: [0]
+ isComposite: true
+ defaultProperty: "contentData"
+ }
+ Component {
+ prototype: "QQuickControl"
+ name: "QtQuick.Controls/Control 2.0"
+ exports: ["QtQuick.Controls/Control 2.0"]
+ exportMetaObjectRevisions: [0]
+ isComposite: true
+ defaultProperty: "data"
+ }
+ Component {
prototype: "QQuickDial"
name: "QtQuick.Controls/Dial 2.0"
exports: ["QtQuick.Controls/Dial 2.0"]
@@ -185,6 +201,14 @@ Module {
defaultProperty: "data"
}
Component {
+ prototype: "QQuickMenuSeparator"
+ name: "QtQuick.Controls/MenuSeparator 2.1"
+ exports: ["QtQuick.Controls/MenuSeparator 2.1"]
+ exportMetaObjectRevisions: [1]
+ isComposite: true
+ defaultProperty: "data"
+ }
+ Component {
prototype: "QQuickPage"
name: "QtQuick.Controls/Page 2.0"
exports: ["QtQuick.Controls/Page 2.0"]
@@ -242,9 +266,9 @@ Module {
}
Component {
prototype: "QQuickRectangle"
- name: "QtQuick.Controls.impl/RadioIndicator 2.1"
- exports: ["QtQuick.Controls.impl/RadioIndicator 2.1"]
- exportMetaObjectRevisions: [1]
+ name: "QtQuick.Controls.impl/RadioIndicator 2.0"
+ exports: ["QtQuick.Controls.impl/RadioIndicator 2.0"]
+ exportMetaObjectRevisions: [0]
isComposite: true
defaultProperty: "data"
Property { name: "control"; type: "QQuickItem"; isPointer: true }
@@ -258,6 +282,14 @@ Module {
defaultProperty: "data"
}
Component {
+ prototype: "QQuickRoundButton"
+ name: "QtQuick.Controls/RoundButton 2.1"
+ exports: ["QtQuick.Controls/RoundButton 2.1"]
+ exportMetaObjectRevisions: [1]
+ isComposite: true
+ defaultProperty: "data"
+ }
+ Component {
prototype: "QQuickScrollBar"
name: "QtQuick.Controls/ScrollBar 2.0"
exports: ["QtQuick.Controls/ScrollBar 2.0"]
@@ -331,9 +363,9 @@ Module {
}
Component {
prototype: "QQuickItem"
- name: "QtQuick.Controls.impl/SwitchIndicator 2.1"
- exports: ["QtQuick.Controls.impl/SwitchIndicator 2.1"]
- exportMetaObjectRevisions: [1]
+ name: "QtQuick.Controls.impl/SwitchIndicator 2.0"
+ exports: ["QtQuick.Controls.impl/SwitchIndicator 2.0"]
+ exportMetaObjectRevisions: [0]
isComposite: true
defaultProperty: "data"
Property { name: "control"; type: "QQuickItem"; isPointer: true }
@@ -529,11 +561,15 @@ Module {
name: "QQuickComboBox"
defaultProperty: "data"
prototype: "QQuickControl"
- exports: ["QtQuick.Templates/ComboBox 2.0"]
- exportMetaObjectRevisions: [0]
+ exports: [
+ "QtQuick.Templates/ComboBox 2.0",
+ "QtQuick.Templates/ComboBox 2.1"
+ ]
+ exportMetaObjectRevisions: [0, 1]
Property { name: "count"; type: "int"; isReadonly: true }
Property { name: "model"; type: "QVariant" }
Property { name: "delegateModel"; type: "QQmlInstanceModel"; isReadonly: true; isPointer: true }
+ Property { name: "flat"; revision: 1; type: "bool" }
Property { name: "pressed"; type: "bool" }
Property { name: "highlightedIndex"; type: "int"; isReadonly: true }
Property { name: "currentIndex"; type: "int" }
@@ -543,6 +579,7 @@ Module {
Property { name: "delegate"; type: "QQmlComponent"; isPointer: true }
Property { name: "indicator"; type: "QQuickItem"; isPointer: true }
Property { name: "popup"; type: "QQuickPopup"; isPointer: true }
+ Signal { name: "flatChanged"; revision: 1 }
Signal {
name: "activated"
Parameter { name: "index"; type: "int" }
@@ -982,6 +1019,13 @@ Module {
Signal { name: "triggered" }
}
Component {
+ name: "QQuickMenuSeparator"
+ defaultProperty: "data"
+ prototype: "QQuickControl"
+ exports: ["QtQuick.Templates/MenuSeparator 2.1"]
+ exportMetaObjectRevisions: [0]
+ }
+ Component {
name: "QQuickOverlay"
defaultProperty: "data"
prototype: "QQuickItem"
@@ -1202,6 +1246,14 @@ Module {
}
}
Component {
+ name: "QQuickRoundButton"
+ defaultProperty: "data"
+ prototype: "QQuickButton"
+ exports: ["QtQuick.Templates/RoundButton 2.1"]
+ exportMetaObjectRevisions: [1]
+ Property { name: "radius"; type: "double" }
+ }
+ Component {
name: "QQuickScrollBar"
defaultProperty: "data"
prototype: "QQuickControl"
@@ -1333,6 +1385,7 @@ Module {
Signal { name: "activating" }
Signal { name: "deactivated" }
Signal { name: "deactivating" }
+ Signal { name: "removed" }
}
Component {
name: "QQuickStackView"
diff --git a/src/imports/controls/qtquickcontrols2plugin.cpp b/src/imports/controls/qtquickcontrols2plugin.cpp
index 3cd3b8b2..f7ee00a6 100644
--- a/src/imports/controls/qtquickcontrols2plugin.cpp
+++ b/src/imports/controls/qtquickcontrols2plugin.cpp
@@ -87,8 +87,6 @@ void QtQuickControls2Plugin::registerTypes(const char *uri)
qmlRegisterType<QQuickAbstractButton>(uri, 2, 0, "AbstractButton");
qmlRegisterType<QQuickButtonGroup>(uri, 2, 0, "ButtonGroup");
qmlRegisterType<QQuickButtonGroupAttached>();
- qmlRegisterType<QQuickContainer>(uri, 2, 0, "Container");
- qmlRegisterType<QQuickControl>(uri, 2, 0, "Control");
QQuickStylePrivate::init(typeUrl());
const QString style = QQuickStyle::name();
@@ -104,6 +102,8 @@ void QtQuickControls2Plugin::registerTypes(const char *uri)
qmlRegisterType(selector.select(QStringLiteral("CheckBox.qml")), uri, 2, 0, "CheckBox");
qmlRegisterType(selector.select(QStringLiteral("CheckDelegate.qml")), uri, 2, 0, "CheckDelegate");
qmlRegisterType(selector.select(QStringLiteral("ComboBox.qml")), uri, 2, 0, "ComboBox");
+ qmlRegisterType(selector.select(QStringLiteral("Container.qml")), uri, 2, 0, "Container");
+ qmlRegisterType(selector.select(QStringLiteral("Control.qml")), uri, 2, 0, "Control");
qmlRegisterType(selector.select(QStringLiteral("Dial.qml")), uri, 2, 0, "Dial");
qmlRegisterType(selector.select(QStringLiteral("Drawer.qml")), uri, 2, 0, "Drawer");
qmlRegisterType(selector.select(QStringLiteral("Frame.qml")), uri, 2, 0, "Frame");
@@ -144,6 +144,7 @@ void QtQuickControls2Plugin::registerTypes(const char *uri)
qmlRegisterType(selector.select(QStringLiteral("Dialog.qml")), uri, 2, 1, "Dialog");
qmlRegisterType(selector.select(QStringLiteral("DialogButtonBox.qml")), uri, 2, 1, "DialogButtonBox");
qmlRegisterType(selector.select(QStringLiteral("MenuSeparator.qml")), uri, 2, 1, "MenuSeparator");
+ qmlRegisterType(selector.select(QStringLiteral("RoundButton.qml")), uri, 2, 1, "RoundButton");
qmlRegisterType(selector.select(QStringLiteral("ToolSeparator.qml")), uri, 2, 1, "ToolSeparator");
}
diff --git a/src/imports/controls/universal/RoundButton.qml b/src/imports/controls/universal/RoundButton.qml
new file mode 100644
index 00000000..61701099
--- /dev/null
+++ b/src/imports/controls/universal/RoundButton.qml
@@ -0,0 +1,87 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.6
+import QtQuick.Templates 2.1 as T
+import QtQuick.Controls.Universal 2.1
+
+T.RoundButton {
+ id: control
+
+ implicitWidth: Math.max(background ? background.implicitWidth : 0,
+ contentItem.implicitWidth + leftPadding + rightPadding)
+ implicitHeight: Math.max(background ? background.implicitHeight : 0,
+ contentItem.implicitHeight + topPadding + bottomPadding)
+ baselineOffset: contentItem.y + contentItem.baselineOffset
+
+ hoverEnabled: Qt.styleHints.useHoverEffects
+
+ padding: 8
+
+ property bool useSystemFocusVisuals: true
+
+ contentItem: Text {
+ text: control.text
+ font: control.font
+ elide: Text.ElideRight
+ horizontalAlignment: Text.AlignHCenter
+ verticalAlignment: Text.AlignVCenter
+
+ opacity: enabled ? 1.0 : 0.2
+ color: control.Universal.foreground
+ }
+
+ background: Rectangle {
+ implicitWidth: 32
+ implicitHeight: 32
+
+ radius: control.radius
+ visible: !control.flat || control.down || control.checked || control.highlighted
+ color: control.down ? control.Universal.baseMediumLowColor :
+ control.enabled && (control.highlighted || control.checked) ? control.Universal.accent :
+ control.Universal.baseLowColor
+
+ Rectangle {
+ width: parent.width
+ height: parent.height
+ radius: control.radius
+ color: "transparent"
+ visible: control.hovered
+ border.width: 2 // ButtonBorderThemeThickness
+ border.color: control.Universal.baseMediumLowColor
+ }
+ }
+}
diff --git a/src/imports/controls/universal/TextField.qml b/src/imports/controls/universal/TextField.qml
index 88bc4fc9..afa09946 100644
--- a/src/imports/controls/universal/TextField.qml
+++ b/src/imports/controls/universal/TextField.qml
@@ -41,9 +41,9 @@ import QtQuick.Controls.Universal 2.1
T.TextField {
id: control
- implicitWidth: Math.max(contentWidth + leftPadding + rightPadding,
- background ? background.implicitWidth : 0,
- placeholder.implicitWidth + leftPadding + rightPadding)
+ implicitWidth: Math.max(background ? background.implicitWidth : 0,
+ placeholderText ? placeholder.implicitWidth + leftPadding + rightPadding : 0)
+ || contentWidth + leftPadding + rightPadding
implicitHeight: Math.max(contentHeight + topPadding + bottomPadding,
background ? background.implicitHeight : 0,
placeholder.implicitHeight + topPadding + bottomPadding)
diff --git a/src/imports/controls/universal/universal.pri b/src/imports/controls/universal/universal.pri
index 72edbc32..3697a2a6 100644
--- a/src/imports/controls/universal/universal.pri
+++ b/src/imports/controls/universal/universal.pri
@@ -26,6 +26,7 @@ QML_FILES += \
$$PWD/RadioDelegate.qml \
$$PWD/RadioIndicator.qml \
$$PWD/RangeSlider.qml \
+ $$PWD/RoundButton.qml \
$$PWD/ScrollBar.qml \
$$PWD/ScrollIndicator.qml \
$$PWD/Slider.qml \
diff --git a/src/imports/templates/plugins.qmltypes b/src/imports/templates/plugins.qmltypes
index cbcc1fc7..dd991cfe 100644
--- a/src/imports/templates/plugins.qmltypes
+++ b/src/imports/templates/plugins.qmltypes
@@ -144,6 +144,7 @@ Module {
Property { name: "delegate"; type: "QQmlComponent"; isPointer: true }
Property { name: "indicator"; type: "QQuickItem"; isPointer: true }
Property { name: "popup"; type: "QQuickPopup"; isPointer: true }
+ Signal { name: "flatChanged"; revision: 1 }
Signal {
name: "activated"
Parameter { name: "index"; type: "int" }
@@ -583,6 +584,13 @@ Module {
Signal { name: "triggered" }
}
Component {
+ name: "QQuickMenuSeparator"
+ defaultProperty: "data"
+ prototype: "QQuickControl"
+ exports: ["QtQuick.Templates/MenuSeparator 2.1"]
+ exportMetaObjectRevisions: [0]
+ }
+ Component {
name: "QQuickOverlay"
defaultProperty: "data"
prototype: "QQuickItem"
@@ -803,6 +811,14 @@ Module {
}
}
Component {
+ name: "QQuickRoundButton"
+ defaultProperty: "data"
+ prototype: "QQuickButton"
+ exports: ["QtQuick.Templates/RoundButton 2.1"]
+ exportMetaObjectRevisions: [1]
+ Property { name: "radius"; type: "double" }
+ }
+ Component {
name: "QQuickScrollBar"
defaultProperty: "data"
prototype: "QQuickControl"
@@ -934,6 +950,7 @@ Module {
Signal { name: "activating" }
Signal { name: "deactivated" }
Signal { name: "deactivating" }
+ Signal { name: "removed" }
}
Component {
name: "QQuickStackView"
diff --git a/src/imports/templates/qtquicktemplates2plugin.cpp b/src/imports/templates/qtquicktemplates2plugin.cpp
index 67a52d14..6624b019 100644
--- a/src/imports/templates/qtquicktemplates2plugin.cpp
+++ b/src/imports/templates/qtquicktemplates2plugin.cpp
@@ -66,6 +66,7 @@
#include <QtQuickTemplates2/private/qquickradiobutton_p.h>
#include <QtQuickTemplates2/private/qquickradiodelegate_p.h>
#include <QtQuickTemplates2/private/qquickrangeslider_p.h>
+#include <QtQuickTemplates2/private/qquickroundbutton_p.h>
#include <QtQuickTemplates2/private/qquickscrollbar_p.h>
#include <QtQuickTemplates2/private/qquickscrollindicator_p.h>
#include <QtQuickTemplates2/private/qquickslider_p.h>
@@ -186,6 +187,7 @@ void QtQuickTemplates2Plugin::registerTypes(const char *uri)
qmlRegisterType<QQuickMenuSeparator>(uri, 2, 1, "MenuSeparator");
qmlRegisterType<QQuickPopup, 1>(uri, 2, 1, "Popup");
qmlRegisterType<QQuickRangeSlider, 1>(uri, 2, 1, "RangeSlider");
+ qmlRegisterType<QQuickRoundButton, 1>(uri, 2, 1, "RoundButton");
qmlRegisterType<QQuickSlider, 1>(uri, 2, 1, "Slider");
qmlRegisterType<QQuickSpinBox, 1>(uri, 2, 1, "SpinBox");
qmlRegisterType<QQuickStackView, 1>(uri, 2, 1, "StackView");
diff --git a/src/quickcontrols2/qquickstyle.cpp b/src/quickcontrols2/qquickstyle.cpp
index bee837e9..ca5beafe 100644
--- a/src/quickcontrols2/qquickstyle.cpp
+++ b/src/quickcontrols2/qquickstyle.cpp
@@ -109,6 +109,24 @@ struct QQuickStyleSpec
resolve();
}
+ static QString findStyle(const QString &path, const QString &name)
+ {
+ QDir dir(path);
+ if (!dir.exists())
+ return QString();
+
+ if (name.isEmpty())
+ return dir.absolutePath() + QLatin1Char('/');
+
+ const QStringList entries = dir.entryList(QStringList(), QDir::Dirs | QDir::NoDotAndDotDot);
+ for (const QString &entry : entries) {
+ if (entry.compare(name, Qt::CaseInsensitive) == 0)
+ return dir.absoluteFilePath(entry);
+ }
+
+ return QString();
+ }
+
void resolve(const QUrl &baseUrl = QUrl())
{
if (style.isEmpty())
@@ -122,10 +140,12 @@ struct QQuickStyleSpec
}
if (baseUrl.isValid()) {
- if (style.isEmpty())
- style = baseUrl.toString(QUrl::StripTrailingSlash) + QLatin1Char('/');
- else if (!style.contains(QLatin1Char('/')))
- style = baseUrl.toString(QUrl::StripTrailingSlash) + QLatin1Char('/') + style;
+ QString path = QQmlFile::urlToLocalFileOrQrc(baseUrl);
+ QString stylePath = findStyle(path, style);
+ if (!stylePath.isEmpty()) {
+ style = stylePath;
+ resolved = true;
+ }
}
if (QGuiApplication::instance()) {
@@ -134,24 +154,12 @@ struct QQuickStyleSpec
const QStringList importPaths = QQmlEngine().importPathList();
for (const QString &importPath : importPaths) {
- QDir importDir(importPath);
- if (importDir.cd(targetPath)) {
- if (style.isEmpty()) {
- style = importDir.absolutePath() + QLatin1Char('/');
- resolved = true;
- break;
- }
- const QStringList entries = importDir.entryList(QStringList(), QDir::Dirs | QDir::NoDotAndDotDot);
- for (const QString &entry : entries) {
- if (entry.compare(style, Qt::CaseInsensitive) == 0) {
- style = importDir.absoluteFilePath(entry);
- resolved = true;
- break;
- }
- }
- }
- if (resolved)
+ QString stylePath = findStyle(importPath + QLatin1Char('/') + targetPath, style);
+ if (!stylePath.isEmpty()) {
+ style = stylePath;
+ resolved = true;
break;
+ }
}
}
resolved = true;
diff --git a/src/quicktemplates2/qquickapplicationwindow.cpp b/src/quicktemplates2/qquickapplicationwindow.cpp
index af14ba6f..7f466fd7 100644
--- a/src/quicktemplates2/qquickapplicationwindow.cpp
+++ b/src/quicktemplates2/qquickapplicationwindow.cpp
@@ -158,12 +158,6 @@ void QQuickApplicationWindowPrivate::relayout()
content->setWidth(q->width());
content->setHeight(q->height() - hh - fh);
- if (overlay) {
- overlay->setWidth(q->width());
- overlay->setHeight(q->height());
- overlay->stackAfter(content);
- }
-
if (header) {
header->setY(-hh);
QQuickItemPrivate *p = QQuickItemPrivate::get(header);
@@ -489,9 +483,12 @@ QQuickItem *QQuickApplicationWindow::activeFocusControl() const
QQuickOverlay *QQuickApplicationWindow::overlay() const
{
QQuickApplicationWindowPrivate *d = const_cast<QQuickApplicationWindowPrivate *>(d_func());
+ if (!d) // being deleted
+ return nullptr;
+
if (!d->overlay) {
d->overlay = new QQuickOverlay(QQuickWindow::contentItem());
- d->relayout();
+ d->overlay->stackAfter(QQuickApplicationWindow::contentItem());
}
return d->overlay;
}
diff --git a/src/quicktemplates2/qquickbutton.cpp b/src/quicktemplates2/qquickbutton.cpp
index a51e2210..19310713 100644
--- a/src/quicktemplates2/qquickbutton.cpp
+++ b/src/quicktemplates2/qquickbutton.cpp
@@ -35,7 +35,7 @@
****************************************************************************/
#include "qquickbutton_p.h"
-#include "qquickabstractbutton_p_p.h"
+#include "qquickbutton_p_p.h"
#include <QtGui/qpa/qplatformtheme.h>
@@ -91,17 +91,6 @@ QT_BEGIN_NAMESPACE
\sa {Customizing Button}, {Button Controls}
*/
-class QQuickButtonPrivate : public QQuickAbstractButtonPrivate
-{
- Q_DECLARE_PUBLIC(QQuickButton)
-
-public:
- QQuickButtonPrivate();
-
- bool flat;
- bool highlighted;
-};
-
QQuickButtonPrivate::QQuickButtonPrivate() :
flat(false), highlighted(false)
{
@@ -112,6 +101,11 @@ QQuickButton::QQuickButton(QQuickItem *parent) :
{
}
+QQuickButton::QQuickButton(QQuickButtonPrivate &dd, QQuickItem *parent) :
+ QQuickAbstractButton(dd, parent)
+{
+}
+
/*!
\qmlproperty bool QtQuick.Controls::Button::checkable
diff --git a/src/quicktemplates2/qquickbutton_p.h b/src/quicktemplates2/qquickbutton_p.h
index fafce150..95f94f10 100644
--- a/src/quicktemplates2/qquickbutton_p.h
+++ b/src/quicktemplates2/qquickbutton_p.h
@@ -78,6 +78,8 @@ Q_SIGNALS:
void flatChanged();
protected:
+ QQuickButton(QQuickButtonPrivate &dd, QQuickItem *parent);
+
void checkableChange() override;
void autoRepeatChange() override;
diff --git a/src/quicktemplates2/qquickbutton_p_p.h b/src/quicktemplates2/qquickbutton_p_p.h
new file mode 100644
index 00000000..86663e9e
--- /dev/null
+++ b/src/quicktemplates2/qquickbutton_p_p.h
@@ -0,0 +1,68 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QQUICKBUTTON_P_P_H
+#define QQUICKBUTTON_P_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtQuickTemplates2/private/qquickabstractbutton_p_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class QQuickButtonPrivate : public QQuickAbstractButtonPrivate
+{
+ Q_DECLARE_PUBLIC(QQuickButton)
+
+public:
+ QQuickButtonPrivate();
+
+ bool flat;
+ bool highlighted;
+};
+
+QT_END_NAMESPACE
+
+#endif // QQUICKBUTTON_P_P_H
diff --git a/src/quicktemplates2/qquickdrawer.cpp b/src/quicktemplates2/qquickdrawer.cpp
index e2e6c84e..a64b5f4e 100644
--- a/src/quicktemplates2/qquickdrawer.cpp
+++ b/src/quicktemplates2/qquickdrawer.cpp
@@ -35,8 +35,7 @@
****************************************************************************/
#include "qquickdrawer_p.h"
-#include "qquickpopup_p_p.h"
-#include "qquickvelocitycalculator_p_p.h"
+#include "qquickdrawer_p_p.h"
#include <QtGui/qstylehints.h>
#include <QtGui/private/qguiapplication_p.h>
@@ -114,33 +113,11 @@ QT_BEGIN_NAMESPACE
\sa SwipeView, {Customizing Drawer}, {Navigation Controls}, {Popup Controls}
*/
-class QQuickDrawerPrivate : public QQuickPopupPrivate
+QQuickDrawerPrivate::QQuickDrawerPrivate()
+ : edge(Qt::LeftEdge), offset(0), position(0),
+ dragMargin(QGuiApplication::styleHints()->startDragDistance())
{
- Q_DECLARE_PUBLIC(QQuickDrawer)
-
-public:
- QQuickDrawerPrivate() : edge(Qt::LeftEdge), offset(0), position(0),
- dragMargin(QGuiApplication::styleHints()->startDragDistance()) { }
-
- qreal positionAt(const QPointF &point) const;
- void reposition() override;
-
- bool handleMousePressEvent(QQuickItem *item, QMouseEvent *event);
- bool handleMouseMoveEvent(QQuickItem *item, QMouseEvent *event);
- bool handleMouseReleaseEvent(QQuickItem *item, QMouseEvent *event);
-
- void prepareEnterTransition(bool notify = true) override;
- void prepareExitTransition() override;
- void finalizeEnterTransition() override;
- void finalizeExitTransition(bool hide = true) override;
-
- Qt::Edge edge;
- qreal offset;
- qreal position;
- qreal dragMargin;
- QPointF pressPoint;
- QQuickVelocityCalculator velocityCalculator;
-};
+}
qreal QQuickDrawerPrivate::positionAt(const QPointF &point) const
{
@@ -191,100 +168,94 @@ static bool dragOverThreshold(qreal d, Qt::Axis axis, QMouseEvent *event, int th
return QQuickWindowPrivate::dragOverThreshold(d, axis, event, threshold);
}
-bool QQuickDrawerPrivate::handleMousePressEvent(QQuickItem *item, QMouseEvent *event)
+bool QQuickDrawerPrivate::startDrag(QQuickWindow *window, QMouseEvent *event)
{
- pressPoint = event->windowPos();
- offset = 0;
-
- QQuickWindow *window = item->window();
- if (!window)
+ if (!window || dragMargin < 0.0 || qFuzzyIsNull(dragMargin))
return false;
- if (qFuzzyIsNull(position)) {
- // only accept pressing at drag margins when fully closed
- switch (edge) {
- case Qt::LeftEdge:
- event->setAccepted(dragMargin > 0 && !dragOverThreshold(event->windowPos().x(), Qt::XAxis, event, dragMargin));
- break;
- case Qt::RightEdge:
- event->setAccepted(dragMargin > 0 && !dragOverThreshold(window->width() - event->windowPos().x(), Qt::XAxis, event, dragMargin));
- break;
- case Qt::TopEdge:
- event->setAccepted(dragMargin > 0 && !dragOverThreshold(event->windowPos().y(), Qt::YAxis, event, dragMargin));
- break;
- case Qt::BottomEdge:
- event->setAccepted(dragMargin > 0 && !dragOverThreshold(window->height() - event->windowPos().y(), Qt::YAxis, event, dragMargin));
- break;
- }
- } else {
- if (modal)
- event->setAccepted(item->isAncestorOf(popupItem));
- else
- event->setAccepted(false);
+ bool drag = false;
+ switch (edge) {
+ case Qt::LeftEdge:
+ drag = !dragOverThreshold(event->windowPos().x(), Qt::XAxis, event, dragMargin);
+ break;
+ case Qt::RightEdge:
+ drag = !dragOverThreshold(window->width() - event->windowPos().x(), Qt::XAxis, event, dragMargin);
+ break;
+ case Qt::TopEdge:
+ drag = !dragOverThreshold(event->windowPos().y(), Qt::YAxis, event, dragMargin);
+ break;
+ case Qt::BottomEdge:
+ drag = !dragOverThreshold(window->height() - event->windowPos().y(), Qt::YAxis, event, dragMargin);
+ break;
+ default:
+ break;
}
- velocityCalculator.startMeasuring(pressPoint, event->timestamp());
+ if (drag) {
+ prepareEnterTransition();
+ reposition();
+ handleMousePressEvent(window->contentItem(), event);
+ }
- return event->isAccepted();
+ return drag;
}
-bool QQuickDrawerPrivate::handleMouseMoveEvent(QQuickItem *item, QMouseEvent *event)
+bool QQuickDrawerPrivate::grabMouse(QMouseEvent *event)
{
Q_Q(QQuickDrawer);
- QQuickWindow *window = item->window();
- if (!window)
+ if (!window || popupItem->keepMouseGrab())
return false;
- QPointF movePoint = event->windowPos();
-
- if (!popupItem->keepMouseGrab()) {
- // Flickable uses a hard-coded threshold of 15 for flicking, and
- // QStyleHints::startDragDistance for dragging. Drawer uses a bit
- // larger threshold to avoid being too eager to steal touch (QTBUG-50045)
- int threshold = qMax(20, QGuiApplication::styleHints()->startDragDistance() + 5);
- bool overThreshold = false;
- if (position > 0 || dragMargin > 0) {
- if (edge == Qt::LeftEdge || edge == Qt::RightEdge)
- overThreshold = dragOverThreshold(movePoint.x() - pressPoint.x(), Qt::XAxis, event, threshold);
- else
- overThreshold = dragOverThreshold(movePoint.y() - pressPoint.y(), Qt::YAxis, event, threshold);
- }
-
- // Don't be too eager to steal presses outside the drawer (QTBUG-53929)
- if (overThreshold && qFuzzyCompare(position, qreal(1.0)) && !popupItem->contains(popupItem->mapFromScene(movePoint))) {
- if (edge == Qt::LeftEdge || edge == Qt::RightEdge)
- overThreshold = qAbs(movePoint.x() - q->width()) < dragMargin;
- else
- overThreshold = qAbs(movePoint.y() - q->height()) < dragMargin;
- }
+ const QPointF movePoint = event->windowPos();
- if (overThreshold) {
- QQuickItem *grabber = window->mouseGrabberItem();
- if (!grabber || !grabber->keepMouseGrab()) {
- popupItem->grabMouse();
- popupItem->setKeepMouseGrab(overThreshold);
- offset = qMin<qreal>(0.0, positionAt(movePoint) - position);
- }
- }
+ // Flickable uses a hard-coded threshold of 15 for flicking, and
+ // QStyleHints::startDragDistance for dragging. Drawer uses a bit
+ // larger threshold to avoid being too eager to steal touch (QTBUG-50045)
+ const int threshold = qMax(20, QGuiApplication::styleHints()->startDragDistance() + 5);
+ bool overThreshold = false;
+ if (position > 0 || dragMargin > 0) {
+ if (edge == Qt::LeftEdge || edge == Qt::RightEdge)
+ overThreshold = dragOverThreshold(movePoint.x() - pressPoint.x(), Qt::XAxis, event, threshold);
+ else
+ overThreshold = dragOverThreshold(movePoint.y() - pressPoint.y(), Qt::YAxis, event, threshold);
}
- if (popupItem->keepMouseGrab())
- q->setPosition(positionAt(movePoint) - offset);
- event->accept();
+ // Don't be too eager to steal presses outside the drawer (QTBUG-53929)
+ if (overThreshold && qFuzzyCompare(position, qreal(1.0)) && !popupItem->contains(popupItem->mapFromScene(movePoint))) {
+ if (edge == Qt::LeftEdge || edge == Qt::RightEdge)
+ overThreshold = qAbs(movePoint.x() - q->width()) < dragMargin;
+ else
+ overThreshold = qAbs(movePoint.y() - q->height()) < dragMargin;
+ }
- return popupItem->keepMouseGrab();
+ return overThreshold;
}
static const qreal openCloseVelocityThreshold = 300;
-bool QQuickDrawerPrivate::handleMouseReleaseEvent(QQuickItem *item, QMouseEvent *event)
+bool QQuickDrawerPrivate::ungrabMouse(QMouseEvent *event)
{
- Q_UNUSED(item);
-
bool wasGrabbed = popupItem->keepMouseGrab();
if (wasGrabbed) {
- velocityCalculator.stopMeasuring(event->pos(), event->timestamp());
- const qreal velocity = velocityCalculator.velocity().x();
+ const QPointF releasePoint = event->windowPos();
+ velocityCalculator.stopMeasuring(releasePoint, event->timestamp());
+
+ qreal velocity = 0;
+ if (edge == Qt::LeftEdge || edge == Qt::RightEdge)
+ velocity = velocityCalculator.velocity().x();
+ else
+ velocity = velocityCalculator.velocity().y();
+
+ // the velocity is calculated so that swipes from left to right
+ // and top to bottom have positive velocity, and swipes from right
+ // to left and bottom to top have negative velocity.
+ //
+ // - top/left edge: positive velocity opens, negative velocity closes
+ // - bottom/right edge: negative velocity opens, positive velocity closes
+ //
+ // => invert the velocity for bottom and right edges, for the threshold comparison below
+ if (edge == Qt::RightEdge || edge == Qt::BottomEdge)
+ velocity = -velocity;
if (position > 0.7 || velocity > openCloseVelocityThreshold) {
transitionManager.transitionEnter();
@@ -293,35 +264,79 @@ bool QQuickDrawerPrivate::handleMouseReleaseEvent(QQuickItem *item, QMouseEvent
} else {
switch (edge) {
case Qt::LeftEdge:
- if (event->x() - pressPoint.x() > 0)
+ if (releasePoint.x() - pressPoint.x() > 0)
transitionManager.transitionEnter();
else
transitionManager.transitionExit();
break;
case Qt::RightEdge:
- if (event->x() - pressPoint.x() < 0)
+ if (releasePoint.x() - pressPoint.x() < 0)
transitionManager.transitionEnter();
else
transitionManager.transitionExit();
break;
case Qt::TopEdge:
- if (event->y() - pressPoint.y() > 0)
+ if (releasePoint.y() - pressPoint.y() > 0)
transitionManager.transitionEnter();
else
transitionManager.transitionExit();
break;
case Qt::BottomEdge:
- if (event->y() - pressPoint.y() < 0)
+ if (releasePoint.y() - pressPoint.y() < 0)
transitionManager.transitionEnter();
else
transitionManager.transitionExit();
break;
}
}
- popupItem->setKeepMouseGrab(false);
}
+ return wasGrabbed;
+}
+
+bool QQuickDrawerPrivate::handleMousePressEvent(QQuickItem *item, QMouseEvent *event)
+{
+ offset = 0;
+ 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));
+ return event->isAccepted();
+}
+
+bool QQuickDrawerPrivate::handleMouseMoveEvent(QQuickItem *item, QMouseEvent *event)
+{
+ Q_Q(QQuickDrawer);
+ Q_UNUSED(item);
+
+ const QPointF movePoint = event->windowPos();
+
+ if (grabMouse(event)) {
+ QQuickItem *grabber = window->mouseGrabberItem();
+ if (!grabber || !grabber->keepMouseGrab()) {
+ popupItem->grabMouse();
+ popupItem->setKeepMouseGrab(true);
+ offset = qMin<qreal>(0.0, positionAt(movePoint) - position);
+ }
+ }
+
+ if (popupItem->keepMouseGrab())
+ q->setPosition(positionAt(movePoint) - offset);
+ event->accept();
+
+ return popupItem->keepMouseGrab();
+}
+
+bool QQuickDrawerPrivate::handleMouseReleaseEvent(QQuickItem *item, QMouseEvent *event)
+{
+ Q_UNUSED(item);
+
+ const bool wasGrabbed = ungrabMouse(event);
+
+ popupItem->setKeepMouseGrab(false);
pressPoint = QPoint();
event->accept();
+
return wasGrabbed;
}
@@ -345,28 +360,18 @@ static QList<QQuickStateAction> prepareTransition(QQuickDrawer *drawer, QQuickTr
return actions;
}
-void QQuickDrawerPrivate::prepareEnterTransition(bool notify)
+bool QQuickDrawerPrivate::prepareEnterTransition()
{
Q_Q(QQuickDrawer);
enterActions = prepareTransition(q, enter, 1.0);
- QQuickPopupPrivate::prepareEnterTransition(notify);
+ return QQuickPopupPrivate::prepareEnterTransition();
}
-void QQuickDrawerPrivate::prepareExitTransition()
+bool QQuickDrawerPrivate::prepareExitTransition()
{
Q_Q(QQuickDrawer);
exitActions = prepareTransition(q, exit, 0.0);
- QQuickPopupPrivate::prepareExitTransition();
-}
-
-void QQuickDrawerPrivate::finalizeEnterTransition()
-{
- QQuickPopupPrivate::finalizeEnterTransition();
-}
-
-void QQuickDrawerPrivate::finalizeExitTransition(bool hide)
-{
- QQuickPopupPrivate::finalizeExitTransition(hide = false);
+ return QQuickPopupPrivate::prepareExitTransition();
}
QQuickDrawer::QQuickDrawer(QObject *parent) :
@@ -430,12 +435,8 @@ void QQuickDrawer::setPosition(qreal position)
d->position = position;
if (isComponentComplete())
d->reposition();
- if (d->dimmer) {
+ if (d->dimmer)
d->dimmer->setOpacity(position);
- // TODO: check QStyleHints::useHoverEffects in Qt 5.8
- d->dimmer->setAcceptHoverEvents(d->modal && position > 0.0);
- // d->dimmer->setAcceptHoverEvents(d->modal && position > 0.0 && QGuiApplication::styleHints()->useHoverEffects());
- }
emit positionChanged();
}
@@ -530,15 +531,4 @@ bool QQuickDrawer::overlayEvent(QQuickItem *item, QEvent *event)
}
}
-void QQuickDrawer::componentComplete()
-{
- Q_D(QQuickDrawer);
- QQuickPopup::componentComplete();
- if (d->window) {
- bool notify = false;
- d->prepareEnterTransition(notify);
- d->reposition();
- }
-}
-
QT_END_NAMESPACE
diff --git a/src/quicktemplates2/qquickdrawer_p.h b/src/quicktemplates2/qquickdrawer_p.h
index 23c5c2ab..e694e27b 100644
--- a/src/quicktemplates2/qquickdrawer_p.h
+++ b/src/quicktemplates2/qquickdrawer_p.h
@@ -87,8 +87,6 @@ protected:
void mouseUngrabEvent() override;
bool overlayEvent(QQuickItem *item, QEvent *event) override;
- void componentComplete() override;
-
private:
Q_DISABLE_COPY(QQuickDrawer)
Q_DECLARE_PRIVATE(QQuickDrawer)
diff --git a/src/quicktemplates2/qquickdrawer_p_p.h b/src/quicktemplates2/qquickdrawer_p_p.h
new file mode 100644
index 00000000..f14c36dd
--- /dev/null
+++ b/src/quicktemplates2/qquickdrawer_p_p.h
@@ -0,0 +1,93 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QQUICKDRAWER_P_P_H
+#define QQUICKDRAWER_P_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qquickdrawer_p.h"
+#include "qquickpopup_p_p.h"
+#include "qquickvelocitycalculator_p_p.h"
+
+QT_BEGIN_NAMESPACE
+
+class QQuickDrawerPrivate : public QQuickPopupPrivate
+{
+ Q_DECLARE_PUBLIC(QQuickDrawer)
+
+public:
+ QQuickDrawerPrivate();
+
+ static QQuickDrawerPrivate *get(QQuickDrawer *drawer)
+ {
+ return drawer->d_func();
+ }
+
+ qreal positionAt(const QPointF &point) const;
+ void reposition() override;
+
+ bool startDrag(QQuickWindow *window, QMouseEvent *event);
+ bool grabMouse(QMouseEvent *event);
+ bool ungrabMouse(QMouseEvent *event);
+
+ bool handleMousePressEvent(QQuickItem *item, QMouseEvent *event);
+ bool handleMouseMoveEvent(QQuickItem *item, QMouseEvent *event);
+ bool handleMouseReleaseEvent(QQuickItem *item, QMouseEvent *event);
+
+ bool prepareEnterTransition() override;
+ bool prepareExitTransition() override;
+
+ Qt::Edge edge;
+ qreal offset;
+ qreal position;
+ qreal dragMargin;
+ QPointF pressPoint;
+ QQuickVelocityCalculator velocityCalculator;
+};
+
+QT_END_NAMESPACE
+
+#endif // QQUICKDRAWER_P_P_H
diff --git a/src/quicktemplates2/qquickoverlay.cpp b/src/quicktemplates2/qquickoverlay.cpp
index 850de875..172307e1 100644
--- a/src/quicktemplates2/qquickoverlay.cpp
+++ b/src/quicktemplates2/qquickoverlay.cpp
@@ -35,39 +35,17 @@
****************************************************************************/
#include "qquickoverlay_p.h"
+#include "qquickoverlay_p_p.h"
#include "qquickpopup_p_p.h"
-#include "qquickdrawer_p.h"
+#include "qquickdrawer_p_p.h"
+#include "qquickapplicationwindow_p.h"
#include <QtQml/qqmlinfo.h>
#include <QtQml/qqmlproperty.h>
#include <QtQml/qqmlcomponent.h>
-#include <QtQuick/private/qquickitem_p.h>
+#include <algorithm>
QT_BEGIN_NAMESPACE
-class QQuickOverlayPrivate : public QQuickItemPrivate
-{
- Q_DECLARE_PUBLIC(QQuickOverlay)
-
-public:
- QQuickOverlayPrivate();
-
- void popupAboutToShow();
- void popupAboutToHide();
-
- void createOverlay(QQuickPopup *popup);
- void destroyOverlay(QQuickPopup *popup);
- void resizeOverlay(QQuickPopup *popup);
-
- QVector<QQuickPopup *> stackingOrderPopups() const;
-
- QQmlComponent *modal;
- QQmlComponent *modeless;
- QVector<QQuickDrawer *> drawers;
- QVector<QQuickPopup *> popups;
- QPointer<QQuickPopup> mouseGrabberPopup;
- int modalPopups;
-};
-
void QQuickOverlayPrivate::popupAboutToShow()
{
Q_Q(QQuickOverlay);
@@ -96,27 +74,35 @@ void QQuickOverlayPrivate::popupAboutToHide()
static QQuickItem *createDimmer(QQmlComponent *component, QQuickPopup *popup, QQuickItem *parent)
{
- if (!component)
- return nullptr;
+ QQuickItem *item = nullptr;
+ if (component) {
+ QQmlContext *creationContext = component->creationContext();
+ if (!creationContext)
+ creationContext = qmlContext(parent);
+ QQmlContext *context = new QQmlContext(creationContext);
+ context->setContextObject(popup);
+ item = qobject_cast<QQuickItem*>(component->beginCreate(context));
+ }
+
+ // when there is no overlay component available (with plain QQuickWindow),
+ // use a plain QQuickItem as a fallback to block hover events
+ if (!item && popup->isModal())
+ item = new QQuickItem;
- QQmlContext *creationContext = component->creationContext();
- if (!creationContext)
- creationContext = qmlContext(parent);
- QQmlContext *context = new QQmlContext(creationContext);
- context->setContextObject(popup);
- QQuickItem *item = qobject_cast<QQuickItem*>(component->beginCreate(context));
if (item) {
- item->setOpacity(0.0);
+ item->setOpacity(popup->isVisible() ? 1.0 : 0.0);
item->setParentItem(parent);
item->stackBefore(popup->popupItem());
item->setZ(popup->z());
- if (popup->isModal() && !qobject_cast<QQuickDrawer *>(popup)) {
+ if (popup->isModal()) {
+ item->setAcceptedMouseButtons(Qt::AllButtons);
// TODO: switch to QStyleHints::useHoverEffects in Qt 5.8
item->setAcceptHoverEvents(true);
// item->setAcceptHoverEvents(QGuiApplication::styleHints()->useHoverEffects());
// connect(QGuiApplication::styleHints(), &QStyleHints::useHoverEffectsChanged, item, &QQuickItem::setAcceptHoverEvents);
}
- component->completeCreate();
+ if (component)
+ component->completeCreate();
}
return item;
}
@@ -150,6 +136,18 @@ void QQuickOverlayPrivate::resizeOverlay(QQuickPopup *popup)
}
}
+void QQuickOverlayPrivate::toggleOverlay()
+{
+ Q_Q(QQuickOverlay);
+ QQuickPopup *popup = qobject_cast<QQuickPopup *>(q->sender());
+ if (!popup)
+ return;
+
+ destroyOverlay(popup);
+ if (popup->dim())
+ createOverlay(popup);
+}
+
QVector<QQuickPopup *> QQuickOverlayPrivate::stackingOrderPopups() const
{
const QList<QQuickItem *> children = paintOrderChildItems();
@@ -166,20 +164,65 @@ QVector<QQuickPopup *> QQuickOverlayPrivate::stackingOrderPopups() const
return popups;
}
+QVector<QQuickDrawer *> QQuickOverlayPrivate::stackingOrderDrawers() const
+{
+ QVector<QQuickDrawer *> sorted(allDrawers);
+ std::sort(sorted.begin(), sorted.end(), [](const QQuickDrawer *one, const QQuickDrawer *another) {
+ return one->z() > another->z();
+ });
+ return sorted;
+}
+
+void QQuickOverlayPrivate::itemGeometryChanged(QQuickItem *item, QQuickGeometryChange, const QRectF &)
+{
+ Q_Q(QQuickOverlay);
+ q->setSize(QSizeF(item->width(), item->height()));
+}
+
QQuickOverlayPrivate::QQuickOverlayPrivate() :
modal(nullptr),
- modeless(nullptr),
- modalPopups(0)
+ modeless(nullptr)
{
}
+void QQuickOverlayPrivate::addPopup(QQuickPopup *popup)
+{
+ Q_Q(QQuickOverlay);
+ allPopups += popup;
+ if (QQuickDrawer *drawer = qobject_cast<QQuickDrawer *>(popup)) {
+ allDrawers += drawer;
+ q->setVisible(!allDrawers.isEmpty() || !q->childItems().isEmpty());
+ }
+}
+
+void QQuickOverlayPrivate::removePopup(QQuickPopup *popup)
+{
+ Q_Q(QQuickOverlay);
+ allPopups.removeOne(popup);
+ if (allDrawers.removeOne(static_cast<QQuickDrawer *>(popup)))
+ q->setVisible(!allDrawers.isEmpty() || !q->childItems().isEmpty());
+}
+
QQuickOverlay::QQuickOverlay(QQuickItem *parent)
: QQuickItem(*(new QQuickOverlayPrivate), parent)
{
+ Q_D(QQuickOverlay);
setZ(1000001); // DefaultWindowDecoration+1
setAcceptedMouseButtons(Qt::AllButtons);
setFiltersChildMouseEvents(true);
setVisible(false);
+
+ if (parent) {
+ setSize(QSizeF(parent->width(), parent->height()));
+ QQuickItemPrivate::get(parent)->addItemChangeListener(d, QQuickItemPrivate::Geometry);
+ }
+}
+
+QQuickOverlay::~QQuickOverlay()
+{
+ Q_D(QQuickOverlay);
+ if (QQuickItem *parent = parentItem())
+ QQuickItemPrivate::get(parent)->removeItemChangeListener(d, QQuickItemPrivate::Geometry);
}
QQmlComponent *QQuickOverlay::modal() const
@@ -216,6 +259,29 @@ void QQuickOverlay::setModeless(QQmlComponent *modeless)
emit modelessChanged();
}
+QQuickOverlay *QQuickOverlay::overlay(QQuickWindow *window)
+{
+ if (!window)
+ return nullptr;
+
+ QQuickApplicationWindow *applicationWindow = qobject_cast<QQuickApplicationWindow *>(window);
+ if (applicationWindow)
+ return applicationWindow->overlay();
+
+ const char *name = "_q_QQuickOverlay";
+ QQuickOverlay *overlay = window->property(name).value<QQuickOverlay *>();
+ if (!overlay) {
+ QQuickItem *content = window->contentItem();
+ // Do not re-create the overlay if the window is being destroyed
+ // and thus, its content item no longer has a window associated.
+ if (content->window()) {
+ overlay = new QQuickOverlay(window->contentItem());
+ window->setProperty(name, QVariant::fromValue(overlay));
+ }
+ }
+ return overlay;
+}
+
void QQuickOverlay::itemChange(ItemChange change, const ItemChangeData &data)
{
Q_D(QQuickOverlay);
@@ -224,37 +290,25 @@ void QQuickOverlay::itemChange(ItemChange change, const ItemChangeData &data)
QQuickPopup *popup = nullptr;
if (change == ItemChildAddedChange || change == ItemChildRemovedChange) {
popup = qobject_cast<QQuickPopup *>(data.item->parent());
- setVisible(!childItems().isEmpty());
+ setVisible(!d->allDrawers.isEmpty() || !childItems().isEmpty());
}
if (!popup)
return;
if (change == ItemChildAddedChange) {
- d->popups.append(popup);
if (popup->dim())
d->createOverlay(popup);
-
- QQuickDrawer *drawer = qobject_cast<QQuickDrawer *>(popup);
- if (drawer) {
- d->drawers.append(drawer);
- } else {
- if (popup->isModal())
- ++d->modalPopups;
-
+ QObjectPrivate::connect(popup, &QQuickPopup::dimChanged, d, &QQuickOverlayPrivate::toggleOverlay);
+ QObjectPrivate::connect(popup, &QQuickPopup::modalChanged, d, &QQuickOverlayPrivate::toggleOverlay);
+ if (!qobject_cast<QQuickDrawer *>(popup)) {
QObjectPrivate::connect(popup, &QQuickPopup::aboutToShow, d, &QQuickOverlayPrivate::popupAboutToShow);
QObjectPrivate::connect(popup, &QQuickPopup::aboutToHide, d, &QQuickOverlayPrivate::popupAboutToHide);
}
} else if (change == ItemChildRemovedChange) {
- d->popups.removeOne(popup);
d->destroyOverlay(popup);
-
- QQuickDrawer *drawer = qobject_cast<QQuickDrawer *>(popup);
- if (drawer) {
- d->drawers.removeOne(drawer);
- } else {
- if (popup->isModal())
- --d->modalPopups;
-
+ QObjectPrivate::disconnect(popup, &QQuickPopup::dimChanged, d, &QQuickOverlayPrivate::toggleOverlay);
+ QObjectPrivate::disconnect(popup, &QQuickPopup::modalChanged, d, &QQuickOverlayPrivate::toggleOverlay);
+ if (!qobject_cast<QQuickDrawer *>(popup)) {
QObjectPrivate::disconnect(popup, &QQuickPopup::aboutToShow, d, &QQuickOverlayPrivate::popupAboutToShow);
QObjectPrivate::disconnect(popup, &QQuickPopup::aboutToHide, d, &QQuickOverlayPrivate::popupAboutToHide);
}
@@ -265,79 +319,86 @@ void QQuickOverlay::geometryChanged(const QRectF &newGeometry, const QRectF &old
{
Q_D(QQuickOverlay);
QQuickItem::geometryChanged(newGeometry, oldGeometry);
- for (QQuickPopup *popup : d->popups)
+ for (QQuickPopup *popup : qAsConst(d->allPopups))
d->resizeOverlay(popup);
}
-bool QQuickOverlay::event(QEvent *event)
+void QQuickOverlay::mousePressEvent(QMouseEvent *event)
{
Q_D(QQuickOverlay);
- switch (event->type()) {
- case QEvent::MouseButtonPress: {
- emit pressed();
+ emit pressed();
+
+ if (!d->allDrawers.isEmpty()) {
+ // the overlay background was pressed, so there are no modal popups open.
+ // test if the press point lands on any drawer's drag margin
+
+ const QVector<QQuickDrawer *> drawers = d->stackingOrderDrawers();
+ for (QQuickDrawer *drawer : drawers) {
+ QQuickDrawerPrivate *p = QQuickDrawerPrivate::get(drawer);
+ if (p->startDrag(window(), event)) {
+ d->mouseGrabberPopup = drawer;
+ return;
+ }
+ }
+ }
+
+ if (!d->mouseGrabberPopup) {
const auto popups = d->stackingOrderPopups();
for (QQuickPopup *popup : popups) {
if (popup->overlayEvent(this, event)) {
d->mouseGrabberPopup = popup;
- return true;
+ return;
}
}
- break;
}
- case QEvent::MouseMove:
- if (d->mouseGrabberPopup) {
- if (d->mouseGrabberPopup->overlayEvent(this, event))
- return true;
- } else {
- const auto popups = d->stackingOrderPopups();
- for (QQuickPopup *popup : popups) {
- if (popup->overlayEvent(this, event))
- return true;
- }
- }
- break;
- case QEvent::MouseButtonRelease:
- emit released();
- if (d->mouseGrabberPopup) {
- QQuickPopup *grabber = d->mouseGrabberPopup;
- d->mouseGrabberPopup = nullptr;
- if (grabber->overlayEvent(this, event))
- return true;
- } else {
- const auto popups = d->stackingOrderPopups();
- for (QQuickPopup *popup : popups) {
- if (popup->overlayEvent(this, event))
- return true;
- }
+
+ event->ignore();
+}
+
+void QQuickOverlay::mouseMoveEvent(QMouseEvent *event)
+{
+ Q_D(QQuickOverlay);
+ if (d->mouseGrabberPopup)
+ d->mouseGrabberPopup->overlayEvent(this, event);
+}
+
+void QQuickOverlay::mouseReleaseEvent(QMouseEvent *event)
+{
+ Q_D(QQuickOverlay);
+ emit released();
+
+ if (d->mouseGrabberPopup) {
+ d->mouseGrabberPopup->overlayEvent(this, event);
+ d->mouseGrabberPopup = nullptr;
+ } else {
+ const auto popups = d->stackingOrderPopups();
+ for (QQuickPopup *popup : popups) {
+ if (popup->overlayEvent(this, event))
+ break;
}
- break;
- default:
- break;
}
-
- return QQuickItem::event(event);
}
bool QQuickOverlay::childMouseEventFilter(QQuickItem *item, QEvent *event)
{
Q_D(QQuickOverlay);
- if (d->modalPopups == 0)
- return false;
- // TODO Filter touch events
- if (event->type() != QEvent::MouseButtonPress)
- return false;
- while (item->parentItem() != this)
- item = item->parentItem();
-
- const auto popups = d->stackingOrderPopups();
- for (QQuickPopup *popup : popups) {
- if (popup->popupItem() == item)
- break;
-
- if (popup->overlayEvent(item, event))
- return true;
+ for (QQuickPopup *popup : qAsConst(d->allPopups)) {
+ QQuickItem *dimmer = QQuickPopupPrivate::get(popup)->dimmer;
+ if (item == dimmer) {
+ switch (event->type()) {
+ case QEvent::MouseButtonPress:
+ emit pressed();
+ return popup->overlayEvent(item, event);
+ case QEvent::MouseMove:
+ return popup->overlayEvent(item, event);
+ case QEvent::MouseButtonRelease:
+ emit released();
+ return popup->overlayEvent(item, event);
+ default:
+ break;
+ }
+ }
}
-
return false;
}
diff --git a/src/quicktemplates2/qquickoverlay_p.h b/src/quicktemplates2/qquickoverlay_p.h
index 99d7ba75..07f7daec 100644
--- a/src/quicktemplates2/qquickoverlay_p.h
+++ b/src/quicktemplates2/qquickoverlay_p.h
@@ -64,6 +64,7 @@ class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickOverlay : public QQuickItem
public:
explicit QQuickOverlay(QQuickItem *parent = nullptr);
+ ~QQuickOverlay();
QQmlComponent *modal() const;
void setModal(QQmlComponent *modal);
@@ -71,6 +72,8 @@ public:
QQmlComponent *modeless() const;
void setModeless(QQmlComponent *modeless);
+ static QQuickOverlay *overlay(QQuickWindow *window);
+
Q_SIGNALS:
void modalChanged();
void modelessChanged();
@@ -81,7 +84,9 @@ protected:
void itemChange(ItemChange change, const ItemChangeData &data) override;
void geometryChanged(const QRectF &oldGeometry, const QRectF &newGeometry) override;
- bool event(QEvent *event) override;
+ void mousePressEvent(QMouseEvent *event) override;
+ void mouseMoveEvent(QMouseEvent *event) override;
+ void mouseReleaseEvent(QMouseEvent *event) override;
bool childMouseEventFilter(QQuickItem *item, QEvent *event) override;
private:
diff --git a/src/quicktemplates2/qquickoverlay_p_p.h b/src/quicktemplates2/qquickoverlay_p_p.h
new file mode 100644
index 00000000..db005555
--- /dev/null
+++ b/src/quicktemplates2/qquickoverlay_p_p.h
@@ -0,0 +1,98 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QQUICKOVERLAY_P_P_H
+#define QQUICKOVERLAY_P_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qquickoverlay_p.h"
+
+#include <QtQuick/private/qquickitem_p.h>
+#include <QtQuick/private/qquickitemchangelistener_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class QQuickPopup;
+class QQuickDrawer;
+
+class QQuickOverlayPrivate : public QQuickItemPrivate, public QQuickItemChangeListener
+{
+ Q_DECLARE_PUBLIC(QQuickOverlay)
+
+public:
+ QQuickOverlayPrivate();
+
+ static QQuickOverlayPrivate *get(QQuickOverlay *overlay)
+ {
+ return overlay->d_func();
+ }
+
+ void addPopup(QQuickPopup *popup);
+ void removePopup(QQuickPopup *popup);
+
+ void popupAboutToShow();
+ void popupAboutToHide();
+
+ void createOverlay(QQuickPopup *popup);
+ void destroyOverlay(QQuickPopup *popup);
+ void resizeOverlay(QQuickPopup *popup);
+ void toggleOverlay();
+
+ QVector<QQuickPopup *> stackingOrderPopups() const;
+ QVector<QQuickDrawer *> stackingOrderDrawers() const;
+
+ void itemGeometryChanged(QQuickItem *item, QQuickGeometryChange change, const QRectF &diff) override;
+
+ QQmlComponent *modal;
+ QQmlComponent *modeless;
+ QVector<QQuickPopup *> allPopups;
+ QVector<QQuickDrawer *> allDrawers;
+ QPointer<QQuickPopup> mouseGrabberPopup;
+};
+
+QT_END_NAMESPACE
+
+#endif // QQUICKOVERLAY_P_P_H
diff --git a/src/quicktemplates2/qquickpopup.cpp b/src/quicktemplates2/qquickpopup.cpp
index 414ba782..4143ee3f 100644
--- a/src/quicktemplates2/qquickpopup.cpp
+++ b/src/quicktemplates2/qquickpopup.cpp
@@ -37,7 +37,7 @@
#include "qquickpopup_p.h"
#include "qquickpopup_p_p.h"
#include "qquickapplicationwindow_p.h"
-#include "qquickoverlay_p.h"
+#include "qquickoverlay_p_p.h"
#include "qquickcontrol_p_p.h"
#include <QtQml/qqmlinfo.h>
@@ -143,6 +143,7 @@ QQuickPopupPrivate::QQuickPopupPrivate()
, bottomMargin(0)
, contentWidth(0)
, contentHeight(0)
+ , transitionState(QQuickPopupPrivate::NoTransition)
, closePolicy(QQuickPopup::CloseOnEscape | QQuickPopup::CloseOnPressOutside)
, parentItem(nullptr)
, dimmer(nullptr)
@@ -180,43 +181,46 @@ bool QQuickPopupPrivate::tryClose(QQuickItem *item, QMouseEvent *event)
return false;
}
-void QQuickPopupPrivate::prepareEnterTransition(bool notify)
+bool QQuickPopupPrivate::prepareEnterTransition()
{
Q_Q(QQuickPopup);
if (!window) {
qmlInfo(q) << "cannot find any window to open popup in.";
- return;
+ return false;
}
- QQuickApplicationWindow *applicationWindow = qobject_cast<QQuickApplicationWindow*>(window);
- if (!applicationWindow) {
- window->installEventFilter(q);
- popupItem->setZ(1000001); // DefaultWindowDecoration+1
- popupItem->setParentItem(window->contentItem());
- } else {
- popupItem->setParentItem(applicationWindow->overlay());
- }
+ if (transitionState == EnterTransition && transitionManager.isRunning())
+ return false;
- if (notify)
+ if (transitionState != EnterTransition) {
+ popupItem->setParentItem(QQuickOverlay::overlay(window));
emit q->aboutToShow();
- visible = notify;
- popupItem->setVisible(true);
- positioner.setParentItem(parentItem);
- emit q->visibleChanged();
+ visible = true;
+ transitionState = EnterTransition;
+ popupItem->setVisible(true);
+ positioner.setParentItem(parentItem);
+ emit q->visibleChanged();
+ }
+ return true;
}
-void QQuickPopupPrivate::prepareExitTransition()
+bool QQuickPopupPrivate::prepareExitTransition()
{
Q_Q(QQuickPopup);
- if (window && !qobject_cast<QQuickApplicationWindow *>(window))
- window->removeEventFilter(q);
- if (focus) {
- // The setFocus(false) call below removes any active focus before we're
- // able to check it in finalizeExitTransition.
- hadActiveFocusBeforeExitTransition = popupItem->hasActiveFocus();
- popupItem->setFocus(false);
+ if (transitionState == ExitTransition && transitionManager.isRunning())
+ return false;
+
+ if (transitionState != ExitTransition) {
+ if (focus) {
+ // The setFocus(false) call below removes any active focus before we're
+ // able to check it in finalizeExitTransition.
+ hadActiveFocusBeforeExitTransition = popupItem->hasActiveFocus();
+ popupItem->setFocus(false);
+ }
+ transitionState = ExitTransition;
+ emit q->aboutToHide();
}
- emit q->aboutToHide();
+ return true;
}
void QQuickPopupPrivate::finalizeEnterTransition()
@@ -224,17 +228,16 @@ void QQuickPopupPrivate::finalizeEnterTransition()
Q_Q(QQuickPopup);
if (focus)
popupItem->setFocus(true);
+ transitionState = NoTransition;
emit q->opened();
}
-void QQuickPopupPrivate::finalizeExitTransition(bool hide)
+void QQuickPopupPrivate::finalizeExitTransition()
{
Q_Q(QQuickPopup);
- if (hide) {
- positioner.setParentItem(nullptr);
- popupItem->setParentItem(nullptr);
- popupItem->setVisible(false);
- }
+ positioner.setParentItem(nullptr);
+ popupItem->setParentItem(nullptr);
+ popupItem->setVisible(false);
if (hadActiveFocusBeforeExitTransition) {
QQuickApplicationWindow *applicationWindow = qobject_cast<QQuickApplicationWindow*>(window);
@@ -245,6 +248,7 @@ void QQuickPopupPrivate::finalizeExitTransition(bool hide)
}
visible = false;
+ transitionState = NoTransition;
hadActiveFocusBeforeExitTransition = false;
emit q->visibleChanged();
emit q->closed();
@@ -314,6 +318,18 @@ void QQuickPopupPrivate::setWindow(QQuickWindow *newWindow)
if (window == newWindow)
return;
+ if (window) {
+ QQuickOverlay *overlay = QQuickOverlay::overlay(window);
+ if (overlay)
+ QQuickOverlayPrivate::get(overlay)->removePopup(q);
+ }
+
+ if (newWindow) {
+ QQuickOverlay *overlay = QQuickOverlay::overlay(newWindow);
+ if (overlay)
+ QQuickOverlayPrivate::get(overlay)->addPopup(q);
+ }
+
window = newWindow;
emit q->windowChanged(newWindow);
}
@@ -711,19 +727,15 @@ bool QQuickPopupPositioner::isAncestor(QQuickItem *item) const
}
QQuickPopupTransitionManager::QQuickPopupTransitionManager(QQuickPopupPrivate *popup)
- : QQuickTransitionManager()
- , state(Off)
- , popup(popup)
+ : QQuickTransitionManager(), popup(popup)
{
}
void QQuickPopupTransitionManager::transitionEnter()
{
- if (state == Enter && isRunning())
+ if (!popup->prepareEnterTransition())
return;
- state = Enter;
- popup->prepareEnterTransition();
if (popup->window)
transition(popup->enterActions, popup->enter, popup->q_func());
else
@@ -732,11 +744,9 @@ void QQuickPopupTransitionManager::transitionEnter()
void QQuickPopupTransitionManager::transitionExit()
{
- if (state == Exit && isRunning())
+ if (!popup->prepareExitTransition())
return;
- state = Exit;
- popup->prepareExitTransition();
if (popup->window)
transition(popup->exitActions, popup->exit, popup->q_func());
else
@@ -745,12 +755,10 @@ void QQuickPopupTransitionManager::transitionExit()
void QQuickPopupTransitionManager::finished()
{
- if (state == Enter)
+ if (popup->transitionState == QQuickPopupPrivate::EnterTransition)
popup->finalizeEnterTransition();
- else if (state == Exit)
+ else if (popup->transitionState == QQuickPopupPrivate::ExitTransition)
popup->finalizeExitTransition();
-
- state = Off;
}
QQuickPopup::QQuickPopup(QObject *parent)
@@ -1895,13 +1903,6 @@ bool QQuickPopup::isComponentComplete() const
return d->complete;
}
-bool QQuickPopup::eventFilter(QObject *object, QEvent *event)
-{
- if (QQuickWindow *window = qobject_cast<QQuickWindow *>(object))
- return overlayEvent(window->contentItem(), event);
- return false;
-}
-
bool QQuickPopup::childMouseEventFilter(QQuickItem *child, QEvent *event)
{
Q_UNUSED(child);
@@ -1961,6 +1962,12 @@ void QQuickPopup::mouseDoubleClickEvent(QMouseEvent *event)
void QQuickPopup::mouseUngrabEvent()
{
+ QQuickOverlay *overlay = QQuickOverlay::overlay(window());
+ if (overlay) {
+ QQuickOverlayPrivate *p = QQuickOverlayPrivate::get(overlay);
+ if (p->mouseGrabberPopup == this)
+ p->mouseGrabberPopup = nullptr;
+ }
}
bool QQuickPopup::overlayEvent(QQuickItem *item, QEvent *event)
diff --git a/src/quicktemplates2/qquickpopup_p.h b/src/quicktemplates2/qquickpopup_p.h
index 1f2cabcf..5f5fd6bd 100644
--- a/src/quicktemplates2/qquickpopup_p.h
+++ b/src/quicktemplates2/qquickpopup_p.h
@@ -344,7 +344,6 @@ protected:
void componentComplete() override;
bool isComponentComplete() const;
- bool eventFilter(QObject *object, QEvent *event) override;
virtual bool childMouseEventFilter(QQuickItem *child, QEvent *event);
virtual void focusInEvent(QFocusEvent *event);
virtual void focusOutEvent(QFocusEvent *event);
diff --git a/src/quicktemplates2/qquickpopup_p_p.h b/src/quicktemplates2/qquickpopup_p_p.h
index 4478c555..93039287 100644
--- a/src/quicktemplates2/qquickpopup_p_p.h
+++ b/src/quicktemplates2/qquickpopup_p_p.h
@@ -76,11 +76,6 @@ protected:
void finished() override;
private:
- enum TransitionState {
- Off, Enter, Exit
- };
-
- TransitionState state;
QQuickPopupPrivate *popup;
};
@@ -163,10 +158,10 @@ public:
bool tryClose(QQuickItem *item, QMouseEvent *event);
virtual void reposition();
- virtual void prepareEnterTransition(bool notify = true);
- virtual void prepareExitTransition();
+ virtual bool prepareEnterTransition();
+ virtual bool prepareExitTransition();
virtual void finalizeEnterTransition();
- virtual void finalizeExitTransition(bool hide = true);
+ virtual void finalizeExitTransition();
QMarginsF getMargins() const;
@@ -178,6 +173,10 @@ public:
void setWindow(QQuickWindow *window);
void itemDestroyed(QQuickItem *item) override;
+ enum TransitionState {
+ NoTransition, EnterTransition, ExitTransition
+ };
+
bool focus;
bool modal;
bool dim;
@@ -202,6 +201,7 @@ public:
qreal bottomMargin;
qreal contentWidth;
qreal contentHeight;
+ TransitionState transitionState;
QQuickPopup::ClosePolicy closePolicy;
QQuickItem *parentItem;
QQuickItem *dimmer;
diff --git a/src/quicktemplates2/qquickroundbutton.cpp b/src/quicktemplates2/qquickroundbutton.cpp
new file mode 100644
index 00000000..4169b269
--- /dev/null
+++ b/src/quicktemplates2/qquickroundbutton.cpp
@@ -0,0 +1,143 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qquickroundbutton_p.h"
+
+#include <QtQuickTemplates2/private/qquickbutton_p_p.h>
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \qmltype RoundButton
+ \inherits Button
+ \instantiates QQuickRoundButton
+ \inqmlmodule QtQuick.Controls
+ \since 5.8
+ \ingroup qtquickcontrols2-buttons
+ \brief A push-button control with rounded corners that can be clicked by the user.
+
+ \image qtquickcontrols2-roundbutton.png
+
+ RoundButton is identical to \l Button, except that it has a \l radius property
+ which allows the corners to be rounded without having to customize the
+ \l background.
+
+ \snippet qtquickcontrols2-roundbutton.qml 1
+
+ \sa {Customizing RoundButton}, {Button Controls}
+*/
+
+class QQuickRoundButtonPrivate : public QQuickButtonPrivate
+{
+ Q_DECLARE_PUBLIC(QQuickRoundButton)
+
+public:
+ QQuickRoundButtonPrivate();
+
+ qreal radius;
+ bool explicitRadius;
+
+ void setRadius(qreal newRadius = -1.0);
+};
+
+QQuickRoundButtonPrivate::QQuickRoundButtonPrivate() :
+ radius(0),
+ explicitRadius(false)
+{
+}
+
+void QQuickRoundButtonPrivate::setRadius(qreal newRadius)
+{
+ Q_Q(QQuickRoundButton);
+ const qreal oldRadius = radius;
+ if (newRadius < 0)
+ radius = qMax<qreal>(0, qMin(width, height) / 2);
+ else
+ radius = newRadius;
+
+ if (!qFuzzyCompare(radius, oldRadius))
+ emit q->radiusChanged();
+}
+
+QQuickRoundButton::QQuickRoundButton(QQuickItem *parent) :
+ QQuickButton(*(new QQuickRoundButtonPrivate), parent)
+{
+}
+
+/*!
+ \qmlproperty real QtQuick.Controls::RoundButton::radius
+
+ This property holds the radius of the button.
+
+ To create a relatively square button that has slightly rounded corners,
+ use a small value, such as \c 3.
+
+ To create a completely circular button (the default), use a value that is
+ equal to half of the width or height of the button, and make the button's
+ width and height identical.
+
+ To reset this property back to the default value, set its value to
+ \c undefined.
+*/
+qreal QQuickRoundButton::radius() const
+{
+ Q_D(const QQuickRoundButton);
+ return d->radius;
+}
+
+void QQuickRoundButton::setRadius(qreal radius)
+{
+ Q_D(QQuickRoundButton);
+ d->explicitRadius = true;
+ d->setRadius(radius);
+}
+
+void QQuickRoundButton::resetRadius()
+{
+ Q_D(QQuickRoundButton);
+ d->explicitRadius = false;
+ d->setRadius();
+}
+
+void QQuickRoundButton::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
+{
+ Q_D(QQuickRoundButton);
+ QQuickControl::geometryChanged(newGeometry, oldGeometry);
+ if (!d->explicitRadius)
+ d->setRadius();
+}
+
+QT_END_NAMESPACE
diff --git a/src/quicktemplates2/qquickroundbutton_p.h b/src/quicktemplates2/qquickroundbutton_p.h
new file mode 100644
index 00000000..f308ddd3
--- /dev/null
+++ b/src/quicktemplates2/qquickroundbutton_p.h
@@ -0,0 +1,84 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QQUICKROUNDBUTTON_P_H
+#define QQUICKROUNDBUTTON_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtQuickTemplates2/private/qquickbutton_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class QQuickRoundButtonPrivate;
+
+class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickRoundButton : public QQuickButton
+{
+ Q_OBJECT
+ Q_PROPERTY(qreal radius READ radius WRITE setRadius RESET resetRadius NOTIFY radiusChanged FINAL)
+
+public:
+ explicit QQuickRoundButton(QQuickItem *parent = nullptr);
+
+ qreal radius() const;
+ void setRadius(qreal radius);
+ void resetRadius();
+
+Q_SIGNALS:
+ void radiusChanged();
+
+protected:
+ void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) override;
+
+private:
+ Q_DISABLE_COPY(QQuickRoundButton)
+ Q_DECLARE_PRIVATE(QQuickRoundButton)
+};
+
+QT_END_NAMESPACE
+
+QML_DECLARE_TYPE(QQuickRoundButton)
+
+#endif // QQUICKROUNDBUTTON_P_H
diff --git a/src/quicktemplates2/qquickscrollindicator.cpp b/src/quicktemplates2/qquickscrollindicator.cpp
index acb8dd46..351f3113 100644
--- a/src/quicktemplates2/qquickscrollindicator.cpp
+++ b/src/quicktemplates2/qquickscrollindicator.cpp
@@ -109,12 +109,17 @@ void QQuickScrollIndicatorPrivate::resizeContent()
if (!contentItem)
return;
+ // - negative overshoot (pos < 0): clamp the pos to 0, and deduct the overshoot from the size
+ // - positive overshoot (pos + size > 1): clamp the size to 1-pos
+ const qreal clampedSize = qBound<qreal>(0, size + qMin<qreal>(0, position), 1.0 - position);
+ const qreal clampedPos = qBound<qreal>(0, position, 1.0 - clampedSize);
+
if (orientation == Qt::Horizontal) {
- contentItem->setPosition(QPointF(q->leftPadding() + position * q->availableWidth(), q->topPadding()));
- contentItem->setSize(QSizeF(q->availableWidth() * size, q->availableHeight()));
+ contentItem->setPosition(QPointF(q->leftPadding() + clampedPos * q->availableWidth(), q->topPadding()));
+ contentItem->setSize(QSizeF(q->availableWidth() * clampedSize, q->availableHeight()));
} else {
- contentItem->setPosition(QPointF(q->leftPadding(), q->topPadding() + position * q->availableHeight()));
- contentItem->setSize(QSizeF(q->availableWidth(), q->availableHeight() * size));
+ contentItem->setPosition(QPointF(q->leftPadding(), q->topPadding() + clampedPos * q->availableHeight()));
+ contentItem->setSize(QSizeF(q->availableWidth(), q->availableHeight() * clampedSize));
}
}
diff --git a/src/quicktemplates2/qquickstackview.cpp b/src/quicktemplates2/qquickstackview.cpp
index df163089..040eff1b 100644
--- a/src/quicktemplates2/qquickstackview.cpp
+++ b/src/quicktemplates2/qquickstackview.cpp
@@ -1092,4 +1092,21 @@ QQuickStackView::Status QQuickStackAttached::status() const
\sa status
*/
+/*!
+ \qmlattachedsignal QtQuick.Controls::StackView::removed()
+ \since QtQuick.Controls 2.1
+
+ This attached signal is emitted when the item it's attached to has been
+ removed from the stack. It can be used to safely destroy an Item that was
+ pushed onto the stack, for example:
+
+ \code
+ Item {
+ StackView.onRemoved: destroy() // Will be destroyed sometime after this call.
+ }
+ \endcode
+
+ \sa status
+*/
+
QT_END_NAMESPACE
diff --git a/src/quicktemplates2/qquickstackview_p.cpp b/src/quicktemplates2/qquickstackview_p.cpp
index 0f5674c2..438b4269 100644
--- a/src/quicktemplates2/qquickstackview_p.cpp
+++ b/src/quicktemplates2/qquickstackview_p.cpp
@@ -85,6 +85,7 @@ QQuickStackElement::~QQuickStackElement()
if (ownComponent)
delete component;
+ QQuickStackAttached *attached = attachedStackObject(this);
if (item) {
if (ownItem) {
item->setParentItem(nullptr);
@@ -99,13 +100,15 @@ QQuickStackElement::~QQuickStackElement()
if (item->parentItem() != originalParent) {
item->setParentItem(originalParent);
} else {
- QQuickStackAttached *attached = attachedStackObject(this);
if (attached)
QQuickStackAttachedPrivate::get(attached)->itemParentChanged(item, nullptr);
}
}
}
+ if (attached)
+ emit attached->removed();
+
delete context;
}
diff --git a/src/quicktemplates2/qquickstackview_p.h b/src/quicktemplates2/qquickstackview_p.h
index d8b6ce7c..9bf60183 100644
--- a/src/quicktemplates2/qquickstackview_p.h
+++ b/src/quicktemplates2/qquickstackview_p.h
@@ -182,6 +182,7 @@ Q_SIGNALS:
/*Q_REVISION(1)*/ void activating();
/*Q_REVISION(1)*/ void deactivated();
/*Q_REVISION(1)*/ void deactivating();
+ /*Q_REVISION(1)*/ void removed();
private:
Q_DISABLE_COPY(QQuickStackAttached)
diff --git a/src/quicktemplates2/qquickswitch.cpp b/src/quicktemplates2/qquickswitch.cpp
index 439950d8..37ae53f0 100644
--- a/src/quicktemplates2/qquickswitch.cpp
+++ b/src/quicktemplates2/qquickswitch.cpp
@@ -37,6 +37,8 @@
#include "qquickswitch_p.h"
#include "qquickabstractbutton_p_p.h"
+#include <QtGui/qstylehints.h>
+#include <QtGui/qguiapplication.h>
#include <QtQuick/private/qquickwindow_p.h>
#include <QtQuick/private/qquickevents_p_p.h>
@@ -119,8 +121,12 @@ bool QQuickSwitchPrivate::handleMousePressEvent(QQuickItem *child, QMouseEvent *
{
Q_Q(QQuickSwitch);
Q_UNUSED(child);
+ if ((focusPolicy & Qt::ClickFocus) == Qt::ClickFocus && !QGuiApplication::styleHints()->setFocusOnTouchRelease())
+ q->forceActiveFocus(Qt::MouseFocusReason);
+
pressPoint = event->pos();
q->setPressed(true);
+ emit q->pressed();
event->accept();
return true;
}
@@ -140,6 +146,9 @@ bool QQuickSwitchPrivate::handleMouseMoveEvent(QQuickItem *child, QMouseEvent *e
bool QQuickSwitchPrivate::handleMouseReleaseEvent(QQuickItem *child, QMouseEvent *event)
{
Q_Q(QQuickSwitch);
+ if ((focusPolicy & Qt::ClickFocus) == Qt::ClickFocus && QGuiApplication::styleHints()->setFocusOnTouchRelease())
+ q->forceActiveFocus(Qt::MouseFocusReason);
+
pressPoint = QPoint();
q->setPressed(false);
if (child->keepMouseGrab()) {
@@ -147,11 +156,14 @@ bool QQuickSwitchPrivate::handleMouseReleaseEvent(QQuickItem *child, QMouseEvent
q->setChecked(position > 0.5);
q->setPosition(checked ? 1.0 : 0.0);
child->setKeepMouseGrab(false);
- if (wasChecked != checked)
+ if (wasChecked != checked) {
+ emit q->released();
emit q->clicked();
+ }
event->accept();
} else {
q->toggle();
+ emit q->released();
emit q->clicked();
event->accept();
}
diff --git a/src/quicktemplates2/quicktemplates2.pri b/src/quicktemplates2/quicktemplates2.pri
index f5e95aea..0d6a0e5a 100644
--- a/src/quicktemplates2/quicktemplates2.pri
+++ b/src/quicktemplates2/quicktemplates2.pri
@@ -6,6 +6,7 @@ HEADERS += \
$$PWD/qquickapplicationwindow_p.h \
$$PWD/qquickbusyindicator_p.h \
$$PWD/qquickbutton_p.h \
+ $$PWD/qquickbutton_p_p.h \
$$PWD/qquickbuttongroup_p.h \
$$PWD/qquickcheckbox_p.h \
$$PWD/qquickcheckdelegate_p.h \
@@ -20,6 +21,7 @@ HEADERS += \
$$PWD/qquickdialogbuttonbox_p.h \
$$PWD/qquickdialogbuttonbox_p_p.h \
$$PWD/qquickdrawer_p.h \
+ $$PWD/qquickdrawer_p_p.h \
$$PWD/qquickframe_p.h \
$$PWD/qquickframe_p_p.h \
$$PWD/qquickgroupbox_p.h \
@@ -32,6 +34,7 @@ HEADERS += \
$$PWD/qquickmenuitem_p.h \
$$PWD/qquickmenuseparator_p.h \
$$PWD/qquickoverlay_p.h \
+ $$PWD/qquickoverlay_p_p.h \
$$PWD/qquickpage_p.h \
$$PWD/qquickpageindicator_p.h \
$$PWD/qquickpagelayout_p_p.h \
@@ -44,6 +47,7 @@ HEADERS += \
$$PWD/qquickradiobutton_p.h \
$$PWD/qquickradiodelegate_p.h \
$$PWD/qquickrangeslider_p.h \
+ $$PWD/qquickroundbutton_p.h \
$$PWD/qquickscrollbar_p.h \
$$PWD/qquickscrollindicator_p.h \
$$PWD/qquickslider_p.h \
@@ -101,6 +105,7 @@ SOURCES += \
$$PWD/qquickradiobutton.cpp \
$$PWD/qquickradiodelegate.cpp \
$$PWD/qquickrangeslider.cpp \
+ $$PWD/qquickroundbutton.cpp \
$$PWD/qquickscrollbar.cpp \
$$PWD/qquickscrollindicator.cpp \
$$PWD/qquickslider.cpp \
diff --git a/tests/auto/controls/data/tst_container.qml b/tests/auto/controls/data/tst_container.qml
new file mode 100644
index 00000000..d1ff54e0
--- /dev/null
+++ b/tests/auto/controls/data/tst_container.qml
@@ -0,0 +1,85 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 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.2
+import QtTest 1.0
+import QtQuick.Controls 2.0
+import QtQuick.Templates 2.0 as T
+
+TestCase {
+ id: testCase
+ width: 400
+ height: 400
+ visible: true
+ when: windowShown
+ name: "Container"
+
+ Component {
+ id: container
+ Container { }
+ }
+
+ Component {
+ id: rectangle
+ Rectangle { }
+ }
+
+ function test_implicitSize() {
+ var control = container.createObject(testCase)
+ verify(control)
+
+ compare(control.implicitWidth, 0)
+ compare(control.implicitHeight, 0)
+
+ control.contentItem = rectangle.createObject(control, {implicitWidth: 10, implicitHeight: 20})
+ compare(control.implicitWidth, 10)
+ compare(control.implicitHeight, 20)
+
+ control.background = rectangle.createObject(control, {implicitWidth: 20, implicitHeight: 30})
+ compare(control.implicitWidth, 20)
+ compare(control.implicitHeight, 30)
+
+ control.padding = 100
+ compare(control.implicitWidth, 210)
+ compare(control.implicitHeight, 220)
+
+ control.destroy()
+ }
+}
diff --git a/tests/auto/controls/data/tst_control.qml b/tests/auto/controls/data/tst_control.qml
index fc839493..0061440b 100644
--- a/tests/auto/controls/data/tst_control.qml
+++ b/tests/auto/controls/data/tst_control.qml
@@ -53,7 +53,12 @@ TestCase {
Component {
id: component
- T.Control { }
+ Control { }
+ }
+
+ Component {
+ id: rectangle
+ Rectangle { }
}
Component {
@@ -877,4 +882,26 @@ TestCase {
control.destroy()
}
+
+ function test_implicitSize() {
+ var control = component.createObject(testCase)
+ verify(control)
+
+ compare(control.implicitWidth, 0)
+ compare(control.implicitHeight, 0)
+
+ control.contentItem = rectangle.createObject(control, {implicitWidth: 10, implicitHeight: 20})
+ compare(control.implicitWidth, 10)
+ compare(control.implicitHeight, 20)
+
+ control.background = rectangle.createObject(control, {implicitWidth: 20, implicitHeight: 30})
+ compare(control.implicitWidth, 20)
+ compare(control.implicitHeight, 30)
+
+ control.padding = 100
+ compare(control.implicitWidth, 210)
+ compare(control.implicitHeight, 220)
+
+ control.destroy()
+ }
}
diff --git a/tests/auto/controls/data/tst_popup.qml b/tests/auto/controls/data/tst_popup.qml
index 759d6988..a86e800e 100644
--- a/tests/auto/controls/data/tst_popup.qml
+++ b/tests/auto/controls/data/tst_popup.qml
@@ -1006,18 +1006,13 @@ TestCase {
ApplicationWindow {
property alias firstDrawer: firstDrawer
property alias secondDrawer: secondDrawer
- property alias upperDrawer: upperDrawer
property alias modalPopup: modalPopup
property alias modelessPopup: modelessPopup
property alias plainPopup: plainPopup
property alias modalPopupWithoutDim: modalPopupWithoutDim
visible: true
Drawer {
- z: 5
- id: upperDrawer
- }
- Drawer {
- z: 1
+ z: 0
id: firstDrawer
}
Drawer {
@@ -1073,52 +1068,41 @@ TestCase {
window.requestActivate()
tryCompare(window, "active", true)
- var countBefore = window.overlay.children.length
- compare(countBefore, 6) // 3 drawers + 3 overlays
+ compare(window.overlay.children.length, 0)
var firstOverlay = findOverlay(window, window.firstDrawer)
+ verify(!firstOverlay)
+ window.firstDrawer.open()
+ compare(window.overlay.children.length, 2) // 1 drawer + 1 overlay
+ firstOverlay = findOverlay(window, window.firstDrawer)
verify(firstOverlay)
- compare(firstOverlay.opacity, 0.0)
compare(firstOverlay.z, window.firstDrawer.z)
compare(indexOf(window.overlay.children, firstOverlay),
indexOf(window.overlay.children, window.firstDrawer.contentItem.parent) - 1)
+ tryCompare(firstOverlay, "opacity", 1.0)
var secondOverlay = findOverlay(window, window.secondDrawer)
+ verify(!secondOverlay)
+ window.secondDrawer.open()
+ compare(window.overlay.children.length, 4) // 2 drawers + 2 overlays
+ secondOverlay = findOverlay(window, window.secondDrawer)
verify(secondOverlay)
- compare(secondOverlay.opacity, 0.0)
compare(secondOverlay.z, window.secondDrawer.z)
compare(indexOf(window.overlay.children, secondOverlay),
indexOf(window.overlay.children, window.secondDrawer.contentItem.parent) - 1)
+ tryCompare(secondOverlay, "opacity", 1.0)
- var upperOverlay = findOverlay(window, window.upperDrawer)
- verify(upperOverlay)
- compare(upperOverlay.opacity, 0.0)
- compare(upperOverlay.z, window.upperDrawer.z)
- compare(indexOf(window.overlay.children, upperOverlay),
- indexOf(window.overlay.children, window.upperDrawer.contentItem.parent) - 1)
-
- window.firstDrawer.open()
- compare(firstOverlay.z, 1.0)
- tryCompare(firstOverlay, "opacity", 1.0)
window.firstDrawer.close()
- tryCompare(firstOverlay, "opacity", 0.0)
tryCompare(window.firstDrawer, "visible", false)
+ firstOverlay = findOverlay(window, window.firstDrawer)
+ verify(!firstOverlay)
+ compare(window.overlay.children.length, 2) // 1 drawer + 1 overlay
- window.secondDrawer.open()
- compare(secondOverlay.z, 1.0)
- tryCompare(secondOverlay, "opacity", 1.0)
window.secondDrawer.close()
- tryCompare(secondOverlay, "opacity", 0.0)
tryCompare(window.secondDrawer, "visible", false)
-
- window.firstDrawer.open()
- window.secondDrawer.open()
- tryCompare(firstOverlay, "opacity", 1.0)
- tryCompare(secondOverlay, "opacity", 1.0)
- window.firstDrawer.close()
- window.secondDrawer.close()
- tryCompare(firstOverlay, "opacity", 0.0)
- tryCompare(secondOverlay, "opacity", 0.0)
+ secondOverlay = findOverlay(window, window.secondDrawer)
+ verify(!secondOverlay)
+ compare(window.overlay.children.length, 0)
var modalOverlay = findOverlay(window, window.modalPopup)
verify(!modalOverlay)
@@ -1128,7 +1112,7 @@ TestCase {
compare(modalOverlay.z, window.modalPopup.z)
compare(window.modalPopup.visible, true)
tryCompare(modalOverlay, "opacity", 1.0)
- compare(window.overlay.children.length, countBefore + 2) // 1 popup + 1 overlay
+ compare(window.overlay.children.length, 2) // 1 popup + 1 overlay
var modelessOverlay = findOverlay(window, window.modelessPopup)
verify(!modelessOverlay)
@@ -1138,13 +1122,13 @@ TestCase {
compare(modelessOverlay.z, window.modelessPopup.z)
compare(window.modelessPopup.visible, true)
tryCompare(modelessOverlay, "opacity", 1.0)
- compare(window.overlay.children.length, countBefore + 4) // 2 popups + 2 overlays
+ compare(window.overlay.children.length, 4) // 2 popups + 2 overlays
window.modelessPopup.close()
tryCompare(window.modelessPopup, "visible", false)
modelessOverlay = findOverlay(window, window.modelessPopup)
verify(!modelessOverlay)
- compare(window.overlay.children.length, countBefore + 2) // 1 popup + 1 overlay
+ compare(window.overlay.children.length, 2) // 1 popup + 1 overlay
compare(window.modalPopup.visible, true)
compare(modalOverlay.opacity, 1.0)
@@ -1153,23 +1137,29 @@ TestCase {
tryCompare(window.modalPopup, "visible", false)
modalOverlay = findOverlay(window, window.modalPopup)
verify(!modalOverlay)
- compare(window.overlay.children.length, countBefore)
+ compare(window.overlay.children.length, 0)
window.plainPopup.open()
tryCompare(window.plainPopup, "visible", true)
- compare(window.overlay.children.length, countBefore + 1) // only popup added, no overlays involved
+ compare(window.overlay.children.length, 1) // only popup added, no overlays involved
+
+ window.plainPopup.modal = true
+ compare(window.overlay.children.length, 2) // overlay added
window.plainPopup.close()
tryCompare(window.plainPopup, "visible", false)
- compare(window.overlay.children.length, countBefore) // only popup removed, no overlays involved
+ compare(window.overlay.children.length, 0) // popup + overlay removed
window.modalPopupWithoutDim.open()
tryCompare(window.modalPopupWithoutDim, "visible", true)
- compare(window.overlay.children.length, countBefore + 1) // only popup added, no overlays involved
+ compare(window.overlay.children.length, 1) // only popup added, no overlays involved
+
+ window.modalPopupWithoutDim.dim = true
+ compare(window.overlay.children.length, 2) // overlay added
window.modalPopupWithoutDim.close()
tryCompare(window.modalPopupWithoutDim, "visible", false)
- compare(window.overlay.children.length, countBefore) // only popup added, no overlays involved
+ compare(window.overlay.children.length, 0) // popup + overlay removed
window.destroy()
}
diff --git a/tests/auto/controls/data/tst_roundbutton.qml b/tests/auto/controls/data/tst_roundbutton.qml
new file mode 100644
index 00000000..aa956776
--- /dev/null
+++ b/tests/auto/controls/data/tst_roundbutton.qml
@@ -0,0 +1,79 @@
+/****************************************************************************
+**
+** 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.2
+import QtTest 1.0
+import QtQuick.Controls 2.1
+
+TestCase {
+ id: testCase
+ width: 200
+ height: 200
+ visible: true
+ when: windowShown
+ name: "RoundButton"
+
+ Component {
+ id: roundButton
+ RoundButton { }
+ }
+
+ function test_radius() {
+ var control = roundButton.createObject(testCase);
+ verify(control);
+
+ var implicitRadius = control.radius;
+ compare(implicitRadius, Math.min(control.width, control.height) / 2);
+
+ control.radius = 10;
+ compare(control.radius, 10);
+
+ control.radius = undefined;
+ compare(control.radius, implicitRadius);
+
+ control.width = -1;
+ compare(control.radius, 0);
+
+ control.width = 10;
+ compare(control.radius, 5);
+
+ control.destroy();
+ }
+}
diff --git a/tests/auto/controls/data/tst_scrollindicator.qml b/tests/auto/controls/data/tst_scrollindicator.qml
index 00730bf4..551247f6 100644
--- a/tests/auto/controls/data/tst_scrollindicator.qml
+++ b/tests/auto/controls/data/tst_scrollindicator.qml
@@ -157,4 +157,38 @@ TestCase {
ignoreWarning(Qt.resolvedUrl("tst_scrollindicator.qml") + ":45:1: QML TestCase: ScrollIndicator must be attached to a Flickable")
testCase.ScrollIndicator.vertical = null
}
+
+ function test_overshoot() {
+ var container = flickable.createObject(testCase)
+ verify(container)
+ waitForRendering(container)
+
+ var vertical = scrollIndicator.createObject(container, {size: 0.5})
+ container.ScrollIndicator.vertical = vertical
+
+ var horizontal = scrollIndicator.createObject(container, {size: 0.5})
+ container.ScrollIndicator.horizontal = horizontal
+
+ // negative vertical overshoot (pos < 0)
+ vertical.position = -0.1
+ compare(vertical.contentItem.y, vertical.topPadding)
+ compare(vertical.contentItem.height, 0.4 * vertical.availableHeight)
+
+ // positive vertical overshoot (pos + size > 1)
+ vertical.position = 0.8
+ compare(vertical.contentItem.y, vertical.topPadding + 0.8 * vertical.availableHeight)
+ compare(vertical.contentItem.height, 0.2 * vertical.availableHeight)
+
+ // negative horizontal overshoot (pos < 0)
+ horizontal.position = -0.1
+ compare(horizontal.contentItem.x, horizontal.leftPadding)
+ compare(horizontal.contentItem.width, 0.4 * horizontal.availableWidth)
+
+ // positive horizontal overshoot (pos + size > 1)
+ horizontal.position = 0.8
+ compare(horizontal.contentItem.x, horizontal.leftPadding + 0.8 * horizontal.availableWidth)
+ compare(horizontal.contentItem.width, 0.2 * horizontal.availableWidth)
+
+ container.destroy()
+ }
}
diff --git a/tests/auto/controls/data/tst_stackview.qml b/tests/auto/controls/data/tst_stackview.qml
index 2de0fb98..4de8bed0 100644
--- a/tests/auto/controls/data/tst_stackview.qml
+++ b/tests/auto/controls/data/tst_stackview.qml
@@ -680,6 +680,60 @@ TestCase {
}
Component {
+ id: removeComponent
+
+ Item {
+ objectName: "removeItem"
+ StackView.onRemoved: destroy()
+ }
+ }
+
+ function test_destroyOnRemoved() {
+ var control = stackView.createObject(testCase, { initialItem: component })
+ verify(control)
+
+ var item = removeComponent.createObject(control)
+ verify(item)
+
+ var removedSpy = signalSpy.createObject(control, { target: item.StackView, signalName: "removed" })
+ verify(removedSpy)
+ verify(removedSpy.valid)
+
+ var destructionSpy = signalSpy.createObject(control, { target: item.Component, signalName: "destruction" })
+ verify(destructionSpy)
+ verify(destructionSpy.valid)
+
+ // push-pop
+ control.push(item, StackView.Immediate)
+ compare(control.currentItem, item)
+ control.pop(StackView.Transition)
+ item = null
+ tryCompare(removedSpy, "count", 1)
+ tryCompare(destructionSpy, "count", 1)
+ compare(control.busy, false)
+
+ item = removeComponent.createObject(control)
+ verify(item)
+
+ removedSpy.target = item.StackView
+ verify(removedSpy.valid)
+
+ destructionSpy.target = item.Component
+ verify(destructionSpy.valid)
+
+ // push-replace
+ control.push(item, StackView.Immediate)
+ compare(control.currentItem, item)
+ control.replace(component, StackView.Transition)
+ item = null
+ tryCompare(removedSpy, "count", 2)
+ tryCompare(destructionSpy, "count", 2)
+ compare(control.busy, false)
+
+ control.destroy()
+ }
+
+ Component {
id: attachedItem
Item {
property int index: StackView.index
diff --git a/tests/auto/controls/data/tst_switch.qml b/tests/auto/controls/data/tst_switch.qml
index b75e2713..6c145fc1 100644
--- a/tests/auto/controls/data/tst_switch.qml
+++ b/tests/auto/controls/data/tst_switch.qml
@@ -50,42 +50,16 @@ TestCase {
when: windowShown
name: "Switch"
- SignalSpy {
- id: checkedSpy
- signalName: "checkedChanged"
- }
-
- SignalSpy {
- id: pressedSpy
- signalName: "pressedChanged"
- }
-
- SignalSpy {
- id: clickedSpy
- signalName: "clicked"
- }
-
Component {
id: swtch
Switch { }
}
- function init() {
- verify(!checkedSpy.target)
- verify(!pressedSpy.target)
- verify(!clickedSpy.target)
- compare(checkedSpy.count, 0)
- compare(pressedSpy.count, 0)
- compare(clickedSpy.count, 0)
- }
-
- function cleanup() {
- checkedSpy.target = null
- pressedSpy.target = null
- clickedSpy.target = null
- checkedSpy.clear()
- pressedSpy.clear()
- clickedSpy.clear()
+ Component {
+ id: signalSequenceSpy
+ SignalSequenceSpy {
+ signals: ["pressed", "released", "canceled", "clicked", "pressedChanged", "checkedChanged"]
+ }
}
function test_text() {
@@ -105,19 +79,18 @@ TestCase {
var control = swtch.createObject(testCase)
verify(control)
- checkedSpy.target = control
- verify(checkedSpy.valid)
-
compare(control.checked, false)
- compare(checkedSpy.count, 0)
+ var spy = signalSequenceSpy.createObject(control, {target: control})
+ spy.expectedSequence = [["checkedChanged", { "checked": true }]]
control.checked = true
compare(control.checked, true)
- compare(checkedSpy.count, 1)
+ verify(spy.success)
+ spy.expectedSequence = [["checkedChanged", { "checked": false }]]
control.checked = false
compare(control.checked, false)
- compare(checkedSpy.count, 2)
+ verify(spy.success)
control.destroy()
}
@@ -126,71 +99,80 @@ TestCase {
var control = swtch.createObject(testCase)
verify(control)
- checkedSpy.target = control
- pressedSpy.target = control
- clickedSpy.target = control
- verify(checkedSpy.valid)
- verify(pressedSpy.valid)
- verify(clickedSpy.valid)
-
// check
+ var spy = signalSequenceSpy.createObject(control, {target: control})
+ spy.expectedSequence = [["pressedChanged", { "pressed": true, "checked": false }],
+ "pressed"]
mousePress(control, control.width / 2, control.height / 2, Qt.LeftButton)
- compare(pressedSpy.count, 1)
compare(control.pressed, true)
+ verify(spy.success)
+ spy.expectedSequence = [["pressedChanged", { "pressed": false, "checked": false }],
+ ["checkedChanged", { "pressed": false, "checked": true }],
+ "released",
+ "clicked"]
mouseRelease(control, control.width / 2, control.height / 2, Qt.LeftButton)
- compare(clickedSpy.count, 1)
- compare(checkedSpy.count, 1)
- compare(pressedSpy.count, 2)
compare(control.checked, true)
compare(control.pressed, false)
+ verify(spy.success)
// uncheck
+ spy.expectedSequence = [["pressedChanged", { "pressed": true, "checked": true }],
+ "pressed"]
mousePress(control, control.width / 2, control.height / 2, Qt.LeftButton)
- compare(pressedSpy.count, 3)
compare(control.pressed, true)
+ verify(spy.success)
+ spy.expectedSequence = [["pressedChanged", { "pressed": false, "checked": true }],
+ ["checkedChanged", { "pressed": false, "checked": false }],
+ "released",
+ "clicked"]
mouseRelease(control, control.width / 2, control.height / 2, Qt.LeftButton)
- compare(clickedSpy.count, 2)
- compare(checkedSpy.count, 2)
- compare(pressedSpy.count, 4)
compare(control.checked, false)
compare(control.pressed, false)
+ verify(spy.success)
// release on the right
+ spy.expectedSequence = [["pressedChanged", { "pressed": true, "checked": false }],
+ "pressed"]
mousePress(control, control.width / 2, control.height / 2, Qt.LeftButton)
- compare(pressedSpy.count, 5)
compare(control.pressed, true)
+ verify(spy.success)
mouseMove(control, control.width * 2, control.height / 2, 0, Qt.LeftButton)
compare(control.pressed, true)
+ spy.expectedSequence = [["pressedChanged", { "pressed": false, "checked": false }],
+ ["checkedChanged", { "pressed": false, "checked": true }],
+ "released",
+ "clicked"]
mouseRelease(control, control.width * 2, control.height / 2, Qt.LeftButton)
- compare(clickedSpy.count, 3)
- compare(checkedSpy.count, 3)
- compare(pressedSpy.count, 6)
compare(control.checked, true)
compare(control.pressed, false)
+ verify(spy.success)
// release on the left
+ spy.expectedSequence = [["pressedChanged", { "pressed": true, "checked": true }],
+ "pressed"]
mousePress(control, control.width / 2, control.height / 2, Qt.LeftButton)
- compare(pressedSpy.count, 7)
compare(control.pressed, true)
+ verify(spy.success)
mouseMove(control, -control.width, control.height / 2, 0, Qt.LeftButton)
compare(control.pressed, true)
+ spy.expectedSequence = [["pressedChanged", { "pressed": false, "checked": true }],
+ ["checkedChanged", { "pressed": false, "checked": false }],
+ "released",
+ "clicked"]
mouseRelease(control, -control.width, control.height / 2, Qt.LeftButton)
- compare(clickedSpy.count, 4)
- compare(checkedSpy.count, 4)
- compare(pressedSpy.count, 8)
compare(control.checked, false)
compare(control.pressed, false)
+ verify(spy.success)
// right button
+ spy.expectedSequence = []
mousePress(control, control.width / 2, control.height / 2, Qt.RightButton)
- compare(pressedSpy.count, 8)
compare(control.pressed, false)
+ verify(spy.success)
mouseRelease(control, control.width / 2, control.height / 2, Qt.RightButton)
- compare(clickedSpy.count, 4)
- compare(checkedSpy.count, 4)
- compare(pressedSpy.count, 8)
compare(control.checked, false)
compare(control.pressed, false)
+ verify(spy.success)
control.destroy()
}
@@ -199,33 +181,39 @@ TestCase {
var control = swtch.createObject(testCase)
verify(control)
- checkedSpy.target = control
- clickedSpy.target = control
- verify(checkedSpy.valid)
- verify(clickedSpy.valid)
-
control.forceActiveFocus()
verify(control.activeFocus)
// check
+ var spy = signalSequenceSpy.createObject(control, {target: control})
+ spy.expectedSequence = [["pressedChanged", { "pressed": true, "checked": false }],
+ "pressed",
+ ["pressedChanged", { "pressed": false, "checked": false }],
+ ["checkedChanged", { "pressed": false, "checked": true }],
+ "released",
+ "clicked"]
keyClick(Qt.Key_Space)
- compare(clickedSpy.count, 1)
- compare(checkedSpy.count, 1)
compare(control.checked, true)
+ verify(spy.success)
// uncheck
+ spy.expectedSequence = [["pressedChanged", { "pressed": true, "checked": true }],
+ "pressed",
+ ["pressedChanged", { "pressed": false, "checked": true }],
+ ["checkedChanged", { "pressed": false, "checked": false }],
+ "released",
+ "clicked"]
keyClick(Qt.Key_Space)
- compare(clickedSpy.count, 2)
- compare(checkedSpy.count, 2)
compare(control.checked, false)
+ verify(spy.success)
// no change
+ spy.expectedSequence = []
var keys = [Qt.Key_Enter, Qt.Key_Return, Qt.Key_Escape, Qt.Key_Tab]
for (var i = 0; i < keys.length; ++i) {
keyClick(keys[i])
- compare(clickedSpy.count, 2)
- compare(checkedSpy.count, 2)
compare(control.checked, false)
+ verify(spy.success)
}
control.destroy()
@@ -263,4 +251,15 @@ TestCase {
compare(control.baselineOffset, control.contentItem.y + control.contentItem.baselineOffset)
control.destroy()
}
+
+ function test_focus() {
+ var control = swtch.createObject(testCase)
+ verify(control)
+
+ verify(!control.activeFocus)
+ mouseClick(control.indicator)
+ verify(control.activeFocus)
+
+ control.destroy()
+ }
}
diff --git a/tests/auto/controls/data/tst_textfield.qml b/tests/auto/controls/data/tst_textfield.qml
index 1f1de748..5dc93287 100644
--- a/tests/auto/controls/data/tst_textfield.qml
+++ b/tests/auto/controls/data/tst_textfield.qml
@@ -72,6 +72,7 @@ TestCase {
var implicitWidthSpy = signalSpy.createObject(control, { target: control, signalName: "implicitWidthChanged"} )
var implicitHeightSpy = signalSpy.createObject(control, { target: control, signalName: "implicitHeightChanged"} )
+
control.background.implicitWidth = 400
control.background.implicitHeight = 200
compare(control.implicitWidth, 400)
@@ -79,6 +80,24 @@ TestCase {
compare(implicitWidthSpy.count, 1)
compare(implicitHeightSpy.count, 1)
+ control.background = null
+ compare(control.implicitWidth, control.leftPadding + control.rightPadding)
+ compare(control.implicitHeight, control.contentHeight + control.topPadding + control.bottomPadding)
+ compare(implicitWidthSpy.count, 2)
+ compare(implicitHeightSpy.count, 2)
+
+ control.text = "TextField"
+ compare(control.implicitWidth, control.contentWidth + control.leftPadding + control.rightPadding)
+ compare(control.implicitHeight, control.contentHeight + control.topPadding + control.bottomPadding)
+ compare(implicitWidthSpy.count, 3)
+ compare(implicitHeightSpy.count, 2)
+
+ control.placeholderText = "..."
+ verify(control.implicitWidth < control.contentWidth + control.leftPadding + control.rightPadding)
+ compare(control.implicitHeight, control.contentHeight + control.topPadding + control.bottomPadding)
+ compare(implicitWidthSpy.count, 4)
+ compare(implicitHeightSpy.count, 2)
+
control.destroy()
}
diff --git a/tests/auto/drawer/data/hover.qml b/tests/auto/drawer/data/applicationwindow-hover.qml
index 5ac41457..5ac41457 100644
--- a/tests/auto/drawer/data/hover.qml
+++ b/tests/auto/drawer/data/applicationwindow-hover.qml
diff --git a/tests/auto/drawer/data/applicationwindow.qml b/tests/auto/drawer/data/applicationwindow.qml
index a826efab..0aa4b34e 100644
--- a/tests/auto/drawer/data/applicationwindow.qml
+++ b/tests/auto/drawer/data/applicationwindow.qml
@@ -51,12 +51,5 @@ ApplicationWindow {
id: drawer
width: 200
height: 200
-
- MouseArea {
- // QTBUG-54629
- anchors.fill: parent
- anchors.margins: -Qt.styleHints.startDragDistance
- Rectangle { color: "red"; opacity: 0.25; anchors.fill: parent }
- }
}
}
diff --git a/tests/auto/drawer/data/multiple.qml b/tests/auto/drawer/data/multiple.qml
new file mode 100644
index 00000000..b2ef9781
--- /dev/null
+++ b/tests/auto/drawer/data/multiple.qml
@@ -0,0 +1,85 @@
+/****************************************************************************
+**
+** 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 leftDrawer: leftDrawer
+ property alias leftButton: leftButton
+
+ property alias rightDrawer: rightDrawer
+ property alias rightButton: rightButton
+
+ property alias contentButton: contentButton
+
+ Drawer {
+ id: leftDrawer
+ width: 300
+ height: 400
+ z: 1
+
+ contentItem: Button {
+ id: leftButton
+ text: "Left"
+ }
+ }
+
+ Button {
+ id: contentButton
+ text: "Content"
+ anchors.fill: parent
+ }
+
+ Drawer {
+ id: rightDrawer
+ width: 300
+ height: 400
+ edge: Qt.RightEdge
+
+ contentItem: Button {
+ id: rightButton
+ text: "Right"
+ }
+ }
+}
diff --git a/tests/auto/drawer/data/window-hover.qml b/tests/auto/drawer/data/window-hover.qml
new file mode 100644
index 00000000..872b934e
--- /dev/null
+++ b/tests/auto/drawer/data/window-hover.qml
@@ -0,0 +1,73 @@
+/****************************************************************************
+**
+** 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 {
+ width: 400
+ height: 400
+
+ property alias drawer: drawer
+ property alias backgroundButton: backgroundButton
+ property alias drawerButton: drawerButton
+
+ Button {
+ id: backgroundButton
+ text: "Background"
+ anchors.fill: parent
+ }
+
+ Drawer {
+ id: drawer
+ width: 100
+ height: 400
+ topPadding: 2
+ leftPadding: 2
+ rightPadding: 2
+ bottomPadding: 2
+
+ contentItem: Button {
+ id: drawerButton
+ text: "Drawer"
+ }
+ }
+}
diff --git a/tests/auto/drawer/data/window.qml b/tests/auto/drawer/data/window.qml
new file mode 100644
index 00000000..47ef5cb0
--- /dev/null
+++ b/tests/auto/drawer/data/window.qml
@@ -0,0 +1,56 @@
+/****************************************************************************
+**
+** 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 {
+ width: 400
+ height: 400
+
+ property alias drawer: drawer
+
+ Drawer {
+ id: drawer
+ width: 200
+ height: 200
+ }
+}
diff --git a/tests/auto/drawer/tst_drawer.cpp b/tests/auto/drawer/tst_drawer.cpp
index 0507d01e..8f023c29 100644
--- a/tests/auto/drawer/tst_drawer.cpp
+++ b/tests/auto/drawer/tst_drawer.cpp
@@ -42,6 +42,7 @@
#include <QtGui/qstylehints.h>
#include <QtGui/qguiapplication.h>
#include <QtQuickTemplates2/private/qquickapplicationwindow_p.h>
+#include <QtQuickTemplates2/private/qquickoverlay_p.h>
#include <QtQuickTemplates2/private/qquickdrawer_p.h>
#include <QtQuickTemplates2/private/qquickbutton_p.h>
@@ -52,6 +53,11 @@ class tst_Drawer : public QQmlDataTest
Q_OBJECT
private slots:
+ void visible_data();
+ void visible();
+
+ void state();
+
void position_data();
void position();
@@ -62,8 +68,158 @@ private slots:
void hover_data();
void hover();
+
+ void multiple();
};
+void tst_Drawer::visible_data()
+{
+ QTest::addColumn<QString>("source");
+ QTest::newRow("Window") << "window.qml";
+ QTest::newRow("ApplicationWindow") << "applicationwindow.qml";
+}
+
+void tst_Drawer::visible()
+{
+ QFETCH(QString, source);
+ QQuickApplicationHelper helper(this, source);
+
+ QQuickWindow *window = helper.window;
+ window->show();
+ QVERIFY(QTest::qWaitForWindowExposed(window));
+
+ QQuickDrawer *drawer = window->property("drawer").value<QQuickDrawer*>();
+ QVERIFY(drawer);
+ QQuickItem *popupItem = drawer->popupItem();
+
+ QCOMPARE(drawer->isVisible(), false);
+ QCOMPARE(drawer->position(), qreal(0.0));
+
+ QQuickOverlay *overlay = QQuickOverlay::overlay(window);
+ QVERIFY(overlay);
+ QVERIFY(!overlay->childItems().contains(popupItem));
+
+ drawer->open();
+ QVERIFY(drawer->isVisible());
+ QVERIFY(overlay->childItems().contains(popupItem));
+ QTRY_COMPARE(drawer->position(), qreal(1.0));
+
+ drawer->close();
+ QTRY_VERIFY(!drawer->isVisible());
+ QTRY_COMPARE(drawer->position(), qreal(0.0));
+ QVERIFY(!overlay->childItems().contains(popupItem));
+
+ drawer->setVisible(true);
+ QVERIFY(drawer->isVisible());
+ QVERIFY(overlay->childItems().contains(popupItem));
+ QTRY_COMPARE(drawer->position(), qreal(1.0));
+
+ drawer->setVisible(false);
+ QTRY_VERIFY(!drawer->isVisible());
+ QTRY_COMPARE(drawer->position(), qreal(0.0));
+ QTRY_VERIFY(!overlay->childItems().contains(popupItem));
+}
+
+void tst_Drawer::state()
+{
+ QQuickApplicationHelper helper(this, "applicationwindow.qml");
+
+ QQuickWindow *window = helper.window;
+ window->show();
+ QVERIFY(QTest::qWaitForWindowExposed(window));
+
+ QQuickDrawer *drawer = window->property("drawer").value<QQuickDrawer*>();
+ QVERIFY(drawer);
+
+ QCOMPARE(drawer->isVisible(), false);
+
+ QSignalSpy visibleChangedSpy(drawer, SIGNAL(visibleChanged()));
+ QSignalSpy aboutToShowSpy(drawer, SIGNAL(aboutToShow()));
+ QSignalSpy aboutToHideSpy(drawer, SIGNAL(aboutToHide()));
+ QSignalSpy openedSpy(drawer, SIGNAL(opened()));
+ QSignalSpy closedSpy(drawer, SIGNAL(closed()));
+
+ QVERIFY(visibleChangedSpy.isValid());
+ QVERIFY(aboutToShowSpy.isValid());
+ QVERIFY(aboutToHideSpy.isValid());
+ QVERIFY(openedSpy.isValid());
+ QVERIFY(closedSpy.isValid());
+
+ int visibleChangedCount = 0;
+ int aboutToShowCount = 0;
+ int aboutToHideCount = 0;
+ int openedCount = 0;
+ int closedCount = 0;
+
+ // open programmatically...
+ drawer->open();
+ QCOMPARE(visibleChangedSpy.count(), ++visibleChangedCount);
+ QCOMPARE(aboutToShowSpy.count(), ++aboutToShowCount);
+ QCOMPARE(aboutToHideSpy.count(), aboutToHideCount);
+ QCOMPARE(openedSpy.count(), openedCount);
+ QCOMPARE(closedSpy.count(), closedCount);
+
+ // ...and wait until fully open
+ QVERIFY(openedSpy.wait());
+ QCOMPARE(visibleChangedSpy.count(), visibleChangedCount);
+ QCOMPARE(aboutToShowSpy.count(), aboutToShowCount);
+ QCOMPARE(aboutToHideSpy.count(), aboutToHideCount);
+ QCOMPARE(openedSpy.count(), ++openedCount);
+ QCOMPARE(closedSpy.count(), closedCount);
+
+ // close programmatically...
+ drawer->close();
+ QCOMPARE(visibleChangedSpy.count(), visibleChangedCount);
+ QCOMPARE(aboutToShowSpy.count(), aboutToShowCount);
+ QCOMPARE(aboutToHideSpy.count(), ++aboutToHideCount);
+ QCOMPARE(openedSpy.count(), openedCount);
+ QCOMPARE(closedSpy.count(), closedCount);
+
+ // ...and wait until fully closed
+ QVERIFY(closedSpy.wait());
+ QCOMPARE(visibleChangedSpy.count(), ++visibleChangedCount);
+ QCOMPARE(aboutToShowSpy.count(), aboutToShowCount);
+ QCOMPARE(aboutToHideSpy.count(), aboutToHideCount);
+ QCOMPARE(openedSpy.count(), openedCount);
+ QCOMPARE(closedSpy.count(), ++closedCount);
+
+ // open interactively...
+ QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, QPoint(0, drawer->height() / 2));
+ QTest::mouseMove(window, QPoint(drawer->width() * 0.2, drawer->height() / 2), 16);
+ QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, QPoint(drawer->width() * 0.8, drawer->height() / 2), 16);
+ QCOMPARE(visibleChangedSpy.count(), ++visibleChangedCount);
+ QCOMPARE(aboutToShowSpy.count(), ++aboutToShowCount);
+ QCOMPARE(aboutToHideSpy.count(), aboutToHideCount);
+ QCOMPARE(openedSpy.count(), openedCount);
+ QCOMPARE(closedSpy.count(), closedCount);
+
+ // ...and wait until fully open
+ QVERIFY(openedSpy.wait());
+ QCOMPARE(visibleChangedSpy.count(), visibleChangedCount);
+ QCOMPARE(aboutToShowSpy.count(), aboutToShowCount);
+ QCOMPARE(aboutToHideSpy.count(), aboutToHideCount);
+ QCOMPARE(openedSpy.count(), ++openedCount);
+ QCOMPARE(closedSpy.count(), closedCount);
+
+ // close interactively...
+ QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, QPoint(drawer->width(), drawer->height() / 2));
+ QTest::mouseMove(window, QPoint(drawer->width() * 0.8, drawer->height() / 2), 16);
+ QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, QPoint(drawer->width() * 0.2, drawer->height() / 2), 16);
+ QCOMPARE(visibleChangedSpy.count(), visibleChangedCount);
+ QCOMPARE(aboutToShowSpy.count(), aboutToShowCount);
+ QCOMPARE(aboutToHideSpy.count(), ++aboutToHideCount);
+ QCOMPARE(openedSpy.count(), openedCount);
+ QCOMPARE(closedSpy.count(), closedCount);
+
+ // ...and wait until fully closed
+ QVERIFY(closedSpy.wait());
+ QCOMPARE(visibleChangedSpy.count(), ++visibleChangedCount);
+ QCOMPARE(aboutToShowSpy.count(), aboutToShowCount);
+ QCOMPARE(aboutToHideSpy.count(), aboutToHideCount);
+ QCOMPARE(openedSpy.count(), openedCount);
+ QCOMPARE(closedSpy.count(), ++closedCount);
+}
+
void tst_Drawer::position_data()
{
QTest::addColumn<Qt::Edge>("edge");
@@ -86,19 +242,22 @@ void tst_Drawer::position()
QQuickApplicationHelper helper(this, QStringLiteral("applicationwindow.qml"));
- QQuickApplicationWindow *window = helper.window;
+ QQuickApplicationWindow *window = helper.appWindow;
window->show();
window->requestActivate();
QVERIFY(QTest::qWaitForWindowActive(window));
- QQuickDrawer *drawer = helper.window->property("drawer").value<QQuickDrawer*>();
+ QQuickDrawer *drawer = helper.appWindow->property("drawer").value<QQuickDrawer*>();
QVERIFY(drawer);
drawer->setEdge(edge);
QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, from);
QTest::mouseMove(window, to);
QCOMPARE(drawer->position(), position);
+
+ // moved half-way open at almost infinite speed => snap to open
QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, to);
+ QTRY_COMPARE(drawer->position(), 1.0);
}
void tst_Drawer::dragMargin_data()
@@ -110,8 +269,8 @@ void tst_Drawer::dragMargin_data()
QTest::newRow("left:0") << Qt::LeftEdge << qreal(0) << qreal(0) << qreal(0);
QTest::newRow("left:-1") << Qt::LeftEdge << qreal(-1) << qreal(0) << qreal(0);
- QTest::newRow("left:startDragDistance") << Qt::LeftEdge << qreal(QGuiApplication::styleHints()->startDragDistance()) << qreal(0.25) << qreal(0);
- QTest::newRow("left:startDragDistance*2") << Qt::LeftEdge << qreal(QGuiApplication::styleHints()->startDragDistance() * 2) << qreal(0.25) << qreal(0);
+ QTest::newRow("left:startDragDistance") << Qt::LeftEdge << qreal(QGuiApplication::styleHints()->startDragDistance()) << qreal(0.45) << qreal(0);
+ QTest::newRow("left:startDragDistance*2") << Qt::LeftEdge << qreal(QGuiApplication::styleHints()->startDragDistance() * 2) << qreal(0.45) << qreal(0);
QTest::newRow("right:0") << Qt::RightEdge << qreal(0) << qreal(0) << qreal(0);
QTest::newRow("right:-1") << Qt::RightEdge << qreal(-1) << qreal(0) << qreal(0);
@@ -128,84 +287,92 @@ void tst_Drawer::dragMargin()
QQuickApplicationHelper helper(this, QStringLiteral("applicationwindow.qml"));
- QQuickApplicationWindow *window = helper.window;
+ QQuickApplicationWindow *window = helper.appWindow;
window->show();
window->requestActivate();
QVERIFY(QTest::qWaitForWindowActive(window));
- QQuickDrawer *drawer = helper.window->property("drawer").value<QQuickDrawer*>();
+ QQuickDrawer *drawer = helper.appWindow->property("drawer").value<QQuickDrawer*>();
QVERIFY(drawer);
drawer->setEdge(edge);
drawer->setDragMargin(dragMargin);
// drag from the left
int leftX = qMax<int>(0, dragMargin);
+ int leftDistance = drawer->width() * 0.45;
+ QVERIFY(leftDistance > QGuiApplication::styleHints()->startDragDistance());
QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, QPoint(leftX, drawer->height() / 2));
- QTest::mouseMove(window, QPoint(drawer->width() * 0.25, drawer->height() / 2));
+ QTest::mouseMove(window, QPoint(leftDistance, drawer->height() / 2));
QCOMPARE(drawer->position(), dragFromLeft);
- QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, QPoint(drawer->width() * 0.25, drawer->height() / 2));
+ QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, QPoint(leftDistance, drawer->height() / 2));
drawer->close();
QTRY_COMPARE(drawer->position(), qreal(0.0));
// drag from the right
int rightX = qMin<int>(window->width() - 1, window->width() - dragMargin);
+ int rightDistance = drawer->width() * 0.75;
+ QVERIFY(rightDistance > QGuiApplication::styleHints()->startDragDistance());
QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, QPoint(rightX, drawer->height() / 2));
- QTest::mouseMove(window, QPoint(window->width() - drawer->width() * 0.75, drawer->height() / 2));
+ QTest::mouseMove(window, QPoint(window->width() - rightDistance, drawer->height() / 2));
QCOMPARE(drawer->position(), dragFromRight);
- QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, QPoint(window->width() - drawer->width() * 0.75, drawer->height() / 2));
+ QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, QPoint(window->width() - rightDistance, drawer->height() / 2));
}
void tst_Drawer::reposition()
{
QQuickApplicationHelper helper(this, QStringLiteral("applicationwindow.qml"));
- QQuickApplicationWindow *window = helper.window;
+ QQuickApplicationWindow *window = helper.appWindow;
window->show();
window->requestActivate();
QVERIFY(QTest::qWaitForWindowActive(window));
- QQuickDrawer *drawer = helper.window->property("drawer").value<QQuickDrawer*>();
+ QQuickDrawer *drawer = helper.appWindow->property("drawer").value<QQuickDrawer*>();
QVERIFY(drawer);
drawer->setEdge(Qt::RightEdge);
drawer->open();
QTRY_COMPARE(drawer->popupItem()->x(), window->width() - drawer->width());
- drawer->close();
- QTRY_COMPARE(drawer->popupItem()->x(), static_cast<qreal>(window->width()));
-
window->setWidth(window->width() + 100);
+ QTRY_COMPARE(drawer->popupItem()->x(), window->width() - drawer->width());
+
+ drawer->close();
QTRY_COMPARE(drawer->popupItem()->x(), static_cast<qreal>(window->width()));
}
void tst_Drawer::hover_data()
{
+ QTest::addColumn<QString>("source");
QTest::addColumn<bool>("modal");
- QTest::newRow("modal") << true;
- QTest::newRow("modeless") << false;
+ QTest::newRow("Window:modal") << "window-hover.qml" << true;
+ QTest::newRow("Window:modeless") << "window-hover.qml" << false;
+ QTest::newRow("ApplicationWindow:modal") << "applicationwindow-hover.qml" << true;
+ QTest::newRow("ApplicationWindow:modeless") << "applicationwindow-hover.qml" << false;
}
void tst_Drawer::hover()
{
+ QFETCH(QString, source);
QFETCH(bool, modal);
- QQuickApplicationHelper helper(this, QStringLiteral("hover.qml"));
- QQuickApplicationWindow *window = helper.window;
+ QQuickApplicationHelper helper(this, source);
+ QQuickWindow *window = helper.window;
window->show();
window->requestActivate();
QVERIFY(QTest::qWaitForWindowActive(window));
- QQuickDrawer *drawer = helper.window->property("drawer").value<QQuickDrawer*>();
+ QQuickDrawer *drawer = window->property("drawer").value<QQuickDrawer*>();
QVERIFY(drawer);
drawer->setModal(modal);
- QQuickButton *backgroundButton = helper.window->property("backgroundButton").value<QQuickButton*>();
+ QQuickButton *backgroundButton = window->property("backgroundButton").value<QQuickButton*>();
QVERIFY(backgroundButton);
backgroundButton->setHoverEnabled(true);
- QQuickButton *drawerButton = helper.window->property("drawerButton").value<QQuickButton*>();
+ QQuickButton *drawerButton = window->property("drawerButton").value<QQuickButton*>();
QVERIFY(drawerButton);
drawerButton->setHoverEnabled(true);
@@ -239,6 +406,127 @@ void tst_Drawer::hover()
QVERIFY(backgroundButton->isHovered());
}
+void tst_Drawer::multiple()
+{
+ QQuickApplicationHelper helper(this, QStringLiteral("multiple.qml"));
+ QQuickWindow *window = helper.window;
+ window->show();
+ QVERIFY(QTest::qWaitForWindowExposed(window));
+
+ QQuickDrawer *leftDrawer = window->property("leftDrawer").value<QQuickDrawer*>();
+ QVERIFY(leftDrawer);
+ QQuickButton *leftButton = window->property("leftButton").value<QQuickButton*>();
+ QVERIFY(leftButton);
+ QSignalSpy leftClickSpy(leftButton, SIGNAL(clicked()));
+ QVERIFY(leftClickSpy.isValid());
+
+ QQuickDrawer *rightDrawer = window->property("rightDrawer").value<QQuickDrawer*>();
+ QVERIFY(rightDrawer);
+ QQuickButton *rightButton = window->property("rightButton").value<QQuickButton*>();
+ QVERIFY(rightButton);
+ QSignalSpy rightClickSpy(rightButton, SIGNAL(clicked()));
+ QVERIFY(rightClickSpy.isValid());
+
+ QQuickButton *contentButton = window->property("contentButton").value<QQuickButton*>();
+ QVERIFY(contentButton);
+ QSignalSpy contentClickSpy(contentButton, SIGNAL(clicked()));
+ QVERIFY(contentClickSpy.isValid());
+
+ // no drawers open, click the content
+ QTest::mouseClick(window, Qt::LeftButton);
+ QCOMPARE(contentClickSpy.count(), 1);
+ QCOMPARE(leftClickSpy.count(), 0);
+ QCOMPARE(rightClickSpy.count(), 0);
+
+ // drag the left drawer open
+ QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, QPoint(0, window->height() / 2));
+ QTest::mouseMove(window, QPoint(leftDrawer->width() / 2, window->height() / 2));
+ QCOMPARE(leftDrawer->position(), 0.5);
+ QCOMPARE(rightDrawer->position(), 0.0);
+ QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, QPoint(leftDrawer->width() / 2, window->height() / 2));
+ QTRY_COMPARE(leftDrawer->position(), 1.0);
+ QCOMPARE(rightDrawer->position(), 0.0);
+
+ // cannot drag the right drawer while the left drawer is open
+ QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, QPoint(window->width() - 1, window->height() / 2));
+ QTest::mouseMove(window, QPoint(window->width() - leftDrawer->width() / 2, window->height() / 2));
+ QCOMPARE(leftDrawer->position(), 1.0);
+ QCOMPARE(rightDrawer->position(), 0.0);
+ QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, QPoint(window->width() - leftDrawer->width() / 2, window->height() / 2));
+ QCOMPARE(rightDrawer->position(), 0.0);
+ QCOMPARE(leftDrawer->position(), 1.0);
+
+ // open the right drawer below the left drawer
+ rightDrawer->open();
+ QTRY_COMPARE(rightDrawer->position(), 1.0);
+
+ // click the left drawer's button
+ QTest::mouseClick(window, Qt::LeftButton);
+ QCOMPARE(contentClickSpy.count(), 1);
+ QCOMPARE(leftClickSpy.count(), 1);
+ QCOMPARE(rightClickSpy.count(), 0);
+
+ // click the left drawer's background (button disabled, don't leak through to the right drawer below)
+ leftButton->setEnabled(false);
+ QTest::mouseClick(window, Qt::LeftButton);
+ QCOMPARE(contentClickSpy.count(), 1);
+ QCOMPARE(leftClickSpy.count(), 1);
+ QCOMPARE(rightClickSpy.count(), 0);
+ leftButton->setEnabled(true);
+
+ // click the overlay of the left drawer (don't leak through to right drawer below)
+ QTest::mouseClick(window, Qt::LeftButton, Qt::NoModifier, QPoint(window->width() - (window->width() - leftDrawer->width()) / 2, window->height() / 2));
+ QCOMPARE(contentClickSpy.count(), 1);
+ QCOMPARE(leftClickSpy.count(), 1);
+ QCOMPARE(rightClickSpy.count(), 0);
+ QTRY_VERIFY(!leftDrawer->isVisible());
+
+ // click the right drawer's button
+ QTest::mouseClick(window, Qt::LeftButton);
+ QCOMPARE(contentClickSpy.count(), 1);
+ QCOMPARE(leftClickSpy.count(), 1);
+ QCOMPARE(rightClickSpy.count(), 1);
+
+ // cannot drag the left drawer while the right drawer is open
+ QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, QPoint(0, window->height() / 2));
+ QTest::mouseMove(window, QPoint(leftDrawer->width() / 2, window->height() / 2));
+ QCOMPARE(leftDrawer->position(), 0.0);
+ QCOMPARE(rightDrawer->position(), 1.0);
+ QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, QPoint(leftDrawer->width() / 2, window->height() / 2));
+ QCOMPARE(leftDrawer->position(), 0.0);
+ QCOMPARE(rightDrawer->position(), 1.0);
+
+ // click the right drawer's background (button disabled, don't leak through to the content below)
+ rightButton->setEnabled(false);
+ QTest::mouseClick(window, Qt::LeftButton);
+ QCOMPARE(contentClickSpy.count(), 1);
+ QCOMPARE(leftClickSpy.count(), 1);
+ QCOMPARE(rightClickSpy.count(), 1);
+ rightButton->setEnabled(true);
+
+ // click the overlay of the right drawer (don't leak through to the content below)
+ QTest::mouseClick(window, Qt::LeftButton, Qt::NoModifier, QPoint((window->width() - rightDrawer->width()) / 2, window->height() / 2));
+ QCOMPARE(contentClickSpy.count(), 1);
+ QCOMPARE(leftClickSpy.count(), 1);
+ QCOMPARE(rightClickSpy.count(), 1);
+ QTRY_VERIFY(!rightDrawer->isVisible());
+
+ // no drawers open, click the content
+ QTest::mouseClick(window, Qt::LeftButton);
+ QCOMPARE(contentClickSpy.count(), 2);
+ QCOMPARE(leftClickSpy.count(), 1);
+ QCOMPARE(rightClickSpy.count(), 1);
+
+ // drag the right drawer open
+ QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, QPoint(window->width() - 1, window->height() / 2));
+ QTest::mouseMove(window, QPoint(window->width() - rightDrawer->width() / 2, window->height() / 2));
+ QCOMPARE(rightDrawer->position(), 0.5);
+ QCOMPARE(leftDrawer->position(), 0.0);
+ QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, QPoint(window->width() - rightDrawer->width() / 2, window->height() / 2));
+ QTRY_COMPARE(rightDrawer->position(), 1.0);
+ QCOMPARE(leftDrawer->position(), 0.0);
+}
+
QTEST_MAIN(tst_Drawer)
#include "tst_drawer.moc"
diff --git a/tests/auto/focus/tst_focus.cpp b/tests/auto/focus/tst_focus.cpp
index cab2625a..dec4fecd 100644
--- a/tests/auto/focus/tst_focus.cpp
+++ b/tests/auto/focus/tst_focus.cpp
@@ -107,7 +107,7 @@ void tst_focus::navigation()
QVERIFY(QTest::qWaitForWindowActive(&view));
QVERIFY(QGuiApplication::focusWindow() == &view);
- foreach (const QString &name, order) {
+ for (const QString &name : qAsConst(order)) {
QKeyEvent event(QEvent::KeyPress, key, Qt::NoModifier);
QGuiApplication::sendEvent(&view, &event);
QVERIFY(event.isAccepted());
diff --git a/tests/auto/menu/tst_menu.cpp b/tests/auto/menu/tst_menu.cpp
index 28882f04..0635ad81 100644
--- a/tests/auto/menu/tst_menu.cpp
+++ b/tests/auto/menu/tst_menu.cpp
@@ -73,7 +73,7 @@ void tst_menu::defaults()
{
QQuickApplicationHelper helper(this, QLatin1String("applicationwindow.qml"));
- QQuickMenu *emptyMenu = helper.window->property("emptyMenu").value<QQuickMenu*>();
+ QQuickMenu *emptyMenu = helper.appWindow->property("emptyMenu").value<QQuickMenu*>();
QCOMPARE(emptyMenu->isVisible(), false);
QCOMPARE(emptyMenu->contentItem()->property("currentIndex"), QVariant(-1));
}
@@ -82,7 +82,7 @@ void tst_menu::mouse()
{
QQuickApplicationHelper helper(this, QLatin1String("applicationwindow.qml"));
- QQuickApplicationWindow *window = helper.window;
+ QQuickApplicationWindow *window = helper.appWindow;
window->show();
QVERIFY(QTest::qWaitForWindowActive(window));
@@ -154,7 +154,7 @@ void tst_menu::contextMenuKeyboard()
QQuickApplicationHelper helper(this, QLatin1String("applicationwindow.qml"));
- QQuickApplicationWindow *window = helper.window;
+ QQuickApplicationWindow *window = helper.appWindow;
window->show();
window->requestActivate();
QVERIFY(QTest::qWaitForWindowActive(window));
@@ -232,7 +232,7 @@ void tst_menu::menuButton()
QQuickApplicationHelper helper(this, QLatin1String("applicationwindow.qml"));
- QQuickApplicationWindow *window = helper.window;
+ QQuickApplicationWindow *window = helper.appWindow;
window->show();
window->requestActivate();
QVERIFY(QTest::qWaitForWindowActive(window));
@@ -256,7 +256,7 @@ void tst_menu::menuButton()
void tst_menu::addItem()
{
QQuickApplicationHelper helper(this, QLatin1String("addItem.qml"));
- QQuickApplicationWindow *window = helper.window;
+ QQuickApplicationWindow *window = helper.appWindow;
window->show();
QVERIFY(QTest::qWaitForWindowActive(window));
@@ -277,7 +277,7 @@ void tst_menu::addItem()
void tst_menu::menuSeparator()
{
QQuickApplicationHelper helper(this, QLatin1String("menuSeparator.qml"));
- QQuickApplicationWindow *window = helper.window;
+ QQuickWindow *window = helper.window;
window->show();
QVERIFY(QTest::qWaitForWindowActive(window));
diff --git a/tests/auto/popup/data/hover.qml b/tests/auto/popup/data/applicationwindow-hover.qml
index 044d983c..044d983c 100644
--- a/tests/auto/popup/data/hover.qml
+++ b/tests/auto/popup/data/applicationwindow-hover.qml
diff --git a/tests/auto/popup/data/window-hover.qml b/tests/auto/popup/data/window-hover.qml
new file mode 100644
index 00000000..78d650fa
--- /dev/null
+++ b/tests/auto/popup/data/window-hover.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.Window 2.2
+import QtQuick.Controls 2.0
+
+Window {
+ width: 400
+ height: 400
+
+ property alias popup: popup
+ property alias parentButton: parentButton
+ property alias childButton: childButton
+
+ Button {
+ id: parentButton
+ text: "Parent"
+ anchors.fill: parent
+
+ Popup {
+ id: popup
+ x: 1
+ y: 1
+ padding: 1
+
+ Button {
+ id: childButton
+ text: "Child"
+ }
+ }
+ }
+}
diff --git a/tests/auto/popup/data/window.qml b/tests/auto/popup/data/window.qml
new file mode 100644
index 00000000..92bfbd70
--- /dev/null
+++ b/tests/auto/popup/data/window.qml
@@ -0,0 +1,84 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 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 {
+ width: 400
+ height: 400
+
+ property alias popup: popup
+ property alias popup2: popup2
+ property alias button: button
+
+ Button {
+ id: button
+ text: "Open"
+ anchors.centerIn: parent
+ anchors.verticalCenterOffset: -height
+
+ Popup {
+ id: popup
+ y: parent.height
+
+ Text {
+ color: "white"
+ text: "Hello, world!"
+
+ MouseArea {
+ anchors.fill: parent
+ onClicked: popup.close()
+ }
+ }
+ }
+ }
+
+ Popup {
+ id: popup2
+ y: popup.y
+ z: 1
+ contentItem: Text {
+ text: "Popup2"
+ font.pixelSize: 36
+ }
+ }
+}
diff --git a/tests/auto/popup/tst_popup.cpp b/tests/auto/popup/tst_popup.cpp
index 1166b517..a6848fc8 100644
--- a/tests/auto/popup/tst_popup.cpp
+++ b/tests/auto/popup/tst_popup.cpp
@@ -51,8 +51,12 @@ class tst_popup : public QQmlDataTest
Q_OBJECT
private slots:
+ void visible_data();
void visible();
+ void state();
+ void overlay_data();
void overlay();
+ void zOrder_data();
void zOrder();
void windowChange();
void closePolicy_data();
@@ -64,46 +68,107 @@ private slots:
void parentDestroyed();
};
+void tst_popup::visible_data()
+{
+ QTest::addColumn<QString>("source");
+ QTest::newRow("Window") << "window.qml";
+ QTest::newRow("ApplicationWindow") << "applicationwindow.qml";
+}
+
void tst_popup::visible()
{
- QQuickApplicationHelper helper(this, QStringLiteral("applicationwindow.qml"));
+ QFETCH(QString, source);
+ QQuickApplicationHelper helper(this, source);
- QQuickApplicationWindow *window = helper.window;
+ QQuickWindow *window = helper.window;
window->show();
window->requestActivate();
QVERIFY(QTest::qWaitForWindowActive(window));
- QQuickPopup *popup = helper.window->property("popup").value<QQuickPopup*>();
+ QQuickPopup *popup = window->property("popup").value<QQuickPopup*>();
QVERIFY(popup);
QQuickItem *popupItem = popup->popupItem();
popup->open();
QVERIFY(popup->isVisible());
- QVERIFY(window->overlay()->childItems().contains(popupItem));
+
+ QQuickOverlay *overlay = QQuickOverlay::overlay(window);
+ QVERIFY(overlay);
+ QVERIFY(overlay->childItems().contains(popupItem));
popup->close();
QVERIFY(!popup->isVisible());
- QVERIFY(!window->overlay()->childItems().contains(popupItem));
+ QVERIFY(!overlay->childItems().contains(popupItem));
popup->setVisible(true);
QVERIFY(popup->isVisible());
- QVERIFY(window->overlay()->childItems().contains(popupItem));
+ QVERIFY(overlay->childItems().contains(popupItem));
popup->setVisible(false);
QVERIFY(!popup->isVisible());
- QVERIFY(!window->overlay()->childItems().contains(popupItem));
+ QVERIFY(!overlay->childItems().contains(popupItem));
+}
+
+void tst_popup::state()
+{
+ QQuickApplicationHelper helper(this, "applicationwindow.qml");
+
+ QQuickWindow *window = helper.window;
+ window->show();
+ QVERIFY(QTest::qWaitForWindowExposed(window));
+
+ QQuickPopup *popup = window->property("popup").value<QQuickPopup*>();
+ QVERIFY(popup);
+
+ QCOMPARE(popup->isVisible(), false);
+
+ QSignalSpy visibleChangedSpy(popup, SIGNAL(visibleChanged()));
+ QSignalSpy aboutToShowSpy(popup, SIGNAL(aboutToShow()));
+ QSignalSpy aboutToHideSpy(popup, SIGNAL(aboutToHide()));
+ QSignalSpy openedSpy(popup, SIGNAL(opened()));
+ QSignalSpy closedSpy(popup, SIGNAL(closed()));
+
+ QVERIFY(visibleChangedSpy.isValid());
+ QVERIFY(aboutToShowSpy.isValid());
+ QVERIFY(aboutToHideSpy.isValid());
+ QVERIFY(openedSpy.isValid());
+ QVERIFY(closedSpy.isValid());
+
+ popup->open();
+ QCOMPARE(visibleChangedSpy.count(), 1);
+ QCOMPARE(aboutToShowSpy.count(), 1);
+ QCOMPARE(aboutToHideSpy.count(), 0);
+ QTRY_COMPARE(openedSpy.count(), 1);
+ QCOMPARE(closedSpy.count(), 0);
+
+ popup->close();
+ QCOMPARE(visibleChangedSpy.count(), 2);
+ QCOMPARE(aboutToShowSpy.count(), 1);
+ QCOMPARE(aboutToHideSpy.count(), 1);
+ QCOMPARE(openedSpy.count(), 1);
+ QTRY_COMPARE(closedSpy.count(), 1);
+}
+
+void tst_popup::overlay_data()
+{
+ QTest::addColumn<QString>("source");
+ QTest::newRow("Window") << "window.qml";
+ QTest::newRow("ApplicationWindow") << "applicationwindow.qml";
}
void tst_popup::overlay()
{
- QQuickApplicationHelper helper(this, QStringLiteral("applicationwindow.qml"));
+ QFETCH(QString, source);
+ QQuickApplicationHelper helper(this, source);
- QQuickApplicationWindow *window = helper.window;
+ QQuickWindow *window = helper.window;
window->show();
window->requestActivate();
QVERIFY(QTest::qWaitForWindowActive(window));
- QQuickItem *overlay = window->overlay();
+ QQuickOverlay *overlay = QQuickOverlay::overlay(window);
+ QVERIFY(overlay);
+
QSignalSpy overlayPressedSignal(overlay, SIGNAL(pressed()));
QSignalSpy overlayReleasedSignal(overlay, SIGNAL(released()));
QVERIFY(overlayPressedSignal.isValid());
@@ -115,10 +180,10 @@ void tst_popup::overlay()
QCOMPARE(overlayPressedSignal.count(), 0);
QCOMPARE(overlayReleasedSignal.count(), 0);
- QQuickPopup *popup = helper.window->property("popup").value<QQuickPopup*>();
+ QQuickPopup *popup = window->property("popup").value<QQuickPopup*>();
QVERIFY(popup);
- QQuickButton *button = helper.window->property("button").value<QQuickButton*>();
+ QQuickButton *button = window->property("button").value<QQuickButton*>();
QVERIFY(button);
popup->open();
@@ -156,20 +221,28 @@ void tst_popup::overlay()
QVERIFY(!overlay->isVisible());
}
+void tst_popup::zOrder_data()
+{
+ QTest::addColumn<QString>("source");
+ QTest::newRow("Window") << "window.qml";
+ QTest::newRow("ApplicationWindow") << "applicationwindow.qml";
+}
+
void tst_popup::zOrder()
{
- QQuickApplicationHelper helper(this, QStringLiteral("applicationwindow.qml"));
+ QFETCH(QString, source);
+ QQuickApplicationHelper helper(this, source);
- QQuickApplicationWindow *window = helper.window;
+ QQuickWindow *window = helper.window;
window->show();
window->requestActivate();
QVERIFY(QTest::qWaitForWindowActive(window));
- QQuickPopup *popup = helper.window->property("popup").value<QQuickPopup*>();
+ QQuickPopup *popup = window->property("popup").value<QQuickPopup*>();
QVERIFY(popup);
popup->setModal(true);
- QQuickPopup *popup2 = helper.window->property("popup2").value<QQuickPopup*>();
+ QQuickPopup *popup2 = window->property("popup2").value<QQuickPopup*>();
QVERIFY(popup2);
popup2->setModal(true);
@@ -220,32 +293,42 @@ void tst_popup::closePolicy_data()
{
qRegisterMetaType<QQuickPopup::ClosePolicy>();
+ QTest::addColumn<QString>("source");
QTest::addColumn<QQuickPopup::ClosePolicy>("closePolicy");
- QTest::newRow("NoAutoClose") << static_cast<QQuickPopup::ClosePolicy>(QQuickPopup::NoAutoClose);
- QTest::newRow("CloseOnPressOutside") << static_cast<QQuickPopup::ClosePolicy>(QQuickPopup::CloseOnPressOutside);
- QTest::newRow("CloseOnPressOutsideParent") << static_cast<QQuickPopup::ClosePolicy>(QQuickPopup::CloseOnPressOutsideParent);
- QTest::newRow("CloseOnPressOutside|Parent") << static_cast<QQuickPopup::ClosePolicy>(QQuickPopup::CloseOnPressOutside | QQuickPopup::CloseOnPressOutsideParent);
- QTest::newRow("CloseOnReleaseOutside") << static_cast<QQuickPopup::ClosePolicy>(QQuickPopup::CloseOnReleaseOutside);
- QTest::newRow("CloseOnReleaseOutside|Parent") << static_cast<QQuickPopup::ClosePolicy>(QQuickPopup::CloseOnReleaseOutside | QQuickPopup::CloseOnReleaseOutsideParent);
- QTest::newRow("CloseOnEscape") << static_cast<QQuickPopup::ClosePolicy>(QQuickPopup::CloseOnEscape);
+ QTest::newRow("Window:NoAutoClose") << "window.qml"<< static_cast<QQuickPopup::ClosePolicy>(QQuickPopup::NoAutoClose);
+ QTest::newRow("Window:CloseOnPressOutside") << "window.qml"<< static_cast<QQuickPopup::ClosePolicy>(QQuickPopup::CloseOnPressOutside);
+ QTest::newRow("Window:CloseOnPressOutsideParent") << "window.qml"<< static_cast<QQuickPopup::ClosePolicy>(QQuickPopup::CloseOnPressOutsideParent);
+ QTest::newRow("Window:CloseOnPressOutside|Parent") << "window.qml"<< static_cast<QQuickPopup::ClosePolicy>(QQuickPopup::CloseOnPressOutside | QQuickPopup::CloseOnPressOutsideParent);
+ QTest::newRow("Window:CloseOnReleaseOutside") << "window.qml"<< static_cast<QQuickPopup::ClosePolicy>(QQuickPopup::CloseOnReleaseOutside);
+ QTest::newRow("Window:CloseOnReleaseOutside|Parent") << "window.qml"<< static_cast<QQuickPopup::ClosePolicy>(QQuickPopup::CloseOnReleaseOutside | QQuickPopup::CloseOnReleaseOutsideParent);
+ QTest::newRow("Window:CloseOnEscape") << "window.qml"<< static_cast<QQuickPopup::ClosePolicy>(QQuickPopup::CloseOnEscape);
+
+ QTest::newRow("ApplicationWindow:NoAutoClose") << "applicationwindow.qml"<< static_cast<QQuickPopup::ClosePolicy>(QQuickPopup::NoAutoClose);
+ QTest::newRow("ApplicationWindow:CloseOnPressOutside") << "applicationwindow.qml"<< static_cast<QQuickPopup::ClosePolicy>(QQuickPopup::CloseOnPressOutside);
+ QTest::newRow("ApplicationWindow:CloseOnPressOutsideParent") << "applicationwindow.qml"<< static_cast<QQuickPopup::ClosePolicy>(QQuickPopup::CloseOnPressOutsideParent);
+ QTest::newRow("ApplicationWindow:CloseOnPressOutside|Parent") << "applicationwindow.qml"<< static_cast<QQuickPopup::ClosePolicy>(QQuickPopup::CloseOnPressOutside | QQuickPopup::CloseOnPressOutsideParent);
+ QTest::newRow("ApplicationWindow:CloseOnReleaseOutside") << "applicationwindow.qml"<< static_cast<QQuickPopup::ClosePolicy>(QQuickPopup::CloseOnReleaseOutside);
+ QTest::newRow("ApplicationWindow:CloseOnReleaseOutside|Parent") << "applicationwindow.qml"<< static_cast<QQuickPopup::ClosePolicy>(QQuickPopup::CloseOnReleaseOutside | QQuickPopup::CloseOnReleaseOutsideParent);
+ QTest::newRow("ApplicationWindow:CloseOnEscape") << "applicationwindow.qml"<< static_cast<QQuickPopup::ClosePolicy>(QQuickPopup::CloseOnEscape);
}
void tst_popup::closePolicy()
{
+ QFETCH(QString, source);
QFETCH(QQuickPopup::ClosePolicy, closePolicy);
- QQuickApplicationHelper helper(this, QStringLiteral("applicationwindow.qml"));
+ QQuickApplicationHelper helper(this, source);
- QQuickApplicationWindow *window = helper.window;
+ QQuickWindow *window = helper.window;
window->show();
window->requestActivate();
QVERIFY(QTest::qWaitForWindowActive(window));
- QQuickPopup *popup = helper.window->property("popup").value<QQuickPopup*>();
+ QQuickPopup *popup = window->property("popup").value<QQuickPopup*>();
QVERIFY(popup);
- QQuickButton *button = helper.window->property("button").value<QQuickButton*>();
+ QQuickButton *button = window->property("button").value<QQuickButton*>();
QVERIFY(button);
popup->setModal(true);
@@ -308,15 +391,15 @@ void tst_popup::activeFocusOnClose1()
// Test that a popup that never sets focus: true (e.g. ToolTip) doesn't affect
// the active focus item when it closes.
QQuickApplicationHelper helper(this, QStringLiteral("activeFocusOnClose1.qml"));
- QQuickApplicationWindow *window = helper.window;
+ QQuickApplicationWindow *window = helper.appWindow;
window->show();
window->requestActivate();
QVERIFY(QTest::qWaitForWindowActive(window));
- QQuickPopup *focusedPopup = helper.window->property("focusedPopup").value<QQuickPopup*>();
+ QQuickPopup *focusedPopup = helper.appWindow->property("focusedPopup").value<QQuickPopup*>();
QVERIFY(focusedPopup);
- QQuickPopup *nonFocusedPopup = helper.window->property("nonFocusedPopup").value<QQuickPopup*>();
+ QQuickPopup *nonFocusedPopup = helper.appWindow->property("nonFocusedPopup").value<QQuickPopup*>();
QVERIFY(nonFocusedPopup);
focusedPopup->open();
@@ -338,18 +421,18 @@ void tst_popup::activeFocusOnClose2()
// calling forceActiveFocus() on another item) before it closes doesn't
// affect the active focus item when it closes.
QQuickApplicationHelper helper(this, QStringLiteral("activeFocusOnClose2.qml"));
- QQuickApplicationWindow *window = helper.window;
+ QQuickApplicationWindow *window = helper.appWindow;
window->show();
window->requestActivate();
QVERIFY(QTest::qWaitForWindowActive(window));
- QQuickPopup *popup1 = helper.window->property("popup1").value<QQuickPopup*>();
+ QQuickPopup *popup1 = helper.appWindow->property("popup1").value<QQuickPopup*>();
QVERIFY(popup1);
- QQuickPopup *popup2 = helper.window->property("popup2").value<QQuickPopup*>();
+ QQuickPopup *popup2 = helper.appWindow->property("popup2").value<QQuickPopup*>();
QVERIFY(popup2);
- QQuickButton *closePopup2Button = helper.window->property("closePopup2Button").value<QQuickButton*>();
+ QQuickButton *closePopup2Button = helper.appWindow->property("closePopup2Button").value<QQuickButton*>();
QVERIFY(closePopup2Button);
popup1->open();
@@ -369,31 +452,35 @@ void tst_popup::activeFocusOnClose2()
void tst_popup::hover_data()
{
+ QTest::addColumn<QString>("source");
QTest::addColumn<bool>("modal");
- QTest::newRow("modal") << true;
- QTest::newRow("modeless") << false;
+ QTest::newRow("Window:modal") << "window-hover.qml" << true;
+ QTest::newRow("Window:modeless") << "window-hover.qml" << false;
+ QTest::newRow("ApplicationWindow:modal") << "applicationwindow-hover.qml" << true;
+ QTest::newRow("ApplicationWindow:modeless") << "applicationwindow-hover.qml" << false;
}
void tst_popup::hover()
{
+ QFETCH(QString, source);
QFETCH(bool, modal);
- QQuickApplicationHelper helper(this, QStringLiteral("hover.qml"));
- QQuickApplicationWindow *window = helper.window;
+ QQuickApplicationHelper helper(this, source);
+ QQuickWindow *window = helper.window;
window->show();
window->requestActivate();
QVERIFY(QTest::qWaitForWindowActive(window));
- QQuickPopup *popup = helper.window->property("popup").value<QQuickPopup*>();
+ QQuickPopup *popup = window->property("popup").value<QQuickPopup*>();
QVERIFY(popup);
popup->setModal(modal);
- QQuickButton *parentButton = helper.window->property("parentButton").value<QQuickButton*>();
+ QQuickButton *parentButton = window->property("parentButton").value<QQuickButton*>();
QVERIFY(parentButton);
parentButton->setHoverEnabled(true);
- QQuickButton *childButton = helper.window->property("childButton").value<QQuickButton*>();
+ QQuickButton *childButton = window->property("childButton").value<QQuickButton*>();
QVERIFY(childButton);
childButton->setHoverEnabled(true);
diff --git a/tests/auto/qquickmaterialstyle/data/tst_material.qml b/tests/auto/qquickmaterialstyle/data/tst_material.qml
index 8eb6933c..63385a6e 100644
--- a/tests/auto/qquickmaterialstyle/data/tst_material.qml
+++ b/tests/auto/qquickmaterialstyle/data/tst_material.qml
@@ -74,6 +74,11 @@ TestCase {
}
Component {
+ id: applicationWindow
+ ApplicationWindow { }
+ }
+
+ Component {
id: styledWindow
Window {
Material.theme: Material.Dark
@@ -600,4 +605,76 @@ TestCase {
window.destroy()
}
+
+ Component {
+ id: backgroundControls
+ ApplicationWindow {
+ id: window
+ property Button button: Button { }
+ property ComboBox combobox: ComboBox { }
+ property Drawer drawer: Drawer { }
+ property GroupBox groupbox: GroupBox { Material.elevation: 10 }
+ property Frame frame: Frame { Material.elevation: 10 }
+ property Menu menu: Menu { }
+ property Page page: Page { }
+ property Pane pane: Pane { }
+ property Popup popup: Popup { }
+ property TabBar tabbar: TabBar { }
+ property ToolBar toolbar: ToolBar { }
+ property ToolTip tooltip: ToolTip { }
+ }
+ }
+
+ function test_background_data() {
+ return [
+ { tag: "button", inherit: false, wait: 400 },
+ { tag: "combobox", inherit: false, wait: 400 },
+ { tag: "drawer", inherit: true },
+ { tag: "groupbox", inherit: true },
+ { tag: "frame", inherit: true },
+ { tag: "menu", inherit: true },
+ { tag: "page", inherit: true },
+ { tag: "pane", inherit: true },
+ { tag: "popup", inherit: true },
+ { tag: "tabbar", inherit: true },
+ { tag: "toolbar", inherit: false },
+ { tag: "tooltip", inherit: false }
+ ]
+ }
+
+ function test_background(data) {
+ var window = backgroundControls.createObject(testCase)
+ verify(window)
+
+ var control = window[data.tag]
+ verify(control)
+
+ control.parent = window.contentItem
+ control.visible = true
+
+ var defaultBackground = control.background.color
+
+ window.Material.background = "#ff0000"
+ compare(window.color, "#ff0000")
+
+ // For controls that have an animated background color, we wait the length
+ // of the color animation to be sure that the color hasn't actually changed.
+ if (data.wait)
+ wait(data.wait)
+
+ // We want the control's background color to be equal to the window's background
+ // color, because we want the color to propagate to items that might actually use
+ // it... Button, ComboBox, ToolBar and ToolTip have a special background color,
+ // so they don't use the generic background color unless explicitly set, so we
+ // compare the actual background rect color instead.
+ if (data.inherit)
+ compare(control.background.color, "#ff0000")
+ else
+ compare(control.background.color, defaultBackground)
+
+ control.Material.background = "#0000ff"
+ tryCompare(control.background, "color", "#0000ff")
+
+ window.destroy()
+ }
}
diff --git a/tests/auto/qquickmaterialstyleconf/tst_qquickmaterialstyleconf.cpp b/tests/auto/qquickmaterialstyleconf/tst_qquickmaterialstyleconf.cpp
index c7670c21..c0db7c49 100644
--- a/tests/auto/qquickmaterialstyleconf/tst_qquickmaterialstyleconf.cpp
+++ b/tests/auto/qquickmaterialstyleconf/tst_qquickmaterialstyleconf.cpp
@@ -55,7 +55,7 @@ void tst_qquickmaterialstyleconf::conf()
{
QQuickApplicationHelper helper(this, QLatin1String("applicationwindow.qml"));
- QQuickApplicationWindow *window = helper.window;
+ QQuickApplicationWindow *window = helper.appWindow;
window->show();
QVERIFY(QTest::qWaitForWindowExposed(window));
// We specified a custom background color, so the window should have it.
diff --git a/tests/auto/qquickuniversalstyleconf/tst_qquickuniversalstyleconf.cpp b/tests/auto/qquickuniversalstyleconf/tst_qquickuniversalstyleconf.cpp
index c676ae6d..ce018a05 100644
--- a/tests/auto/qquickuniversalstyleconf/tst_qquickuniversalstyleconf.cpp
+++ b/tests/auto/qquickuniversalstyleconf/tst_qquickuniversalstyleconf.cpp
@@ -55,7 +55,7 @@ void tst_qquickuniversalstyleconf::conf()
{
QQuickApplicationHelper helper(this, QLatin1String("applicationwindow.qml"));
- QQuickApplicationWindow *window = helper.window;
+ QQuickApplicationWindow *window = helper.appWindow;
window->show();
QVERIFY(QTest::qWaitForWindowExposed(window));
// We specified a custom background color, so the window should have it.
diff --git a/tests/auto/sanity/tst_sanity.cpp b/tests/auto/sanity/tst_sanity.cpp
index 6b9e05ba..10348ba4 100644
--- a/tests/auto/sanity/tst_sanity.cpp
+++ b/tests/auto/sanity/tst_sanity.cpp
@@ -114,7 +114,8 @@ public:
QQmlJS::Parser parser(&engine);
if (!parser.parse()) {
- foreach (const QQmlJS::DiagnosticMessage &msg, parser.diagnosticMessages())
+ const auto diagnosticMessages = parser.diagnosticMessages();
+ for (const QQmlJS::DiagnosticMessage &msg : diagnosticMessages)
m_errors += QString("%s:%d : %s").arg(m_fileName).arg(msg.loc.startLine).arg(msg.message);
return false;
}
@@ -267,11 +268,12 @@ static void addTestRows(QQmlEngine *engine, const QString &sourcePath, const QSt
// the engine's import path. This way we can use QQmlComponent to load each QML file
// for benchmarking.
- QFileInfoList entries = QDir(QQC2_IMPORT_PATH "/" + sourcePath).entryInfoList(QStringList("*.qml"), QDir::Files);
- foreach (const QFileInfo &entry, entries) {
+ const QFileInfoList entries = QDir(QQC2_IMPORT_PATH "/" + sourcePath).entryInfoList(QStringList("*.qml"), QDir::Files);
+ for (const QFileInfo &entry : entries) {
QString name = entry.baseName();
if (!skiplist.contains(name)) {
- foreach (const QString &importPath, engine->importPathList()) {
+ const auto importPathList = engine->importPathList();
+ for (const QString &importPath : importPathList) {
QString name = entry.dir().dirName() + "/" + entry.fileName();
QString filePath = importPath + "/" + targetPath + "/" + entry.fileName();
if (QFile::exists(filePath)) {
@@ -296,7 +298,7 @@ void tst_Sanity::attachedObjects()
QSet<QString> classNames;
QScopedPointer<QObject> object(component.create());
QVERIFY2(object.data(), qPrintable(component.errorString()));
- foreach (QObject *object, *qt_qobjects) {
+ for (QObject *object : qAsConst(*qt_qobjects)) {
if (object->parent() == &engine)
continue; // allow "global" instances
QString className = object->metaObject()->className();
diff --git a/tests/auto/shared/visualtestutil.h b/tests/auto/shared/visualtestutil.h
index c1cc9c7d..c67e5bdc 100644
--- a/tests/auto/shared/visualtestutil.h
+++ b/tests/auto/shared/visualtestutil.h
@@ -118,9 +118,10 @@ namespace QQuickVisualTestUtil
component.loadUrl(testCase->testFileUrl(testFilePath));
QObject *rootObject = component.create();
cleanup.reset(rootObject);
- QVERIFY2(rootObject, qPrintable(QString::fromLatin1("Failed to create ApplicationWindow: %1").arg(component.errorString())));
+ QVERIFY2(rootObject, qPrintable(QString::fromLatin1("Failed to create window: %1").arg(component.errorString())));
- window = qobject_cast<QQuickApplicationWindow*>(rootObject);
+ window = qobject_cast<QQuickWindow*>(rootObject);
+ appWindow = qobject_cast<QQuickApplicationWindow*>(rootObject);
QVERIFY(window);
QVERIFY(!window->isVisible());
}
@@ -128,7 +129,8 @@ namespace QQuickVisualTestUtil
QQmlEngine engine;
QQmlComponent component;
QScopedPointer<QObject> cleanup;
- QQuickApplicationWindow *window;
+ QQuickApplicationWindow *appWindow;
+ QQuickWindow *window;
};
}
diff --git a/tests/auto/snippets/tst_snippets.cpp b/tests/auto/snippets/tst_snippets.cpp
index fb581b90..6ca9e72c 100644
--- a/tests/auto/snippets/tst_snippets.cpp
+++ b/tests/auto/snippets/tst_snippets.cpp
@@ -101,7 +101,7 @@ void tst_Snippets::screenshots()
QVERIFY(QTest::qWaitForWindowActive(&view));
bool generateScreenshot = true;
- foreach (const QString &baseName, nonVisualSnippets) {
+ for (const QString &baseName : qAsConst(nonVisualSnippets)) {
if (input.contains(baseName)) {
generateScreenshot = false;
break;
diff --git a/tests/benchmarks/creationtime/tst_creationtime.cpp b/tests/benchmarks/creationtime/tst_creationtime.cpp
index 877cf273..3eec3825 100644
--- a/tests/benchmarks/creationtime/tst_creationtime.cpp
+++ b/tests/benchmarks/creationtime/tst_creationtime.cpp
@@ -78,11 +78,12 @@ static void addTestRows(QQmlEngine *engine, const QString &sourcePath, const QSt
// the engine's import path. This way we can use QQmlComponent to load each QML file
// for benchmarking.
- QFileInfoList entries = QDir(QQC2_IMPORT_PATH "/" + sourcePath).entryInfoList(QStringList("*.qml"), QDir::Files);
- foreach (const QFileInfo &entry, entries) {
+ const QFileInfoList entries = QDir(QQC2_IMPORT_PATH "/" + sourcePath).entryInfoList(QStringList("*.qml"), QDir::Files);
+ for (const QFileInfo &entry : entries) {
QString name = entry.baseName();
if (!skiplist.contains(name)) {
- foreach (const QString &importPath, engine->importPathList()) {
+ const auto importPathList = engine->importPathList();
+ for (const QString &importPath : importPathList) {
QString name = entry.dir().dirName() + "/" + entry.fileName();
QString filePath = importPath + "/" + targetPath + "/" + entry.fileName();
if (QFile::exists(filePath)) {
diff --git a/tests/benchmarks/objectcount/tst_objectcount.cpp b/tests/benchmarks/objectcount/tst_objectcount.cpp
index 91c17fcc..14a950f3 100644
--- a/tests/benchmarks/objectcount/tst_objectcount.cpp
+++ b/tests/benchmarks/objectcount/tst_objectcount.cpp
@@ -100,7 +100,7 @@ static void printItems(const QList<QQuickItem *> &items)
std::cout << " QQuickItems: " << items.count() << " (total of QObjects: " << qt_qobjects->count() << ")" << std::endl;
if (qt_verbose) {
- foreach (QObject *object, *qt_qobjects)
+ for (QObject *object : qAsConst(*qt_qobjects))
qInfo() << "\t" << object;
}
}
@@ -118,11 +118,12 @@ static void addTestRows(QQmlEngine *engine, const QString &sourcePath, const QSt
// the engine's import path. This way we can use QQmlComponent to load each QML file
// for benchmarking.
- QFileInfoList entries = QDir(QQC2_IMPORT_PATH "/" + sourcePath).entryInfoList(QStringList("*.qml"), QDir::Files);
- foreach (const QFileInfo &entry, entries) {
+ const QFileInfoList entries = QDir(QQC2_IMPORT_PATH "/" + sourcePath).entryInfoList(QStringList("*.qml"), QDir::Files);
+ for (const QFileInfo &entry : entries) {
QString name = entry.baseName();
if (!skiplist.contains(name)) {
- foreach (const QString &importPath, engine->importPathList()) {
+ const auto importPathList = engine->importPathList();
+ for (const QString &importPath : importPathList) {
QString name = entry.dir().dirName() + "/" + entry.fileName();
QString filePath = importPath + "/" + targetPath + "/" + entry.fileName();
if (QFile::exists(filePath)) {
@@ -148,7 +149,7 @@ static void doBenchmark(QQmlEngine *engine, const QUrl &url)
QVERIFY2(object.data(), qPrintable(component.errorString()));
QList<QQuickItem *> items;
- foreach (QObject *object, *qt_qobjects()) {
+ for (QObject *object : qAsConst(*qt_qobjects)) {
QQuickItem *item = qobject_cast<QQuickItem *>(object);
if (item)
items += item;
diff --git a/tests/manual/buttons/ButtonLoader.qml b/tests/manual/buttons/ButtonLoader.qml
new file mode 100644
index 00000000..8793d98f
--- /dev/null
+++ b/tests/manual/buttons/ButtonLoader.qml
@@ -0,0 +1,91 @@
+/****************************************************************************
+**
+** 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.8
+import QtQuick.Controls 2.1
+
+Item {
+ id: root
+ implicitWidth: activeButton.implicitWidth
+ implicitHeight: activeButton.implicitHeight
+
+ property bool round: false
+
+ property string text
+ property bool flat
+ property bool hoverEnabled
+ property bool highlighted
+ property bool checked
+ property var down: undefined
+
+ property AbstractButton activeButton: round ? roundButton : button
+
+ Button {
+ id: button
+ visible: !round
+ text: root.text
+ flat: root.flat
+ hoverEnabled: root.hoverEnabled
+ highlighted: root.highlighted
+ checked: root.checked
+ down: root.down
+ enabled: root.enabled
+ }
+
+ RoundButton {
+ id: roundButton
+ visible: round
+ text: "\u2713"
+ flat: root.flat
+ hoverEnabled: root.hoverEnabled
+ highlighted: root.highlighted
+ checked: root.checked
+ down: root.down
+ enabled: root.enabled
+
+ Label {
+ text: root.text
+ font.pixelSize: roundButton.contentItem.font.pixelSize * 0.5
+ anchors.top: parent.bottom
+ anchors.topMargin: 2
+ anchors.horizontalCenter: parent.horizontalCenter
+ }
+ }
+}
diff --git a/tests/manual/buttons/buttons.pro b/tests/manual/buttons/buttons.pro
index d0a6eb28..2cb1c14c 100644
--- a/tests/manual/buttons/buttons.pro
+++ b/tests/manual/buttons/buttons.pro
@@ -3,4 +3,4 @@ TARGET = buttons
QT += qml quickcontrols2
SOURCES += buttons.cpp
-RESOURCES += buttons.qml
+RESOURCES += $$files(*.qml)
diff --git a/tests/manual/buttons/buttons.qml b/tests/manual/buttons/buttons.qml
index e1a393fd..b3aba775 100644
--- a/tests/manual/buttons/buttons.qml
+++ b/tests/manual/buttons/buttons.qml
@@ -62,6 +62,11 @@ ApplicationWindow {
text: "Hover"
checked: true
}
+ CheckBox {
+ id: roundBox
+ text: "Round"
+ checked: false
+ }
}
}
@@ -105,25 +110,25 @@ ApplicationWindow {
spacing: 20
padding: 20
- Button { text: "Normal"; flat: modelData.flat; hoverEnabled: hoverBox.checked }
- Button { text: "Disabled"; flat: modelData.flat; hoverEnabled: hoverBox.checked; enabled: false }
- Button { text: "Down"; flat: modelData.flat; hoverEnabled: hoverBox.checked; down: true }
- Button { text: "Disabled"; flat: modelData.flat; hoverEnabled: hoverBox.checked; down: true; enabled: false }
-
- Button { text: "Checked"; flat: modelData.flat; hoverEnabled: hoverBox.checked; checked: true }
- Button { text: "Disabled"; flat: modelData.flat; hoverEnabled: hoverBox.checked; checked: true; enabled: false }
- Button { text: "Down"; flat: modelData.flat; hoverEnabled: hoverBox.checked; checked: true; down: true }
- Button { text: "Disabled"; flat: modelData.flat; hoverEnabled: hoverBox.checked; checked: true; down: true; enabled: false }
-
- Button { text: "Highlighted"; flat: modelData.flat; hoverEnabled: hoverBox.checked; highlighted: true }
- Button { text: "Disabled"; flat: modelData.flat; hoverEnabled: hoverBox.checked; highlighted: true; enabled: false }
- Button { text: "Down"; flat: modelData.flat; hoverEnabled: hoverBox.checked; highlighted: true; down: true }
- Button { text: "Disabled"; flat: modelData.flat; hoverEnabled: hoverBox.checked; highlighted: true; down: true; enabled: false }
-
- Button { text: "Hi-checked"; flat: modelData.flat; hoverEnabled: hoverBox.checked; highlighted: true; checked: true }
- Button { text: "Disabled"; flat: modelData.flat; hoverEnabled: hoverBox.checked; highlighted: true; checked: true; enabled: false }
- Button { text: "Down"; flat: modelData.flat; hoverEnabled: hoverBox.checked; highlighted: true; checked: true; down: true }
- Button { text: "Disabled"; flat: modelData.flat; hoverEnabled: hoverBox.checked; highlighted: true; checked: true; down: true; enabled: false }
+ ButtonLoader { text: "Normal"; flat: modelData.flat; hoverEnabled: hoverBox.checked; round: roundBox.checked }
+ ButtonLoader { text: "Disabled"; flat: modelData.flat; hoverEnabled: hoverBox.checked; enabled: false; round: roundBox.checked }
+ ButtonLoader { text: "Down"; flat: modelData.flat; hoverEnabled: hoverBox.checked; down: true; round: roundBox.checked }
+ ButtonLoader { text: "Disabled"; flat: modelData.flat; hoverEnabled: hoverBox.checked; down: true; enabled: false; round: roundBox.checked }
+
+ ButtonLoader { text: "Checked"; flat: modelData.flat; hoverEnabled: hoverBox.checked; checked: true; round: roundBox.checked }
+ ButtonLoader { text: "Disabled"; flat: modelData.flat; hoverEnabled: hoverBox.checked; checked: true; enabled: false; round: roundBox.checked }
+ ButtonLoader { text: "Down"; flat: modelData.flat; hoverEnabled: hoverBox.checked; checked: true; down: true; round: roundBox.checked }
+ ButtonLoader { text: "Disabled"; flat: modelData.flat; hoverEnabled: hoverBox.checked; checked: true; down: true; enabled: false; round: roundBox.checked }
+
+ ButtonLoader { text: "Highlighted"; flat: modelData.flat; hoverEnabled: hoverBox.checked; highlighted: true; round: roundBox.checked }
+ ButtonLoader { text: "Disabled"; flat: modelData.flat; hoverEnabled: hoverBox.checked; highlighted: true; enabled: false; round: roundBox.checked }
+ ButtonLoader { text: "Down"; flat: modelData.flat; hoverEnabled: hoverBox.checked; highlighted: true; down: true; round: roundBox.checked }
+ ButtonLoader { text: "Disabled"; flat: modelData.flat; hoverEnabled: hoverBox.checked; highlighted: true; down: true; enabled: false; round: roundBox.checked }
+
+ ButtonLoader { text: "Hi-checked"; flat: modelData.flat; hoverEnabled: hoverBox.checked; highlighted: true; checked: true; round: roundBox.checked }
+ ButtonLoader { text: "Disabled"; flat: modelData.flat; hoverEnabled: hoverBox.checked; highlighted: true; checked: true; enabled: false; round: roundBox.checked }
+ ButtonLoader { text: "Down"; flat: modelData.flat; hoverEnabled: hoverBox.checked; highlighted: true; checked: true; down: true; round: roundBox.checked }
+ ButtonLoader { text: "Disabled"; flat: modelData.flat; hoverEnabled: hoverBox.checked; highlighted: true; checked: true; down: true; enabled: false; round: roundBox.checked }
}
}
}
diff --git a/tests/manual/gifs/eventcapturer.cpp b/tests/manual/gifs/eventcapturer.cpp
index 83e1c76b..3c355f59 100644
--- a/tests/manual/gifs/eventcapturer.cpp
+++ b/tests/manual/gifs/eventcapturer.cpp
@@ -57,7 +57,8 @@
// interact with the view here, in order for the events to be captured
qDebug() << "\n";
- foreach (CapturedEvent event, eventCapturer.capturedEvents())
+ const auto capturedEvents = eventCapturer.capturedEvents();
+ for (CapturedEvent event : capturedEvents)
qDebug().noquote() << event.cppCommand();
\endcode
diff --git a/tests/manual/gifs/tst_gifs.cpp b/tests/manual/gifs/tst_gifs.cpp
index 94400e04..919ba104 100644
--- a/tests/manual/gifs/tst_gifs.cpp
+++ b/tests/manual/gifs/tst_gifs.cpp
@@ -191,7 +191,8 @@ void tst_Gifs::tumblerWrap()
gifRecorder.waitForFinish();
- foreach (CapturedEvent event, eventCapturer.capturedEvents())
+ const auto capturedEvents = eventCapturer.capturedEvents();
+ for (CapturedEvent event : capturedEvents)
qDebug().noquote() << event.cppCommand();
}
diff --git a/tests/manual/testbench/main.qml b/tests/manual/testbench/main.qml
index dd1a1de8..ea59d5b5 100644
--- a/tests/manual/testbench/main.qml
+++ b/tests/manual/testbench/main.qml
@@ -251,6 +251,108 @@ ApplicationWindow {
}
RowLayout {
+ spacing: window.controlSpacing * 2
+
+ Button {
+ text: "Normal"
+ }
+ Button {
+ text: "Pressed"
+ down: true
+ }
+ Button {
+ text: "Checked"
+ checked: true
+ }
+ Button {
+ text: "CH + PR"
+ checked: true
+ down: true
+ }
+ Button {
+ text: "Disabled"
+ enabled: false
+ }
+ Button {
+ text: "CH + DIS"
+ enabled: false
+ checked: true
+ }
+ }
+
+ RowLayout {
+ spacing: window.controlSpacing * 2
+
+ ColumnLayout {
+ RoundButton {
+ highlighted: true
+ Layout.alignment: Qt.AlignHCenter
+ }
+ Label {
+ text: "HI"
+ Layout.alignment: Qt.AlignHCenter
+ }
+ }
+ ColumnLayout {
+ RoundButton {
+ highlighted: true
+ down: true
+ Layout.alignment: Qt.AlignHCenter
+ }
+ Label {
+ text: "HI + PR"
+ Layout.alignment: Qt.AlignHCenter
+ }
+ }
+ ColumnLayout {
+ RoundButton {
+ highlighted: true
+ checked: true
+ Layout.alignment: Qt.AlignHCenter
+ }
+ Label {
+ text: "HI + CH"
+ Layout.alignment: Qt.AlignHCenter
+ }
+ }
+ ColumnLayout {
+ RoundButton {
+ highlighted: true
+ down: true
+ checked: true
+ Layout.alignment: Qt.AlignHCenter
+ }
+ Label {
+ text: "HI+CH+PR"
+ Layout.alignment: Qt.AlignHCenter
+ }
+ }
+ ColumnLayout {
+ RoundButton {
+ highlighted: true
+ enabled: false
+ Layout.alignment: Qt.AlignHCenter
+ }
+ Label {
+ text: "HI + DIS"
+ Layout.alignment: Qt.AlignHCenter
+ }
+ }
+ ColumnLayout {
+ RoundButton {
+ highlighted: true
+ enabled: false
+ checked: true
+ Layout.alignment: Qt.AlignHCenter
+ }
+ Label {
+ text: "HI+CH+DIS"
+ Layout.alignment: Qt.AlignHCenter
+ }
+ }
+ }
+
+ RowLayout {
CheckBox {
text: "Normal"
}