aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--examples/quickcontrols2/gallery/gallery.qml29
-rw-r--r--src/imports/controls/Button.qml1
-rw-r--r--src/imports/controls/CheckBox.qml2
-rw-r--r--src/imports/controls/CheckIndicator.qml1
-rw-r--r--src/imports/controls/ComboBox.qml4
-rw-r--r--src/imports/controls/Dialog.qml22
-rw-r--r--src/imports/controls/Page.qml4
-rw-r--r--src/imports/controls/RadioButton.qml2
-rw-r--r--src/imports/controls/RadioIndicator.qml1
-rw-r--r--src/imports/controls/RangeSlider.qml1
-rw-r--r--src/imports/controls/Slider.qml1
-rw-r--r--src/imports/controls/SpinBox.qml1
-rw-r--r--src/imports/controls/SwitchIndicator.qml1
-rw-r--r--src/imports/controls/doc/snippets/qtquickcontrols2-dialog.qml1
-rw-r--r--src/imports/controls/doc/src/qtquickcontrols2-customize.qdoc6
-rw-r--r--src/imports/controls/doc/src/qtquickcontrols2-environment.qdoc8
-rw-r--r--src/imports/controls/material/Dialog.qml27
-rw-r--r--src/imports/controls/material/Page.qml4
-rw-r--r--src/imports/controls/material/images/drop-indicator.pngbin342 -> 192 bytes
-rw-r--r--src/imports/controls/material/images/drop-indicator.svg5
-rw-r--r--src/imports/controls/material/images/drop-indicator@2x.pngbin273 -> 221 bytes
-rw-r--r--src/imports/controls/material/images/drop-indicator@3x.pngbin406 -> 256 bytes
-rw-r--r--src/imports/controls/material/images/drop-indicator@4x.pngbin520 -> 289 bytes
-rw-r--r--src/imports/controls/material/qquickmaterialtheme.cpp8
-rw-r--r--src/imports/controls/universal/Dialog.qml26
-rw-r--r--src/imports/controls/universal/Page.qml4
-rw-r--r--src/imports/controls/universal/qquickuniversaltheme.cpp4
-rw-r--r--src/imports/templates/qtquicktemplates2plugin.cpp1
-rw-r--r--src/quickcontrols2/qquickstyle.cpp18
-rw-r--r--src/quicktemplates2/qquickcontrol.cpp21
-rw-r--r--src/quicktemplates2/qquickcontrol_p.h1
-rw-r--r--src/quicktemplates2/qquickdialog.cpp138
-rw-r--r--src/quicktemplates2/qquickdialog_p.h13
-rw-r--r--src/quicktemplates2/qquickdialog_p_p.h7
-rw-r--r--src/quicktemplates2/qquickdrawer.cpp18
-rw-r--r--src/quicktemplates2/qquickgroupbox.cpp4
-rw-r--r--src/quicktemplates2/qquicklabel.cpp2
-rw-r--r--src/quicktemplates2/qquickpage.cpp7
-rw-r--r--src/quicktemplates2/qquickpage_p.h1
-rw-r--r--src/quicktemplates2/qquickpagelayout.cpp8
-rw-r--r--src/quicktemplates2/qquickpopup.cpp37
-rw-r--r--src/quicktemplates2/qquickpopup_p.h7
-rw-r--r--src/quicktemplates2/qquickpopup_p_p.h1
-rw-r--r--src/quicktemplates2/qquickpopupitem.cpp6
-rw-r--r--src/quicktemplates2/qquickpopupitem_p_p.h2
-rw-r--r--src/quicktemplates2/qquickpopuppositioner.cpp10
-rw-r--r--src/quicktemplates2/qquickpopuppositioner_p_p.h1
-rw-r--r--src/quicktemplates2/qquickscrollbar.cpp33
-rw-r--r--src/quicktemplates2/qquickscrollindicator.cpp33
-rw-r--r--src/quicktemplates2/qquickswitch.cpp14
-rw-r--r--src/quicktemplates2/qquickswitchdelegate.cpp8
-rw-r--r--src/quicktemplates2/qquicktextarea.cpp8
-rw-r--r--tests/auto/controls/data/tst_dialog.qml97
-rw-r--r--tests/auto/controls/data/tst_page.qml40
-rw-r--r--tests/auto/controls/data/tst_popup.qml31
-rw-r--r--tests/auto/controls/data/tst_scrollbar.qml16
-rw-r--r--tests/auto/controls/data/tst_scrollindicator.qml16
-rw-r--r--tests/auto/drawer/tst_drawer.cpp2
-rw-r--r--tests/manual/testbench/main.cpp2
-rw-r--r--tests/manual/testbench/qml.qrc2
-rw-r--r--tests/manual/testbench/testbench.qml (renamed from tests/manual/testbench/main.qml)140
61 files changed, 666 insertions, 242 deletions
diff --git a/examples/quickcontrols2/gallery/gallery.qml b/examples/quickcontrols2/gallery/gallery.qml
index 5fabe77f..89c0c607 100644
--- a/examples/quickcontrols2/gallery/gallery.qml
+++ b/examples/quickcontrols2/gallery/gallery.qml
@@ -57,6 +57,15 @@ ApplicationWindow {
property string style: "Default"
}
+ Shortcut {
+ sequence: "Esc"
+ enabled: stackView.depth > 1
+ onActivated: {
+ stackView.pop()
+ listView.currentIndex = -1
+ }
+ }
+
header: ToolBar {
Material.foreground: "white"
@@ -126,6 +135,8 @@ ApplicationWindow {
ListView {
id: listView
+
+ focus: true
currentIndex: -1
anchors.fill: parent
@@ -134,10 +145,8 @@ ApplicationWindow {
text: model.title
highlighted: ListView.isCurrentItem
onClicked: {
- if (listView.currentIndex != index) {
- listView.currentIndex = index
- stackView.push(model.source)
- }
+ listView.currentIndex = index
+ stackView.push(model.source)
drawer.close()
}
}
@@ -221,6 +230,7 @@ ApplicationWindow {
width: Math.round(Math.min(window.width, window.height) / 3 * 2)
modal: true
focus: true
+ title: "Settings"
standardButtons: Dialog.Ok | Dialog.Cancel
onAccepted: {
@@ -236,11 +246,6 @@ ApplicationWindow {
id: settingsColumn
spacing: 20
- Label {
- text: "Settings"
- font.bold: true
- }
-
RowLayout {
spacing: 10
@@ -277,6 +282,7 @@ ApplicationWindow {
id: aboutDialog
modal: true
focus: true
+ title: "About"
x: (window.width - width) / 2
y: window.height / 6
width: Math.min(window.width, window.height) / 3 * 2
@@ -287,11 +293,6 @@ ApplicationWindow {
spacing: 20
Label {
- text: "About"
- font.bold: true
- }
-
- Label {
width: aboutDialog.availableWidth
text: "The Qt Quick Controls 2 module delivers the next generation user interface controls based on Qt Quick."
wrapMode: Label.Wrap
diff --git a/src/imports/controls/Button.qml b/src/imports/controls/Button.qml
index 6bf30df0..5410afa9 100644
--- a/src/imports/controls/Button.qml
+++ b/src/imports/controls/Button.qml
@@ -70,7 +70,6 @@ T.Button {
background: Rectangle {
implicitWidth: 100
implicitHeight: 40
- opacity: enabled ? 1 : 0.3
visible: !control.flat || control.down || control.checked || control.highlighted
color: control.checked || control.highlighted ?
(control.visualFocus ? (control.down ? Default.buttonCheckedFocusColor : Default.focusColor) : (control.down ? Default.buttonCheckedPressedColor : Default.textColor)) :
diff --git a/src/imports/controls/CheckBox.qml b/src/imports/controls/CheckBox.qml
index dcfb54a7..38614b6a 100644
--- a/src/imports/controls/CheckBox.qml
+++ b/src/imports/controls/CheckBox.qml
@@ -51,7 +51,6 @@ T.CheckBox {
padding: 6
spacing: 6
- opacity: enabled ? 1 : 0.2
//! [indicator]
indicator: CheckIndicator {
@@ -73,6 +72,7 @@ T.CheckBox {
visible: control.text
horizontalAlignment: Text.AlignLeft
verticalAlignment: Text.AlignVCenter
+ opacity: enabled ? 1 : 0.3
}
//! [contentItem]
}
diff --git a/src/imports/controls/CheckIndicator.qml b/src/imports/controls/CheckIndicator.qml
index b3d1b25e..9078e0c6 100644
--- a/src/imports/controls/CheckIndicator.qml
+++ b/src/imports/controls/CheckIndicator.qml
@@ -53,6 +53,7 @@ Rectangle {
border.color: control.enabled ? (control.visualFocus
? Default.focusColor
: (control.down ? Default.indicatorFramePressedColor : Default.indicatorFrameColor)) : "transparent"
+ opacity: enabled ? 1 : 0.3
Image {
x: (parent.width - width) / 2
diff --git a/src/imports/controls/ComboBox.qml b/src/imports/controls/ComboBox.qml
index 85a9cc13..f461b34e 100644
--- a/src/imports/controls/ComboBox.qml
+++ b/src/imports/controls/ComboBox.qml
@@ -55,8 +55,6 @@ T.ComboBox {
leftPadding: padding + 6
rightPadding: padding + 6
- opacity: enabled ? 1 : 0.3
-
//! [delegate]
delegate: ItemDelegate {
width: control.popup.width
@@ -74,6 +72,7 @@ T.ComboBox {
source: "image://default/double-arrow/" + (control.visualFocus ? Default.focusColor : Default.textColor)
sourceSize.width: width
sourceSize.height: height
+ opacity: enabled ? 1 : 0.3
}
//! [indicator]
@@ -88,6 +87,7 @@ T.ComboBox {
horizontalAlignment: Text.AlignLeft
verticalAlignment: Text.AlignVCenter
elide: Text.ElideRight
+ opacity: enabled ? 1 : 0.3
}
//! [contentItem]
diff --git a/src/imports/controls/Dialog.qml b/src/imports/controls/Dialog.qml
index ce6df0f6..1cf64164 100644
--- a/src/imports/controls/Dialog.qml
+++ b/src/imports/controls/Dialog.qml
@@ -47,8 +47,9 @@ T.Dialog {
footer && footer.visible ? footer.implicitWidth : 0,
contentWidth > 0 ? contentWidth + leftPadding + rightPadding : 0)
implicitHeight: Math.max(background ? background.implicitHeight : 0,
- (header && header.visible ? header.implicitHeight : 0) + (footer && footer.visible ? footer.implicitHeight : 0))
- + (contentHeight > 0 ? contentHeight + topPadding + bottomPadding : 0)
+ (header && header.visible ? header.implicitHeight + spacing : 0)
+ + (footer && footer.visible ? footer.implicitHeight + spacing : 0)
+ + (contentHeight > 0 ? contentHeight + topPadding + bottomPadding : 0))
contentWidth: contentItem.implicitWidth || (contentChildren.length === 1 ? contentChildren[0].implicitWidth : 0)
contentHeight: contentItem.implicitHeight || (contentChildren.length === 1 ? contentChildren[0].implicitHeight : 0)
@@ -59,7 +60,20 @@ T.Dialog {
border.color: Default.frameDarkColor
}
- buttonBox: DialogButtonBox {
- position: DialogButtonBox.Footer
+ header: Label {
+ text: control.title
+ visible: control.title
+ elide: Label.ElideRight
+ font.bold: true
+ padding: 12
+ background: Rectangle {
+ x: 1; y: 1
+ width: parent.width - 2
+ height: parent.height - 1
+ }
+ }
+
+ footer: DialogButtonBox {
+ visible: count > 0
}
}
diff --git a/src/imports/controls/Page.qml b/src/imports/controls/Page.qml
index fbed527f..edd8d628 100644
--- a/src/imports/controls/Page.qml
+++ b/src/imports/controls/Page.qml
@@ -48,8 +48,8 @@ T.Page {
footer && footer.visible ? footer.implicitWidth : 0) + leftPadding + rightPadding)
implicitHeight: Math.max(background ? background.implicitHeight : 0,
contentHeight + topPadding + bottomPadding
- + (header && header.visible ? header.implicitHeight : 0)
- + (footer && footer.visible ? footer.implicitHeight : 0))
+ + (header && header.visible ? header.implicitHeight + spacing : 0)
+ + (footer && footer.visible ? footer.implicitHeight + spacing : 0))
contentWidth: contentItem.implicitWidth || (contentChildren.length === 1 ? contentChildren[0].implicitWidth : 0)
contentHeight: contentItem.implicitHeight || (contentChildren.length === 1 ? contentChildren[0].implicitHeight : 0)
diff --git a/src/imports/controls/RadioButton.qml b/src/imports/controls/RadioButton.qml
index 80e4e182..65c9328b 100644
--- a/src/imports/controls/RadioButton.qml
+++ b/src/imports/controls/RadioButton.qml
@@ -51,7 +51,6 @@ T.RadioButton {
padding: 6
spacing: 6
- opacity: enabled ? 1 : 0.2
//! [indicator]
indicator: RadioIndicator {
@@ -73,6 +72,7 @@ T.RadioButton {
visible: control.text
horizontalAlignment: Text.AlignLeft
verticalAlignment: Text.AlignVCenter
+ opacity: enabled ? 1 : 0.3
}
//! [contentItem]
}
diff --git a/src/imports/controls/RadioIndicator.qml b/src/imports/controls/RadioIndicator.qml
index 43159e6c..15e6f9cf 100644
--- a/src/imports/controls/RadioIndicator.qml
+++ b/src/imports/controls/RadioIndicator.qml
@@ -48,6 +48,7 @@ Rectangle {
: (control.visualFocus ? Default.focusLightColor : Default.backgroundColor)
border.width: control.visualFocus ? 2 : 1
border.color: control.visualFocus ? Default.focusColor : (control.down ? Default.indicatorFramePressedColor : Default.indicatorFrameColor)
+ opacity: enabled ? 1 : 0.3
property Item control
diff --git a/src/imports/controls/RangeSlider.qml b/src/imports/controls/RangeSlider.qml
index 005fa99c..4eefe8e1 100644
--- a/src/imports/controls/RangeSlider.qml
+++ b/src/imports/controls/RangeSlider.qml
@@ -98,7 +98,6 @@ T.RangeSlider {
width: horizontal ? control.availableWidth : implicitWidth
height: horizontal ? implicitHeight : control.availableHeight
radius: 3
- opacity: control.enabled ? 1 : 0.3
color: Default.buttonColor
scale: horizontal && control.mirrored ? -1 : 1
diff --git a/src/imports/controls/Slider.qml b/src/imports/controls/Slider.qml
index d2aba229..3564c3ae 100644
--- a/src/imports/controls/Slider.qml
+++ b/src/imports/controls/Slider.qml
@@ -77,7 +77,6 @@ T.Slider {
width: horizontal ? control.availableWidth : implicitWidth
height: horizontal ? implicitHeight : control.availableHeight
radius: 3
- opacity: control.enabled ? 1 : 0.3
color: Default.buttonColor
scale: horizontal && control.mirrored ? -1 : 1
diff --git a/src/imports/controls/SpinBox.qml b/src/imports/controls/SpinBox.qml
index 0a562110..b9e2199e 100644
--- a/src/imports/controls/SpinBox.qml
+++ b/src/imports/controls/SpinBox.qml
@@ -139,7 +139,6 @@ T.SpinBox {
//! [background]
background: Rectangle {
- opacity: control.enabled ? 1 : 0.3
implicitWidth: 140
border.color: Default.buttonColor
}
diff --git a/src/imports/controls/SwitchIndicator.qml b/src/imports/controls/SwitchIndicator.qml
index 37c23d80..362ebfef 100644
--- a/src/imports/controls/SwitchIndicator.qml
+++ b/src/imports/controls/SwitchIndicator.qml
@@ -49,7 +49,6 @@ Item {
width: 56
height: 16
radius: 8
- opacity: control.enabled ? 1 : 0.3
color: control.checked ? (control.visualFocus ? Default.focusColor : Default.buttonCheckedColor) : Default.buttonColor
border.width: control.visualFocus ? 2 : 0
border.color: Default.focusColor
diff --git a/src/imports/controls/doc/snippets/qtquickcontrols2-dialog.qml b/src/imports/controls/doc/snippets/qtquickcontrols2-dialog.qml
index c5de0b71..69e84914 100644
--- a/src/imports/controls/doc/snippets/qtquickcontrols2-dialog.qml
+++ b/src/imports/controls/doc/snippets/qtquickcontrols2-dialog.qml
@@ -34,6 +34,7 @@ Item {
//! [1]
Dialog {
id: dialog
+ title: "Title"
standardButtons: Dialog.Ok | Dialog.Cancel
onAccepted: console.log("Ok clicked")
diff --git a/src/imports/controls/doc/src/qtquickcontrols2-customize.qdoc b/src/imports/controls/doc/src/qtquickcontrols2-customize.qdoc
index 866aef23..06201404 100644
--- a/src/imports/controls/doc/src/qtquickcontrols2-customize.qdoc
+++ b/src/imports/controls/doc/src/qtquickcontrols2-customize.qdoc
@@ -136,8 +136,6 @@
\list
\li At least one QML file whose name matches a control (for example,
\c Button.qml) must exist.
-
- The Default style will be used for any controls that aren't implemented.
\li The files must be in a directory in the filesystem or in the
\l {The Qt Resource System}{resource system}.
@@ -155,6 +153,10 @@
for example.
\endlist
+ By default, the styling system uses the Default style as a fallback for
+ controls that aren't implemented. To customize or extend any other built-in
+ style, it is possible to specify a different fallback style using \l QQuickStyle.
+
What this means is that you can implement as many controls as you like for
your custom style, and place them almost anywhere. It also allows users to
create their own styles for your application.
diff --git a/src/imports/controls/doc/src/qtquickcontrols2-environment.qdoc b/src/imports/controls/doc/src/qtquickcontrols2-environment.qdoc
index 7c1b1c16..c83adf4b 100644
--- a/src/imports/controls/doc/src/qtquickcontrols2-environment.qdoc
+++ b/src/imports/controls/doc/src/qtquickcontrols2-environment.qdoc
@@ -43,10 +43,18 @@
The value can be either one of the built-in styles, for example \c "Material",
or the path to a custom style such as \c ":/mystyle".
\row
+ \li \c QT_QUICK_CONTROLS_FALLBACK_STYLE
+ \li Specifies a fallback style for \l {Creating a Custom Style}{custom styles}.
+ The value can be one of the built-in styles, for example \c "Material",
+ \row
\li \c QT_QUICK_CONTROLS_CONF
\li Specifies the location of the \l {Qt Quick Controls 2 configuration file}.
By default, the configuration file is loaded from the application's
resources in \c ":/qtquickcontrols2.conf".
+ \row
+ \li \c QT_QUICK_CONTROLS_HOVER_ENABLED
+ \li Specifies whether Qt Quick Controls 2 use \l {Control::hoverEnabled}{hover effects}.
+ The value can be set to \c 0 or \c 1 to disable or enable hover effects, respectively.
\endtable
\l {Material style} specific environment variables:
diff --git a/src/imports/controls/material/Dialog.qml b/src/imports/controls/material/Dialog.qml
index 1e2e50ac..90cda45a 100644
--- a/src/imports/controls/material/Dialog.qml
+++ b/src/imports/controls/material/Dialog.qml
@@ -48,13 +48,15 @@ T.Dialog {
footer && footer.visible ? footer.implicitWidth : 0,
contentWidth > 0 ? contentWidth + leftPadding + rightPadding : 0)
implicitHeight: Math.max(background ? background.implicitHeight : 0,
- (header && header.visible ? header.implicitHeight : 0) + (footer && footer.visible ? footer.implicitHeight : 0))
- + (contentHeight > 0 ? contentHeight + topPadding + bottomPadding : 0)
+ (header && header.visible ? header.implicitHeight + spacing : 0)
+ + (footer && footer.visible ? footer.implicitHeight + spacing : 0)
+ + (contentHeight > 0 ? contentHeight + topPadding + bottomPadding : 0))
contentWidth: contentItem.implicitWidth || (contentChildren.length === 1 ? contentChildren[0].implicitWidth : 0)
contentHeight: contentItem.implicitHeight || (contentChildren.length === 1 ? contentChildren[0].implicitHeight : 0)
padding: 24
+ topPadding: 20
Material.elevation: 24
@@ -80,7 +82,24 @@ T.Dialog {
}
}
- buttonBox: DialogButtonBox {
- position: DialogButtonBox.Footer
+ header: Label {
+ text: control.title
+ visible: control.title
+ elide: Label.ElideRight
+ padding: 24
+ bottomPadding: 0
+ // TODO: QPlatformTheme::TitleBarFont
+ font.bold: true
+ font.pixelSize: 16
+ background: PaddedRectangle {
+ radius: 2
+ color: control.Material.dialogColor
+ bottomPadding: -2
+ clip: true
+ }
+ }
+
+ footer: DialogButtonBox {
+ visible: count > 0
}
}
diff --git a/src/imports/controls/material/Page.qml b/src/imports/controls/material/Page.qml
index 707d471e..c91b16c1 100644
--- a/src/imports/controls/material/Page.qml
+++ b/src/imports/controls/material/Page.qml
@@ -47,8 +47,8 @@ T.Page {
footer && footer.visible ? footer.implicitWidth : 0) + leftPadding + rightPadding)
implicitHeight: Math.max(background ? background.implicitHeight : 0,
contentHeight + topPadding + bottomPadding
- + (header && header.visible ? header.implicitHeight : 0)
- + (footer && footer.visible ? footer.implicitHeight : 0))
+ + (header && header.visible ? header.implicitHeight + spacing : 0)
+ + (footer && footer.visible ? footer.implicitHeight + spacing : 0))
contentWidth: contentItem.implicitWidth || (contentChildren.length === 1 ? contentChildren[0].implicitWidth : 0)
contentHeight: contentItem.implicitHeight || (contentChildren.length === 1 ? contentChildren[0].implicitHeight : 0)
diff --git a/src/imports/controls/material/images/drop-indicator.png b/src/imports/controls/material/images/drop-indicator.png
index b4396ec6..08bb4855 100644
--- a/src/imports/controls/material/images/drop-indicator.png
+++ b/src/imports/controls/material/images/drop-indicator.png
Binary files differ
diff --git a/src/imports/controls/material/images/drop-indicator.svg b/src/imports/controls/material/images/drop-indicator.svg
new file mode 100644
index 00000000..94b5ca15
--- /dev/null
+++ b/src/imports/controls/material/images/drop-indicator.svg
@@ -0,0 +1,5 @@
+<?xml version="1.0" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg width="24" height="24" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" version="1.1">
+ <path d="M7,10l5,5,5-5z" fill="#757575"/>
+</svg>
diff --git a/src/imports/controls/material/images/drop-indicator@2x.png b/src/imports/controls/material/images/drop-indicator@2x.png
index 1c711bc2..ccdfc2b1 100644
--- a/src/imports/controls/material/images/drop-indicator@2x.png
+++ b/src/imports/controls/material/images/drop-indicator@2x.png
Binary files differ
diff --git a/src/imports/controls/material/images/drop-indicator@3x.png b/src/imports/controls/material/images/drop-indicator@3x.png
index 06dd8bd2..00cae691 100644
--- a/src/imports/controls/material/images/drop-indicator@3x.png
+++ b/src/imports/controls/material/images/drop-indicator@3x.png
Binary files differ
diff --git a/src/imports/controls/material/images/drop-indicator@4x.png b/src/imports/controls/material/images/drop-indicator@4x.png
index b2157c30..0a61cb01 100644
--- a/src/imports/controls/material/images/drop-indicator@4x.png
+++ b/src/imports/controls/material/images/drop-indicator@4x.png
Binary files differ
diff --git a/src/imports/controls/material/qquickmaterialtheme.cpp b/src/imports/controls/material/qquickmaterialtheme.cpp
index 0d2f8a70..1967a74b 100644
--- a/src/imports/controls/material/qquickmaterialtheme.cpp
+++ b/src/imports/controls/material/qquickmaterialtheme.cpp
@@ -45,15 +45,15 @@ QQuickMaterialTheme::QQuickMaterialTheme(QPlatformTheme *theme)
: QQuickProxyTheme(theme)
{
QFont font;
- font.setFamily(QStringLiteral("Roboto"));
+ font.setFamily(QLatin1String("Roboto"));
QString family = QFontInfo(font).family();
- if (family != QStringLiteral("Roboto")) {
- font.setFamily(QStringLiteral("Noto"));
+ if (family != QLatin1String("Roboto")) {
+ font.setFamily(QLatin1String("Noto"));
family = QFontInfo(font).family();
}
- if (family == QStringLiteral("Roboto") || family == QStringLiteral("Noto")) {
+ if (family == QLatin1String("Roboto") || family == QLatin1String("Noto")) {
systemFont.setFamily(family);
buttonFont.setFamily(family);
toolTipFont.setFamily(family);
diff --git a/src/imports/controls/universal/Dialog.qml b/src/imports/controls/universal/Dialog.qml
index 0f00b760..f805581c 100644
--- a/src/imports/controls/universal/Dialog.qml
+++ b/src/imports/controls/universal/Dialog.qml
@@ -47,8 +47,9 @@ T.Dialog {
footer && footer.visible ? footer.implicitWidth : 0,
contentWidth > 0 ? contentWidth + leftPadding + rightPadding : 0)
implicitHeight: Math.max(background ? background.implicitHeight : 0,
- (header && header.visible ? header.implicitHeight : 0) + (footer && footer.visible ? footer.implicitHeight : 0))
- + (contentHeight > 0 ? contentHeight + topPadding + bottomPadding : 0)
+ (header && header.visible ? header.implicitHeight + spacing : 0)
+ + (footer && footer.visible ? footer.implicitHeight + spacing : 0)
+ + (contentHeight > 0 ? contentHeight + topPadding + bottomPadding : 0))
contentWidth: contentItem.implicitWidth || (contentChildren.length === 1 ? contentChildren[0].implicitWidth : 0)
contentHeight: contentItem.implicitHeight || (contentChildren.length === 1 ? contentChildren[0].implicitHeight : 0)
@@ -63,7 +64,24 @@ T.Dialog {
border.width: 1 // FlyoutBorderThemeThickness
}
- buttonBox: DialogButtonBox {
- position: DialogButtonBox.Footer
+ header: Label {
+ text: control.title
+ visible: control.title
+ elide: Label.ElideRight
+ topPadding: 18
+ leftPadding: 24
+ rightPadding: 24
+ // TODO: QPlatformTheme::TitleBarFont
+ font.pixelSize: 20
+ background: Rectangle {
+ x: 1; y: 1 // // FlyoutBorderThemeThickness
+ color: control.Universal.chromeMediumLowColor
+ width: parent.width - 2
+ height: parent.height - 1
+ }
+ }
+
+ footer: DialogButtonBox {
+ visible: count > 0
}
}
diff --git a/src/imports/controls/universal/Page.qml b/src/imports/controls/universal/Page.qml
index 9bd85751..e8c7bd4a 100644
--- a/src/imports/controls/universal/Page.qml
+++ b/src/imports/controls/universal/Page.qml
@@ -47,8 +47,8 @@ T.Page {
footer && footer.visible ? footer.implicitWidth : 0) + leftPadding + rightPadding)
implicitHeight: Math.max(background ? background.implicitHeight : 0,
contentHeight + topPadding + bottomPadding
- + (header && header.visible ? header.implicitHeight : 0)
- + (footer && footer.visible ? footer.implicitHeight : 0))
+ + (header && header.visible ? header.implicitHeight + spacing : 0)
+ + (footer && footer.visible ? footer.implicitHeight + spacing : 0))
contentWidth: contentItem.implicitWidth || (contentChildren.length === 1 ? contentChildren[0].implicitWidth : 0)
contentHeight: contentItem.implicitHeight || (contentChildren.length === 1 ? contentChildren[0].implicitHeight : 0)
diff --git a/src/imports/controls/universal/qquickuniversaltheme.cpp b/src/imports/controls/universal/qquickuniversaltheme.cpp
index 51642c4a..dc516b45 100644
--- a/src/imports/controls/universal/qquickuniversaltheme.cpp
+++ b/src/imports/controls/universal/qquickuniversaltheme.cpp
@@ -44,8 +44,8 @@ QT_BEGIN_NAMESPACE
QQuickUniversalTheme::QQuickUniversalTheme(QPlatformTheme *theme)
: QQuickProxyTheme(theme)
{
- const QFont font(QStringLiteral("Segoe UI"));
- if (QFontInfo(font).family() == QStringLiteral("Segoe UI")) {
+ const QFont font(QLatin1String("Segoe UI"));
+ if (QFontInfo(font).family() == QLatin1String("Segoe UI")) {
const QString family = font.family();
systemFont.setFamily(family);
groupBoxTitleFont.setFamily(family);
diff --git a/src/imports/templates/qtquicktemplates2plugin.cpp b/src/imports/templates/qtquicktemplates2plugin.cpp
index b03028eb..58e5ce90 100644
--- a/src/imports/templates/qtquicktemplates2plugin.cpp
+++ b/src/imports/templates/qtquicktemplates2plugin.cpp
@@ -187,6 +187,7 @@ void QtQuickTemplates2Plugin::registerTypes(const char *uri)
qmlRegisterType<QQuickDialogButtonBoxAttached>();
qmlRegisterType<QQuickMenuSeparator>(uri, 2, 1, "MenuSeparator");
qmlRegisterType<QQuickPage, 1>(uri, 2, 1, "Page");
+ 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");
diff --git a/src/quickcontrols2/qquickstyle.cpp b/src/quickcontrols2/qquickstyle.cpp
index 80a7abef..f4fc1764 100644
--- a/src/quickcontrols2/qquickstyle.cpp
+++ b/src/quickcontrols2/qquickstyle.cpp
@@ -80,6 +80,19 @@ QT_BEGIN_NAMESPACE
Qt Quick Controls 2. It is not possible to change the style after the QML
types have been registered.
+ The style can also be specified as a path to a custom style, such as
+ \c ":/mystyle". See \l {Creating a Custom Style} for more details about
+ building custom styles. Custom styles do not need to implement all controls.
+ By default, the styling system uses the \l {Default style} as a fallback
+ for controls that a custom style does not provide. It is possible to
+ specify a different fallback style to customize or extend one of the
+ built-in styles.
+
+ \code
+ QQuickStyle::setStyle(":/mystyle");
+ QQuickStyle::setFallbackStyle("Material");
+ \endcode
+
\sa {Styling Qt Quick Controls 2}
*/
@@ -273,13 +286,16 @@ void QQuickStyle::setStyle(const QString &style)
}
/*!
- \since 5.9
+ \since 5.8
Sets the application fallback style to \a style.
\note The fallback style must be the name of one of the built-in Qt Quick Controls 2 styles, e.g. "Material".
\note The style must be configured \b before loading QML that imports Qt Quick Controls 2.
It is not possible to change the style after the QML types have been registered.
+
+ The fallback style can be also specified by setting the \c QT_QUICK_CONTROLS_FALLBACK_STYLE
+ \l {Supported Environment Variables in Qt Quick Controls 2}{environment variable}.
*/
void QQuickStyle::setFallbackStyle(const QString &style)
{
diff --git a/src/quicktemplates2/qquickcontrol.cpp b/src/quicktemplates2/qquickcontrol.cpp
index 84f7a6cf..20de449e 100644
--- a/src/quicktemplates2/qquickcontrol.cpp
+++ b/src/quicktemplates2/qquickcontrol.cpp
@@ -766,10 +766,13 @@ qreal QQuickControl::spacing() const
void QQuickControl::setSpacing(qreal spacing)
{
Q_D(QQuickControl);
- if (!qFuzzyCompare(d->spacing, spacing)) {
- d->spacing = spacing;
- emit spacingChanged();
- }
+ if (qFuzzyCompare(d->spacing, spacing))
+ return;
+
+ qreal oldSpacing = d->spacing;
+ d->spacing = spacing;
+ emit spacingChanged();
+ spacingChange(spacing, oldSpacing);
}
void QQuickControl::resetSpacing()
@@ -1012,6 +1015,10 @@ void QQuickControl::setHovered(bool hovered)
Setting this property propagates the value to all child controls that do not have
\c hoverEnabled explicitly set.
+ You can also enable or disable hover effects for all Qt Quick Controls 2 applications
+ by setting the \c QT_QUICK_CONTROLS_HOVER_ENABLED \l {Supported Environment Variables
+ in Qt Quick Controls 2}{environment variable}.
+
\sa hovered
*/
bool QQuickControl::isHoverEnabled() const
@@ -1287,6 +1294,12 @@ void QQuickControl::mirrorChange()
emit mirroredChanged();
}
+void QQuickControl::spacingChange(qreal newSpacing, qreal oldSpacing)
+{
+ Q_UNUSED(newSpacing);
+ Q_UNUSED(oldSpacing);
+}
+
void QQuickControl::paddingChange(const QMarginsF &newPadding, const QMarginsF &oldPadding)
{
Q_D(QQuickControl);
diff --git a/src/quicktemplates2/qquickcontrol_p.h b/src/quicktemplates2/qquickcontrol_p.h
index 7187344a..3bc21684 100644
--- a/src/quicktemplates2/qquickcontrol_p.h
+++ b/src/quicktemplates2/qquickcontrol_p.h
@@ -189,6 +189,7 @@ protected:
virtual void fontChange(const QFont &newFont, const QFont &oldFont);
virtual void hoverChange();
virtual void mirrorChange();
+ virtual void spacingChange(qreal newSpacing, qreal oldSpacing);
virtual void paddingChange(const QMarginsF &newPadding, const QMarginsF &oldPadding);
virtual void contentItemChange(QQuickItem *newItem, QQuickItem *oldItem);
virtual void localeChange(const QLocale &newLocale, const QLocale &oldLocale);
diff --git a/src/quicktemplates2/qquickdialog.cpp b/src/quicktemplates2/qquickdialog.cpp
index e747b251..94378a15 100644
--- a/src/quicktemplates2/qquickdialog.cpp
+++ b/src/quicktemplates2/qquickdialog.cpp
@@ -39,10 +39,6 @@
#include "qquickdialogbuttonbox_p.h"
#include "qquickpopupitem_p_p.h"
-#include <QtQml/qqmlinfo.h>
-#include <QtQml/qqmlcontext.h>
-#include <QtQml/qqmlcomponent.h>
-
QT_BEGIN_NAMESPACE
/*!
@@ -61,22 +57,19 @@ QT_BEGIN_NAMESPACE
\image qtquickcontrols2-page-wireframe.png
- \section1 Dialog Buttons
+ \section1 Dialog Title and Buttons
+
+ Dialog's \l title is displayed by a style-specific title bar that is assigned
+ as a dialog \l header by default.
- Dialog's standard buttons are managed by \l DialogButtonBox. When a button box
- is assigned as a dialog \l footer or \l header, the dialog's \l standardButtons
- property is forwarded to the respective property of the button box. Furthermore,
- the \l {DialogButtonBox::}{accepted()} and \l {DialogButtonBox::}{rejected()}
+ Dialog's standard buttons are managed by a \l DialogButtonBox that is assigned
+ as a dialog \l footer by default. The dialog's \l standardButtons property is
+ forwarded to the respective property of the button box. Furthermore, the
+ \l {DialogButtonBox::}{accepted()} and \l {DialogButtonBox::}{rejected()}
signals of the button box are connected to the respective signals in Dialog.
\snippet qtquickcontrols2-dialog.qml 1
- \note If any standard buttons are specified for the dialog but no button box has
- been assigned as a footer or header, Dialog automatically creates an instance of
- \l buttonBox, and assigns it as a footer or header of the dialog depending on the
- value of the \l {DialogButtonBox::}{position} property. All built-in Dialog styles
- assign the button box as a footer.
-
\section1 Modal Dialogs
A \l {Popup::}{modal} dialog blocks input to other content beneath
@@ -122,45 +115,44 @@ QT_BEGIN_NAMESPACE
\sa accepted()
*/
-void QQuickDialogPrivate::createButtonBox()
+QQuickDialog::QQuickDialog(QObject *parent) :
+ QQuickPopup(*(new QQuickDialogPrivate), parent)
{
- Q_Q(QQuickDialog);
- QQmlContext *context = qmlContext(q);
- if (!context || !buttonBoxComponent)
- return;
+ Q_D(QQuickDialog);
+ d->layout.reset(new QQuickPageLayout(d->popupItem));
+}
- QObject *object = buttonBoxComponent->create(context);
- QQuickDialogButtonBox *buttonBox = qobject_cast<QQuickDialogButtonBox *>(object);
- if (!buttonBox) {
- if (object) {
- qmlInfo(q) << "buttonBox must be an instance of DialogButtonBox";
- delete object;
- }
- return;
- }
+/*!
+ \qmlproperty string QtQuick.Controls::Dialog::title
- if (buttonBox->position() == QQuickDialogButtonBox::Header) {
- if (layout->header()) {
- qmlInfo(q) << "Custom header detected. Cannot assign buttonBox as a header. No standard buttons will appear in the header.";
- delete buttonBox;
- } else {
- q->setHeader(buttonBox);
- }
- } else {
- if (layout->footer()) {
- qmlInfo(q) << "Custom footer detected. Cannot assign buttonBox as a footer. No standard buttons will appear in the footer.";
- delete buttonBox;
- } else {
- q->setFooter(buttonBox);
+ This property holds the dialog title.
+
+ The title is displayed in the dialog header.
+
+ \code
+ Dialog {
+ title: qsTr("About")
+
+ Label {
+ text: "Lorem ipsum..."
}
}
+ \endcode
+*/
+QString QQuickDialog::title() const
+{
+ Q_D(const QQuickDialog);
+ return d->title;
}
-QQuickDialog::QQuickDialog(QObject *parent) :
- QQuickPopup(*(new QQuickDialogPrivate), parent)
+void QQuickDialog::setTitle(const QString &title)
{
Q_D(QQuickDialog);
- d->layout.reset(new QQuickPageLayout(d->popupItem));
+ if (d->title == title)
+ return;
+
+ d->title = title;
+ emit titleChanged();
}
/*!
@@ -177,7 +169,7 @@ QQuickDialog::QQuickDialog(QObject *parent) :
header automatically sets the respective \l DialogButtonBox::position,
\l ToolBar::position, or \l TabBar::position property to \c Header.
- \sa footer, buttonBox
+ \sa footer
*/
QQuickItem *QQuickDialog::header() const
{
@@ -224,7 +216,7 @@ void QQuickDialog::setHeader(QQuickItem *header)
footer automatically sets the respective \l DialogButtonBox::position,
\l ToolBar::position, or \l TabBar::position property to \c Footer.
- \sa header, buttonBox
+ \sa header
*/
QQuickItem *QQuickDialog::footer() const
{
@@ -258,33 +250,6 @@ void QQuickDialog::setFooter(QQuickItem *footer)
}
/*!
- \qmlproperty Component QtQuick.Controls::Dialog::buttonBox
-
- This property holds a delegate for creating a button box.
-
- A button box is only created if any standard buttons are set.
- The \l {DialogButtonBox::}{position} property determines whether
- the button box is assigned as a \l header or \l footer.
-
- \sa standardButtons, header, footer, DialogButtonBox
-*/
-QQmlComponent *QQuickDialog::buttonBox() const
-{
- Q_D(const QQuickDialog);
- return d->buttonBoxComponent;
-}
-
-void QQuickDialog::setButtonBox(QQmlComponent *box)
-{
- Q_D(QQuickDialog);
- if (d->buttonBoxComponent == box)
- return;
-
- d->buttonBoxComponent = box;
- emit buttonBoxChanged();
-}
-
-/*!
\qmlproperty enumeration QtQuick.Controls::Dialog::standardButtons
This property holds a combination of standard buttons that are used by the dialog.
@@ -312,7 +277,7 @@ void QQuickDialog::setButtonBox(QQmlComponent *box)
\value Dialog.Ignore An "Ignore" button defined with the \c AcceptRole.
\value Dialog.NoButton An invalid button.
- \sa buttonBox, DialogButtonBox
+ \sa DialogButtonBox
*/
QPlatformDialogHelper::StandardButtons QQuickDialog::standardButtons() const
{
@@ -327,12 +292,8 @@ void QQuickDialog::setStandardButtons(QPlatformDialogHelper::StandardButtons but
return;
d->standardButtons = buttons;
- if (isComponentComplete()) {
- if (d->buttonBox)
- d->buttonBox->setStandardButtons(buttons);
- else if (buttons)
- d->createButtonBox();
- }
+ if (d->buttonBox)
+ d->buttonBox->setStandardButtons(buttons);
emit standardButtonsChanged();
}
@@ -362,14 +323,6 @@ void QQuickDialog::reject()
emit rejected();
}
-void QQuickDialog::componentComplete()
-{
- Q_D(QQuickDialog);
- QQuickPopup::componentComplete();
- if (!d->buttonBox && d->standardButtons)
- d->createButtonBox();
-}
-
void QQuickDialog::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
{
Q_D(QQuickDialog);
@@ -384,4 +337,11 @@ void QQuickDialog::paddingChange(const QMarginsF &newPadding, const QMarginsF &o
d->layout->update();
}
+void QQuickDialog::spacingChange(qreal newSpacing, qreal oldSpacing)
+{
+ Q_D(QQuickDialog);
+ QQuickPopup::spacingChange(newSpacing, oldSpacing);
+ d->layout->update();
+}
+
QT_END_NAMESPACE
diff --git a/src/quicktemplates2/qquickdialog_p.h b/src/quicktemplates2/qquickdialog_p.h
index 2c7eee95..ea03dddf 100644
--- a/src/quicktemplates2/qquickdialog_p.h
+++ b/src/quicktemplates2/qquickdialog_p.h
@@ -53,30 +53,29 @@
QT_BEGIN_NAMESPACE
-class QQmlComponent;
class QQuickDialogPrivate;
class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickDialog : public QQuickPopup
{
Q_OBJECT
+ Q_PROPERTY(QString title READ title WRITE setTitle NOTIFY titleChanged FINAL)
Q_PROPERTY(QQuickItem *header READ header WRITE setHeader NOTIFY headerChanged FINAL)
Q_PROPERTY(QQuickItem *footer READ footer WRITE setFooter NOTIFY footerChanged FINAL)
- Q_PROPERTY(QQmlComponent *buttonBox READ buttonBox WRITE setButtonBox NOTIFY buttonBoxChanged FINAL)
Q_PROPERTY(QPlatformDialogHelper::StandardButtons standardButtons READ standardButtons WRITE setStandardButtons NOTIFY standardButtonsChanged FINAL)
Q_FLAGS(QPlatformDialogHelper::StandardButtons)
public:
explicit QQuickDialog(QObject *parent = nullptr);
+ QString title() const;
+ void setTitle(const QString &title);
+
QQuickItem *header() const;
void setHeader(QQuickItem *header);
QQuickItem *footer() const;
void setFooter(QQuickItem *footer);
- QQmlComponent *buttonBox() const;
- void setButtonBox(QQmlComponent *box);
-
QPlatformDialogHelper::StandardButtons standardButtons() const;
void setStandardButtons(QPlatformDialogHelper::StandardButtons buttons);
@@ -88,15 +87,15 @@ Q_SIGNALS:
void accepted();
void rejected();
+ void titleChanged();
void headerChanged();
void footerChanged();
- void buttonBoxChanged();
void standardButtonsChanged();
protected:
- void componentComplete() override;
void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) override;
void paddingChange(const QMarginsF &newPadding, const QMarginsF &oldPadding) override;
+ void spacingChange(qreal newSpacing, qreal oldSpacing) override;
private:
Q_DISABLE_COPY(QQuickDialog)
diff --git a/src/quicktemplates2/qquickdialog_p_p.h b/src/quicktemplates2/qquickdialog_p_p.h
index a893690d..5ea84cc8 100644
--- a/src/quicktemplates2/qquickdialog_p_p.h
+++ b/src/quicktemplates2/qquickdialog_p_p.h
@@ -53,7 +53,6 @@
QT_BEGIN_NAMESPACE
-class QQmlComponent;
class QQuickDialogButtonBox;
class QQuickDialogPrivate : public QQuickPopupPrivate
@@ -61,17 +60,15 @@ class QQuickDialogPrivate : public QQuickPopupPrivate
Q_DECLARE_PUBLIC(QQuickDialog)
public:
- QQuickDialogPrivate() : buttonBox(nullptr), buttonBoxComponent(nullptr) { }
+ QQuickDialogPrivate() : buttonBox(nullptr) { }
static QQuickDialogPrivate *get(QQuickDialog *dialog)
{
return dialog->d_func();
}
- void createButtonBox();
-
+ QString title;
QQuickDialogButtonBox *buttonBox;
- QQmlComponent *buttonBoxComponent;
QScopedPointer<QQuickPageLayout> layout;
QPlatformDialogHelper::StandardButtons standardButtons;
};
diff --git a/src/quicktemplates2/qquickdrawer.cpp b/src/quicktemplates2/qquickdrawer.cpp
index a996b343..839fb1c9 100644
--- a/src/quicktemplates2/qquickdrawer.cpp
+++ b/src/quicktemplates2/qquickdrawer.cpp
@@ -157,7 +157,9 @@ QT_BEGIN_NAMESPACE
the drawer is opened, don't apply a translation.
\note On some platforms, certain edges may be reserved for system
- gestures and therefore cannot be used with Drawer.
+ gestures and therefore cannot be used with Drawer. For example, the
+ top and bottom edges may be reserved for system notifications and
+ control centers on Android and iOS.
\sa SwipeView, {Customizing Drawer}, {Navigation Controls}, {Popup Controls}
*/
@@ -482,13 +484,13 @@ QQuickDrawer::QQuickDrawer(QObject *parent) :
/*!
\qmlproperty enumeration QtQuick.Controls::Drawer::edge
- This property holds the edge of the content item at which the drawer will
+ This property holds the edge of the window at which the drawer will
open from. The acceptable values are:
- \value Qt.TopEdge The top edge of the content item.
- \value Qt.LeftEdge The left edge of the content item (default).
- \value Qt.RightEdge The right edge of the content item.
- \value Qt.BottomEdge The bottom edge of the content item.
+ \value Qt.TopEdge The top edge of the window.
+ \value Qt.LeftEdge The left edge of the window (default).
+ \value Qt.RightEdge The right edge of the window.
+ \value Qt.BottomEdge The bottom edge of the window.
*/
Qt::Edge QQuickDrawer::edge() const
{
@@ -512,8 +514,8 @@ void QQuickDrawer::setEdge(Qt::Edge edge)
\qmlproperty real QtQuick.Controls::Drawer::position
This property holds the position of the drawer relative to its final
- destination. That is, the position will be \c 0 when the drawer
- is fully closed, and \c 1 when fully open.
+ destination. That is, the position will be \c 0.0 when the drawer
+ is fully closed, and \c 1.0 when fully open.
*/
qreal QQuickDrawer::position() const
{
diff --git a/src/quicktemplates2/qquickgroupbox.cpp b/src/quicktemplates2/qquickgroupbox.cpp
index 27c325ef..5a5a8005 100644
--- a/src/quicktemplates2/qquickgroupbox.cpp
+++ b/src/quicktemplates2/qquickgroupbox.cpp
@@ -56,8 +56,8 @@ QT_BEGIN_NAMESPACE
or a \l ColumnLayout.
Items declared as children of a GroupBox are automatically parented to the
- GroupBox's contentItem. Items created dynamically need to be explicitly
- parented to the contentItem.
+ GroupBox's \l {Control::}{contentItem}. Items created dynamically need to be
+ explicitly parented to the contentItem.
If only a single item is used within a GroupBox, it will resize to fit the
implicit size of its contained item. This makes it particularly suitable
diff --git a/src/quicktemplates2/qquicklabel.cpp b/src/quicktemplates2/qquicklabel.cpp
index 03bed16f..b3596022 100644
--- a/src/quicktemplates2/qquicklabel.cpp
+++ b/src/quicktemplates2/qquicklabel.cpp
@@ -66,7 +66,7 @@ QT_BEGIN_NAMESPACE
\snippet qtquickcontrols2-label.qml 1
- You can use the properties of Text to change the appearance of the text as desired:
+ You can use the properties of \l Text to change the appearance of the text as desired:
\qml
Label {
diff --git a/src/quicktemplates2/qquickpage.cpp b/src/quicktemplates2/qquickpage.cpp
index 0098cb93..432c8c63 100644
--- a/src/quicktemplates2/qquickpage.cpp
+++ b/src/quicktemplates2/qquickpage.cpp
@@ -349,6 +349,13 @@ void QQuickPage::paddingChange(const QMarginsF &newPadding, const QMarginsF &old
d->layout->update();
}
+void QQuickPage::spacingChange(qreal newSpacing, qreal oldSpacing)
+{
+ Q_D(QQuickPage);
+ QQuickControl::spacingChange(newSpacing, oldSpacing);
+ d->layout->update();
+}
+
#ifndef QT_NO_ACCESSIBILITY
QAccessible::Role QQuickPage::accessibleRole() const
{
diff --git a/src/quicktemplates2/qquickpage_p.h b/src/quicktemplates2/qquickpage_p.h
index c63b11d7..36ba9fff 100644
--- a/src/quicktemplates2/qquickpage_p.h
+++ b/src/quicktemplates2/qquickpage_p.h
@@ -100,6 +100,7 @@ protected:
void contentItemChange(QQuickItem *newItem, QQuickItem *oldItem) override;
void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) override;
void paddingChange(const QMarginsF &newPadding, const QMarginsF &oldPadding) override;
+ void spacingChange(qreal newSpacing, qreal oldSpacing) override;
#ifndef QT_NO_ACCESSIBILITY
QAccessible::Role accessibleRole() const override;
diff --git a/src/quicktemplates2/qquickpagelayout.cpp b/src/quicktemplates2/qquickpagelayout.cpp
index a1747b47..b787dd08 100644
--- a/src/quicktemplates2/qquickpagelayout.cpp
+++ b/src/quicktemplates2/qquickpagelayout.cpp
@@ -142,17 +142,19 @@ void QQuickPageLayout::update()
const qreal hh = m_header && m_header->isVisible() ? m_header->height() : 0;
const qreal fh = m_footer && m_footer->isVisible() ? m_footer->height() : 0;
+ const qreal hsp = hh > 0 ? m_control->spacing() : 0;
+ const qreal fsp = fh > 0 ? m_control->spacing() : 0;
- content->setY(hh + m_control->topPadding());
+ content->setY(m_control->topPadding() + hh + hsp);
content->setX(m_control->leftPadding());
content->setWidth(m_control->availableWidth());
- content->setHeight(m_control->availableHeight() - hh - fh);
+ content->setHeight(m_control->availableHeight() - hh - fh - hsp - fsp);
if (m_header)
m_header->setWidth(m_control->width());
if (m_footer) {
- m_footer->setY(m_control->height() - fh);
+ m_footer->setY(m_control->height() - m_footer->height());
m_footer->setWidth(m_control->width());
}
}
diff --git a/src/quicktemplates2/qquickpopup.cpp b/src/quicktemplates2/qquickpopup.cpp
index 13dd1a4d..a7927d19 100644
--- a/src/quicktemplates2/qquickpopup.cpp
+++ b/src/quicktemplates2/qquickpopup.cpp
@@ -123,6 +123,7 @@ QQuickPopupPrivate::QQuickPopupPrivate()
, hasDim(false)
, visible(false)
, complete(false)
+ , positioning(false)
, hasWidth(false)
, hasHeight(false)
, hasTopMargin(false)
@@ -717,6 +718,35 @@ qreal QQuickPopup::availableHeight() const
}
/*!
+ \since QtQuick.Controls 2.1
+ \qmlproperty real QtQuick.Controls::Popup::spacing
+
+ This property holds the spacing.
+
+ Spacing is useful for popups that have multiple or repetitive building
+ blocks. For example, some styles use spacing to determine the distance
+ between the header, content, and footer of \l Dialog. Spacing is not
+ enforced by Popup, so each style may interpret it differently, and some
+ may ignore it altogether.
+*/
+qreal QQuickPopup::spacing() const
+{
+ Q_D(const QQuickPopup);
+ return d->popupItem->spacing();
+}
+
+void QQuickPopup::setSpacing(qreal spacing)
+{
+ Q_D(QQuickPopup);
+ d->popupItem->setSpacing(spacing);
+}
+
+void QQuickPopup::resetSpacing()
+{
+ setSpacing(0);
+}
+
+/*!
\qmlproperty real QtQuick.Controls::Popup::margins
This property holds the default margins around the popup.
@@ -1740,6 +1770,13 @@ void QQuickPopup::paddingChange(const QMarginsF &newPadding, const QMarginsF &ol
emit availableHeightChanged();
}
+void QQuickPopup::spacingChange(qreal newSpacing, qreal oldSpacing)
+{
+ Q_UNUSED(newSpacing);
+ Q_UNUSED(oldSpacing);
+ emit spacingChanged();
+}
+
QFont QQuickPopup::defaultFont() const
{
return QQuickControlPrivate::themeFont(QPlatformTheme::SystemFont);
diff --git a/src/quicktemplates2/qquickpopup_p.h b/src/quicktemplates2/qquickpopup_p.h
index a024c68f..de42b793 100644
--- a/src/quicktemplates2/qquickpopup_p.h
+++ b/src/quicktemplates2/qquickpopup_p.h
@@ -84,6 +84,7 @@ class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickPopup : public QObject, public QQml
Q_PROPERTY(qreal contentHeight READ contentHeight WRITE setContentHeight NOTIFY contentHeightChanged FINAL)
Q_PROPERTY(qreal availableWidth READ availableWidth NOTIFY availableWidthChanged FINAL)
Q_PROPERTY(qreal availableHeight READ availableHeight NOTIFY availableHeightChanged FINAL)
+ Q_PROPERTY(qreal spacing READ spacing WRITE setSpacing RESET resetSpacing NOTIFY spacingChanged FINAL REVISION 1)
Q_PROPERTY(qreal margins READ margins WRITE setMargins RESET resetMargins NOTIFY marginsChanged FINAL)
Q_PROPERTY(qreal topMargin READ topMargin WRITE setTopMargin RESET resetTopMargin NOTIFY topMarginChanged FINAL)
Q_PROPERTY(qreal leftMargin READ leftMargin WRITE setLeftMargin RESET resetLeftMargin NOTIFY leftMarginChanged FINAL)
@@ -154,6 +155,10 @@ public:
qreal availableWidth() const;
qreal availableHeight() const;
+ qreal spacing() const;
+ void setSpacing(qreal spacing);
+ void resetSpacing();
+
qreal margins() const;
void setMargins(qreal margins);
void resetMargins();
@@ -293,6 +298,7 @@ Q_SIGNALS:
void contentHeightChanged();
void availableWidthChanged();
void availableHeightChanged();
+ Q_REVISION(1) void spacingChanged();
void marginsChanged();
void topMarginChanged();
void leftMarginChanged();
@@ -354,6 +360,7 @@ protected:
virtual void itemChange(QQuickItem::ItemChange change, const QQuickItem::ItemChangeData &data);
virtual void marginsChange(const QMarginsF &newMargins, const QMarginsF &oldMargins);
virtual void paddingChange(const QMarginsF &newPadding, const QMarginsF &oldPadding);
+ virtual void spacingChange(qreal newSpacing, qreal oldSpacing);
virtual QFont defaultFont() const;
diff --git a/src/quicktemplates2/qquickpopup_p_p.h b/src/quicktemplates2/qquickpopup_p_p.h
index 56baaa36..1d25f922 100644
--- a/src/quicktemplates2/qquickpopup_p_p.h
+++ b/src/quicktemplates2/qquickpopup_p_p.h
@@ -123,6 +123,7 @@ public:
bool hasDim;
bool visible;
bool complete;
+ bool positioning;
bool hasWidth;
bool hasHeight;
bool hasTopMargin;
diff --git a/src/quicktemplates2/qquickpopupitem.cpp b/src/quicktemplates2/qquickpopupitem.cpp
index b599b145..b939d57c 100644
--- a/src/quicktemplates2/qquickpopupitem.cpp
+++ b/src/quicktemplates2/qquickpopupitem.cpp
@@ -103,6 +103,12 @@ QQuickPopupItem::QQuickPopupItem(QQuickPopup *popup) :
// connect(QGuiApplication::styleHints(), &QStyleHints::useHoverEffectsChanged, this, &QQuickItem::setAcceptHoverEvents);
}
+void QQuickPopupItem::updatePolish()
+{
+ Q_D(QQuickPopupItem);
+ return QQuickPopupPrivate::get(d->popup)->reposition();
+}
+
bool QQuickPopupItem::childMouseEventFilter(QQuickItem *child, QEvent *event)
{
Q_D(QQuickPopupItem);
diff --git a/src/quicktemplates2/qquickpopupitem_p_p.h b/src/quicktemplates2/qquickpopupitem_p_p.h
index a72f5646..4b675010 100644
--- a/src/quicktemplates2/qquickpopupitem_p_p.h
+++ b/src/quicktemplates2/qquickpopupitem_p_p.h
@@ -63,6 +63,8 @@ public:
explicit QQuickPopupItem(QQuickPopup *popup);
protected:
+ void updatePolish() override;
+
bool childMouseEventFilter(QQuickItem *child, QEvent *event) override;
void focusInEvent(QFocusEvent *event) override;
void focusOutEvent(QFocusEvent *event) override;
diff --git a/src/quicktemplates2/qquickpopuppositioner.cpp b/src/quicktemplates2/qquickpopuppositioner.cpp
index cdd9332f..762b6d30 100644
--- a/src/quicktemplates2/qquickpopuppositioner.cpp
+++ b/src/quicktemplates2/qquickpopuppositioner.cpp
@@ -50,6 +50,7 @@ static const QQuickItemPrivate::ChangeTypes ItemChangeTypes = QQuickItemPrivate:
| QQuickItemPrivate::Parent;
QQuickPopupPositioner::QQuickPopupPositioner(QQuickPopup *popup) :
+ m_positioning(false),
m_parentItem(nullptr),
m_popup(popup)
{
@@ -96,6 +97,11 @@ void QQuickPopupPositioner::reposition()
if (!popupItem->isVisible())
return;
+ if (m_positioning) {
+ popupItem->polish();
+ return;
+ }
+
const qreal w = popupItem->width();
const qreal h = popupItem->height();
const qreal iw = popupItem->implicitWidth();
@@ -205,6 +211,8 @@ void QQuickPopupPositioner::reposition()
}
}
+ m_positioning = true;
+
popupItem->setPosition(rect.topLeft());
const QPointF effectivePos = m_parentItem ? m_parentItem->mapFromScene(rect.topLeft()) : rect.topLeft();
@@ -221,6 +229,8 @@ void QQuickPopupPositioner::reposition()
popupItem->setWidth(rect.width());
if (!p->hasHeight && heightAdjusted && rect.height() > 0)
popupItem->setHeight(rect.height());
+
+ m_positioning = false;
}
void QQuickPopupPositioner::itemGeometryChanged(QQuickItem *, QQuickGeometryChange, const QRectF &)
diff --git a/src/quicktemplates2/qquickpopuppositioner_p_p.h b/src/quicktemplates2/qquickpopuppositioner_p_p.h
index 10f5465a..8d3c6386 100644
--- a/src/quicktemplates2/qquickpopuppositioner_p_p.h
+++ b/src/quicktemplates2/qquickpopuppositioner_p_p.h
@@ -75,6 +75,7 @@ private:
void removeAncestorListeners(QQuickItem *item);
void addAncestorListeners(QQuickItem *item);
+ bool m_positioning;
QQuickItem *m_parentItem;
QQuickPopup *m_popup;
};
diff --git a/src/quicktemplates2/qquickscrollbar.cpp b/src/quicktemplates2/qquickscrollbar.cpp
index ebccbcba..06cc8832 100644
--- a/src/quicktemplates2/qquickscrollbar.cpp
+++ b/src/quicktemplates2/qquickscrollbar.cpp
@@ -65,9 +65,9 @@ QT_BEGIN_NAMESPACE
}
\endcode
- \note When ScrollBar is attached \l {ScrollBar::vertical}{vertically} or
- \l {ScrollBar::horizontal}{horizontally} to a Flickable, its geometry and
- the following properties are automatically set and updated as appropriate:
+ When ScrollBar is attached \l {ScrollBar::vertical}{vertically} or
+ \l {ScrollBar::horizontal}{horizontally} to a Flickable, the following
+ properties are automatically set and updated as appropriate:
\list
\li \l orientation
\li \l position
@@ -75,6 +75,29 @@ QT_BEGIN_NAMESPACE
\li \l active
\endlist
+ An attached ScrollBar re-parents itself to the target Flickable. A vertically
+ attached ScrollBar resizes itself to the height of the Flickable, and positions
+ itself to either side of it based on the \l {Control::mirrored}{layout direction}.
+ A horizontally attached ScrollBar resizes itself to the width of the Flickable,
+ and positions itself to the bottom. The automatic geometry management can be disabled
+ by specifying another parent for the attached ScrollBar. This can be useful, for
+ example, if the ScrollBar should be placed outside a clipping Flickable. This is
+ demonstrated by the following example:
+
+ \code
+ Flickable {
+ id: flickable
+ clip: true
+ // ...
+ ScrollBar.vertical: ScrollBar {
+ parent: flickable.parent
+ anchors.top: flickable.top
+ anchors.left: flickable.right
+ anchors.bottom: flickable.bottom
+ }
+ }
+ \endcode
+
Notice that ScrollBar does not filter key events of the Flickable it is
attached to. The following example illustrates how to implement scrolling
with up and down keys:
@@ -477,6 +500,8 @@ void QQuickScrollBarAttachedPrivate::mirrorVertical()
void QQuickScrollBarAttachedPrivate::layoutHorizontal(bool move)
{
Q_ASSERT(horizontal && flickable);
+ if (horizontal->parentItem() != flickable)
+ return;
horizontal->setWidth(flickable->width());
if (move)
horizontal->setY(flickable->height() - horizontal->height());
@@ -485,6 +510,8 @@ void QQuickScrollBarAttachedPrivate::layoutHorizontal(bool move)
void QQuickScrollBarAttachedPrivate::layoutVertical(bool move)
{
Q_ASSERT(vertical && flickable);
+ if (vertical->parentItem() != flickable)
+ return;
vertical->setHeight(flickable->height());
if (move)
vertical->setX(vertical->isMirrored() ? 0 : flickable->width() - vertical->width());
diff --git a/src/quicktemplates2/qquickscrollindicator.cpp b/src/quicktemplates2/qquickscrollindicator.cpp
index b1a3e4ec..6145a5b3 100644
--- a/src/quicktemplates2/qquickscrollindicator.cpp
+++ b/src/quicktemplates2/qquickscrollindicator.cpp
@@ -65,9 +65,9 @@ QT_BEGIN_NAMESPACE
}
\endcode
- \note When ScrollIndicator is attached \l {ScrollIndicator::vertical}{vertically}
- or \l {ScrollIndicator::horizontal}{horizontally} to a Flickable, its geometry and
- the following properties are automatically set and updated as appropriate:
+ When ScrollIndicator is attached \l {ScrollIndicator::vertical}{vertically} or
+ \l {ScrollIndicator::horizontal}{horizontally} to a Flickable, the following
+ properties are automatically set and updated as appropriate:
\list
\li \l orientation
\li \l position
@@ -75,6 +75,29 @@ QT_BEGIN_NAMESPACE
\li \l active
\endlist
+ An attached ScrollIndicator re-parents itself to the target Flickable. A vertically
+ attached ScrollIndicator resizes itself to the height of the Flickable, and positions
+ itself to either side of it based on the \l {Control::mirrored}{layout direction}.
+ A horizontally attached ScrollIndicator resizes itself to the width of the Flickable,
+ and positions itself to the bottom. The automatic geometry management can be disabled
+ by specifying another parent for the attached ScrollIndicator. This can be useful, for
+ example, if the ScrollIndicator should be placed outside a clipping Flickable. This is
+ demonstrated by the following example:
+
+ \code
+ Flickable {
+ id: flickable
+ clip: true
+ // ...
+ ScrollIndicator.vertical: ScrollIndicator {
+ parent: flickable.parent
+ anchors.top: flickable.top
+ anchors.left: flickable.right
+ anchors.bottom: flickable.bottom
+ }
+ }
+ \endcode
+
Horizontal and vertical scroll indicators do not share the \l active state with
each other by default. In order to keep both indicators visible whilst scrolling
to either direction, establish a two-way binding between the active states as
@@ -268,6 +291,8 @@ void QQuickScrollIndicatorAttachedPrivate::activateVertical()
void QQuickScrollIndicatorAttachedPrivate::layoutHorizontal(bool move)
{
Q_ASSERT(horizontal && flickable);
+ if (horizontal->parentItem() != flickable)
+ return;
horizontal->setWidth(flickable->width());
if (move)
horizontal->setY(flickable->height() - horizontal->height());
@@ -276,6 +301,8 @@ void QQuickScrollIndicatorAttachedPrivate::layoutHorizontal(bool move)
void QQuickScrollIndicatorAttachedPrivate::layoutVertical(bool move)
{
Q_ASSERT(vertical && flickable);
+ if (vertical->parentItem() != flickable)
+ return;
vertical->setHeight(flickable->height());
if (move && !QQuickItemPrivate::get(vertical)->isMirrored())
vertical->setX(flickable->width() - vertical->width());
diff --git a/src/quicktemplates2/qquickswitch.cpp b/src/quicktemplates2/qquickswitch.cpp
index a7d17e86..8c3d9f0b 100644
--- a/src/quicktemplates2/qquickswitch.cpp
+++ b/src/quicktemplates2/qquickswitch.cpp
@@ -57,17 +57,11 @@ QT_BEGIN_NAMESPACE
Switch is an option button that can be dragged or toggled on (checked) or
off (unchecked). Switches are typically used to select between two states.
+ For larger sets of options, such as those in a list, consider using
+ \l SwitchDelegate instead.
- \table
- \row \li \image qtquickcontrols2-switch-normal.png
- \li A switch in its normal state.
- \row \li \image qtquickcontrols2-switch-checked.png
- \li A switch that is checked.
- \row \li \image qtquickcontrols2-switch-focused.png
- \li A switch that has active focus.
- \row \li \image qtquickcontrols2-switch-disabled.png
- \li A switch that is disabled.
- \endtable
+ Switch inherits its API from \l AbstractButton. For instance, the state
+ of the switch can be set with the \l {AbstractButton::}{checked} property.
\code
ColumnLayout {
diff --git a/src/quicktemplates2/qquickswitchdelegate.cpp b/src/quicktemplates2/qquickswitchdelegate.cpp
index 62b677e5..edfb15d5 100644
--- a/src/quicktemplates2/qquickswitchdelegate.cpp
+++ b/src/quicktemplates2/qquickswitchdelegate.cpp
@@ -53,9 +53,13 @@ QT_BEGIN_NAMESPACE
SwitchDelegate presents an item delegate that can be toggled on (checked) or
off (unchecked). Switch delegates are typically used to select one or more
- options from a set of options.
+ options from a set of options. For smaller sets of options, or for options
+ that need to be uniquely identifiable, consider using \l Switch instead.
- The state of the check delegate can be set with the
+ SwitchDelegate inherits its API from \l ItemDelegate, which is inherited
+ from \l AbstractButton. For instance, you can set \l {AbstractButton::text}{text},
+ and react to \l {AbstractButton::clicked}{clicks} using the \l AbstractButton
+ API. The state of the switch delegate can be set with the
\l {AbstractButton::}{checked} property.
\code
diff --git a/src/quicktemplates2/qquicktextarea.cpp b/src/quicktemplates2/qquicktextarea.cpp
index 9a5590a5..7d15a428 100644
--- a/src/quicktemplates2/qquicktextarea.cpp
+++ b/src/quicktemplates2/qquicktextarea.cpp
@@ -79,6 +79,8 @@ QT_BEGIN_NAMESPACE
decoration of the TextArea scrolls together with the rest of the scrollable
content.
+ \section2 Scrollable TextArea
+
If you want to make a TextArea scrollable, for example, when it covers
an entire application page, attach it to a \l Flickable and combine with a
\l ScrollBar or \l ScrollIndicator.
@@ -87,7 +89,7 @@ QT_BEGIN_NAMESPACE
\snippet qtquickcontrols2-textarea-flickable.qml 1
- A TextArea that is attached to a Flickable does the following:
+ A TextArea that is attached to a \l Flickable does the following:
\list
\li Sets the content size automatically
@@ -755,9 +757,7 @@ QQuickTextAreaAttached::~QQuickTextAreaAttached()
This property attaches a text area to a \l Flickable.
- \snippet qtquickcontrols2-textarea-flickable.qml 1
-
- \sa ScrollBar, ScrollIndicator
+ \sa ScrollBar, ScrollIndicator, {Scrollable TextArea}
*/
QQuickTextArea *QQuickTextAreaAttached::flickable() const
{
diff --git a/tests/auto/controls/data/tst_dialog.qml b/tests/auto/controls/data/tst_dialog.qml
index d4cbc222..69c47fed 100644
--- a/tests/auto/controls/data/tst_dialog.qml
+++ b/tests/auto/controls/data/tst_dialog.qml
@@ -62,16 +62,6 @@ TestCase {
}
Component {
- id: headerBox
- DialogButtonBox { position: DialogButtonBox.Header }
- }
-
- Component {
- id: footerBox
- DialogButtonBox { position: DialogButtonBox.Footer }
- }
-
- Component {
id: signalSpy
SignalSpy { }
}
@@ -79,9 +69,8 @@ TestCase {
function test_defaults() {
var control = dialog.createObject(testCase)
verify(control)
- verify(!control.header)
- verify(!control.footer)
- verify(control.buttonBox)
+ verify(control.header)
+ verify(control.footer)
compare(control.standardButtons, 0)
control.destroy()
}
@@ -122,22 +111,18 @@ TestCase {
function test_buttonBox_data() {
return [
- { tag: "default header", property: "header", buttonBox: headerBox },
- { tag: "default footer", property: "footer", buttonBox: footerBox },
- { tag: "custom header", property: "header", position: DialogButtonBox.Header },
- { tag: "custom footer", property: "footer", position: DialogButtonBox.Footer }
+ { tag: "default" },
+ { tag: "custom", custom: true }
]
}
function test_buttonBox(data) {
var control = dialog.createObject(testCase)
- if (data.buttonBox)
- control.buttonBox = data.buttonBox
- else
- control[data.property] = buttonBox.createObject(testCase, {position: data.position})
+ if (data.custom)
+ control.footer = buttonBox.createObject(testCase)
control.standardButtons = Dialog.Ok | Dialog.Cancel
- var box = control[data.property]
+ var box = control.footer
verify(box)
compare(box.standardButtons, Dialog.Ok | Dialog.Cancel)
@@ -192,30 +177,6 @@ TestCase {
control.destroy()
}
- function test_warnings() {
- var control = dialog.createObject(testCase)
- verify(control)
-
- var testComponent = Qt.createComponent("TestItem.qml")
- verify(testComponent)
-
- control.buttonBox = headerBox
- control.header = testComponent.createObject(testCase)
- ignoreWarning(Qt.resolvedUrl("tst_dialog.qml") + ":56:9: QML Dialog: Custom header detected. Cannot assign buttonBox as a header. No standard buttons will appear in the header.")
- control.standardButtons = Dialog.Apply
-
- control.buttonBox = footerBox
- control.footer = testComponent.createObject(testCase)
- ignoreWarning(Qt.resolvedUrl("tst_dialog.qml") + ":56:9: QML Dialog: Custom footer detected. Cannot assign buttonBox as a footer. No standard buttons will appear in the footer.")
- control.standardButtons = Dialog.Cancel
-
- control.buttonBox = testComponent
- ignoreWarning(Qt.resolvedUrl("tst_dialog.qml") + ":56:9: QML Dialog: buttonBox must be an instance of DialogButtonBox")
- control.standardButtons = Dialog.Ok
-
- control.destroy()
- }
-
function test_layout() {
var control = dialog.createObject(testCase, {width: 100, height: 100})
verify(control)
@@ -294,4 +255,48 @@ TestCase {
control.destroy()
}
+
+ function test_spacing_data() {
+ return [
+ { tag: "content", header: false, content: true, footer: false },
+ { tag: "header,content", header: true, content: true, footer: false },
+ { tag: "content,footer", header: false, content: true, footer: true },
+ { tag: "header,content,footer", header: true, content: true, footer: true },
+ { tag: "header,footer", header: true, content: false, footer: true },
+ { tag: "header", header: true, content: false, footer: false },
+ { tag: "footer", header: false, content: false, footer: true },
+ ]
+ }
+
+ function test_spacing(data) {
+ var control = dialog.createObject(testCase, {spacing: 20, width: 100, height: 100})
+ verify(control)
+
+ control.open()
+ waitForRendering(control.contentItem)
+ verify(control.visible)
+
+ control.contentItem.visible = data.content
+ control.header = buttonBox.createObject(control.contentItem, {visible: data.header})
+ control.footer = buttonBox.createObject(control.contentItem, {visible: data.footer})
+
+ compare(control.header.x, 0)
+ compare(control.header.y, 0)
+ compare(control.header.width, control.width)
+ verify(control.header.height > 0)
+
+ compare(control.footer.x, 0)
+ compare(control.footer.y, control.height - control.footer.height)
+ compare(control.footer.width, control.width)
+ verify(control.footer.height > 0)
+
+ compare(control.contentItem.x, control.leftPadding)
+ compare(control.contentItem.y, control.topPadding + (data.header ? control.header.height + control.spacing : 0))
+ compare(control.contentItem.width, control.availableWidth)
+ compare(control.contentItem.height, control.availableHeight
+ - (data.header ? control.header.height + control.spacing : 0)
+ - (data.footer ? control.footer.height + control.spacing : 0))
+
+ control.destroy()
+ }
}
diff --git a/tests/auto/controls/data/tst_page.qml b/tests/auto/controls/data/tst_page.qml
index a1cdbf8e..9b52236e 100644
--- a/tests/auto/controls/data/tst_page.qml
+++ b/tests/auto/controls/data/tst_page.qml
@@ -226,4 +226,44 @@ TestCase {
control.destroy()
}
+
+ function test_spacing_data() {
+ return [
+ { tag: "content", header: false, content: true, footer: false },
+ { tag: "header,content", header: true, content: true, footer: false },
+ { tag: "content,footer", header: false, content: true, footer: true },
+ { tag: "header,content,footer", header: true, content: true, footer: true },
+ { tag: "header,footer", header: true, content: false, footer: true },
+ { tag: "header", header: true, content: false, footer: false },
+ { tag: "footer", header: false, content: false, footer: true },
+ ]
+ }
+
+ function test_spacing(data) {
+ var control = page.createObject(testCase, {spacing: 20, width: 100, height: 100})
+ verify(control)
+
+ control.contentItem.visible = data.content
+ control.header = toolBar.createObject(control.contentItem, {visible: data.header})
+ control.footer = toolBar.createObject(control.contentItem, {visible: data.footer})
+
+ compare(control.header.x, 0)
+ compare(control.header.y, 0)
+ compare(control.header.width, control.width)
+ verify(control.header.height > 0)
+
+ compare(control.footer.x, 0)
+ compare(control.footer.y, control.height - control.footer.height)
+ compare(control.footer.width, control.width)
+ verify(control.footer.height > 0)
+
+ compare(control.contentItem.x, control.leftPadding)
+ compare(control.contentItem.y, control.topPadding + (data.header ? control.header.height + control.spacing : 0))
+ compare(control.contentItem.width, control.availableWidth)
+ compare(control.contentItem.height, control.availableHeight
+ - (data.header ? control.header.height + control.spacing : 0)
+ - (data.footer ? control.footer.height + control.spacing : 0))
+
+ control.destroy()
+ }
}
diff --git a/tests/auto/controls/data/tst_popup.qml b/tests/auto/controls/data/tst_popup.qml
index c81c6341..982ac7ab 100644
--- a/tests/auto/controls/data/tst_popup.qml
+++ b/tests/auto/controls/data/tst_popup.qml
@@ -1229,4 +1229,35 @@ TestCase {
control.destroy()
}
+
+ Component {
+ id: xyBindingLoop
+ ApplicationWindow {
+ id: window
+ width: 360
+ height: 360
+ visible: true
+ property alias popup: popup
+
+ Popup {
+ id: popup
+ visible: true
+ x: (parent.width - width) / 2
+ y: (parent.height - height) / 2
+ Label {
+ text: "Content"
+ anchors.fill: parent
+ }
+ }
+ }
+ }
+
+ function test_xyBindingLoop() {
+ var window = xyBindingLoop.createObject(testCase)
+ var control = window.popup
+ waitForRendering(control.contentItem)
+ compare(control.x, (control.parent.width - control.width) / 2)
+ compare(control.y, (control.parent.height - control.height) / 2)
+ window.destroy()
+ }
}
diff --git a/tests/auto/controls/data/tst_scrollbar.qml b/tests/auto/controls/data/tst_scrollbar.qml
index 15b4b3f0..54ecf15f 100644
--- a/tests/auto/controls/data/tst_scrollbar.qml
+++ b/tests/auto/controls/data/tst_scrollbar.qml
@@ -155,6 +155,22 @@ TestCase {
compare(horizontal.size, container.visibleArea.widthRatio)
compare(horizontal.position, container.visibleArea.xPosition)
+ var oldY = vertical.y
+ var oldHeight = vertical.height
+ vertical.parent = testCase
+ vertical.y -= 10
+ container.height += 10
+ compare(vertical.y, oldY - 10)
+ compare(vertical.height, oldHeight)
+
+ var oldX = horizontal.x
+ var oldWidth = horizontal.width
+ horizontal.parent = testCase
+ horizontal.x -= 10
+ container.width += 10
+ compare(horizontal.x, oldX - 10)
+ compare(horizontal.width, oldWidth)
+
container.destroy()
}
diff --git a/tests/auto/controls/data/tst_scrollindicator.qml b/tests/auto/controls/data/tst_scrollindicator.qml
index 551247f6..1ec03b15 100644
--- a/tests/auto/controls/data/tst_scrollindicator.qml
+++ b/tests/auto/controls/data/tst_scrollindicator.qml
@@ -150,6 +150,22 @@ TestCase {
compare(horizontal.size, container.visibleArea.widthRatio)
compare(horizontal.position, container.visibleArea.xPosition)
+ var oldY = vertical.y
+ var oldHeight = vertical.height
+ vertical.parent = testCase
+ vertical.y -= 10
+ container.height += 10
+ compare(vertical.y, oldY - 10)
+ compare(vertical.height, oldHeight)
+
+ var oldX = horizontal.x
+ var oldWidth = horizontal.width
+ horizontal.parent = testCase
+ horizontal.x -= 10
+ container.width += 10
+ compare(horizontal.x, oldX - 10)
+ compare(horizontal.width, oldWidth)
+
container.destroy()
}
diff --git a/tests/auto/drawer/tst_drawer.cpp b/tests/auto/drawer/tst_drawer.cpp
index 58a5ba3c..a523beed 100644
--- a/tests/auto/drawer/tst_drawer.cpp
+++ b/tests/auto/drawer/tst_drawer.cpp
@@ -380,7 +380,7 @@ void tst_Drawer::reposition()
window->setWidth(window->width() + 100);
QTRY_COMPARE(geometry(dimmer), QRectF(0, 150, window->width(), window->height() - 150));
- QCOMPARE(geometry(popupItem), QRectF(window->width() - drawer->width(), 150, window->width() / 2, window->height() - 150));
+ QTRY_COMPARE(geometry(popupItem), QRectF(window->width() - drawer->width(), 150, window->width() / 2, window->height() - 150));
drawer->close();
QTRY_COMPARE(geometry(popupItem), QRectF(window->width(), 150, window->width() / 2, window->height() - 150));
diff --git a/tests/manual/testbench/main.cpp b/tests/manual/testbench/main.cpp
index a782b5fe..5a54dab3 100644
--- a/tests/manual/testbench/main.cpp
+++ b/tests/manual/testbench/main.cpp
@@ -54,7 +54,7 @@ int main(int argc, char *argv[])
// TODO: move style selection into app UI and use settings to save choices.
// qputenv("QT_QUICK_CONTROLS_STYLE", "material");
QQmlApplicationEngine engine;
- engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
+ engine.load(QUrl(QStringLiteral("qrc:/testbench.qml")));
return app.exec();
}
diff --git a/tests/manual/testbench/qml.qrc b/tests/manual/testbench/qml.qrc
index 5f6483ac..9f4b1783 100644
--- a/tests/manual/testbench/qml.qrc
+++ b/tests/manual/testbench/qml.qrc
@@ -1,5 +1,5 @@
<RCC>
<qresource prefix="/">
- <file>main.qml</file>
+ <file>testbench.qml</file>
</qresource>
</RCC>
diff --git a/tests/manual/testbench/main.qml b/tests/manual/testbench/testbench.qml
index ea59d5b5..38fd06fc 100644
--- a/tests/manual/testbench/main.qml
+++ b/tests/manual/testbench/testbench.qml
@@ -745,14 +745,14 @@ ApplicationWindow {
Frame {
Tumbler {
model: 5
- implicitWidth: 100
+ implicitWidth: 80
implicitHeight: 100
}
}
Frame {
Tumbler {
model: 5
- implicitWidth: 100
+ implicitWidth: 80
implicitHeight: 100
enabled: false
}
@@ -761,11 +761,147 @@ ApplicationWindow {
RowLayout {
Dial {
+ implicitWidth: 100
+ implicitHeight: 100
}
Dial {
+ implicitWidth: 100
+ implicitHeight: 100
enabled: false
}
}
+
+ ListModel {
+ id: checkableDelegateModel
+ ListElement { label: "Normal" }
+ ListElement { label: "Pressed"; press: true }
+ ListElement { label: "Checked"; check: true }
+ ListElement { label: "CH + PR"; check: true; press: true }
+ ListElement { label: "Disabled"; disabled: true }
+ }
+
+ RowLayout {
+ Frame {
+ Column {
+ width: 200
+
+ Repeater {
+ model: checkableDelegateModel
+ delegate: CheckDelegate {
+ text: label
+ width: parent.width
+ down: press
+ checked: check
+ enabled: !disabled
+ ButtonGroup.group: radioButtonGroup
+ }
+ }
+ }
+ }
+
+ ButtonGroup {
+ id: radioButtonGroup
+ }
+
+ Frame {
+ Column {
+ width: 200
+
+ Repeater {
+ model: checkableDelegateModel
+ delegate: RadioDelegate {
+ text: label
+ down: press
+ width: parent.width
+ checked: check
+ enabled: !disabled
+ ButtonGroup.group: radioButtonGroup
+ }
+ }
+ }
+ }
+
+ Frame {
+ Column {
+ width: 200
+
+ Repeater {
+ model: checkableDelegateModel
+ delegate: SwitchDelegate {
+ text: label
+ width: parent.width
+ checked: check
+ down: press
+ enabled: !disabled
+ }
+ }
+ }
+ }
+ }
+
+ ListModel {
+ id: regularDelegateModel
+ ListElement { label: "Normal" }
+ ListElement { label: "Pressed"; press: true }
+ ListElement { label: "Disabled"; disabled: true }
+ }
+
+ RowLayout {
+ Frame {
+ Column {
+ width: 200
+
+ Repeater {
+ model: regularDelegateModel
+ delegate: ItemDelegate {
+ text: label
+ width: parent.width
+ down: press
+ enabled: !disabled
+ }
+ }
+ }
+ }
+ Frame {
+ Column {
+ id: listView
+ width: 200
+ clip: true
+
+ Repeater {
+ model: regularDelegateModel
+ delegate: SwipeDelegate {
+ id: swipeDelegate
+ text: label
+ width: parent.width
+ down: press
+ enabled: !disabled
+
+ Component {
+ id: removeComponent
+
+ Rectangle {
+ color: swipeDelegate.swipe.complete && swipeDelegate.pressed ? "#333" : "#444"
+ width: parent.width
+ height: parent.height
+ clip: true
+
+ Label {
+ font.pixelSize: swipeDelegate.font.pixelSize
+ text: "Boop"
+ color: "white"
+ anchors.centerIn: parent
+ }
+ }
+ }
+
+ swipe.left: removeComponent
+ swipe.right: removeComponent
+ }
+ }
+ }
+ }
+ }
}
}
}