1/****************************************************************************
2**
3** Copyright (C) 2017 The Qt Company Ltd.
4** Contact: http://www.qt.io/licensing/
5**
6** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL3$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see http://www.qt.io/terms-conditions. For further
15** information use the contact form at http://www.qt.io/contact-us.
16**
17** GNU Lesser General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU Lesser
19** General Public License version 3 as published by the Free Software
20** Foundation and appearing in the file LICENSE.LGPLv3 included in the
21** packaging of this file. Please review the following information to
22** ensure the GNU Lesser General Public License version 3 requirements
23** will be met: https://www.gnu.org/licenses/lgpl.html.
24**
25** GNU General Public License Usage
26** Alternatively, this file may be used under the terms of the GNU
27** General Public License version 2.0 or later as published by the Free
28** Software Foundation and appearing in the file LICENSE.GPL included in
29** the packaging of this file. Please review the following information to
30** ensure the GNU General Public License version 2.0 requirements will be
31** met: http://www.gnu.org/licenses/gpl-2.0.html.
32**
33** $QT_END_LICENSE$
34**
35****************************************************************************/
36
37#include "qquickpopup_p.h"
38#include "qquickpopup_p_p.h"
39#include "qquickpopupanchors_p.h"
40#include "qquickpopupitem_p_p.h"
41#include "qquickpopuppositioner_p_p.h"
42#include "qquickapplicationwindow_p.h"
43#include "qquickoverlay_p_p.h"
44#include "qquickcontrol_p_p.h"
45#include "qquickdialog_p.h"
46
47#include <QtQml/qqmlinfo.h>
48#include <QtQuick/qquickitem.h>
49#include <QtQuick/private/qquicktransition_p.h>
50#include <QtQuick/private/qquickitem_p.h>
51
52QT_BEGIN_NAMESPACE
53
54Q_LOGGING_CATEGORY(lcDimmer, "qt.quick.controls.popup.dimmer")
55
56/*!
57 \qmltype Popup
58 \inherits QtObject
59//! \instantiates QQuickPopup
60 \inqmlmodule QtQuick.Controls
61 \since 5.7
62 \ingroup qtquickcontrols2-popups
63 \ingroup qtquickcontrols2-focusscopes
64 \brief Base type of popup-like user interface controls.
65
66 Popup is the base type of popup-like user interface controls. It can be
67 used with \l Window or \l ApplicationWindow.
68
69 \qml
70 import QtQuick.Window 2.2
71 import QtQuick.Controls 2.12
72
73 ApplicationWindow {
74 id: window
75 width: 400
76 height: 400
77 visible: true
78
79 Button {
80 text: "Open"
81 onClicked: popup.open()
82 }
83
84 Popup {
85 id: popup
86 x: 100
87 y: 100
88 width: 200
89 height: 300
90 modal: true
91 focus: true
92 closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutsideParent
93 }
94 }
95 \endqml
96
97 In order to ensure that a popup is displayed above other items in the
98 scene, it is recommended to use ApplicationWindow. ApplicationWindow also
99 provides background dimming effects.
100
101 Popup does not provide a layout of its own, but requires you to position
102 its contents, for instance by creating a \l RowLayout or a \l ColumnLayout.
103
104 Items declared as children of a Popup are automatically parented to the
105 Popups's \l contentItem. Items created dynamically need to be explicitly
106 parented to the contentItem.
107
108 \section1 Popup Layout
109
110 The following diagram illustrates the layout of a popup within a window:
111
112 \image qtquickcontrols2-popup.png
113
114 The \l implicitWidth and \l implicitHeight of a popup are typically based
115 on the implicit sizes of the background and the content item plus any insets
116 and paddings. These properties determine how large the popup will be when no
117 explicit \l width or \l height is specified.
118
119 The geometry of the \l contentItem is determined by the padding. The following
120 example reserves 10px padding between the boundaries of the popup and its content:
121
122 \code
123 Popup {
124 padding: 10
125
126 contentItem: Text {
127 text: "Content"
128 }
129 }
130 \endcode
131
132 The \l background item fills the entire width and height of the popup,
133 unless insets or an explicit size have been given for it.
134
135 Negative insets can be used to make the background larger than the popup.
136 The following example uses negative insets to place a shadow outside the
137 popup's boundaries:
138
139 \code
140 Popup {
141 topInset: -2
142 leftInset: -2
143 rightInset: -6
144 bottomInset: -6
145
146 background: BorderImage {
147 source: ":/images/shadowed-background.png"
148 }
149 }
150 \endcode
151
152 \section1 Popup Sizing
153
154 If only a single item is used within a Popup, it will resize to fit the
155 implicit size of its contained item. This makes it particularly suitable
156 for use together with layouts.
157
158 \code
159 Popup {
160 ColumnLayout {
161 anchors.fill: parent
162 CheckBox { text: qsTr("E-mail") }
163 CheckBox { text: qsTr("Calendar") }
164 CheckBox { text: qsTr("Contacts") }
165 }
166 }
167 \endcode
168
169 Sometimes there might be two items within the popup:
170
171 \code
172 Popup {
173 SwipeView {
174 // ...
175 }
176 PageIndicator {
177 anchors.horizontalCenter: parent.horizontalCenter
178 anchors.bottom: parent.bottom
179 }
180 }
181 \endcode
182
183 In this case, Popup cannot calculate a sensible implicit size. Since we're
184 anchoring the \l PageIndicator over the \l SwipeView, we can simply set the
185 content size to the view's implicit size:
186
187 \code
188 Popup {
189 contentWidth: view.implicitWidth
190 contentHeight: view.implicitHeight
191
192 SwipeView {
193 id: view
194 // ...
195 }
196 PageIndicator {
197 anchors.horizontalCenter: parent.horizontalCenter
198 anchors.bottom: parent.bottom
199 }
200 }
201 \endcode
202
203 \section1 Popup Positioning
204
205 Similar to items in Qt Quick, Popup's \l x and \l y coordinates are
206 relative to its parent. This means that opening a popup that is a
207 child of a \l Button, for example, will cause the popup to be positioned
208 relative to the button.
209
210 \include qquickoverlay-popup-parent.qdocinc
211
212 Another way to center a popup in the window regardless of its parent item
213 is to use \l {anchors.centerIn}:
214
215 \snippet qtquickcontrols2-popup.qml centerIn
216
217 To ensure that the popup is positioned within the bounds of the enclosing
218 window, the \l margins property can be set to a non-negative value.
219
220 \section1 Popup Transitions
221
222 Since Qt 5.15.3 the following properties are restored to their original values from before
223 the enter transition after the exit transition is completed.
224
225 \list
226 \li \l opacity
227 \li \l scale
228 \endlist
229
230 This allows the built-in styles to animate on these properties without losing any explicitly
231 defined value.
232
233 \sa {Popup Controls}, {Customizing Popup}, ApplicationWindow
234*/
235
236/*!
237 \qmlsignal void QtQuick.Controls::Popup::opened()
238
239 This signal is emitted when the popup is opened.
240
241 \sa aboutToShow()
242*/
243
244/*!
245 \qmlsignal void QtQuick.Controls::Popup::closed()
246
247 This signal is emitted when the popup is closed.
248
249 \sa aboutToHide()
250*/
251
252/*!
253 \qmlsignal void QtQuick.Controls::Popup::aboutToShow()
254
255 This signal is emitted when the popup is about to show.
256
257 \sa opened()
258*/
259
260/*!
261 \qmlsignal void QtQuick.Controls::Popup::aboutToHide()
262
263 This signal is emitted when the popup is about to hide.
264
265 \sa closed()
266*/
267
268const QQuickPopup::ClosePolicy QQuickPopupPrivate::DefaultClosePolicy = QQuickPopup::CloseOnEscape | QQuickPopup::CloseOnPressOutside;
269
270QQuickPopupPrivate::QQuickPopupPrivate()
271 : transitionManager(this)
272{
273}
274
275void QQuickPopupPrivate::init()
276{
277 Q_Q(QQuickPopup);
278 popupItem = new QQuickPopupItem(q);
279 popupItem->setVisible(false);
280 q->setParentItem(qobject_cast<QQuickItem *>(object: parent));
281 QObject::connect(sender: popupItem, signal: &QQuickControl::paddingChanged, receiver: q, slot: &QQuickPopup::paddingChanged);
282 QObject::connect(sender: popupItem, signal: &QQuickControl::backgroundChanged, receiver: q, slot: &QQuickPopup::backgroundChanged);
283 QObject::connect(sender: popupItem, signal: &QQuickControl::contentItemChanged, receiver: q, slot: &QQuickPopup::contentItemChanged);
284 QObject::connect(sender: popupItem, signal: &QQuickControl::implicitContentWidthChanged, receiver: q, slot: &QQuickPopup::implicitContentWidthChanged);
285 QObject::connect(sender: popupItem, signal: &QQuickControl::implicitContentHeightChanged, receiver: q, slot: &QQuickPopup::implicitContentHeightChanged);
286 QObject::connect(sender: popupItem, signal: &QQuickControl::implicitBackgroundWidthChanged, receiver: q, slot: &QQuickPopup::implicitBackgroundWidthChanged);
287 QObject::connect(sender: popupItem, signal: &QQuickControl::implicitBackgroundHeightChanged, receiver: q, slot: &QQuickPopup::implicitBackgroundHeightChanged);
288}
289
290void QQuickPopupPrivate::closeOrReject()
291{
292 Q_Q(QQuickPopup);
293 if (QQuickDialog *dialog = qobject_cast<QQuickDialog*>(object: q))
294 dialog->reject();
295 else
296 q->close();
297}
298
299bool QQuickPopupPrivate::tryClose(const QPointF &pos, QQuickPopup::ClosePolicy flags)
300{
301 if (!interactive)
302 return false;
303
304 static const QQuickPopup::ClosePolicy outsideFlags = QQuickPopup::CloseOnPressOutside | QQuickPopup::CloseOnReleaseOutside;
305 static const QQuickPopup::ClosePolicy outsideParentFlags = QQuickPopup::CloseOnPressOutsideParent | QQuickPopup::CloseOnReleaseOutsideParent;
306
307 const bool onOutside = closePolicy & (flags & outsideFlags);
308 const bool onOutsideParent = closePolicy & (flags & outsideParentFlags);
309 if (onOutside || onOutsideParent) {
310 if (!contains(scenePos: pos)) {
311 if (!onOutsideParent || !parentItem || !parentItem->contains(point: parentItem->mapFromScene(point: pos))) {
312 closeOrReject();
313 return true;
314 }
315 }
316 }
317 return false;
318}
319
320bool QQuickPopupPrivate::contains(const QPointF &scenePos) const
321{
322 return popupItem->contains(point: popupItem->mapFromScene(point: scenePos));
323}
324
325#if QT_CONFIG(quicktemplates2_multitouch)
326bool QQuickPopupPrivate::acceptTouch(const QTouchEvent::TouchPoint &point)
327{
328 if (point.id() == touchId)
329 return true;
330
331 if (touchId == -1 && point.state() != Qt::TouchPointReleased) {
332 touchId = point.id();
333 return true;
334 }
335
336 return false;
337}
338#endif
339
340bool QQuickPopupPrivate::blockInput(QQuickItem *item, const QPointF &point) const
341{
342 // don't block presses and releases
343 // a) outside a non-modal popup,
344 // b) to popup children/content, or
345 // b) outside a modal popups's background dimming
346 return modal && !popupItem->isAncestorOf(child: item) && (!dimmer || dimmer->contains(point: dimmer->mapFromScene(point)));
347}
348
349bool QQuickPopupPrivate::handlePress(QQuickItem *item, const QPointF &point, ulong timestamp)
350{
351 Q_UNUSED(timestamp);
352 pressPoint = point;
353 tryClose(pos: point, flags: QQuickPopup::CloseOnPressOutside | QQuickPopup::CloseOnPressOutsideParent);
354 return blockInput(item, point);
355}
356
357bool QQuickPopupPrivate::handleMove(QQuickItem *item, const QPointF &point, ulong timestamp)
358{
359 Q_UNUSED(timestamp);
360 return blockInput(item, point);
361}
362
363bool QQuickPopupPrivate::handleRelease(QQuickItem *item, const QPointF &point, ulong timestamp)
364{
365 Q_UNUSED(timestamp);
366 if (item != popupItem && !contains(scenePos: pressPoint))
367 tryClose(pos: point, flags: QQuickPopup::CloseOnReleaseOutside | QQuickPopup::CloseOnReleaseOutsideParent);
368 pressPoint = QPointF();
369 touchId = -1;
370 return blockInput(item, point);
371}
372
373void QQuickPopupPrivate::handleUngrab()
374{
375 Q_Q(QQuickPopup);
376 QQuickOverlay *overlay = QQuickOverlay::overlay(window);
377 if (overlay) {
378 QQuickOverlayPrivate *p = QQuickOverlayPrivate::get(overlay);
379 if (p->mouseGrabberPopup == q)
380 p->mouseGrabberPopup = nullptr;
381 }
382 pressPoint = QPointF();
383 touchId = -1;
384}
385
386bool QQuickPopupPrivate::handleMouseEvent(QQuickItem *item, QMouseEvent *event)
387{
388 switch (event->type()) {
389 case QEvent::MouseButtonPress:
390 return handlePress(item, point: event->windowPos(), timestamp: event->timestamp());
391 case QEvent::MouseMove:
392 return handleMove(item, point: event->windowPos(), timestamp: event->timestamp());
393 case QEvent::MouseButtonRelease:
394 return handleRelease(item, point: event->windowPos(), timestamp: event->timestamp());
395 default:
396 Q_UNREACHABLE();
397 return false;
398 }
399}
400
401#if QT_CONFIG(quicktemplates2_multitouch)
402bool QQuickPopupPrivate::handleTouchEvent(QQuickItem *item, QTouchEvent *event)
403{
404 switch (event->type()) {
405 case QEvent::TouchBegin:
406 case QEvent::TouchUpdate:
407 case QEvent::TouchEnd:
408 for (const QTouchEvent::TouchPoint &point : event->touchPoints()) {
409 if (!acceptTouch(point))
410 return blockInput(item, point: point.pos());
411
412 switch (point.state()) {
413 case Qt::TouchPointPressed:
414 return handlePress(item, point: item->mapToScene(point: point.pos()), timestamp: event->timestamp());
415 case Qt::TouchPointMoved:
416 return handleMove(item, point: item->mapToScene(point: point.pos()), timestamp: event->timestamp());
417 case Qt::TouchPointReleased:
418 return handleRelease(item, point: item->mapToScene(point: point.pos()), timestamp: event->timestamp());
419 default:
420 break;
421 }
422 }
423 break;
424
425 case QEvent::TouchCancel:
426 handleUngrab();
427 break;
428
429 default:
430 break;
431 }
432
433 return false;
434}
435#endif
436
437bool QQuickPopupPrivate::prepareEnterTransition()
438{
439 Q_Q(QQuickPopup);
440 if (!window) {
441 qmlWarning(me: q) << "cannot find any window to open popup in.";
442 return false;
443 }
444
445 if (transitionState == EnterTransition && transitionManager.isRunning())
446 return false;
447
448 if (transitionState != EnterTransition) {
449 popupItem->setParentItem(QQuickOverlay::overlay(window));
450 if (dim)
451 createOverlay();
452 showOverlay();
453 emit q->aboutToShow();
454 visible = true;
455 transitionState = EnterTransition;
456 popupItem->setVisible(true);
457 getPositioner()->setParentItem(parentItem);
458 emit q->visibleChanged();
459
460 if (focus)
461 popupItem->setFocus(true);
462 }
463 return true;
464}
465
466bool QQuickPopupPrivate::prepareExitTransition()
467{
468 Q_Q(QQuickPopup);
469 if (transitionState == ExitTransition && transitionManager.isRunning())
470 return false;
471
472 // We need to cache the original scale and opacity values so we can reset it after
473 // the exit transition is done so they have the original values again
474 prevScale = popupItem->scale();
475 prevOpacity = popupItem->opacity();
476
477 if (transitionState != ExitTransition) {
478 // The setFocus(false) call below removes any active focus before we're
479 // able to check it in finalizeExitTransition.
480 if (!hadActiveFocusBeforeExitTransition)
481 hadActiveFocusBeforeExitTransition = popupItem->hasActiveFocus();
482 if (focus)
483 popupItem->setFocus(false);
484 transitionState = ExitTransition;
485 hideOverlay();
486 emit q->aboutToHide();
487 emit q->openedChanged();
488 }
489 return true;
490}
491
492void QQuickPopupPrivate::finalizeEnterTransition()
493{
494 Q_Q(QQuickPopup);
495 transitionState = NoTransition;
496 getPositioner()->reposition();
497 emit q->openedChanged();
498 emit q->opened();
499}
500
501void QQuickPopupPrivate::finalizeExitTransition()
502{
503 Q_Q(QQuickPopup);
504 getPositioner()->setParentItem(nullptr);
505 if (popupItem) {
506 popupItem->setParentItem(nullptr);
507 popupItem->setVisible(false);
508 }
509 destroyOverlay();
510
511 if (hadActiveFocusBeforeExitTransition && window) {
512 // restore focus to the next popup in chain, or to the window content if there are no other popups open
513 QQuickPopup *nextFocusPopup = nullptr;
514 if (QQuickOverlay *overlay = QQuickOverlay::overlay(window)) {
515 const auto stackingOrderPopups = QQuickOverlayPrivate::get(overlay)->stackingOrderPopups();
516 for (auto popup : stackingOrderPopups) {
517 if (QQuickPopupPrivate::get(popup)->transitionState != ExitTransition
518 && popup->hasFocus()) {
519 nextFocusPopup = popup;
520 break;
521 }
522 }
523 }
524 if (nextFocusPopup) {
525 nextFocusPopup->forceActiveFocus();
526 } else {
527 QQuickApplicationWindow *applicationWindow = qobject_cast<QQuickApplicationWindow*>(object: window);
528 if (applicationWindow)
529 applicationWindow->contentItem()->setFocus(true);
530 else
531 window->contentItem()->setFocus(true);
532 }
533 }
534
535 visible = false;
536 transitionState = NoTransition;
537 hadActiveFocusBeforeExitTransition = false;
538 emit q->visibleChanged();
539 emit q->closed();
540 if (popupItem) {
541 popupItem->setScale(prevScale);
542 popupItem->setOpacity(prevOpacity);
543 }
544}
545
546QMarginsF QQuickPopupPrivate::getMargins() const
547{
548 Q_Q(const QQuickPopup);
549 return QMarginsF(q->leftMargin(), q->topMargin(), q->rightMargin(), q->bottomMargin());
550}
551
552void QQuickPopupPrivate::setTopMargin(qreal value, bool reset)
553{
554 Q_Q(QQuickPopup);
555 qreal oldMargin = q->topMargin();
556 topMargin = value;
557 hasTopMargin = !reset;
558 if ((!reset && !qFuzzyCompare(p1: oldMargin, p2: value)) || (reset && !qFuzzyCompare(p1: oldMargin, p2: margins))) {
559 emit q->topMarginChanged();
560 q->marginsChange(newMargins: QMarginsF(leftMargin, topMargin, rightMargin, bottomMargin),
561 oldMargins: QMarginsF(leftMargin, oldMargin, rightMargin, bottomMargin));
562 }
563}
564
565void QQuickPopupPrivate::setLeftMargin(qreal value, bool reset)
566{
567 Q_Q(QQuickPopup);
568 qreal oldMargin = q->leftMargin();
569 leftMargin = value;
570 hasLeftMargin = !reset;
571 if ((!reset && !qFuzzyCompare(p1: oldMargin, p2: value)) || (reset && !qFuzzyCompare(p1: oldMargin, p2: margins))) {
572 emit q->leftMarginChanged();
573 q->marginsChange(newMargins: QMarginsF(leftMargin, topMargin, rightMargin, bottomMargin),
574 oldMargins: QMarginsF(oldMargin, topMargin, rightMargin, bottomMargin));
575 }
576}
577
578void QQuickPopupPrivate::setRightMargin(qreal value, bool reset)
579{
580 Q_Q(QQuickPopup);
581 qreal oldMargin = q->rightMargin();
582 rightMargin = value;
583 hasRightMargin = !reset;
584 if ((!reset && !qFuzzyCompare(p1: oldMargin, p2: value)) || (reset && !qFuzzyCompare(p1: oldMargin, p2: margins))) {
585 emit q->rightMarginChanged();
586 q->marginsChange(newMargins: QMarginsF(leftMargin, topMargin, rightMargin, bottomMargin),
587 oldMargins: QMarginsF(leftMargin, topMargin, oldMargin, bottomMargin));
588 }
589}
590
591void QQuickPopupPrivate::setBottomMargin(qreal value, bool reset)
592{
593 Q_Q(QQuickPopup);
594 qreal oldMargin = q->bottomMargin();
595 bottomMargin = value;
596 hasBottomMargin = !reset;
597 if ((!reset && !qFuzzyCompare(p1: oldMargin, p2: value)) || (reset && !qFuzzyCompare(p1: oldMargin, p2: margins))) {
598 emit q->bottomMarginChanged();
599 q->marginsChange(newMargins: QMarginsF(leftMargin, topMargin, rightMargin, bottomMargin),
600 oldMargins: QMarginsF(leftMargin, topMargin, rightMargin, oldMargin));
601 }
602}
603
604/*!
605 \since QtQuick.Controls 2.5 (Qt 5.12)
606 \qmlproperty Object QtQuick.Controls::Popup::anchors.centerIn
607
608 Anchors provide a way to position an item by specifying its
609 relationship with other items.
610
611 A common use case is to center a popup within its parent. One way to do
612 this is with the \l[QtQuick]{Item::}{x} and \l[QtQuick]{Item::}{y} properties. Anchors offer
613 a more convenient approach:
614
615 \qml
616 Pane {
617 // ...
618
619 Popup {
620 anchors.centerIn: parent
621 }
622 }
623 \endqml
624
625 It is also possible to center the popup in the window by using \l Overlay:
626
627 \snippet qtquickcontrols2-popup.qml centerIn
628
629 This makes it easy to center a popup in the window from any component.
630
631 \note Popups can only be centered within their immediate parent or
632 the window overlay; trying to center in other items will produce a warning.
633
634 \sa {Popup Positioning}, {QtQuick::Item::anchors}{anchors}
635*/
636QQuickPopupAnchors *QQuickPopupPrivate::getAnchors()
637{
638 Q_Q(QQuickPopup);
639 if (!anchors)
640 anchors = new QQuickPopupAnchors(q);
641 return anchors;
642}
643
644QQuickPopupPositioner *QQuickPopupPrivate::getPositioner()
645{
646 Q_Q(QQuickPopup);
647 if (!positioner)
648 positioner = new QQuickPopupPositioner(q);
649 return positioner;
650}
651
652void QQuickPopupPrivate::setWindow(QQuickWindow *newWindow)
653{
654 Q_Q(QQuickPopup);
655 if (window == newWindow)
656 return;
657
658 if (window) {
659 QQuickOverlay *overlay = QQuickOverlay::overlay(window);
660 if (overlay)
661 QQuickOverlayPrivate::get(overlay)->removePopup(popup: q);
662 }
663
664 window = newWindow;
665
666 if (newWindow) {
667 QQuickOverlay *overlay = QQuickOverlay::overlay(window: newWindow);
668 if (overlay)
669 QQuickOverlayPrivate::get(overlay)->addPopup(popup: q);
670
671 QQuickControlPrivate *p = QQuickControlPrivate::get(control: popupItem);
672 p->resolveFont();
673 p->resolvePalette();
674 if (QQuickApplicationWindow *appWindow = qobject_cast<QQuickApplicationWindow *>(object: newWindow))
675 p->updateLocale(l: appWindow->locale(), e: false); // explicit=false
676 }
677
678 emit q->windowChanged(window: newWindow);
679
680 if (complete && visible && window)
681 transitionManager.transitionEnter();
682}
683
684void QQuickPopupPrivate::itemDestroyed(QQuickItem *item)
685{
686 Q_Q(QQuickPopup);
687 if (item == parentItem)
688 q->setParentItem(nullptr);
689}
690
691void QQuickPopupPrivate::reposition()
692{
693 getPositioner()->reposition();
694}
695
696static QQuickItem *createDimmer(QQmlComponent *component, QQuickPopup *popup, QQuickItem *parent)
697{
698 QQuickItem *item = nullptr;
699 if (component) {
700 QQmlContext *creationContext = component->creationContext();
701 if (!creationContext)
702 creationContext = qmlContext(popup);
703 QQmlContext *context = new QQmlContext(creationContext, popup);
704 context->setContextObject(popup);
705 item = qobject_cast<QQuickItem*>(object: component->beginCreate(context));
706 }
707
708 // when there is no overlay component available (with plain QQuickWindow),
709 // use a plain QQuickItem as a fallback to block hover events
710 if (!item && popup->isModal())
711 item = new QQuickItem;
712
713 if (item) {
714 item->setOpacity(popup->isVisible() ? 1.0 : 0.0);
715 item->setParentItem(parent);
716 item->stackBefore(popup->popupItem());
717 item->setZ(popup->z());
718 if (popup->isModal()) {
719 item->setAcceptedMouseButtons(Qt::AllButtons);
720#if QT_CONFIG(cursor)
721 item->setCursor(Qt::ArrowCursor);
722#endif
723#if QT_CONFIG(quicktemplates2_hover)
724 // TODO: switch to QStyleHints::useHoverEffects in Qt 5.8
725 item->setAcceptHoverEvents(true);
726 // item->setAcceptHoverEvents(QGuiApplication::styleHints()->useHoverEffects());
727 // connect(QGuiApplication::styleHints(), &QStyleHints::useHoverEffectsChanged, item, &QQuickItem::setAcceptHoverEvents);
728#endif
729 }
730 if (component)
731 component->completeCreate();
732 }
733 qCDebug(lcDimmer) << "finished creating dimmer from component" << component
734 << "for popup" << popup << "with parent" << parent << "- item is:" << item;
735 return item;
736}
737
738void QQuickPopupPrivate::createOverlay()
739{
740 Q_Q(QQuickPopup);
741 QQuickOverlay *overlay = QQuickOverlay::overlay(window);
742 if (!overlay)
743 return;
744
745 QQmlComponent *component = nullptr;
746 QQuickOverlayAttached *overlayAttached = qobject_cast<QQuickOverlayAttached *>(object: qmlAttachedPropertiesObject<QQuickOverlay>(obj: q, create: false));
747 if (overlayAttached)
748 component = modal ? overlayAttached->modal() : overlayAttached->modeless();
749
750 if (!component)
751 component = modal ? overlay->modal() : overlay->modeless();
752
753 if (!dimmer)
754 dimmer = createDimmer(component, popup: q, parent: overlay);
755 resizeOverlay();
756}
757
758void QQuickPopupPrivate::destroyOverlay()
759{
760 if (dimmer) {
761 qCDebug(lcDimmer) << "destroying dimmer" << dimmer;
762 dimmer->setParentItem(nullptr);
763 dimmer->deleteLater();
764 dimmer = nullptr;
765 }
766}
767
768void QQuickPopupPrivate::toggleOverlay()
769{
770 destroyOverlay();
771 if (dim)
772 createOverlay();
773}
774
775void QQuickPopupPrivate::showOverlay()
776{
777 // use QQmlProperty instead of QQuickItem::setOpacity() to trigger QML Behaviors
778 if (dim && dimmer)
779 QQmlProperty::write(dimmer, QStringLiteral("opacity"), 1.0);
780}
781
782void QQuickPopupPrivate::hideOverlay()
783{
784 // use QQmlProperty instead of QQuickItem::setOpacity() to trigger QML Behaviors
785 if (dim && dimmer)
786 QQmlProperty::write(dimmer, QStringLiteral("opacity"), 0.0);
787}
788
789void QQuickPopupPrivate::resizeOverlay()
790{
791 if (!dimmer)
792 return;
793
794 qreal w = window ? window->width() : 0;
795 qreal h = window ? window->height() : 0;
796 dimmer->setSize(QSizeF(w, h));
797}
798
799QQuickPopupTransitionManager::QQuickPopupTransitionManager(QQuickPopupPrivate *popup)
800 : popup(popup)
801{
802}
803
804void QQuickPopupTransitionManager::transitionEnter()
805{
806 if (popup->transitionState == QQuickPopupPrivate::ExitTransition)
807 cancel();
808
809 if (!popup->prepareEnterTransition())
810 return;
811
812 if (popup->window)
813 transition(popup->enterActions, transition: popup->enter, defaultTarget: popup->q_func());
814 else
815 finished();
816}
817
818void QQuickPopupTransitionManager::transitionExit()
819{
820 if (!popup->prepareExitTransition())
821 return;
822
823 if (popup->window)
824 transition(popup->exitActions, transition: popup->exit, defaultTarget: popup->q_func());
825 else
826 finished();
827}
828
829void QQuickPopupTransitionManager::finished()
830{
831 if (popup->transitionState == QQuickPopupPrivate::EnterTransition)
832 popup->finalizeEnterTransition();
833 else if (popup->transitionState == QQuickPopupPrivate::ExitTransition)
834 popup->finalizeExitTransition();
835}
836
837QQuickPopup::QQuickPopup(QObject *parent)
838 : QObject(*(new QQuickPopupPrivate), parent)
839{
840 Q_D(QQuickPopup);
841 d->init();
842}
843
844QQuickPopup::QQuickPopup(QQuickPopupPrivate &dd, QObject *parent)
845 : QObject(dd, parent)
846{
847 Q_D(QQuickPopup);
848 d->init();
849}
850
851QQuickPopup::~QQuickPopup()
852{
853 Q_D(QQuickPopup);
854 setParentItem(nullptr);
855 d->popupItem->ungrabShortcut();
856 delete d->popupItem;
857 d->popupItem = nullptr;
858 delete d->positioner;
859 d->positioner = nullptr;
860
861 // If the popup is destroyed before the exit transition finishes,
862 // the necessary cleanup (removing modal dimmers that block mouse events,
863 // emitting closed signal, etc.) won't happen. That's why we do it manually here.
864 if (d->transitionState == QQuickPopupPrivate::ExitTransition && d->transitionManager.isRunning())
865 d->finalizeExitTransition();
866}
867
868/*!
869 \qmlmethod void QtQuick.Controls::Popup::open()
870
871 Opens the popup.
872
873 \sa visible
874*/
875void QQuickPopup::open()
876{
877 setVisible(true);
878}
879
880/*!
881 \qmlmethod void QtQuick.Controls::Popup::close()
882
883 Closes the popup.
884
885 \sa visible
886*/
887void QQuickPopup::close()
888{
889 setVisible(false);
890}
891
892/*!
893 \qmlproperty real QtQuick.Controls::Popup::x
894
895 This property holds the x-coordinate of the popup.
896
897 \sa y, z
898*/
899qreal QQuickPopup::x() const
900{
901 Q_D(const QQuickPopup);
902 return d->effectiveX;
903}
904
905void QQuickPopup::setX(qreal x)
906{
907 Q_D(QQuickPopup);
908 setPosition(QPointF(x, d->y));
909}
910
911/*!
912 \qmlproperty real QtQuick.Controls::Popup::y
913
914 This property holds the y-coordinate of the popup.
915
916 \sa x, z
917*/
918qreal QQuickPopup::y() const
919{
920 Q_D(const QQuickPopup);
921 return d->effectiveY;
922}
923
924void QQuickPopup::setY(qreal y)
925{
926 Q_D(QQuickPopup);
927 setPosition(QPointF(d->x, y));
928}
929
930QPointF QQuickPopup::position() const
931{
932 Q_D(const QQuickPopup);
933 return QPointF(d->effectiveX, d->effectiveY);
934}
935
936void QQuickPopup::setPosition(const QPointF &pos)
937{
938 Q_D(QQuickPopup);
939 const bool xChange = !qFuzzyCompare(p1: d->x, p2: pos.x());
940 const bool yChange = !qFuzzyCompare(p1: d->y, p2: pos.y());
941 if (!xChange && !yChange)
942 return;
943
944 d->x = pos.x();
945 d->y = pos.y();
946 if (d->popupItem->isVisible()) {
947 d->reposition();
948 } else {
949 if (xChange)
950 emit xChanged();
951 if (yChange)
952 emit yChanged();
953 }
954}
955
956/*!
957 \qmlproperty real QtQuick.Controls::Popup::z
958
959 This property holds the z-value of the popup. Z-value determines
960 the stacking order of popups.
961
962 If two visible popups have the same z-value, the last one that
963 was opened will be on top.
964
965 The default z-value is \c 0.
966
967 \sa x, y
968*/
969qreal QQuickPopup::z() const
970{
971 Q_D(const QQuickPopup);
972 return d->popupItem->z();
973}
974
975void QQuickPopup::setZ(qreal z)
976{
977 Q_D(QQuickPopup);
978 if (qFuzzyCompare(p1: z, p2: d->popupItem->z()))
979 return;
980 d->popupItem->setZ(z);
981 emit zChanged();
982}
983
984/*!
985 \qmlproperty real QtQuick.Controls::Popup::width
986
987 This property holds the width of the popup.
988*/
989qreal QQuickPopup::width() const
990{
991 Q_D(const QQuickPopup);
992 return d->popupItem->width();
993}
994
995void QQuickPopup::setWidth(qreal width)
996{
997 Q_D(QQuickPopup);
998 d->hasWidth = true;
999 d->popupItem->setWidth(width);
1000}
1001
1002void QQuickPopup::resetWidth()
1003{
1004 Q_D(QQuickPopup);
1005 if (!d->hasWidth)
1006 return;
1007
1008 d->hasWidth = false;
1009 d->popupItem->resetWidth();
1010 if (d->popupItem->isVisible())
1011 d->reposition();
1012}
1013
1014/*!
1015 \qmlproperty real QtQuick.Controls::Popup::height
1016
1017 This property holds the height of the popup.
1018*/
1019qreal QQuickPopup::height() const
1020{
1021 Q_D(const QQuickPopup);
1022 return d->popupItem->height();
1023}
1024
1025void QQuickPopup::setHeight(qreal height)
1026{
1027 Q_D(QQuickPopup);
1028 d->hasHeight = true;
1029 d->popupItem->setHeight(height);
1030}
1031
1032void QQuickPopup::resetHeight()
1033{
1034 Q_D(QQuickPopup);
1035 if (!d->hasHeight)
1036 return;
1037
1038 d->hasHeight = false;
1039 d->popupItem->resetHeight();
1040 if (d->popupItem->isVisible())
1041 d->reposition();
1042}
1043
1044/*!
1045 \qmlproperty real QtQuick.Controls::Popup::implicitWidth
1046
1047 This property holds the implicit width of the popup.
1048*/
1049qreal QQuickPopup::implicitWidth() const
1050{
1051 Q_D(const QQuickPopup);
1052 return d->popupItem->implicitWidth();
1053}
1054
1055void QQuickPopup::setImplicitWidth(qreal width)
1056{
1057 Q_D(QQuickPopup);
1058 d->popupItem->setImplicitWidth(width);
1059}
1060
1061/*!
1062 \qmlproperty real QtQuick.Controls::Popup::implicitHeight
1063
1064 This property holds the implicit height of the popup.
1065*/
1066qreal QQuickPopup::implicitHeight() const
1067{
1068 Q_D(const QQuickPopup);
1069 return d->popupItem->implicitHeight();
1070}
1071
1072void QQuickPopup::setImplicitHeight(qreal height)
1073{
1074 Q_D(QQuickPopup);
1075 d->popupItem->setImplicitHeight(height);
1076}
1077
1078/*!
1079 \qmlproperty real QtQuick.Controls::Popup::contentWidth
1080
1081 This property holds the content width. It is used for calculating the
1082 total implicit width of the Popup.
1083
1084 For more information, see \l {Popup Sizing}.
1085
1086 \sa contentHeight
1087*/
1088qreal QQuickPopup::contentWidth() const
1089{
1090 Q_D(const QQuickPopup);
1091 return d->popupItem->contentWidth();
1092}
1093
1094void QQuickPopup::setContentWidth(qreal width)
1095{
1096 Q_D(QQuickPopup);
1097 d->popupItem->setContentWidth(width);
1098}
1099
1100/*!
1101 \qmlproperty real QtQuick.Controls::Popup::contentHeight
1102
1103 This property holds the content height. It is used for calculating the
1104 total implicit height of the Popup.
1105
1106 For more information, see \l {Popup Sizing}.
1107
1108 \sa contentWidth
1109*/
1110qreal QQuickPopup::contentHeight() const
1111{
1112 Q_D(const QQuickPopup);
1113 return d->popupItem->contentHeight();
1114}
1115
1116void QQuickPopup::setContentHeight(qreal height)
1117{
1118 Q_D(QQuickPopup);
1119 d->popupItem->setContentHeight(height);
1120}
1121
1122/*!
1123 \qmlproperty real QtQuick.Controls::Popup::availableWidth
1124 \readonly
1125
1126 This property holds the width available to the \l contentItem after
1127 deducting horizontal padding from the \l {Item::}{width} of the popup.
1128
1129 \sa padding, leftPadding, rightPadding
1130*/
1131qreal QQuickPopup::availableWidth() const
1132{
1133 Q_D(const QQuickPopup);
1134 return d->popupItem->availableWidth();
1135}
1136
1137/*!
1138 \qmlproperty real QtQuick.Controls::Popup::availableHeight
1139 \readonly
1140
1141 This property holds the height available to the \l contentItem after
1142 deducting vertical padding from the \l {Item::}{height} of the popup.
1143
1144 \sa padding, topPadding, bottomPadding
1145*/
1146qreal QQuickPopup::availableHeight() const
1147{
1148 Q_D(const QQuickPopup);
1149 return d->popupItem->availableHeight();
1150}
1151
1152/*!
1153 \since QtQuick.Controls 2.1 (Qt 5.8)
1154 \qmlproperty real QtQuick.Controls::Popup::spacing
1155
1156 This property holds the spacing.
1157
1158 Spacing is useful for popups that have multiple or repetitive building
1159 blocks. For example, some styles use spacing to determine the distance
1160 between the header, content, and footer of \l Dialog. Spacing is not
1161 enforced by Popup, so each style may interpret it differently, and some
1162 may ignore it altogether.
1163*/
1164qreal QQuickPopup::spacing() const
1165{
1166 Q_D(const QQuickPopup);
1167 return d->popupItem->spacing();
1168}
1169
1170void QQuickPopup::setSpacing(qreal spacing)
1171{
1172 Q_D(QQuickPopup);
1173 d->popupItem->setSpacing(spacing);
1174}
1175
1176void QQuickPopup::resetSpacing()
1177{
1178 setSpacing(0);
1179}
1180
1181/*!
1182 \qmlproperty real QtQuick.Controls::Popup::margins
1183
1184 This property holds the distance between the edges of the popup and the
1185 edges of its window.
1186
1187 A popup with negative margins is not pushed within the bounds
1188 of the enclosing window. The default value is \c -1.
1189
1190 \sa topMargin, leftMargin, rightMargin, bottomMargin, {Popup Layout}
1191*/
1192qreal QQuickPopup::margins() const
1193{
1194 Q_D(const QQuickPopup);
1195 return d->margins;
1196}
1197
1198void QQuickPopup::setMargins(qreal margins)
1199{
1200 Q_D(QQuickPopup);
1201 if (qFuzzyCompare(p1: d->margins, p2: margins))
1202 return;
1203 QMarginsF oldMargins(leftMargin(), topMargin(), rightMargin(), bottomMargin());
1204 d->margins = margins;
1205 emit marginsChanged();
1206 QMarginsF newMargins(leftMargin(), topMargin(), rightMargin(), bottomMargin());
1207 if (!qFuzzyCompare(p1: newMargins.top(), p2: oldMargins.top()))
1208 emit topMarginChanged();
1209 if (!qFuzzyCompare(p1: newMargins.left(), p2: oldMargins.left()))
1210 emit leftMarginChanged();
1211 if (!qFuzzyCompare(p1: newMargins.right(), p2: oldMargins.right()))
1212 emit rightMarginChanged();
1213 if (!qFuzzyCompare(p1: newMargins.bottom(), p2: oldMargins.bottom()))
1214 emit bottomMarginChanged();
1215 marginsChange(newMargins, oldMargins);
1216}
1217
1218void QQuickPopup::resetMargins()
1219{
1220 setMargins(-1);
1221}
1222
1223/*!
1224 \qmlproperty real QtQuick.Controls::Popup::topMargin
1225
1226 This property holds the distance between the top edge of the popup and
1227 the top edge of its window.
1228
1229 A popup with a negative top margin is not pushed within the top edge
1230 of the enclosing window. The default value is \c -1.
1231
1232 \sa margins, bottomMargin, {Popup Layout}
1233*/
1234qreal QQuickPopup::topMargin() const
1235{
1236 Q_D(const QQuickPopup);
1237 if (d->hasTopMargin)
1238 return d->topMargin;
1239 return d->margins;
1240}
1241
1242void QQuickPopup::setTopMargin(qreal margin)
1243{
1244 Q_D(QQuickPopup);
1245 d->setTopMargin(value: margin);
1246}
1247
1248void QQuickPopup::resetTopMargin()
1249{
1250 Q_D(QQuickPopup);
1251 d->setTopMargin(value: -1, reset: true);
1252}
1253
1254/*!
1255 \qmlproperty real QtQuick.Controls::Popup::leftMargin
1256
1257 This property holds the distance between the left edge of the popup and
1258 the left edge of its window.
1259
1260 A popup with a negative left margin is not pushed within the left edge
1261 of the enclosing window. The default value is \c -1.
1262
1263 \sa margins, rightMargin, {Popup Layout}
1264*/
1265qreal QQuickPopup::leftMargin() const
1266{
1267 Q_D(const QQuickPopup);
1268 if (d->hasLeftMargin)
1269 return d->leftMargin;
1270 return d->margins;
1271}
1272
1273void QQuickPopup::setLeftMargin(qreal margin)
1274{
1275 Q_D(QQuickPopup);
1276 d->setLeftMargin(value: margin);
1277}
1278
1279void QQuickPopup::resetLeftMargin()
1280{
1281 Q_D(QQuickPopup);
1282 d->setLeftMargin(value: -1, reset: true);
1283}
1284
1285/*!
1286 \qmlproperty real QtQuick.Controls::Popup::rightMargin
1287
1288 This property holds the distance between the right edge of the popup and
1289 the right edge of its window.
1290
1291 A popup with a negative right margin is not pushed within the right edge
1292 of the enclosing window. The default value is \c -1.
1293
1294 \sa margins, leftMargin, {Popup Layout}
1295*/
1296qreal QQuickPopup::rightMargin() const
1297{
1298 Q_D(const QQuickPopup);
1299 if (d->hasRightMargin)
1300 return d->rightMargin;
1301 return d->margins;
1302}
1303
1304void QQuickPopup::setRightMargin(qreal margin)
1305{
1306 Q_D(QQuickPopup);
1307 d->setRightMargin(value: margin);
1308}
1309
1310void QQuickPopup::resetRightMargin()
1311{
1312 Q_D(QQuickPopup);
1313 d->setRightMargin(value: -1, reset: true);
1314}
1315
1316/*!
1317 \qmlproperty real QtQuick.Controls::Popup::bottomMargin
1318
1319 This property holds the distance between the bottom edge of the popup and
1320 the bottom edge of its window.
1321
1322 A popup with a negative bottom margin is not pushed within the bottom edge
1323 of the enclosing window. The default value is \c -1.
1324
1325 \sa margins, topMargin, {Popup Layout}
1326*/
1327qreal QQuickPopup::bottomMargin() const
1328{
1329 Q_D(const QQuickPopup);
1330 if (d->hasBottomMargin)
1331 return d->bottomMargin;
1332 return d->margins;
1333}
1334
1335void QQuickPopup::setBottomMargin(qreal margin)
1336{
1337 Q_D(QQuickPopup);
1338 d->setBottomMargin(value: margin);
1339}
1340
1341void QQuickPopup::resetBottomMargin()
1342{
1343 Q_D(QQuickPopup);
1344 d->setBottomMargin(value: -1, reset: true);
1345}
1346
1347/*!
1348 \qmlproperty real QtQuick.Controls::Popup::padding
1349
1350 This property holds the default padding.
1351
1352 \include qquickpopup-padding.qdocinc
1353
1354 \sa availableWidth, availableHeight, topPadding, leftPadding, rightPadding, bottomPadding
1355*/
1356qreal QQuickPopup::padding() const
1357{
1358 Q_D(const QQuickPopup);
1359 return d->popupItem->padding();
1360}
1361
1362void QQuickPopup::setPadding(qreal padding)
1363{
1364 Q_D(QQuickPopup);
1365 d->popupItem->setPadding(padding);
1366}
1367
1368void QQuickPopup::resetPadding()
1369{
1370 Q_D(QQuickPopup);
1371 d->popupItem->resetPadding();
1372}
1373
1374/*!
1375 \qmlproperty real QtQuick.Controls::Popup::topPadding
1376
1377 This property holds the top padding. Unless explicitly set, the value
1378 is equal to \c verticalPadding.
1379
1380 \include qquickpopup-padding.qdocinc
1381
1382 \sa padding, bottomPadding, verticalPadding, availableHeight
1383*/
1384qreal QQuickPopup::topPadding() const
1385{
1386 Q_D(const QQuickPopup);
1387 return d->popupItem->topPadding();
1388}
1389
1390void QQuickPopup::setTopPadding(qreal padding)
1391{
1392 Q_D(QQuickPopup);
1393 d->popupItem->setTopPadding(padding);
1394}
1395
1396void QQuickPopup::resetTopPadding()
1397{
1398 Q_D(QQuickPopup);
1399 d->popupItem->resetTopPadding();
1400}
1401
1402/*!
1403 \qmlproperty real QtQuick.Controls::Popup::leftPadding
1404
1405 This property holds the left padding. Unless explicitly set, the value
1406 is equal to \c horizontalPadding.
1407
1408 \include qquickpopup-padding.qdocinc
1409
1410 \sa padding, rightPadding, horizontalPadding, availableWidth
1411*/
1412qreal QQuickPopup::leftPadding() const
1413{
1414 Q_D(const QQuickPopup);
1415 return d->popupItem->leftPadding();
1416}
1417
1418void QQuickPopup::setLeftPadding(qreal padding)
1419{
1420 Q_D(QQuickPopup);
1421 d->popupItem->setLeftPadding(padding);
1422}
1423
1424void QQuickPopup::resetLeftPadding()
1425{
1426 Q_D(QQuickPopup);
1427 d->popupItem->resetLeftPadding();
1428}
1429
1430/*!
1431 \qmlproperty real QtQuick.Controls::Popup::rightPadding
1432
1433 This property holds the right padding. Unless explicitly set, the value
1434 is equal to \c horizontalPadding.
1435
1436 \include qquickpopup-padding.qdocinc
1437
1438 \sa padding, leftPadding, horizontalPadding, availableWidth
1439*/
1440qreal QQuickPopup::rightPadding() const
1441{
1442 Q_D(const QQuickPopup);
1443 return d->popupItem->rightPadding();
1444}
1445
1446void QQuickPopup::setRightPadding(qreal padding)
1447{
1448 Q_D(QQuickPopup);
1449 d->popupItem->setRightPadding(padding);
1450}
1451
1452void QQuickPopup::resetRightPadding()
1453{
1454 Q_D(QQuickPopup);
1455 d->popupItem->resetRightPadding();
1456}
1457
1458/*!
1459 \qmlproperty real QtQuick.Controls::Popup::bottomPadding
1460
1461 This property holds the bottom padding. Unless explicitly set, the value
1462 is equal to \c verticalPadding.
1463
1464 \include qquickpopup-padding.qdocinc
1465
1466 \sa padding, topPadding, verticalPadding, availableHeight
1467*/
1468qreal QQuickPopup::bottomPadding() const
1469{
1470 Q_D(const QQuickPopup);
1471 return d->popupItem->bottomPadding();
1472}
1473
1474void QQuickPopup::setBottomPadding(qreal padding)
1475{
1476 Q_D(QQuickPopup);
1477 d->popupItem->setBottomPadding(padding);
1478}
1479
1480void QQuickPopup::resetBottomPadding()
1481{
1482 Q_D(QQuickPopup);
1483 d->popupItem->resetBottomPadding();
1484}
1485
1486/*!
1487 \qmlproperty Locale QtQuick.Controls::Popup::locale
1488
1489 This property holds the locale of the popup.
1490
1491 \sa mirrored, {LayoutMirroring}{LayoutMirroring}
1492*/
1493QLocale QQuickPopup::locale() const
1494{
1495 Q_D(const QQuickPopup);
1496 return d->popupItem->locale();
1497}
1498
1499void QQuickPopup::setLocale(const QLocale &locale)
1500{
1501 Q_D(QQuickPopup);
1502 d->popupItem->setLocale(locale);
1503}
1504
1505void QQuickPopup::resetLocale()
1506{
1507 Q_D(QQuickPopup);
1508 d->popupItem->resetLocale();
1509}
1510
1511/*!
1512 \since QtQuick.Controls 2.3 (Qt 5.10)
1513 \qmlproperty bool QtQuick.Controls::Popup::mirrored
1514 \readonly
1515
1516 This property holds whether the popup is mirrored.
1517
1518 This property is provided for convenience. A popup is considered mirrored
1519 when its visual layout direction is right-to-left; that is, when using a
1520 right-to-left locale.
1521
1522 \sa locale, {Right-to-left User Interfaces}
1523*/
1524bool QQuickPopup::isMirrored() const
1525{
1526 Q_D(const QQuickPopup);
1527 return d->popupItem->isMirrored();
1528}
1529
1530/*!
1531 \qmlproperty font QtQuick.Controls::Popup::font
1532
1533 This property holds the font currently set for the popup.
1534
1535 Popup propagates explicit font properties to its children. If you change a specific
1536 property on a popup's font, that property propagates to all of the popup's children,
1537 overriding any system defaults for that property.
1538
1539 \code
1540 Popup {
1541 font.family: "Courier"
1542
1543 Column {
1544 Label {
1545 text: qsTr("This will use Courier...")
1546 }
1547
1548 Switch {
1549 text: qsTr("... and so will this")
1550 }
1551 }
1552 }
1553 \endcode
1554
1555 \sa Control::font, ApplicationWindow::font
1556*/
1557QFont QQuickPopup::font() const
1558{
1559 Q_D(const QQuickPopup);
1560 return d->popupItem->font();
1561}
1562
1563void QQuickPopup::setFont(const QFont &font)
1564{
1565 Q_D(QQuickPopup);
1566 d->popupItem->setFont(font);
1567}
1568
1569void QQuickPopup::resetFont()
1570{
1571 Q_D(QQuickPopup);
1572 d->popupItem->resetFont();
1573}
1574
1575
1576/*!
1577 \since QtQuick.Controls 2.3 (Qt 5.10)
1578 \qmlproperty palette QtQuick.Controls::Popup::palette
1579
1580 This property holds the palette currently set for the popup.
1581
1582 Popup propagates explicit palette properties to its children. If you change a specific
1583 property on a popup's palette, that property propagates to all of the popup's children,
1584 overriding any system defaults for that property.
1585
1586 \code
1587 Popup {
1588 palette.text: "red"
1589
1590 Column {
1591 Label {
1592 text: qsTr("This will use red color...")
1593 }
1594
1595 Switch {
1596 text: qsTr("... and so will this")
1597 }
1598 }
1599 }
1600 \endcode
1601
1602 \sa Control::palette, ApplicationWindow::palette, {qtquickcontrols2-palette}{palette QML Basic Type}
1603*/
1604QPalette QQuickPopup::palette() const
1605{
1606 Q_D(const QQuickPopup);
1607 return d->popupItem->palette();
1608}
1609
1610void QQuickPopup::setPalette(const QPalette &palette)
1611{
1612 Q_D(QQuickPopup);
1613 d->popupItem->setPalette(palette);
1614}
1615
1616void QQuickPopup::resetPalette()
1617{
1618 Q_D(QQuickPopup);
1619 d->popupItem->resetPalette();
1620}
1621
1622QQuickWindow *QQuickPopup::window() const
1623{
1624 Q_D(const QQuickPopup);
1625 return d->window;
1626}
1627
1628QQuickItem *QQuickPopup::popupItem() const
1629{
1630 Q_D(const QQuickPopup);
1631 return d->popupItem;
1632}
1633
1634/*!
1635 \qmlproperty Item QtQuick.Controls::Popup::parent
1636
1637 This property holds the parent item.
1638*/
1639QQuickItem *QQuickPopup::parentItem() const
1640{
1641 Q_D(const QQuickPopup);
1642 return d->parentItem;
1643}
1644
1645void QQuickPopup::setParentItem(QQuickItem *parent)
1646{
1647 Q_D(QQuickPopup);
1648 if (d->parentItem == parent)
1649 return;
1650
1651 if (d->parentItem) {
1652 QObjectPrivate::disconnect(sender: d->parentItem, signal: &QQuickItem::windowChanged, receiverPrivate: d, slot: &QQuickPopupPrivate::setWindow);
1653 QQuickItemPrivate::get(item: d->parentItem)->removeItemChangeListener(d, types: QQuickItemPrivate::Destroyed);
1654 }
1655 d->parentItem = parent;
1656 QQuickPopupPositioner *positioner = d->getPositioner();
1657 if (positioner->parentItem())
1658 positioner->setParentItem(parent);
1659 if (parent) {
1660 QObjectPrivate::connect(sender: parent, signal: &QQuickItem::windowChanged, receiverPrivate: d, slot: &QQuickPopupPrivate::setWindow);
1661 QQuickItemPrivate::get(item: d->parentItem)->addItemChangeListener(listener: d, types: QQuickItemPrivate::Destroyed);
1662 } else {
1663 close();
1664 }
1665 d->setWindow(parent ? parent->window() : nullptr);
1666 emit parentChanged();
1667}
1668
1669void QQuickPopup::resetParentItem()
1670{
1671 if (QQuickWindow *window = qobject_cast<QQuickWindow *>(object: parent()))
1672 setParentItem(window->contentItem());
1673 else
1674 setParentItem(qobject_cast<QQuickItem *>(object: parent()));
1675}
1676
1677/*!
1678 \qmlproperty Item QtQuick.Controls::Popup::background
1679
1680 This property holds the background item.
1681
1682 \note If the background item has no explicit size specified, it automatically
1683 follows the popup's size. In most cases, there is no need to specify
1684 width or height for a background item.
1685
1686 \note Most popups use the implicit size of the background item to calculate
1687 the implicit size of the popup itself. If you replace the background item
1688 with a custom one, you should also consider providing a sensible implicit
1689 size for it (unless it is an item like \l Image which has its own implicit
1690 size).
1691
1692 \sa {Customizing Popup}
1693*/
1694QQuickItem *QQuickPopup::background() const
1695{
1696 Q_D(const QQuickPopup);
1697 return d->popupItem->background();
1698}
1699
1700void QQuickPopup::setBackground(QQuickItem *background)
1701{
1702 Q_D(QQuickPopup);
1703 d->popupItem->setBackground(background);
1704}
1705
1706/*!
1707 \qmlproperty Item QtQuick.Controls::Popup::contentItem
1708
1709 This property holds the content item of the popup.
1710
1711 The content item is the visual implementation of the popup. When the
1712 popup is made visible, the content item is automatically reparented to
1713 the \l {Overlay::overlay}{overlay item}.
1714
1715 \note The content item is automatically resized to fit within the
1716 \l padding of the popup.
1717
1718 \note Most popups use the implicit size of the content item to calculate
1719 the implicit size of the popup itself. If you replace the content item
1720 with a custom one, you should also consider providing a sensible implicit
1721 size for it (unless it is an item like \l Text which has its own implicit
1722 size).
1723
1724 \sa {Customizing Popup}
1725*/
1726QQuickItem *QQuickPopup::contentItem() const
1727{
1728 Q_D(const QQuickPopup);
1729 return d->popupItem->contentItem();
1730}
1731
1732void QQuickPopup::setContentItem(QQuickItem *item)
1733{
1734 Q_D(QQuickPopup);
1735 d->popupItem->setContentItem(item);
1736}
1737
1738/*!
1739 \qmlproperty list<Object> QtQuick.Controls::Popup::contentData
1740 \default
1741
1742 This property holds the list of content data.
1743
1744 The list contains all objects that have been declared in QML as children
1745 of the popup.
1746
1747 \note Unlike \c contentChildren, \c contentData does include non-visual QML
1748 objects.
1749
1750 \sa Item::data, contentChildren
1751*/
1752QQmlListProperty<QObject> QQuickPopupPrivate::contentData()
1753{
1754 QQuickControlPrivate *p = QQuickControlPrivate::get(control: popupItem);
1755 if (!p->contentItem)
1756 p->executeContentItem();
1757 return QQmlListProperty<QObject>(popupItem->contentItem(), nullptr,
1758 QQuickItemPrivate::data_append,
1759 QQuickItemPrivate::data_count,
1760 QQuickItemPrivate::data_at,
1761 QQuickItemPrivate::data_clear);
1762}
1763
1764/*!
1765 \qmlproperty list<Item> QtQuick.Controls::Popup::contentChildren
1766
1767 This property holds the list of content children.
1768
1769 The list contains all items that have been declared in QML as children
1770 of the popup.
1771
1772 \note Unlike \c contentData, \c contentChildren does not include non-visual
1773 QML objects.
1774
1775 \sa Item::children, contentData
1776*/
1777QQmlListProperty<QQuickItem> QQuickPopupPrivate::contentChildren()
1778{
1779 return QQmlListProperty<QQuickItem>(popupItem->contentItem(), nullptr,
1780 QQuickItemPrivate::children_append,
1781 QQuickItemPrivate::children_count,
1782 QQuickItemPrivate::children_at,
1783 QQuickItemPrivate::children_clear);
1784}
1785
1786/*!
1787 \qmlproperty bool QtQuick.Controls::Popup::clip
1788
1789 This property holds whether clipping is enabled. The default value is \c false.
1790*/
1791bool QQuickPopup::clip() const
1792{
1793 Q_D(const QQuickPopup);
1794 return d->popupItem->clip();
1795}
1796
1797void QQuickPopup::setClip(bool clip)
1798{
1799 Q_D(QQuickPopup);
1800 if (clip == d->popupItem->clip())
1801 return;
1802 d->popupItem->setClip(clip);
1803 emit clipChanged();
1804}
1805
1806/*!
1807 \qmlproperty bool QtQuick.Controls::Popup::focus
1808
1809 This property holds whether the popup wants focus.
1810
1811 When the popup actually receives focus, \l activeFocus will be \c true.
1812 For more information, see \l {Keyboard Focus in Qt Quick}.
1813
1814 The default value is \c false.
1815
1816 \sa activeFocus
1817*/
1818bool QQuickPopup::hasFocus() const
1819{
1820 Q_D(const QQuickPopup);
1821 return d->focus;
1822}
1823
1824void QQuickPopup::setFocus(bool focus)
1825{
1826 Q_D(QQuickPopup);
1827 if (d->focus == focus)
1828 return;
1829 d->focus = focus;
1830 emit focusChanged();
1831}
1832
1833/*!
1834 \qmlproperty bool QtQuick.Controls::Popup::activeFocus
1835 \readonly
1836
1837 This property holds whether the popup has active focus.
1838
1839 \sa focus, {Keyboard Focus in Qt Quick}
1840*/
1841bool QQuickPopup::hasActiveFocus() const
1842{
1843 Q_D(const QQuickPopup);
1844 return d->popupItem->hasActiveFocus();
1845}
1846
1847/*!
1848 \qmlproperty bool QtQuick.Controls::Popup::modal
1849
1850 This property holds whether the popup is modal.
1851
1852 Modal popups often have a distinctive background dimming effect defined
1853 in \l {Overlay::modal}{Overlay.modal}, and do not allow press
1854 or release events through to items beneath them. For example, if the user
1855 accidentally clicks outside of a popup, any item beneath that popup at
1856 the location of the click will not receive the event.
1857
1858 On desktop platforms, it is common for modal popups to be closed only when
1859 the escape key is pressed. To achieve this behavior, set
1860 \l closePolicy to \c Popup.CloseOnEscape. By default, \c closePolicy
1861 is set to \c {Popup.CloseOnEscape | Popup.CloseOnPressOutside}, which
1862 means that clicking outside of a modal popup will close it.
1863
1864 The default value is \c false.
1865
1866 \sa dim
1867*/
1868bool QQuickPopup::isModal() const
1869{
1870 Q_D(const QQuickPopup);
1871 return d->modal;
1872}
1873
1874void QQuickPopup::setModal(bool modal)
1875{
1876 Q_D(QQuickPopup);
1877 if (d->modal == modal)
1878 return;
1879 d->modal = modal;
1880 if (d->complete && d->visible)
1881 d->toggleOverlay();
1882 emit modalChanged();
1883
1884 QQuickItemPrivate::get(item: d->popupItem)->isTabFence = modal;
1885
1886 if (!d->hasDim) {
1887 setDim(modal);
1888 d->hasDim = false;
1889 }
1890}
1891
1892/*!
1893 \qmlproperty bool QtQuick.Controls::Popup::dim
1894
1895 This property holds whether the popup dims the background.
1896
1897 Unless explicitly set, this property follows the value of \l modal. To
1898 return to the default value, set this property to \c undefined.
1899
1900 \sa modal, {Overlay::modeless}{Overlay.modeless}
1901*/
1902bool QQuickPopup::dim() const
1903{
1904 Q_D(const QQuickPopup);
1905 return d->dim;
1906}
1907
1908void QQuickPopup::setDim(bool dim)
1909{
1910 Q_D(QQuickPopup);
1911 d->hasDim = true;
1912
1913 if (d->dim == dim)
1914 return;
1915
1916 d->dim = dim;
1917 if (d->complete && d->visible)
1918 d->toggleOverlay();
1919 emit dimChanged();
1920}
1921
1922void QQuickPopup::resetDim()
1923{
1924 Q_D(QQuickPopup);
1925 if (!d->hasDim)
1926 return;
1927
1928 setDim(d->modal);
1929 d->hasDim = false;
1930}
1931
1932/*!
1933 \qmlproperty bool QtQuick.Controls::Popup::visible
1934
1935 This property holds whether the popup is visible. The default value is \c false.
1936
1937 \sa open(), close(), opened
1938*/
1939bool QQuickPopup::isVisible() const
1940{
1941 Q_D(const QQuickPopup);
1942 return d->visible && d->popupItem->isVisible();
1943}
1944
1945void QQuickPopup::setVisible(bool visible)
1946{
1947 Q_D(QQuickPopup);
1948 if (d->visible == visible && d->transitionState != QQuickPopupPrivate::ExitTransition)
1949 return;
1950
1951 if (d->complete) {
1952 if (visible)
1953 d->transitionManager.transitionEnter();
1954 else
1955 d->transitionManager.transitionExit();
1956 } else {
1957 d->visible = visible;
1958 }
1959}
1960
1961/*!
1962 \since QtQuick.Controls 2.3 (Qt 5.10)
1963 \qmlproperty bool QtQuick.Controls::Popup::enabled
1964
1965 This property holds whether the popup is enabled. The default value is \c true.
1966
1967 \sa visible, Item::enabled
1968*/
1969bool QQuickPopup::isEnabled() const
1970{
1971 Q_D(const QQuickPopup);
1972 return d->popupItem->isEnabled();
1973}
1974
1975void QQuickPopup::setEnabled(bool enabled)
1976{
1977 Q_D(QQuickPopup);
1978 d->popupItem->setEnabled(enabled);
1979}
1980
1981/*!
1982 \since QtQuick.Controls 2.3 (Qt 5.10)
1983 \qmlproperty bool QtQuick.Controls::Popup::opened
1984
1985 This property holds whether the popup is fully open. The popup is considered opened
1986 when it's visible and neither the \l enter nor \l exit transitions are running.
1987
1988 \sa open(), close(), visible
1989*/
1990bool QQuickPopup::isOpened() const
1991{
1992 Q_D(const QQuickPopup);
1993 return d->transitionState == QQuickPopupPrivate::NoTransition && isVisible();
1994}
1995
1996/*!
1997 \qmlproperty real QtQuick.Controls::Popup::opacity
1998
1999 This property holds the opacity of the popup. Opacity is specified as a number between
2000 \c 0.0 (fully transparent) and \c 1.0 (fully opaque). The default value is \c 1.0.
2001
2002 \sa visible
2003*/
2004qreal QQuickPopup::opacity() const
2005{
2006 Q_D(const QQuickPopup);
2007 return d->popupItem->opacity();
2008}
2009
2010void QQuickPopup::setOpacity(qreal opacity)
2011{
2012 Q_D(QQuickPopup);
2013 d->popupItem->setOpacity(opacity);
2014}
2015
2016/*!
2017 \qmlproperty real QtQuick.Controls::Popup::scale
2018
2019 This property holds the scale factor of the popup. The default value is \c 1.0.
2020
2021 A scale of less than \c 1.0 causes the popup to be rendered at a smaller size,
2022 and a scale greater than \c 1.0 renders the popup at a larger size. Negative
2023 scales are not supported.
2024*/
2025qreal QQuickPopup::scale() const
2026{
2027 Q_D(const QQuickPopup);
2028 return d->popupItem->scale();
2029}
2030
2031void QQuickPopup::setScale(qreal scale)
2032{
2033 Q_D(QQuickPopup);
2034 if (qFuzzyCompare(p1: scale, p2: d->popupItem->scale()))
2035 return;
2036 d->popupItem->setScale(scale);
2037 emit scaleChanged();
2038}
2039
2040/*!
2041 \qmlproperty enumeration QtQuick.Controls::Popup::closePolicy
2042
2043 This property determines the circumstances under which the popup closes.
2044 The flags can be combined to allow several ways of closing the popup.
2045
2046 The available values are:
2047 \value Popup.NoAutoClose The popup will only close when manually instructed to do so.
2048 \value Popup.CloseOnPressOutside The popup will close when the mouse is pressed outside of it.
2049 \value Popup.CloseOnPressOutsideParent The popup will close when the mouse is pressed outside of its parent.
2050 \value Popup.CloseOnReleaseOutside The popup will close when the mouse is released outside of it.
2051 \value Popup.CloseOnReleaseOutsideParent The popup will close when the mouse is released outside of its parent.
2052 \value Popup.CloseOnEscape The popup will close when the escape key is pressed while the popup
2053 has active focus.
2054
2055 The default value is \c {Popup.CloseOnEscape | Popup.CloseOnPressOutside}.
2056
2057 \note There is a known limitation that the \c Popup.CloseOnReleaseOutside
2058 and \c Popup.CloseOnReleaseOutsideParent policies only work with
2059 \l modal popups.
2060*/
2061QQuickPopup::ClosePolicy QQuickPopup::closePolicy() const
2062{
2063 Q_D(const QQuickPopup);
2064 return d->closePolicy;
2065}
2066
2067void QQuickPopup::setClosePolicy(ClosePolicy policy)
2068{
2069 Q_D(QQuickPopup);
2070 d->hasClosePolicy = true;
2071 if (d->closePolicy == policy)
2072 return;
2073 d->closePolicy = policy;
2074 if (isVisible()) {
2075 if (policy & QQuickPopup::CloseOnEscape)
2076 d->popupItem->grabShortcut();
2077 else
2078 d->popupItem->ungrabShortcut();
2079 }
2080 emit closePolicyChanged();
2081}
2082
2083void QQuickPopup::resetClosePolicy()
2084{
2085 Q_D(QQuickPopup);
2086 setClosePolicy(QQuickPopupPrivate::DefaultClosePolicy);
2087 d->hasClosePolicy = false;
2088}
2089
2090/*!
2091 \qmlproperty enumeration QtQuick.Controls::Popup::transformOrigin
2092
2093 This property holds the origin point for transformations in enter and exit transitions.
2094
2095 Nine transform origins are available, as shown in the image below.
2096 The default transform origin is \c Popup.Center.
2097
2098 \image qtquickcontrols2-popup-transformorigin.png
2099
2100 \sa enter, exit, Item::transformOrigin
2101*/
2102QQuickPopup::TransformOrigin QQuickPopup::transformOrigin() const
2103{
2104 Q_D(const QQuickPopup);
2105 return static_cast<TransformOrigin>(d->popupItem->transformOrigin());
2106}
2107
2108void QQuickPopup::setTransformOrigin(TransformOrigin origin)
2109{
2110 Q_D(QQuickPopup);
2111 d->popupItem->setTransformOrigin(static_cast<QQuickItem::TransformOrigin>(origin));
2112}
2113
2114/*!
2115 \qmlproperty Transition QtQuick.Controls::Popup::enter
2116
2117 This property holds the transition that is applied to the popup item
2118 when the popup is opened and enters the screen.
2119
2120 The following example animates the opacity of the popup when it enters
2121 the screen:
2122 \code
2123 Popup {
2124 enter: Transition {
2125 NumberAnimation { property: "opacity"; from: 0.0; to: 1.0 }
2126 }
2127 }
2128 \endcode
2129
2130 \sa exit
2131*/
2132QQuickTransition *QQuickPopup::enter() const
2133{
2134 Q_D(const QQuickPopup);
2135 return d->enter;
2136}
2137
2138void QQuickPopup::setEnter(QQuickTransition *transition)
2139{
2140 Q_D(QQuickPopup);
2141 if (d->enter == transition)
2142 return;
2143 d->enter = transition;
2144 emit enterChanged();
2145}
2146
2147/*!
2148 \qmlproperty Transition QtQuick.Controls::Popup::exit
2149
2150 This property holds the transition that is applied to the popup item
2151 when the popup is closed and exits the screen.
2152
2153 The following example animates the opacity of the popup when it exits
2154 the screen:
2155 \code
2156 Popup {
2157 exit: Transition {
2158 NumberAnimation { property: "opacity"; from: 1.0; to: 0.0 }
2159 }
2160 }
2161 \endcode
2162
2163 \sa enter
2164*/
2165QQuickTransition *QQuickPopup::exit() const
2166{
2167 Q_D(const QQuickPopup);
2168 return d->exit;
2169}
2170
2171void QQuickPopup::setExit(QQuickTransition *transition)
2172{
2173 Q_D(QQuickPopup);
2174 if (d->exit == transition)
2175 return;
2176 d->exit = transition;
2177 emit exitChanged();
2178}
2179
2180/*!
2181 \since QtQuick.Controls 2.5 (Qt 5.12)
2182 \qmlproperty real QtQuick.Controls::Popup::horizontalPadding
2183
2184 This property holds the horizontal padding. Unless explicitly set, the value
2185 is equal to \c padding.
2186
2187 \include qquickpopup-padding.qdocinc
2188
2189 \sa padding, leftPadding, rightPadding, verticalPadding
2190*/
2191qreal QQuickPopup::horizontalPadding() const
2192{
2193 Q_D(const QQuickPopup);
2194 return d->popupItem->horizontalPadding();
2195}
2196
2197void QQuickPopup::setHorizontalPadding(qreal padding)
2198{
2199 Q_D(QQuickPopup);
2200 d->popupItem->setHorizontalPadding(padding);
2201}
2202
2203void QQuickPopup::resetHorizontalPadding()
2204{
2205 Q_D(QQuickPopup);
2206 d->popupItem->resetHorizontalPadding();
2207}
2208
2209/*!
2210 \since QtQuick.Controls 2.5 (Qt 5.12)
2211 \qmlproperty real QtQuick.Controls::Popup::verticalPadding
2212
2213 This property holds the vertical padding. Unless explicitly set, the value
2214 is equal to \c padding.
2215
2216 \include qquickpopup-padding.qdocinc
2217
2218 \sa padding, topPadding, bottomPadding, horizontalPadding
2219*/
2220qreal QQuickPopup::verticalPadding() const
2221{
2222 Q_D(const QQuickPopup);
2223 return d->popupItem->verticalPadding();
2224}
2225
2226void QQuickPopup::setVerticalPadding(qreal padding)
2227{
2228 Q_D(QQuickPopup);
2229 d->popupItem->setVerticalPadding(padding);
2230}
2231
2232void QQuickPopup::resetVerticalPadding()
2233{
2234 Q_D(QQuickPopup);
2235 d->popupItem->resetVerticalPadding();
2236}
2237
2238/*!
2239 \since QtQuick.Controls 2.5 (Qt 5.12)
2240 \qmlproperty real QtQuick.Controls::Popup::implicitContentWidth
2241 \readonly
2242
2243 This property holds the implicit content width.
2244
2245 The value is calculated based on the content children.
2246
2247 \sa implicitContentHeight, implicitBackgroundWidth
2248*/
2249qreal QQuickPopup::implicitContentWidth() const
2250{
2251 Q_D(const QQuickPopup);
2252 return d->popupItem->implicitContentWidth();
2253}
2254
2255/*!
2256 \since QtQuick.Controls 2.5 (Qt 5.12)
2257 \qmlproperty real QtQuick.Controls::Popup::implicitContentHeight
2258 \readonly
2259
2260 This property holds the implicit content height.
2261
2262 The value is calculated based on the content children.
2263
2264 \sa implicitContentWidth, implicitBackgroundHeight
2265*/
2266qreal QQuickPopup::implicitContentHeight() const
2267{
2268 Q_D(const QQuickPopup);
2269 return d->popupItem->implicitContentHeight();
2270}
2271
2272/*!
2273 \since QtQuick.Controls 2.5 (Qt 5.12)
2274 \qmlproperty real QtQuick.Controls::Popup::implicitBackgroundWidth
2275 \readonly
2276
2277 This property holds the implicit background width.
2278
2279 The value is equal to \c {background ? background.implicitWidth : 0}.
2280
2281 \sa implicitBackgroundHeight, implicitContentWidth
2282*/
2283qreal QQuickPopup::implicitBackgroundWidth() const
2284{
2285 Q_D(const QQuickPopup);
2286 return d->popupItem->implicitBackgroundWidth();
2287}
2288
2289/*!
2290 \since QtQuick.Controls 2.5 (Qt 5.12)
2291 \qmlproperty real QtQuick.Controls::Popup::implicitBackgroundHeight
2292 \readonly
2293
2294 This property holds the implicit background height.
2295
2296 The value is equal to \c {background ? background.implicitHeight : 0}.
2297
2298 \sa implicitBackgroundWidth, implicitContentHeight
2299*/
2300qreal QQuickPopup::implicitBackgroundHeight() const
2301{
2302 Q_D(const QQuickPopup);
2303 return d->popupItem->implicitBackgroundHeight();
2304}
2305
2306/*!
2307 \since QtQuick.Controls 2.5 (Qt 5.12)
2308 \qmlproperty real QtQuick.Controls::Popup::topInset
2309
2310 This property holds the top inset for the background.
2311
2312 \sa {Popup Layout}, bottomInset
2313*/
2314qreal QQuickPopup::topInset() const
2315{
2316 Q_D(const QQuickPopup);
2317 return d->popupItem->topInset();
2318}
2319
2320void QQuickPopup::setTopInset(qreal inset)
2321{
2322 Q_D(QQuickPopup);
2323 d->popupItem->setTopInset(inset);
2324}
2325
2326void QQuickPopup::resetTopInset()
2327{
2328 Q_D(QQuickPopup);
2329 d->popupItem->resetTopInset();
2330}
2331
2332/*!
2333 \since QtQuick.Controls 2.5 (Qt 5.12)
2334 \qmlproperty real QtQuick.Controls::Popup::leftInset
2335
2336 This property holds the left inset for the background.
2337
2338 \sa {Popup Layout}, rightInset
2339*/
2340qreal QQuickPopup::leftInset() const
2341{
2342 Q_D(const QQuickPopup);
2343 return d->popupItem->leftInset();
2344}
2345
2346void QQuickPopup::setLeftInset(qreal inset)
2347{
2348 Q_D(QQuickPopup);
2349 d->popupItem->setLeftInset(inset);
2350}
2351
2352void QQuickPopup::resetLeftInset()
2353{
2354 Q_D(QQuickPopup);
2355 d->popupItem->resetLeftInset();
2356}
2357
2358/*!
2359 \since QtQuick.Controls 2.5 (Qt 5.12)
2360 \qmlproperty real QtQuick.Controls::Popup::rightInset
2361
2362 This property holds the right inset for the background.
2363
2364 \sa {Popup Layout}, leftInset
2365*/
2366qreal QQuickPopup::rightInset() const
2367{
2368 Q_D(const QQuickPopup);
2369 return d->popupItem->rightInset();
2370}
2371
2372void QQuickPopup::setRightInset(qreal inset)
2373{
2374 Q_D(QQuickPopup);
2375 d->popupItem->setRightInset(inset);
2376}
2377
2378void QQuickPopup::resetRightInset()
2379{
2380 Q_D(QQuickPopup);
2381 d->popupItem->resetRightInset();
2382}
2383
2384/*!
2385 \since QtQuick.Controls 2.5 (Qt 5.12)
2386 \qmlproperty real QtQuick.Controls::Popup::bottomInset
2387
2388 This property holds the bottom inset for the background.
2389
2390 \sa {Popup Layout}, topInset
2391*/
2392qreal QQuickPopup::bottomInset() const
2393{
2394 Q_D(const QQuickPopup);
2395 return d->popupItem->bottomInset();
2396}
2397
2398void QQuickPopup::setBottomInset(qreal inset)
2399{
2400 Q_D(QQuickPopup);
2401 d->popupItem->setBottomInset(inset);
2402}
2403
2404void QQuickPopup::resetBottomInset()
2405{
2406 Q_D(QQuickPopup);
2407 d->popupItem->resetBottomInset();
2408}
2409
2410bool QQuickPopup::filtersChildMouseEvents() const
2411{
2412 Q_D(const QQuickPopup);
2413 return d->popupItem->filtersChildMouseEvents();
2414}
2415
2416void QQuickPopup::setFiltersChildMouseEvents(bool filter)
2417{
2418 Q_D(QQuickPopup);
2419 d->popupItem->setFiltersChildMouseEvents(filter);
2420}
2421
2422/*!
2423 \qmlmethod QtQuick.Controls::Popup::forceActiveFocus(enumeration reason = Qt.OtherFocusReason)
2424
2425 Forces active focus on the popup with the given \a reason.
2426
2427 This method sets focus on the popup and ensures that all ancestor
2428 \l FocusScope objects in the object hierarchy are also given \l focus.
2429
2430 \sa activeFocus, Qt::FocusReason
2431*/
2432void QQuickPopup::forceActiveFocus(Qt::FocusReason reason)
2433{
2434 Q_D(QQuickPopup);
2435 d->popupItem->forceActiveFocus(reason);
2436}
2437
2438void QQuickPopup::classBegin()
2439{
2440 Q_D(QQuickPopup);
2441 d->complete = false;
2442 QQmlContext *context = qmlContext(this);
2443 if (context)
2444 QQmlEngine::setContextForObject(d->popupItem, context);
2445 d->popupItem->classBegin();
2446}
2447
2448void QQuickPopup::componentComplete()
2449{
2450 Q_D(QQuickPopup);
2451 if (!parentItem())
2452 resetParentItem();
2453
2454 if (d->visible && d->window)
2455 d->transitionManager.transitionEnter();
2456
2457 d->complete = true;
2458 d->popupItem->componentComplete();
2459
2460 if (isVisible()) {
2461 if (d->closePolicy & QQuickPopup::CloseOnEscape)
2462 d->popupItem->grabShortcut();
2463 else
2464 d->popupItem->ungrabShortcut();
2465 }
2466}
2467
2468bool QQuickPopup::isComponentComplete() const
2469{
2470 Q_D(const QQuickPopup);
2471 return d->complete;
2472}
2473
2474bool QQuickPopup::childMouseEventFilter(QQuickItem *child, QEvent *event)
2475{
2476 Q_UNUSED(child);
2477 Q_UNUSED(event);
2478 return false;
2479}
2480
2481void QQuickPopup::focusInEvent(QFocusEvent *event)
2482{
2483 event->accept();
2484}
2485
2486void QQuickPopup::focusOutEvent(QFocusEvent *event)
2487{
2488 event->accept();
2489}
2490
2491void QQuickPopup::keyPressEvent(QKeyEvent *event)
2492{
2493 Q_D(QQuickPopup);
2494 event->accept();
2495
2496 if (hasActiveFocus() && (event->key() == Qt::Key_Tab || event->key() == Qt::Key_Backtab))
2497 QQuickItemPrivate::focusNextPrev(item: d->popupItem, forward: event->key() == Qt::Key_Tab);
2498}
2499
2500void QQuickPopup::keyReleaseEvent(QKeyEvent *event)
2501{
2502 event->accept();
2503}
2504
2505void QQuickPopup::mousePressEvent(QMouseEvent *event)
2506{
2507 Q_D(QQuickPopup);
2508 d->handleMouseEvent(item: d->popupItem, event);
2509 event->accept();
2510}
2511
2512void QQuickPopup::mouseMoveEvent(QMouseEvent *event)
2513{
2514 Q_D(QQuickPopup);
2515 d->handleMouseEvent(item: d->popupItem, event);
2516 event->accept();
2517}
2518
2519void QQuickPopup::mouseReleaseEvent(QMouseEvent *event)
2520{
2521 Q_D(QQuickPopup);
2522 d->handleMouseEvent(item: d->popupItem, event);
2523 event->accept();
2524}
2525
2526void QQuickPopup::mouseDoubleClickEvent(QMouseEvent *event)
2527{
2528 event->accept();
2529}
2530
2531void QQuickPopup::mouseUngrabEvent()
2532{
2533 Q_D(QQuickPopup);
2534 d->handleUngrab();
2535}
2536
2537bool QQuickPopup::overlayEvent(QQuickItem *item, QEvent *event)
2538{
2539 Q_D(QQuickPopup);
2540 switch (event->type()) {
2541 case QEvent::KeyPress:
2542 case QEvent::KeyRelease:
2543 case QEvent::MouseMove:
2544 case QEvent::Wheel:
2545 if (d->modal)
2546 event->accept();
2547 return d->modal;
2548
2549#if QT_CONFIG(quicktemplates2_multitouch)
2550 case QEvent::TouchBegin:
2551 case QEvent::TouchUpdate:
2552 case QEvent::TouchEnd:
2553 return d->handleTouchEvent(item, event: static_cast<QTouchEvent *>(event));
2554#endif
2555
2556 case QEvent::MouseButtonPress:
2557 case QEvent::MouseButtonRelease:
2558 return d->handleMouseEvent(item, event: static_cast<QMouseEvent *>(event));
2559
2560 default:
2561 return false;
2562 }
2563}
2564
2565#if QT_CONFIG(quicktemplates2_multitouch)
2566void QQuickPopup::touchEvent(QTouchEvent *event)
2567{
2568 Q_D(QQuickPopup);
2569 d->handleTouchEvent(item: d->popupItem, event);
2570}
2571
2572void QQuickPopup::touchUngrabEvent()
2573{
2574 Q_D(QQuickPopup);
2575 d->handleUngrab();
2576}
2577#endif
2578
2579#if QT_CONFIG(wheelevent)
2580void QQuickPopup::wheelEvent(QWheelEvent *event)
2581{
2582 event->accept();
2583}
2584#endif
2585
2586void QQuickPopup::contentItemChange(QQuickItem *newItem, QQuickItem *oldItem)
2587{
2588 Q_UNUSED(newItem);
2589 Q_UNUSED(oldItem);
2590}
2591
2592void QQuickPopup::contentSizeChange(const QSizeF &newSize, const QSizeF &oldSize)
2593{
2594 if (!qFuzzyCompare(p1: newSize.width(), p2: oldSize.width()))
2595 emit contentWidthChanged();
2596 if (!qFuzzyCompare(p1: newSize.height(), p2: oldSize.height()))
2597 emit contentHeightChanged();
2598}
2599
2600void QQuickPopup::fontChange(const QFont &newFont, const QFont &oldFont)
2601{
2602 Q_UNUSED(newFont);
2603 Q_UNUSED(oldFont);
2604 emit fontChanged();
2605}
2606
2607void QQuickPopup::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
2608{
2609 Q_D(QQuickPopup);
2610 d->reposition();
2611 if (!qFuzzyCompare(p1: newGeometry.width(), p2: oldGeometry.width())) {
2612 emit widthChanged();
2613 emit availableWidthChanged();
2614 }
2615 if (!qFuzzyCompare(p1: newGeometry.height(), p2: oldGeometry.height())) {
2616 emit heightChanged();
2617 emit availableHeightChanged();
2618 }
2619}
2620
2621void QQuickPopup::itemChange(QQuickItem::ItemChange change, const QQuickItem::ItemChangeData &data)
2622{
2623 Q_D(QQuickPopup);
2624
2625 switch (change) {
2626 case QQuickItem::ItemActiveFocusHasChanged:
2627 emit activeFocusChanged();
2628 break;
2629 case QQuickItem::ItemOpacityHasChanged:
2630 emit opacityChanged();
2631 break;
2632 case QQuickItem::ItemVisibleHasChanged:
2633 if (isComponentComplete() && d->closePolicy & CloseOnEscape) {
2634 if (data.boolValue)
2635 d->popupItem->grabShortcut();
2636 else
2637 d->popupItem->ungrabShortcut();
2638 }
2639 break;
2640 default:
2641 break;
2642 }
2643}
2644
2645void QQuickPopup::localeChange(const QLocale &newLocale, const QLocale &oldLocale)
2646{
2647 Q_UNUSED(newLocale);
2648 Q_UNUSED(oldLocale);
2649 emit localeChanged();
2650}
2651
2652void QQuickPopup::marginsChange(const QMarginsF &newMargins, const QMarginsF &oldMargins)
2653{
2654 Q_D(QQuickPopup);
2655 Q_UNUSED(newMargins);
2656 Q_UNUSED(oldMargins);
2657 d->reposition();
2658}
2659
2660void QQuickPopup::paddingChange(const QMarginsF &newPadding, const QMarginsF &oldPadding)
2661{
2662 const bool tp = !qFuzzyCompare(p1: newPadding.top(), p2: oldPadding.top());
2663 const bool lp = !qFuzzyCompare(p1: newPadding.left(), p2: oldPadding.left());
2664 const bool rp = !qFuzzyCompare(p1: newPadding.right(), p2: oldPadding.right());
2665 const bool bp = !qFuzzyCompare(p1: newPadding.bottom(), p2: oldPadding.bottom());
2666
2667 if (tp)
2668 emit topPaddingChanged();
2669 if (lp)
2670 emit leftPaddingChanged();
2671 if (rp)
2672 emit rightPaddingChanged();
2673 if (bp)
2674 emit bottomPaddingChanged();
2675
2676 if (lp || rp) {
2677 emit horizontalPaddingChanged();
2678 emit availableWidthChanged();
2679 }
2680 if (tp || bp) {
2681 emit verticalPaddingChanged();
2682 emit availableHeightChanged();
2683 }
2684}
2685
2686void QQuickPopup::paletteChange(const QPalette &newPalette, const QPalette &oldPalette)
2687{
2688 Q_UNUSED(newPalette);
2689 Q_UNUSED(oldPalette);
2690 emit paletteChanged();
2691}
2692
2693void QQuickPopup::spacingChange(qreal newSpacing, qreal oldSpacing)
2694{
2695 Q_UNUSED(newSpacing);
2696 Q_UNUSED(oldSpacing);
2697 emit spacingChanged();
2698}
2699
2700void QQuickPopup::insetChange(const QMarginsF &newInset, const QMarginsF &oldInset)
2701{
2702 if (!qFuzzyCompare(p1: newInset.top(), p2: oldInset.top()))
2703 emit topInsetChanged();
2704 if (!qFuzzyCompare(p1: newInset.left(), p2: oldInset.left()))
2705 emit leftInsetChanged();
2706 if (!qFuzzyCompare(p1: newInset.right(), p2: oldInset.right()))
2707 emit rightInsetChanged();
2708 if (!qFuzzyCompare(p1: newInset.bottom(), p2: oldInset.bottom()))
2709 emit bottomInsetChanged();
2710}
2711
2712QFont QQuickPopup::defaultFont() const
2713{
2714 return QQuickTheme::font(scope: QQuickTheme::System);
2715}
2716
2717QPalette QQuickPopup::defaultPalette() const
2718{
2719 return QQuickTheme::palette(scope: QQuickTheme::System);
2720}
2721
2722#if QT_CONFIG(accessibility)
2723QAccessible::Role QQuickPopup::accessibleRole() const
2724{
2725 return QAccessible::Dialog;
2726}
2727
2728void QQuickPopup::accessibilityActiveChanged(bool active)
2729{
2730 Q_UNUSED(active);
2731}
2732#endif
2733
2734QString QQuickPopup::accessibleName() const
2735{
2736 Q_D(const QQuickPopup);
2737 return d->popupItem->accessibleName();
2738}
2739
2740void QQuickPopup::maybeSetAccessibleName(const QString &name)
2741{
2742 Q_D(QQuickPopup);
2743 d->popupItem->maybeSetAccessibleName(name);
2744}
2745
2746QVariant QQuickPopup::accessibleProperty(const char *propertyName)
2747{
2748 Q_D(const QQuickPopup);
2749 return d->popupItem->accessibleProperty(propertyName);
2750}
2751
2752bool QQuickPopup::setAccessibleProperty(const char *propertyName, const QVariant &value)
2753{
2754 Q_D(QQuickPopup);
2755 return d->popupItem->setAccessibleProperty(propertyName, value);
2756}
2757
2758QT_END_NAMESPACE
2759
2760#include "moc_qquickpopup_p.cpp"
2761

source code of qtquickcontrols2/src/quicktemplates2/qquickpopup.cpp