aboutsummaryrefslogtreecommitdiffstats
path: root/src/quicktemplates2/qquickpopuppositioner.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/quicktemplates2/qquickpopuppositioner.cpp')
-rw-r--r--src/quicktemplates2/qquickpopuppositioner.cpp39
1 files changed, 35 insertions, 4 deletions
diff --git a/src/quicktemplates2/qquickpopuppositioner.cpp b/src/quicktemplates2/qquickpopuppositioner.cpp
index 4fe5135c..ebd8ff29 100644
--- a/src/quicktemplates2/qquickpopuppositioner.cpp
+++ b/src/quicktemplates2/qquickpopuppositioner.cpp
@@ -34,10 +34,13 @@
**
****************************************************************************/
+#include "qquickoverlay_p.h"
#include "qquickpopuppositioner_p_p.h"
+#include "qquickpopupanchors_p.h"
#include "qquickpopupitem_p_p.h"
#include "qquickpopup_p_p.h"
+#include <QtQml/qqmlinfo.h>
#include <QtQuick/private/qquickitem_p.h>
QT_BEGIN_NAMESPACE
@@ -62,6 +65,11 @@ QQuickPopupPositioner::~QQuickPopupPositioner()
}
}
+QQuickPopup *QQuickPopupPositioner::popup() const
+{
+ return m_popup;
+}
+
QQuickItem *QQuickPopupPositioner::parentItem() const
{
return m_parentItem;
@@ -109,12 +117,31 @@ void QQuickPopupPositioner::reposition()
bool heightAdjusted = false;
QQuickPopupPrivate *p = QQuickPopupPrivate::get(m_popup);
- QRectF rect(p->allowHorizontalMove ? p->x : popupItem->x(),
- p->allowVerticalMove ? p->y : popupItem->y(),
+ const QQuickItem *centerInParent = p->anchors ? p->getAnchors()->centerIn() : nullptr;
+ const QQuickOverlay *centerInOverlay = qobject_cast<const QQuickOverlay*>(centerInParent);
+ QRectF rect(!centerInParent ? p->allowHorizontalMove ? p->x : popupItem->x() : 0,
+ !centerInParent ? p->allowVerticalMove ? p->y : popupItem->y() : 0,
!p->hasWidth && iw > 0 ? iw : w,
!p->hasHeight && ih > 0 ? ih : h);
if (m_parentItem) {
- rect.moveTopLeft(m_parentItem->mapToItem(popupItem->parentItem(), rect.topLeft()));
+ // m_parentItem is the parent that the popup should open in,
+ // and popupItem()->parentItem() is the overlay, so the mapToItem() calls below
+ // effectively map the rect to scene coordinates.
+ if (centerInParent) {
+ if (centerInParent != parentItem() && !centerInOverlay) {
+ qmlWarning(m_popup) << "Popup can only be centered within its immediate parent or Overlay.overlay";
+ return;
+ }
+
+ if (centerInOverlay) {
+ rect.moveCenter(QPointF(qRound(centerInOverlay->width() / 2.0), qRound(centerInOverlay->height() / 2.0)));
+ } else {
+ const QPointF parentItemCenter = QPointF(qRound(m_parentItem->width() / 2), qRound(m_parentItem->height() / 2));
+ rect.moveCenter(m_parentItem->mapToItem(popupItem->parentItem(), parentItemCenter));
+ }
+ } else {
+ rect.moveTopLeft(m_parentItem->mapToItem(popupItem->parentItem(), rect.topLeft()));
+ }
if (p->window) {
const QMarginsF margins = p->getMargins();
@@ -215,7 +242,11 @@ void QQuickPopupPositioner::reposition()
popupItem->setPosition(rect.topLeft());
- const QPointF effectivePos = m_parentItem ? m_parentItem->mapFromScene(rect.topLeft()) : rect.topLeft();
+ // If the popup was assigned a parent, rect will be in scene coordinates,
+ // so we need to map its top left back to item coordinates.
+ // However, if centering within the overlay, the coordinates will be relative
+ // to the window, so we don't need to do anything.
+ const QPointF effectivePos = m_parentItem && !centerInOverlay ? m_parentItem->mapFromScene(rect.topLeft()) : rect.topLeft();
if (!qFuzzyCompare(p->effectiveX, effectivePos.x())) {
p->effectiveX = effectivePos.x();
emit m_popup->xChanged();