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