diff options
Diffstat (limited to 'src/quicktemplates2/qquickpopup.cpp')
-rw-r--r-- | src/quicktemplates2/qquickpopup.cpp | 91 |
1 files changed, 91 insertions, 0 deletions
diff --git a/src/quicktemplates2/qquickpopup.cpp b/src/quicktemplates2/qquickpopup.cpp index 18579b90..1ccd1040 100644 --- a/src/quicktemplates2/qquickpopup.cpp +++ b/src/quicktemplates2/qquickpopup.cpp @@ -437,6 +437,9 @@ bool QQuickPopupPrivate::prepareEnterTransition() if (transitionState != EnterTransition) { popupItem->setParentItem(QQuickOverlay::overlay(window)); + if (dim) + createOverlay(); + showOverlay(); emit q->aboutToShow(); visible = true; transitionState = EnterTransition; @@ -461,6 +464,7 @@ bool QQuickPopupPrivate::prepareExitTransition() popupItem->setFocus(false); } transitionState = ExitTransition; + hideOverlay(); emit q->aboutToHide(); emit q->openedChanged(); } @@ -483,6 +487,7 @@ void QQuickPopupPrivate::finalizeExitTransition() positioner->setParentItem(nullptr); popupItem->setParentItem(nullptr); popupItem->setVisible(false); + destroyOverlay(); if (hadActiveFocusBeforeExitTransition && window) { if (!qobject_cast<QQuickPopupItem *>(window->activeFocusItem())) { @@ -603,6 +608,88 @@ void QQuickPopupPrivate::reposition() positioner->reposition(); } +static QQuickItem *createDimmer(QQmlComponent *component, QQuickPopup *popup, QQuickItem *parent) +{ + QQuickItem *item = nullptr; + if (component) { + QQmlContext *creationContext = component->creationContext(); + if (!creationContext) + creationContext = qmlContext(parent); + QQmlContext *context = new QQmlContext(creationContext, parent); + context->setContextObject(popup); + item = qobject_cast<QQuickItem*>(component->beginCreate(context)); + } + + // when there is no overlay component available (with plain QQuickWindow), + // use a plain QQuickItem as a fallback to block hover events + if (!item && popup->isModal()) + item = new QQuickItem; + + if (item) { + item->setOpacity(popup->isVisible() ? 1.0 : 0.0); + item->setParentItem(parent); + item->stackBefore(popup->popupItem()); + item->setZ(popup->z()); + if (popup->isModal()) { + item->setAcceptedMouseButtons(Qt::AllButtons); +#if QT_CONFIG(cursor) + item->setCursor(Qt::ArrowCursor); +#endif +#if QT_CONFIG(quicktemplates2_hover) + // TODO: switch to QStyleHints::useHoverEffects in Qt 5.8 + item->setAcceptHoverEvents(true); + // item->setAcceptHoverEvents(QGuiApplication::styleHints()->useHoverEffects()); + // connect(QGuiApplication::styleHints(), &QStyleHints::useHoverEffectsChanged, item, &QQuickItem::setAcceptHoverEvents); +#endif + } + if (component) + component->completeCreate(); + } + return item; +} + +void QQuickPopupPrivate::createOverlay() +{ + Q_Q(QQuickPopup); + QQuickOverlay *overlay = QQuickOverlay::overlay(window); + if (!overlay) + return; + + if (!dimmer) + dimmer = createDimmer(modal ? overlay->modal() : overlay->modeless(), q, overlay); + resizeOverlay(); +} + +void QQuickPopupPrivate::destroyOverlay() +{ + if (dimmer) { + dimmer->setParentItem(nullptr); + dimmer->deleteLater(); + dimmer = nullptr; + } +} + +void QQuickPopupPrivate::toggleOverlay() +{ + destroyOverlay(); + if (dim) + createOverlay(); +} + +void QQuickPopupPrivate::showOverlay() +{ + // use QQmlProperty instead of QQuickItem::setOpacity() to trigger QML Behaviors + if (dim && dimmer) + QQmlProperty::write(dimmer, QStringLiteral("opacity"), 1.0); +} + +void QQuickPopupPrivate::hideOverlay() +{ + // use QQmlProperty instead of QQuickItem::setOpacity() to trigger QML Behaviors + if (dim && dimmer) + QQmlProperty::write(dimmer, QStringLiteral("opacity"), 0.0); +} + void QQuickPopupPrivate::resizeOverlay() { if (!dimmer) @@ -1660,6 +1747,8 @@ void QQuickPopup::setModal(bool modal) if (d->modal == modal) return; d->modal = modal; + if (d->complete && d->visible) + d->toggleOverlay(); emit modalChanged(); if (!d->hasDim) { @@ -1693,6 +1782,8 @@ void QQuickPopup::setDim(bool dim) return; d->dim = dim; + if (d->complete && d->visible) + d->toggleOverlay(); emit dimChanged(); } |