From 1abc7fcbabcc5a89ceaaf69173d077e22ed2d658 Mon Sep 17 00:00:00 2001 From: Mitch Curtis Date: Thu, 15 Mar 2018 09:53:48 +0100 Subject: Add anchors property to Popup to allow centering in parent/window Currently, users must manually position their Popup using x and y bindings: Popup { x: (parent.width - width) / 2 y: (parent.height - height) / 2 } This patch adds an anchors property so that you can do this instead: Popup { anchors.centerIn: parent } It's also possible to conveniently center within the window from anywhere within the scene (106e7b63 also documents an alternative way of doing this using Overlay): Window { id: window Pane { Popup { anchors.centerIn: window } } } QQuickAnchors were never used with Popup, because we cannot use the QQuickAnchors implementation as-is, as the visual QQuickItem parent is not the actual parent item of QQuickPopupItem. Currently just centerIn is supported, as that's the most common use case. [ChangeLog][Controls][Popup] Added anchors.centerIn to Popup to allow a covenient way of centering a popup. Task-number: QTBUG-60354 Change-Id: Ia030f812df9da646fea8f373ef6199a21205ffbd Reviewed-by: J-P Nurmi --- tests/auto/controls/data/tst_popup.qml | 78 ++++++++++++++++++++++++++++++++-- 1 file changed, 75 insertions(+), 3 deletions(-) (limited to 'tests') diff --git a/tests/auto/controls/data/tst_popup.qml b/tests/auto/controls/data/tst_popup.qml index 3f9f5e48..0712b82b 100644 --- a/tests/auto/controls/data/tst_popup.qml +++ b/tests/auto/controls/data/tst_popup.qml @@ -48,10 +48,10 @@ ** ****************************************************************************/ -import QtQuick 2.4 +import QtQuick 2.12 import QtTest 1.0 -import QtQuick.Controls 2.3 -import QtQuick.Templates 2.3 as T +import QtQuick.Controls 2.5 +import QtQuick.Templates 2.5 as T TestCase { id: testCase @@ -1269,4 +1269,76 @@ TestCase { compare(control.background.width, 200 + (control.background.leftInset || 0) + (control.background.rightInset || 0)) compare(control.background.height, 100 + (control.background.topInset || 0) + (control.background.bottomInset || 0)) } + + function test_anchors() { + var control = createTemporaryObject(popupControl, applicationWindow.contentItem.Overlay.overlay, + { visible: true, width: 100, height: 100 }) + verify(control) + verify(control.visible) + compare(control.parent, control.Overlay.overlay) + compare(control.x, 0) + compare(control.y, 0) + + var overlay = control.Overlay.overlay + verify(overlay) + + var centerInSpy = createTemporaryObject(signalSpy, testCase, { target: control.anchors, signalName: "centerInChanged" }) + verify(centerInSpy.valid) + + applicationWindow.visible = true + verify(waitForRendering(applicationWindow.contentItem)) + verify(overlay.width > 0) + verify(overlay.height > 0) + + // Center the popup in the window via the overlay. + control.anchors.centerIn = Qt.binding(function() { return control.parent; }) + compare(centerInSpy.count, 1) + compare(control.x, (overlay.width - control.width) / 2) + compare(control.y, (overlay.height - control.height) / 2) + + // Ensure that it warns when trying to set it to an item that's not its parent. + var anotherItem = createTemporaryObject(rect, applicationWindow.contentItem, { x: 100, y: 100, width: 50, height: 50 }) + verify(anotherItem) + + ignoreWarning(Qt.resolvedUrl("tst_popup.qml") + ":77:9: QML Popup: Popup can only be centered within its immediate parent or Overlay.overlay") + control.anchors.centerIn = anotherItem + // The property will change, because we can't be sure that the parent + // in QQuickPopupAnchors::setCenterIn() is the final parent, as some reparenting can happen. + // We still expect the warning from QQuickPopupPositioner::reposition() though. + compare(centerInSpy.count, 2) + compare(control.anchors.centerIn, anotherItem) + + // The binding to the popup's parent was broken above, so restore it. + control.anchors.centerIn = Qt.binding(function() { return control.parent; }) + compare(centerInSpy.count, 3) + + // Change the popup's parent and ensure that it's anchored accordingly. + control.parent = Qt.binding(function() { return anotherItem; }) + compare(control.parent, anotherItem) + compare(control.anchors.centerIn, anotherItem) + compare(centerInSpy.count, 4) + compare(control.x, (anotherItem.width - control.width) / 2) + compare(control.y, (anotherItem.height - control.height) / 2) + + // Check that anchors.centerIn beats x and y coordinates as it does in QQuickItem. + control.x = 33; + control.y = 44; + compare(control.x, (anotherItem.width - control.width) / 2) + compare(control.y, (anotherItem.height - control.height) / 2) + + // Check that the popup's x and y coordinates are restored when it's no longer centered. + control.anchors.centerIn = undefined + compare(centerInSpy.count, 5) + compare(control.x, 33) + compare(control.y, 44) + + // Test centering in the overlay while having a different parent (anotherItem). + control.anchors.centerIn = overlay + compare(centerInSpy.count, 6) + compare(control.x, (overlay.width - control.width) / 2) + compare(control.y, (overlay.height - control.height) / 2) + + // TODO: do this properly by creating a component or something + applicationWindow.visible = false + } } -- cgit v1.2.3