aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--examples/quickcontrols2/gallery/pages/DialogPage.qml8
-rw-r--r--src/imports/controls/Dialog.qml8
-rw-r--r--src/imports/controls/Drawer.qml10
-rw-r--r--src/imports/controls/Menu.qml8
-rw-r--r--src/imports/controls/Popup.qml8
-rw-r--r--src/imports/controls/fusion/Dialog.qml8
-rw-r--r--src/imports/controls/fusion/Drawer.qml10
-rw-r--r--src/imports/controls/fusion/Menu.qml8
-rw-r--r--src/imports/controls/fusion/Popup.qml8
-rw-r--r--src/imports/controls/material/Dialog.qml10
-rw-r--r--src/imports/controls/material/Drawer.qml12
-rw-r--r--src/imports/controls/material/Menu.qml10
-rw-r--r--src/imports/controls/material/Popup.qml10
-rw-r--r--src/imports/controls/qtquickcontrols2plugin.cpp2
-rw-r--r--src/imports/controls/universal/Dialog.qml8
-rw-r--r--src/imports/controls/universal/Drawer.qml10
-rw-r--r--src/imports/controls/universal/Menu.qml8
-rw-r--r--src/imports/controls/universal/Popup.qml8
-rw-r--r--src/imports/templates/qtquicktemplates2plugin.cpp2
-rw-r--r--src/quicktemplates2/qquickapplicationwindow.cpp41
-rw-r--r--src/quicktemplates2/qquickoverlay.cpp187
-rw-r--r--src/quicktemplates2/qquickoverlay_p.h35
-rw-r--r--src/quicktemplates2/qquickpopup.cpp10
-rw-r--r--tests/auto/controls/data/tst_drawer.qml4
-rw-r--r--tests/auto/controls/data/tst_popup.qml5
-rw-r--r--tests/auto/popup/tst_popup.cpp21
26 files changed, 416 insertions, 43 deletions
diff --git a/examples/quickcontrols2/gallery/pages/DialogPage.qml b/examples/quickcontrols2/gallery/pages/DialogPage.qml
index daaa7329..8bade21f 100644
--- a/examples/quickcontrols2/gallery/pages/DialogPage.qml
+++ b/examples/quickcontrols2/gallery/pages/DialogPage.qml
@@ -50,7 +50,7 @@
import QtQuick 2.6
import QtQuick.Layouts 1.0
-import QtQuick.Controls 2.1
+import QtQuick.Controls 2.3
ScrollablePage {
id: page
@@ -101,7 +101,7 @@ ScrollablePage {
x: (parent.width - width) / 2
y: (parent.height - height) / 2
- parent: ApplicationWindow.overlay
+ parent: Overlay.overlay
modal: true
title: "Confirmation"
@@ -134,7 +134,7 @@ ScrollablePage {
y: (parent.height - height) / 2
width: Math.min(page.width, page.height) / 3 * 2
contentHeight: logo.height * 2
- parent: ApplicationWindow.overlay
+ parent: Overlay.overlay
modal: true
title: "Content"
@@ -194,7 +194,7 @@ ScrollablePage {
x: (parent.width - width) / 2
y: (parent.height - height) / 2
- parent: ApplicationWindow.overlay
+ parent: Overlay.overlay
focus: true
modal: true
diff --git a/src/imports/controls/Dialog.qml b/src/imports/controls/Dialog.qml
index f2ebae34..28266670 100644
--- a/src/imports/controls/Dialog.qml
+++ b/src/imports/controls/Dialog.qml
@@ -76,4 +76,12 @@ T.Dialog {
footer: DialogButtonBox {
visible: count > 0
}
+
+ T.Overlay.modal: Rectangle {
+ color: Default.overlayModalColor
+ }
+
+ T.Overlay.modeless: Rectangle {
+ color: Default.overlayDimColor
+ }
}
diff --git a/src/imports/controls/Drawer.qml b/src/imports/controls/Drawer.qml
index 8368838a..e21de5b4 100644
--- a/src/imports/controls/Drawer.qml
+++ b/src/imports/controls/Drawer.qml
@@ -42,7 +42,7 @@ import QtQuick.Templates 2.3 as T
T.Drawer {
id: control
- parent: T.ApplicationWindow.overlay
+ parent: T.Overlay.overlay
implicitWidth: Math.max(background ? background.implicitWidth : 0, contentWidth + leftPadding + rightPadding)
implicitHeight: Math.max(background ? background.implicitHeight : 0, contentHeight + topPadding + bottomPadding)
@@ -68,4 +68,12 @@ T.Drawer {
y: control.edge === Qt.TopEdge ? parent.height - 1 : 0
}
}
+
+ T.Overlay.modal: Rectangle {
+ color: Default.overlayModalColor
+ }
+
+ T.Overlay.modeless: Rectangle {
+ color: Default.overlayDimColor
+ }
}
diff --git a/src/imports/controls/Menu.qml b/src/imports/controls/Menu.qml
index 32cbfa3f..03503e0a 100644
--- a/src/imports/controls/Menu.qml
+++ b/src/imports/controls/Menu.qml
@@ -69,4 +69,12 @@ T.Menu {
color: Default.backgroundColor
border.color: Default.frameDarkColor
}
+
+ T.Overlay.modal: Rectangle {
+ color: Default.overlayModalColor
+ }
+
+ T.Overlay.modeless: Rectangle {
+ color: Default.overlayDimColor
+ }
}
diff --git a/src/imports/controls/Popup.qml b/src/imports/controls/Popup.qml
index 7a94aaab..58799744 100644
--- a/src/imports/controls/Popup.qml
+++ b/src/imports/controls/Popup.qml
@@ -55,4 +55,12 @@ T.Popup {
background: Rectangle {
border.color: Default.frameDarkColor
}
+
+ T.Overlay.modal: Rectangle {
+ color: Default.overlayModalColor
+ }
+
+ T.Overlay.modeless: Rectangle {
+ color: Default.overlayDimColor
+ }
}
diff --git a/src/imports/controls/fusion/Dialog.qml b/src/imports/controls/fusion/Dialog.qml
index a0c9ef18..b79b9254 100644
--- a/src/imports/controls/fusion/Dialog.qml
+++ b/src/imports/controls/fusion/Dialog.qml
@@ -92,4 +92,12 @@ T.Dialog {
footer: DialogButtonBox {
visible: count > 0
}
+
+ T.Overlay.modal: Rectangle {
+ color: Fusion.topShadow
+ }
+
+ T.Overlay.modeless: Rectangle {
+ color: Fusion.topShadow
+ }
}
diff --git a/src/imports/controls/fusion/Drawer.qml b/src/imports/controls/fusion/Drawer.qml
index 4115ec06..236c359a 100644
--- a/src/imports/controls/fusion/Drawer.qml
+++ b/src/imports/controls/fusion/Drawer.qml
@@ -44,7 +44,7 @@ import QtQuick.Controls.Fusion.impl 2.3
T.Drawer {
id: control
- parent: T.ApplicationWindow.overlay
+ parent: T.Overlay.overlay
implicitWidth: Math.max(background ? background.implicitWidth : 0, contentWidth + leftPadding + rightPadding)
implicitHeight: Math.max(background ? background.implicitHeight : 0, contentHeight + topPadding + bottomPadding)
@@ -79,4 +79,12 @@ T.Drawer {
y: control.edge === Qt.TopEdge ? parent.height : 0
}
}
+
+ T.Overlay.modal: Rectangle {
+ color: Fusion.topShadow
+ }
+
+ T.Overlay.modeless: Rectangle {
+ color: Fusion.topShadow
+ }
}
diff --git a/src/imports/controls/fusion/Menu.qml b/src/imports/controls/fusion/Menu.qml
index 06886ad7..fe82e0e7 100644
--- a/src/imports/controls/fusion/Menu.qml
+++ b/src/imports/controls/fusion/Menu.qml
@@ -82,4 +82,12 @@ T.Menu {
opacity: 0.2
}
}
+
+ T.Overlay.modal: Rectangle {
+ color: Fusion.topShadow
+ }
+
+ T.Overlay.modeless: Rectangle {
+ color: Fusion.topShadow
+ }
}
diff --git a/src/imports/controls/fusion/Popup.qml b/src/imports/controls/fusion/Popup.qml
index 64c9fe49..30532e7e 100644
--- a/src/imports/controls/fusion/Popup.qml
+++ b/src/imports/controls/fusion/Popup.qml
@@ -59,4 +59,12 @@ T.Popup {
border.color: control.palette.mid
radius: 2
}
+
+ T.Overlay.modal: Rectangle {
+ color: Fusion.topShadow
+ }
+
+ T.Overlay.modeless: Rectangle {
+ color: Fusion.topShadow
+ }
}
diff --git a/src/imports/controls/material/Dialog.qml b/src/imports/controls/material/Dialog.qml
index 68f856c6..abad5662 100644
--- a/src/imports/controls/material/Dialog.qml
+++ b/src/imports/controls/material/Dialog.qml
@@ -103,4 +103,14 @@ T.Dialog {
footer: DialogButtonBox {
visible: count > 0
}
+
+ T.Overlay.modal: Rectangle {
+ color: control.Material.backgroundDimColor
+ Behavior on opacity { NumberAnimation { duration: 150 } }
+ }
+
+ T.Overlay.modeless: Rectangle {
+ color: control.Material.backgroundDimColor
+ Behavior on opacity { NumberAnimation { duration: 150 } }
+ }
}
diff --git a/src/imports/controls/material/Drawer.qml b/src/imports/controls/material/Drawer.qml
index 78b6f2b8..7ea52b46 100644
--- a/src/imports/controls/material/Drawer.qml
+++ b/src/imports/controls/material/Drawer.qml
@@ -42,7 +42,7 @@ import QtQuick.Controls.Material.impl 2.3
T.Drawer {
id: control
- parent: T.ApplicationWindow.overlay
+ parent: T.Overlay.overlay
implicitWidth: Math.max(background ? background.implicitWidth : 0, contentWidth + leftPadding + rightPadding)
implicitHeight: Math.max(background ? background.implicitHeight : 0, contentHeight + topPadding + bottomPadding)
@@ -79,4 +79,14 @@ T.Drawer {
fullHeight: true
}
}
+
+ T.Overlay.modal: Rectangle {
+ color: control.Material.backgroundDimColor
+ Behavior on opacity { NumberAnimation { duration: 150 } }
+ }
+
+ T.Overlay.modeless: Rectangle {
+ color: control.Material.backgroundDimColor
+ Behavior on opacity { NumberAnimation { duration: 150 } }
+ }
}
diff --git a/src/imports/controls/material/Menu.qml b/src/imports/controls/material/Menu.qml
index 8410dfeb..9c8128a7 100644
--- a/src/imports/controls/material/Menu.qml
+++ b/src/imports/controls/material/Menu.qml
@@ -94,4 +94,14 @@ T.Menu {
elevation: control.Material.elevation
}
}
+
+ T.Overlay.modal: Rectangle {
+ color: control.Material.backgroundDimColor
+ Behavior on opacity { NumberAnimation { duration: 150 } }
+ }
+
+ T.Overlay.modeless: Rectangle {
+ color: control.Material.backgroundDimColor
+ Behavior on opacity { NumberAnimation { duration: 150 } }
+ }
}
diff --git a/src/imports/controls/material/Popup.qml b/src/imports/controls/material/Popup.qml
index 49b39a6c..e22b8b7c 100644
--- a/src/imports/controls/material/Popup.qml
+++ b/src/imports/controls/material/Popup.qml
@@ -75,4 +75,14 @@ T.Popup {
elevation: control.Material.elevation
}
}
+
+ T.Overlay.modal: Rectangle {
+ color: control.Material.backgroundDimColor
+ Behavior on opacity { NumberAnimation { duration: 150 } }
+ }
+
+ T.Overlay.modeless: Rectangle {
+ color: control.Material.backgroundDimColor
+ Behavior on opacity { NumberAnimation { duration: 150 } }
+ }
}
diff --git a/src/imports/controls/qtquickcontrols2plugin.cpp b/src/imports/controls/qtquickcontrols2plugin.cpp
index f9ee88d8..7a1651e4 100644
--- a/src/imports/controls/qtquickcontrols2plugin.cpp
+++ b/src/imports/controls/qtquickcontrols2plugin.cpp
@@ -48,6 +48,7 @@
#if QT_CONFIG(quick_listview) && QT_CONFIG(quick_pathview)
#include <QtQuickControls2/private/qquicktumblerview_p.h>
#endif
+#include <QtQuickTemplates2/private/qquickoverlay_p.h>
#include "qquickdefaultbusyindicator_p.h"
#include "qquickdefaultdial_p.h"
@@ -157,6 +158,7 @@ void QtQuickControls2Plugin::registerTypes(const char *uri)
// QtQuick.Controls 2.3 (new types in Qt 5.10)
qmlRegisterType(selector.select(QStringLiteral("Action.qml")), uri, 2, 3, "Action");
qmlRegisterType(selector.select(QStringLiteral("ActionGroup.qml")), uri, 2, 3, "ActionGroup");
+ qmlRegisterUncreatableType<QQuickOverlay>(uri, 2, 3, "Overlay", QStringLiteral("Overlay is only available as an attached property."));
}
static QObject *styleSingleton(QQmlEngine *engine, QJSEngine *scriptEngine)
diff --git a/src/imports/controls/universal/Dialog.qml b/src/imports/controls/universal/Dialog.qml
index 4f8a6180..dd463b83 100644
--- a/src/imports/controls/universal/Dialog.qml
+++ b/src/imports/controls/universal/Dialog.qml
@@ -84,4 +84,12 @@ T.Dialog {
footer: DialogButtonBox {
visible: count > 0
}
+
+ T.Overlay.modal: Rectangle {
+ color: control.Universal.baseLowColor
+ }
+
+ T.Overlay.modeless: Rectangle {
+ color: control.Universal.baseLowColor
+ }
}
diff --git a/src/imports/controls/universal/Drawer.qml b/src/imports/controls/universal/Drawer.qml
index 5ef0b325..40cfaadd 100644
--- a/src/imports/controls/universal/Drawer.qml
+++ b/src/imports/controls/universal/Drawer.qml
@@ -41,7 +41,7 @@ import QtQuick.Controls.Universal 2.3
T.Drawer {
id: control
- parent: T.ApplicationWindow.overlay
+ parent: T.Overlay.overlay
implicitWidth: Math.max(background ? background.implicitWidth : 0, contentWidth + leftPadding + rightPadding)
implicitHeight: Math.max(background ? background.implicitHeight : 0, contentHeight + topPadding + bottomPadding)
@@ -68,4 +68,12 @@ T.Drawer {
y: control.edge === Qt.TopEdge ? parent.height - 1 : 0
}
}
+
+ T.Overlay.modal: Rectangle {
+ color: control.Universal.baseLowColor
+ }
+
+ T.Overlay.modeless: Rectangle {
+ color: control.Universal.baseLowColor
+ }
}
diff --git a/src/imports/controls/universal/Menu.qml b/src/imports/controls/universal/Menu.qml
index 8ffefb1b..8b69051f 100644
--- a/src/imports/controls/universal/Menu.qml
+++ b/src/imports/controls/universal/Menu.qml
@@ -70,4 +70,12 @@ T.Menu {
border.color: control.Universal.chromeHighColor
border.width: 1 // FlyoutBorderThemeThickness
}
+
+ T.Overlay.modal: Rectangle {
+ color: control.Universal.baseLowColor
+ }
+
+ T.Overlay.modeless: Rectangle {
+ color: control.Universal.baseLowColor
+ }
}
diff --git a/src/imports/controls/universal/Popup.qml b/src/imports/controls/universal/Popup.qml
index f844d8e1..e44e953c 100644
--- a/src/imports/controls/universal/Popup.qml
+++ b/src/imports/controls/universal/Popup.qml
@@ -56,4 +56,12 @@ T.Popup {
border.color: control.Universal.chromeHighColor
border.width: 1 // FlyoutBorderThemeThickness
}
+
+ T.Overlay.modal: Rectangle {
+ color: control.Universal.baseLowColor
+ }
+
+ T.Overlay.modeless: Rectangle {
+ color: control.Universal.baseLowColor
+ }
}
diff --git a/src/imports/templates/qtquicktemplates2plugin.cpp b/src/imports/templates/qtquicktemplates2plugin.cpp
index e7e08e32..2ce655c3 100644
--- a/src/imports/templates/qtquicktemplates2plugin.cpp
+++ b/src/imports/templates/qtquicktemplates2plugin.cpp
@@ -301,6 +301,8 @@ void QtQuickTemplates2Plugin::registerTypes(const char *uri)
qRegisterMetaType<QQuickIcon>();
qmlRegisterType<QQuickMenu, 3>(uri, 2, 3, "Menu");
qmlRegisterType<QQuickMenuItem, 3>(uri, 2, 3, "MenuItem");
+ qmlRegisterUncreatableType<QQuickOverlay>(uri, 2, 3, "Overlay", QStringLiteral("Overlay is only available as an attached property."));
+ qmlRegisterType<QQuickOverlayAttached>();
qmlRegisterType<QQuickPopup, 3>(uri, 2, 3, "Popup");
qmlRegisterType<QQuickRangeSlider, 3>(uri, 2, 3, "RangeSlider");
qmlRegisterType<QQuickScrollBar, 3>(uri, 2, 3, "ScrollBar");
diff --git a/src/quicktemplates2/qquickapplicationwindow.cpp b/src/quicktemplates2/qquickapplicationwindow.cpp
index 9311958e..cee38b23 100644
--- a/src/quicktemplates2/qquickapplicationwindow.cpp
+++ b/src/quicktemplates2/qquickapplicationwindow.cpp
@@ -88,11 +88,6 @@ QT_BEGIN_NAMESPACE
}
\endqml
- ApplicationWindow supports popups via its \l overlay property, which
- ensures that popups are displayed above other content and that the
- background is dimmed when a \l {Popup::}{modal} or \l {Popup::dim}
- {dimmed} popup is visible.
-
\note By default, an ApplicationWindow is not visible.
\section2 Attached ApplicationWindow Properties
@@ -107,29 +102,9 @@ QT_BEGIN_NAMESPACE
to access the window and its building blocks from places where no direct
access to the window is available, without creating a dependency to a
certain window \c id. A QML component that uses the ApplicationWindow
- attached properties works in any window regardless of its \c id. The
- following example uses the attached \c overlay property to position the
- popup to the center of the window, despite the position of the button
- that opens the popup.
-
- \code
- Button {
- onClicked: popup.open()
+ attached properties works in any window regardless of its \c id.
- Popup {
- id: popup
-
- parent: ApplicationWindow.overlay
-
- x: (parent.width - width) / 2
- y: (parent.height - height) / 2
- width: 100
- height: 100
- }
- }
- \endcode
-
- \sa {Customizing ApplicationWindow}, Page, {Container Controls}
+ \sa {Customizing ApplicationWindow}, Overlay, Page, {Container Controls}
*/
class QQuickApplicationWindowPrivate : public QQuickItemChangeListener
@@ -378,7 +353,7 @@ QQuickApplicationWindow::~QQuickApplicationWindow()
follows the control's size. In most cases, there is no need to specify
width or height for a background item.
- \sa {Customizing ApplicationWindow}, contentItem, header, footer, overlay
+ \sa {Customizing ApplicationWindow}, contentItem, header, footer
*/
QQuickItem *QQuickApplicationWindow::background() const
{
@@ -554,9 +529,9 @@ QQmlListProperty<QObject> QQuickApplicationWindow::contentData()
This property holds the window content item.
The content item is stacked above the \l background item, and under the
- \l header, \l footer, and \l overlay items.
+ \l header, and \l footer items.
- \sa background, header, footer, overlay
+ \sa background, header, footer
*/
QQuickItem *QQuickApplicationWindow::contentItem() const
{
@@ -591,11 +566,14 @@ QQuickItem *QQuickApplicationWindow::activeFocusControl() const
}
/*!
+ \deprecated
\qmlpropertygroup QtQuick.Controls::ApplicationWindow::overlay
\qmlproperty Item QtQuick.Controls::ApplicationWindow::overlay
\qmlproperty Component QtQuick.Controls::ApplicationWindow::overlay.modal
\qmlproperty Component QtQuick.Controls::ApplicationWindow::overlay.modeless
+ Use the \l Overlay attached properties and signals instead.
+
This property holds the window overlay item. Popups are automatically
reparented to the overlay.
@@ -976,9 +954,12 @@ QQuickItem *QQuickApplicationWindowAttached::footer() const
}
/*!
+ \deprecated
\qmlattachedproperty Item QtQuick.Controls::ApplicationWindow::overlay
\readonly
+ Use the \l Overlay::overlay attached property instead.
+
This attached property holds the window overlay item. The property can be attached
to any item. The value is \c null if the item is not in an ApplicationWindow.
diff --git a/src/quicktemplates2/qquickoverlay.cpp b/src/quicktemplates2/qquickoverlay.cpp
index 8ea97069..12158f06 100644
--- a/src/quicktemplates2/qquickoverlay.cpp
+++ b/src/quicktemplates2/qquickoverlay.cpp
@@ -47,6 +47,43 @@
QT_BEGIN_NAMESPACE
+/*!
+ \qmltype Overlay
+ \inherits Item
+ \instantiates QQuickOverlay
+ \inqmlmodule QtQuick.Controls
+ \since 5.10
+ \brief A window overlay for popups.
+
+ Overlay provides a layer for popups, ensuring that popups are displayed above
+ other content and that the background is dimmed when a \l {Popup::}{modal} or
+ \l {Popup::dim}{dimmed} popup is visible.
+
+ The overlay is an ordinary Item that covers the entire window. It can be used
+ as a visual parent to position a popup in scene coordinates. The following
+ example uses the attached \c overlay property to position a popup to the center
+ of the window, despite the position of the button that opens the popup.
+
+ \code
+ Button {
+ onClicked: popup.open()
+
+ Popup {
+ id: popup
+
+ parent: Overlay.overlay
+
+ x: (parent.width - width) / 2
+ y: (parent.height - height) / 2
+ width: 100
+ height: 100
+ }
+ }
+ \endcode
+
+ \sa ApplicationWindow
+*/
+
QVector<QQuickPopup *> QQuickOverlayPrivate::stackingOrderPopups() const
{
const QList<QQuickItem *> children = paintOrderChildItems();
@@ -321,6 +358,11 @@ QQuickOverlay *QQuickOverlay::overlay(QQuickWindow *window)
return overlay;
}
+QQuickOverlayAttached *QQuickOverlay::qmlAttachedProperties(QObject *object)
+{
+ return new QQuickOverlayAttached(object);
+}
+
void QQuickOverlay::itemChange(ItemChange change, const ItemChangeData &data)
{
Q_D(QQuickOverlay);
@@ -490,4 +532,149 @@ bool QQuickOverlay::eventFilter(QObject *object, QEvent *event)
return false;
}
+class QQuickOverlayAttachedPrivate : public QObjectPrivate
+{
+ Q_DECLARE_PUBLIC(QQuickOverlayAttached)
+
+public:
+ QQuickOverlayAttachedPrivate()
+ : window(nullptr),
+ modal(nullptr),
+ modeless(nullptr)
+ {
+ }
+
+ void setWindow(QQuickWindow *newWindow);
+
+ QQuickWindow *window;
+ QQmlComponent *modal;
+ QQmlComponent *modeless;
+};
+
+void QQuickOverlayAttachedPrivate::setWindow(QQuickWindow *newWindow)
+{
+ Q_Q(QQuickOverlayAttached);
+ if (window == newWindow)
+ return;
+
+ if (QQuickOverlay *oldOverlay = QQuickOverlay::overlay(window)) {
+ QObject::disconnect(oldOverlay, &QQuickOverlay::pressed, q, &QQuickOverlayAttached::pressed);
+ QObject::disconnect(oldOverlay, &QQuickOverlay::released, q, &QQuickOverlayAttached::released);
+ }
+
+ if (QQuickOverlay *newOverlay = QQuickOverlay::overlay(newWindow)) {
+ QObject::connect(newOverlay, &QQuickOverlay::pressed, q, &QQuickOverlayAttached::pressed);
+ QObject::connect(newOverlay, &QQuickOverlay::released, q, &QQuickOverlayAttached::released);
+ }
+
+ window = newWindow;
+ emit q->overlayChanged();
+}
+
+/*!
+ \qmlattachedsignal QtQuick.Controls::Overlay::pressed()
+
+ This attached signal is emitted when the overlay is pressed by the user while
+ a popup is visible.
+
+ The signal can be attached to any item, popup, or window. When attached to an
+ item or a popup, the signal is only emitted if the item or popup is in a window.
+*/
+
+/*!
+ \qmlattachedsignal QtQuick.Controls::Overlay::released()
+
+ This attached signal is emitted when the overlay is released by the user while
+ a popup is visible.
+
+ The signal can be attached to any item, popup, or window. When attached to an
+ item or a popup, the signal is only emitted if the item or popup is in a window.
+*/
+
+QQuickOverlayAttached::QQuickOverlayAttached(QObject *parent)
+ : QObject(*(new QQuickOverlayAttachedPrivate), parent)
+{
+ Q_D(QQuickOverlayAttached);
+ if (QQuickItem *item = qobject_cast<QQuickItem *>(parent)) {
+ d->setWindow(item->window());
+ QObjectPrivate::connect(item, &QQuickItem::windowChanged, d, &QQuickOverlayAttachedPrivate::setWindow);
+ } else if (QQuickPopup *popup = qobject_cast<QQuickPopup *>(parent)) {
+ d->setWindow(popup->window());
+ QObjectPrivate::connect(popup, &QQuickPopup::windowChanged, d, &QQuickOverlayAttachedPrivate::setWindow);
+ } else {
+ d->setWindow(qobject_cast<QQuickWindow *>(parent));
+ }
+}
+
+/*!
+ \qmlattachedproperty Overlay QtQuick.Controls::Overlay::overlay
+ \readonly
+
+ This attached property holds the window overlay item.
+
+ The property can be attached to any item, popup, or window. When attached to an
+ item or a popup, the value is \c null if the item or popup is not in a window.
+*/
+QQuickOverlay *QQuickOverlayAttached::overlay() const
+{
+ Q_D(const QQuickOverlayAttached);
+ return QQuickOverlay::overlay(d->window);
+}
+
+/*!
+ \qmlattachedproperty Component QtQuick.Controls::Overlay::modal
+
+ This attached property holds a component to use as a visual item that implements
+ background dimming for modal popups. It is created for and stacked below visible
+ modal popups.
+
+ The property can be attached to any popup.
+
+ \sa Popup::modal
+*/
+QQmlComponent *QQuickOverlayAttached::modal() const
+{
+ Q_D(const QQuickOverlayAttached);
+ return d->modal;
+}
+
+void QQuickOverlayAttached::setModal(QQmlComponent *modal)
+{
+ Q_D(QQuickOverlayAttached);
+ if (d->modal == modal)
+ return;
+
+ delete d->modal;
+ d->modal = modal;
+ emit modalChanged();
+}
+
+/*!
+ \qmlattachedproperty Component QtQuick.Controls::Overlay::modeless
+
+ This attached property holds a component to use as a visual item that implements
+ background dimming for modeless popups. It is created for and stacked below visible
+ dimming popups.
+
+ The property can be attached to any popup.
+
+ \sa Popup::dim
+*/
+QQmlComponent *QQuickOverlayAttached::modeless() const
+{
+ Q_D(const QQuickOverlayAttached);
+ return d->modeless;
+}
+
+void QQuickOverlayAttached::setModeless(QQmlComponent *modeless)
+{
+ Q_D(QQuickOverlayAttached);
+ if (d->modeless == modeless)
+ return;
+
+ delete d->modeless;
+ d->modeless = modeless;
+ emit modelessChanged();
+}
+
QT_END_NAMESPACE
diff --git a/src/quicktemplates2/qquickoverlay_p.h b/src/quicktemplates2/qquickoverlay_p.h
index ba61c9c9..0d8bccf5 100644
--- a/src/quicktemplates2/qquickoverlay_p.h
+++ b/src/quicktemplates2/qquickoverlay_p.h
@@ -55,6 +55,8 @@ QT_BEGIN_NAMESPACE
class QQmlComponent;
class QQuickOverlayPrivate;
+class QQuickOverlayAttached;
+class QQuickOverlayAttachedPrivate;
class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickOverlay : public QQuickItem
{
@@ -74,6 +76,8 @@ public:
static QQuickOverlay *overlay(QQuickWindow *window);
+ static QQuickOverlayAttached *qmlAttachedProperties(QObject *object);
+
Q_SIGNALS:
void modalChanged();
void modelessChanged();
@@ -101,8 +105,39 @@ private:
Q_DECLARE_PRIVATE(QQuickOverlay)
};
+class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickOverlayAttached : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(QQuickOverlay *overlay READ overlay NOTIFY overlayChanged FINAL)
+ Q_PROPERTY(QQmlComponent *modal READ modal WRITE setModal NOTIFY modalChanged FINAL)
+ Q_PROPERTY(QQmlComponent *modeless READ modeless WRITE setModeless NOTIFY modelessChanged FINAL)
+
+public:
+ explicit QQuickOverlayAttached(QObject *parent = nullptr);
+
+ QQuickOverlay *overlay() const;
+
+ QQmlComponent *modal() const;
+ void setModal(QQmlComponent *modal);
+
+ QQmlComponent *modeless() const;
+ void setModeless(QQmlComponent *modeless);
+
+Q_SIGNALS:
+ void overlayChanged();
+ void modalChanged();
+ void modelessChanged();
+ void pressed();
+ void released();
+
+private:
+ Q_DISABLE_COPY(QQuickOverlayAttached)
+ Q_DECLARE_PRIVATE(QQuickOverlayAttached)
+};
+
QT_END_NAMESPACE
QML_DECLARE_TYPE(QQuickOverlay)
+QML_DECLARE_TYPEINFO(QQuickOverlay, QML_HAS_ATTACHED_PROPERTIES)
#endif // QQUICKOVERLAY_P_H
diff --git a/src/quicktemplates2/qquickpopup.cpp b/src/quicktemplates2/qquickpopup.cpp
index 1ccd1040..38ca6edf 100644
--- a/src/quicktemplates2/qquickpopup.cpp
+++ b/src/quicktemplates2/qquickpopup.cpp
@@ -655,8 +655,16 @@ void QQuickPopupPrivate::createOverlay()
if (!overlay)
return;
+ QQmlComponent *component = nullptr;
+ QQuickOverlayAttached *overlayAttached = qobject_cast<QQuickOverlayAttached *>(qmlAttachedPropertiesObject<QQuickOverlay>(q, false));
+ if (overlayAttached)
+ component = modal ? overlayAttached->modal() : overlayAttached->modeless();
+
+ if (!component)
+ component = modal ? overlay->modal() : overlay->modeless();
+
if (!dimmer)
- dimmer = createDimmer(modal ? overlay->modal() : overlay->modeless(), q, overlay);
+ dimmer = createDimmer(component, q, overlay);
resizeOverlay();
}
diff --git a/tests/auto/controls/data/tst_drawer.qml b/tests/auto/controls/data/tst_drawer.qml
index 11a57e2f..617e7677 100644
--- a/tests/auto/controls/data/tst_drawer.qml
+++ b/tests/auto/controls/data/tst_drawer.qml
@@ -50,7 +50,7 @@
import QtQuick 2.2
import QtTest 1.0
-import QtQuick.Controls 2.2
+import QtQuick.Controls 2.3
TestCase {
id: testCase
@@ -70,7 +70,7 @@ TestCase {
compare(control.edge, Qt.LeftEdge)
compare(control.position, 0.0)
compare(control.dragMargin, Qt.styleHints.startDragDistance)
- compare(control.parent, ApplicationWindow.overlay)
+ compare(control.parent, Overlay.overlay)
}
Component {
diff --git a/tests/auto/controls/data/tst_popup.qml b/tests/auto/controls/data/tst_popup.qml
index c8b3985c..296d026d 100644
--- a/tests/auto/controls/data/tst_popup.qml
+++ b/tests/auto/controls/data/tst_popup.qml
@@ -50,8 +50,8 @@
import QtQuick 2.4
import QtTest 1.0
-import QtQuick.Controls 2.2
-import QtQuick.Templates 2.2 as T
+import QtQuick.Controls 2.3
+import QtQuick.Templates 2.3 as T
TestCase {
id: testCase
@@ -1069,6 +1069,7 @@ TestCase {
tryCompare(window, "active", true)
compare(window.overlay.children.length, 0)
+ compare(window.overlay, window.Overlay.overlay)
var firstOverlay = findOverlay(window, window.firstDrawer)
verify(!firstOverlay)
diff --git a/tests/auto/popup/tst_popup.cpp b/tests/auto/popup/tst_popup.cpp
index 0193b769..48295e10 100644
--- a/tests/auto/popup/tst_popup.cpp
+++ b/tests/auto/popup/tst_popup.cpp
@@ -216,6 +216,15 @@ void tst_popup::overlay()
QQuickPopup *popup = window->property("popup").value<QQuickPopup*>();
QVERIFY(popup);
+ QQuickOverlayAttached *overlayAttached = qobject_cast<QQuickOverlayAttached *>(qmlAttachedPropertiesObject<QQuickOverlay>(popup));
+ QVERIFY(overlayAttached);
+ QCOMPARE(overlayAttached->overlay(), overlay);
+
+ QSignalSpy overlayAttachedPressedSignal(overlayAttached, SIGNAL(pressed()));
+ QSignalSpy overlayAttachedReleasedSignal(overlayAttached, SIGNAL(released()));
+ QVERIFY(overlayAttachedPressedSignal.isValid());
+ QVERIFY(overlayAttachedReleasedSignal.isValid());
+
QQuickButton *button = window->property("button").value<QQuickButton*>();
QVERIFY(button);
@@ -229,10 +238,14 @@ void tst_popup::overlay()
QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, QPoint(1, 1));
QCOMPARE(overlayPressedSignal.count(), ++overlayPressCount);
QCOMPARE(overlayReleasedSignal.count(), overlayReleaseCount);
+ QCOMPARE(overlayAttachedPressedSignal.count(), overlayPressCount);
+ QCOMPARE(overlayAttachedReleasedSignal.count(), overlayReleaseCount);
QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, QPoint(1, 1));
QCOMPARE(overlayPressedSignal.count(), overlayPressCount);
QCOMPARE(overlayReleasedSignal.count(), overlayReleaseCount); // no modal-popups open
+ QCOMPARE(overlayAttachedPressedSignal.count(), overlayPressCount);
+ QCOMPARE(overlayAttachedReleasedSignal.count(), overlayReleaseCount);
popup->close();
QVERIFY(!popup->isVisible());
@@ -250,10 +263,14 @@ void tst_popup::overlay()
QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, QPoint(1, 1));
QCOMPARE(overlayPressedSignal.count(), ++overlayPressCount);
QCOMPARE(overlayReleasedSignal.count(), overlayReleaseCount);
+ QCOMPARE(overlayAttachedPressedSignal.count(), overlayPressCount);
+ QCOMPARE(overlayAttachedReleasedSignal.count(), overlayReleaseCount);
QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, QPoint(1, 1));
QCOMPARE(overlayPressedSignal.count(), overlayPressCount);
QCOMPARE(overlayReleasedSignal.count(), ++overlayReleaseCount);
+ QCOMPARE(overlayAttachedPressedSignal.count(), overlayPressCount);
+ QCOMPARE(overlayAttachedReleasedSignal.count(), overlayReleaseCount);
QVERIFY(!popup->isVisible());
QCOMPARE(overlay->isVisible(), popup->isVisible());
@@ -279,10 +296,14 @@ void tst_popup::overlay()
QTest::touchEvent(window, device.data()).press(0, QPoint(1, 1));
QCOMPARE(overlayPressedSignal.count(), ++overlayPressCount);
QCOMPARE(overlayReleasedSignal.count(), overlayReleaseCount);
+ QCOMPARE(overlayAttachedPressedSignal.count(), overlayPressCount);
+ QCOMPARE(overlayAttachedReleasedSignal.count(), overlayReleaseCount);
QTest::touchEvent(window, device.data()).release(0, QPoint(1, 1));
QCOMPARE(overlayPressedSignal.count(), overlayPressCount);
QCOMPARE(overlayReleasedSignal.count(), ++overlayReleaseCount);
+ QCOMPARE(overlayAttachedPressedSignal.count(), overlayPressCount);
+ QCOMPARE(overlayAttachedReleasedSignal.count(), overlayReleaseCount);
QVERIFY(!popup->isVisible());
QCOMPARE(overlay->isVisible(), popup->isVisible());