aboutsummaryrefslogtreecommitdiffstats
path: root/src/quicktemplates2/qquickoverlay.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/quicktemplates2/qquickoverlay.cpp')
-rw-r--r--src/quicktemplates2/qquickoverlay.cpp728
1 files changed, 0 insertions, 728 deletions
diff --git a/src/quicktemplates2/qquickoverlay.cpp b/src/quicktemplates2/qquickoverlay.cpp
deleted file mode 100644
index 6689d93c..00000000
--- a/src/quicktemplates2/qquickoverlay.cpp
+++ /dev/null
@@ -1,728 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the Qt Quick Templates 2 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 "qquickcontrol_p_p.h"
-#include "qquickoverlay_p.h"
-#include "qquickoverlay_p_p.h"
-#include "qquickpopupitem_p_p.h"
-#include "qquickpopup_p_p.h"
-#include "qquickdrawer_p.h"
-#include "qquickdrawer_p_p.h"
-#include "qquickapplicationwindow_p.h"
-#include <QtQml/qqmlinfo.h>
-#include <QtQml/qqmlproperty.h>
-#include <QtQml/qqmlcomponent.h>
-#include <algorithm>
-
-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.
-
- \include qquickoverlay-popup-parent.qdocinc
-
- \sa ApplicationWindow
-*/
-
-QList<QQuickPopup *> QQuickOverlayPrivate::stackingOrderPopups() const
-{
- const QList<QQuickItem *> children = paintOrderChildItems();
-
- QList<QQuickPopup *> popups;
- popups.reserve(children.count());
-
- for (auto it = children.crbegin(), end = children.crend(); it != end; ++it) {
- QQuickPopup *popup = qobject_cast<QQuickPopup *>((*it)->parent());
- if (popup)
- popups += popup;
- }
-
- return popups;
-}
-
-QList<QQuickDrawer *> QQuickOverlayPrivate::stackingOrderDrawers() const
-{
- QList<QQuickDrawer *> sorted(allDrawers);
- std::sort(sorted.begin(), sorted.end(), [](const QQuickDrawer *one, const QQuickDrawer *another) {
- return one->z() > another->z();
- });
- return sorted;
-}
-
-void QQuickOverlayPrivate::itemGeometryChanged(QQuickItem *, QQuickGeometryChange, const QRectF &)
-{
- updateGeometry();
-}
-
-bool QQuickOverlayPrivate::startDrag(QEvent *event, const QPointF &pos)
-{
- Q_Q(QQuickOverlay);
- if (allDrawers.isEmpty())
- return false;
-
- // don't start dragging a drawer if a modal popup overlay is blocking (QTBUG-60602)
- QQuickItem *item = q->childAt(pos.x(), pos.y());
- if (item) {
- const auto popups = stackingOrderPopups();
- for (QQuickPopup *popup : popups) {
- QQuickPopupPrivate *p = QQuickPopupPrivate::get(popup);
- if (p->dimmer == item && popup->isVisible() && popup->isModal())
- return false;
- }
- }
-
- const QList<QQuickDrawer *> drawers = stackingOrderDrawers();
- for (QQuickDrawer *drawer : drawers) {
- QQuickDrawerPrivate *p = QQuickDrawerPrivate::get(drawer);
- if (p->startDrag(event)) {
- setMouseGrabberPopup(drawer);
- return true;
- }
- }
-
- return false;
-}
-
-bool QQuickOverlayPrivate::handlePress(QQuickItem *source, QEvent *event, QQuickPopup *target)
-{
- if (target) {
- if (target->overlayEvent(source, event)) {
- setMouseGrabberPopup(target);
- return true;
- }
- return false;
- }
-
- switch (event->type()) {
- default: {
- if (mouseGrabberPopup)
- break;
-#if QT_CONFIG(quicktemplates2_multitouch)
- Q_FALLTHROUGH();
- case QEvent::TouchBegin:
- case QEvent::TouchUpdate:
- case QEvent::TouchEnd:
-#endif
- // allow non-modal popups to close themselves,
- // and non-dimming modal popups to block the event
- const auto popups = stackingOrderPopups();
- for (QQuickPopup *popup : popups) {
- if (popup->overlayEvent(source, event)) {
- setMouseGrabberPopup(popup);
- return true;
- }
- }
- break;
- }
- }
-
- event->ignore();
- return false;
-}
-
-bool QQuickOverlayPrivate::handleMove(QQuickItem *source, QEvent *event, QQuickPopup *target)
-{
- if (target)
- return target->overlayEvent(source, event);
- return false;
-}
-
-bool QQuickOverlayPrivate::handleRelease(QQuickItem *source, QEvent *event, QQuickPopup *target)
-{
- if (target) {
- setMouseGrabberPopup(nullptr);
- if (target->overlayEvent(source, event)) {
- setMouseGrabberPopup(nullptr);
- return true;
- }
- } else {
- const auto popups = stackingOrderPopups();
- for (QQuickPopup *popup : popups) {
- if (popup->overlayEvent(source, event))
- return true;
- }
- }
- return false;
-}
-
-bool QQuickOverlayPrivate::handleMouseEvent(QQuickItem *source, QMouseEvent *event, QQuickPopup *target)
-{
- switch (event->type()) {
- case QEvent::MouseButtonPress:
- if (!target && startDrag(event, event->scenePosition()))
- return true;
- return handlePress(source, event, target);
- case QEvent::MouseMove:
- return handleMove(source, event, target ? target : mouseGrabberPopup.data());
- case QEvent::MouseButtonRelease:
- return handleRelease(source, event, target ? target : mouseGrabberPopup.data());
- default:
- break;
- }
- return false;
-}
-
-bool QQuickOverlayPrivate::handleHoverEvent(QQuickItem *source, QHoverEvent *event, QQuickPopup *target)
-{
- switch (event->type()) {
- case QEvent::HoverEnter:
- case QEvent::HoverMove:
- case QEvent::HoverLeave:
- if (target)
- return target->overlayEvent(source, event);
- return false;
- default:
- Q_UNREACHABLE(); // function must only be called on hover events
- break;
- }
- return false;
-}
-
-#if QT_CONFIG(quicktemplates2_multitouch)
-bool QQuickOverlayPrivate::handleTouchEvent(QQuickItem *source, QTouchEvent *event, QQuickPopup *target)
-{
- bool handled = false;
- switch (event->type()) {
- case QEvent::TouchBegin:
- case QEvent::TouchUpdate:
- case QEvent::TouchEnd:
- for (const QTouchEvent::TouchPoint &point : event->points()) {
- switch (point.state()) {
- case QEventPoint::Pressed:
- if (!target && startDrag(event, point.scenePosition()))
- handled = true;
- else
- handled |= handlePress(source, event, target);
- break;
- case QEventPoint::Updated:
- handled |= handleMove(source, event, target ? target : mouseGrabberPopup.data());
- break;
- case QEventPoint::Released:
- handled |= handleRelease(source, event, target ? target : mouseGrabberPopup.data());
- break;
- default:
- break;
- }
- }
- break;
-
- default:
- break;
- }
-
- return handled;
-}
-#endif
-
-void QQuickOverlayPrivate::addPopup(QQuickPopup *popup)
-{
- Q_Q(QQuickOverlay);
- allPopups += popup;
- if (QQuickDrawer *drawer = qobject_cast<QQuickDrawer *>(popup)) {
- allDrawers += drawer;
- q->setVisible(!allDrawers.isEmpty() || !q->childItems().isEmpty());
- }
-}
-
-void QQuickOverlayPrivate::removePopup(QQuickPopup *popup)
-{
- Q_Q(QQuickOverlay);
- allPopups.removeOne(popup);
- if (allDrawers.removeOne(qobject_cast<QQuickDrawer *>(popup)))
- q->setVisible(!allDrawers.isEmpty() || !q->childItems().isEmpty());
-}
-
-void QQuickOverlayPrivate::setMouseGrabberPopup(QQuickPopup *popup)
-{
- if (popup && !popup->isVisible())
- popup = nullptr;
- mouseGrabberPopup = popup;
-}
-
-void QQuickOverlayPrivate::updateGeometry()
-{
- Q_Q(QQuickOverlay);
- if (!window)
- return;
-
- QPointF pos;
- QSizeF size = window->size();
- qreal rotation = 0;
-
- switch (window->contentOrientation()) {
- case Qt::PrimaryOrientation:
- case Qt::PortraitOrientation:
- size = window->size();
- break;
- case Qt::LandscapeOrientation:
- rotation = 90;
- pos = QPointF((size.width() - size.height()) / 2, -(size.width() - size.height()) / 2);
- size.transpose();
- break;
- case Qt::InvertedPortraitOrientation:
- rotation = 180;
- break;
- case Qt::InvertedLandscapeOrientation:
- rotation = 270;
- pos = QPointF((size.width() - size.height()) / 2, -(size.width() - size.height()) / 2);
- size.transpose();
- break;
- default:
- break;
- }
-
- q->setSize(size);
- q->setPosition(pos);
- q->setRotation(rotation);
-}
-
-QQuickOverlay::QQuickOverlay(QQuickItem *parent)
- : QQuickItem(*(new QQuickOverlayPrivate), parent)
-{
- Q_D(QQuickOverlay);
- setZ(1000001); // DefaultWindowDecoration+1
- setAcceptedMouseButtons(Qt::AllButtons);
-#if QT_CONFIG(quicktemplates2_multitouch)
- setAcceptTouchEvents(true);
-#endif
- setFiltersChildMouseEvents(true);
- setVisible(false);
-
- if (parent) {
- d->updateGeometry();
- QQuickItemPrivate::get(parent)->addItemChangeListener(d, QQuickItemPrivate::Geometry);
- if (QQuickWindow *window = parent->window()) {
- window->installEventFilter(this);
- QObjectPrivate::connect(window, &QWindow::contentOrientationChanged, d, &QQuickOverlayPrivate::updateGeometry);
- }
- }
-}
-
-QQuickOverlay::~QQuickOverlay()
-{
- Q_D(QQuickOverlay);
- if (QQuickItem *parent = parentItem())
- QQuickItemPrivate::get(parent)->removeItemChangeListener(d, QQuickItemPrivate::Geometry);
-}
-
-QQmlComponent *QQuickOverlay::modal() const
-{
- Q_D(const QQuickOverlay);
- return d->modal;
-}
-
-void QQuickOverlay::setModal(QQmlComponent *modal)
-{
- Q_D(QQuickOverlay);
- if (d->modal == modal)
- return;
-
- d->modal = modal;
- emit modalChanged();
-}
-
-QQmlComponent *QQuickOverlay::modeless() const
-{
- Q_D(const QQuickOverlay);
- return d->modeless;
-}
-
-void QQuickOverlay::setModeless(QQmlComponent *modeless)
-{
- Q_D(QQuickOverlay);
- if (d->modeless == modeless)
- return;
-
- d->modeless = modeless;
- emit modelessChanged();
-}
-
-QQuickOverlay *QQuickOverlay::overlay(QQuickWindow *window)
-{
- if (!window)
- return nullptr;
-
- const char *name = "_q_QQuickOverlay";
- QQuickOverlay *overlay = window->property(name).value<QQuickOverlay *>();
- if (!overlay) {
- QQuickItem *content = window->contentItem();
- // Do not re-create the overlay if the window is being destroyed
- // and thus, its content item no longer has a window associated.
- if (content && content->window()) {
- overlay = new QQuickOverlay(window->contentItem());
- window->setProperty(name, QVariant::fromValue(overlay));
- }
- }
- return overlay;
-}
-
-QQuickOverlayAttached *QQuickOverlay::qmlAttachedProperties(QObject *object)
-{
- return new QQuickOverlayAttached(object);
-}
-
-void QQuickOverlay::itemChange(ItemChange change, const ItemChangeData &data)
-{
- Q_D(QQuickOverlay);
- QQuickItem::itemChange(change, data);
-
- if (change == ItemChildAddedChange || change == ItemChildRemovedChange)
- setVisible(!d->allDrawers.isEmpty() || !childItems().isEmpty());
-}
-
-void QQuickOverlay::geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry)
-{
- Q_D(QQuickOverlay);
- QQuickItem::geometryChange(newGeometry, oldGeometry);
- for (QQuickPopup *popup : qAsConst(d->allPopups))
- QQuickPopupPrivate::get(popup)->resizeOverlay();
-}
-
-void QQuickOverlay::mousePressEvent(QMouseEvent *event)
-{
- Q_D(QQuickOverlay);
- d->handleMouseEvent(this, event);
-}
-
-void QQuickOverlay::mouseMoveEvent(QMouseEvent *event)
-{
- Q_D(QQuickOverlay);
- d->handleMouseEvent(this, event);
-}
-
-void QQuickOverlay::mouseReleaseEvent(QMouseEvent *event)
-{
- Q_D(QQuickOverlay);
- d->handleMouseEvent(this, event);
-}
-
-#if QT_CONFIG(quicktemplates2_multitouch)
-void QQuickOverlay::touchEvent(QTouchEvent *event)
-{
- Q_D(QQuickOverlay);
- d->handleTouchEvent(this, event);
-}
-#endif
-
-#if QT_CONFIG(wheelevent)
-void QQuickOverlay::wheelEvent(QWheelEvent *event)
-{
- Q_D(QQuickOverlay);
- if (d->mouseGrabberPopup) {
- d->mouseGrabberPopup->overlayEvent(this, event);
- return;
- } else {
- const auto popups = d->stackingOrderPopups();
- for (QQuickPopup *popup : popups) {
- if (popup->overlayEvent(this, event))
- return;
- }
- }
- event->ignore();
-}
-#endif
-
-bool QQuickOverlay::childMouseEventFilter(QQuickItem *item, QEvent *event)
-{
- Q_D(QQuickOverlay);
- const auto popups = d->stackingOrderPopups();
- for (QQuickPopup *popup : popups) {
- QQuickPopupPrivate *p = QQuickPopupPrivate::get(popup);
-
- // Stop filtering overlay events when reaching a popup item or an item
- // that is inside the popup. Let the popup content handle its events.
- if (item == p->popupItem || p->popupItem->isAncestorOf(item))
- break;
-
- // Let the popup try closing itself when pressing or releasing over its
- // background dimming OR over another popup underneath, in case the popup
- // does not have background dimming.
- if (item == p->dimmer || !p->popupItem->isAncestorOf(item)) {
- switch (event->type()) {
-#if QT_CONFIG(quicktemplates2_multitouch)
- case QEvent::TouchBegin:
- case QEvent::TouchUpdate:
- case QEvent::TouchEnd:
- return d->handleTouchEvent(item, static_cast<QTouchEvent *>(event), popup);
-#endif
- case QEvent::HoverEnter:
- case QEvent::HoverMove:
- case QEvent::HoverLeave:
- return d->handleHoverEvent(item, static_cast<QHoverEvent *>(event), popup);
-
- case QEvent::MouseButtonPress:
- case QEvent::MouseMove:
- case QEvent::MouseButtonRelease:
- return d->handleMouseEvent(item, static_cast<QMouseEvent *>(event), popup);
-
- default:
- break;
- }
- }
- }
- return false;
-}
-
-bool QQuickOverlay::eventFilter(QObject *object, QEvent *event)
-{
- Q_D(QQuickOverlay);
- if (!isVisible() || object != d->window)
- return false;
-
- switch (event->type()) {
-#if QT_CONFIG(quicktemplates2_multitouch)
- case QEvent::TouchBegin:
- case QEvent::TouchUpdate:
- case QEvent::TouchEnd:
- if (static_cast<QTouchEvent *>(event)->touchPointStates() & QEventPoint::Pressed)
- emit pressed();
- if (static_cast<QTouchEvent *>(event)->touchPointStates() & QEventPoint::Released)
- emit released();
-
- // allow non-modal popups to close on touch release outside
- if (!d->mouseGrabberPopup) {
- for (const QTouchEvent::TouchPoint &point : static_cast<QTouchEvent *>(event)->points()) {
- if (point.state() == QEventPoint::Released) {
- if (d->handleRelease(d->window->contentItem(), event, nullptr))
- break;
- }
- }
- }
-
- QQuickWindowPrivate::get(d->window)->handleTouchEvent(static_cast<QTouchEvent *>(event));
-
- // If a touch event hasn't been accepted after being delivered, there
- // were no items interested in touch events at any of the touch points.
- // Make sure to accept the touch event in order to receive the consequent
- // touch events, to be able to close non-modal popups on release outside.
- event->accept();
- return true;
-#endif
-
- case QEvent::MouseButtonPress:
-#if QT_CONFIG(quicktemplates2_multitouch)
- // do not emit pressed() twice when mouse events have been synthesized from touch events
- if (static_cast<QMouseEvent *>(event)->source() == Qt::MouseEventNotSynthesized)
-#endif
- emit pressed();
-
- QQuickWindowPrivate::get(d->window)->handleMouseEvent(static_cast<QMouseEvent *>(event));
-
- // If a mouse event hasn't been accepted after being delivered, there
- // was no item interested in mouse events at the mouse point. Make sure
- // to accept the mouse event in order to receive the consequent mouse
- // events, to be able to close non-modal popups on release outside.
- event->accept();
- return true;
-
- case QEvent::MouseButtonRelease:
-#if QT_CONFIG(quicktemplates2_multitouch)
- // do not emit released() twice when mouse events have been synthesized from touch events
- if (static_cast<QMouseEvent *>(event)->source() == Qt::MouseEventNotSynthesized)
-#endif
- emit released();
-
- // allow non-modal popups to close on mouse release outside
- if (!d->mouseGrabberPopup)
- d->handleRelease(d->window->contentItem(), event, nullptr);
- break;
-
- default:
- break;
- }
-
- return false;
-}
-
-class QQuickOverlayAttachedPrivate : public QObjectPrivate
-{
- Q_DECLARE_PUBLIC(QQuickOverlayAttached)
-
-public:
- void setWindow(QQuickWindow *newWindow);
-
- QQuickWindow *window = nullptr;
- QQmlComponent *modal = nullptr;
- QQmlComponent *modeless = nullptr;
-};
-
-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.
-
- For example, to change the color of the background dimming for a modal
- popup, the following code can be used:
-
- \snippet qtquickcontrols2-overlay-modal.qml 1
-
- \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;
-
- 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.
-
- For example, to change the color of the background dimming for a modeless
- popup, the following code can be used:
-
- \snippet qtquickcontrols2-overlay-modeless.qml 1
-
- \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;
-
- d->modeless = modeless;
- emit modelessChanged();
-}
-
-QT_END_NAMESPACE