aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/quicktemplates2/qquickdrawer.cpp40
-rw-r--r--src/quicktemplates2/qquickdrawer_p.h2
-rw-r--r--src/quicktemplates2/qquickoverlay.cpp144
-rw-r--r--src/quicktemplates2/qquickoverlay_p.h4
-rw-r--r--src/quicktemplates2/qquickoverlay_p_p.h2
-rw-r--r--src/quicktemplates2/qquickpopup.cpp6
6 files changed, 102 insertions, 96 deletions
diff --git a/src/quicktemplates2/qquickdrawer.cpp b/src/quicktemplates2/qquickdrawer.cpp
index 551352de..44fc8f50 100644
--- a/src/quicktemplates2/qquickdrawer.cpp
+++ b/src/quicktemplates2/qquickdrawer.cpp
@@ -191,6 +191,12 @@ bool QQuickDrawerPrivate::startDrag(QQuickWindow *window, QMouseEvent *event)
break;
}
+ if (drag) {
+ prepareEnterTransition();
+ reposition();
+ handleMousePressEvent(window->contentItem(), event);
+ }
+
return drag;
}
@@ -289,21 +295,12 @@ bool QQuickDrawerPrivate::ungrabMouse(QMouseEvent *event)
bool QQuickDrawerPrivate::handleMousePressEvent(QQuickItem *item, QMouseEvent *event)
{
- pressPoint = event->windowPos();
offset = 0;
-
- if (qFuzzyIsNull(position)) {
- // only accept pressing at drag margins when fully closed
- event->setAccepted(startDrag(item->window(), event));
- } else {
- if (modal)
- event->setAccepted(item->isAncestorOf(popupItem));
- else
- event->setAccepted(false);
- }
-
+ pressPoint = event->windowPos();
velocityCalculator.startMeasuring(pressPoint, event->timestamp());
+ // don't block press events a) outside a non-modal drawer, or b) to drawer children
+ event->setAccepted(modal && !popupItem->isAncestorOf(item));
return event->isAccepted();
}
@@ -384,7 +381,7 @@ void QQuickDrawerPrivate::finalizeEnterTransition()
void QQuickDrawerPrivate::finalizeExitTransition(bool hide)
{
- QQuickPopupPrivate::finalizeExitTransition(hide = false);
+ QQuickPopupPrivate::finalizeExitTransition(hide);
}
QQuickDrawer::QQuickDrawer(QObject *parent) :
@@ -448,12 +445,8 @@ void QQuickDrawer::setPosition(qreal position)
d->position = position;
if (isComponentComplete())
d->reposition();
- if (d->dimmer) {
+ if (d->dimmer)
d->dimmer->setOpacity(position);
- // TODO: check QStyleHints::useHoverEffects in Qt 5.8
- d->dimmer->setAcceptHoverEvents(d->modal && position > 0.0);
- // d->dimmer->setAcceptHoverEvents(d->modal && position > 0.0 && QGuiApplication::styleHints()->useHoverEffects());
- }
emit positionChanged();
}
@@ -548,15 +541,4 @@ bool QQuickDrawer::overlayEvent(QQuickItem *item, QEvent *event)
}
}
-void QQuickDrawer::componentComplete()
-{
- Q_D(QQuickDrawer);
- QQuickPopup::componentComplete();
- if (d->window) {
- bool notify = false;
- d->prepareEnterTransition(notify);
- d->reposition();
- }
-}
-
QT_END_NAMESPACE
diff --git a/src/quicktemplates2/qquickdrawer_p.h b/src/quicktemplates2/qquickdrawer_p.h
index 23c5c2ab..e694e27b 100644
--- a/src/quicktemplates2/qquickdrawer_p.h
+++ b/src/quicktemplates2/qquickdrawer_p.h
@@ -87,8 +87,6 @@ protected:
void mouseUngrabEvent() override;
bool overlayEvent(QQuickItem *item, QEvent *event) override;
- void componentComplete() override;
-
private:
Q_DISABLE_COPY(QQuickDrawer)
Q_DECLARE_PRIVATE(QQuickDrawer)
diff --git a/src/quicktemplates2/qquickoverlay.cpp b/src/quicktemplates2/qquickoverlay.cpp
index d34fd7fc..19677cb7 100644
--- a/src/quicktemplates2/qquickoverlay.cpp
+++ b/src/quicktemplates2/qquickoverlay.cpp
@@ -37,11 +37,12 @@
#include "qquickoverlay_p.h"
#include "qquickoverlay_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
@@ -93,7 +94,8 @@ static QQuickItem *createDimmer(QQmlComponent *component, QQuickPopup *popup, QQ
item->setParentItem(parent);
item->stackBefore(popup->popupItem());
item->setZ(popup->z());
- if (popup->isModal() && !qobject_cast<QQuickDrawer *>(popup)) {
+ if (popup->isModal()) {
+ item->setAcceptedMouseButtons(Qt::AllButtons);
// TODO: switch to QStyleHints::useHoverEffects in Qt 5.8
item->setAcceptHoverEvents(true);
// item->setAcceptHoverEvents(QGuiApplication::styleHints()->useHoverEffects());
@@ -162,6 +164,15 @@ QVector<QQuickPopup *> QQuickOverlayPrivate::stackingOrderPopups() const
return popups;
}
+QVector<QQuickDrawer *> QQuickOverlayPrivate::stackingOrderDrawers() const
+{
+ QVector<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 *, const QRectF &newGeometry, const QRectF &)
{
Q_Q(QQuickOverlay);
@@ -170,22 +181,26 @@ void QQuickOverlayPrivate::itemGeometryChanged(QQuickItem *, const QRectF &newGe
QQuickOverlayPrivate::QQuickOverlayPrivate() :
modal(nullptr),
- modeless(nullptr),
- modalPopups(0)
+ modeless(nullptr)
{
}
void QQuickOverlayPrivate::addPopup(QQuickPopup *popup)
{
+ Q_Q(QQuickOverlay);
allPopups += popup;
- if (QQuickDrawer *drawer = qobject_cast<QQuickDrawer *>(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);
- allDrawers.removeOne(static_cast<QQuickDrawer *>(popup));
+ if (allDrawers.removeOne(static_cast<QQuickDrawer *>(popup)))
+ q->setVisible(!allDrawers.isEmpty() || !q->childItems().isEmpty());
}
QQuickOverlay::QQuickOverlay(QQuickItem *parent)
@@ -275,7 +290,7 @@ void QQuickOverlay::itemChange(ItemChange change, const ItemChangeData &data)
QQuickPopup *popup = nullptr;
if (change == ItemChildAddedChange || change == ItemChildRemovedChange) {
popup = qobject_cast<QQuickPopup *>(data.item->parent());
- setVisible(!childItems().isEmpty());
+ setVisible(!d->allDrawers.isEmpty() || !childItems().isEmpty());
}
if (!popup)
return;
@@ -286,8 +301,6 @@ void QQuickOverlay::itemChange(ItemChange change, const ItemChangeData &data)
QObjectPrivate::connect(popup, &QQuickPopup::dimChanged, d, &QQuickOverlayPrivate::toggleOverlay);
QObjectPrivate::connect(popup, &QQuickPopup::modalChanged, d, &QQuickOverlayPrivate::toggleOverlay);
if (!qobject_cast<QQuickDrawer *>(popup)) {
- if (popup->isModal())
- ++d->modalPopups;
QObjectPrivate::connect(popup, &QQuickPopup::aboutToShow, d, &QQuickOverlayPrivate::popupAboutToShow);
QObjectPrivate::connect(popup, &QQuickPopup::aboutToHide, d, &QQuickOverlayPrivate::popupAboutToHide);
}
@@ -296,8 +309,6 @@ void QQuickOverlay::itemChange(ItemChange change, const ItemChangeData &data)
QObjectPrivate::disconnect(popup, &QQuickPopup::dimChanged, d, &QQuickOverlayPrivate::toggleOverlay);
QObjectPrivate::disconnect(popup, &QQuickPopup::modalChanged, d, &QQuickOverlayPrivate::toggleOverlay);
if (!qobject_cast<QQuickDrawer *>(popup)) {
- if (popup->isModal())
- --d->modalPopups;
QObjectPrivate::disconnect(popup, &QQuickPopup::aboutToShow, d, &QQuickOverlayPrivate::popupAboutToShow);
QObjectPrivate::disconnect(popup, &QQuickPopup::aboutToHide, d, &QQuickOverlayPrivate::popupAboutToHide);
}
@@ -312,75 +323,82 @@ void QQuickOverlay::geometryChanged(const QRectF &newGeometry, const QRectF &old
d->resizeOverlay(popup);
}
-bool QQuickOverlay::event(QEvent *event)
+void QQuickOverlay::mousePressEvent(QMouseEvent *event)
{
Q_D(QQuickOverlay);
- switch (event->type()) {
- case QEvent::MouseButtonPress: {
- emit pressed();
+ emit pressed();
+
+ if (!d->allDrawers.isEmpty()) {
+ // the overlay background was pressed, so there are no modal popups open.
+ // test if the press point lands on any drawer's drag margin
+
+ const QVector<QQuickDrawer *> drawers = d->stackingOrderDrawers();
+ for (QQuickDrawer *drawer : drawers) {
+ QQuickDrawerPrivate *p = QQuickDrawerPrivate::get(drawer);
+ if (p->startDrag(window(), event)) {
+ d->mouseGrabberPopup = drawer;
+ return;
+ }
+ }
+ }
+
+ if (!d->mouseGrabberPopup) {
const auto popups = d->stackingOrderPopups();
for (QQuickPopup *popup : popups) {
if (popup->overlayEvent(this, event)) {
d->mouseGrabberPopup = popup;
- return true;
+ return;
}
}
- break;
}
- case QEvent::MouseMove:
- if (d->mouseGrabberPopup) {
- if (d->mouseGrabberPopup->overlayEvent(this, event))
- return true;
- } else {
- const auto popups = d->stackingOrderPopups();
- for (QQuickPopup *popup : popups) {
- if (popup->overlayEvent(this, event))
- return true;
- }
- }
- break;
- case QEvent::MouseButtonRelease:
- emit released();
- if (d->mouseGrabberPopup) {
- QQuickPopup *grabber = d->mouseGrabberPopup;
- d->mouseGrabberPopup = nullptr;
- if (grabber->overlayEvent(this, event))
- return true;
- } else {
- const auto popups = d->stackingOrderPopups();
- for (QQuickPopup *popup : popups) {
- if (popup->overlayEvent(this, event))
- return true;
- }
+
+ event->ignore();
+}
+
+void QQuickOverlay::mouseMoveEvent(QMouseEvent *event)
+{
+ Q_D(QQuickOverlay);
+ if (d->mouseGrabberPopup)
+ d->mouseGrabberPopup->overlayEvent(this, event);
+}
+
+void QQuickOverlay::mouseReleaseEvent(QMouseEvent *event)
+{
+ Q_D(QQuickOverlay);
+ emit released();
+
+ if (d->mouseGrabberPopup) {
+ d->mouseGrabberPopup->overlayEvent(this, event);
+ d->mouseGrabberPopup = nullptr;
+ } else {
+ const auto popups = d->stackingOrderPopups();
+ for (QQuickPopup *popup : popups) {
+ if (popup->overlayEvent(this, event))
+ break;
}
- break;
- default:
- break;
}
-
- return QQuickItem::event(event);
}
bool QQuickOverlay::childMouseEventFilter(QQuickItem *item, QEvent *event)
{
Q_D(QQuickOverlay);
- if (d->modalPopups == 0)
- return false;
- // TODO Filter touch events
- if (event->type() != QEvent::MouseButtonPress)
- return false;
- while (item->parentItem() != this)
- item = item->parentItem();
-
- const auto popups = d->stackingOrderPopups();
- for (QQuickPopup *popup : popups) {
- if (popup->popupItem() == item)
- break;
-
- if (popup->overlayEvent(item, event))
- return true;
+ for (QQuickPopup *popup : qAsConst(d->allPopups)) {
+ QQuickItem *dimmer = QQuickPopupPrivate::get(popup)->dimmer;
+ if (item == dimmer) {
+ switch (event->type()) {
+ case QEvent::MouseButtonPress:
+ emit pressed();
+ return popup->overlayEvent(item, event);
+ case QEvent::MouseMove:
+ return popup->overlayEvent(item, event);
+ case QEvent::MouseButtonRelease:
+ emit released();
+ return popup->overlayEvent(item, event);
+ default:
+ break;
+ }
+ }
}
-
return false;
}
diff --git a/src/quicktemplates2/qquickoverlay_p.h b/src/quicktemplates2/qquickoverlay_p.h
index ecb0e20a..07f7daec 100644
--- a/src/quicktemplates2/qquickoverlay_p.h
+++ b/src/quicktemplates2/qquickoverlay_p.h
@@ -84,7 +84,9 @@ protected:
void itemChange(ItemChange change, const ItemChangeData &data) override;
void geometryChanged(const QRectF &oldGeometry, const QRectF &newGeometry) override;
- bool event(QEvent *event) override;
+ void mousePressEvent(QMouseEvent *event) override;
+ void mouseMoveEvent(QMouseEvent *event) override;
+ void mouseReleaseEvent(QMouseEvent *event) override;
bool childMouseEventFilter(QQuickItem *item, QEvent *event) override;
private:
diff --git a/src/quicktemplates2/qquickoverlay_p_p.h b/src/quicktemplates2/qquickoverlay_p_p.h
index f9e962ee..6dc2853c 100644
--- a/src/quicktemplates2/qquickoverlay_p_p.h
+++ b/src/quicktemplates2/qquickoverlay_p_p.h
@@ -82,6 +82,7 @@ public:
void toggleOverlay();
QVector<QQuickPopup *> stackingOrderPopups() const;
+ QVector<QQuickDrawer *> stackingOrderDrawers() const;
void itemGeometryChanged(QQuickItem *item, const QRectF &newGeometry, const QRectF &oldGeometry) override;
@@ -90,7 +91,6 @@ public:
QVector<QQuickPopup *> allPopups;
QVector<QQuickDrawer *> allDrawers;
QPointer<QQuickPopup> mouseGrabberPopup;
- int modalPopups;
};
QT_END_NAMESPACE
diff --git a/src/quicktemplates2/qquickpopup.cpp b/src/quicktemplates2/qquickpopup.cpp
index 6c184243..6d06708b 100644
--- a/src/quicktemplates2/qquickpopup.cpp
+++ b/src/quicktemplates2/qquickpopup.cpp
@@ -1898,6 +1898,12 @@ void QQuickPopup::mouseDoubleClickEvent(QMouseEvent *event)
void QQuickPopup::mouseUngrabEvent()
{
+ QQuickOverlay *overlay = QQuickOverlay::overlay(window());
+ if (overlay) {
+ QQuickOverlayPrivate *p = QQuickOverlayPrivate::get(overlay);
+ if (p->mouseGrabberPopup == this)
+ p->mouseGrabberPopup = nullptr;
+ }
}
bool QQuickPopup::overlayEvent(QQuickItem *item, QEvent *event)