aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJ-P Nurmi <jpnurmi@qt.io>2016-04-25 08:41:40 +0200
committerJ-P Nurmi <jpnurmi@qt.io>2016-04-27 12:44:44 +0000
commit3d6d026602cf9a6ccc35655347c2ed6267bbc49f (patch)
treebbf7b3e017d50b5c6e3cbb425c279b9d2f6da4b5 /src
parent3851ae607c6bb1b77bde99172ebd8a1ff6929c39 (diff)
Popup: separate modal and modeless background dimming
iOS generally has white popups on white background, so it must dim the overlay background also for modeless popups to make them stand out. Make it possible to have modal and modeless background dimming separately, because both might be visible at the same time (eg. in Gallery settings). Change-Id: Id990675c8d06ceb8f8a26e6505d4bd020069f297 Reviewed-by: Mitch Curtis <mitch.curtis@theqtcompany.com>
Diffstat (limited to 'src')
-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
10 files changed, 177 insertions, 45 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;