aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/imports/controls/ApplicationWindow.qml6
-rw-r--r--src/imports/controls/material/ApplicationWindow.qml7
-rw-r--r--src/imports/controls/universal/ApplicationWindow.qml6
-rw-r--r--src/imports/templates/plugins.qmltypes4
-rw-r--r--src/quicktemplates2/qquickapplicationwindow.cpp25
-rw-r--r--src/quicktemplates2/qquickoverlay.cpp108
-rw-r--r--src/quicktemplates2/qquickoverlay_p.h13
-rw-r--r--src/quicktemplates2/qquickpopup.cpp45
-rw-r--r--src/quicktemplates2/qquickpopup_p.h6
-rw-r--r--src/quicktemplates2/qquickpopup_p_p.h2
-rw-r--r--tests/auto/controls/data/tst_popup.qml55
11 files changed, 215 insertions, 62 deletions
diff --git a/src/imports/controls/ApplicationWindow.qml b/src/imports/controls/ApplicationWindow.qml
index cc30c601..98de8946 100644
--- a/src/imports/controls/ApplicationWindow.qml
+++ b/src/imports/controls/ApplicationWindow.qml
@@ -43,7 +43,11 @@ T.ApplicationWindow {
color: "#ffffff"
- overlay.background: Rectangle {
+ overlay.modal: Rectangle {
color: "#7f28282a"
}
+
+ overlay.modeless: Rectangle {
+ color: "#1f28282a"
+ }
}
diff --git a/src/imports/controls/material/ApplicationWindow.qml b/src/imports/controls/material/ApplicationWindow.qml
index a09cd89f..db27f25b 100644
--- a/src/imports/controls/material/ApplicationWindow.qml
+++ b/src/imports/controls/material/ApplicationWindow.qml
@@ -44,7 +44,12 @@ T.ApplicationWindow {
color: Material.backgroundColor
- overlay.background: Rectangle {
+ overlay.modal: Rectangle {
+ color: window.Material.backgroundDimColor
+ Behavior on opacity { NumberAnimation { duration: 150 } }
+ }
+
+ overlay.modeless: Rectangle {
color: window.Material.backgroundDimColor
Behavior on opacity { NumberAnimation { duration: 150 } }
}
diff --git a/src/imports/controls/universal/ApplicationWindow.qml b/src/imports/controls/universal/ApplicationWindow.qml
index 664229a3..70bd403c 100644
--- a/src/imports/controls/universal/ApplicationWindow.qml
+++ b/src/imports/controls/universal/ApplicationWindow.qml
@@ -44,7 +44,11 @@ T.ApplicationWindow {
color: Universal.background
- overlay.background: Rectangle {
+ overlay.modal: Rectangle {
+ color: window.Universal.baseLowColor
+ }
+
+ overlay.modeless: Rectangle {
color: window.Universal.baseLowColor
}
diff --git a/src/imports/templates/plugins.qmltypes b/src/imports/templates/plugins.qmltypes
index af573750..b4155841 100644
--- a/src/imports/templates/plugins.qmltypes
+++ b/src/imports/templates/plugins.qmltypes
@@ -491,7 +491,8 @@ Module {
name: "QQuickOverlay"
defaultProperty: "data"
prototype: "QQuickItem"
- Property { name: "background"; type: "QQuickItem"; isPointer: true }
+ Property { name: "modal"; type: "QQuickItem"; isPointer: true }
+ Property { name: "modeless"; type: "QQuickItem"; isPointer: true }
Signal { name: "pressed" }
Signal { name: "released" }
}
@@ -591,6 +592,7 @@ Module {
Property { name: "focus"; type: "bool" }
Property { name: "activeFocus"; type: "bool"; isReadonly: true }
Property { name: "modal"; type: "bool" }
+ Property { name: "dim"; type: "bool" }
Property { name: "visible"; type: "bool" }
Property { name: "opacity"; type: "double" }
Property { name: "scale"; type: "double" }
diff --git a/src/quicktemplates2/qquickapplicationwindow.cpp b/src/quicktemplates2/qquickapplicationwindow.cpp
index 7191d57f..1611ebaf 100644
--- a/src/quicktemplates2/qquickapplicationwindow.cpp
+++ b/src/quicktemplates2/qquickapplicationwindow.cpp
@@ -446,13 +446,30 @@ QQuickItem *QQuickApplicationWindow::activeFocusControl() const
/*!
\qmlpropertygroup QtQuick.Controls::ApplicationWindow::overlay
\qmlproperty Item QtQuick.Controls::ApplicationWindow::overlay
- \qmlproperty Item QtQuick.Controls::ApplicationWindow::overlay.background
+ \qmlproperty Item QtQuick.Controls::ApplicationWindow::overlay.modal
+ \qmlproperty Item QtQuick.Controls::ApplicationWindow::overlay.modeless
- This property holds the window overlay item and its background that implements the
- background dimming when any modal popups are open. Popups are automatically
+ This property holds the window overlay item. Popups are automatically
reparented to the overlay.
- \sa Popup
+ \table
+ \header
+ \li Property
+ \li Description
+ \row
+ \li overlay.modal
+ \li This property holds a visual item that implements background
+ dimming for modal popups. It is stacked below the top-most open
+ modal popup, or hidden when there are no modal popups open.
+ \row
+ \li overlay.modeless
+ \li This property holds a visual item that implements background
+ dimming for modeless popups. It is stacked below the top-most
+ open modeless dimming popup, or hidden when there are no modeless
+ dimming popups open.
+ \endtable
+
+ \sa Popup::modal, Popup::dim
*/
QQuickOverlay *QQuickApplicationWindow::overlay() const
{
diff --git a/src/quicktemplates2/qquickoverlay.cpp b/src/quicktemplates2/qquickoverlay.cpp
index 07db8d27..24d10e9c 100644
--- a/src/quicktemplates2/qquickoverlay.cpp
+++ b/src/quicktemplates2/qquickoverlay.cpp
@@ -53,9 +53,10 @@ public:
void popupAboutToShow();
void popupAboutToHide();
void drawerPositionChange();
- void resizeBackground();
+ void resizeOverlay(QQuickItem *overlay);
- QQuickItem *background;
+ QQuickItem *modal;
+ QQuickItem *modeless;
QVector<QQuickDrawer *> drawers;
QVector<QQuickPopup *> popups;
QPointer<QQuickPopup> mouseGrabberPopup;
@@ -65,52 +66,71 @@ public:
void QQuickOverlayPrivate::popupAboutToShow()
{
Q_Q(QQuickOverlay);
- if (!background)
- return;
-
QQuickPopup *popup = qobject_cast<QQuickPopup *>(q->sender());
- if (!popup || !popup->isModal())
+ if (!popup)
return;
// use QQmlProperty instead of QQuickItem::setOpacity() to trigger QML Behaviors
- QQmlProperty::write(background, QStringLiteral("opacity"), 1.0);
+ if (popup->isModal()) {
+ if (modal) {
+ modal->setZ(popup->z());
+ modal->stackBefore(popup->popupItem());
+ QQmlProperty::write(modal, QStringLiteral("opacity"), 1.0);
+ }
+ } else if (popup->dim()) {
+ if (modeless) {
+ modeless->setZ(popup->z());
+ modeless->stackBefore(popup->popupItem());
+ QQmlProperty::write(modeless, QStringLiteral("opacity"), 1.0);
+ }
+ }
}
void QQuickOverlayPrivate::popupAboutToHide()
{
Q_Q(QQuickOverlay);
- if (!background || modalPopups > 1)
- return;
-
QQuickPopup *popup = qobject_cast<QQuickPopup *>(q->sender());
- if (!popup || !popup->isModal())
+ if (!popup)
return;
// use QQmlProperty instead of QQuickItem::setOpacity() to trigger QML Behaviors
- QQmlProperty::write(background, QStringLiteral("opacity"), 0.0);
+ if (popup->isModal()) {
+ if (modal && modalPopups <= 1)
+ QQmlProperty::write(modal, QStringLiteral("opacity"), 0.0);
+ } else if (popup->dim()) {
+ if (modeless)
+ QQmlProperty::write(modeless, QStringLiteral("opacity"), 0.0);
+ }
}
void QQuickOverlayPrivate::drawerPositionChange()
{
Q_Q(QQuickOverlay);
QQuickDrawer *drawer = qobject_cast<QQuickDrawer *>(q->sender());
- if (!background || !drawer || !drawer->isModal())
+ if (!drawer)
return;
// call QQuickItem::setOpacity() directly to avoid triggering QML Behaviors
// which would make the fading feel laggy compared to the drawer movement
- background->setOpacity(drawer->position());
+ if (drawer->isModal()) {
+ if (modal)
+ modal->setOpacity(drawer->position());
+ } else if (drawer->dim()) {
+ if (modeless)
+ modeless->setOpacity(drawer->position());
+ }
}
-void QQuickOverlayPrivate::resizeBackground()
+void QQuickOverlayPrivate::resizeOverlay(QQuickItem *overlay)
{
Q_Q(QQuickOverlay);
- background->setWidth(q->width());
- background->setHeight(q->height());
+ overlay->setWidth(q->width());
+ overlay->setHeight(q->height());
}
QQuickOverlayPrivate::QQuickOverlayPrivate() :
- background(nullptr),
+ modal(nullptr),
+ modeless(nullptr),
modalPopups(0)
{
}
@@ -123,30 +143,50 @@ QQuickOverlay::QQuickOverlay(QQuickItem *parent)
setVisible(false);
}
+QQuickItem *QQuickOverlay::modal() const
+{
+ Q_D(const QQuickOverlay);
+ return d->modal;
+}
+
+void QQuickOverlay::setModal(QQuickItem *modal)
+{
+ Q_D(QQuickOverlay);
+ if (d->modal == modal)
+ return;
+
+ delete d->modal;
+ d->modal = modal;
+ if (modal) {
+ modal->setOpacity(0.0);
+ modal->setParentItem(this);
+ if (isComponentComplete())
+ d->resizeOverlay(modal);
+ }
+ emit modalChanged();
+}
-QQuickItem *QQuickOverlay::background() const
+QQuickItem *QQuickOverlay::modeless() const
{
Q_D(const QQuickOverlay);
- return d->background;
+ return d->modeless;
}
-void QQuickOverlay::setBackground(QQuickItem *background)
+void QQuickOverlay::setModeless(QQuickItem *modeless)
{
Q_D(QQuickOverlay);
- if (d->background == background)
+ if (d->modeless == modeless)
return;
- delete d->background;
- d->background = background;
- if (background) {
- background->setOpacity(0.0);
- background->setParentItem(this);
- if (qFuzzyIsNull(background->z()))
- background->setZ(-1);
+ delete d->modeless;
+ d->modeless = modeless;
+ if (modeless) {
+ modeless->setOpacity(0.0);
+ modeless->setParentItem(this);
if (isComponentComplete())
- d->resizeBackground();
+ d->resizeOverlay(modeless);
}
- emit backgroundChanged();
+ emit modelessChanged();
}
void QQuickOverlay::itemChange(ItemChange change, const ItemChangeData &data)
@@ -197,8 +237,10 @@ void QQuickOverlay::geometryChanged(const QRectF &newGeometry, const QRectF &old
{
Q_D(QQuickOverlay);
QQuickItem::geometryChanged(newGeometry, oldGeometry);
- if (d->background)
- d->resizeBackground();
+ if (d->modal)
+ d->resizeOverlay(d->modal);
+ if (d->modeless)
+ d->resizeOverlay(d->modeless);
}
bool QQuickOverlay::event(QEvent *event)
diff --git a/src/quicktemplates2/qquickoverlay_p.h b/src/quicktemplates2/qquickoverlay_p.h
index 78916036..4b6cb9c7 100644
--- a/src/quicktemplates2/qquickoverlay_p.h
+++ b/src/quicktemplates2/qquickoverlay_p.h
@@ -58,16 +58,21 @@ class QQuickOverlayPrivate;
class Q_QUICKTEMPLATES2_EXPORT QQuickOverlay : public QQuickItem
{
Q_OBJECT
- Q_PROPERTY(QQuickItem *background READ background WRITE setBackground NOTIFY backgroundChanged FINAL)
+ Q_PROPERTY(QQuickItem *modal READ modal WRITE setModal NOTIFY modalChanged FINAL)
+ Q_PROPERTY(QQuickItem *modeless READ modeless WRITE setModeless NOTIFY modelessChanged FINAL)
public:
explicit QQuickOverlay(QQuickItem *parent = nullptr);
- QQuickItem *background() const;
- void setBackground(QQuickItem *background);
+ QQuickItem *modal() const;
+ void setModal(QQuickItem *modal);
+
+ QQuickItem *modeless() const;
+ void setModeless(QQuickItem *modeless);
Q_SIGNALS:
- void backgroundChanged();
+ void modalChanged();
+ void modelessChanged();
void pressed();
void released();
diff --git a/src/quicktemplates2/qquickpopup.cpp b/src/quicktemplates2/qquickpopup.cpp
index 13e562d0..5b10bb12 100644
--- a/src/quicktemplates2/qquickpopup.cpp
+++ b/src/quicktemplates2/qquickpopup.cpp
@@ -121,6 +121,8 @@ QQuickPopupPrivate::QQuickPopupPrivate()
: QObjectPrivate()
, focus(false)
, modal(false)
+ , dim(false)
+ , hasDim(false)
, visible(false)
, complete(false)
, hasTopMargin(false)
@@ -1520,6 +1522,49 @@ void QQuickPopup::setModal(bool modal)
return;
d->modal = modal;
emit modalChanged();
+
+ if (!d->hasDim) {
+ setDim(modal);
+ d->hasDim = false;
+ }
+}
+
+/*!
+ \qmlproperty bool QtQuick.Controls::Popup::dim
+
+ This property holds whether the popup dims the background.
+
+ Unless explicitly set, this property follows the value of \l modal. To
+ return to the default value, set this property to \c undefined.
+
+ \sa modal
+*/
+bool QQuickPopup::dim() const
+{
+ Q_D(const QQuickPopup);
+ return d->dim;
+}
+
+void QQuickPopup::setDim(bool dim)
+{
+ Q_D(QQuickPopup);
+ d->hasDim = true;
+
+ if (d->dim == dim)
+ return;
+
+ d->dim = dim;
+ emit dimChanged();
+}
+
+void QQuickPopup::resetDim()
+{
+ Q_D(QQuickPopup);
+ if (!d->hasDim)
+ return;
+
+ setDim(d->modal);
+ d->hasDim = false;
}
/*!
diff --git a/src/quicktemplates2/qquickpopup_p.h b/src/quicktemplates2/qquickpopup_p.h
index e1219a2c..27123ae5 100644
--- a/src/quicktemplates2/qquickpopup_p.h
+++ b/src/quicktemplates2/qquickpopup_p.h
@@ -105,6 +105,7 @@ class Q_QUICKTEMPLATES2_EXPORT QQuickPopup : public QObject, public QQmlParserSt
Q_PROPERTY(bool focus READ hasFocus WRITE setFocus NOTIFY focusChanged FINAL)
Q_PROPERTY(bool activeFocus READ hasActiveFocus NOTIFY activeFocusChanged FINAL)
Q_PROPERTY(bool modal READ isModal WRITE setModal NOTIFY modalChanged FINAL)
+ Q_PROPERTY(bool dim READ dim WRITE setDim RESET resetDim NOTIFY dimChanged FINAL)
Q_PROPERTY(bool visible READ isVisible WRITE setVisible NOTIFY visibleChanged FINAL)
Q_PROPERTY(qreal opacity READ opacity WRITE setOpacity NOTIFY opacityChanged FINAL)
Q_PROPERTY(qreal scale READ scale WRITE setScale NOTIFY scaleChanged FINAL)
@@ -227,6 +228,10 @@ public:
bool isModal() const;
void setModal(bool modal);
+ bool dim() const;
+ void setDim(bool dim);
+ void resetDim();
+
bool isVisible() const;
void setVisible(bool visible);
@@ -306,6 +311,7 @@ Q_SIGNALS:
void focusChanged();
void activeFocusChanged();
void modalChanged();
+ void dimChanged();
void visibleChanged();
void opacityChanged();
void scaleChanged();
diff --git a/src/quicktemplates2/qquickpopup_p_p.h b/src/quicktemplates2/qquickpopup_p_p.h
index a765998a..7d367812 100644
--- a/src/quicktemplates2/qquickpopup_p_p.h
+++ b/src/quicktemplates2/qquickpopup_p_p.h
@@ -176,6 +176,8 @@ public:
bool focus;
bool modal;
+ bool dim;
+ bool hasDim;
bool visible;
bool complete;
bool hasTopMargin;
diff --git a/tests/auto/controls/data/tst_popup.qml b/tests/auto/controls/data/tst_popup.qml
index b63bc826..b28a31e8 100644
--- a/tests/auto/controls/data/tst_popup.qml
+++ b/tests/auto/controls/data/tst_popup.qml
@@ -869,17 +869,24 @@ TestCase {
Component {
id: overlayTest
ApplicationWindow {
- property alias popup1: popup1
- property alias popup2: popup2
+ property alias modalPopup: modalPopup
+ property alias modelessPopup: modelessPopup
+ property alias plainPopup: plainPopup
visible: true
Popup {
- id: popup1
+ id: modalPopup
modal: true
exit: Transition { PauseAnimation { duration: 200 } }
}
Popup {
- id: popup2
- modal: true
+ id: modelessPopup
+ dim: true
+ exit: Transition { PauseAnimation { duration: 200 } }
+ }
+ Popup {
+ id: plainPopup
+ enter: Transition { PauseAnimation { duration: 200 } }
+ exit: Transition { PauseAnimation { duration: 200 } }
}
}
}
@@ -890,18 +897,32 @@ TestCase {
window.requestActivate()
tryCompare(window, "active", true)
- compare(window.overlay.background.opacity, 0.0)
-
- window.popup1.open()
- compare(window.popup1.visible, true)
- compare(window.popup2.visible, false)
- tryCompare(window.overlay.background, "opacity", 1.0)
-
- window.popup1.close()
- window.popup2.open()
- compare(window.popup2.visible, true)
- tryCompare(window.popup1, "visible", false)
- compare(window.overlay.background.opacity, 1.0)
+ compare(window.overlay.modal.opacity, 0.0)
+ compare(window.overlay.modeless.opacity, 0.0)
+
+ window.modalPopup.open()
+ compare(window.modalPopup.visible, true)
+ tryCompare(window.overlay.modal, "opacity", 1.0)
+
+ window.modelessPopup.open()
+ compare(window.modelessPopup.visible, true)
+ tryCompare(window.overlay.modeless, "opacity", 1.0)
+
+ window.modelessPopup.close()
+ tryCompare(window.modelessPopup, "visible", false)
+ tryCompare(window.overlay.modeless, "opacity", 0.0)
+
+ compare(window.modalPopup.visible, true)
+ compare(window.overlay.modal.opacity, 1.0)
+
+ window.modalPopup.close()
+ tryCompare(window.modalPopup, "visible", false)
+ tryCompare(window.overlay.modal, "opacity", 0.0)
+
+ window.plainPopup.open()
+ tryCompare(window.plainPopup, "visible", true)
+ compare(window.overlay.modal.opacity, 0.0)
+ compare(window.overlay.modeless.opacity, 0.0)
window.destroy()
}