diff options
author | J-P Nurmi <jpnurmi@qt.io> | 2017-06-01 14:44:53 +0200 |
---|---|---|
committer | J-P Nurmi <jpnurmi@qt.io> | 2017-06-26 15:35:25 +0000 |
commit | d0fdebbc378f2d5c1993eee56b63e27bcff04ca5 (patch) | |
tree | 848f544ac0b1575751c679f2860f6b345003f398 /src/quicktemplates2 | |
parent | 5dfa85e68c6a9fc3fbedb47737dd34c843e2ba2b (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/quicktemplates2')
-rw-r--r-- | src/quicktemplates2/qquickapplicationwindow.cpp | 41 | ||||
-rw-r--r-- | src/quicktemplates2/qquickoverlay.cpp | 187 | ||||
-rw-r--r-- | src/quicktemplates2/qquickoverlay_p.h | 35 | ||||
-rw-r--r-- | src/quicktemplates2/qquickpopup.cpp | 10 |
4 files changed, 242 insertions, 31 deletions
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(); } |