aboutsummaryrefslogtreecommitdiffstats
path: root/src/templates/qquickoverlay.cpp
diff options
context:
space:
mode:
authorGabriel de Dietrich <gabriel.dedietrich@theqtcompany.com>2015-07-20 17:40:25 +0200
committerJ-P Nurmi <jpnurmi@theqtcompany.com>2015-11-14 00:33:00 +0000
commit0a0902b10d3135b0697741cc9b1f5b1b318eeb1f (patch)
tree4e1eb3116bc1caa7e221970349a130864c0d24d8 /src/templates/qquickoverlay.cpp
parent4cd3cd7cbec2a6713ba146b7036652f6916cab1e (diff)
Introducing Panel type
This is the base type to implement all sorts of Popups and Dialogs. Its main role is to keep the panel contents stacked on top of the application window contents and to ensure mouse and key events are forwarded or blocked depending on the visible panels modality. Currently, it only works with ApplicationWindow, which holds a QQuickOverlay. This special item is where the Panel contents gets reparented when the Panel becomes visible. It's also responsible for filtering the mouse events. Future developements may include adding a 'level' property instead of relying on the item's z value. This may or may not result into having several overlays per window. Change-Id: I18a4b8905e4d5a4a4697642b0553a1f9e86b669f Reviewed-by: Gabriel de Dietrich <gabriel.dedietrich@theqtcompany.com> Reviewed-by: J-P Nurmi <jpnurmi@theqtcompany.com>
Diffstat (limited to 'src/templates/qquickoverlay.cpp')
-rw-r--r--src/templates/qquickoverlay.cpp150
1 files changed, 150 insertions, 0 deletions
diff --git a/src/templates/qquickoverlay.cpp b/src/templates/qquickoverlay.cpp
new file mode 100644
index 00000000..d786f3c7
--- /dev/null
+++ b/src/templates/qquickoverlay.cpp
@@ -0,0 +1,150 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Labs Templates module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qquickoverlay_p.h"
+#include "qquickpanel_p.h"
+#include <QtQml/qqmlinfo.h>
+#include <QtQuick/private/qquickitem_p.h>
+
+QT_BEGIN_NAMESPACE
+
+QQuickOverlay::QQuickOverlay(QQuickItem *parent)
+ : QQuickItem(parent), m_modalPanels(0)
+{
+ setAcceptedMouseButtons(Qt::AllButtons);
+ setFiltersChildMouseEvents(true);
+ setVisible(false);
+}
+
+void QQuickOverlay::itemChange(ItemChange change, const ItemChangeData &data)
+{
+ QQuickItem::itemChange(change, data);
+
+ QQuickItem *panelItem = const_cast<QQuickItem *>(data.item);
+ QQuickPanel *panel = Q_NULLPTR;
+ if (change == ItemChildAddedChange || change == ItemChildRemovedChange)
+ panel = qobject_cast<QQuickPanel *>(panelItem->parent());
+ if (!panel)
+ return;
+
+ if (change == ItemChildAddedChange) {
+ if (QQuickPanel *prevPanel = m_panels.value(panelItem)) {
+ qmlInfo(panel).nospace() << "Panel is sharing item " << panelItem << " with " << prevPanel
+ << ". This is not supported and strange things are about to happen.";
+ return;
+ }
+
+ m_panels.insert(panelItem, panel);
+ if (panel->isModal())
+ ++m_modalPanels;
+
+ connect(this, &QQuickOverlay::pressed, panel, &QQuickPanel::pressedOutside);
+ connect(this, &QQuickOverlay::released, panel, &QQuickPanel::releasedOutside);
+
+ if (!isVisible())
+ setVisible(true);
+ } else if (change == ItemChildRemovedChange) {
+ Q_ASSERT(panel == m_panels.value(panelItem));
+
+ disconnect(this, &QQuickOverlay::pressed, panel, &QQuickPanel::pressedOutside);
+ disconnect(this, &QQuickOverlay::released, panel, &QQuickPanel::releasedOutside);
+
+ if (panel->isModal())
+ --m_modalPanels;
+ m_panels.remove(panelItem);
+ if (m_panels.isEmpty())
+ setVisible(false);
+ }
+}
+
+void QQuickOverlay::keyPressEvent(QKeyEvent *event)
+{
+ event->setAccepted(m_modalPanels > 0);
+}
+
+void QQuickOverlay::keyReleaseEvent(QKeyEvent *event)
+{
+ event->setAccepted(m_modalPanels > 0);
+}
+
+void QQuickOverlay::mousePressEvent(QMouseEvent *event)
+{
+ event->setAccepted(m_modalPanels > 0);
+ emit pressed();
+}
+
+void QQuickOverlay::mouseMoveEvent(QMouseEvent *event)
+{
+ event->setAccepted(m_modalPanels > 0);
+}
+
+void QQuickOverlay::mouseReleaseEvent(QMouseEvent *event)
+{
+ event->setAccepted(m_modalPanels > 0);
+ emit released();
+}
+
+bool QQuickOverlay::childMouseEventFilter(QQuickItem *item, QEvent *event)
+{
+ if (m_modalPanels == 0)
+ return false;
+ // TODO Filter touch events
+ if (event->type() != QEvent::MouseButtonPress)
+ return false;
+ while (item->parentItem() != this)
+ item = item->parentItem();
+
+ bool modalBlocked = false;
+ const QQuickItemPrivate *priv = QQuickItemPrivate::get(this);
+ const QList<QQuickItem *> &sortedChildren = priv->paintOrderChildItems();
+ for (int i = sortedChildren.count() - 1; i >= 0; --i) {
+ QQuickItem *panelItem = sortedChildren[i];
+ if (panelItem == item)
+ break;
+
+ QQuickPanel *panel = m_panels.value(panelItem);
+ if (panel) {
+ emit panel->pressedOutside();
+
+ if (!modalBlocked && panel->isModal())
+ modalBlocked = true;
+ }
+ }
+
+ return modalBlocked;
+}
+
+QT_END_NAMESPACE