@@ -1,5 +1,5 @@
11/*
2− * Copyright 2013 Canonical Ltd.
2+ * Copyright 2013-2014 Canonical Ltd.
33 *
44 * This program is free software; you can redistribute it and/or modify
55 * it under the terms of the GNU General Public License as published by
@@ -14,95 +14,106 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
17+import QtQuick 2.1
18+import QtQuick.Layouts 1.1
1819import QtTest 1.0
1920import Unity.Test 0.1 as UT
20−import Ubuntu.Components 0.1 as UC
21+import Ubuntu.Components 0.1
22+import Unity.Indicators 0.1 as Indicators
2123import Ubuntu.Telephony 0.1 as Telephony
22−import ".."
2324import "../../../qml/Panel"
2425
25−/*
26− This tests the Panel component using a fake model to stage data in the indicators
27− A view will show with indicators at the top, as does in the shell. This can be controlled
28− as in the shell.
29−*/
30−Item {
31− id: shell
32− width: units.gu(40)
33− height: units.gu(80)
34−
35− Panel {
36− id: panel
37− anchors {
38− left: parent.left
39− right: parent.right
40− }
41− height: parent.height - row.height
42− fullscreenMode: false
26+IndicatorTest {
27+ id: root
28+ width: units.gu(100)
29+ height: units.gu(71)
30+ color: "white"
4331
44− indicators {
45− profile: "test1"
46− panelHeight: units.gu(5)
47− }
48− callHint {
49− height: units.gu(4)
50− }
32+ property string indicatorProfile: "phone"
5133
52− property real panelAndSeparatorHeight: panel.indicators.panelHeight + units.dp(2)
53− }
34+ RowLayout {
35+ anchors.fill: parent
36+ anchors.margins: units.gu(1)
37+ clip: true
5438
39+ Rectangle {
40+ Layout.fillWidth: true
41+ Layout.fillHeight: true
5542
56− Row {
57− id: row
58− anchors {
59− bottom: shell.bottom
60− left: parent.left
61− right: parent.right
62− }
63− height: 50
43+ id: itemArea
44+ color: "blue"
6445
65− UC.Button {
66− text: panel.indicators.shown ? "Hide" : "Show"
67− anchors {
68− top: parent.top
69− bottom: parent.bottom
46+ Panel {
47+ id: panel
48+ anchors.fill: parent
49+ indicators {
50+ width: parent.width > units.gu(60) ? units.gu(40) : parent.width
51+ indicatorsModel: root.indicatorsModel
52+ }
53+
54+ property real panelAndSeparatorHeight: panel.indicators.minimizedPanelHeight + units.dp(2)
7055 }
71− width: parent.width/3
56+ }
7257
73− onClicked: {
74− if (panel.indicators.shown) {
75− panel.indicators.hide();
76− } else {
77− panel.indicators.show();
58+ ColumnLayout {
59+ Layout.alignment: Qt.AlignTop
60+ Layout.fillWidth: false
61+
62+ Button {
63+ Layout.fillWidth: true
64+ text: panel.indicators.shown ? "Hide" : "Show"
65+ onClicked: {
66+ if (panel.indicators.shown) {
67+ panel.indicators.hide();
68+ } else {
69+ panel.indicators.show();
70+ }
7871 }
7972 }
80− }
8173
82− UC.Button {
83− text: panel.fullscreenMode ? "Maximize" : "FullScreen"
84− anchors {
85− top: parent.top
86− bottom: parent.bottom
74+ Button {
75+ text: panel.fullscreenMode ? "Maximize" : "FullScreen"
76+ Layout.fillWidth: true
77+ onClicked: panel.fullscreenMode = !panel.fullscreenMode
8778 }
88− width: parent.width/3
8979
90− onClicked: panel.fullscreenMode = !panel.fullscreenMode
91− }
80+ Button {
81+ Layout.fillWidth: true
82+ text: callManager.hasCalls ? "Called" : "No Calls"
83+ onClicked: {
84+ if (callManager.foregroundCall) {
85+ callManager.foregroundCall = null;
86+ } else {
87+ callManager.foregroundCall = phoneCall;
88+ }
89+ }
90+ }
9291
93− UC.Button {
94− text: callManager.hasCalls ? "Called" : "No Calls"
95− anchors {
96− top: parent.top
97− bottom: parent.bottom
92+ Rectangle {
93+ Layout.preferredHeight: units.dp(1);
94+ Layout.fillWidth: true;
95+ color: "black"
9896 }
99− width: parent.width/3
10097
101− onClicked: {
102− if (callManager.foregroundCall) {
103− callManager.foregroundCall = null;
104− } else {
105− callManager.foregroundCall = phoneCall;
98+ Repeater {
99+ model: root.originalModelData
100+ RowLayout {
101+ CheckBox {
102+ checked: true
103+ onCheckedChanged: checked ? insertIndicator(index) : removeIndicator(index);
104+ }
105+ Label {
106+ Layout.fillWidth: true
107+ text: modelData["identifier"]
108+ }
109+
110+ CheckBox {
111+ checked: true
112+ onCheckedChanged: setIndicatorVisible(index, checked);
113+ }
114+ Label {
115+ text: "visible"
116+ }
106117 }
107118 }
108119 }
@@ -118,13 +129,12 @@ Item {
118129 when: windowShown
119130
120131 function init() {
121− panel.indicators.initialise();
122132 panel.fullscreenMode = false;
133+ callManager.foregroundCall = null;
123134
124135 panel.indicators.hide();
125136 // Wait for animation to complete
126137 tryCompare(panel.indicators.hideAnimation, "running", false);
127− callManager.foregroundCall = null;
128138
129139 // Wait for the indicators to get into position.
130140 // (switches between normal and fullscreen modes are animated)
@@ -133,100 +143,21 @@ Item {
133143 }
134144
135145 function get_indicator_item(index) {
136− var indicatorRow = findChild(panel.indicators, "indicatorRow");
137− verify(indicatorRow !== null);
138−
139− return findChild(indicatorRow.row, "item" + index);
140− }
141−
142− function get_indicator_item_position(index) {
143− var indicatorRow = findChild(panel.indicators, "indicatorRow");
144− verify(indicatorRow !== null);
145−
146− var indicatorItem = get_indicator_item(index);
146+ var indicatorItem = findChild(panel, root.originalModelData[index]["identifier"]+"-panelItem");
147147 verify(indicatorItem !== null);
148148
149− return panel.mapFromItem(indicatorItem, indicatorItem.width/2, indicatorItem.height/2);
150− }
151−
152− // Pressing on the indicator panel should activate the indicator hints
153− // and expose a portion of the conent.
154− function test_hint() {
155− var indicatorItemCoord = get_indicator_item_position(0);
156−
157− touchPress(panel, indicatorItemCoord.x, panel.indicators.panelHeight / 2);
158−
159− // hint animation should be run, meaning that indicators will move downwards
160− // by hintValue pixels without any drag taking place
161− tryCompareFunction(function() { return panel.indicators.height },
162− panel.indicators.panelHeight + panel.indicators.hintValue);
163− tryCompare(panel.indicators, "partiallyOpened", true);
164− tryCompare(panel.indicators, "fullyOpened", false);
165−
166− touchRelease(panel, indicatorItemCoord.x, panel.indicators.panelHeight/2);
167− }
168−
169− // Pressing on the top edge of the screen should have no effect if the panel
170− // is hidden (fullscreen), which is the case when a fullscreen app is being shown
171− function test_noHintOnFullscreenMode() {
172− panel.fullscreenMode = true;
173− // Wait for the indicators to get into position.
174− // (switches between normal and fullscreen modes are animated)
175− var indicatorArea = findChild(panel, "indicatorArea");
176− tryCompare(indicatorArea, "y", -panel.panelHeight);
177−
178− var indicatorItemCoord = get_indicator_item_position(0);
179−
180− touchPress(panel, indicatorItemCoord.x, panel.indicators.panelHeight / 2);
181−
182− // Give some time for a hint animation to change things, if any
183− wait(500);
184−
185− // no hint animation when fullscreen
186− compare(panel.indicators.partiallyOpened, false,
187− "Indicator should not be partially opened when panel is pressed in" +
188− " fullscreenmode");
189− compare(panel.indicators.fullyOpened, false, "Indicator should not be partially" +
190− " opened when panel is pressed in fullscreenmode");
191−
192− touchRelease(panel, indicatorItemCoord.x, panel.panelHeight/2);
193− }
194−
195− // Pressing on the top edge of the indicator should have no effect if the panel
196− // has an active call
197− function test_noHintOnActiveCall() {
198− callManager.foregroundCall = phoneCall;
199−
200− var indicatorItemCoord = get_indicator_item_position(0);
201−
202− touchPress(panel, indicatorItemCoord.x, panel.callHint.height + panel.indicators.panelHeight / 2);
203−
204− // Give some time for a hint animation to change things, if any
205− wait(500);
206−
207− // no hint animation when fullscreen
208− compare(panel.indicators.partiallyOpened, false,
209− "Indicator should not be partially opened when panel is pressed in" +
210− " fullscreenmode");
211− compare(panel.indicators.fullyOpened, false, "Indicator should not be partially" +
212− " opened when panel is pressed in fullscreenmode");
213−
214− touchRelease(panel, indicatorItemCoord.x, panel.panelHeight/2);
149+ return indicatorItem;
215150 }
216151
217152 function test_drag_show_data() {
218153 return [
219− { tag: "pinned", fullscreenFlag: false, alreadyOpen: false, call: null,
154+ { tag: "pinned", fullscreen: false, call: null,
220155 indicatorY: 0 },
221− { tag: "fullscreen", fullscreenFlag: true, alreadyOpen: false, call: null,
156+ { tag: "fullscreen", fullscreen: true, call: null,
222157 indicatorY: -panel.panelAndSeparatorHeight },
223− { tag: "pinned-alreadyOpen", fullscreenFlag: false, alreadyOpen: true, call: null,
224− indicatorY: 0 },
225− { tag: "fullscreen-alreadyOpen", fullscreenFlag: true, alreadyOpen: true, call: null,
226− indicatorY: 0 },
227− { tag: "pinned-callActive", fullscreenFlag: false, alreadyOpen: false, call: phoneCall,
158+ { tag: "pinned-callActive", fullscreen: false, call: phoneCall,
228159 indicatorY: 0},
229− { tag: "fullscreen-callActive", fullscreenFlag: true, alreadyOpen: false, call: phoneCall,
160+ { tag: "fullscreen-callActive", fullscreen: true, call: phoneCall,
230161 indicatorY: -panel.panelAndSeparatorHeight }
231162 ];
232163 }
@@ -234,16 +165,12 @@ Item {
234165 // Dragging from a indicator item in the panel will gradually expose the
235166 // indicators, first by running the hint animation, then after dragging down will
236167 // expose more of the panel, binding it to the selected indicator and opening it's menu.
168+ // Tested from first Y pixel to check for swipe from offscreen.
237169 function test_drag_show(data) {
238− panel.fullscreenMode = data.fullscreenFlag;
170+ panel.fullscreenMode = data.fullscreen;
239171 callManager.foregroundCall = data.call;
240172
241− if (data.alreadyOpen) {
242− panel.indicators.show();
243− tryCompare(panel.indicators, "fullyOpened", true);
244− }
245−
246− var indicatorRow = findChild(panel.indicators, "indicatorRow");
173+ var indicatorRow = findChild(panel.indicators, "indicatorItemRow");
247174 verify(indicatorRow !== null);
248175
249176 var menuContent = findChild(panel.indicators, "menuContent");
@@ -256,25 +183,16 @@ Item {
256183 // (switches between normal and fullscreen modes are animated)
257184 tryCompareFunction(function() { return indicatorArea.y }, data.indicatorY);
258185
259− // do this for each indicator item
260− for (var i = 0; i < indicatorRow.row.count; i++) {
261−
186+ for (var i = 0; i < root.originalModelData.length; i++) {
262187 var indicatorItem = get_indicator_item(i);
263− verify(indicatorItem !== null);
264188
265− if (!indicatorItem.visible)
266− continue;
189+ var startXPosition = root.mapFromItem(indicatorItem, indicatorItem.width / 2, 0).x;
190+ var startYPosition = root.mapFromItem(panel, 0, 0).y;
267191
268− var indicatorItemCoord = get_indicator_item_position(i);
269−
270− touchPress(panel,
271− indicatorItemCoord.x, panel.indicators.panelHeight / 2);
272−
273− // 1) Drag the mouse down
274192 touchFlick(panel,
275− indicatorItemCoord.x, panel.indicators.panelHeight / 2,
276− indicatorItemCoord.x, panel.height,
277− false /* beginTouch */, false /* endTouch */);
193+ startXPosition, startYPosition,
194+ startXPosition, panel.height,
195+ true /* beginTouch */, false /* endTouch */, units.gu(5), 15);
278196
279197 // Indicators height should follow the drag, and therefore increase accordingly.
280198 // They should be at least half-way through the screen
@@ -282,56 +200,109 @@ Item {
282200 function() {return panel.indicators.height >= panel.height * 0.5},
283201 true);
284202
285− touchRelease(panel, indicatorItemCoord.x, panel.height);
203+ touchRelease(panel, startXPosition, panel.height);
286204
287− compare(indicatorRow.currentItem, indicatorItem,
288− "Incorrect item activated at position " + i);
289− compare(menuContent.currentMenuIndex, i, "Menu conetent should be enabled for item at position " + i);
205+ compare(indicatorRow.currentItemIndex, i, "Indicator item should be activated at position " + i);
206+ compare(menuContent.currentMenuIndex, i, "Menu conetent should be activated for item at position " + i);
290207
291208 // init for next indicatorItem
292− if (!data.alreadyOpen) {
293− panel.indicators.hide();
294− tryCompare(panel.indicators.hideAnimation, "running", false);
295− tryCompare(panel.indicators, "state", "initial");
296− }
209+ panel.indicators.hide();
210+ tryCompare(panel.indicators.hideAnimation, "running", false);
211+ tryCompare(panel.indicators, "state", "initial");
297212 }
298213 }
299214
300− // Test the vertical velocity check when flicking the indicators open at an angle.
301− // If the vertical velocity is above a specific point, we shouldnt change active indicators
302− // if the x position changes
303− function test_vertical_velocity_detector() {
304− panel.fullscreenMode = false;
215+ function test_drag_hide_data() {
216+ return [
217+ { tag: "pinned", fullscreen: false, call: null,
218+ indicatorY: 0 },
219+ { tag: "fullscreen", fullscreen: true, call: null,
220+ indicatorY: -panel.panelAndSeparatorHeight },
221+ { tag: "pinned-callActive", fullscreen: false, call: phoneCall,
222+ indicatorY: 0},
223+ { tag: "fullscreen-callActive", fullscreen: true, call: phoneCall,
224+ indicatorY: -panel.panelAndSeparatorHeight }
225+ ];
226+ }
227+
228+ // Dragging the shown indicators up from bottom of panel will hide the indicators
229+ // Tested from last Y pixel to check for swipe from offscreen.
230+ function test_drag_hide(data) {
231+ panel.fullscreenMode = data.fullscreen;
232+ callManager.foregroundCall = data.call;
305233
306− var indicatorRow = findChild(panel.indicators, "indicatorRow");
234+ var indicatorRow = findChild(panel.indicators, "indicatorItemRow");
307235 verify(indicatorRow !== null);
308236
309− // Get the first indicator
310− var indicatorItemFirst = get_indicator_item(0);
311− verify(indicatorItemFirst !== null);
237+ var menuContent = findChild(panel.indicators, "menuContent");
238+ verify(menuContent !== null);
312239
313− var indicatorItemCoordFirst = get_indicator_item_position(0);
314− var indicatorItemCoordNext = get_indicator_item_position(indicatorRow.row.count - 1);
240+ var indicatorArea = findChild(panel, "indicatorArea");
241+ verify(indicatorArea !== null);
315242
316− touchPress(panel,
317− indicatorItemCoordFirst.x, panel.indicators.panelHeight / 2);
243+ // Wait for the indicators to get into position.
244+ // (switches between normal and fullscreen modes are animated)
245+ tryCompareFunction(function() { return indicatorArea.y }, data.indicatorY);
246+
247+ var startXPosition = root.mapFromItem(panel.indicators, panel.indicators.width / 2, 0).x;
248+ var startYPosition = root.mapFromItem(panel, 0, panel.height).y;
249+
250+ panel.indicators.show();
251+ tryCompare(panel.indicators.showAnimation, "running", false);
252+ tryCompare(panel.indicators, "unitProgress", 1);
253+
254+
255+ touchFlick(panel.indicators,
256+ startXPosition, startYPosition,
257+ startXPosition, 0,
258+ true /* beginTouch */, false /* endTouch */, units.gu(5), 15);
318259
319− // 1) Drag the mouse down to hint a bit
320− touchFlick(panel,
321− indicatorItemCoordFirst.x, panel.indicators.panelHeight / 2,
322− indicatorItemCoordFirst.x, panel.indicators.panelHeight * 2,
323− false /* beginTouch */, false /* endTouch */);
260+ // Indicators height should follow the drag, and therefore increase accordingly.
261+ // They should be at least half-way through the screen
262+ tryCompareFunction(
263+ function() {return panel.indicators.height <= panel.height * 0.5},
264+ true);
324265
325− tryCompare(indicatorRow, "currentItem", indicatorItemFirst)
266+ touchRelease(panel.indicators, startXPosition, 0);
326267
327− // 1) Flick mouse down to bottom
328− touchFlick(panel,
329− indicatorItemCoordFirst.x, panel.indicators.panelHeight * 2,
330− indicatorItemCoordNext.x, panel.height,
331− false /* beginTouch */, true /* endTouch */,
332− units.gu(10) /* speed */, 30 /* iterations */); // more samples needed for accurate velocity
268+ tryCompare(panel.indicators.hideAnimation, "running", true);
269+ tryCompare(panel.indicators.hideAnimation, "running", false);
270+ tryCompare(panel.indicators, "state", "initial");
271+ }
272+
273+ function test_hint_data() {
274+ return [
275+ { tag: "normal", fullscreen: false, call: null, hintExpected: true},
276+ { tag: "fullscreen", fullscreen: true, call: null, hintExpected: false},
277+ { tag: "call hint", fullscreen: false, call: phoneCall, hintExpected: false},
278+ ];
279+ }
280+
281+ function test_hint(data) {
282+ panel.fullscreenMode = data.fullscreen;
283+ callManager.foregroundCall = data.call;
284+
285+ if (data.fullscreen) {
286+ // Wait for the indicators to get into position.
287+ // (switches between normal and fullscreen modes are animated)
288+ var indicatorArea = findChild(panel, "indicatorArea");
289+ tryCompare(indicatorArea, "y", -panel.panelHeight);
290+ }
291+
292+ var indicatorItem = get_indicator_item(0);
293+ var mappedPosition = root.mapFromItem(indicatorItem, indicatorItem.width / 2, indicatorItem.height / 2);
294+
295+ touchPress(panel, mappedPosition.x, panel.indicators.minimizedPanelHeight / 2);
296+
297+ // Give some time for a hint animation to change things, if any
298+ wait(500);
299+
300+ // no hint animation when fullscreen
301+ compare(panel.indicators.fullyClosed, !data.hintExpected, "Indicator should be fully closed");
302+ compare(panel.indicators.partiallyOpened, data.hintExpected, "Indicator should be partialy opened");
303+ compare(panel.indicators.fullyOpened, false, "Indicator should not be fully opened");
333304
334− compare(indicatorRow.currentItem, indicatorItemFirst, "First indicator should still be the current item");
305+ touchRelease(panel, mappedPosition.x, panel.minimizedPanelHeight / 2);
335306 }
336307 }
337308}