From c886facd990acf207f3164662601222babc8dde2 Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Thu, 15 Sep 2016 07:38:53 +0200 Subject: QQuickControl: clear the hovered state when hidden Task-number: QTBUG-56007 Change-Id: I6433e0ebc9570b1e9e6e149ef7f631ea6786f672 Reviewed-by: Mitch Curtis --- tests/auto/controls/data/tst_control.qml | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'tests/auto') diff --git a/tests/auto/controls/data/tst_control.qml b/tests/auto/controls/data/tst_control.qml index 601b7f8f..4b7a60dc 100644 --- a/tests/auto/controls/data/tst_control.qml +++ b/tests/auto/controls/data/tst_control.qml @@ -880,6 +880,12 @@ TestCase { mouseMove(control, -10, -10) compare(control.hovered, false) + mouseMove(control, control.width / 2, control.height / 2) + compare(control.hovered, true) + + control.visible = false + compare(control.hovered, false) + control.destroy() } -- cgit v1.2.3 From 541a7a8e785476e2e93f88f770715f25ce7e6dc8 Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Thu, 15 Sep 2016 06:46:54 +0200 Subject: Drawer: fix drag to close from the outside on touch Set mouseGrabberPopup in QQuickOverlay::childMouseEventFilter() the same way it is set in QQuickOverlay::mousePressEvent() to ensure that the consequent mouse move events are routed to the appropriate popup. This worked with "genuine" mouse move events that were caught by the same child mouse event filter and that way routed to the appropriate popup, but not with "synthesized" mouse move events that are caught by QQuickOverlay::mousePressEvent() instead. Change-Id: Ic59afd85e55c13ebec482bc4dc534accd1f92b2c Task-number: QTBUG-56010 Reviewed-by: Mitch Curtis --- tests/auto/drawer/BLACKLIST | 2 ++ tests/auto/drawer/tst_drawer.cpp | 58 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+) create mode 100644 tests/auto/drawer/BLACKLIST (limited to 'tests/auto') diff --git a/tests/auto/drawer/BLACKLIST b/tests/auto/drawer/BLACKLIST new file mode 100644 index 00000000..1b06b49c --- /dev/null +++ b/tests/auto/drawer/BLACKLIST @@ -0,0 +1,2 @@ +[touch] +windows diff --git a/tests/auto/drawer/tst_drawer.cpp b/tests/auto/drawer/tst_drawer.cpp index 8b02e95c..3a02e9a9 100644 --- a/tests/auto/drawer/tst_drawer.cpp +++ b/tests/auto/drawer/tst_drawer.cpp @@ -40,7 +40,10 @@ #include "../shared/visualtestutil.h" #include +#include #include +#include +#include #include #include #include @@ -74,6 +77,9 @@ private slots: void wheel(); void multiple(); + + void touch_data(); + void touch(); }; void tst_Drawer::visible_data() @@ -615,6 +621,58 @@ void tst_Drawer::multiple() QCOMPARE(leftDrawer->position(), 0.0); } +void tst_Drawer::touch_data() +{ + QTest::addColumn("source"); + QTest::newRow("Window") << "window.qml"; + QTest::newRow("ApplicationWindow") << "applicationwindow.qml"; +} + +void tst_Drawer::touch() +{ + QFETCH(QString, source); + QQuickApplicationHelper helper(this, source); + + QQuickWindow *window = helper.window; + window->show(); + QVERIFY(QTest::qWaitForWindowExposed(window)); + + QQuickDrawer *drawer = window->property("drawer").value(); + QVERIFY(drawer); + + struct TouchDeviceDeleter + { + static inline void cleanup(QTouchDevice *device) + { + QWindowSystemInterface::unregisterTouchDevice(device); + delete device; + } + }; + + QScopedPointer device(new QTouchDevice); + device->setType(QTouchDevice::TouchScreen); + QWindowSystemInterface::registerTouchDevice(device.data()); + + // drag to open + QTest::touchEvent(window, device.data()).press(0, QPoint(0, 100)); + QTest::touchEvent(window, device.data()).move(0, QPoint(100, 100)); + QTRY_COMPARE(drawer->position(), 0.5); + QTest::touchEvent(window, device.data()).release(0, QPoint(100, 100)); + QTRY_COMPARE(drawer->position(), 1.0); + + // drag to close + QTest::touchEvent(window, device.data()).press(0, QPoint(300, 100)); + QTest::touchEvent(window, device.data()).move(0, QPoint(300 - drawer->dragMargin(), 100)); + for (int x = 300; x > 100; x -= 10) { + QTest::touchEvent(window, device.data()).move(0, QPoint(x, 100)); + QQuickWindowPrivate::get(window)->flushDelayedTouchEvent(); + } + QTest::touchEvent(window, device.data()).move(0, QPoint(100, 100)); + QTRY_COMPARE(drawer->position(), 0.5); + QTest::touchEvent(window, device.data()).release(0, QPoint(100, 100)); + QTRY_COMPARE(drawer->position(), 0.0); +} + QTEST_MAIN(tst_Drawer) #include "tst_drawer.moc" -- cgit v1.2.3 From fbe806c544a45c83f091109e04fab5d86620183f Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Thu, 15 Sep 2016 16:50:16 +0200 Subject: Fix Popup to respect explicit size [ChangeLog][Controls][Popup] Fixed to respect explicitly set width and height. Task-number: QTBUG-56025 Change-Id: I7c8b0dcf59459a313c4c52eda44de45f1ab648ea Reviewed-by: Mitch Curtis --- tests/auto/controls/data/tst_popup.qml | 48 ++++++++++++++++++++++++++++++---- 1 file changed, 43 insertions(+), 5 deletions(-) (limited to 'tests/auto') diff --git a/tests/auto/controls/data/tst_popup.qml b/tests/auto/controls/data/tst_popup.qml index e714a7d0..919bfffc 100644 --- a/tests/auto/controls/data/tst_popup.qml +++ b/tests/auto/controls/data/tst_popup.qml @@ -940,14 +940,52 @@ TestCase { var control = popupControl.createObject(testCase) verify(control) - control.width = 200 - control.height = 200 - control.open() waitForRendering(control.contentItem) - compare(control.width, 200) - compare(control.height, 200) + // implicit size of the content + control.contentItem.implicitWidth = 10 + compare(control.implicitWidth, 10 + control.leftPadding + control.rightPadding) + compare(control.width, control.implicitWidth) + compare(control.contentItem.width, control.width - control.leftPadding - control.rightPadding) + + control.contentItem.implicitHeight = 20 + compare(control.implicitHeight, 20 + control.topPadding + control.bottomPadding) + compare(control.height, control.implicitHeight) + compare(control.contentItem.height, control.height - control.topPadding - control.bottomPadding) + + // implicit size of the popup + control.implicitWidth = 30 + compare(control.implicitWidth, 30) + compare(control.width, 30) + compare(control.contentItem.width, control.width - control.leftPadding - control.rightPadding) + + control.implicitHeight = 40 + compare(control.implicitHeight, 40) + compare(control.height, 40) + compare(control.contentItem.height, control.height - control.topPadding - control.bottomPadding) + + // set explicit size + control.width = 50 + compare(control.implicitWidth, 30) + compare(control.width, 50) + compare(control.contentItem.width, control.width - control.leftPadding - control.rightPadding) + + control.height = 60 + compare(control.implicitHeight, 40) + compare(control.height, 60) + compare(control.contentItem.height, control.height - control.topPadding - control.bottomPadding) + + // reset explicit size + control.width = undefined + compare(control.implicitWidth, 30) + compare(control.width, 30) + compare(control.contentItem.width, control.width - control.leftPadding - control.rightPadding) + + control.height = undefined + compare(control.implicitHeight, 40) + compare(control.height, 40) + compare(control.contentItem.height, control.height - control.topPadding - control.bottomPadding) control.destroy() } -- cgit v1.2.3 From 935974e174d87f9bf10a56d14bb73ade726d827a Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Mon, 19 Sep 2016 15:19:40 +0200 Subject: Fix Switch to stay pressed as appropriate Switch is a special type of button that should stay pressed (similarly to Slider) even if the finger slips outside the bounds of the control. It was doing that only when dragged from the handle, not when dragged from the background. Change-Id: I462c66cfe2e67fc3c95215ffeafe3e5771174418 Reviewed-by: Mitch Curtis --- tests/auto/controls/data/tst_switch.qml | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) (limited to 'tests/auto') diff --git a/tests/auto/controls/data/tst_switch.qml b/tests/auto/controls/data/tst_switch.qml index ba41015f..1b77ff42 100644 --- a/tests/auto/controls/data/tst_switch.qml +++ b/tests/auto/controls/data/tst_switch.qml @@ -95,6 +95,29 @@ TestCase { control.destroy() } + function test_pressed_data() { + return [ + { tag: "indicator", x: 15 }, + { tag: "background", x: 5 } + ] + } + + function test_pressed(data) { + var control = swtch.createObject(testCase, {padding: 10}) + verify(control) + + // stays pressed when dragged outside + compare(control.pressed, false) + mousePress(control, data.x, control.height / 2, Qt.LeftButton) + compare(control.pressed, true) + mouseMove(control, -1, control.height / 2) + compare(control.pressed, true) + mouseRelease(control, -1, control.height / 2, Qt.LeftButton) + compare(control.pressed, false) + + control.destroy() + } + function test_mouse() { var control = swtch.createObject(testCase) verify(control) -- cgit v1.2.3 From 6ed4918f131ff235bcab3efe849f5b67406ef350 Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Mon, 19 Sep 2016 15:43:36 +0200 Subject: QQuickSwitch: fix event handling Switch implemented custom event handling for the indicator, and used QQuickAbstractButton's event handling for the background. This lead to inconsistent signals depending on whether interacting with the handle or the background. This change gets rid of the child mouse event filter for the indicator and makes QQuickSwitch fully utilize the base class event handlers. Change-Id: I773e2eb939cbbf4bc9086cdf2b34e876597ea08e Reviewed-by: Mitch Curtis --- tests/auto/controls/data/tst_switch.qml | 70 +++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) (limited to 'tests/auto') diff --git a/tests/auto/controls/data/tst_switch.qml b/tests/auto/controls/data/tst_switch.qml index 1b77ff42..f854526c 100644 --- a/tests/auto/controls/data/tst_switch.qml +++ b/tests/auto/controls/data/tst_switch.qml @@ -200,6 +200,76 @@ TestCase { control.destroy() } + function test_drag() { + var control = swtch.createObject(testCase, {leftPadding: 100, rightPadding: 100}) + verify(control) + + var spy = signalSequenceSpy.createObject(control, {target: control}) + compare(control.position, 0.0) + compare(control.checked, false) + compare(control.pressed, false) + + // press-drag-release inside the indicator + spy.expectedSequence = [["pressedChanged", { "pressed": true, "checked": false }], + "pressed"] + mousePress(control.indicator, 0) + compare(control.position, 0.0) + compare(control.checked, false) + compare(control.pressed, true) + verify(spy.success) + + mouseMove(control.indicator, control.width) + compare(control.position, 1.0) + compare(control.checked, false) + compare(control.pressed, true) + + spy.expectedSequence = [["pressedChanged", { "pressed": false, "checked": false }], + ["checkedChanged", { "pressed": false, "checked": true }], + "released", + "clicked"] + mouseRelease(control.indicator, control.indicator.width) + compare(control.position, 1.0) + compare(control.checked, true) + compare(control.pressed, false) + verify(spy.success) + + // press-drag-release outside the indicator + spy.expectedSequence = [["pressedChanged", { "pressed": true, "checked": true }], + "pressed"] + mousePress(control, 0) + compare(control.position, 1.0) + compare(control.checked, true) + compare(control.pressed, true) + verify(spy.success) + + mouseMove(control, control.width - control.rightPadding) + compare(control.position, 1.0) + compare(control.checked, true) + compare(control.pressed, true) + + mouseMove(control, control.width / 2) + compare(control.position, 0.5) + compare(control.checked, true) + compare(control.pressed, true) + + mouseMove(control, control.leftPadding) + compare(control.position, 0.0) + compare(control.checked, true) + compare(control.pressed, true) + + spy.expectedSequence = [["pressedChanged", { "pressed": false, "checked": true }], + ["checkedChanged", { "pressed": false, "checked": false }], + "released", + "clicked"] + mouseRelease(control, control.width) + compare(control.position, 0.0) + compare(control.checked, false) + compare(control.pressed, false) + verify(spy.success) + + control.destroy() + } + function test_keys() { var control = swtch.createObject(testCase) verify(control) -- cgit v1.2.3 From b3983692680a91023dc5f22608b4e84b46fae883 Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Mon, 19 Sep 2016 16:39:41 +0200 Subject: QQuickSwitchDelegate: make the handle draggable Sync the implementation with QQuickSwitch to make it behave exactly the same way. Change-Id: I59d08f68f87d8776e4012da880ac57a99950dfe8 Task-number: QTBUG-55686 Reviewed-by: Mitch Curtis --- tests/auto/controls/data/tst_switchdelegate.qml | 182 ++++++++++++++++++++++++ 1 file changed, 182 insertions(+) (limited to 'tests/auto') diff --git a/tests/auto/controls/data/tst_switchdelegate.qml b/tests/auto/controls/data/tst_switchdelegate.qml index 231736c6..6d23a403 100644 --- a/tests/auto/controls/data/tst_switchdelegate.qml +++ b/tests/auto/controls/data/tst_switchdelegate.qml @@ -55,6 +55,13 @@ TestCase { SwitchDelegate {} } + Component { + id: signalSequenceSpy + SignalSequenceSpy { + signals: ["pressed", "released", "canceled", "clicked", "pressedChanged", "checkedChanged"] + } + } + // TODO: data-fy tst_checkbox (rename to tst_check?) so we don't duplicate its tests here? function test_defaults() { @@ -83,4 +90,179 @@ TestCase { compare(control.baselineOffset, control.contentItem.y + control.contentItem.baselineOffset); control.destroy(); } + + function test_pressed_data() { + return [ + { tag: "indicator", x: 15 }, + { tag: "background", x: 5 } + ] + } + + function test_pressed(data) { + var control = switchDelegate.createObject(testCase, {padding: 10}) + verify(control) + + // stays pressed when dragged outside + compare(control.pressed, false) + mousePress(control, data.x, control.height / 2, Qt.LeftButton) + compare(control.pressed, true) + mouseMove(control, -1, control.height / 2) + compare(control.pressed, true) + mouseRelease(control, -1, control.height / 2, Qt.LeftButton) + compare(control.pressed, false) + + control.destroy() + } + + function test_mouse() { + var control = switchDelegate.createObject(testCase) + verify(control) + + // check + var spy = signalSequenceSpy.createObject(control, {target: control}) + spy.expectedSequence = [["pressedChanged", { "pressed": true, "checked": false }], + "pressed"] + mousePress(control, control.width / 2, control.height / 2, Qt.LeftButton) + compare(control.pressed, true) + verify(spy.success) + spy.expectedSequence = [["pressedChanged", { "pressed": false, "checked": false }], + ["checkedChanged", { "pressed": false, "checked": true }], + "released", + "clicked"] + mouseRelease(control, control.width / 2, control.height / 2, Qt.LeftButton) + compare(control.checked, true) + compare(control.pressed, false) + verify(spy.success) + + // uncheck + spy.expectedSequence = [["pressedChanged", { "pressed": true, "checked": true }], + "pressed"] + mousePress(control, control.width / 2, control.height / 2, Qt.LeftButton) + compare(control.pressed, true) + verify(spy.success) + spy.expectedSequence = [["pressedChanged", { "pressed": false, "checked": true }], + ["checkedChanged", { "pressed": false, "checked": false }], + "released", + "clicked"] + mouseRelease(control, control.width / 2, control.height / 2, Qt.LeftButton) + compare(control.checked, false) + compare(control.pressed, false) + verify(spy.success) + + // release on the right + spy.expectedSequence = [["pressedChanged", { "pressed": true, "checked": false }], + "pressed"] + mousePress(control, control.width / 2, control.height / 2, Qt.LeftButton) + compare(control.pressed, true) + verify(spy.success) + mouseMove(control, control.width * 2, control.height / 2, 0, Qt.LeftButton) + compare(control.pressed, true) + spy.expectedSequence = [["pressedChanged", { "pressed": false, "checked": false }], + ["checkedChanged", { "pressed": false, "checked": true }], + "released", + "clicked"] + mouseRelease(control, control.width * 2, control.height / 2, Qt.LeftButton) + compare(control.checked, true) + compare(control.pressed, false) + verify(spy.success) + + // release on the left + spy.expectedSequence = [["pressedChanged", { "pressed": true, "checked": true }], + "pressed"] + mousePress(control, control.width / 2, control.height / 2, Qt.LeftButton) + compare(control.pressed, true) + verify(spy.success) + mouseMove(control, -control.width, control.height / 2, 0, Qt.LeftButton) + compare(control.pressed, true) + spy.expectedSequence = [["pressedChanged", { "pressed": false, "checked": true }], + ["checkedChanged", { "pressed": false, "checked": false }], + "released", + "clicked"] + mouseRelease(control, -control.width, control.height / 2, Qt.LeftButton) + compare(control.checked, false) + compare(control.pressed, false) + verify(spy.success) + + // right button + spy.expectedSequence = [] + mousePress(control, control.width / 2, control.height / 2, Qt.RightButton) + compare(control.pressed, false) + verify(spy.success) + mouseRelease(control, control.width / 2, control.height / 2, Qt.RightButton) + compare(control.checked, false) + compare(control.pressed, false) + verify(spy.success) + + control.destroy() + } + + function test_drag() { + var control = switchDelegate.createObject(testCase, {leftPadding: 100, rightPadding: 100}) + verify(control) + + var spy = signalSequenceSpy.createObject(control, {target: control}) + compare(control.position, 0.0) + compare(control.checked, false) + compare(control.pressed, false) + + // press-drag-release inside the indicator + spy.expectedSequence = [["pressedChanged", { "pressed": true, "checked": false }], + "pressed"] + mousePress(control.indicator, 0) + compare(control.position, 0.0) + compare(control.checked, false) + compare(control.pressed, true) + verify(spy.success) + + mouseMove(control.indicator, control.width) + compare(control.position, 1.0) + compare(control.checked, false) + compare(control.pressed, true) + + spy.expectedSequence = [["pressedChanged", { "pressed": false, "checked": false }], + ["checkedChanged", { "pressed": false, "checked": true }], + "released", + "clicked"] + mouseRelease(control.indicator, control.indicator.width) + compare(control.position, 1.0) + compare(control.checked, true) + compare(control.pressed, false) + verify(spy.success) + + // press-drag-release outside the indicator + spy.expectedSequence = [["pressedChanged", { "pressed": true, "checked": true }], + "pressed"] + mousePress(control, 0) + compare(control.position, 1.0) + compare(control.checked, true) + compare(control.pressed, true) + verify(spy.success) + + mouseMove(control, control.width - control.rightPadding) + compare(control.position, 1.0) + compare(control.checked, true) + compare(control.pressed, true) + + mouseMove(control, control.width / 2) + compare(control.position, 0.5) + compare(control.checked, true) + compare(control.pressed, true) + + mouseMove(control, control.leftPadding) + compare(control.position, 0.0) + compare(control.checked, true) + compare(control.pressed, true) + + spy.expectedSequence = [["pressedChanged", { "pressed": false, "checked": true }], + ["checkedChanged", { "pressed": false, "checked": false }], + "released", + "clicked"] + mouseRelease(control, control.width) + compare(control.position, 0.0) + compare(control.checked, false) + compare(control.pressed, false) + verify(spy.success) + + control.destroy() + } } -- cgit v1.2.3 From 7b9c4db132d03a24b63d1fb9f3d85c82b63089db Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Tue, 20 Sep 2016 10:02:44 +0200 Subject: Switch/Delegate: improve dragging behavior Don't start dragging the handle unless the initial press was at the indicator, or the drag has reached the indicator area. This prevents unnatural jumps when dragging far outside the indicator. Change-Id: I2b31b319a347ab489f2de5c044e42d908827b425 Reviewed-by: Mitch Curtis --- tests/auto/controls/data/tst_switch.qml | 34 +++++++++++++++++++++++++ tests/auto/controls/data/tst_switchdelegate.qml | 34 +++++++++++++++++++++++++ 2 files changed, 68 insertions(+) (limited to 'tests/auto') diff --git a/tests/auto/controls/data/tst_switch.qml b/tests/auto/controls/data/tst_switch.qml index f854526c..93773e0d 100644 --- a/tests/auto/controls/data/tst_switch.qml +++ b/tests/auto/controls/data/tst_switch.qml @@ -267,6 +267,40 @@ TestCase { compare(control.pressed, false) verify(spy.success) + // press-drag-release from and to outside the indicator + spy.expectedSequence = [["pressedChanged", { "pressed": true, "checked": false }], + "pressed"] + mousePress(control, control.width) + compare(control.position, 0.0) + compare(control.checked, false) + compare(control.pressed, true) + verify(spy.success) + + mouseMove(control, control.width - control.rightPadding) + compare(control.position, 0.0) + compare(control.checked, false) + compare(control.pressed, true) + + mouseMove(control, control.width / 2) + compare(control.position, 0.5) + compare(control.checked, false) + compare(control.pressed, true) + + mouseMove(control, control.width - control.rightPadding) + compare(control.position, 1.0) + compare(control.checked, false) + compare(control.pressed, true) + + spy.expectedSequence = [["pressedChanged", { "pressed": false, "checked": false }], + ["checkedChanged", { "pressed": false, "checked": true }], + "released", + "clicked"] + mouseRelease(control, control.width) + compare(control.position, 1.0) + compare(control.checked, true) + compare(control.pressed, false) + verify(spy.success) + control.destroy() } diff --git a/tests/auto/controls/data/tst_switchdelegate.qml b/tests/auto/controls/data/tst_switchdelegate.qml index 6d23a403..8bc0e4c3 100644 --- a/tests/auto/controls/data/tst_switchdelegate.qml +++ b/tests/auto/controls/data/tst_switchdelegate.qml @@ -263,6 +263,40 @@ TestCase { compare(control.pressed, false) verify(spy.success) + // press-drag-release from and to outside the indicator + spy.expectedSequence = [["pressedChanged", { "pressed": true, "checked": false }], + "pressed"] + mousePress(control, control.width) + compare(control.position, 0.0) + compare(control.checked, false) + compare(control.pressed, true) + verify(spy.success) + + mouseMove(control, control.width - control.rightPadding) + compare(control.position, 0.0) + compare(control.checked, false) + compare(control.pressed, true) + + mouseMove(control, control.width / 2) + compare(control.position, 0.5) + compare(control.checked, false) + compare(control.pressed, true) + + mouseMove(control, control.width - control.rightPadding) + compare(control.position, 1.0) + compare(control.checked, false) + compare(control.pressed, true) + + spy.expectedSequence = [["pressedChanged", { "pressed": false, "checked": false }], + ["checkedChanged", { "pressed": false, "checked": true }], + "released", + "clicked"] + mouseRelease(control, control.width) + compare(control.position, 1.0) + compare(control.checked, true) + compare(control.pressed, false) + verify(spy.success) + control.destroy() } } -- cgit v1.2.3 From 8a4af9e87704f7b8ed269114d3ab75430bd61998 Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Tue, 20 Sep 2016 16:23:57 +0200 Subject: QQuickPopup: fix negative margins The documentation states: A popup with negative margins is not pushed within the bounds of the enclosing window. Therefore QQuickPopupPrivate::reposition() must not subtract negative margins to calculate the available bounds. Change-Id: I626772970bf3d5d9eefbb13811ea1003a85bcf0b Reviewed-by: Mitch Curtis --- tests/auto/controls/data/tst_popup.qml | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'tests/auto') diff --git a/tests/auto/controls/data/tst_popup.qml b/tests/auto/controls/data/tst_popup.qml index 919bfffc..ae1c7185 100644 --- a/tests/auto/controls/data/tst_popup.qml +++ b/tests/auto/controls/data/tst_popup.qml @@ -355,6 +355,30 @@ TestCase { control.destroy() } + function test_negativeMargins() { + var control = popupControl.createObject(testCase, {implicitWidth: testCase.width, implicitHeight: testCase.height}) + verify(control) + + control.open() + verify(control.visible) + + compare(control.x, 0) + compare(control.y, 0) + + compare(control.margins, -1) + compare(control.topMargin, -1) + compare(control.leftMargin, -1) + compare(control.rightMargin, -1) + compare(control.bottomMargin, -1) + + control.x = -10 + control.y = -10 + compare(control.x, 0) + compare(control.y, 0) + + control.destroy() + } + function test_margins() { var control = popupControl.createObject(testCase, {width: 100, height: 100}) verify(control) -- cgit v1.2.3 From 3ed4944a7e21191ee726ca31c4e50bd055f9d25b Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Tue, 20 Sep 2016 17:23:16 +0200 Subject: Fix QQuickPopup::resetWidth/Height() When reseting the explicit size of a popup, the popup items geometry does not necessarily change. However, it affects the positioning of the popup whether it has explicit size or not. For that reason we must ensure that the popup gets repositioned as appropriate. Change-Id: I2dcd895eb7a1adc9c6a804bed4731edac1d550ec Reviewed-by: Mitch Curtis --- tests/auto/controls/data/tst_popup.qml | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'tests/auto') diff --git a/tests/auto/controls/data/tst_popup.qml b/tests/auto/controls/data/tst_popup.qml index ae1c7185..8d8f94b7 100644 --- a/tests/auto/controls/data/tst_popup.qml +++ b/tests/auto/controls/data/tst_popup.qml @@ -355,6 +355,24 @@ TestCase { control.destroy() } + function test_resetSize() { + var control = popupControl.createObject(testCase, {visible: true, margins: 0}) + verify(control) + + control.width = control.implicitWidth = testCase.width + 10 + control.height = control.implicitHeight = testCase.height + 10 + + compare(control.width, testCase.width + 10) + compare(control.height, testCase.height + 10) + + control.width = undefined + control.height = undefined + compare(control.width, testCase.width) + compare(control.height, testCase.height) + + control.destroy() + } + function test_negativeMargins() { var control = popupControl.createObject(testCase, {implicitWidth: testCase.width, implicitHeight: testCase.height}) verify(control) -- cgit v1.2.3 From aae5b793666091a780e63b68b2a0426f8edd6174 Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Wed, 21 Sep 2016 13:55:25 +0200 Subject: Make ApplicationWindow.overlay attached property work with QML Window Since 14dd934c, we're using QQuickOverlay even with plain QML Window. Now that the overlay is guaranteed to always exist, we can make the attached property to give a reliable access to the overlay. Change-Id: I707fc52f6dfc7a0dbc9a3467646fb5feb36b9572 Reviewed-by: Mitch Curtis --- tests/auto/applicationwindow/tst_applicationwindow.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'tests/auto') diff --git a/tests/auto/applicationwindow/tst_applicationwindow.cpp b/tests/auto/applicationwindow/tst_applicationwindow.cpp index 02528fdc..2f91f664 100644 --- a/tests/auto/applicationwindow/tst_applicationwindow.cpp +++ b/tests/auto/applicationwindow/tst_applicationwindow.cpp @@ -318,7 +318,7 @@ void tst_applicationwindow::attachedProperties() QVERIFY(!childWindowControl->property("attached_activeFocusControl").value()); QVERIFY(!childWindowControl->property("attached_header").value()); QVERIFY(!childWindowControl->property("attached_footer").value()); - QVERIFY(!childWindowControl->property("attached_overlay").value()); + QCOMPARE(childWindowControl->property("attached_overlay").value(), QQuickOverlay::overlay(childWindow)); QQuickItem *childWindowItem = object->property("childWindowItem").value(); QVERIFY(childWindowItem); @@ -327,7 +327,7 @@ void tst_applicationwindow::attachedProperties() QVERIFY(!childWindowItem->property("attached_activeFocusControl").value()); QVERIFY(!childWindowItem->property("attached_header").value()); QVERIFY(!childWindowItem->property("attached_footer").value()); - QVERIFY(!childWindowItem->property("attached_overlay").value()); + QCOMPARE(childWindowItem->property("attached_overlay").value(), QQuickOverlay::overlay(childWindow)); QObject *childWindowObject = object->property("childWindowObject").value(); QVERIFY(childWindowObject); -- cgit v1.2.3 From 175d0ea3f80af0ca32baec489d8ea66dd4ee3418 Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Wed, 21 Sep 2016 11:56:08 +0200 Subject: Drawer: reparent to the overlay by default Drawer is a special type of popup that always resides at one of the window edges. Therefore it makes sense for drawers to operate on window coordinates. Re-parenting drawers to the window overlay achieves that. Now that the window overlay is guaranteed to always exist and the ApplicationWindow.overlay attached property works even with plain QML Window, we can reliably use it as a parent for Drawer. Task-number: QTBUG-53168 Change-Id: I37c727001350217ea1d2d9c52d73b4cae44d7c8d Reviewed-by: Mitch Curtis --- tests/auto/controls/data/tst_drawer.qml | 1 + tests/auto/drawer/data/header.qml | 57 +++++++++++++++++++++++++++++++++ tests/auto/drawer/tst_drawer.cpp | 32 ++++++++++++++++++ 3 files changed, 90 insertions(+) create mode 100644 tests/auto/drawer/data/header.qml (limited to 'tests/auto') diff --git a/tests/auto/controls/data/tst_drawer.qml b/tests/auto/controls/data/tst_drawer.qml index e08856bd..021afdb2 100644 --- a/tests/auto/controls/data/tst_drawer.qml +++ b/tests/auto/controls/data/tst_drawer.qml @@ -60,6 +60,7 @@ TestCase { compare(control.edge, Qt.LeftEdge) compare(control.position, 0.0) compare(control.dragMargin, Qt.styleHints.startDragDistance) + compare(control.parent, ApplicationWindow.overlay) control.destroy() } diff --git a/tests/auto/drawer/data/header.qml b/tests/auto/drawer/data/header.qml new file mode 100644 index 00000000..9a352ffc --- /dev/null +++ b/tests/auto/drawer/data/header.qml @@ -0,0 +1,57 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.6 +import QtQuick.Controls 2.0 + +ApplicationWindow { + width: 400 + height: 400 + + property alias drawer: drawer + + header: ToolBar { } + + Drawer { + id: drawer + width: 200 + height: parent.height + } +} diff --git a/tests/auto/drawer/tst_drawer.cpp b/tests/auto/drawer/tst_drawer.cpp index 3a02e9a9..f29abf21 100644 --- a/tests/auto/drawer/tst_drawer.cpp +++ b/tests/auto/drawer/tst_drawer.cpp @@ -69,6 +69,7 @@ private slots: void dragMargin(); void reposition(); + void header(); void hover_data(); void hover(); @@ -352,6 +353,37 @@ void tst_Drawer::reposition() QTRY_COMPARE(drawer->popupItem()->x(), static_cast(window->width())); } +void tst_Drawer::header() +{ + QQuickApplicationHelper helper(this, QStringLiteral("header.qml")); + + QQuickApplicationWindow *window = helper.appWindow; + window->show(); + QVERIFY(QTest::qWaitForWindowExposed(window)); + + QQuickItem *content = window->contentItem(); + QVERIFY(content); + + QQuickOverlay *overlay = QQuickOverlay::overlay(window); + QVERIFY(overlay); + + QQuickDrawer *drawer = window->property("drawer").value(); + QVERIFY(drawer); + QQuickItem *popupItem = drawer->popupItem(); + + drawer->open(); + QVERIFY(drawer->isVisible()); + + QCOMPARE(drawer->parentItem(), overlay); + QCOMPARE(drawer->height(), overlay->height()); + QCOMPARE(popupItem->height(), overlay->height()); + + drawer->setParentItem(content); + QCOMPARE(drawer->parentItem(), content); + QCOMPARE(drawer->height(), content->height()); + QCOMPARE(popupItem->height(), content->height()); +} + void tst_Drawer::hover_data() { QTest::addColumn("source"); -- cgit v1.2.3 From 244356ba182c2807ef9b15eb71ac16a568d65642 Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Thu, 15 Sep 2016 10:09:36 +0200 Subject: QQuickDrawer: allow resizing and positioning Make QQuickDrawer re-use QQuickPopup's reposition() implementation. This way QQuickDrawer gains support for proper positioning and margins "for free". Now it is possible to place Drawer below the window header, for instance: import QtQuick 2.0 import QtQuick.Controls 2.0 ApplicationWindow { id: window visible: true header: ToolBar { } Drawer { y: header.height width: window.width * 0.6 height: window.height - header.height } } [ChangeLog][Controls][Drawer] Made it possible to control the vertical position of a horizontal drawer, and vice versa. This allows placing a drawer below a header/toolbar, for instance. Task-number: QTBUG-55360 Change-Id: I63621195efeefa2ea88935d676771b392e0a4030 Reviewed-by: Mitch Curtis --- tests/auto/drawer/data/reposition.qml | 58 +++++++++++++++++++++++++++++++++++ tests/auto/drawer/tst_drawer.cpp | 47 +++++++++++++++++++++++----- 2 files changed, 97 insertions(+), 8 deletions(-) create mode 100644 tests/auto/drawer/data/reposition.qml (limited to 'tests/auto') diff --git a/tests/auto/drawer/data/reposition.qml b/tests/auto/drawer/data/reposition.qml new file mode 100644 index 00000000..abaec5ae --- /dev/null +++ b/tests/auto/drawer/data/reposition.qml @@ -0,0 +1,58 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.6 +import QtQuick.Controls 2.0 + +ApplicationWindow { + width: 400 + height: 400 + + property alias drawer: drawer + + header: Item { implicitHeight: 50 } + footer: Item { implicitHeight: 50 } + + Drawer { + id: drawer + width: parent.width / 2 + implicitHeight: parent.height + } +} diff --git a/tests/auto/drawer/tst_drawer.cpp b/tests/auto/drawer/tst_drawer.cpp index f29abf21..19a66326 100644 --- a/tests/auto/drawer/tst_drawer.cpp +++ b/tests/auto/drawer/tst_drawer.cpp @@ -46,6 +46,7 @@ #include #include #include +#include #include #include #include @@ -330,27 +331,57 @@ void tst_Drawer::dragMargin() QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, QPoint(window->width() - rightDistance, drawer->height() / 2)); } +static QRectF geometry(const QQuickItem *item) +{ + return QRectF(item->x(), item->y(), item->width(), item->height()); +} + void tst_Drawer::reposition() { - QQuickApplicationHelper helper(this, QStringLiteral("applicationwindow.qml")); + QQuickApplicationHelper helper(this, QStringLiteral("reposition.qml")); QQuickApplicationWindow *window = helper.appWindow; window->show(); - window->requestActivate(); - QVERIFY(QTest::qWaitForWindowActive(window)); + QVERIFY(QTest::qWaitForWindowExposed(window)); - QQuickDrawer *drawer = helper.appWindow->property("drawer").value(); + QQuickDrawer *drawer = window->property("drawer").value(); QVERIFY(drawer); - drawer->setEdge(Qt::RightEdge); + QQuickItem *popupItem = drawer->popupItem(); + QVERIFY(popupItem); drawer->open(); - QTRY_COMPARE(drawer->popupItem()->x(), window->width() - drawer->width()); + QQuickItem *dimmer = QQuickPopupPrivate::get(drawer)->dimmer; + QVERIFY(dimmer); + + QCOMPARE(geometry(dimmer), QRectF(0, 0, window->width(), window->height())); + QTRY_COMPARE(geometry(popupItem), QRectF(0, 0, window->width() / 2, window->height())); + + drawer->setY(100); + QCOMPARE(geometry(dimmer), QRectF(0, 100, window->width(), window->height() - 100)); + QCOMPARE(geometry(popupItem), QRectF(0, 100, window->width() / 2, window->height() - 100)); + + drawer->setHeight(window->height()); + QCOMPARE(geometry(dimmer), QRectF(0, 100, window->width(), window->height())); + QCOMPARE(geometry(popupItem), QRectF(0, 100, window->width() / 2, window->height())); + + drawer->resetHeight(); + QCOMPARE(geometry(dimmer), QRectF(0, 100, window->width(), window->height() - 100)); + QCOMPARE(geometry(popupItem), QRectF(0, 100, window->width() / 2, window->height() - 100)); + + drawer->setParentItem(window->contentItem()); + QCOMPARE(geometry(dimmer), QRectF(0, 150, window->width(), window->height() - 150)); + QCOMPARE(geometry(popupItem), QRectF(0, 150, window->width() / 2, window->height() - 150)); + + drawer->setEdge(Qt::RightEdge); + QCOMPARE(geometry(dimmer), QRectF(0, 150, window->width(), window->height() - 150)); + QTRY_COMPARE(geometry(popupItem), QRectF(window->width() - drawer->width(), 150, window->width() / 2, window->height() - 150)); window->setWidth(window->width() + 100); - QTRY_COMPARE(drawer->popupItem()->x(), window->width() - drawer->width()); + QTRY_COMPARE(geometry(dimmer), QRectF(0, 150, window->width(), window->height() - 150)); + QCOMPARE(geometry(popupItem), QRectF(window->width() - drawer->width(), 150, window->width() / 2, window->height() - 150)); drawer->close(); - QTRY_COMPARE(drawer->popupItem()->x(), static_cast(window->width())); + QTRY_COMPARE(geometry(popupItem), QRectF(window->width(), 150, window->width() / 2, window->height() - 150)); } void tst_Drawer::header() -- cgit v1.2.3