@@ -1,4 +1,4 @@
2 * Copyright (C) 2016 Canonical, Ltd.
2 * Copyright (C) 2016 Canonical, Ltd.
4 * This program is free software; you can redistribute it and/or modify
4 * This program is free software; you can redistribute it and/or modify
@@ -28,8 +28,8 @@ import ".."
31− width: Math.max(units.gu(100), page.width + units.gu(6))
31+ width: Math.max(units.gu(100), loader.width + units.gu(6))
32− height: Math.max(units.gu(50), page.height + units.gu(6))
32+ height: Math.max(units.gu(50), loader.height + units.gu(6))
35 target: MouseTouchAdaptor
35 target: MouseTouchAdaptor
@@ -39,25 +39,37 @@ Item {
40 ApplicationMenuDataLoader { id: appMenuData }
40 ApplicationMenuDataLoader { id: appMenuData }
42− MenuPopup {
44+ sourceComponent: MenuPopup {
43− id: page
45+ anchors {
46+ left: parent ? parent.left : undefined
47+ top: parent ? parent.top : undefined
48+ leftMargin: units.gu(3)
49+ topMargin: units.gu(3)
45− anchors {
52+ unityMenuModel: UnityMenuModel {
46− left: parent.left
53+ modelData: [{
47− top: parent.top
54+ "rowData": {
48− leftMargin: units.gu(3)
55+ "label": "Short",
49− topMargin: units.gu(3)
56+ }}, {
58+ "label": "This is a long menu item which tests width",
52− unityMenuModel: UnityMenuModel {
63+ Binding {
53− id: menuBackend
64+ target: activatedSpy
54− modelData: appMenuData.generateTestData(7,5,2,3,"menu")
65+ property: "target"
66+ value: unityMenuModel
58 SignalSpy {
71 SignalSpy {
59 id: activatedSpy
72 id: activatedSpy
61 signalName: "activated"
73 signalName: "activated"
@@ -66,14 +78,20 @@ Item {
66 name: "MenuPopup"
78 name: "MenuPopup"
67 when: windowShown
79 when: windowShown
81+ property var menu: loader.status === Loader.Ready ? loader.item : null
69 function init() {
83 function init() {
84+ loader.active = true;
70− page.show();
85+ menu.show();
73 function cleanup() {
88 function cleanup() {
74− page.reset();
89+ menu.reset();
75 wait(100); // let the page dismiss
90 wait(100); // let the page dismiss
76 activatedSpy.clear();
91 activatedSpy.clear();
93+ loader.active = false;
94+ tryCompare(loader, "item", null);
79 // visit and verify that all the backend menus have been created
97 // visit and verify that all the backend menus have been created
@@ -90,6 +108,7 @@ Item {
90 // recurse into submenu
108 // recurse into submenu
91 var submenu = rows[i]["submenu"];
109 var submenu = rows[i]["submenu"];
92 if (submenu) {
110 if (submenu) {
111+ waitForRendering(menuItem);
93 mouseClick(menuItem, menuItem.width/2, menuItem.height/2);
112 mouseClick(menuItem, menuItem.width/2, menuItem.height/2);
94 tryCompare(menuPriv, "currentItem", menuItem);
113 tryCompare(menuPriv, "currentItem", menuItem);
@@ -113,15 +132,15 @@ Item {
115 function test_mouseNavigation(data) {
134 function test_mouseNavigation(data) {
116− menuBackend.modelData = data.testData;
135+ menu.unityMenuModel.modelData = data.testData;
118− recurseMenuConstruction(data.testData, page);
137+ recurseMenuConstruction(data.testData, menu);
121 function test_checkableMenuTogglesOnClick() {
140 function test_checkableMenuTogglesOnClick() {
122− menuBackend.modelData = appMenuData.singleCheckable;
141+ menu.unityMenuModel.modelData = appMenuData.singleCheckable;
124− var menuItem = findChild(page, "menu-item0-actionItem");
143+ var menuItem = findChild(menu, "menu-item0-actionItem");
125 verify(menuItem);
144 verify(menuItem);
126 compare(menuItem.action.checkable, true, "Menu item should be checkable");
145 compare(menuItem.action.checkable, true, "Menu item should be checkable");
127 compare(menuItem.action.checked, false, "Menu item should not be checked");
146 compare(menuItem.action.checked, false, "Menu item should not be checked");
@@ -132,13 +151,13 @@ Item {
134 function test_keyboardNavigation_DownKeySelectsAndOpensNextMenuItemAndRotates() {
153 function test_keyboardNavigation_DownKeySelectsAndOpensNextMenuItemAndRotates() {
135− menuBackend.modelData = appMenuData.generateTestData(3,3,0,0,"menu",false);
154+ menu.unityMenuModel.modelData = appMenuData.generateTestData(3,3,0,0,"menu",false);
137− var item0 = findChild(page, "menu-item0"); verify(item0);
156+ var item0 = findChild(menu, "menu-item0"); verify(item0);
138− var item1 = findChild(page, "menu-item1"); verify(item1);
157+ var item1 = findChild(menu, "menu-item1"); verify(item1);
139− var item2 = findChild(page, "menu-item2"); verify(item2);
158+ var item2 = findChild(menu, "menu-item2"); verify(item2);
141− var priv = findInvisibleChild(page, "d");
160+ var priv = findInvisibleChild(menu, "d");
143 keyClick(Qt.Key_Down, Qt.NoModifier);
162 keyClick(Qt.Key_Down, Qt.NoModifier);
144 compare(priv.currentItem, item0, "CurrentItem should have moved to item 0");
163 compare(priv.currentItem, item0, "CurrentItem should have moved to item 0");
@@ -154,13 +173,13 @@ Item {
156 function test_keyboardNavigation_UpKeySelectsAndOpensPreviousMenuItemAndRotates() {
175 function test_keyboardNavigation_UpKeySelectsAndOpensPreviousMenuItemAndRotates() {
157− menuBackend.modelData = appMenuData.generateTestData(3,3,0,0,"menu",false);
176+ menu.unityMenuModel.modelData = appMenuData.generateTestData(3,3,0,0,"menu",false);
159− var item0 = findChild(page, "menu-item0"); verify(item0);
178+ var item0 = findChild(menu, "menu-item0"); verify(item0);
160− var item1 = findChild(page, "menu-item1"); verify(item1);
179+ var item1 = findChild(menu, "menu-item1"); verify(item1);
161− var item2 = findChild(page, "menu-item2"); verify(item2);
180+ var item2 = findChild(menu, "menu-item2"); verify(item2);
163− var priv = findInvisibleChild(page, "d");
182+ var priv = findInvisibleChild(menu, "d");
165 keyClick(Qt.Key_Down, Qt.NoModifier);
184 keyClick(Qt.Key_Down, Qt.NoModifier);
166 compare(priv.currentItem, item0, "CurrentItem should have moved to item 2");
185 compare(priv.currentItem, item0, "CurrentItem should have moved to item 2");
@@ -176,17 +195,17 @@ Item {
178 function test_keyboardNavigation_RightKeyEntersSubMenu() {
197 function test_keyboardNavigation_RightKeyEntersSubMenu() {
179− menuBackend.modelData = appMenuData.generateTestData(3,3,1,0,"menu",false);
198+ menu.unityMenuModel.modelData = appMenuData.generateTestData(3,3,1,0,"menu",false);
181− var menuItem = findChild(page, "menu-item0");
200+ var menuItem = findChild(menu, "menu-item0");
183− var priv = findInvisibleChild(page, "d");
202+ var priv = findInvisibleChild(menu, "d");
184 priv.currentItem = menuItem;
203 priv.currentItem = menuItem;
186 keyClick(Qt.Key_Right, Qt.NoModifier);
205 keyClick(Qt.Key_Right, Qt.NoModifier);
187 tryCompareFunction(function() { return menuItem.popup !== null && menuItem.popup.visible }, true);
206 tryCompareFunction(function() { return menuItem.popup !== null && menuItem.popup.visible }, true);
189− var submenu0 = findChild(page, "menu-item0-menu"); verify(submenu0);
208+ var submenu0 = findChild(menu, "menu-item0-menu"); verify(submenu0);
190 var submenu0item0 = findChild(submenu0, "menu-item0-menu-item0"); verify(submenu0item0);
209 var submenu0item0 = findChild(submenu0, "menu-item0-menu-item0"); verify(submenu0item0);
192 var submenu0Priv = findInvisibleChild(submenu0, "d"); verify(submenu0Priv);
211 var submenu0Priv = findInvisibleChild(submenu0, "d"); verify(submenu0Priv);
@@ -194,14 +213,106 @@ Item {
196 function test_keyboardNavigation_LeftKeyClosesSubMenu() {
215 function test_keyboardNavigation_LeftKeyClosesSubMenu() {
197− menuBackend.modelData = appMenuData.generateTestData(3,3,1,0,"menu",false);
216+ menu.unityMenuModel.modelData = appMenuData.generateTestData(3,3,1,0,"menu",false);
199− var menuItem = findChild(page, "menu-item0"); verify(menuItem);
218+ var menuItem = findChild(menu, "menu-item0"); verify(menuItem);
200 mouseClick(menuItem, menuItem.width/2, menuItem.height/2);
219 mouseClick(menuItem, menuItem.width/2, menuItem.height/2);
201 tryCompareFunction(function() { return menuItem.popup !== null && menuItem.popup.visible }, true);
220 tryCompareFunction(function() { return menuItem.popup !== null && menuItem.popup.visible }, true);
203 keyClick(Qt.Key_Left, Qt.NoModifier);
222 keyClick(Qt.Key_Left, Qt.NoModifier);
204 tryCompareFunction(function() { return menuItem.popup !== null && menuItem.popup.visible }, false);
223 tryCompareFunction(function() { return menuItem.popup !== null && menuItem.popup.visible }, false);
226+ function test_differentSizes() {
227+ var differentSizesMenu = [{
228+ "rowData": { "label": "Short" }}, {
229+ "rowData": { "label": "This is a long menu item which tests width" }
232+ menu.unityMenuModel.modelData = differentSizesMenu;
234+ waitForRendering(menu);
235+ var longWidth = menu.width;
236+ differentSizesMenu.pop();
237+ menu.unityMenuModel.modelData = differentSizesMenu;
239+ waitForRendering(menu);
240+ verify(menu.width < longWidth);
243+ function test_minimumWidth() {
245+ "rowData": { "label": "Short" }
247+ menu.unityMenuModel.modelData = shortMenu;
249+ var priv = findInvisibleChild(menu, "d");
250+ priv.__minimumWidth = 0;
251+ priv.__maximumWidth = 1000;
252+ tryCompareFunction(function() { return menu.width > priv.__minimumWidth; }, true);
254+ priv.__minimumWidth = 300;
255+ tryCompare(menu, "width", priv.__minimumWidth);
258+ function test_maximumWidth() {
260+ "rowData": { "label": "This is a long menu item which tests width" }
263+ var priv = findInvisibleChild(menu, "d");
264+ priv.__minimumWidth = 0;
265+ priv.__maximumWidth = 100;
267+ menu.unityMenuModel.modelData = longMenu;
268+ tryCompare(menu, "width", priv.__maximumWidth);
270+ priv.__maximumWidth = 200;
271+ tryCompare(menu, "width", priv.__maximumWidth);
273+ priv.__maximumWidth = 1200;
274+ tryCompareFunction(function() { return menu.width < priv.__maximumWidth; }, true);
277+ function test_minimumHeight() {
279+ "rowData": { "label": "menu1" }
281+ menu.unityMenuModel.modelData = shortMenu;
283+ var priv = findInvisibleChild(menu, "d");
284+ priv.__minimumHeight = 0;
285+ priv.__maximumHeight = 1000;
286+ tryCompareFunction(function() { return menu.height > priv.__minimumHeight; }, true);
288+ priv.__minimumHeight = 300;
289+ tryCompare(menu, "height", priv.__minimumHeight);
292+ function test_maximumHeight() {
294+ "rowData": { "label": "menu1" }}, {
295+ "rowData": { "label": "menu2" }}, {
296+ "rowData": { "label": "menu3" }}, {
297+ "rowData": { "label": "menu4" }}, {
298+ "rowData": { "label": "menu5" }}, {
299+ "rowData": { "label": "menu6" }}, {
300+ "rowData": { "label": "menu7" }}, {
301+ "rowData": { "label": "menu8" }}, {
302+ "rowData": { "label": "menu9" }
304+ menu.unityMenuModel.modelData = shortMenu;
306+ var priv = findInvisibleChild(menu, "d");
307+ priv.__minimumHeight = 0;
308+ priv.__maximumHeight = 100;
309+ tryCompare(menu, "height", priv.__maximumHeight);
311+ priv.__maximumHeight = 200;
312+ tryCompare(menu, "height", priv.__maximumHeight);
314+ priv.__maximumHeight = 1200;
315+ tryCompareFunction(function() { return menu.height < priv.__maximumHeight; }, true);