diff options
author | Mitch Curtis <mitch.curtis@theqtcompany.com> | 2015-02-12 13:55:22 +0100 |
---|---|---|
committer | J-P Nurmi <jpnurmi@theqtcompany.com> | 2015-02-13 12:01:33 +0000 |
commit | 6f15c206b069ed0fcf48a285bfcc4ad636927df0 (patch) | |
tree | 6150e262bc2d049219981a4cb1e1deeeeed5d636 /tests/auto/extras/data/tst_piemenu.qml | |
parent | d28a02aec9a1632f2263d9276099454b33fb6741 (diff) | |
download | qtquickcontrols-6f15c206b069ed0fcf48a285bfcc4ad636927df0.tar.gz |
Import Qt Quick Extras (the former Qt Quick Enterprise Controls)
Change-Id: I59c5c97c564f707da4ce617e25e13ff8124f7d4b
Reviewed-by: J-P Nurmi <jpnurmi@theqtcompany.com>
Diffstat (limited to 'tests/auto/extras/data/tst_piemenu.qml')
-rw-r--r-- | tests/auto/extras/data/tst_piemenu.qml | 836 |
1 files changed, 836 insertions, 0 deletions
diff --git a/tests/auto/extras/data/tst_piemenu.qml b/tests/auto/extras/data/tst_piemenu.qml new file mode 100644 index 00000000..fa109a1a --- /dev/null +++ b/tests/auto/extras/data/tst_piemenu.qml @@ -0,0 +1,836 @@ +/**************************************************************************** +** +** Copyright (C) 2015 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:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtTest 1.0 +import QtQuick 2.1 +import QtQuick.Controls 1.1 +import QtQuick.Extras 1.3 +import QtQuick.Extras.Private 1.0 +import QtQuick.Extras.Private.CppUtils 1.0 + +// Have to have Item here otherwise mouse clicks don't work. +Item { + id: container + width: 400 + height: 400 + + TestCase { + id: testcase + name: "Tests_PieMenu" + when: windowShown + anchors.fill: parent + + readonly property real menuWidth: 200 + readonly property real menuHeight: 200 + + // The root item for each test, if one exists. + property Item root + // The pie menu for each test, if no root is created. + property Item pieMenu + + SignalSpy { + id: currentIndexSignalSpy + } + + SignalSpy { + id: actionSignalSpy + } + + SignalSpy { + id: selectedAngleChangedSpy + } + + function cleanup() { + currentIndexSignalSpy.clear(); + actionSignalSpy.clear(); + selectedAngleChangedSpy.clear(); + + if (root) + root.destroy(); + if (pieMenu) + pieMenu.destroy(); + } + + function mouseButtonToString(button) { + return button === Qt.LeftButton ? "Qt.LeftButton" : "Qt.RightButton"; + } + + function triggerModeToString(triggerMode) { + return triggerMode === TriggerMode.TriggerOnPress ? "TriggerOnPress" + : (triggerMode === TriggerMode.TriggerOnRelease ? "TriggerOnRelease" : "TriggerOnClick"); + } + + function test_instance() { + var pieMenu = Qt.createQmlObject("import QtQuick.Extras 1.3; PieMenu { }", container, ""); + verify(pieMenu, "PieMenu: failed to create an instance"); + verify(pieMenu.__style); + compare(pieMenu.triggerMode, TriggerMode.TriggerOnClick); + pieMenu.destroy(); + + // Ensure setting visible = true; visible = false; in onCompleted doesn't cause any problems. + var pieMenuComponent = Qt.createComponent("PieMenuVisibleOnCompleted.qml"); + tryCompare(pieMenuComponent, "status", Component.Ready); + pieMenu = pieMenuComponent.createObject(container); + verify(pieMenu, "PieMenu: failed to create an instance"); + pieMenu.destroy(); + + // Ensure constructing a menu as a property (and hence no parent) + // with visible = true doesn't cause any problems. + pieMenuComponent = Qt.createComponent("PieMenuVisibleButNoParent.qml"); + tryCompare(pieMenuComponent, "status", Component.Ready); + pieMenu = pieMenuComponent.createObject(container); + verify(pieMenu, "PieMenu: failed to create an instance"); + pieMenu.destroy(); + } + + function test_triggerMode() { + var pieMenuComponent = Qt.createComponent("PieMenu3Items.qml"); + tryCompare(pieMenuComponent, "status", Component.Ready); + root = pieMenuComponent.createObject(container); + var mouseArea = root.mouseArea; + var pieMenu = root.pieMenu; + currentIndexSignalSpy.signalName = "onCurrentIndexChanged" + currentIndexSignalSpy.target = pieMenu; + actionSignalSpy.signalName = "onActionTriggered"; + actionSignalSpy.target = root; + + compare(pieMenu.triggerMode, TriggerMode.TriggerOnClick); + + var triggerModes = [ + TriggerMode.TriggerOnClick, + TriggerMode.TriggerOnPress, + TriggerMode.TriggerOnRelease + ]; + // Our root mouse area will accept either left click or right click, + // and the menu should accept either to select items or close it. + var buttonVariations = [ + [Qt.LeftButton, Qt.LeftButton], + [Qt.RightButton, Qt.RightButton], + [Qt.LeftButton, Qt.RightButton], + [Qt.RightButton, Qt.LeftButton] + ]; + for (var modeIndex = 0; modeIndex < triggerModes.length; ++modeIndex) { + for (var i = 0; i < buttonVariations.length; ++i) { + var openButton = buttonVariations[i][0]; + var closeButton = buttonVariations[i][1]; + + pieMenu.triggerMode = triggerModes[modeIndex]; + compare(pieMenu.triggerMode, triggerModes[modeIndex]); + + // Make the menu visible. + if (pieMenu.triggerMode !== TriggerMode.TriggerOnRelease) { + mouseClick(root, 0, 0, openButton); + } else { + mousePress(root, 0, 0, openButton); + } + tryCompare(pieMenu, "visible", true); + + // Click/press outside the menu to close it. + switch (pieMenu.triggerMode) { + case TriggerMode.TriggerOnClick: + mouseClick(root, 0, 0, closeButton); + tryCompare(currentIndexSignalSpy, "count", 0); + compare(pieMenu.visible, false, "Menu isn't closed when clicking " + + mouseButtonToString(closeButton) + " outside (triggerMode: " + + triggerModeToString(pieMenu.triggerMode) + ", openButton: " + + mouseButtonToString(openButton) + ")"); + break; + case TriggerMode.TriggerOnPress: + mousePress(root, 0, 0, closeButton); + tryCompare(currentIndexSignalSpy, "count", 0); + compare(pieMenu.visible, false, "Menu isn't closed when pressing " + + mouseButtonToString(closeButton) + " outside (triggerMode: " + + triggerModeToString(pieMenu.triggerMode) + ", openButton: " + + mouseButtonToString(openButton) + ")"); + mouseRelease(root, 0, 0, closeButton); + tryCompare(currentIndexSignalSpy, "count", 0); + compare(pieMenu.visible, false, "Menu shouldn't be opened when releasing " + + mouseButtonToString(closeButton) + " outside (triggerMode: " + + triggerModeToString(pieMenu.triggerMode) + ", openButton: " + + mouseButtonToString(openButton) + ")"); + break; + case TriggerMode.TriggerOnRelease: + mouseRelease(root, 0, 0, closeButton); + tryCompare(currentIndexSignalSpy, "count", 0); + compare(pieMenu.visible, false, "Menu is closed when releasing " + + mouseButtonToString(closeButton) + " outside"); + break; + } + + // Make the menu visible again. + if (pieMenu.triggerMode !== TriggerMode.TriggerOnRelease) { + mouseClick(root, 0, 0, openButton); + } else { + mousePress(root, 0, 0, openButton); + } + tryCompare(pieMenu, "visible", true); + + switch (pieMenu.triggerMode) { + case TriggerMode.TriggerOnClick: + // Click on a section of the menu (index 1); it should trigger the item and then close the menu. + mouseClick(root, pieMenu.x + pieMenu.width / 2, pieMenu.y + pieMenu.height / 4, closeButton); + // The current index changes once when the item is selected (1) and once when the menu closes (-1). + tryCompare(currentIndexSignalSpy, "count", 2); + compare(actionSignalSpy.count, 1); + compare(actionSignalSpy.signalArguments[0][0], 1); + compare(pieMenu.currentIndex, -1); + compare(pieMenu.visible, false); + break; + case TriggerMode.TriggerOnPress: + // Press on a section of the menu (index 1); it should trigger the item and then close the menu. + mousePress(root, pieMenu.x + pieMenu.width / 2, pieMenu.y + pieMenu.height / 4, closeButton); + // The current index changes once when the item is selected (1) and once when the menu closes (-1). + tryCompare(currentIndexSignalSpy, "count", 2); + compare(actionSignalSpy.count, 1); + compare(actionSignalSpy.signalArguments[0][0], 1); + compare(pieMenu.currentIndex, -1); + compare(pieMenu.visible, false); + + mouseRelease(root, pieMenu.x + pieMenu.width / 2, pieMenu.y + pieMenu.height / 4, closeButton); + // None of these should change after releasing. + tryCompare(currentIndexSignalSpy, "count", 2); + compare(actionSignalSpy.count, 1); + compare(pieMenu.currentIndex, -1); + compare(pieMenu.visible, false); + break; + case TriggerMode.TriggerOnRelease: + // Click/press on a section of the menu (index 1); it should trigger the item and then close the menu. + mouseRelease(root, pieMenu.x + pieMenu.width / 2, pieMenu.y + pieMenu.height / 4, closeButton); + // The current index changes once when the item is selected (1) and once when the menu closes (-1). + tryCompare(currentIndexSignalSpy, "count", 2); + compare(actionSignalSpy.count, 1); + compare(actionSignalSpy.signalArguments[0][0], 1); + compare(pieMenu.currentIndex, -1); + compare(pieMenu.visible, false); + } + + currentIndexSignalSpy.clear(); + actionSignalSpy.clear(); + } + } + } + + function test_selectionAngle_data() { + var data = []; + + var dataRow = {}; + dataRow.startAngle = -90; + dataRow.endAngle = 90; + dataRow.mouseX = 1; + dataRow.mouseY = 1; + dataRow.expectedAngle = -Math.PI / 4; + dataRow.expectedCurrentIndex = -1; + dataRow.tag = "startAngle=" + dataRow.startAngle + ", endAngle=" + dataRow.endAngle + ", top left"; + data.push(dataRow); + + dataRow = {}; + dataRow.startAngle = -90; + dataRow.endAngle = 90; + dataRow.mouseX = menuWidth - 1; + dataRow.mouseY = menuHeight - 1; + dataRow.expectedAngle = Math.PI * 0.75; + dataRow.expectedCurrentIndex = -1; + dataRow.tag = "startAngle=" + dataRow.startAngle + ", endAngle=" + dataRow.endAngle + ", bottom right"; + data.push(dataRow); + + dataRow = {}; + dataRow.startAngle = -90; + dataRow.endAngle = -270; + dataRow.mouseX = menuWidth / 2 - 1; + dataRow.mouseY = menuHeight * 0.75; + dataRow.expectedAngle = -3.1215953196166426; + dataRow.expectedCurrentIndex = 1; + dataRow.tag = "startAngle=" + dataRow.startAngle + ", endAngle=" + dataRow.endAngle + ", bottom left edge"; + data.push(dataRow); + + dataRow = {}; + dataRow.startAngle = -90; + dataRow.endAngle = -270; + dataRow.mouseX = menuWidth / 2 + 1; + dataRow.mouseY = menuHeight * 0.75; + dataRow.expectedAngle = 3.1215953196166426; + dataRow.expectedCurrentIndex = 1; + dataRow.tag = "startAngle=" + dataRow.startAngle + ", endAngle=" + dataRow.endAngle + ", bottom right edge"; + data.push(dataRow); + + dataRow = {}; + dataRow.startAngle = 0; + dataRow.endAngle = 190; + dataRow.mouseX = menuWidth / 2 - 1; + dataRow.mouseY = menuHeight * 0.75; + dataRow.expectedAngle = -3.1215953196166426; + dataRow.expectedCurrentIndex = 2; + dataRow.tag = "startAngle=" + dataRow.startAngle + ", endAngle=" + dataRow.endAngle + ", bottom left edge"; + data.push(dataRow); + + dataRow = {}; + dataRow.startAngle = 0; + dataRow.endAngle = -90; + dataRow.mouseX = menuWidth / 4; + dataRow.mouseY = menuHeight / 2 - 1; + dataRow.expectedAngle = -1.550798992821746; + dataRow.expectedCurrentIndex = 2; + dataRow.tag = "startAngle=" + dataRow.startAngle + ", endAngle=" + dataRow.endAngle + ", section 2"; + data.push(dataRow); + + dataRow = {}; + dataRow.startAngle = 0; + dataRow.endAngle = -90; + dataRow.mouseX = menuWidth / 4; + dataRow.mouseY = menuHeight / 4; + dataRow.expectedAngle = -0.7853981633974483; + dataRow.expectedCurrentIndex = 1; + dataRow.tag = "startAngle=" + dataRow.startAngle + ", endAngle=" + dataRow.endAngle + ", section 1"; + data.push(dataRow); + + dataRow = {}; + dataRow.startAngle = 0; + dataRow.endAngle = -90; + dataRow.mouseX = menuWidth / 2 - 1; + dataRow.mouseY = menuHeight / 4; + dataRow.expectedAngle = -0.01999733397315053; + dataRow.expectedCurrentIndex = 0; + dataRow.tag = "startAngle=" + dataRow.startAngle + ", endAngle=" + dataRow.endAngle + ", section 0"; + data.push(dataRow); + + dataRow = {}; + dataRow.startAngle = -190; + dataRow.endAngle = -90; + dataRow.mouseX = menuWidth / 2 + 1; + dataRow.mouseY = menuHeight * 0.75; + dataRow.expectedAngle = 3.1215953196166426; + dataRow.expectedCurrentIndex = 0; + dataRow.tag = "startAngle=" + dataRow.startAngle + ", endAngle=" + dataRow.endAngle + ", bottom right edge"; + data.push(dataRow); + + dataRow = {}; + dataRow.startAngle = -90; + dataRow.endAngle = -190; + dataRow.mouseX = menuWidth / 2 + 1; + dataRow.mouseY = menuHeight * 0.75; + dataRow.expectedAngle = 3.1215953196166426; + dataRow.expectedCurrentIndex = 2; + dataRow.tag = "startAngle=" + dataRow.startAngle + ", endAngle=" + dataRow.endAngle + ", bottom right edge"; + data.push(dataRow); + + return data; + } + + function test_selectionAngle(data) { + var pieMenuComponent = Qt.createComponent("PieMenu3Items.qml"); + tryCompare(pieMenuComponent, "status", Component.Ready); + root = pieMenuComponent.createObject(container); + var mouseArea = root.mouseArea; + var pieMenu = root.pieMenu; + + compare(pieMenu.selectionAngle, 0); + + pieMenu.__style.startAngle = data.startAngle; + pieMenu.__style.endAngle = data.endAngle; + + waitForRendering(root); + root.forceActiveFocus(); + // Don't allow bounds snapping by always opening within bounds. + mouseClick(root, menuWidth / 2, menuHeight / 2); + tryCompare(pieMenu, "visible", true); + + mouseMove(root, data.mouseX, data.mouseY); + compare(pieMenu.selectionAngle, data.expectedAngle); + compare(pieMenu.currentIndex, data.expectedCurrentIndex); + } + + function test_sectionAngles_data() { + var data = []; + var angleOrigin = 90; + + var dataRow = {}; + dataRow.startAngle = -90; + dataRow.endAngle = 90; + dataRow.section = 0; + dataRow.expectedSectionSize = MathUtils.degToRadOffset(60 + angleOrigin); + dataRow.expectedSectionStartAngle = MathUtils.degToRadOffset(-90); + dataRow.expectedSectionCenterAngle = MathUtils.degToRadOffset(-60); + dataRow.expectedSectionEndAngle = MathUtils.degToRadOffset(-30); + dataRow.tag = "startAngle=" + dataRow.startAngle + ", endAngle=" + dataRow.endAngle + ", section=" + dataRow.section; + data.push(dataRow); + + dataRow = {}; + dataRow.startAngle = 270; + dataRow.endAngle = 90; + dataRow.section = 0; + dataRow.expectedSectionSize = MathUtils.degToRadOffset(-60 + angleOrigin); + dataRow.expectedSectionStartAngle = MathUtils.degToRadOffset(270); + dataRow.expectedSectionCenterAngle = MathUtils.degToRadOffset(240); + dataRow.expectedSectionEndAngle = MathUtils.degToRadOffset(210); + dataRow.tag = "startAngle=" + dataRow.startAngle + ", endAngle=" + dataRow.endAngle + ", section=" + dataRow.section; + data.push(dataRow); + + return data; + } + + function test_sectionAngles(data) { + var pieMenuComponent = Qt.createComponent("PieMenu3Items.qml"); + tryCompare(pieMenuComponent, "status", Component.Ready); + root = pieMenuComponent.createObject(container); + var pieMenu = root.pieMenu; + + pieMenu.__style.startAngle = data.startAngle; + pieMenu.__style.endAngle = data.endAngle; + compare(pieMenu.__protectedScope.sectionSize, data.expectedSectionSize); + compare(pieMenu.__protectedScope.sectionStartAngle(data.section), data.expectedSectionStartAngle); + compare(pieMenu.__protectedScope.sectionCenterAngle(data.section), data.expectedSectionCenterAngle); + compare(pieMenu.__protectedScope.sectionEndAngle(data.section), data.expectedSectionEndAngle); + } + + function test_bounds_data() { + return [ + { tag: "noSnapCenter", mouseX: container.width / 2, mouseY: container.height / 2, + expectedX: container.width / 2 - 100, expectedY: container.height / 2 - 100 }, + { tag: "noSnapNearLeft", mouseX: 100, mouseY: container.height / 2, + expectedX: 0, expectedY: container.height / 2 - 100 }, + { tag: "noSnapNearRight", mouseX: container.width - 100, mouseY: container.height / 2, + expectedX: container.width - menuWidth, expectedY: container.height / 2 - 100 }, + { tag: "noSnapNearTop", mouseX: container.width / 2, mouseY: 100, + expectedX: container.width / 2 - 100, expectedY: 0 }, + { tag: "noSnapNearBottom", mouseX: container.width / 2, mouseY: container.height - 100, + expectedX: container.width / 2 - 100, expectedY: container.height - menuHeight }, + { tag: "noSnapNearTopLeft", mouseX: 100, mouseY: 100, + expectedX: 0, expectedY: 0 }, + { tag: "noSnapNearTopRight", mouseX: container.width - 100, mouseY: 100, + expectedX: container.width - menuWidth, expectedY: 0 }, + { tag: "noSnapNearBottomRight", mouseX: container.width - 100, mouseY: container.height - 100, + expectedX: container.width - menuWidth, expectedY: container.height - menuHeight }, + { tag: "noSnapNearBottomLeft", mouseX: 100, mouseY: container.height - 100, + expectedX: 0, expectedY: container.height - menuHeight }, + { tag: "leftEdge", mouseX: 10, mouseY: container.height / 2, + expectedX: 0, expectedY: container.height / 2 - 100 }, + { tag: "rightEdge", mouseX: container.width - 10, mouseY: container.height / 2, + expectedX: container.width - menuHeight, expectedY: container.height / 2 - 100 }, + { tag: "topEdge", mouseX: container.width / 2, mouseY: 10, + expectedX: container.width / 2 - 100, expectedY: 0 }, + // The default start and end angles mean that the bottom edge won't snap. + { tag: "bottomEdge", mouseX: container.width / 2, mouseY: container.height - 10, + expectedX: container.width / 2 - 100, expectedY: container.height - 100 - 10 }, + { tag: "topLeftCorner", mouseX: 10, mouseY: 10, + expectedX: 0, expectedY: 0 }, + { tag: "topRightCorner", mouseX: container.width - 10, mouseY: 10, + expectedX: container.width - menuHeight, expectedY: 0 }, + { tag: "bottomRightCorner", mouseX: container.width - 10, mouseY: container.height - 10, + expectedX: container.width - menuHeight, expectedY: container.height - 100 - 10 }, + { tag: "bottomLeftCorner", mouseX: 10, mouseY: container.height - 10, + expectedX: 0, expectedY: container.height - 100 - 10 } + ] + } + + function test_bounds(data) { + var pieMenuComponent = Qt.createComponent("PieMenu3Items.qml"); + tryCompare(pieMenuComponent, "status", Component.Ready); + root = pieMenuComponent.createObject(container); + var mouseArea = root.mouseArea; + var pieMenu = root.pieMenu; + + var rootParent = pieMenu; + while (rootParent.parent) { + rootParent = rootParent.parent; + } + // Necessary due to QTBUG-36938 + rootParent.width = 400; + rootParent.height = 400; + + var originalStartAngle = pieMenu.__style.startAngle; + var originalEndAngle = pieMenu.__style.endAngle; + + mouseClick(root, data.mouseX, data.mouseY); + tryCompare(pieMenu, "visible", true); + + compare(pieMenu.x, data.expectedX); + compare(pieMenu.y, data.expectedY); + + // Angles shouldn't change. + compare(pieMenu.__style.startAngle, originalStartAngle); + compare(pieMenu.__style.endAngle, originalEndAngle); + + // Cancel the menu. Even if it's at the top left, this will land on the cancel area. + mouseClick(root, pieMenu.x + pieMenu.width / 2, pieMenu.y + pieMenu.height / 2); + compare(pieMenu.visible, false); + + // Angles shouldn't change. + compare(pieMenu.__style.startAngle, originalStartAngle); + compare(pieMenu.__style.endAngle, originalEndAngle); + } + + function test_hideItem_data() { + return [ + { tag: "hideFirst", indexVisibility: [false, true, true], expectedIndexHits: [0, 1, 1], expectedText: ["item1", "item1", "item2"] }, + { tag: "hideSecond", indexVisibility: [true, false, true], expectedIndexHits: [0, 1, 1], expectedText: ["item0", "item0", "item2"] }, + { tag: "hideThird", indexVisibility: [true, true, false], expectedIndexHits: [0, 1, 1], expectedText: ["item0", "item0", "item1"] }, + ]; + } + + function test_hideItem(data) { + var pieMenuComponent = Qt.createComponent("PieMenu3Items.qml"); + tryCompare(pieMenuComponent, "status", Component.Ready); + root = pieMenuComponent.createObject(container); + var mouseArea = root.mouseArea; + var pieMenu = root.pieMenu; + + var originalStartAngle = pieMenu.__style.startAngle; + var originalEndAngle = pieMenu.__style.endAngle; + + // Store the positions at which we should click before we remove any items. + var mousePositions = [Qt.point(40, 70), Qt.point(90, 30), Qt.point(160, 70)]; + + while (pieMenu.menuItems.length > 0) { + pieMenu.removeItem(pieMenu.menuItems[pieMenu.menuItems.length - 1]); + } + + for (var i = 0; i < data.indexVisibility.length; ++i) { + var item = pieMenu.addItem("item" + i); + item.triggered.connect(function (){ root.actionTriggered(data.expectedIndexHits[i]) }) + item.visible = data.indexVisibility[i]; + } + + // Angles shouldn't change. + compare(pieMenu.__style.startAngle, originalStartAngle); + compare(pieMenu.__style.endAngle, originalEndAngle); + + for (i = 0; i < data.indexVisibility.length; ++i) { + actionSignalSpy.signalName = "onActionTriggered"; + actionSignalSpy.target = root; + + compare(pieMenu.visible, false); + + // Make the menu visible. + mouseClick(root, 100, 100, Qt.LeftButton); + tryCompare(pieMenu, "visible", true); + + var pos = mousePositions[i]; + + mouseMove(root, pos.x, pos.y); + // Not all styles have titles. + if (pieMenu.__style.title) + tryCompare(pieMenu.__panel.titleItem, "text", data.expectedText[i]); + + mouseClick(root, pos.x, pos.y, Qt.LeftButton); + + tryCompare(pieMenu, "visible", false); + compare(actionSignalSpy.count, 1); + compare(actionSignalSpy.signalArguments[0][0], data.expectedIndexHits[i]); + + actionSignalSpy.clear(); + } + } + + function test_addItem() { + pieMenu = Qt.createQmlObject("import QtQuick.Extras 1.1; PieMenu {}", container); + compare(pieMenu.menuItems.length, 0); + + pieMenu.addItem("Action 1"); + compare(pieMenu.menuItems.length, 1); + } + + function test_insertItem() { + pieMenu = Qt.createQmlObject("import QtQuick.Extras 1.1; PieMenu {}", container); + compare(pieMenu.menuItems.length, 0); + + pieMenu.insertItem(0, "Action 1"); + compare(pieMenu.menuItems.length, 1); + compare(pieMenu.menuItems[0].text, "Action 1"); + + pieMenu.insertItem(1, "Action 2"); + compare(pieMenu.menuItems.length, 2); + compare(pieMenu.menuItems[0].text, "Action 1"); + compare(pieMenu.menuItems[1].text, "Action 2"); + } + + function test_removeItem() { + var pieMenuComponent = Qt.createComponent("PieMenu3Items.qml"); + tryCompare(pieMenuComponent, "status", Component.Ready); + root = pieMenuComponent.createObject(container); + var pieMenu = root.pieMenu; + + var originalLength = pieMenu.menuItems.length; + for (var i = 0; i < originalLength; ++i) { + pieMenu.removeItem(pieMenu.menuItems[pieMenu.menuItems.length - 1]); + compare(pieMenu.menuItems.length, originalLength - (i + 1)); + } + } + + function debugMousePosition(pieMenu, mouseX, mouseY, positionText) { + var rectItem = Qt.createQmlObject("import QtQuick 2.0; Rectangle { width: 10; height: 10; radius: 5; color: 'red' }", pieMenu); + rectItem.x = mouseX - rectItem.width / 2; + rectItem.y = mouseY - rectItem.height / 2; + + var textItem = Qt.createQmlObject("import QtQuick 2.0; Text {}", rectItem); + textItem.text = positionText; + textItem.font.pixelSize = 8; + textItem.anchors.centerIn = textItem.parent; + } + + function test_selectionItemOnMouseMove_QTRD3024() { + // Check when an item is hovered by the mouse, it gets made current + // as expected and the current item is cleared when the mouse moves outside the menu + var pieMenuComponent = Qt.createComponent("PieMenu3Items.qml"); + tryCompare(pieMenuComponent, "status", Component.Ready); + root = pieMenuComponent.createObject(container); + var mouseArea = root.mouseArea; + pieMenu = root.pieMenu; + + // Make the menu visible at (0,0) + waitForRendering(root); + root.forceActiveFocus(); + mouseClick(root, 0, 0); + tryCompare(pieMenu, "visible", true); + + // Move the mouse over the menu + mouseMove(root, 0, 0); + compare(pieMenu.currentIndex, -1); + + // We would use a data function for this, but we need access to properties + // of the style that change with each style. + var data = []; + var xCenter = pieMenu.width / 2; + var yCenter = pieMenu.height / 2; + var startAngleFunction = pieMenu.__protectedScope.sectionStartAngle; + var centerAngleFunction = pieMenu.__protectedScope.sectionCenterAngle; + var endAngleFunction = pieMenu.__protectedScope.sectionEndAngle; + + var pos = MathUtils.centerAlongCircle(xCenter, yCenter, 0, 0, centerAngleFunction(0), 90) + data.push({ name: "inside", mouseX: pos.x, mouseY: pos.y, expectedCurrentIndex: 0 }); + + pos = MathUtils.centerAlongCircle(xCenter, yCenter, 0, 0, startAngleFunction(0) + MathUtils.degToRad(1), pieMenu.__style.cancelRadius + 10); + data.push({ name: "bottom", mouseX: pos.x, mouseY: pos.y, expectedCurrentIndex: 0 }); + + pos = MathUtils.centerAlongCircle(xCenter, yCenter, 0, 0, centerAngleFunction(0), pieMenu.__style.cancelRadius + 10); + data.push({ name: "outside", mouseX: pos.x, mouseY: pos.y, expectedCurrentIndex: 0 }); + + pos = MathUtils.centerAlongCircle(xCenter, yCenter, 0, 0, endAngleFunction(0) - MathUtils.degToRad(1), pieMenu.__style.radius - 1); + data.push({ name: "close to second", mouseX: pos.x, mouseY: pos.y, expectedCurrentIndex: 0 }); + + pos = MathUtils.centerAlongCircle(xCenter, yCenter, 0, 0, centerAngleFunction(1), pieMenu.__style.radius - 1); + data.push({ name: "outside", mouseX: pos.x, mouseY: pos.y, expectedCurrentIndex: 1 }); + + pos = MathUtils.centerAlongCircle(xCenter, yCenter, 0, 0, centerAngleFunction(1) - MathUtils.degToRad(10), + pieMenu.__style.cancelRadius + (pieMenu.__style.radius - pieMenu.__style.cancelRadius) / 2); + data.push({ name: "inside", mouseX: pos.x, mouseY: pos.y, expectedCurrentIndex: 1 }); + + pos = MathUtils.centerAlongCircle(xCenter, yCenter, 0, 0, startAngleFunction(1) + MathUtils.degToRad(1), + pieMenu.__style.radius - 1); + data.push({ name: "close to first", mouseX: pos.x, mouseY: pos.y, expectedCurrentIndex: 1 }); + + pos = MathUtils.centerAlongCircle(xCenter, yCenter, 0, 0, centerAngleFunction(1), pieMenu.__style.cancelRadius + 10); + data.push({ name: "low center", mouseX: 100, mouseY: 50, expectedCurrentIndex: 1 }); + + for (var i = 0; i < data.length; ++i) { + var mouseX = data[i].mouseX; + var mouseY = data[i].mouseY; + var expectedCurrentIndex = data[i].expectedCurrentIndex; + + // Illustrates the positions. +// debugMousePosition(pieMenu, mouseX, mouseY, i); +// wait(1000) + + mouseMove(root, mouseX, mouseY); + compare(pieMenu.currentIndex, expectedCurrentIndex, data[i].name + ": current index should be " + + expectedCurrentIndex + " when mouse is at " + mouseX + ", " + mouseY); + } + } + + function test_QTRD3027() { + // Check that an item's selection is cleared when the mouse moves outside + // its boundaries without changing the selectionAngle + var pieMenuComponent = Qt.createComponent("PieMenu3Items.qml"); + tryCompare(pieMenuComponent, "status", Component.Ready); + root = pieMenuComponent.createObject(container); + var mouseArea = root.mouseArea; + var pieMenu = root.pieMenu; + + // Make the menu visible at (0,0) + root.forceActiveFocus(); + mouseClick(root, 0, 0); + tryCompare(pieMenu, "visible", true); + + // Move the mouse over the menu + mouseMove(root, 0, 0) + compare(pieMenu.currentIndex, -1) + // Move over middle item + mouseMove(root, 100, 50) + compare(pieMenu.currentIndex, 1) + selectedAngleChangedSpy.signalName = "onSelectionAngleChanged" + selectedAngleChangedSpy.target = pieMenu; + // Move outside the middle item without changing angle + mouseMove(root, 100, 98) + compare(pieMenu.currentIndex, -1) + compare(selectedAngleChangedSpy.count, 0) + } + + function test_rotatedBoundingItem() { + var pieMenuComponent = Qt.createComponent("PieMenuRotatedBoundingItem.qml"); + tryCompare(pieMenuComponent, "status", Component.Ready); + root = pieMenuComponent.createObject(container); + var mouseArea = root.mouseArea; + var pieMenu = root.pieMenu; + + mouseClick(root, root.width / 2, root.height / 2, Qt.RightButton); + tryCompare(pieMenu, "visible", true); + + mouseMove(root, 230, 145); + // Not all styles have titles. + if (pieMenu.__style.title) + tryCompare(pieMenu.__panel.titleItem, "text", "Action 1"); + + actionSignalSpy.signalName = "onActionTriggered"; + actionSignalSpy.target = root; + mouseClick(root, 230, 145); + compare(actionSignalSpy.count, 1); + compare(actionSignalSpy.signalArguments[0][0], 0); + } + + function test_boundingItem() { + var oldContainerWidth = container.width; + var oldContainerHeight = container.height; + container.width = 560; + container.height = 560; + + // Tests boundingItem when there are nested margins. + var pieMenuComponent = Qt.createComponent("PieMenuBoundingItem.qml"); + tryCompare(pieMenuComponent, "status", Component.Ready); + root = pieMenuComponent.createObject(container); + var mouseArea = root.mouseArea; + var pieMenu = root.pieMenu; + + var mouseAreaAbsolutePos = mouseArea.mapToItem(root, 0, 0); + mouseClick(root, mouseAreaAbsolutePos.x + mouseArea.width / 2, mouseAreaAbsolutePos.y, Qt.RightButton); + compare(pieMenu.visible, true); + compare(pieMenu.y, -root.margins); + + mouseClick(root, 0, 0); + compare(pieMenu.visible, false); + + var mouseAreaCenterAbsolutePos = mouseArea.mapToItem(root, mouseArea.width / 2, mouseArea.height / 2); + mouseClick(root, mouseAreaCenterAbsolutePos.x, mouseAreaCenterAbsolutePos.y, Qt.RightButton); + compare(pieMenu.visible, true); + compare(pieMenu.mapToItem(root, 0, 0).x, mouseAreaCenterAbsolutePos.x - pieMenu.width / 2); + compare(pieMenu.mapToItem(root, 0, 0).y, mouseAreaCenterAbsolutePos.y - pieMenu.height / 2); + + container.width = oldContainerWidth; + container.height = oldContainerHeight; + } + + function test_longPressTriggerOnClick() { + // Tests that a menu that is opened on press or long press does not + // get closed by a release event when the triggerMode requires a + // press before the release (TriggerOnClick). + var pieMenuComponent = Qt.createComponent("PieMenu3ItemsLongPress.qml"); + tryCompare(pieMenuComponent, "status", Component.Ready); + root = pieMenuComponent.createObject(container); + var pieMenu = root.pieMenu; + + mousePress(root, 0, 0, Qt.LeftButton); + tryCompare(pieMenu, "visible", true); + compare(pieMenu.__mouseThief.receivedPressEvent, false); + compare(pieMenu.__protectedScope.pressedIndex, -1); + + mouseRelease(root, 0, 0, Qt.LeftButton); + compare(pieMenu.visible, true); + compare(pieMenu.__mouseThief.receivedPressEvent, false); + compare(pieMenu.__protectedScope.pressedIndex, -1); + + mousePress(root, 0, 0, Qt.LeftButton); + compare(pieMenu.visible, true); + compare(pieMenu.__mouseThief.receivedPressEvent, true); + compare(pieMenu.__protectedScope.pressedIndex, -1); + + mouseRelease(root, 0, 0, Qt.LeftButton); + compare(pieMenu.visible, false); + compare(pieMenu.__mouseThief.receivedPressEvent, false); + compare(pieMenu.__protectedScope.pressedIndex, -1); + } + + function test_keepMenuOpenWhenTriggered() { + // This functionality is used in the flat example. + var pieMenuComponent = Qt.createComponent("PieMenu3ItemsKeepOpen.qml"); + tryCompare(pieMenuComponent, "status", Component.Ready); + root = pieMenuComponent.createObject(container); + var pieMenu = root.pieMenu; + actionSignalSpy.signalName = "onActionTriggered"; + actionSignalSpy.target = root; + + mouseClick(root, 0, 0, Qt.LeftButton); + tryCompare(pieMenu, "visible", true); + + mouseClick(root, pieMenu.x + pieMenu.width / 4, pieMenu.y + pieMenu.height / 4, Qt.LeftButton); + tryCompare(pieMenu, "visible", true); + compare(actionSignalSpy.count, 1); + compare(actionSignalSpy.signalArguments[0][0], 0); + + actionSignalSpy.clear(); + mouseClick(root, pieMenu.x + pieMenu.width / 2, pieMenu.y + pieMenu.height / 4, Qt.LeftButton); + tryCompare(pieMenu, "visible", true); + compare(actionSignalSpy.count, 1); + compare(actionSignalSpy.signalArguments[0][0], 1); + + actionSignalSpy.clear(); + mouseClick(root, pieMenu.x + pieMenu.width * 0.75, pieMenu.y + pieMenu.height / 4, Qt.LeftButton); + tryCompare(pieMenu, "visible", true); + compare(actionSignalSpy.count, 1); + compare(actionSignalSpy.signalArguments[0][0], 2); + } + + function test_pressedIndex() { + var pieMenuComponent = Qt.createComponent("PieMenu3Items.qml"); + tryCompare(pieMenuComponent, "status", Component.Ready); + root = pieMenuComponent.createObject(container); + pieMenu = root.pieMenu; + actionSignalSpy.signalName = "onActionTriggered"; + actionSignalSpy.target = root; + + mouseClick(root, 0, 0, Qt.LeftButton); + tryCompare(pieMenu, "visible", true); + compare(pieMenu.__protectedScope.pressedIndex, -1); + + mousePress(root, pieMenu.x + pieMenu.width / 4, pieMenu.y + pieMenu.height / 4, Qt.LeftButton); + tryCompare(pieMenu, "visible", true); + compare(pieMenu.__protectedScope.pressedIndex, 0); + + mouseRelease(root, pieMenu.x + pieMenu.width / 4, pieMenu.y + pieMenu.height / 4, Qt.LeftButton); + tryCompare(pieMenu, "visible", false); + compare(actionSignalSpy.count, 1); + compare(actionSignalSpy.signalArguments[0][0], 0); + compare(pieMenu.__protectedScope.pressedIndex, -1); + } + } +} |