aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJ-P Nurmi <jpnurmi@qt.io>2017-06-01 14:44:53 +0200
committerJ-P Nurmi <jpnurmi@qt.io>2017-06-26 15:35:25 +0000
commitd0fdebbc378f2d5c1993eee56b63e27bcff04ca5 (patch)
tree848f544ac0b1575751c679f2860f6b345003f398 /src
parent5dfa85e68c6a9fc3fbedb47737dd34c843e2ba2b (diff)
Add Overlay attached properties and signals
[ChangeLog][Controls][ApplicationWindow] Deprecated the overlay grouped property in favor of the newly introduced Overlay attached properties. [ChangeLog][Controls][Overlay] Introduced Overlay attached properties and signals that supersede the overlay grouped property in Application Window. The Overlay attached type allows providing background dimming for popups without requiring an ApplicationWindow instance. Task-number: QTBUG-61336 Change-Id: I9df11bcb167e7725014d5f058fe24d70da4a10b3 Reviewed-by: Topi Reiniƶ <topi.reinio@qt.io> Reviewed-by: Mitch Curtis <mitch.curtis@qt.io>
Diffstat (limited to 'src')
-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
22 files changed, 386 insertions, 35 deletions
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();
}