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