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