aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJ-P Nurmi <jpnurmi@theqtcompany.com>2016-01-25 11:02:44 +0100
committerJ-P Nurmi <jpnurmi@theqtcompany.com>2016-01-25 11:03:53 +0100
commit5ada1525e03116326a480fb05611904d3484c296 (patch)
treef23822e6b0482012065b9586d95cb8ab5d70c4bf
parentf4f5e857447d42738b1b60b5c4184f39df2f1593 (diff)
parent4f1fb09ed70c69e73f2e19f28f4299f4cfbc90dc (diff)
Merge remote-tracking branch 'origin/5.6' into dev
Conflicts: .gitignore src/templates/qquickcombobox_p.h src/templates/qquickmenu_p.h src/templates/qquickmenu_p_p.h src/templates/qquickoverlay_p.h src/templates/qquickpopup.cpp src/templates/qquickpopup_p.h src/templates/qquickstackview_p.cpp Change-Id: I89c7d518697beec0b81ef3a12205286a4f3ccf89
-rw-r--r--.gitignore1
-rw-r--r--examples/controls/gallery/gallery.qml195
-rw-r--r--examples/controls/gallery/qtlabscontrols.conf1
-rw-r--r--src/controls/qquickstyle.cpp4
-rw-r--r--src/imports/calendar/qquickcalendarmodel.cpp2
-rw-r--r--src/imports/calendar/qquickdayofweekrow.cpp2
-rw-r--r--src/imports/calendar/qquickmonthgrid.cpp4
-rw-r--r--src/imports/calendar/qquickweeknumbercolumn.cpp2
-rw-r--r--src/imports/controls/Button.qml2
-rw-r--r--src/imports/controls/CheckBox.qml2
-rw-r--r--src/imports/controls/ComboBox.qml40
-rw-r--r--src/imports/controls/Menu.qml25
-rw-r--r--src/imports/controls/Popup.qml14
-rw-r--r--src/imports/controls/RadioButton.qml2
-rw-r--r--src/imports/controls/Slider.qml2
-rw-r--r--src/imports/controls/SpinBox.qml4
-rw-r--r--src/imports/controls/Switch.qml2
-rw-r--r--src/imports/controls/doc/qtlabscontrols.qdocconf2
-rw-r--r--src/imports/controls/doc/src/qtlabscontrols-gettingstarted.qdoc70
-rw-r--r--src/imports/controls/doc/src/qtlabscontrols-index.qdoc42
-rw-r--r--src/imports/controls/doc/src/qtlabscontrols-material.qdoc50
-rw-r--r--src/imports/controls/doc/src/qtlabscontrols-universal.qdoc2
-rw-r--r--src/imports/controls/doc/src/qtlabscontrols.qdoc2
-rw-r--r--src/imports/controls/doc/src/templates/qtlabstemplates.qdoc2
-rw-r--r--src/imports/controls/material/ComboBox.qml35
-rw-r--r--src/imports/controls/material/Menu.qml42
-rw-r--r--src/imports/controls/material/Popup.qml24
-rw-r--r--src/imports/controls/material/ToolBar.qml2
-rw-r--r--src/imports/controls/material/qquickmaterialstyle.cpp125
-rw-r--r--src/imports/controls/material/qquickmaterialstyle_p.h13
-rw-r--r--src/imports/controls/universal/ComboBox.qml33
-rw-r--r--src/imports/controls/universal/Menu.qml27
-rw-r--r--src/imports/controls/universal/Popup.qml59
-rw-r--r--src/imports/controls/universal/universal.pri1
-rw-r--r--src/templates/qquickabstractbutton.cpp2
-rw-r--r--src/templates/qquickapplicationwindow.cpp2
-rw-r--r--src/templates/qquickbusyindicator.cpp2
-rw-r--r--src/templates/qquickbutton.cpp2
-rw-r--r--src/templates/qquickbuttongroup.cpp2
-rw-r--r--src/templates/qquickcheckbox.cpp2
-rw-r--r--src/templates/qquickcombobox.cpp9
-rw-r--r--src/templates/qquickcombobox_p.h1
-rw-r--r--src/templates/qquickcontainer.cpp2
-rw-r--r--src/templates/qquickcontrol.cpp2
-rw-r--r--src/templates/qquickdial.cpp24
-rw-r--r--src/templates/qquickdrawer.cpp2
-rw-r--r--src/templates/qquickframe.cpp2
-rw-r--r--src/templates/qquickgroupbox.cpp2
-rw-r--r--src/templates/qquickitemdelegate.cpp2
-rw-r--r--src/templates/qquicklabel.cpp2
-rw-r--r--src/templates/qquickmenu.cpp108
-rw-r--r--src/templates/qquickmenu_p.h2
-rw-r--r--src/templates/qquickmenu_p_p.h8
-rw-r--r--src/templates/qquickmenuitem.cpp2
-rw-r--r--src/templates/qquickoverlay.cpp12
-rw-r--r--src/templates/qquickoverlay_p.h1
-rw-r--r--src/templates/qquickpageindicator.cpp2
-rw-r--r--src/templates/qquickpane.cpp2
-rw-r--r--src/templates/qquickpopup.cpp938
-rw-r--r--src/templates/qquickpopup_p.h128
-rw-r--r--src/templates/qquickpopup_p_p.h99
-rw-r--r--src/templates/qquickprogressbar.cpp2
-rw-r--r--src/templates/qquickradiobutton.cpp2
-rw-r--r--src/templates/qquickrangeslider.cpp2
-rw-r--r--src/templates/qquickscrollbar.cpp2
-rw-r--r--src/templates/qquickscrollindicator.cpp2
-rw-r--r--src/templates/qquickslider.cpp2
-rw-r--r--src/templates/qquickspinbox.cpp6
-rw-r--r--src/templates/qquickstackview.cpp16
-rw-r--r--src/templates/qquickstackview_p.cpp24
-rw-r--r--src/templates/qquickswipeview.cpp2
-rw-r--r--src/templates/qquickswitch.cpp2
-rw-r--r--src/templates/qquicktabbar.cpp2
-rw-r--r--src/templates/qquicktabbutton.cpp2
-rw-r--r--src/templates/qquicktextarea.cpp2
-rw-r--r--src/templates/qquicktextfield.cpp2
-rw-r--r--src/templates/qquicktoolbar.cpp2
-rw-r--r--src/templates/qquicktoolbutton.cpp2
-rw-r--r--src/templates/qquicktumbler.cpp2
-rw-r--r--tests/auto/controls/data/tst_stackview.qml39
-rw-r--r--tests/auto/material/data/tst_material.qml90
-rw-r--r--tests/auto/menu/tst_menu.cpp12
-rw-r--r--tests/auto/universal/data/tst_universal.qml2
-rw-r--r--tests/manual/testbench/main.qml39
84 files changed, 2036 insertions, 419 deletions
diff --git a/.gitignore b/.gitignore
index c4a2ee8b..e85efb72 100644
--- a/.gitignore
+++ b/.gitignore
@@ -96,3 +96,4 @@ android-*.so-deployment-settings.json
*.directory
*_plugin_import.cpp
*_wrapper.sh
+*_wrapper.bat
diff --git a/examples/controls/gallery/gallery.qml b/examples/controls/gallery/gallery.qml
index 2bd7d40f..d40e7f9b 100644
--- a/examples/controls/gallery/gallery.qml
+++ b/examples/controls/gallery/gallery.qml
@@ -86,6 +86,20 @@ ApplicationWindow {
source: "qrc:/images/menu.png"
}
onClicked: optionsMenu.open()
+
+ Menu {
+ id: optionsMenu
+ x: parent.width - width
+
+ MenuItem {
+ text: "Settings"
+ onTriggered: settingsPopup.open()
+ }
+ MenuItem {
+ text: "About"
+ onTriggered: aboutDialog.open()
+ }
+ }
}
}
}
@@ -193,83 +207,76 @@ ApplicationWindow {
Popup {
id: settingsPopup
+ x: (window.width - width) / 2
+ y: window.height / 6
+ width: Math.min(window.width, window.height) / 3 * 2
+ height: settingsColumn.implicitHeight + topPadding + bottomPadding
modal: true
focus: true
onPressedOutside: close()
- contentItem: Pane {
- id: settingsPane
- x: (window.width - width) / 2
- y: window.height / 6
- width: Math.min(window.width, window.height) / 3 * 2
- contentHeight: settingsColumn.implicitHeight
-
- Keys.onEscapePressed: settingsPopup.close()
+ contentItem: ColumnLayout {
+ id: settingsColumn
+ spacing: 20
+ Keys.onEscapePressed: settingsPopup.close() // TODO: Popup::closePolicy
+ Label {
+ text: "Settings"
+ font.bold: true
+ }
- ColumnLayout {
- id: settingsColumn
- spacing: 20
- anchors.fill: parent
+ RowLayout {
+ spacing: 10
Label {
- text: "Settings"
- font.bold: true
+ text: "Style:"
}
- RowLayout {
- spacing: 10
-
- Label {
- text: "Style:"
- }
-
- ComboBox {
- id: styleBox
- property int styleIndex: -1
- model: ["Default", "Material", "Universal"]
- Component.onCompleted: {
- styleIndex = find(settings.style)
- if (styleIndex !== -1)
- currentIndex = styleIndex
- }
- Layout.fillWidth: true
+ ComboBox {
+ id: styleBox
+ property int styleIndex: -1
+ model: ["Default", "Material", "Universal"]
+ Component.onCompleted: {
+ styleIndex = find(settings.style)
+ if (styleIndex !== -1)
+ currentIndex = styleIndex
}
- }
-
- Label {
- text: "Restart required"
- opacity: styleBox.currentIndex !== styleBox.styleIndex ? 1.0 : 0.0
- horizontalAlignment: Label.AlignHCenter
- verticalAlignment: Label.AlignVCenter
Layout.fillWidth: true
- Layout.fillHeight: true
}
+ }
+
+ Label {
+ text: "Restart required"
+ opacity: styleBox.currentIndex !== styleBox.styleIndex ? 1.0 : 0.0
+ horizontalAlignment: Label.AlignHCenter
+ verticalAlignment: Label.AlignVCenter
+ Layout.fillWidth: true
+ Layout.fillHeight: true
+ }
- RowLayout {
- spacing: 10
+ RowLayout {
+ spacing: 10
- Button {
- id: okButton
- text: "Ok"
- onClicked: {
- settings.style = styleBox.displayText
- settingsPopup.close()
- }
- Layout.preferredWidth: 0
- Layout.fillWidth: true
+ Button {
+ id: okButton
+ text: "Ok"
+ onClicked: {
+ settings.style = styleBox.displayText
+ settingsPopup.close()
}
+ Layout.preferredWidth: 0
+ Layout.fillWidth: true
+ }
- Button {
- id: cancelButton
- text: "Cancel"
- onClicked: {
- styleBox.currentIndex = styleBox.styleIndex
- settingsPopup.close()
- }
- Layout.preferredWidth: 0
- Layout.fillWidth: true
+ Button {
+ id: cancelButton
+ text: "Cancel"
+ onClicked: {
+ styleBox.currentIndex = styleBox.styleIndex
+ settingsPopup.close()
}
+ Layout.preferredWidth: 0
+ Layout.fillWidth: true
}
}
}
@@ -279,57 +286,37 @@ ApplicationWindow {
id: aboutDialog
modal: true
focus: true
+ x: (window.width - width) / 2
+ y: window.height / 6
+ width: Math.min(window.width, window.height) / 3 * 2
+ contentHeight: aboutColumn.height
onPressedOutside: close()
- contentItem: Pane {
- x: (window.width - width) / 2
- y: (window.height - height) / 2
- width: Math.min(window.width, window.height) / 3 * 2
- contentHeight: aboutColumn.implicitHeight
-
- Keys.onEscapePressed: aboutDialog.close()
-
- Column {
- id: aboutColumn
-
- spacing: 20
- anchors.fill: parent
-
- Label {
- text: "About"
- font.bold: true
- }
-
- Label {
- width: parent.width
- text: "The Qt Labs Controls module is a technology preview of the next generation user interface controls based on Qt Quick."
- wrapMode: Label.Wrap
- font.pixelSize: 12
- }
+ Column {
+ id: aboutColumn
+ spacing: 20
+ Keys.onEscapePressed: aboutDialog.close() // TODO: Popup::closePolicy
- Label {
- width: parent.width
- text: "In comparison to the desktop oriented Qt Quick Controls 1, the experimental Qt Labs "
- + "Controls are an order of magnitude simpler, lighter and faster, and are primarily targeting embedded "
- + "and mobile platforms."
- wrapMode: Label.Wrap
- font.pixelSize: 12
- }
+ Label {
+ text: "About"
+ font.bold: true
}
- }
- }
- Menu {
- id: optionsMenu
- contentItem.x: contentItem.parent ? (contentItem.parent.width - contentItem.width) : 0
+ Label {
+ width: aboutDialog.availableWidth
+ text: "The Qt Labs Controls module is a technology preview of the next generation user interface controls based on Qt Quick."
+ wrapMode: Label.Wrap
+ font.pixelSize: 12
+ }
- MenuItem {
- text: "Settings"
- onTriggered: settingsPopup.open()
- }
- MenuItem {
- text: "About"
- onTriggered: aboutDialog.open()
+ Label {
+ width: aboutDialog.availableWidth
+ text: "In comparison to the desktop oriented Qt Quick Controls 1, the experimental Qt Labs "
+ + "Controls are an order of magnitude simpler, lighter and faster, and are primarily targeting embedded "
+ + "and mobile platforms."
+ wrapMode: Label.Wrap
+ font.pixelSize: 12
+ }
}
}
}
diff --git a/examples/controls/gallery/qtlabscontrols.conf b/examples/controls/gallery/qtlabscontrols.conf
index 80041052..8f176563 100644
--- a/examples/controls/gallery/qtlabscontrols.conf
+++ b/examples/controls/gallery/qtlabscontrols.conf
@@ -2,6 +2,7 @@
Style=Universal
[Material]
+Primary=LightGreen
Accent=LightGreen
Theme=Light
diff --git a/src/controls/qquickstyle.cpp b/src/controls/qquickstyle.cpp
index 6728667e..576506fb 100644
--- a/src/controls/qquickstyle.cpp
+++ b/src/controls/qquickstyle.cpp
@@ -40,7 +40,7 @@
#include <QtCore/qsettings.h>
#include <QtCore/qfileselector.h>
#include <QtQuick/private/qquickitem_p.h>
-#include <QtLabsTemplates/private/qquickpopup_p.h>
+#include <QtLabsTemplates/private/qquickpopup_p_p.h>
QT_BEGIN_NAMESPACE
@@ -119,7 +119,7 @@ static QList<QQuickStyle *> findChildStyles(const QMetaObject *type, QObject *ob
}
}
} else if (QQuickPopup *popup = qobject_cast<QQuickPopup *>(object)) {
- item = popup->contentItem();
+ item = QQuickPopupPrivate::get(popup)->popupItem;
QQuickStyle *style = attachedStyle(type, popup);
if (style)
diff --git a/src/imports/calendar/qquickcalendarmodel.cpp b/src/imports/calendar/qquickcalendarmodel.cpp
index 832513d7..6b59d45a 100644
--- a/src/imports/calendar/qquickcalendarmodel.cpp
+++ b/src/imports/calendar/qquickcalendarmodel.cpp
@@ -60,6 +60,8 @@ QT_BEGIN_NAMESPACE
\row \li \b model.year : int \li The number of the year
\endtable
+ \labs
+
\sa MonthGrid
*/
diff --git a/src/imports/calendar/qquickdayofweekrow.cpp b/src/imports/calendar/qquickdayofweekrow.cpp
index e87c3d45..1f5e4387 100644
--- a/src/imports/calendar/qquickdayofweekrow.cpp
+++ b/src/imports/calendar/qquickdayofweekrow.cpp
@@ -64,6 +64,8 @@ QT_BEGIN_NAMESPACE
The visual appearance of DayOfWeekRow can be changed by
implementing a \l {delegate}{custom delegate}.
+ \labs
+
\sa MonthGrid, WeekNumberColumn
*/
diff --git a/src/imports/calendar/qquickmonthgrid.cpp b/src/imports/calendar/qquickmonthgrid.cpp
index 07e3448a..8fe9ad63 100644
--- a/src/imports/calendar/qquickmonthgrid.cpp
+++ b/src/imports/calendar/qquickmonthgrid.cpp
@@ -49,7 +49,7 @@ QT_BEGIN_NAMESPACE
\inherits Control
\instantiates QQuickMonthGrid
\inqmlmodule Qt.labs.calendar
- \brief A calendar view.
+ \brief A grid of days for a calendar month.
MonthGrid presents a calendar month in a grid. The contents are
calculated for a given \l month and \l year, using the specified
@@ -68,6 +68,8 @@ QT_BEGIN_NAMESPACE
The visual appearance of MonthGrid can be changed by
implementing a \l {delegate}{custom delegate}.
+ \labs
+
\sa DayOfWeekRow, WeekNumberColumn, CalendarModel
*/
diff --git a/src/imports/calendar/qquickweeknumbercolumn.cpp b/src/imports/calendar/qquickweeknumbercolumn.cpp
index 1a796ce0..031b0555 100644
--- a/src/imports/calendar/qquickweeknumbercolumn.cpp
+++ b/src/imports/calendar/qquickweeknumbercolumn.cpp
@@ -66,6 +66,8 @@ QT_BEGIN_NAMESPACE
The visual appearance of WeekNumberColumn can be changed by
implementing a \l {delegate}{custom delegate}.
+ \labs
+
\sa MonthGrid, DayOfWeekRow
*/
diff --git a/src/imports/controls/Button.qml b/src/imports/controls/Button.qml
index 1196f56b..290f4ce4 100644
--- a/src/imports/controls/Button.qml
+++ b/src/imports/controls/Button.qml
@@ -71,7 +71,7 @@ T.Button {
implicitWidth: 100
implicitHeight: 40
opacity: enabled ? 1 : 0.3
- color: control.pressed ? (control.highlighted ? "#585a5c" : "#e4e4e4") : (control.highlighted ? "#353637" : "#ffffff")
+ color: control.pressed ? (control.highlighted ? "#585a5c" : "#e4e4e4") : (control.highlighted ? "#353637" : "#f6f6f6")
border.color: control.pressed ? "#26282a" : "#353637"
}
//! [background]
diff --git a/src/imports/controls/CheckBox.qml b/src/imports/controls/CheckBox.qml
index b7d67fe6..20d8ef1c 100644
--- a/src/imports/controls/CheckBox.qml
+++ b/src/imports/controls/CheckBox.qml
@@ -60,7 +60,7 @@ T.CheckBox {
x: text ? (control.mirrored ? control.width - width - control.rightPadding : control.leftPadding) : control.leftPadding + (control.availableWidth - width) / 2
y: control.topPadding + (control.availableHeight - height) / 2
- color: control.enabled ? (control.pressed ? "#e4e4e4" : "#ffffff") : "#353637"
+ color: control.enabled ? (control.pressed ? "#e4e4e4" : "#f6f6f6") : "#353637"
border.color: control.enabled ? (control.pressed ? "#26282a" : "#353637") : "transparent"
Image {
diff --git a/src/imports/controls/ComboBox.qml b/src/imports/controls/ComboBox.qml
index 5be26304..33568699 100644
--- a/src/imports/controls/ComboBox.qml
+++ b/src/imports/controls/ComboBox.qml
@@ -99,35 +99,29 @@ T.ComboBox {
//! [popup]
popup: T.Popup {
- contentItem: Rectangle {
- // TODO: Popup::anchors
- readonly property var above: popup.visible ? control.mapToItem(null, 0, -height + 1) : Qt.point(0, 0)
- readonly property var below: popup.visible ? control.mapToItem(null, 0, control.height - 1) : Qt.point(0, 0)
+ y: control.height - 1
+ implicitWidth: control.width
+ implicitHeight: Math.min(200, listview.contentHeight)
- x: below.x
- y: above.y >= 0 && below.y + height > control.Window.height ? above.y : below.y
- width: control.width
- height: listview.height
-
- ListView {
- id: listview
- width: control.width
- height: Math.min(200, contentHeight)
-
- clip: true
- model: control.delegateModel
- currentIndex: control.highlightedIndex
-
-// ScrollIndicator.vertical: ScrollIndicator { }
- }
+ contentItem: ListView {
+ id: listview
+ clip: true
+ model: control.delegateModel
+ currentIndex: control.highlightedIndex
Rectangle {
- width: parent.width
- height: parent.height
- color: "transparent"
+ z: 10
+ parent: listview
+ width: listview.width
+ height: listview.height
border.color: "#353637"
+ color: "transparent"
}
+
+// ScrollIndicator.vertical: ScrollIndicator { }
}
+
+ background: Rectangle { }
}
//! [popup]
}
diff --git a/src/imports/controls/Menu.qml b/src/imports/controls/Menu.qml
index f4a4243e..6692ef08 100644
--- a/src/imports/controls/Menu.qml
+++ b/src/imports/controls/Menu.qml
@@ -41,10 +41,14 @@ import Qt.labs.templates 1.0 as T
T.Menu {
id: control
+ implicitWidth: Math.max(background ? background.implicitWidth : 0,
+ contentItem ? contentItem.implicitWidth + leftPadding + rightPadding : 0)
+ implicitHeight: Math.min(background ? background.implicitHeight : 0,
+ contentItem ? contentItem.implicitHeight + topPadding + bottomPadding : 0)
+
//! [contentItem]
contentItem: ListView {
- implicitWidth: 200
- implicitHeight: Math.min(contentHeight, 200)
+ implicitHeight: contentHeight
model: control.contentModel
// TODO: improve this?
interactive: ApplicationWindow.window ? contentHeight > ApplicationWindow.window.height : false
@@ -53,14 +57,15 @@ T.Menu {
currentIndex: -1
ScrollIndicator.vertical: ScrollIndicator {}
-
- Rectangle {
- width: parent.width
- height: parent.height
- color: "#ffffff"
- border.color: "#353637"
- z: -1
- }
}
//! [contentItem]
+
+ //! [background]
+ background: Rectangle {
+ implicitWidth: 200
+ implicitHeight: 200
+ color: "#ffffff"
+ border.color: "#353637"
+ }
+ //! [background]
}
diff --git a/src/imports/controls/Popup.qml b/src/imports/controls/Popup.qml
index b7c6fe08..bc7c610c 100644
--- a/src/imports/controls/Popup.qml
+++ b/src/imports/controls/Popup.qml
@@ -39,4 +39,18 @@ import Qt.labs.templates 1.0 as T
T.Popup {
id: control
+
+ implicitWidth: Math.max(background ? background.implicitWidth : 0, contentWidth + leftPadding + rightPadding)
+ implicitHeight: Math.max(background ? background.implicitHeight : 0, contentHeight + topPadding + bottomPadding)
+
+ contentWidth: contentChildren.length === 1 ? contentChildren[0].implicitWidth : 0
+ contentHeight: contentChildren.length === 1 ? contentChildren[0].implicitHeight : 0
+
+ padding: 6
+
+ contentItem: Item { }
+
+ background: Rectangle {
+ border.color: "#353637"
+ }
}
diff --git a/src/imports/controls/RadioButton.qml b/src/imports/controls/RadioButton.qml
index 82d74b88..8e1e0bce 100644
--- a/src/imports/controls/RadioButton.qml
+++ b/src/imports/controls/RadioButton.qml
@@ -64,7 +64,7 @@ T.RadioButton {
radius: width / 2
border.width: 1
border.color: (control.pressed ? "#26282a" : "#353637")
- color: control.pressed ? "#e4e4e4" : "#ffffff"
+ color: control.pressed ? "#e4e4e4" : "#f6f6f6"
Rectangle {
x: (parent.width - width) / 2
diff --git a/src/imports/controls/Slider.qml b/src/imports/controls/Slider.qml
index 250dbd3a..95cfc54e 100644
--- a/src/imports/controls/Slider.qml
+++ b/src/imports/controls/Slider.qml
@@ -57,7 +57,7 @@ T.Slider {
implicitHeight: 28
radius: width / 2
border.color: "#353637"
- color: control.pressed ? "#bdbebf" : "#ffffff"
+ color: control.pressed ? "#bdbebf" : "#f6f6f6"
readonly property bool horizontal: control.orientation === Qt.Horizontal
}
diff --git a/src/imports/controls/SpinBox.qml b/src/imports/controls/SpinBox.qml
index 4b42a839..c84a2e3e 100644
--- a/src/imports/controls/SpinBox.qml
+++ b/src/imports/controls/SpinBox.qml
@@ -84,7 +84,7 @@ T.SpinBox {
x: control.mirrored ? 0 : parent.width - width
implicitWidth: 40
implicitHeight: 40
- color: up.pressed ? "#e4e4e4" : "#ffffff"
+ color: up.pressed ? "#e4e4e4" : "#f6f6f6"
border.color: control.enabled ? "#353637" : "#bdbebf"
Rectangle {
@@ -109,7 +109,7 @@ T.SpinBox {
x: control.mirrored ? parent.width - width : 0
implicitWidth: 40
implicitHeight: 40
- color: down.pressed ? "#e4e4e4" : "#ffffff"
+ color: down.pressed ? "#e4e4e4" : "#f6f6f6"
border.color: control.enabled ? "#353637" : "#bdbebf"
Rectangle {
diff --git a/src/imports/controls/Switch.qml b/src/imports/controls/Switch.qml
index e1627d32..51348e77 100644
--- a/src/imports/controls/Switch.qml
+++ b/src/imports/controls/Switch.qml
@@ -75,7 +75,7 @@ T.Switch {
width: 28
height: 28
radius: 16
- color: control.pressed ? "#e4e4e4" : "#ffffff"
+ color: control.pressed ? "#e4e4e4" : "#f6f6f6"
border.width: 1
border.color: control.pressed ? "#26282a" : "#353637"
diff --git a/src/imports/controls/doc/qtlabscontrols.qdocconf b/src/imports/controls/doc/qtlabscontrols.qdocconf
index df004294..cfd5ec55 100644
--- a/src/imports/controls/doc/qtlabscontrols.qdocconf
+++ b/src/imports/controls/doc/qtlabscontrols.qdocconf
@@ -60,3 +60,5 @@ macro.styleimport.HTML = "<table class=\"alignedsummary\"><tbody><tr><td class=\
# \endstyleproperty
macro.styleproperty.HTML = "<div class=\"qmlproto\"><table class=\"qmlname\"><tbody><tr valign=\"top\" class=\"odd\" id=\"\3\"><td class=\"tblQmlPropNode\"><p><span class=\"name\">\1</span> : <span class=\"type\">\2</span></p></td></tr></tbody></table></div>"
macro.endstyleproperty = "\\br"
+
+macro.labs = "\\note \\e{Types in the Qt.labs module are not guaranteed to remain compatible in future versions.}"
diff --git a/src/imports/controls/doc/src/qtlabscontrols-gettingstarted.qdoc b/src/imports/controls/doc/src/qtlabscontrols-gettingstarted.qdoc
new file mode 100644
index 00000000..3f6d2898
--- /dev/null
+++ b/src/imports/controls/doc/src/qtlabscontrols-gettingstarted.qdoc
@@ -0,0 +1,70 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 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$
+**
+****************************************************************************/
+
+/*!
+ \page qtlabscontrols-gettingstarted.html
+ \title Getting Started with Qt Labs Controls
+
+ A basic example of a QML file that makes use of controls is shown here:
+
+ \snippet basic-example.qml 0
+
+ \section1 Setting Up Controls from C++
+
+ Although QQuickView has traditionally been used to display QML files in a
+ C++ application, doing this means you can only set window properties from
+ C++.
+
+ With Qt Labs Controls, declare an ApplicationWindow as the root item of
+ your application and launch it by using QQmlApplicationEngine instead.
+ This ensures that you can control top level window properties from QML.
+
+ A basic example of a source file that makes use of controls is shown here:
+
+ \code
+ #include <QGuiApplication>
+ #include <QQmlApplicationEngine>
+
+ int main(int argc, char *argv[])
+ {
+ QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
+ QGuiApplication app(argc, argv);
+ QQmlApplicationEngine engine("main.qml");
+ return app.exec();
+ }
+ \endcode
+
+ \section2 Using C++ Data From QML
+
+ If you need to register a C++ class to use from QML, you can call
+ qmlRegisterType() before declaring your QQmlApplicationEngine.
+ See \l [QtQml] {Defining QML Types from C++} for more information.
+
+ If you need to expose data to QML components, you need to make them
+ available to the context of the current QML engine. See QQmlContext for
+ more information.
+*/
diff --git a/src/imports/controls/doc/src/qtlabscontrols-index.qdoc b/src/imports/controls/doc/src/qtlabscontrols-index.qdoc
index dc198135..93040e3f 100644
--- a/src/imports/controls/doc/src/qtlabscontrols-index.qdoc
+++ b/src/imports/controls/doc/src/qtlabscontrols-index.qdoc
@@ -42,50 +42,10 @@
\section2 Qt.labs.calendar Module
\generatelist {qmltypesbymodule Qt.labs.calendar}
- \section1 Getting Started
-
- A basic example of a QML file that makes use of controls is shown here:
-
- \snippet basic-example.qml 0
-
- \section1 Setting Up Controls from C++
-
- Although QQuickView has traditionally been used to display QML files in a
- C++ application, doing this means you can only set window properties from
- C++.
-
- With Qt Labs Controls, declare an ApplicationWindow as the root item of
- your application and launch it by using QQmlApplicationEngine instead.
- This ensures that you can control top level window properties from QML.
-
- A basic example of a source file that makes use of controls is shown here:
-
- \code
- #include <QGuiApplication>
- #include <QQmlApplicationEngine>
-
- int main(int argc, char *argv[])
- {
- QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
- QGuiApplication app(argc, argv);
- QQmlApplicationEngine engine("main.qml");
- return app.exec();
- }
- \endcode
-
- \section2 Using C++ Data From QML
-
- If you need to register a C++ class to use from QML, you can call
- qmlRegisterType() before declaring your QQmlApplicationEngine.
- See \l [QtQml] {Defining QML Types from C++} for more information.
-
- If you need to expose data to QML components, you need to make them
- available to the context of the current QML engine. See QQmlContext for
- more information.
-
\section1 Important Concepts in Qt Labs Controls
\list
+ \li \l{Getting Started with Qt Labs Controls}
\li \l{Styling Qt Labs Controls}
\li \l{High-DPI Support in Qt Labs Controls}
\li \l{Differences between Qt Quick Controls}
diff --git a/src/imports/controls/doc/src/qtlabscontrols-material.qdoc b/src/imports/controls/doc/src/qtlabscontrols-material.qdoc
index f9b6a008..e2cadbda 100644
--- a/src/imports/controls/doc/src/qtlabscontrols-material.qdoc
+++ b/src/imports/controls/doc/src/qtlabscontrols-material.qdoc
@@ -38,6 +38,7 @@
\list
\li \l {accent-attached-prop}{\b accent} : color
+ \li \l {primary-attached-prop}{\b primary} : color
\li \l {theme-attached-prop}{\b theme} : enumeration
\endlist
@@ -59,9 +60,9 @@
\section2 Customization
- The Material style allows customizing two attributes, \l {theme-attached-prop}{theme}
- and \l {accent-attached-prop}{accent}. The following example illustrates how to create
- a red \e stop button with light text:
+ The Material style allows customizing three attributes, \l {theme-attached-prop}{theme},
+ \l {primary-attached-prop}{primary} and \l {accent-attached-prop}{accent}. The following
+ example illustrates how to create a red \e stop button with light text:
\table
\row
@@ -123,18 +124,13 @@
of explicit Material style-specific references, the Material style must
be deployed with the application.
- \section1 Attached Property Documentation
-
- \styleproperty {Material.accent} {color} {accent-attached-prop}
- \target accent-attached-prop
- This attached property holds the accent color of the theme. The property
- can be attached to any window or item. The value is propagated to children.
+ \section2 Pre-defined Colors
- Even though the accent can be any \l {colorbasictypedocs}{color}, it is
- recommended to use one of the pre-defined accents that have been designed
+ Even though primary and accent can be any \l {colorbasictypedocs}{color}, it
+ is recommended to use one of the pre-defined colors that have been designed
to work well with the rest of the Material style palette:
- Available accents:
+ Available pre-defined colors:
\value Material.Red Red (#F44336)
\value Material.Pink Pink (#E91E63)
\value Material.Purple Purple (#9C27B0)
@@ -143,7 +139,7 @@
\value Material.Blue Blue (#2196F3)
\value Material.LightBlue Light Blue (#03A9F4)
\value Material.Cyan Cyan (#00BCD4)
- \value Material.Teal Teal (#009688, default)
+ \value Material.Teal Teal (#009688)
\value Material.Green Green (#4CAF50)
\value Material.LightGreen Light Green (#8BC34A)
\value Material.Lime Lime (#CDDC39)
@@ -155,6 +151,34 @@
\value Material.Grey Grey (#9E9E9E)
\value Material.BlueGrey Blue Grey (#607D8B)
+ \labs
+
+ \section1 Attached Property Documentation
+
+ \styleproperty {Material.accent} {color} {accent-attached-prop}
+ \target accent-attached-prop
+ This attached property holds the accent color of the theme. The property
+ can be attached to any window or item. The value is propagated to children.
+
+ The default value is \c Material.Teal.
+
+ \note Even though the accent can be any \l {colorbasictypedocs}{color}, it is
+ recommended to use one of the \l {pre-defined colors} that have been designed
+ to work well with the rest of the Material style palette.
+
+ \endstyleproperty
+
+ \styleproperty {Material.primary} {color} {primary-attached-prop}
+ \target primary-attached-prop
+ This attached property holds the primary color of the theme. The property
+ can be attached to any window or item. The value is propagated to children.
+
+ The default value is \c Material.BlueGray.
+
+ \note Even though the primary can be any \l {colorbasictypedocs}{color}, it is
+ recommended to use one of the \l {pre-defined colors} that have been designed
+ to work well with the rest of the Material style palette.
+
\endstyleproperty
\styleproperty {Material.theme} {enumeration} {theme-attached-prop}
diff --git a/src/imports/controls/doc/src/qtlabscontrols-universal.qdoc b/src/imports/controls/doc/src/qtlabscontrols-universal.qdoc
index 3c616d84..bf3dcfdc 100644
--- a/src/imports/controls/doc/src/qtlabscontrols-universal.qdoc
+++ b/src/imports/controls/doc/src/qtlabscontrols-universal.qdoc
@@ -124,6 +124,8 @@
of explicit Universal style-specific references, the Universal style must
be deployed with the application.
+ \labs
+
\section1 Attached Property Documentation
\styleproperty {Universal.accent} {color} {accent-attached-prop}
diff --git a/src/imports/controls/doc/src/qtlabscontrols.qdoc b/src/imports/controls/doc/src/qtlabscontrols.qdoc
index 10476f08..17e93a44 100644
--- a/src/imports/controls/doc/src/qtlabscontrols.qdoc
+++ b/src/imports/controls/doc/src/qtlabscontrols.qdoc
@@ -49,6 +49,8 @@
import Qt.labs.calendar 1.0
\endcode
+ \labs
+
\section1 QML Types
\section2 Qt.labs.controls Module
diff --git a/src/imports/controls/doc/src/templates/qtlabstemplates.qdoc b/src/imports/controls/doc/src/templates/qtlabstemplates.qdoc
index 84eabe44..0f7f7d86 100644
--- a/src/imports/controls/doc/src/templates/qtlabstemplates.qdoc
+++ b/src/imports/controls/doc/src/templates/qtlabstemplates.qdoc
@@ -41,6 +41,8 @@
import Qt.labs.templates 1.0 as T
\endcode
+ \labs
+
For the sake of clarity, there is a one-to-one mapping between the types
provided by the \c Qt.labs.templates and \c Qt.labs.controls imports. For
every type available in the \c Qt.labs.controls import, a non-visual template
diff --git a/src/imports/controls/material/ComboBox.qml b/src/imports/controls/material/ComboBox.qml
index 4b154182..fc284be1 100644
--- a/src/imports/controls/material/ComboBox.qml
+++ b/src/imports/controls/material/ComboBox.qml
@@ -115,6 +115,10 @@ T.ComboBox {
//! [popup]
popup: T.Popup {
+ y: control.height
+ implicitWidth: control.width
+ implicitHeight: Math.min(200, listview.contentHeight)
+
enter: Transition {
// grow_fade_in
NumberAnimation { property: "scale"; from: 0.9; to: 1.0; easing.type: Easing.OutQuint; duration: 220 }
@@ -127,18 +131,17 @@ T.ComboBox {
NumberAnimation { property: "opacity"; from: 1.0; to: 0.0; easing.type: Easing.OutCubic; duration: 150 }
}
- contentItem: Item {
- // TODO: Popup::anchors
- readonly property var above: popup.visible ? control.mapToItem(null, 0, -height) : Qt.point(0, 0)
- readonly property var below: popup.visible ? control.mapToItem(null, 0, control.height) : Qt.point(0, 0)
- readonly property bool showAbove: above.y >= 0 && below.y + height > control.Window.height
+ contentItem: ListView {
+ id: listview
+ clip: true
+ model: control.delegateModel
+ currentIndex: control.highlightedIndex
+ transformOrigin: popup.showAbove ? Item.Bottom : Item.Top
- x: below.x
- y: showAbove ? above.y : below.y
- width: control.width
- height: listview.height
- transformOrigin: showAbove ? Item.Bottom : Item.Top
+// ScrollIndicator.vertical: ScrollIndicator { }
+ }
+ background: Item {
Rectangle {
id: panel
width: parent.width
@@ -156,18 +159,6 @@ T.ComboBox {
samples: 15
spread: 0.5
}
-
- ListView {
- id: listview
- width: control.width
- height: Math.min(200, contentHeight) // TODO: 396
-
- clip: true
- model: control.delegateModel
- currentIndex: control.highlightedIndex
-
-// ScrollIndicator.vertical: ScrollIndicator { }
- }
}
}
//! [popup]
diff --git a/src/imports/controls/material/Menu.qml b/src/imports/controls/material/Menu.qml
index 4523fc26..6a5c6f61 100644
--- a/src/imports/controls/material/Menu.qml
+++ b/src/imports/controls/material/Menu.qml
@@ -43,6 +43,11 @@ import QtGraphicalEffects 1.0
T.Menu {
id: control
+ implicitWidth: Math.max(background ? background.implicitWidth : 0,
+ contentItem ? contentItem.implicitWidth + leftPadding + rightPadding : 0)
+ implicitHeight: Math.min(background ? background.implicitHeight : 0,
+ contentItem ? contentItem.implicitHeight + topPadding + bottomPadding : 0)
+
enter: Transition {
// grow_fade_in
NumberAnimation { property: "scale"; from: 0.9; to: 1.0; easing.type: Easing.OutQuint; duration: 220 }
@@ -56,11 +61,26 @@ T.Menu {
}
//! [contentItem]
- contentItem: Item {
- implicitWidth: 200
- implicitHeight: Math.min(listview.contentHeight, 200)
+ contentItem: ListView {
+ implicitHeight: contentHeight
transformOrigin: Item.Top
+ model: control.contentModel
+ // TODO: improve this?
+ interactive: ApplicationWindow.window ? contentHeight > ApplicationWindow.window.height : false
+ clip: true
+ keyNavigationWraps: false
+ currentIndex: -1
+
+ ScrollIndicator.vertical: ScrollIndicator {}
+ }
+ //! [contentItem]
+
+ //! [background]
+ background: Item {
+ implicitWidth: 200
+ implicitHeight: 200
+
Rectangle {
id: panel
width: parent.width
@@ -77,20 +97,6 @@ T.Menu {
samples: 15
spread: 0.5
}
-
- ListView {
- id: listview
- width: parent.width
- height: parent.height
- model: control.contentModel
- // TODO: improve this?
- interactive: ApplicationWindow.window ? contentHeight > ApplicationWindow.window.height : false
- clip: true
- keyNavigationWraps: false
- currentIndex: -1
-
- ScrollIndicator.vertical: ScrollIndicator {}
- }
}
- //! [contentItem]
+ //! [background]
}
diff --git a/src/imports/controls/material/Popup.qml b/src/imports/controls/material/Popup.qml
index 40531c61..b1c73b0c 100644
--- a/src/imports/controls/material/Popup.qml
+++ b/src/imports/controls/material/Popup.qml
@@ -35,11 +35,21 @@
****************************************************************************/
import QtQuick 2.6
+import QtGraphicalEffects 1.0
import Qt.labs.templates 1.0 as T
+import Qt.labs.controls.material 1.0
T.Popup {
id: control
+ implicitWidth: Math.max(background ? background.implicitWidth : 0, contentWidth + leftPadding + rightPadding)
+ implicitHeight: Math.max(background ? background.implicitHeight : 0, contentHeight + topPadding + bottomPadding)
+
+ contentWidth: contentChildren.length === 1 ? contentChildren[0].implicitWidth : 0
+ contentHeight: contentChildren.length === 1 ? contentChildren[0].implicitHeight : 0
+
+ padding: 6
+
enter: Transition {
// grow_fade_in
NumberAnimation { property: "scale"; from: 0.9; to: 1.0; easing.type: Easing.OutQuint; duration: 220 }
@@ -51,4 +61,18 @@ T.Popup {
NumberAnimation { property: "scale"; from: 1.0; to: 0.9; easing.type: Easing.OutQuint; duration: 220 }
NumberAnimation { property: "opacity"; from: 1.0; to: 0.0; easing.type: Easing.OutCubic; duration: 150 }
}
+
+ contentItem: Item { }
+
+ background: Rectangle {
+ radius: 3
+ color: control.Material.dialogColor
+
+ layer.effect: DropShadow {
+ verticalOffset: 1
+ color: control.Material.dropShadowColor
+ samples: 15
+ spread: 0.5
+ }
+ }
}
diff --git a/src/imports/controls/material/ToolBar.qml b/src/imports/controls/material/ToolBar.qml
index 83f07be1..ad34e1a0 100644
--- a/src/imports/controls/material/ToolBar.qml
+++ b/src/imports/controls/material/ToolBar.qml
@@ -54,7 +54,7 @@ T.ToolBar {
//! [background]
background: Rectangle {
implicitHeight: 48
- color: control.Material.accentColor
+ color: control.Material.primaryColor
}
//! [background]
}
diff --git a/src/imports/controls/material/qquickmaterialstyle.cpp b/src/imports/controls/material/qquickmaterialstyle.cpp
index 04e96480..71b48a2b 100644
--- a/src/imports/controls/material/qquickmaterialstyle.cpp
+++ b/src/imports/controls/material/qquickmaterialstyle.cpp
@@ -43,21 +43,6 @@
QT_BEGIN_NAMESPACE
-/*!
- \qmltype Material
- \inherits QtObject
- \instantiates QQuickMaterialStyleAttached
- \inqmlmodule QtQuick.Controls.Material
- \ingroup utilities
- \brief A style interface.
-
- TODO
-*/
-
-/*!
- \qmlattachedproperty color QtQuickControls2::Material::textColorPrimaray
-*/
-
static const QRgb colors[][14] = {
// Red
{
@@ -385,8 +370,10 @@ static const QRgb colors[][14] = {
};
static QQuickMaterialStyle::Theme defaultTheme = QQuickMaterialStyle::Light;
-static uint defaultAccent = QQuickMaterialStyle::Teal;
-static bool defaultCustom = false;
+static uint defaultPrimary = QQuickMaterialStyle::Indigo;
+static uint defaultAccent = QQuickMaterialStyle::Pink;
+static bool defaultPrimaryCustom = false;
+static bool defaultAccentCustom = false;
static const QRgb backgroundColorLight = 0xFFFAFAFA;
static const QRgb backgroundColorDark = 0xFF303030;
static const QRgb dialogColorLight = 0xFFFFFFFF;
@@ -420,9 +407,12 @@ static const QRgb checkBoxUncheckedRippleColorDark = 0x20FFFFFF;
QQuickMaterialStyle::QQuickMaterialStyle(QObject *parent) : QQuickStyle(parent),
m_explicitTheme(false),
+ m_explicitPrimary(false),
m_explicitAccent(false),
- m_customAccent(defaultCustom),
+ m_customPrimary(defaultPrimaryCustom),
+ m_customAccent(defaultAccentCustom),
m_theme(defaultTheme),
+ m_primary(defaultPrimary),
m_accent(defaultAccent)
{
init();
@@ -478,6 +468,76 @@ void QQuickMaterialStyle::resetTheme()
}
}
+QVariant QQuickMaterialStyle::primary() const
+{
+ return primaryColor();
+}
+
+void QQuickMaterialStyle::setPrimary(const QVariant &var)
+{
+ QRgb primary = 0;
+ bool custom = false;
+ if (var.type() == QVariant::Int) {
+ int val = var.toInt();
+ if (val > BlueGrey) {
+ qmlInfo(parent()) << "unknown Material.primary value: " << val;
+ return;
+ }
+ primary = val;
+ } else {
+ int val = QMetaEnum::fromType<Color>().keyToValue(var.toByteArray());
+ if (val != -1) {
+ primary = val;
+ } else {
+ QColor color(var.toString());
+ if (!color.isValid()) {
+ qmlInfo(parent()) << "unknown Material.primary value: " << var.toString();
+ return;
+ }
+ custom = true;
+ primary = color.rgba();
+ }
+ }
+
+ m_explicitPrimary = true;
+ if (m_primary != primary) {
+ m_customPrimary = custom;
+ m_primary = primary;
+ propagatePrimary();
+ emit primaryChanged();
+ emit paletteChanged();
+ }
+}
+
+void QQuickMaterialStyle::inheritPrimary(uint primary, bool custom)
+{
+ if (!m_explicitPrimary && m_primary != primary) {
+ m_customPrimary = custom;
+ m_primary = primary;
+ propagatePrimary();
+ emit primaryChanged();
+ }
+}
+
+void QQuickMaterialStyle::propagatePrimary()
+{
+ foreach (QQuickStyle *child, childStyles()) {
+ QQuickMaterialStyle *material = qobject_cast<QQuickMaterialStyle *>(child);
+ if (material)
+ material->inheritPrimary(m_primary, m_customPrimary);
+ }
+}
+
+void QQuickMaterialStyle::resetPrimary()
+{
+ if (m_explicitPrimary) {
+ m_customPrimary = false;
+ m_explicitPrimary = false;
+ QQuickMaterialStyle *material = qobject_cast<QQuickMaterialStyle *>(parentStyle());
+ inheritPrimary(material ? material->m_primary : defaultPrimary, true);
+ }
+}
+
QVariant QQuickMaterialStyle::accent() const
{
return accentColor();
@@ -549,6 +609,15 @@ void QQuickMaterialStyle::resetAccent()
}
}
+QColor QQuickMaterialStyle::primaryColor() const
+{
+ if (m_customPrimary)
+ return QColor::fromRgba(m_primary);
+ if (m_primary > BlueGrey)
+ return QColor();
+ return colors[m_primary][Shade500];
+}
+
QColor QQuickMaterialStyle::accentColor() const
{
if (m_customAccent)
@@ -820,6 +889,7 @@ void QQuickMaterialStyle::parentStyleChange(QQuickStyle *newParent, QQuickStyle
Q_UNUSED(oldParent);
QQuickMaterialStyle *material = qobject_cast<QQuickMaterialStyle *>(newParent);
if (material) {
+ inheritPrimary(material->m_primary, material->m_customPrimary);
inheritAccent(material->m_accent, material->m_customAccent);
inheritTheme(material->theme());
}
@@ -846,15 +916,30 @@ void QQuickMaterialStyle::init()
else if (!value.isEmpty())
qWarning().nospace().noquote() << settings->fileName() << ": unknown Material theme value: " << value;
+ value = settings->value(QStringLiteral("Primary")).toByteArray();
+ Color primary = toEnumValue<Color>(value, &ok);
+ if (ok) {
+ defaultPrimaryCustom = m_customPrimary = false;
+ defaultPrimary = m_primary = primary;
+ } else {
+ QColor color(value.constData());
+ if (color.isValid()) {
+ defaultPrimaryCustom = m_customPrimary = true;
+ defaultPrimary = m_primary = color.rgba();
+ } else if (!value.isEmpty()) {
+ qWarning().nospace().noquote() << settings->fileName() << ": unknown Material primary value: " << value;
+ }
+ }
+
value = settings->value(QStringLiteral("Accent")).toByteArray();
Color accent = toEnumValue<Color>(value, &ok);
if (ok) {
- defaultCustom = m_customAccent = false;
+ defaultAccentCustom = m_customAccent = false;
defaultAccent = m_accent = accent;
} else {
QColor color(value.constData());
if (color.isValid()) {
- defaultCustom = m_customAccent = true;
+ defaultAccentCustom = m_customAccent = true;
defaultAccent = m_accent = color.rgba();
} else if (!value.isEmpty()) {
qWarning().nospace().noquote() << settings->fileName() << ": unknown Material accent value: " << value;
diff --git a/src/imports/controls/material/qquickmaterialstyle_p.h b/src/imports/controls/material/qquickmaterialstyle_p.h
index b9236216..00103361 100644
--- a/src/imports/controls/material/qquickmaterialstyle_p.h
+++ b/src/imports/controls/material/qquickmaterialstyle_p.h
@@ -59,7 +59,9 @@ class QQuickMaterialStyle : public QQuickStyle
{
Q_OBJECT
Q_PROPERTY(Theme theme READ theme WRITE setTheme RESET resetTheme NOTIFY themeChanged FINAL)
+ Q_PROPERTY(QVariant primary READ primary WRITE setPrimary RESET resetPrimary NOTIFY primaryChanged FINAL)
Q_PROPERTY(QVariant accent READ accent WRITE setAccent RESET resetAccent NOTIFY accentChanged FINAL)
+ Q_PROPERTY(QColor primaryColor READ primaryColor NOTIFY primaryChanged FINAL) // TODO: remove?
Q_PROPERTY(QColor accentColor READ accentColor NOTIFY accentChanged FINAL) // TODO: remove?
Q_PROPERTY(QColor backgroundColor READ backgroundColor NOTIFY paletteChanged FINAL)
Q_PROPERTY(QColor primaryTextColor READ primaryTextColor NOTIFY paletteChanged FINAL)
@@ -153,12 +155,19 @@ public:
void propagateTheme();
void resetTheme();
+ QVariant primary() const;
+ void setPrimary(const QVariant &accent);
+ void inheritPrimary(uint primary, bool custom);
+ void propagatePrimary();
+ void resetPrimary();
+
QVariant accent() const;
void setAccent(const QVariant &accent);
void inheritAccent(uint accent, bool custom);
void propagateAccent();
void resetAccent();
+ QColor primaryColor() const;
QColor accentColor() const;
QColor backgroundColor() const;
QColor primaryTextColor() const;
@@ -198,6 +207,7 @@ public:
Q_SIGNALS:
void themeChanged();
+ void primaryChanged();
void accentChanged();
void paletteChanged();
@@ -208,9 +218,12 @@ private:
void init();
bool m_explicitTheme;
+ bool m_explicitPrimary;
bool m_explicitAccent;
+ bool m_customPrimary;
bool m_customAccent;
Theme m_theme;
+ uint m_primary;
uint m_accent;
};
diff --git a/src/imports/controls/universal/ComboBox.qml b/src/imports/controls/universal/ComboBox.qml
index 38c8e6e2..f61ab634 100644
--- a/src/imports/controls/universal/ComboBox.qml
+++ b/src/imports/controls/universal/ComboBox.qml
@@ -110,29 +110,22 @@ T.ComboBox {
//! [popup]
popup: T.Popup {
- contentItem: Rectangle {
- // TODO: Popup::anchors
- readonly property var above: popup.visible ? control.mapToItem(null, 0, control.height - height) : Qt.point(0, 0)
- readonly property var below: popup.visible ? control.mapToItem(null, 0, 0) : Qt.point(0, 0)
+ implicitWidth: control.width
+ implicitHeight: Math.min(200, listview.contentHeight) // TODO: 396
- x: below.x
- y: above.y >= 0 && below.y + height > control.Window.height ? above.y : below.y
- width: control.width
- height: listview.height
+ contentItem: ListView {
+ id: listview
+ clip: true
+ model: control.delegateModel
+ currentIndex: control.highlightedIndex
- color: control.Universal.chromeMediumLowColor
-
- ListView {
- id: listview
- width: control.width
- height: Math.min(200, contentHeight) // TODO: 396
-
- clip: true
- model: control.delegateModel
- currentIndex: control.highlightedIndex
+// ScrollIndicator.vertical: ScrollIndicator { }
+ }
-// ScrollIndicator.vertical: ScrollIndicator { }
- }
+ background: Rectangle {
+ color: control.Universal.chromeMediumLowColor
+ border.color: control.Universal.chromeHighColor
+ border.width: 1 // FlyoutBorderThemeThickness
}
}
//! [popup]
diff --git a/src/imports/controls/universal/Menu.qml b/src/imports/controls/universal/Menu.qml
index fec16c16..7cae65f1 100644
--- a/src/imports/controls/universal/Menu.qml
+++ b/src/imports/controls/universal/Menu.qml
@@ -42,10 +42,14 @@ import Qt.labs.controls.universal 1.0
T.Menu {
id: control
+ implicitWidth: Math.max(background ? background.implicitWidth : 0,
+ contentItem ? contentItem.implicitWidth + leftPadding + rightPadding : 0)
+ implicitHeight: Math.min(background ? background.implicitHeight : 0,
+ contentItem ? contentItem.implicitHeight + topPadding + bottomPadding : 0)
+
//! [contentItem]
contentItem: ListView {
- implicitWidth: 200
- implicitHeight: Math.min(contentHeight, 200)
+ implicitHeight: contentHeight
model: control.contentModel
// TODO: improve this?
interactive: ApplicationWindow.window ? contentHeight > ApplicationWindow.window.height : false
@@ -54,15 +58,16 @@ T.Menu {
currentIndex: -1
ScrollIndicator.vertical: ScrollIndicator {}
-
- Rectangle {
- z: -1
- width: parent.width
- height: parent.height
- color: control.Universal.chromeMediumLowColor
- border.color: control.Universal.chromeHighColor
- border.width: 1 // FlyoutBorderThemeThickness
- }
}
//! [contentItem]
+
+ //! [background]
+ background: Rectangle {
+ implicitWidth: 200
+ implicitHeight: 200
+ color: control.Universal.chromeMediumLowColor
+ border.color: control.Universal.chromeHighColor
+ border.width: 1 // FlyoutBorderThemeThickness
+ }
+ //! [background]
}
diff --git a/src/imports/controls/universal/Popup.qml b/src/imports/controls/universal/Popup.qml
new file mode 100644
index 00000000..16ed5451
--- /dev/null
+++ b/src/imports/controls/universal/Popup.qml
@@ -0,0 +1,59 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Labs Controls 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 Qt.labs.templates 1.0 as T
+import Qt.labs.controls.universal 1.0
+
+T.Popup {
+ id: control
+
+ implicitWidth: Math.max(background ? background.implicitWidth : 0, contentWidth + leftPadding + rightPadding)
+ implicitHeight: Math.max(background ? background.implicitHeight : 0, contentHeight + topPadding + bottomPadding)
+
+ contentWidth: contentChildren.length === 1 ? contentChildren[0].implicitWidth : 0
+ contentHeight: contentChildren.length === 1 ? contentChildren[0].implicitHeight : 0
+
+ padding: 12
+
+ contentItem: Item { }
+
+ background: Rectangle {
+ color: control.Universal.chromeMediumLowColor
+ border.color: control.Universal.chromeHighColor
+ border.width: 1 // FlyoutBorderThemeThickness
+ }
+}
diff --git a/src/imports/controls/universal/universal.pri b/src/imports/controls/universal/universal.pri
index 73547f4d..965228cb 100644
--- a/src/imports/controls/universal/universal.pri
+++ b/src/imports/controls/universal/universal.pri
@@ -14,6 +14,7 @@ QML_FILES += \
$$PWD/Page.qml \
$$PWD/PageIndicator.qml \
$$PWD/Pane.qml \
+ $$PWD/Popup.qml \
$$PWD/ProgressBar.qml \
$$PWD/RadioButton.qml \
$$PWD/RangeSlider.qml \
diff --git a/src/templates/qquickabstractbutton.cpp b/src/templates/qquickabstractbutton.cpp
index 5fde4be1..6c42d7d8 100644
--- a/src/templates/qquickabstractbutton.cpp
+++ b/src/templates/qquickabstractbutton.cpp
@@ -62,6 +62,8 @@ static const int AUTO_REPEAT_INTERVAL = 100;
implementations, leaving them to the types that derive from it.
TODO: ButtonGroup usage
+
+ \labs
*/
/*!
diff --git a/src/templates/qquickapplicationwindow.cpp b/src/templates/qquickapplicationwindow.cpp
index b49f80af..80e347c9 100644
--- a/src/templates/qquickapplicationwindow.cpp
+++ b/src/templates/qquickapplicationwindow.cpp
@@ -81,6 +81,8 @@ QT_BEGIN_NAMESPACE
\note By default, an ApplicationWindow is not visible.
+ \labs
+
\sa Page, {Container Controls}
*/
diff --git a/src/templates/qquickbusyindicator.cpp b/src/templates/qquickbusyindicator.cpp
index 8751ef7c..381ac5c7 100644
--- a/src/templates/qquickbusyindicator.cpp
+++ b/src/templates/qquickbusyindicator.cpp
@@ -60,6 +60,8 @@ QT_BEGIN_NAMESPACE
}
\endqml
+ \labs
+
\sa {Customizing BusyIndicator}, {Indicator Controls}
*/
diff --git a/src/templates/qquickbutton.cpp b/src/templates/qquickbutton.cpp
index b323cb0b..1e40ec05 100644
--- a/src/templates/qquickbutton.cpp
+++ b/src/templates/qquickbutton.cpp
@@ -80,6 +80,8 @@ QT_BEGIN_NAMESPACE
}
\endcode
+ \labs
+
\sa {Customizing Button}, {Button Controls}
*/
diff --git a/src/templates/qquickbuttongroup.cpp b/src/templates/qquickbuttongroup.cpp
index af975cad..c1822183 100644
--- a/src/templates/qquickbuttongroup.cpp
+++ b/src/templates/qquickbuttongroup.cpp
@@ -119,6 +119,8 @@ QT_BEGIN_NAMESPACE
More advanced use cases can be handled using the addButton() and
removeButton() methods.
+ \labs
+
\sa RadioButton
*/
diff --git a/src/templates/qquickcheckbox.cpp b/src/templates/qquickcheckbox.cpp
index 9a416419..644e151e 100644
--- a/src/templates/qquickcheckbox.cpp
+++ b/src/templates/qquickcheckbox.cpp
@@ -80,6 +80,8 @@ QT_BEGIN_NAMESPACE
}
\endcode
+ \labs
+
\sa {Customizing CheckBox}, {Button Controls}
*/
diff --git a/src/templates/qquickcombobox.cpp b/src/templates/qquickcombobox.cpp
index 9bf1c4e6..3283a46e 100644
--- a/src/templates/qquickcombobox.cpp
+++ b/src/templates/qquickcombobox.cpp
@@ -98,6 +98,8 @@ QT_BEGIN_NAMESPACE
\l textRole is not defined, ComboBox is unable to visualize it and throws a
\c {ReferenceError: modelData is not defined}.
+ \labs
+
\sa {Customizing ComboBox}, {Input Controls}
*/
@@ -330,6 +332,13 @@ QQuickComboBox::QQuickComboBox(QQuickItem *parent) :
setAcceptedMouseButtons(Qt::LeftButton);
}
+QQuickComboBox::~QQuickComboBox()
+{
+ Q_D(QQuickComboBox);
+ delete d->popup;
+ d->popup = nullptr;
+}
+
/*!
\readonly
\qmlproperty int Qt.labs.controls::ComboBox::count
diff --git a/src/templates/qquickcombobox_p.h b/src/templates/qquickcombobox_p.h
index 30bc7760..3381791e 100644
--- a/src/templates/qquickcombobox_p.h
+++ b/src/templates/qquickcombobox_p.h
@@ -73,6 +73,7 @@ class Q_LABSTEMPLATES_EXPORT QQuickComboBox : public QQuickControl
public:
explicit QQuickComboBox(QQuickItem *parent = nullptr);
+ ~QQuickComboBox();
int count() const;
diff --git a/src/templates/qquickcontainer.cpp b/src/templates/qquickcontainer.cpp
index c6638768..d5c387fb 100644
--- a/src/templates/qquickcontainer.cpp
+++ b/src/templates/qquickcontainer.cpp
@@ -51,6 +51,8 @@ QT_BEGIN_NAMESPACE
Container is the base type of container-like user interface controls.
+ \labs
+
\sa {Container Controls}
*/
diff --git a/src/templates/qquickcontrol.cpp b/src/templates/qquickcontrol.cpp
index 6914037d..42ab4c70 100644
--- a/src/templates/qquickcontrol.cpp
+++ b/src/templates/qquickcontrol.cpp
@@ -63,6 +63,8 @@ QT_BEGIN_NAMESPACE
\brief A user interface control.
Control is the base type of user interface controls.
+
+ \labs
*/
QQuickControlPrivate::QQuickControlPrivate() :
diff --git a/src/templates/qquickdial.cpp b/src/templates/qquickdial.cpp
index 3c354be4..2ad86f45 100644
--- a/src/templates/qquickdial.cpp
+++ b/src/templates/qquickdial.cpp
@@ -70,6 +70,8 @@ QT_BEGIN_NAMESPACE
\row \li Set \l value to \l to \li \c Qt.Key_End
\endtable
+ \labs
+
\sa {Customizing Dial}, {Input Controls}
*/
@@ -427,27 +429,39 @@ void QQuickDial::setHandle(QQuickItem *handle)
void QQuickDial::keyPressEvent(QKeyEvent *event)
{
Q_D(QQuickDial);
- if (event->key() == Qt::Key_Left || event->key() == Qt::Key_Down) {
+ switch (event->key()) {
+ case Qt::Key_Left:
+ case Qt::Key_Down:
setPressed(true);
if (isMirrored())
increase();
else
decrease();
- } else if (event->key() == Qt::Key_Right || event->key() == Qt::Key_Up) {
+ break;
+
+ case Qt::Key_Right:
+ case Qt::Key_Up:
setPressed(true);
if (isMirrored())
decrease();
else
increase();
- } else if (event->key() == Qt::Key_Home) {
+ break;
+
+ case Qt::Key_Home:
setPressed(true);
setValue(isMirrored() ? d->to : d->from);
- } else if (event->key() == Qt::Key_End) {
+ break;
+
+ case Qt::Key_End:
setPressed(true);
setValue(isMirrored() ? d->from : d->to);
- } else {
+ break;
+
+ default:
event->ignore();
QQuickControl::keyPressEvent(event);
+ break;
}
}
diff --git a/src/templates/qquickdrawer.cpp b/src/templates/qquickdrawer.cpp
index e0216872..2eb12676 100644
--- a/src/templates/qquickdrawer.cpp
+++ b/src/templates/qquickdrawer.cpp
@@ -80,6 +80,8 @@ QT_BEGIN_NAMESPACE
If you would like the application's contents to stay where they are when
the drawer is opened, don't apply a translation.
+ \labs
+
\sa SwipeView, {Customizing Drawer}, {Navigation Controls}, {Container Controls}
*/
diff --git a/src/templates/qquickframe.cpp b/src/templates/qquickframe.cpp
index 68be30a2..6ca9da0e 100644
--- a/src/templates/qquickframe.cpp
+++ b/src/templates/qquickframe.cpp
@@ -60,6 +60,8 @@ QT_BEGIN_NAMESPACE
\snippet qtlabscontrols-frame.qml 1
+ \labs
+
\sa {Customizing Frame}, {Container Controls}
*/
diff --git a/src/templates/qquickgroupbox.cpp b/src/templates/qquickgroupbox.cpp
index d324bb15..011245b1 100644
--- a/src/templates/qquickgroupbox.cpp
+++ b/src/templates/qquickgroupbox.cpp
@@ -75,6 +75,8 @@ QT_BEGIN_NAMESPACE
\snippet qtlabscontrols-groupbox-checkable.qml 1
+ \labs
+
\sa CheckBox, {Customizing GroupBox}, {Container Controls}
*/
diff --git a/src/templates/qquickitemdelegate.cpp b/src/templates/qquickitemdelegate.cpp
index 7e13b638..f25a117f 100644
--- a/src/templates/qquickitemdelegate.cpp
+++ b/src/templates/qquickitemdelegate.cpp
@@ -54,6 +54,8 @@ QT_BEGIN_NAMESPACE
\snippet qtlabscontrols-itemdelegate.qml 1
+ \labs
+
\sa {Customizing ItemDelegate}
*/
diff --git a/src/templates/qquicklabel.cpp b/src/templates/qquicklabel.cpp
index e749645c..8420deb1 100644
--- a/src/templates/qquicklabel.cpp
+++ b/src/templates/qquicklabel.cpp
@@ -65,6 +65,8 @@ QT_BEGIN_NAMESPACE
\snippet qtlabscontrols-label.qml 1
+ \labs
+
\sa {Customizing Label}
*/
diff --git a/src/templates/qquickmenu.cpp b/src/templates/qquickmenu.cpp
index 69a409eb..beda1489 100644
--- a/src/templates/qquickmenu.cpp
+++ b/src/templates/qquickmenu.cpp
@@ -85,6 +85,8 @@ QT_BEGIN_NAMESPACE
}
\endcode
+ \labs
+
\sa {Customizing Menu}, {Menu Controls}
*/
@@ -106,6 +108,8 @@ void QQuickMenuPrivate::insertItem(int index, QQuickItem *item)
{
contentData.append(item);
item->setParentItem(contentItem);
+ if (complete)
+ resizeItem(item);
QQuickItemPrivate::get(item)->addItemChangeListener(this, QQuickItemPrivate::Destroyed | QQuickItemPrivate::Parent);
contentModel->insert(index, item);
}
@@ -124,6 +128,27 @@ void QQuickMenuPrivate::removeItem(int index, QQuickItem *item)
contentModel->remove(index);
}
+void QQuickMenuPrivate::resizeItem(QQuickItem *item)
+{
+ if (!item || !contentItem)
+ return;
+
+ QQuickItemPrivate *p = QQuickItemPrivate::get(item);
+ if (!p->widthValid) {
+ item->setWidth(contentItem->width());
+ p->widthValid = false;
+ }
+}
+
+void QQuickMenuPrivate::resizeItems()
+{
+ if (!contentModel)
+ return;
+
+ for (int i = 0; i < contentModel->count(); ++i)
+ resizeItem(itemAt(i));
+}
+
void QQuickMenuPrivate::itemChildAdded(QQuickItem *, QQuickItem *child)
{
// add dynamically reparented items (eg. by a Repeater)
@@ -157,32 +182,10 @@ void QQuickMenuPrivate::itemDestroyed(QQuickItem *item)
removeItem(index, item);
}
-void QQuickMenuPrivate::onContentItemChanged()
+void QQuickMenuPrivate::itemGeometryChanged(QQuickItem *, const QRectF &, const QRectF &)
{
- Q_Q(QQuickMenu);
- if (contentItem) {
- contentItem->installEventFilter(q);
- contentItem->setFlag(QQuickItem::ItemIsFocusScope);
- contentItem->setActiveFocusOnTab(true);
-
- // Trying to give active focus to the contentItem (ListView, by default)
- // when the menu first opens, without also giving it to the first delegate item
- // doesn't seem to be possible, but this is what we need to do. QMenu behaves
- // similarly to this; it receives focus if a button that has it as a menu is clicked,
- // and only after pressing tab is the first menu item then given active focus.
- if (!dummyFocusItem) {
- dummyFocusItem = new QQuickItem(contentItem);
- dummyFocusItem->setObjectName(QStringLiteral("dummyMenuFocusItem"));
- } else {
- dummyFocusItem->setParentItem(contentItem);
- }
-
- dummyFocusItem->setActiveFocusOnTab(true);
- dummyFocusItem->stackBefore(contentItem->childItems().first());
-
- QObjectPrivate::connect(q, &QQuickMenu::visibleChanged, this, &QQuickMenuPrivate::onMenuVisibleChanged);
- QObjectPrivate::connect(dummyFocusItem, &QQuickItem::activeFocusChanged, this, &QQuickMenuPrivate::maybeUnsetDummyFocusOnTab);
- }
+ if (complete)
+ resizeItems();
}
void QQuickMenuPrivate::onItemPressed()
@@ -300,7 +303,7 @@ QQuickMenu::QQuickMenu(QObject *parent) :
Q_D(QQuickMenu);
connect(this, &QQuickMenu::pressedOutside, this, &QQuickMenu::close);
connect(this, &QQuickMenu::releasedOutside, this, &QQuickMenu::close);
- QObjectPrivate::connect(this, &QQuickMenu::contentItemChanged, d, &QQuickMenuPrivate::onContentItemChanged);
+ QObjectPrivate::connect(this, &QQuickMenu::visibleChanged, d, &QQuickMenuPrivate::onMenuVisibleChanged);
}
/*!
@@ -442,6 +445,47 @@ void QQuickMenu::setTitle(QString &title)
emit titleChanged();
}
+void QQuickMenu::componentComplete()
+{
+ Q_D(QQuickMenu);
+ QQuickPopup::componentComplete();
+ d->resizeItems();
+}
+
+void QQuickMenu::contentItemChange(QQuickItem *newItem, QQuickItem *oldItem)
+{
+ Q_D(QQuickMenu);
+ QQuickPopup::contentItemChange(newItem, oldItem);
+ if (oldItem) {
+ oldItem->removeEventFilter(this);
+ if (d->dummyFocusItem)
+ QObjectPrivate::disconnect(d->dummyFocusItem.data(), &QQuickItem::activeFocusChanged, d, &QQuickMenuPrivate::maybeUnsetDummyFocusOnTab);
+ }
+
+ if (newItem) {
+ newItem->installEventFilter(this);
+ newItem->setFlag(QQuickItem::ItemIsFocusScope);
+ newItem->setActiveFocusOnTab(true);
+
+ // Trying to give active focus to the contentItem (ListView, by default)
+ // when the menu first opens, without also giving it to the first delegate item
+ // doesn't seem to be possible, but this is what we need to do. QMenu behaves
+ // similarly to this; it receives focus if a button that has it as a menu is clicked,
+ // and only after pressing tab is the first menu item then given active focus.
+ if (!d->dummyFocusItem) {
+ d->dummyFocusItem = new QQuickItem(newItem);
+ d->dummyFocusItem->setObjectName(QStringLiteral("dummyMenuFocusItem"));
+ } else {
+ d->dummyFocusItem->setParentItem(newItem);
+ }
+
+ d->dummyFocusItem->setActiveFocusOnTab(true);
+ d->dummyFocusItem->stackBefore(newItem->childItems().first());
+
+ QObjectPrivate::connect(d->dummyFocusItem.data(), &QQuickItem::activeFocusChanged, d, &QQuickMenuPrivate::maybeUnsetDummyFocusOnTab);
+ }
+}
+
bool QQuickMenu::eventFilter(QObject *object, QEvent *event)
{
Q_D(QQuickMenu);
@@ -458,17 +502,23 @@ bool QQuickMenu::eventFilter(QObject *object, QEvent *event)
// only allow flicking with the mouse when there are too many menu items to be
// shown at once.
QKeyEvent *keyEvent = static_cast<QKeyEvent*>(event);
- if (keyEvent->key() == Qt::Key_Up) {
+ switch (keyEvent->key()) {
+ case Qt::Key_Up:
if (d->contentItem->metaObject()->indexOfMethod("decrementCurrentIndex()") != -1)
QMetaObject::invokeMethod(d->contentItem, "decrementCurrentIndex");
return true;
- } else if (keyEvent->key() == Qt::Key_Down) {
+
+ case Qt::Key_Down:
if (d->contentItem->metaObject()->indexOfMethod("incrementCurrentIndex()") != -1)
QMetaObject::invokeMethod(d->contentItem, "incrementCurrentIndex");
return true;
- } else if (keyEvent->key() == Qt::Key_Escape) {
+
+ case Qt::Key_Escape:
close();
return true;
+
+ default:
+ break;
}
return false;
diff --git a/src/templates/qquickmenu_p.h b/src/templates/qquickmenu_p.h
index a54cafbd..ec417d16 100644
--- a/src/templates/qquickmenu_p.h
+++ b/src/templates/qquickmenu_p.h
@@ -82,6 +82,8 @@ public:
void setTitle(QString &title);
protected:
+ void componentComplete() override;
+ void contentItemChange(QQuickItem *newItem, QQuickItem *oldItem) override;
bool eventFilter(QObject *object, QEvent *event) override;
Q_SIGNALS:
diff --git a/src/templates/qquickmenu_p_p.h b/src/templates/qquickmenu_p_p.h
index e06c0299..505f3cb9 100644
--- a/src/templates/qquickmenu_p_p.h
+++ b/src/templates/qquickmenu_p_p.h
@@ -49,6 +49,7 @@
//
#include <QtCore/qvector.h>
+#include <QtCore/qpointer.h>
#include <QtQuick/private/qquickitemchangelistener_p.h>
#include <QtLabsTemplates/private/qquickpopup_p_p.h>
@@ -69,12 +70,15 @@ public:
void moveItem(int from, int to);
void removeItem(int index, QQuickItem *item);
+ void resizeItem(QQuickItem *item);
+ void resizeItems();
+
void itemChildAdded(QQuickItem *item, QQuickItem *child) override;
void itemSiblingOrderChanged(QQuickItem *item) override;
void itemParentChanged(QQuickItem *item, QQuickItem *parent) override;
void itemDestroyed(QQuickItem *item) override;
+ void itemGeometryChanged(QQuickItem *, const QRectF &newGeometry, const QRectF &oldGeometry) override;
- void onContentItemChanged();
void onItemPressed();
void onItemActiveFocusChanged();
void onMenuVisibleChanged();
@@ -87,7 +91,7 @@ public:
QVector<QObject *> contentData;
QQmlObjectModel *contentModel;
- QQuickItem *dummyFocusItem;
+ QPointer<QQuickItem> dummyFocusItem;
bool ignoreActiveFocusChanges;
QString title;
};
diff --git a/src/templates/qquickmenuitem.cpp b/src/templates/qquickmenuitem.cpp
index f6cfda4c..d784af02 100644
--- a/src/templates/qquickmenuitem.cpp
+++ b/src/templates/qquickmenuitem.cpp
@@ -75,6 +75,8 @@ QT_BEGIN_NAMESPACE
}
\endcode
+ \labs
+
\sa {Customizing MenuItem}, {Menu Controls}
*/
diff --git a/src/templates/qquickoverlay.cpp b/src/templates/qquickoverlay.cpp
index 5455676f..8b19e8e9 100644
--- a/src/templates/qquickoverlay.cpp
+++ b/src/templates/qquickoverlay.cpp
@@ -240,6 +240,12 @@ void QQuickOverlay::mouseReleaseEvent(QMouseEvent *event)
emit released();
}
+void QQuickOverlay::wheelEvent(QWheelEvent *event)
+{
+ Q_D(QQuickOverlay);
+ event->setAccepted(d->modalPopups > 0);
+}
+
bool QQuickOverlay::childMouseEventFilter(QQuickItem *item, QEvent *event)
{
Q_D(QQuickOverlay);
@@ -255,11 +261,11 @@ bool QQuickOverlay::childMouseEventFilter(QQuickItem *item, QEvent *event)
const QQuickItemPrivate *priv = QQuickItemPrivate::get(this);
const QList<QQuickItem *> &sortedChildren = priv->paintOrderChildItems();
for (int i = sortedChildren.count() - 1; i >= 0; --i) {
- QQuickItem *contentItem = sortedChildren[i];
- if (contentItem == item)
+ QQuickItem *popupItem = sortedChildren[i];
+ if (popupItem == item)
break;
- QQuickPopup *popup = d->popups.value(contentItem);
+ QQuickPopup *popup = d->popups.value(popupItem);
if (popup) {
emit popup->pressedOutside();
diff --git a/src/templates/qquickoverlay_p.h b/src/templates/qquickoverlay_p.h
index b532720f..f5ce54f6 100644
--- a/src/templates/qquickoverlay_p.h
+++ b/src/templates/qquickoverlay_p.h
@@ -80,6 +80,7 @@ protected:
void mousePressEvent(QMouseEvent *event) override;
void mouseMoveEvent(QMouseEvent *event) override;
void mouseReleaseEvent(QMouseEvent *event) override;
+ void wheelEvent(QWheelEvent *event) override;
bool childMouseEventFilter(QQuickItem *item, QEvent *event) override;
private:
diff --git a/src/templates/qquickpageindicator.cpp b/src/templates/qquickpageindicator.cpp
index 400a5237..1333c245 100644
--- a/src/templates/qquickpageindicator.cpp
+++ b/src/templates/qquickpageindicator.cpp
@@ -59,6 +59,8 @@ QT_BEGIN_NAMESPACE
\snippet qtlabscontrols-pageindicator.qml 1
+ \labs
+
\sa SwipeView, {Customizing PageIndicator}, {Indicator Controls}
*/
diff --git a/src/templates/qquickpane.cpp b/src/templates/qquickpane.cpp
index bbec8e42..c660220c 100644
--- a/src/templates/qquickpane.cpp
+++ b/src/templates/qquickpane.cpp
@@ -60,6 +60,8 @@ QT_BEGIN_NAMESPACE
\snippet qtlabscontrols-pane.qml 1
+ \labs
+
\sa {Customizing Pane}, {Container Controls}
*/
diff --git a/src/templates/qquickpopup.cpp b/src/templates/qquickpopup.cpp
index 87c63f8d..93e5a63a 100644
--- a/src/templates/qquickpopup.cpp
+++ b/src/templates/qquickpopup.cpp
@@ -55,34 +55,400 @@ QT_BEGIN_NAMESPACE
\brief A popup control.
Popup is the base type of popup-like user interface controls.
+
+ \labs
*/
+static const QQuickItemPrivate::ChangeTypes AncestorChangeTypes = QQuickItemPrivate::Geometry
+ | QQuickItemPrivate::Parent
+ | QQuickItemPrivate::Children;
+
+static const QQuickItemPrivate::ChangeTypes ItemChangeTypes = QQuickItemPrivate::Geometry
+ | QQuickItemPrivate::Parent
+ | QQuickItemPrivate::Destroyed;
+
QQuickPopupPrivate::QQuickPopupPrivate()
: QObjectPrivate()
, focus(false)
, modal(false)
+ , hasTopPadding(false)
+ , hasLeftPadding(false)
+ , hasRightPadding(false)
+ , hasBottomPadding(false)
+ , padding(0)
+ , topPadding(0)
+ , leftPadding(0)
+ , rightPadding(0)
+ , bottomPadding(0)
+ , contentWidth(0)
+ , contentHeight(0)
+ , parentItem(nullptr)
+ , background(nullptr)
, contentItem(nullptr)
, overlay(nullptr)
, enter(nullptr)
, exit(nullptr)
+ , popupItem(nullptr)
+ , positioner(this)
, transitionManager(this)
{
}
+void QQuickPopupPrivate::init()
+{
+ Q_Q(QQuickPopup);
+ popupItem = new QQuickPopupItem(q);
+ popupItem->setParent(q);
+ q->setParentItem(qobject_cast<QQuickItem *>(parent));
+}
+
void QQuickPopupPrivate::finalizeEnterTransition()
{
if (focus)
- contentItem->setFocus(true);
+ popupItem->setFocus(true);
}
void QQuickPopupPrivate::finalizeExitTransition()
{
Q_Q(QQuickPopup);
overlay = nullptr;
- contentItem->setParentItem(nullptr);
+ positioner.setParentItem(nullptr);
+ popupItem->setParentItem(nullptr);
emit q->visibleChanged();
}
+void QQuickPopupPrivate::resizeBackground()
+{
+ Q_Q(QQuickPopup);
+ if (background) {
+ QQuickItemPrivate *p = QQuickItemPrivate::get(background);
+ if (!p->widthValid && qFuzzyIsNull(background->x())) {
+ background->setWidth(q->width());
+ p->widthValid = false;
+ }
+ if (!p->heightValid && qFuzzyIsNull(background->y())) {
+ background->setHeight(q->height());
+ p->heightValid = false;
+ }
+ }
+}
+
+void QQuickPopupPrivate::resizeContent()
+{
+ Q_Q(QQuickPopup);
+ if (contentItem) {
+ contentItem->setPosition(QPointF(q->leftPadding(), q->topPadding()));
+ contentItem->setSize(QSizeF(q->availableWidth(), q->availableHeight()));
+ }
+}
+
+void QQuickPopupPrivate::setTopPadding(qreal value, bool reset)
+{
+ Q_Q(QQuickPopup);
+ qreal oldPadding = q->topPadding();
+ topPadding = value;
+ hasTopPadding = !reset;
+ if ((!reset && !qFuzzyCompare(oldPadding, value)) || (reset && !qFuzzyCompare(oldPadding, padding))) {
+ emit q->topPaddingChanged();
+ emit q->availableHeightChanged();
+ q->paddingChange(QMarginsF(leftPadding, topPadding, rightPadding, bottomPadding),
+ QMarginsF(leftPadding, oldPadding, rightPadding, bottomPadding));
+ }
+}
+
+void QQuickPopupPrivate::setLeftPadding(qreal value, bool reset)
+{
+ Q_Q(QQuickPopup);
+ qreal oldPadding = q->leftPadding();
+ leftPadding = value;
+ hasLeftPadding = !reset;
+ if ((!reset && !qFuzzyCompare(oldPadding, value)) || (reset && !qFuzzyCompare(oldPadding, padding))) {
+ emit q->leftPaddingChanged();
+ emit q->availableWidthChanged();
+ q->paddingChange(QMarginsF(leftPadding, topPadding, rightPadding, bottomPadding),
+ QMarginsF(oldPadding, topPadding, rightPadding, bottomPadding));
+ }
+}
+
+void QQuickPopupPrivate::setRightPadding(qreal value, bool reset)
+{
+ Q_Q(QQuickPopup);
+ qreal oldPadding = q->rightPadding();
+ rightPadding = value;
+ hasRightPadding = !reset;
+ if ((!reset && !qFuzzyCompare(oldPadding, value)) || (reset && !qFuzzyCompare(oldPadding, padding))) {
+ emit q->rightPaddingChanged();
+ emit q->availableWidthChanged();
+ q->paddingChange(QMarginsF(leftPadding, topPadding, rightPadding, bottomPadding),
+ QMarginsF(leftPadding, topPadding, oldPadding, bottomPadding));
+ }
+}
+
+void QQuickPopupPrivate::setBottomPadding(qreal value, bool reset)
+{
+ Q_Q(QQuickPopup);
+ qreal oldPadding = q->bottomPadding();
+ bottomPadding = value;
+ hasBottomPadding = !reset;
+ if ((!reset && !qFuzzyCompare(oldPadding, value)) || (reset && !qFuzzyCompare(oldPadding, padding))) {
+ emit q->bottomPaddingChanged();
+ emit q->availableHeightChanged();
+ q->paddingChange(QMarginsF(leftPadding, topPadding, rightPadding, bottomPadding),
+ QMarginsF(leftPadding, topPadding, rightPadding, oldPadding));
+ }
+}
+
+class QQuickPopupItemPrivate : public QQuickItemPrivate
+{
+ Q_DECLARE_PUBLIC(QQuickPopupItem)
+
+public:
+ QQuickPopupItemPrivate(QQuickPopup *popup);
+
+ void implicitWidthChanged() override;
+ void implicitHeightChanged() override;
+
+ QQuickPopup *popup;
+};
+
+QQuickPopupItemPrivate::QQuickPopupItemPrivate(QQuickPopup *popup) : popup(popup)
+{
+}
+
+void QQuickPopupItemPrivate::implicitWidthChanged()
+{
+ emit popup->implicitHeightChanged();
+}
+
+void QQuickPopupItemPrivate::implicitHeightChanged()
+{
+ emit popup->implicitHeightChanged();
+}
+
+QQuickPopupItem::QQuickPopupItem(QQuickPopup *popup) :
+ QQuickItem(*(new QQuickPopupItemPrivate(popup)))
+{
+ setAcceptedMouseButtons(Qt::AllButtons);
+}
+
+void QQuickPopupItem::focusInEvent(QFocusEvent *event)
+{
+ Q_D(QQuickPopupItem);
+ d->popup->focusInEvent(event);
+}
+
+void QQuickPopupItem::focusOutEvent(QFocusEvent *event)
+{
+ Q_D(QQuickPopupItem);
+ d->popup->focusOutEvent(event);
+}
+
+void QQuickPopupItem::keyPressEvent(QKeyEvent *event)
+{
+ Q_D(QQuickPopupItem);
+ d->popup->keyPressEvent(event);
+}
+
+void QQuickPopupItem::keyReleaseEvent(QKeyEvent *event)
+{
+ Q_D(QQuickPopupItem);
+ d->popup->keyReleaseEvent(event);
+}
+
+void QQuickPopupItem::mousePressEvent(QMouseEvent *event)
+{
+ Q_D(QQuickPopupItem);
+ d->popup->mousePressEvent(event);
+}
+
+void QQuickPopupItem::mouseMoveEvent(QMouseEvent *event)
+{
+ Q_D(QQuickPopupItem);
+ d->popup->mouseMoveEvent(event);
+}
+
+void QQuickPopupItem::mouseReleaseEvent(QMouseEvent *event)
+{
+ Q_D(QQuickPopupItem);
+ d->popup->mouseReleaseEvent(event);
+}
+
+void QQuickPopupItem::mouseDoubleClickEvent(QMouseEvent *event)
+{
+ Q_D(QQuickPopupItem);
+ d->popup->mouseDoubleClickEvent(event);
+}
+
+void QQuickPopupItem::mouseUngrabEvent()
+{
+ Q_D(QQuickPopupItem);
+ d->popup->mouseUngrabEvent();
+}
+
+void QQuickPopupItem::wheelEvent(QWheelEvent *event)
+{
+ Q_D(QQuickPopupItem);
+ d->popup->wheelEvent(event);
+}
+
+void QQuickPopupItem::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
+{
+ Q_D(QQuickPopupItem);
+ d->popup->geometryChanged(newGeometry, oldGeometry);
+}
+
+QQuickPopupPositioner::QQuickPopupPositioner(QQuickPopupPrivate *popup) :
+ m_x(0),
+ m_y(0),
+ m_parentItem(nullptr),
+ m_popup(popup)
+{
+}
+
+QQuickPopupPositioner::~QQuickPopupPositioner()
+{
+ if (m_parentItem) {
+ QQuickItemPrivate::get(m_parentItem)->removeItemChangeListener(this, ItemChangeTypes);
+ removeAncestorListeners(m_parentItem->parentItem());
+ }
+}
+
+qreal QQuickPopupPositioner::x() const
+{
+ return m_x;
+}
+
+void QQuickPopupPositioner::setX(qreal x)
+{
+ if (m_x != x) {
+ m_x = x;
+ repositionPopup();
+ }
+}
+
+qreal QQuickPopupPositioner::y() const
+{
+ return m_y;
+}
+
+void QQuickPopupPositioner::setY(qreal y)
+{
+ if (m_y != y) {
+ m_y = y;
+ repositionPopup();
+ }
+}
+
+QQuickItem *QQuickPopupPositioner::parentItem() const
+{
+ return m_parentItem;
+}
+
+void QQuickPopupPositioner::setParentItem(QQuickItem *parent)
+{
+ if (m_parentItem == parent)
+ return;
+
+ if (m_parentItem) {
+ QQuickItemPrivate::get(m_parentItem)->removeItemChangeListener(this, ItemChangeTypes);
+ removeAncestorListeners(m_parentItem->parentItem());
+ }
+
+ m_parentItem = parent;
+
+ if (!parent)
+ return;
+
+ QQuickItemPrivate::get(parent)->addItemChangeListener(this, ItemChangeTypes);
+ addAncestorListeners(parent->parentItem());
+
+ repositionPopup();
+}
+
+void QQuickPopupPositioner::itemGeometryChanged(QQuickItem *, const QRectF &, const QRectF &)
+{
+ repositionPopup();
+}
+
+void QQuickPopupPositioner::itemParentChanged(QQuickItem *, QQuickItem *parent)
+{
+ addAncestorListeners(parent);
+}
+
+void QQuickPopupPositioner::itemChildRemoved(QQuickItem *, QQuickItem *child)
+{
+ if (isAncestor(child))
+ removeAncestorListeners(child);
+}
+
+void QQuickPopupPositioner::itemDestroyed(QQuickItem *item)
+{
+ Q_ASSERT(m_parentItem == item);
+
+ m_parentItem = nullptr;
+ QQuickItemPrivate::get(item)->removeItemChangeListener(this, ItemChangeTypes);
+ removeAncestorListeners(item->parentItem());
+}
+
+void QQuickPopupPositioner::repositionPopup()
+{
+ QRectF rect(m_x, m_y, m_popup->popupItem->width(), m_popup->popupItem->height());
+ if (m_parentItem) {
+ rect = m_parentItem->mapRectToScene(rect);
+
+ QQuickWindow *window = m_parentItem->window();
+ if (window) {
+ if (rect.top() < 0 || rect.bottom() > window->height()) {
+ // if the popup doesn't fit on the screen, try flipping it around (below <-> above)
+ QRectF flipped = m_parentItem->mapRectToScene(QRectF(m_x, m_parentItem->height() - m_y - rect.height(), rect.width(), rect.height()));
+ if (flipped.y() >= 0 && flipped.bottom() < window->height())
+ rect = flipped;
+ }
+ }
+ }
+
+ m_popup->popupItem->setPosition(rect.topLeft());
+}
+
+void QQuickPopupPositioner::removeAncestorListeners(QQuickItem *item)
+{
+ if (item == m_parentItem)
+ return;
+
+ QQuickItem *p = item;
+ while (p) {
+ QQuickItemPrivate::get(p)->removeItemChangeListener(this, AncestorChangeTypes);
+ p = p->parentItem();
+ }
+}
+
+void QQuickPopupPositioner::addAncestorListeners(QQuickItem *item)
+{
+ if (item == m_parentItem)
+ return;
+
+ QQuickItem *p = item;
+ while (p) {
+ QQuickItemPrivate::get(p)->addItemChangeListener(this, AncestorChangeTypes);
+ p = p->parentItem();
+ }
+}
+
+// TODO: use QQuickItem::isAncestorOf() in dev/5.7
+bool QQuickPopupPositioner::isAncestor(QQuickItem *item) const
+{
+ if (!m_parentItem)
+ return false;
+
+ QQuickItem *parent = m_parentItem->parentItem();
+ while (parent) {
+ if (parent == item)
+ return true;
+ parent = parent->parentItem();
+ }
+ return false;
+}
+
QQuickPopupTransitionManager::QQuickPopupTransitionManager(QQuickPopupPrivate *popup)
: QQuickTransitionManager()
, state(Off)
@@ -96,7 +462,7 @@ void QQuickPopupTransitionManager::transitionEnter()
return;
QList<QQuickStateAction> actions;
state = Enter;
- transition(actions, popup->enter, popup->contentItem);
+ transition(actions, popup->enter, popup->popupItem);
}
void QQuickPopupTransitionManager::transitionExit()
@@ -105,7 +471,7 @@ void QQuickPopupTransitionManager::transitionExit()
return;
QList<QQuickStateAction> actions;
state = Exit;
- transition(actions, popup->exit, popup->contentItem);
+ transition(actions, popup->exit, popup->popupItem);
}
void QQuickPopupTransitionManager::finished()
@@ -121,11 +487,21 @@ void QQuickPopupTransitionManager::finished()
QQuickPopup::QQuickPopup(QObject *parent)
: QObject(*(new QQuickPopupPrivate), parent)
{
+ Q_D(QQuickPopup);
+ d->init();
}
QQuickPopup::QQuickPopup(QQuickPopupPrivate &dd, QObject *parent)
: QObject(dd, parent)
{
+ Q_D(QQuickPopup);
+ d->init();
+}
+
+QQuickPopup::~QQuickPopup()
+{
+ Q_D(QQuickPopup);
+ d->positioner.setParentItem(nullptr);
}
/*!
@@ -136,13 +512,8 @@ QQuickPopup::QQuickPopup(QQuickPopupPrivate &dd, QObject *parent)
void QQuickPopup::open()
{
Q_D(QQuickPopup);
- if (!d->contentItem) {
- qmlInfo(this) << "no popup content to show.";
- return;
- }
if (d->overlay) {
- // FIXME qmlInfo needs to know about QQuickWindow and/or QObject
- static_cast<QDebug>(qmlInfo(this) << "popup already open in window") << d->overlay->window();
+ // popup already open
return;
}
@@ -172,7 +543,11 @@ void QQuickPopup::open()
}
d->overlay = static_cast<QQuickOverlay *>(applicationWindow->overlay());
- d->contentItem->setParentItem(d->overlay);
+ d->popupItem->setParentItem(d->overlay);
+ d->positioner.setParentItem(d->parentItem);
+ // TODO: add Popup::transformOrigin?
+ if (d->contentItem)
+ d->popupItem->setTransformOrigin(d->contentItem->transformOrigin());
emit aboutToShow();
d->transitionManager.transitionEnter();
emit visibleChanged();
@@ -187,17 +562,406 @@ void QQuickPopup::close()
{
Q_D(QQuickPopup);
if (!d->overlay) {
- // TODO This could mean we opened the popup item in a plain QQuickWindow
- qmlInfo(this) << "trying to close non-visible Popup.";
+ // popup already closed
return;
}
- d->contentItem->setFocus(false);
+ d->popupItem->setFocus(false);
emit aboutToHide();
d->transitionManager.transitionExit();
}
/*!
+ \qmlproperty real Qt.labs.controls::Popup::x
+
+ This property holds the x-coordinate of the popup.
+*/
+qreal QQuickPopup::x() const
+{
+ Q_D(const QQuickPopup);
+ return d->positioner.x();
+}
+
+void QQuickPopup::setX(qreal x)
+{
+ Q_D(QQuickPopup);
+ d->positioner.setX(x);
+}
+
+/*!
+ \qmlproperty real Qt.labs.controls::Popup::y
+
+ This property holds the y-coordinate of the popup.
+*/
+qreal QQuickPopup::y() const
+{
+ Q_D(const QQuickPopup);
+ return d->positioner.y();
+}
+
+void QQuickPopup::setY(qreal y)
+{
+ Q_D(QQuickPopup);
+ d->positioner.setY(y);
+}
+
+/*!
+ \qmlproperty real Qt.labs.controls::Popup::width
+
+ This property holds the width of the popup.
+*/
+qreal QQuickPopup::width() const
+{
+ Q_D(const QQuickPopup);
+ return d->popupItem->width();
+}
+
+void QQuickPopup::setWidth(qreal width)
+{
+ Q_D(QQuickPopup);
+ d->popupItem->setWidth(width);
+}
+
+void QQuickPopup::resetWidth()
+{
+ Q_D(QQuickPopup);
+ d->popupItem->resetWidth();
+}
+
+/*!
+ \qmlproperty real Qt.labs.controls::Popup::height
+
+ This property holds the height of the popup.
+*/
+qreal QQuickPopup::height() const
+{
+ Q_D(const QQuickPopup);
+ return d->popupItem->height();
+}
+
+void QQuickPopup::setHeight(qreal height)
+{
+ Q_D(QQuickPopup);
+ d->popupItem->setHeight(height);
+}
+
+void QQuickPopup::resetHeight()
+{
+ Q_D(QQuickPopup);
+ d->popupItem->resetHeight();
+}
+
+/*!
+ \qmlproperty real Qt.labs.controls::Popup::implicitWidth
+
+ This property holds the implicit width of the popup.
+*/
+qreal QQuickPopup::implicitWidth() const
+{
+ Q_D(const QQuickPopup);
+ return d->popupItem->implicitWidth();
+}
+
+void QQuickPopup::setImplicitWidth(qreal width)
+{
+ Q_D(QQuickPopup);
+ d->popupItem->setImplicitWidth(width);
+}
+
+/*!
+ \qmlproperty real Qt.labs.controls::Popup::implicitHeight
+
+ This property holds the implicit height of the popup.
+*/
+qreal QQuickPopup::implicitHeight() const
+{
+ Q_D(const QQuickPopup);
+ return d->popupItem->implicitHeight();
+}
+
+void QQuickPopup::setImplicitHeight(qreal height)
+{
+ Q_D(QQuickPopup);
+ d->popupItem->setImplicitHeight(height);
+}
+
+/*!
+ \qmlproperty real Qt.labs.controls::Popup::contentWidth
+
+ This property holds the content width. It is used for calculating the
+ total implicit width of the Popup.
+
+ \note If only a single item is used within the Popup, the implicit width
+ of its contained item is used as the content width.
+*/
+qreal QQuickPopup::contentWidth() const
+{
+ Q_D(const QQuickPopup);
+ return d->contentWidth;
+}
+
+void QQuickPopup::setContentWidth(qreal width)
+{
+ Q_D(QQuickPopup);
+ if (d->contentWidth != width) {
+ d->contentWidth = width;
+ emit contentWidthChanged();
+ }
+}
+
+/*!
+ \qmlproperty real Qt.labs.controls::Popup::contentHeight
+
+ This property holds the content height. It is used for calculating the
+ total implicit height of the Popup.
+
+ \note If only a single item is used within the Popup, the implicit height
+ of its contained item is used as the content height.
+*/
+qreal QQuickPopup::contentHeight() const
+{
+ Q_D(const QQuickPopup);
+ return d->contentHeight;
+}
+
+void QQuickPopup::setContentHeight(qreal height)
+{
+ Q_D(QQuickPopup);
+ if (d->contentHeight != height) {
+ d->contentHeight = height;
+ emit contentHeightChanged();
+ }
+}
+
+/*!
+ \qmlproperty real Qt.labs.controls::Popup::availableWidth
+
+ This property holds the width available after deducting horizontal padding.
+
+ \sa padding, leftPadding, rightPadding
+*/
+qreal QQuickPopup::availableWidth() const
+{
+ return qMax<qreal>(0.0, width() - leftPadding() - rightPadding());
+}
+
+/*!
+ \qmlproperty real Qt.labs.controls::Popup::availableHeight
+
+ This property holds the height available after deducting vertical padding.
+
+ \sa padding, topPadding, bottomPadding
+*/
+qreal QQuickPopup::availableHeight() const
+{
+ return qMax<qreal>(0.0, height() - topPadding() - bottomPadding());
+}
+
+/*!
+ \qmlproperty real Qt.labs.controls::Popup::padding
+
+ This property holds the default padding.
+
+ \sa availableWidth, availableHeight, topPadding, leftPadding, rightPadding, bottomPadding
+*/
+qreal QQuickPopup::padding() const
+{
+ Q_D(const QQuickPopup);
+ return d->padding;
+}
+
+void QQuickPopup::setPadding(qreal padding)
+{
+ Q_D(QQuickPopup);
+ if (qFuzzyCompare(d->padding, padding))
+ return;
+ QMarginsF oldPadding(leftPadding(), topPadding(), rightPadding(), bottomPadding());
+ d->padding = padding;
+ emit paddingChanged();
+ QMarginsF newPadding(leftPadding(), topPadding(), rightPadding(), bottomPadding());
+ if (!qFuzzyCompare(newPadding.top(), oldPadding.top()))
+ emit topPaddingChanged();
+ if (!qFuzzyCompare(newPadding.left(), oldPadding.left()))
+ emit leftPaddingChanged();
+ if (!qFuzzyCompare(newPadding.right(), oldPadding.right()))
+ emit rightPaddingChanged();
+ if (!qFuzzyCompare(newPadding.bottom(), oldPadding.bottom()))
+ emit bottomPaddingChanged();
+ if (!qFuzzyCompare(newPadding.top(), oldPadding.top()) || !qFuzzyCompare(newPadding.bottom(), oldPadding.bottom()))
+ emit availableHeightChanged();
+ if (!qFuzzyCompare(newPadding.left(), oldPadding.left()) || !qFuzzyCompare(newPadding.right(), oldPadding.right()))
+ emit availableWidthChanged();
+ paddingChange(newPadding, oldPadding);
+}
+
+void QQuickPopup::resetPadding()
+{
+ setPadding(0);
+}
+
+/*!
+ \qmlproperty real Qt.labs.controls::Popup::topPadding
+
+ This property holds the top padding.
+
+ \sa padding, bottomPadding, availableHeight
+*/
+qreal QQuickPopup::topPadding() const
+{
+ Q_D(const QQuickPopup);
+ if (d->hasTopPadding)
+ return d->topPadding;
+ return d->padding;
+}
+
+void QQuickPopup::setTopPadding(qreal padding)
+{
+ Q_D(QQuickPopup);
+ d->setTopPadding(padding);
+}
+
+void QQuickPopup::resetTopPadding()
+{
+ Q_D(QQuickPopup);
+ d->setTopPadding(0, true);
+}
+
+/*!
+ \qmlproperty real Qt.labs.controls::Popup::leftPadding
+
+ This property holds the left padding.
+
+ \sa padding, rightPadding, availableWidth
+*/
+qreal QQuickPopup::leftPadding() const
+{
+ Q_D(const QQuickPopup);
+ if (d->hasLeftPadding)
+ return d->leftPadding;
+ return d->padding;
+}
+
+void QQuickPopup::setLeftPadding(qreal padding)
+{
+ Q_D(QQuickPopup);
+ d->setLeftPadding(padding);
+}
+
+void QQuickPopup::resetLeftPadding()
+{
+ Q_D(QQuickPopup);
+ d->setLeftPadding(0, true);
+}
+
+/*!
+ \qmlproperty real Qt.labs.controls::Popup::rightPadding
+
+ This property holds the right padding.
+
+ \sa padding, leftPadding, availableWidth
+*/
+qreal QQuickPopup::rightPadding() const
+{
+ Q_D(const QQuickPopup);
+ if (d->hasRightPadding)
+ return d->rightPadding;
+ return d->padding;
+}
+
+void QQuickPopup::setRightPadding(qreal padding)
+{
+ Q_D(QQuickPopup);
+ d->setRightPadding(padding);
+}
+
+void QQuickPopup::resetRightPadding()
+{
+ Q_D(QQuickPopup);
+ d->setRightPadding(0, true);
+}
+
+/*!
+ \qmlproperty real Qt.labs.controls::Popup::bottomPadding
+
+ This property holds the bottom padding.
+
+ \sa padding, topPadding, availableHeight
+*/
+qreal QQuickPopup::bottomPadding() const
+{
+ Q_D(const QQuickPopup);
+ if (d->hasBottomPadding)
+ return d->bottomPadding;
+ return d->padding;
+}
+
+void QQuickPopup::setBottomPadding(qreal padding)
+{
+ Q_D(QQuickPopup);
+ d->setBottomPadding(padding);
+}
+
+void QQuickPopup::resetBottomPadding()
+{
+ Q_D(QQuickPopup);
+ d->setBottomPadding(0, true);
+}
+
+/*!
+ \qmlproperty Item Qt.labs.popups::Popup::parent
+
+ This property holds the parent item.
+*/
+QQuickItem *QQuickPopup::parentItem() const
+{
+ Q_D(const QQuickPopup);
+ return d->parentItem;
+}
+
+void QQuickPopup::setParentItem(QQuickItem *parent)
+{
+ Q_D(QQuickPopup);
+ if (d->parentItem != parent) {
+ d->parentItem = parent;
+ if (d->positioner.parentItem())
+ d->positioner.setParentItem(parent);
+ emit parentChanged();
+ }
+}
+
+/*!
+ \qmlproperty Item Qt.labs.popups::Popup::background
+
+ This property holds the background item.
+
+ \note If the background item has no explicit size specified, it automatically
+ follows the popup's size. In most cases, there is no need to specify
+ width or height for a background item.
+*/
+QQuickItem *QQuickPopup::background() const
+{
+ Q_D(const QQuickPopup);
+ return d->background;
+}
+
+void QQuickPopup::setBackground(QQuickItem *background)
+{
+ Q_D(QQuickPopup);
+ if (d->background != background) {
+ delete d->background;
+ d->background = background;
+ if (background) {
+ background->setParentItem(d->popupItem);
+ if (qFuzzyIsNull(background->z()))
+ background->setZ(-1);
+ if (isComponentComplete())
+ d->resizeBackground();
+ }
+ emit backgroundChanged();
+ }
+}
+
+/*!
\qmlproperty Item Qt.labs.controls::Popup::contentItem
This property holds the content item of the popup.
@@ -222,15 +986,55 @@ void QQuickPopup::setContentItem(QQuickItem *item)
return;
}
if (d->contentItem != item) {
+ contentItemChange(item, d->contentItem);
delete d->contentItem;
d->contentItem = item;
- if (item)
+ if (item) {
+ item->setParentItem(d->popupItem);
QQuickItemPrivate::get(item)->isTabFence = true;
+ if (isComponentComplete())
+ d->resizeContent();
+ }
emit contentItemChanged();
}
}
/*!
+ \qmlproperty list<Object> Qt.labs.controls::Popup::contentData
+ \default
+
+ This property holds the list of content data.
+
+ \sa Item::data
+*/
+QQmlListProperty<QObject> QQuickPopup::contentData()
+{
+ Q_D(QQuickPopup);
+ return QQmlListProperty<QObject>(d->contentItem, nullptr,
+ QQuickItemPrivate::data_append,
+ QQuickItemPrivate::data_count,
+ QQuickItemPrivate::data_at,
+ QQuickItemPrivate::data_clear);
+}
+
+/*!
+ \qmlproperty list<Item> Qt.labs.controls::Popup::contentChildren
+
+ This property holds the list of content children.
+
+ \sa Item::children
+*/
+QQmlListProperty<QQuickItem> QQuickPopup::contentChildren()
+{
+ Q_D(QQuickPopup);
+ return QQmlListProperty<QQuickItem>(d->contentItem, nullptr,
+ QQuickItemPrivate::children_append,
+ QQuickItemPrivate::children_count,
+ QQuickItemPrivate::children_at,
+ QQuickItemPrivate::children_clear);
+}
+
+/*!
\qmlproperty bool Qt.labs.controls::Popup::focus
This property holds whether the popup has focus.
@@ -281,6 +1085,14 @@ bool QQuickPopup::isVisible() const
return d->overlay != nullptr /*&& !d->transitionManager.isRunning()*/;
}
+void QQuickPopup::setVisible(bool visible)
+{
+ if (visible)
+ open();
+ else
+ close();
+}
+
/*!
\qmlproperty Transition Qt.labs.controls::Popup::enter
@@ -323,6 +1135,102 @@ void QQuickPopup::setExit(QQuickTransition *transition)
emit exitChanged();
}
+void QQuickPopup::classBegin()
+{
+}
+
+void QQuickPopup::componentComplete()
+{
+ Q_D(QQuickPopup);
+ d->complete = true;
+ if (!parentItem())
+ setParentItem(qobject_cast<QQuickItem *>(parent()));
+}
+
+bool QQuickPopup::isComponentComplete() const
+{
+ Q_D(const QQuickPopup);
+ return d->complete;
+}
+
+void QQuickPopup::focusInEvent(QFocusEvent *event)
+{
+ event->accept();
+}
+
+void QQuickPopup::focusOutEvent(QFocusEvent *event)
+{
+ event->accept();
+}
+
+void QQuickPopup::keyPressEvent(QKeyEvent *event)
+{
+ event->accept();
+}
+
+void QQuickPopup::keyReleaseEvent(QKeyEvent *event)
+{
+ event->accept();
+}
+
+void QQuickPopup::mousePressEvent(QMouseEvent *event)
+{
+ event->accept();
+}
+
+void QQuickPopup::mouseMoveEvent(QMouseEvent *event)
+{
+ event->accept();
+}
+
+void QQuickPopup::mouseReleaseEvent(QMouseEvent *event)
+{
+ event->accept();
+}
+
+void QQuickPopup::mouseDoubleClickEvent(QMouseEvent *event)
+{
+ event->accept();
+}
+
+void QQuickPopup::mouseUngrabEvent()
+{
+}
+
+void QQuickPopup::wheelEvent(QWheelEvent *event)
+{
+ event->accept();
+}
+
+void QQuickPopup::contentItemChange(QQuickItem *newItem, QQuickItem *oldItem)
+{
+ Q_UNUSED(newItem);
+ Q_UNUSED(oldItem);
+}
+
+void QQuickPopup::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
+{
+ Q_D(QQuickPopup);
+ d->resizeBackground();
+ d->resizeContent();
+ if (!qFuzzyCompare(newGeometry.width(), oldGeometry.width())) {
+ emit widthChanged();
+ emit availableWidthChanged();
+ }
+ if (!qFuzzyCompare(newGeometry.height(), oldGeometry.height())) {
+ emit heightChanged();
+ emit availableHeightChanged();
+ }
+}
+
+void QQuickPopup::paddingChange(const QMarginsF &newPadding, const QMarginsF &oldPadding)
+{
+ Q_D(QQuickPopup);
+ Q_UNUSED(newPadding);
+ Q_UNUSED(oldPadding);
+ d->resizeContent();
+}
+
QT_END_NAMESPACE
#include "moc_qquickpopup_p.cpp"
diff --git a/src/templates/qquickpopup_p.h b/src/templates/qquickpopup_p.h
index 8eb5e150..e94b63f1 100644
--- a/src/templates/qquickpopup_p.h
+++ b/src/templates/qquickpopup_p.h
@@ -49,31 +49,116 @@
//
#include <QtCore/qobject.h>
+#include <QtCore/qmargins.h>
+#include <QtGui/qevent.h>
#include <QtLabsTemplates/private/qtlabstemplatesglobal_p.h>
#include <QtQml/qqml.h>
+#include <QtQml/qqmllist.h>
+#include <QtQml/qqmlparserstatus.h>
QT_BEGIN_NAMESPACE
class QQuickItem;
class QQuickPopupPrivate;
class QQuickTransition;
+class QQuickTransform;
-class Q_LABSTEMPLATES_EXPORT QQuickPopup : public QObject
+class Q_LABSTEMPLATES_EXPORT QQuickPopup : public QObject, public QQmlParserStatus
{
Q_OBJECT
+ Q_INTERFACES(QQmlParserStatus)
+ Q_PROPERTY(qreal x READ x WRITE setX NOTIFY xChanged FINAL)
+ Q_PROPERTY(qreal y READ y WRITE setY NOTIFY yChanged FINAL)
+ Q_PROPERTY(qreal width READ width WRITE setWidth RESET resetWidth NOTIFY widthChanged FINAL)
+ Q_PROPERTY(qreal height READ height WRITE setHeight RESET resetHeight NOTIFY heightChanged FINAL)
+ Q_PROPERTY(qreal implicitWidth READ implicitWidth WRITE setImplicitWidth NOTIFY implicitWidthChanged FINAL)
+ Q_PROPERTY(qreal implicitHeight READ implicitHeight WRITE setImplicitHeight NOTIFY implicitHeightChanged FINAL)
+ Q_PROPERTY(qreal contentWidth READ contentWidth WRITE setContentWidth NOTIFY contentWidthChanged FINAL)
+ 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 padding READ padding WRITE setPadding RESET resetPadding NOTIFY paddingChanged FINAL)
+ Q_PROPERTY(qreal topPadding READ topPadding WRITE setTopPadding RESET resetTopPadding NOTIFY topPaddingChanged FINAL)
+ Q_PROPERTY(qreal leftPadding READ leftPadding WRITE setLeftPadding RESET resetLeftPadding NOTIFY leftPaddingChanged FINAL)
+ Q_PROPERTY(qreal rightPadding READ rightPadding WRITE setRightPadding RESET resetRightPadding NOTIFY rightPaddingChanged FINAL)
+ Q_PROPERTY(qreal bottomPadding READ bottomPadding WRITE setBottomPadding RESET resetBottomPadding NOTIFY bottomPaddingChanged FINAL)
+ Q_PROPERTY(QQuickItem *parent READ parentItem WRITE setParentItem NOTIFY parentChanged FINAL)
+ Q_PROPERTY(QQuickItem *background READ background WRITE setBackground NOTIFY backgroundChanged FINAL)
Q_PROPERTY(QQuickItem *contentItem READ contentItem WRITE setContentItem NOTIFY contentItemChanged FINAL)
+ Q_PROPERTY(QQmlListProperty<QObject> contentData READ contentData FINAL)
+ Q_PROPERTY(QQmlListProperty<QQuickItem> contentChildren READ contentChildren NOTIFY contentChildrenChanged FINAL)
Q_PROPERTY(bool focus READ hasFocus WRITE setFocus NOTIFY focusChanged)
Q_PROPERTY(bool modal READ isModal WRITE setModal NOTIFY modalChanged)
- Q_PROPERTY(bool visible READ isVisible NOTIFY visibleChanged)
+ Q_PROPERTY(bool visible READ isVisible WRITE setVisible NOTIFY visibleChanged)
Q_PROPERTY(QQuickTransition *enter READ enter WRITE setEnter NOTIFY enterChanged FINAL)
Q_PROPERTY(QQuickTransition *exit READ exit WRITE setExit NOTIFY exitChanged FINAL)
+ Q_CLASSINFO("DefaultProperty", "contentData")
public:
explicit QQuickPopup(QObject *parent = nullptr);
+ ~QQuickPopup();
+
+ qreal x() const;
+ void setX(qreal x);
+
+ qreal y() const;
+ void setY(qreal y);
+
+ qreal width() const;
+ void setWidth(qreal width);
+ void resetWidth();
+
+ qreal height() const;
+ void setHeight(qreal height);
+ void resetHeight();
+
+ qreal implicitWidth() const;
+ void setImplicitWidth(qreal width);
+
+ qreal implicitHeight() const;
+ void setImplicitHeight(qreal height);
+
+ qreal contentWidth() const;
+ void setContentWidth(qreal width);
+
+ qreal contentHeight() const;
+ void setContentHeight(qreal height);
+
+ qreal availableWidth() const;
+ qreal availableHeight() const;
+
+ qreal padding() const;
+ void setPadding(qreal padding);
+ void resetPadding();
+
+ qreal topPadding() const;
+ void setTopPadding(qreal padding);
+ void resetTopPadding();
+
+ qreal leftPadding() const;
+ void setLeftPadding(qreal padding);
+ void resetLeftPadding();
+
+ qreal rightPadding() const;
+ void setRightPadding(qreal padding);
+ void resetRightPadding();
+
+ qreal bottomPadding() const;
+ void setBottomPadding(qreal padding);
+ void resetBottomPadding();
+
+ QQuickItem *parentItem() const;
+ void setParentItem(QQuickItem *parent);
+
+ QQuickItem *background() const;
+ void setBackground(QQuickItem *background);
QQuickItem *contentItem() const;
void setContentItem(QQuickItem *item);
+ QQmlListProperty<QObject> contentData();
+ QQmlListProperty<QQuickItem> contentChildren();
+
bool hasFocus() const;
void setFocus(bool focus);
@@ -81,6 +166,7 @@ public:
void setModal(bool modal);
bool isVisible() const;
+ void setVisible(bool visible);
QQuickTransition *enter() const;
void setEnter(QQuickTransition *transition);
@@ -93,7 +179,25 @@ public Q_SLOTS:
void close();
Q_SIGNALS:
+ void xChanged();
+ void yChanged();
+ void widthChanged();
+ void heightChanged();
+ void implicitWidthChanged();
+ void implicitHeightChanged();
+ void contentWidthChanged();
+ void contentHeightChanged();
+ void availableWidthChanged();
+ void availableHeightChanged();
+ void paddingChanged();
+ void topPaddingChanged();
+ void leftPaddingChanged();
+ void rightPaddingChanged();
+ void bottomPaddingChanged();
+ void parentChanged();
+ void backgroundChanged();
void contentItemChanged();
+ void contentChildrenChanged();
void focusChanged();
void modalChanged();
void visibleChanged();
@@ -110,9 +214,29 @@ Q_SIGNALS:
protected:
QQuickPopup(QQuickPopupPrivate &dd, QObject *parent);
+ void classBegin() override;
+ void componentComplete() override;
+ bool isComponentComplete() const;
+
+ virtual void focusInEvent(QFocusEvent *event);
+ virtual void focusOutEvent(QFocusEvent *event);
+ virtual void keyPressEvent(QKeyEvent *event);
+ virtual void keyReleaseEvent(QKeyEvent *event);
+ virtual void mousePressEvent(QMouseEvent *event);
+ virtual void mouseMoveEvent(QMouseEvent *event);
+ virtual void mouseReleaseEvent(QMouseEvent *event);
+ virtual void mouseDoubleClickEvent(QMouseEvent *event);
+ virtual void mouseUngrabEvent();
+ virtual void wheelEvent(QWheelEvent *event);
+
+ virtual void contentItemChange(QQuickItem *newItem, QQuickItem *oldItem);
+ virtual void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry);
+ virtual void paddingChange(const QMarginsF &newPadding, const QMarginsF &oldPadding);
+
private:
Q_DISABLE_COPY(QQuickPopup)
Q_DECLARE_PRIVATE(QQuickPopup)
+ friend class QQuickPopupItem;
};
QT_END_NAMESPACE
diff --git a/src/templates/qquickpopup_p_p.h b/src/templates/qquickpopup_p_p.h
index 3a5909b7..910fca9e 100644
--- a/src/templates/qquickpopup_p_p.h
+++ b/src/templates/qquickpopup_p_p.h
@@ -48,17 +48,21 @@
// We mean it.
//
+#include "qquickpopup_p.h"
+
#include <QtCore/private/qobject_p.h>
+#include <QtQuick/qquickitem.h>
+#include <QtQuick/private/qquickitemchangelistener_p.h>
#include <QtQuick/private/qquicktransitionmanager_p_p.h>
QT_BEGIN_NAMESPACE
-class QQuickItem;
class QQuickTransition;
class QQuickTransitionManager;
class QQuickPopup;
-class QQuickPopupPrivate;
class QQuickOverlay;
+class QQuickPopupPrivate;
+class QQuickPopupItemPrivate;
class QQuickPopupTransitionManager : public QQuickTransitionManager
{
@@ -80,6 +84,66 @@ private:
QQuickPopupPrivate *popup;
};
+class QQuickPopupItem : public QQuickItem
+{
+ Q_OBJECT
+
+public:
+ explicit QQuickPopupItem(QQuickPopup *popup);
+
+protected:
+ void focusInEvent(QFocusEvent *event) override;
+ void focusOutEvent(QFocusEvent *event) override;
+ void keyPressEvent(QKeyEvent *event) override;
+ void keyReleaseEvent(QKeyEvent *event) override;
+ void mousePressEvent(QMouseEvent *event) override;
+ void mouseMoveEvent(QMouseEvent *event) override;
+ void mouseReleaseEvent(QMouseEvent *event) override;
+ void mouseDoubleClickEvent(QMouseEvent *event) override;
+ void mouseUngrabEvent() override;
+ void wheelEvent(QWheelEvent *event) override;
+
+ void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) override;
+
+private:
+ Q_DECLARE_PRIVATE(QQuickPopupItem)
+};
+
+class QQuickPopupPositioner : public QQuickItemChangeListener
+{
+public:
+ explicit QQuickPopupPositioner(QQuickPopupPrivate *popup);
+ ~QQuickPopupPositioner();
+
+ qreal x() const;
+ void setX(qreal x);
+
+ qreal y() const;
+ void setY(qreal y);
+
+ QQuickItem *parentItem() const;
+ void setParentItem(QQuickItem *parent);
+
+protected:
+ void itemGeometryChanged(QQuickItem *, const QRectF &, const QRectF &);
+ void itemParentChanged(QQuickItem *, QQuickItem *parent);
+ void itemChildRemoved(QQuickItem *, QQuickItem *child);
+ void itemDestroyed(QQuickItem *item);
+
+private:
+ void repositionPopup();
+
+ void removeAncestorListeners(QQuickItem *item);
+ void addAncestorListeners(QQuickItem *item);
+
+ bool isAncestor(QQuickItem *item) const;
+
+ qreal m_x;
+ qreal m_y;
+ QQuickItem *m_parentItem;
+ QQuickPopupPrivate *m_popup;
+};
+
class QQuickPopupPrivate : public QObjectPrivate
{
Q_DECLARE_PUBLIC(QQuickPopup)
@@ -87,15 +151,46 @@ class QQuickPopupPrivate : public QObjectPrivate
public:
QQuickPopupPrivate();
+ static QQuickPopupPrivate *get(QQuickPopup *popup)
+ {
+ return popup->d_func();
+ }
+
+ void init();
+
void finalizeEnterTransition();
void finalizeExitTransition();
+ void resizeBackground();
+ void resizeContent();
+
+ void setTopPadding(qreal value, bool reset = false);
+ void setLeftPadding(qreal value, bool reset = false);
+ void setRightPadding(qreal value, bool reset = false);
+ void setBottomPadding(qreal value, bool reset = false);
+
bool focus;
bool modal;
+ bool complete;
+ bool hasTopPadding;
+ bool hasLeftPadding;
+ bool hasRightPadding;
+ bool hasBottomPadding;
+ qreal padding;
+ qreal topPadding;
+ qreal leftPadding;
+ qreal rightPadding;
+ qreal bottomPadding;
+ qreal contentWidth;
+ qreal contentHeight;
+ QQuickItem *parentItem;
+ QQuickItem *background;
QQuickItem *contentItem;
QQuickOverlay *overlay;
QQuickTransition *enter;
QQuickTransition *exit;
+ QQuickPopupItem *popupItem;
+ QQuickPopupPositioner positioner;
QQuickPopupTransitionManager transitionManager;
};
diff --git a/src/templates/qquickprogressbar.cpp b/src/templates/qquickprogressbar.cpp
index 114b117e..cd490f50 100644
--- a/src/templates/qquickprogressbar.cpp
+++ b/src/templates/qquickprogressbar.cpp
@@ -62,6 +62,8 @@ QT_BEGIN_NAMESPACE
}
\endcode
+ \labs
+
\sa {Customizing ProgressBar}
*/
diff --git a/src/templates/qquickradiobutton.cpp b/src/templates/qquickradiobutton.cpp
index 9aca5808..7d7a64aa 100644
--- a/src/templates/qquickradiobutton.cpp
+++ b/src/templates/qquickradiobutton.cpp
@@ -84,6 +84,8 @@ QT_BEGIN_NAMESPACE
}
\endcode
+ \labs
+
\sa ButtonGroup, {Customizing RadioButton}, {Button Controls}
*/
diff --git a/src/templates/qquickrangeslider.cpp b/src/templates/qquickrangeslider.cpp
index 0a16cafc..0dec63cb 100644
--- a/src/templates/qquickrangeslider.cpp
+++ b/src/templates/qquickrangeslider.cpp
@@ -73,6 +73,8 @@ QT_BEGIN_NAMESPACE
}
\endcode
+ \labs
+
\sa {Customizing RangeSlider}, {Input Controls}
*/
diff --git a/src/templates/qquickscrollbar.cpp b/src/templates/qquickscrollbar.cpp
index caabbcf7..ad7b0a6d 100644
--- a/src/templates/qquickscrollbar.cpp
+++ b/src/templates/qquickscrollbar.cpp
@@ -73,6 +73,8 @@ QT_BEGIN_NAMESPACE
\li \l active
\endlist
+ \labs
+
\sa ScrollIndicator, {Customizing ScrollBar}, {Indicator Controls}
*/
diff --git a/src/templates/qquickscrollindicator.cpp b/src/templates/qquickscrollindicator.cpp
index 59f2acc0..5e210f09 100644
--- a/src/templates/qquickscrollindicator.cpp
+++ b/src/templates/qquickscrollindicator.cpp
@@ -73,6 +73,8 @@ QT_BEGIN_NAMESPACE
\li \l active
\endlist
+ \labs
+
\sa ScrollBar, {Customizing ScrollIndicator}, {Indicator Controls}
*/
diff --git a/src/templates/qquickslider.cpp b/src/templates/qquickslider.cpp
index f1eca648..b109fc5a 100644
--- a/src/templates/qquickslider.cpp
+++ b/src/templates/qquickslider.cpp
@@ -68,6 +68,8 @@ QT_BEGIN_NAMESPACE
}
\endcode
+ \labs
+
\sa {Customizing Slider}, {Input Controls}
*/
diff --git a/src/templates/qquickspinbox.cpp b/src/templates/qquickspinbox.cpp
index 83eefbf3..31368a1a 100644
--- a/src/templates/qquickspinbox.cpp
+++ b/src/templates/qquickspinbox.cpp
@@ -80,6 +80,8 @@ static const int AUTO_REPEAT_INTERVAL = 100;
\snippet qtlabscontrols-spinbox-textual.qml 1
+ \labs
+
\sa Tumbler, {Customizing SpinBox}
*/
@@ -181,7 +183,7 @@ bool QQuickSpinBoxPrivate::handleMousePressEvent(QQuickItem *child, QMouseEvent
q->setAccessibleProperty("pressed", pressed);
if (pressed)
startRepeatDelay();
- return up->isPressed() || down->isPressed();
+ return pressed;
}
bool QQuickSpinBoxPrivate::handleMouseMoveEvent(QQuickItem *child, QMouseEvent *event)
@@ -195,7 +197,7 @@ bool QQuickSpinBoxPrivate::handleMouseMoveEvent(QQuickItem *child, QMouseEvent *
bool pressed = up->isPressed() || down->isPressed();
q->setAccessibleProperty("pressed", pressed);
stopPressRepeat();
- return up->isPressed() || down->isPressed();
+ return pressed;
}
bool QQuickSpinBoxPrivate::handleMouseReleaseEvent(QQuickItem *child, QMouseEvent *event)
diff --git a/src/templates/qquickstackview.cpp b/src/templates/qquickstackview.cpp
index 29b631dc..b338f3bf 100644
--- a/src/templates/qquickstackview.cpp
+++ b/src/templates/qquickstackview.cpp
@@ -257,6 +257,8 @@ QT_BEGIN_NAMESPACE
}
\endqml
+ \labs
+
\sa {Customizing StackView}, {Navigation Controls}, {Container Controls}
*/
@@ -877,10 +879,18 @@ void QQuickStackView::geometryChanged(const QRectF &newGeometry, const QRectF &o
}
}
-bool QQuickStackView::childMouseEventFilter(QQuickItem *, QEvent *)
+bool QQuickStackView::childMouseEventFilter(QQuickItem *item, QEvent *event)
{
- // busy should be true if this function gets called
- return true;
+ // in order to block accidental user interaction while busy/transitioning,
+ // StackView filters out childrens' mouse events. therefore we block all
+ // press events. however, since push() may be called from signal handlers
+ // such as onPressed or onDoubleClicked, we must let the current mouse
+ // grabber item receive the respective mouse release event to avoid
+ // breaking its state (QTBUG-50305).
+ if (event->type() == QEvent::MouseButtonPress)
+ return true;
+ QQuickWindow *window = item->window();
+ return window && !window->mouseGrabberItem();
}
void QQuickStackAttachedPrivate::itemParentChanged(QQuickItem *item, QQuickItem *parent)
diff --git a/src/templates/qquickstackview_p.cpp b/src/templates/qquickstackview_p.cpp
index a34b62e9..5d967a0e 100644
--- a/src/templates/qquickstackview_p.cpp
+++ b/src/templates/qquickstackview_p.cpp
@@ -83,18 +83,20 @@ QQuickStackElement::~QQuickStackElement()
if (ownComponent)
delete component;
- if (ownItem && item) {
- item->setParentItem(nullptr);
- item->deleteLater();
- item = nullptr;
- } else if (item) {
- item->setVisible(false);
- if (item->parentItem() != originalParent) {
- item->setParentItem(originalParent);
+ if (item) {
+ if (ownItem) {
+ item->setParentItem(nullptr);
+ item->deleteLater();
+ item = nullptr;
} else {
- QQuickStackAttached *attached = attachedStackObject(this);
- if (attached)
- QQuickStackAttachedPrivate::get(attached)->itemParentChanged(item, nullptr);
+ item->setVisible(false);
+ if (item->parentItem() != originalParent) {
+ item->setParentItem(originalParent);
+ } else {
+ QQuickStackAttached *attached = attachedStackObject(this);
+ if (attached)
+ QQuickStackAttachedPrivate::get(attached)->itemParentChanged(item, nullptr);
+ }
}
}
diff --git a/src/templates/qquickswipeview.cpp b/src/templates/qquickswipeview.cpp
index 40366af1..b73a8ac0 100644
--- a/src/templates/qquickswipeview.cpp
+++ b/src/templates/qquickswipeview.cpp
@@ -67,6 +67,8 @@ QT_BEGIN_NAMESPACE
\l {Container::moveItem()}{move}, and \l {Container::removeItem()}{remove}
pages dynamically at run time.
+ \labs
+
\sa TabBar, PageIndicator, {Customizing SwipeView}, {Navigation Controls}, {Container Controls}
*/
diff --git a/src/templates/qquickswitch.cpp b/src/templates/qquickswitch.cpp
index a867ec70..8544d7ca 100644
--- a/src/templates/qquickswitch.cpp
+++ b/src/templates/qquickswitch.cpp
@@ -77,6 +77,8 @@ QT_BEGIN_NAMESPACE
}
\endcode
+ \labs
+
\sa {Customizing Switch}, {Button Controls}
*/
diff --git a/src/templates/qquicktabbar.cpp b/src/templates/qquicktabbar.cpp
index d2362f0c..880a89e2 100644
--- a/src/templates/qquicktabbar.cpp
+++ b/src/templates/qquicktabbar.cpp
@@ -59,6 +59,8 @@ QT_BEGIN_NAMESPACE
\snippet qtlabscontrols-tabbar.qml 1
+ \labs
+
\sa TabButton, {Customizing TabBar}, {Navigation Controls}, {Container Controls}
*/
diff --git a/src/templates/qquicktabbutton.cpp b/src/templates/qquicktabbutton.cpp
index 00d4d8b4..a70dcbe1 100644
--- a/src/templates/qquicktabbutton.cpp
+++ b/src/templates/qquicktabbutton.cpp
@@ -55,6 +55,8 @@ QT_BEGIN_NAMESPACE
\snippet qtlabscontrols-tabbutton.qml 1
+ \labs
+
\sa TabBar, {Customizing TabButton}, {Navigation Controls}
*/
diff --git a/src/templates/qquicktextarea.cpp b/src/templates/qquicktextarea.cpp
index 98fd7648..e83f8bf1 100644
--- a/src/templates/qquicktextarea.cpp
+++ b/src/templates/qquicktextarea.cpp
@@ -67,6 +67,8 @@ QT_BEGIN_NAMESPACE
}
\endcode
+ \labs
+
\sa TextField, {Customizing TextArea}, {Input Controls}
*/
diff --git a/src/templates/qquicktextfield.cpp b/src/templates/qquicktextfield.cpp
index a8a6895e..782ff148 100644
--- a/src/templates/qquicktextfield.cpp
+++ b/src/templates/qquicktextfield.cpp
@@ -77,6 +77,8 @@ QT_BEGIN_NAMESPACE
}
\endcode
+ \labs
+
\sa TextArea, {Customizing TextField}, {Input Controls}
*/
diff --git a/src/templates/qquicktoolbar.cpp b/src/templates/qquicktoolbar.cpp
index c20303e8..882834e3 100644
--- a/src/templates/qquicktoolbar.cpp
+++ b/src/templates/qquicktoolbar.cpp
@@ -86,6 +86,8 @@ QT_BEGIN_NAMESPACE
}
\endcode
+ \labs
+
\sa ApplicationWindow, ToolButton, {Customizing ToolBar}, {Container Controls}
*/
diff --git a/src/templates/qquicktoolbutton.cpp b/src/templates/qquicktoolbutton.cpp
index 3505346c..775eedd1 100644
--- a/src/templates/qquicktoolbutton.cpp
+++ b/src/templates/qquicktoolbutton.cpp
@@ -73,6 +73,8 @@ QT_BEGIN_NAMESPACE
}
\endcode
+ \labs
+
\sa ToolBar, {Customizing ToolButton}, {Button Controls}
*/
diff --git a/src/templates/qquicktumbler.cpp b/src/templates/qquicktumbler.cpp
index b1a64051..fcc443df 100644
--- a/src/templates/qquicktumbler.cpp
+++ b/src/templates/qquicktumbler.cpp
@@ -66,6 +66,8 @@ QT_BEGIN_NAMESPACE
\image qtlabscontrols-tumbler-wrap.gif
+ \labs
+
\sa {Customizing Tumbler}, {Input Controls}
*/
diff --git a/tests/auto/controls/data/tst_stackview.qml b/tests/auto/controls/data/tst_stackview.qml
index 2eb802bf..762be4cc 100644
--- a/tests/auto/controls/data/tst_stackview.qml
+++ b/tests/auto/controls/data/tst_stackview.qml
@@ -761,6 +761,45 @@ TestCase {
control.destroy()
}
+ Component {
+ id: mouseArea
+ MouseArea {
+ property int presses: 0
+ property int releases: 0
+ property int clicks: 0
+ property int doubleClicks: 0
+ property int cancels: 0
+ onPressed: ++presses
+ onReleased: ++releases
+ onClicked: ++clicks
+ onDoubleClicked: ++doubleClicks
+ onCanceled: ++cancels
+ }
+ }
+
+ // QTBUG-50305
+ function test_events() {
+ var control = stackView.createObject(testCase, {initialItem: mouseArea, width: testCase.width, height: testCase.height})
+ verify(control)
+
+ var testItem = control.currentItem
+ verify(testItem)
+
+ testItem.doubleClicked.connect(function() {
+ control.push(mouseArea) // ungrab -> cancel
+ })
+
+ mouseDoubleClickSequence(testItem)
+ compare(testItem.presses, 2)
+ compare(testItem.releases, 2)
+ compare(testItem.clicks, 1)
+ compare(testItem.doubleClicks, 1)
+ compare(testItem.pressed, false)
+ compare(testItem.cancels, 0)
+
+ control.destroy()
+ }
+
function test_failures() {
var control = stackView.createObject(testCase, {initialItem: component})
verify(control)
diff --git a/tests/auto/material/data/tst_material.qml b/tests/auto/material/data/tst_material.qml
index e29fea3b..6cd704eb 100644
--- a/tests/auto/material/data/tst_material.qml
+++ b/tests/auto/material/data/tst_material.qml
@@ -61,6 +61,7 @@ TestCase {
id: styledButton
Button {
Material.theme: Material.Dark
+ Material.primary: Material.DeepOrange
Material.accent: Material.DeepPurple
}
}
@@ -74,6 +75,7 @@ TestCase {
id: styledWindow
Window {
Material.theme: Material.Dark
+ Material.primary: Material.Brown
Material.accent: Material.Green
}
}
@@ -97,6 +99,7 @@ TestCase {
Component {
id: menu
Item {
+ Material.primary: Material.Blue
Material.accent: Material.Red
property alias menu: popup
Menu {
@@ -113,6 +116,7 @@ TestCase {
width: 200
height: 200
visible: true
+ Material.primary: Material.Blue
Material.accent: Material.Red
property alias combo: box
ComboBox {
@@ -127,7 +131,8 @@ TestCase {
var control = button.createObject(testCase)
verify(control)
verify(control.Material)
- compare(control.Material.accent, Material.color(Material.Teal))
+ compare(control.Material.primary, Material.color(Material.Indigo))
+ compare(control.Material.accent, Material.color(Material.Pink))
compare(control.Material.theme, Material.Light)
control.destroy()
}
@@ -135,8 +140,10 @@ TestCase {
function test_set() {
var control = button.createObject(testCase)
verify(control)
+ control.Material.primary = Material.Green
control.Material.accent = Material.Brown
control.Material.theme = Material.Dark
+ compare(control.Material.primary, Material.color(Material.Green))
compare(control.Material.accent, Material.color(Material.Brown))
compare(control.Material.theme, Material.Dark)
control.destroy()
@@ -145,10 +152,13 @@ TestCase {
function test_reset() {
var control = styledButton.createObject(testCase)
verify(control)
+ compare(control.Material.primary, Material.color(Material.DeepOrange))
compare(control.Material.accent, Material.color(Material.DeepPurple))
compare(control.Material.theme, Material.Dark)
+ control.Material.primary = undefined
control.Material.accent = undefined
control.Material.theme = undefined
+ compare(control.Material.primary, testCase.Material.primary)
compare(control.Material.accent, testCase.Material.accent)
compare(control.Material.theme, testCase.Material.theme)
control.destroy()
@@ -156,6 +166,7 @@ TestCase {
function test_inheritance_data() {
return [
+ { tag: "primary", value1: Material.color(Material.Amber), value2: Material.color(Material.Indigo) },
{ tag: "accent", value1: Material.color(Material.Amber), value2: Material.color(Material.Indigo) },
{ tag: "theme", value1: Material.Dark, value2: Material.Light },
]
@@ -209,17 +220,25 @@ TestCase {
var parent = window.createObject()
var control = button.createObject(parent.contentItem)
+ compare(control.Material.primary, parent.Material.primary)
compare(control.Material.accent, parent.Material.accent)
compare(control.Material.theme, parent.Material.theme)
var styledChild = styledWindow.createObject(window)
+ verify(styledChild.Material.primary !== parent.Material.primary)
verify(styledChild.Material.accent !== parent.Material.accent)
verify(styledChild.Material.theme !== parent.Material.theme)
var unstyledChild = window.createObject(window)
+ compare(unstyledChild.Material.primary, parent.Material.primary)
compare(unstyledChild.Material.accent, parent.Material.accent)
compare(unstyledChild.Material.theme, parent.Material.theme)
+ parent.Material.primary = Material.Lime
+ compare(control.Material.primary, Material.color(Material.Lime))
+ verify(styledChild.Material.primary !== Material.color(Material.Lime))
+ // ### TODO: compare(unstyledChild.Material.primary, Material.color(Material.Lime))
+
parent.Material.accent = Material.Cyan
compare(control.Material.accent, Material.color(Material.Cyan))
verify(styledChild.Material.accent !== Material.color(Material.Cyan))
@@ -230,14 +249,20 @@ TestCase {
function test_loader() {
var control = loader.createObject(testCase)
+ control.Material.primary = Material.Yellow
control.Material.accent = Material.Lime
control.active = true
+ compare(control.item.Material.primary, Material.color(Material.Yellow))
compare(control.item.Material.accent, Material.color(Material.Lime))
+ control.Material.primary = Material.Red
control.Material.accent = Material.Pink
+ compare(control.item.Material.primary, Material.color(Material.Red))
compare(control.item.Material.accent, Material.color(Material.Pink))
control.active = false
+ control.Material.primary = Material.Orange
control.Material.accent = Material.Brown
control.active = true
+ compare(control.item.Material.primary, Material.color(Material.Orange))
compare(control.item.Material.accent, Material.color(Material.Brown))
control.destroy()
}
@@ -261,6 +286,9 @@ TestCase {
compare(container.Material.theme, Material.Light)
compare(container.menu.Material.theme, Material.Dark)
compare(child.Material.theme, Material.Dark)
+ compare(container.Material.primary, Material.color(Material.Blue))
+ compare(container.menu.Material.primary, Material.color(Material.Blue))
+ compare(child.Material.primary, Material.color(Material.Blue))
compare(container.Material.accent, Material.color(Material.Red))
compare(container.menu.Material.accent, Material.color(Material.Red))
compare(child.Material.accent, Material.color(Material.Red))
@@ -276,58 +304,70 @@ TestCase {
verify(window.combo.activeFocus)
keyClick(Qt.Key_Space)
verify(window.combo.popup.visible)
- var listView = window.combo.popup.contentItem.children[0]
+ var listView = window.combo.popup.contentItem
verify(listView)
var child = listView.contentItem.children[0]
verify(child)
compare(window.Material.theme, Material.Light)
compare(window.combo.Material.theme, Material.Dark)
compare(child.Material.theme, Material.Dark)
+ compare(window.Material.primary, Material.color(Material.Blue))
+ compare(window.combo.Material.primary, Material.color(Material.Blue))
+ compare(child.Material.primary, Material.color(Material.Blue))
compare(window.Material.accent, Material.color(Material.Red))
compare(window.combo.Material.accent, Material.color(Material.Red))
compare(child.Material.accent, Material.color(Material.Red))
window.destroy()
}
- function test_colors() {
+
+ function test_colors_data() {
+ return [
+ { tag: "primary" }, { tag: "accent" }
+ ]
+ }
+
+ function test_colors(data) {
var control = button.createObject(testCase)
verify(control)
- // Material.Accent - enum
- control.Material.accent = Material.Red
- compare(control.Material.accent, "#f44336")
+ var prop = data.tag
+
+ // Material.Color - enum
+ control.Material[prop] = Material.Red
+ compare(control.Material[prop], "#f44336")
- // Material.Accent - string
- control.Material.accent = "BlueGrey"
- compare(control.Material.accent, "#607d8b")
+ // Material.Color - string
+ control.Material[prop] = "BlueGrey"
+ compare(control.Material[prop], "#607d8b")
// SVG named color
- control.Material.accent = "tomato"
- compare(control.Material.accent, "#ff6347")
+ control.Material[prop] = "tomato"
+ compare(control.Material[prop], "#ff6347")
// #rrggbb
- control.Material.accent = "#123456"
- compare(control.Material.accent, "#123456")
+ control.Material[prop] = "#123456"
+ compare(control.Material[prop], "#123456")
// #aarrggbb
- control.Material.accent = "#12345678"
- compare(control.Material.accent, "#12345678")
+ control.Material[prop] = "#12345678"
+ compare(control.Material[prop], "#12345678")
// Qt.rgba() - no alpha
- control.Material.accent = Qt.rgba(0.5, 0.5, 0.5)
- compare(control.Material.accent, "#808080")
+ control.Material[prop] = Qt.rgba(0.5, 0.5, 0.5)
+ compare(control.Material[prop], "#808080")
// Qt.rgba() - with alpha
- control.Material.accent = Qt.rgba(0.5, 0.5, 0.5, 0.5)
- compare(control.Material.accent, "#80808080")
+ control.Material[prop] = Qt.rgba(0.5, 0.5, 0.5, 0.5)
+ compare(control.Material[prop], "#80808080")
// unknown
- ignoreWarning(Qt.resolvedUrl("tst_material.qml") + ":57:9: QML Button: unknown Material.accent value: 123")
- control.Material.accent = 123
- ignoreWarning(Qt.resolvedUrl("tst_material.qml") + ":57:9: QML Button: unknown Material.accent value: foo")
- control.Material.accent = "foo"
- ignoreWarning(Qt.resolvedUrl("tst_material.qml") + ":57:9: QML Button: unknown Material.accent value: #1")
- control.Material.accent = "#1"
+ ignoreWarning(Qt.resolvedUrl("tst_material.qml") + ":57:9: QML Button: unknown Material." + prop + " value: 123")
+ control.Material[prop] = 123
+ ignoreWarning(Qt.resolvedUrl("tst_material.qml") + ":57:9: QML Button: unknown Material." + prop + " value: foo")
+ control.Material[prop] = "foo"
+ ignoreWarning(Qt.resolvedUrl("tst_material.qml") + ":57:9: QML Button: unknown Material." + prop + " value: #1")
+ control.Material[prop] = "#1"
control.destroy()
}
diff --git a/tests/auto/menu/tst_menu.cpp b/tests/auto/menu/tst_menu.cpp
index 3a2d9c61..d072af4b 100644
--- a/tests/auto/menu/tst_menu.cpp
+++ b/tests/auto/menu/tst_menu.cpp
@@ -86,7 +86,7 @@ void tst_menu::mouse()
QQuickMenu *menu = window->property("menu").value<QQuickMenu*>();
menu->open();
QVERIFY(menu->isVisible());
- QVERIFY(window->overlay()->childItems().contains(menu->contentItem()));
+ QVERIFY(window->overlay()->childItems().contains(menu->contentItem()->parentItem()));
QQuickItem *firstItem = menu->itemAt(0);
QSignalSpy clickedSpy(firstItem, SIGNAL(clicked(QQuickMouseEvent*)));
@@ -111,7 +111,7 @@ void tst_menu::mouse()
menu->open();
QCOMPARE(visibleSpy.count(), 2);
QVERIFY(menu->isVisible());
- QVERIFY(window->overlay()->childItems().contains(menu->contentItem()));
+ QVERIFY(window->overlay()->childItems().contains(menu->contentItem()->parentItem()));
// Ensure that we have enough space to click outside of the menu.
QVERIFY(window->width() > menu->contentItem()->width());
@@ -120,12 +120,12 @@ void tst_menu::mouse()
QPoint(menu->contentItem()->width() + 1, menu->contentItem()->height() + 1));
QCOMPARE(visibleSpy.count(), 3);
QVERIFY(!menu->isVisible());
- QVERIFY(!window->overlay()->childItems().contains(menu->contentItem()));
+ QVERIFY(!window->overlay()->childItems().contains(menu->contentItem()->parentItem()));
menu->open();
QCOMPARE(visibleSpy.count(), 4);
QVERIFY(menu->isVisible());
- QVERIFY(window->overlay()->childItems().contains(menu->contentItem()));
+ QVERIFY(window->overlay()->childItems().contains(menu->contentItem()->parentItem()));
// Try pressing within the menu and releasing outside of it; it should close.
// TODO: won't work until QQuickPopup::releasedOutside() actually gets emitted
@@ -167,7 +167,7 @@ void tst_menu::contextMenuKeyboard()
menu->open();
QCOMPARE(visibleSpy.count(), 1);
QVERIFY(menu->isVisible());
- QVERIFY(window->overlay()->childItems().contains(menu->contentItem()));
+ QVERIFY(window->overlay()->childItems().contains(menu->contentItem()->parentItem()));
QVERIFY(!firstItem->hasActiveFocus());
QCOMPARE(menu->contentItem()->property("currentIndex"), QVariant(-1));
@@ -194,7 +194,7 @@ void tst_menu::contextMenuKeyboard()
menu->open();
QCOMPARE(visibleSpy.count(), 3);
QVERIFY(menu->isVisible());
- QVERIFY(window->overlay()->childItems().contains(menu->contentItem()));
+ QVERIFY(window->overlay()->childItems().contains(menu->contentItem()->parentItem()));
QVERIFY(!firstItem->hasActiveFocus());
QVERIFY(!secondItem->hasActiveFocus());
QCOMPARE(menu->contentItem()->property("currentIndex"), QVariant(-1));
diff --git a/tests/auto/universal/data/tst_universal.qml b/tests/auto/universal/data/tst_universal.qml
index af70ad0e..36e8b0b2 100644
--- a/tests/auto/universal/data/tst_universal.qml
+++ b/tests/auto/universal/data/tst_universal.qml
@@ -276,7 +276,7 @@ TestCase {
verify(window.combo.activeFocus)
keyClick(Qt.Key_Space)
verify(window.combo.popup.visible)
- var listView = window.combo.popup.contentItem.children[0]
+ var listView = window.combo.popup.contentItem
verify(listView)
var child = listView.contentItem.children[0]
verify(child)
diff --git a/tests/manual/testbench/main.qml b/tests/manual/testbench/main.qml
index 76008497..6ace3620 100644
--- a/tests/manual/testbench/main.qml
+++ b/tests/manual/testbench/main.qml
@@ -53,7 +53,6 @@ ApplicationWindow {
Material.theme: themeSwitch.checked ? Material.Dark : Material.Light
Universal.theme: themeSwitch.checked ? Universal.Dark : Universal.Light
- Material.accent: Material.LightGreen
property int controlSpacing: 10
@@ -71,6 +70,25 @@ ApplicationWindow {
ToolButton {
text: "Normal"
onClicked: menu.visible ? menu.close() : menu.open()
+
+ Menu {
+ id: menu
+ x: 1
+ y: 1 + parent.height
+
+ MenuItem {
+ text: "Option 1"
+ checkable: true
+ }
+ MenuItem {
+ text: "Option 2"
+ checkable: true
+ }
+ MenuItem {
+ text: "Option 3"
+ checkable: true
+ }
+ }
}
ToolButton {
text: "Pressed"
@@ -115,25 +133,6 @@ ApplicationWindow {
}
}
- Menu {
- id: menu
- contentItem.x: 1
- contentItem.y: header.height
-
- MenuItem {
- text: "Option 1"
- checkable: true
- }
- MenuItem {
- text: "Option 2"
- checkable: true
- }
- MenuItem {
- text: "Option 3"
- checkable: true
- }
- }
-
Pane {
anchors.fill: parent