Merge lp:~unity-team/unity8/rtm-expanded-panel-design into lp:unity8/rtm-14.09
- rtm-expanded-panel-design
- Merge into rtm-14.09
Status: | Merged | ||||||||
---|---|---|---|---|---|---|---|---|---|
Approved by: | Michał Sawicz | ||||||||
Approved revision: | 1326 | ||||||||
Merged at revision: | 1358 | ||||||||
Proposed branch: | lp:~unity-team/unity8/rtm-expanded-panel-design | ||||||||
Merge into: | lp:unity8/rtm-14.09 | ||||||||
Prerequisite: | lp:~unity-team/unity8/rtm-sharedunitymenumodel | ||||||||
Diff against target: |
5058 lines (+1883/-2006) 45 files modified
plugins/Unity/Indicators/Indicators.qmltypes (+2/-4) plugins/Unity/Indicators/indicators.h (+0/-2) plugins/Unity/Indicators/indicatorsmodel.cpp (+0/-6) plugins/Unity/Indicators/visibleindicatorsmodel.cpp (+0/-2) qml/Components/DragHandle.qml (+6/-1) qml/Components/ListItems/VerticalThinDivider.qml (+0/-26) qml/Components/ScrollCalculator.qml (+81/-0) qml/Panel/Handle.qml (+43/-0) qml/Panel/IndicatorItem.qml (+0/-53) qml/Panel/IndicatorItemRow.qml (+256/-0) qml/Panel/IndicatorPage.qml (+2/-6) qml/Panel/IndicatorRow.qml (+0/-162) qml/Panel/Indicators.qml (+0/-415) qml/Panel/Indicators/DefaultIndicatorWidget.qml (+0/-119) qml/Panel/Indicators/IndicatorBase.qml (+1/-3) qml/Panel/Indicators/VisibleIndicators.qml (+4/-5) qml/Panel/Indicators/client/IndicatorRepresentation.qml (+22/-11) qml/Panel/Indicators/client/IndicatorsList.qml (+2/-2) qml/Panel/Indicators/client/IndicatorsTree.qml (+5/-27) qml/Panel/IndicatorsBar.qml (+260/-0) qml/Panel/IndicatorsMenu.qml (+285/-0) qml/Panel/MenuContent.qml (+25/-82) qml/Panel/Panel.qml (+0/-191) qml/Panel/PanelVelocityCalculator.qml (+54/-0) qml/Shell.qml (+15/-4) tests/autopilot/unity8/indicators/tests/test_indicators.py (+1/-1) tests/autopilot/unity8/shell/emulators/main_window.py (+6/-6) tests/mocks/Unity/Indicators/Indicators.qmltypes (+2/-4) tests/mocks/Unity/Indicators/IndicatorsModel.qml (+23/-17) tests/mocks/Unity/Indicators/fakeindicatorsmodel.cpp (+0/-2) tests/qmltests/CMakeLists.txt (+5/-5) tests/qmltests/Panel/IndicatorTest.qml (+67/-0) tests/qmltests/Panel/Indicators/tst_DefaultIndicatorWidget.qml (+0/-52) tests/qmltests/Panel/tst_ActiveCallHint.qml (+0/-1) tests/qmltests/Panel/tst_IndicatorItem.qml (+0/-50) tests/qmltests/Panel/tst_IndicatorItemRow.qml (+279/-0) tests/qmltests/Panel/tst_IndicatorPage.qml (+4/-4) tests/qmltests/Panel/tst_IndicatorRow.qml (+0/-158) tests/qmltests/Panel/tst_Indicators.qml (+0/-231) tests/qmltests/Panel/tst_IndicatorsBar.qml (+178/-0) tests/qmltests/Panel/tst_IndicatorsMenu.qml (+247/-0) tests/qmltests/Panel/tst_MenuContent.qml (+6/-14) tests/qmltests/Panel/tst_Panel.qml (+0/-337) tests/qmltests/Panel/tst_SearchIndicator.qml (+0/-1) tests/qmltests/tst_Shell.qml (+2/-2) |
||||||||
To merge this branch: | bzr merge lp:~unity-team/unity8/rtm-expanded-panel-design | ||||||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Michał Sawicz | Approve | ||
Review via email: mp+238244@code.launchpad.net |
Commit message
Implementation of expandable panel design
Description of the change
New Panel design described in:
https:/
* Are there any related MPs required for this MP to build/function as expected? Please list.
No
* Did you perform an exploratory manual test run of your code change and any related functionality?
No
* Did you make sure that your branch does not contain spurious tags?
Yes
* If you changed the packaging (debian), did you subscribe the ubuntu-unity team to this MP?
N/A
* If you changed the UI, has there been a design review?
No
- 1323. By Nick Dedekind
-
sync indicator page delegate loader
- 1324. By Nick Dedekind
-
remove previouslyStopped
- 1325. By Nick Dedekind
-
full screen notifications don't include panel
Ted Gould (ted) wrote : | # |
- 1326. By Nick Dedekind
-
remove/add item fixes
Michał Sawicz (saviq) wrote : | # |
This has been tested extensively for going into rtm.
Preview Diff
1 | === modified file 'plugins/Unity/Indicators/Indicators.qmltypes' |
2 | --- plugins/Unity/Indicators/Indicators.qmltypes 2014-10-15 16:33:45 +0000 |
3 | +++ plugins/Unity/Indicators/Indicators.qmltypes 2014-10-15 16:33:46 +0000 |
4 | @@ -99,10 +99,8 @@ |
5 | values: { |
6 | "Identifier": 0, |
7 | "Position": 1, |
8 | - "WidgetSource": 2, |
9 | - "PageSource": 3, |
10 | - "IndicatorProperties": 4, |
11 | - "IsVisible": 5 |
12 | + "IndicatorProperties": 2, |
13 | + "IsVisible": 3 |
14 | } |
15 | } |
16 | } |
17 | |
18 | === modified file 'plugins/Unity/Indicators/indicators.h' |
19 | --- plugins/Unity/Indicators/indicators.h 2013-09-17 12:31:19 +0000 |
20 | +++ plugins/Unity/Indicators/indicators.h 2014-10-15 16:33:46 +0000 |
21 | @@ -74,8 +74,6 @@ |
22 | enum Roles { |
23 | Identifier = 0, |
24 | Position, |
25 | - WidgetSource, |
26 | - PageSource, |
27 | IndicatorProperties, |
28 | IsVisible |
29 | }; |
30 | |
31 | === modified file 'plugins/Unity/Indicators/indicatorsmodel.cpp' |
32 | --- plugins/Unity/Indicators/indicatorsmodel.cpp 2014-01-30 14:54:01 +0000 |
33 | +++ plugins/Unity/Indicators/indicatorsmodel.cpp 2014-10-15 16:33:46 +0000 |
34 | @@ -202,8 +202,6 @@ |
35 | { |
36 | roles[IndicatorsModelRole::Identifier] = "identifier"; |
37 | roles[IndicatorsModelRole::Position] = "position"; |
38 | - roles[IndicatorsModelRole::WidgetSource] = "widgetSource"; |
39 | - roles[IndicatorsModelRole::PageSource] = "pageSource"; |
40 | roles[IndicatorsModelRole::IndicatorProperties] = "indicatorProperties"; |
41 | } |
42 | return roles; |
43 | @@ -248,10 +246,6 @@ |
44 | return QVariant(indicator->indicatorProperties()); |
45 | } |
46 | break; |
47 | - case IndicatorsModelRole::WidgetSource: |
48 | - return qmlDirectory()+"/Panel/Indicators/DefaultIndicatorWidget.qml"; |
49 | - case IndicatorsModelRole::PageSource: |
50 | - return qmlDirectory()+"/Panel/Indicators/DefaultIndicatorPage.qml"; |
51 | default: |
52 | break; |
53 | } |
54 | |
55 | === modified file 'plugins/Unity/Indicators/visibleindicatorsmodel.cpp' |
56 | --- plugins/Unity/Indicators/visibleindicatorsmodel.cpp 2013-09-17 12:31:19 +0000 |
57 | +++ plugins/Unity/Indicators/visibleindicatorsmodel.cpp 2014-10-15 16:33:46 +0000 |
58 | @@ -33,8 +33,6 @@ |
59 | { |
60 | roles[IndicatorsModelRole::Identifier] = "identifier"; |
61 | roles[IndicatorsModelRole::Position] = "position"; |
62 | - roles[IndicatorsModelRole::WidgetSource] = "widgetSource"; |
63 | - roles[IndicatorsModelRole::PageSource] = "pageSource"; |
64 | roles[IndicatorsModelRole::IndicatorProperties] = "indicatorProperties"; |
65 | roles[IndicatorsModelRole::IsVisible] = "isVisible"; |
66 | } |
67 | |
68 | === modified file 'qml/Components/DragHandle.qml' |
69 | --- qml/Components/DragHandle.qml 2014-02-12 18:51:36 +0000 |
70 | +++ qml/Components/DragHandle.qml 2014-10-15 16:33:46 +0000 |
71 | @@ -68,6 +68,7 @@ |
72 | } |
73 | |
74 | property real hintDisplacement: 0 |
75 | + property var overrideStartValue: undefined |
76 | SmoothedAnimation { |
77 | id: hintingAnimation |
78 | target: hintingAnimation |
79 | @@ -196,7 +197,11 @@ |
80 | } else /* Undecided || Recognized */ { |
81 | if (d.previousStatus === DirectionalDragArea.WaitingForTouch) { |
82 | dragEvaluator.reset(); |
83 | - d.startValue = parent[d.targetProp]; |
84 | + if (overrideStartValue !== undefined) { |
85 | + d.startValue = overrideStartValue; |
86 | + } else { |
87 | + d.startValue = parent[d.targetProp]; |
88 | + } |
89 | |
90 | if (hintDisplacement > 0) { |
91 | hintingAnimation.targetValue = d.startValue; |
92 | |
93 | === removed file 'qml/Components/ListItems/VerticalThinDivider.qml' |
94 | --- qml/Components/ListItems/VerticalThinDivider.qml 2013-06-05 22:03:08 +0000 |
95 | +++ qml/Components/ListItems/VerticalThinDivider.qml 1970-01-01 00:00:00 +0000 |
96 | @@ -1,26 +0,0 @@ |
97 | -/* |
98 | - * Copyright (C) 2012 Canonical, Ltd. |
99 | - * |
100 | - * This program is free software; you can redistribute it and/or modify |
101 | - * it under the terms of the GNU General Public License as published by |
102 | - * the Free Software Foundation; version 3. |
103 | - * |
104 | - * This program is distributed in the hope that it will be useful, |
105 | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
106 | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
107 | - * GNU General Public License for more details. |
108 | - * |
109 | - * You should have received a copy of the GNU General Public License |
110 | - * along with this program. If not, see <http://www.gnu.org/licenses/>. |
111 | - */ |
112 | - |
113 | -import QtQuick 2.0 |
114 | - |
115 | -Image { |
116 | - anchors { |
117 | - top: (parent) ? parent.top : null |
118 | - bottom: (parent) ? parent.bottom : null |
119 | - } |
120 | - width: (visible) ? units.dp(2) : 0 |
121 | - source: "graphics/ListItemDividerVertical.png" |
122 | -} |
123 | |
124 | === removed file 'qml/Components/ListItems/graphics/ListItemDividerVertical@18.png' |
125 | Binary files qml/Components/ListItems/graphics/ListItemDividerVertical@18.png 2013-06-05 22:03:08 +0000 and qml/Components/ListItems/graphics/ListItemDividerVertical@18.png 1970-01-01 00:00:00 +0000 differ |
126 | === added file 'qml/Components/ScrollCalculator.qml' |
127 | --- qml/Components/ScrollCalculator.qml 1970-01-01 00:00:00 +0000 |
128 | +++ qml/Components/ScrollCalculator.qml 2014-10-15 16:33:46 +0000 |
129 | @@ -0,0 +1,81 @@ |
130 | +/* |
131 | + * Copyright (C) 2014 Canonical, Ltd. |
132 | + * |
133 | + * This program is free software; you can redistribute it and/or modify |
134 | + * it under the terms of the GNU General Public License as published by |
135 | + * the Free Software Foundation; version 3. |
136 | + * |
137 | + * This program is distributed in the hope that it will be useful, |
138 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
139 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
140 | + * GNU General Public License for more details. |
141 | + * |
142 | + * You should have received a copy of the GNU General Public License |
143 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
144 | + */ |
145 | + |
146 | +import QtQuick 2.2 |
147 | +import Ubuntu.Components 1.1 |
148 | + |
149 | +Item { |
150 | + id: scrollArea |
151 | + |
152 | + readonly property bool areaActive: lateralPosition >= 0 |
153 | + property real stopScrollThreshold: units.gu(2) |
154 | + property int direction: Qt.LeftToRight |
155 | + property real baseScrollAmount: units.dp(3) |
156 | + property real maximumScrollAmount: units.dp(8) |
157 | + property real lateralPosition: -1 |
158 | + property real forceScrollingPercentage: 0.4 |
159 | + |
160 | + signal scroll(real scrollAmount) |
161 | + |
162 | + width: units.gu(5) |
163 | + rotation: direction === Qt.LeftToRight ? 0 : 180 |
164 | + |
165 | + onAreaActiveChanged: areaActive ? handleEnter() : handleExit() |
166 | + |
167 | + function handleEnter() { |
168 | + d.thresholdAreaX = -scrollArea.stopScrollThreshold; |
169 | + scrollTimer.restart(); |
170 | + } |
171 | + |
172 | + function handleExit() { |
173 | + d.thresholdAreaX = -scrollArea.stopScrollThreshold; |
174 | + scrollTimer.stop(); |
175 | + } |
176 | + |
177 | + onLateralPositionChanged: { |
178 | + if (scrollArea.areaActive) { |
179 | + if (lateralPosition > width * (1 - forceScrollingPercentage)) { |
180 | + d.thresholdAreaX = width * (1 - forceScrollingPercentage); |
181 | + if (!scrollTimer.running) scrollTimer.restart(); |
182 | + } else if (lateralPosition > d.thresholdAreaX + scrollArea.stopScrollThreshold) { |
183 | + d.thresholdAreaX = lateralPosition - scrollArea.stopScrollThreshold; |
184 | + if (!scrollTimer.running) scrollTimer.restart(); |
185 | + } else if (lateralPosition < d.thresholdAreaX) { |
186 | + d.thresholdAreaX = lateralPosition; |
187 | + scrollTimer.stop(); |
188 | + } |
189 | + |
190 | + d.progression = lateralPosition / width; |
191 | + } |
192 | + } |
193 | + |
194 | + Timer { |
195 | + id: scrollTimer |
196 | + interval: 16 |
197 | + repeat: true |
198 | + |
199 | + onTriggered: { |
200 | + var scrollAmount = scrollArea.baseScrollAmount + scrollArea.maximumScrollAmount * d.progression; |
201 | + scrollArea.scroll(scrollAmount); |
202 | + } |
203 | + } |
204 | + |
205 | + QtObject { |
206 | + id: d |
207 | + property real progression: 0 |
208 | + property real thresholdAreaX: -scrollArea.stopScrollThreshold |
209 | + } |
210 | +} |
211 | |
212 | === added file 'qml/Panel/Handle.qml' |
213 | --- qml/Panel/Handle.qml 1970-01-01 00:00:00 +0000 |
214 | +++ qml/Panel/Handle.qml 2014-10-15 16:33:46 +0000 |
215 | @@ -0,0 +1,43 @@ |
216 | +/* |
217 | + * Copyright (C) 2014 Canonical, Ltd. |
218 | + * |
219 | + * This program is free software; you can redistribute it and/or modify |
220 | + * it under the terms of the GNU General Public License as published by |
221 | + * the Free Software Foundation; version 3. |
222 | + * |
223 | + * This program is distributed in the hope that it will be useful, |
224 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
225 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
226 | + * GNU General Public License for more details. |
227 | + * |
228 | + * You should have received a copy of the GNU General Public License |
229 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
230 | + */ |
231 | + |
232 | +import QtQuick 2.2 |
233 | +import Ubuntu.Components 1.1 |
234 | + |
235 | +Rectangle { |
236 | + id: handle |
237 | + color: "#333333" |
238 | + height: units.gu(2) |
239 | + property bool active: false |
240 | + |
241 | + Row { |
242 | + id: dots |
243 | + width: childrenRect.width |
244 | + height: childrenRect.height |
245 | + anchors.centerIn: parent |
246 | + spacing: units.gu(0.5) |
247 | + Repeater { |
248 | + model: 3 |
249 | + delegate: Rectangle { |
250 | + id: dot |
251 | + width: units.dp(3) |
252 | + height: width |
253 | + color: handle.active ? "#de4814" : "#717171" |
254 | + radius: units.dp(1) |
255 | + } |
256 | + } |
257 | + } |
258 | +} |
259 | |
260 | === removed file 'qml/Panel/IndicatorItem.qml' |
261 | --- qml/Panel/IndicatorItem.qml 2014-09-29 10:24:58 +0000 |
262 | +++ qml/Panel/IndicatorItem.qml 1970-01-01 00:00:00 +0000 |
263 | @@ -1,53 +0,0 @@ |
264 | -/* |
265 | - * Copyright (C) 2013 Canonical, Ltd. |
266 | - * |
267 | - * This program is free software; you can redistribute it and/or modify |
268 | - * it under the terms of the GNU General Public License as published by |
269 | - * the Free Software Foundation; version 3. |
270 | - * |
271 | - * This program is distributed in the hope that it will be useful, |
272 | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
273 | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
274 | - * GNU General Public License for more details. |
275 | - * |
276 | - * You should have received a copy of the GNU General Public License |
277 | - * along with this program. If not, see <http://www.gnu.org/licenses/>. |
278 | - */ |
279 | - |
280 | -import QtQuick 2.0 |
281 | -import Ubuntu.Components 0.1 |
282 | -import Unity.Indicators 0.1 as Indicators |
283 | -import "../Components" |
284 | - |
285 | -Loader { |
286 | - id: root |
287 | - |
288 | - property alias widgetSource: root.source |
289 | - property bool dimmed: false |
290 | - property var indicatorProperties: undefined |
291 | - property bool indicatorVisible: item ? item.enabled : false |
292 | - property string identifier |
293 | - |
294 | - opacity: dimmed ? 0.4 : 1 |
295 | - Behavior on opacity { UbuntuNumberAnimation { duration: UbuntuAnimation.BriskDuration } } |
296 | - |
297 | - onLoaded: { |
298 | - for(var pName in indicatorProperties) { |
299 | - if (item.hasOwnProperty(pName)) { |
300 | - item[pName] = indicatorProperties[pName]; |
301 | - } |
302 | - } |
303 | - } |
304 | - |
305 | - Binding { |
306 | - target: item |
307 | - property: "identifier" |
308 | - value: identifier |
309 | - } |
310 | - |
311 | - Binding { |
312 | - target: item |
313 | - property: "objectName" |
314 | - value: identifier + "-widget" |
315 | - } |
316 | -} |
317 | |
318 | === added file 'qml/Panel/IndicatorItemRow.qml' |
319 | --- qml/Panel/IndicatorItemRow.qml 1970-01-01 00:00:00 +0000 |
320 | +++ qml/Panel/IndicatorItemRow.qml 2014-10-15 16:33:46 +0000 |
321 | @@ -0,0 +1,256 @@ |
322 | +/* |
323 | + * Copyright (C) 2013-2014 Canonical, Ltd. |
324 | + * |
325 | + * This program is free software; you can redistribute it and/or modify |
326 | + * it under the terms of the GNU General Public License as published by |
327 | + * the Free Software Foundation; version 3. |
328 | + * |
329 | + * This program is distributed in the hope that it will be useful, |
330 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
331 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
332 | + * GNU General Public License for more details. |
333 | + * |
334 | + * You should have received a copy of the GNU General Public License |
335 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
336 | + */ |
337 | + |
338 | +import QtQuick 2.2 |
339 | +import Ubuntu.Components 1.1 |
340 | + |
341 | +Item { |
342 | + id: root |
343 | + width: row.width |
344 | + height: units.gu(3) |
345 | + |
346 | + property QtObject indicatorsModel: null |
347 | + property real overFlowWidth: width |
348 | + property bool expanded: false |
349 | + property var currentItem |
350 | + readonly property int currentItemIndex: currentItem ? currentItem.ownIndex : -1 |
351 | + |
352 | + property real unitProgress: 0.0 |
353 | + property real selectionChangeBuffer: units.gu(2) |
354 | + property bool enableLateralChanges: false |
355 | + property color hightlightColor: "#ededed" |
356 | + |
357 | + property real lateralPosition: -1 |
358 | + onLateralPositionChanged: { |
359 | + updateItemFromLateralPosition(); |
360 | + } |
361 | + |
362 | + onEnableLateralChangesChanged: { |
363 | + updateItemFromLateralPosition(); |
364 | + } |
365 | + |
366 | + function updateItemFromLateralPosition() { |
367 | + if (currentItem && !enableLateralChanges) return; |
368 | + if (lateralPosition === -1) return; |
369 | + |
370 | + if (!currentItem) { |
371 | + selectItemAt(lateralPosition); |
372 | + return; |
373 | + } |
374 | + |
375 | + var maximumBufferOffset = selectionChangeBuffer * unitProgress; |
376 | + var proposedItem = indicatorAt(lateralPosition, 0); |
377 | + if (proposedItem) { |
378 | + var bufferExceeded = false; |
379 | + |
380 | + if (proposedItem !== currentItem) { |
381 | + // Proposed item is not directly adjacent to current? |
382 | + if (Math.abs(proposedItem.ownIndex - currentItem.ownIndex) > 1) { |
383 | + bufferExceeded = true; |
384 | + } else { // no |
385 | + var currentItemLateralPosition = root.mapToItem(proposedItem, lateralPosition, 0).x; |
386 | + |
387 | + // Is the distance into proposed item greater than max buffer? |
388 | + // Proposed item is before current item |
389 | + if (proposedItem.x < currentItem.x) { |
390 | + bufferExceeded = (proposedItem.width - currentItemLateralPosition) > maximumBufferOffset; |
391 | + } else { // After |
392 | + bufferExceeded = currentItemLateralPosition > maximumBufferOffset; |
393 | + } |
394 | + } |
395 | + if (bufferExceeded) { |
396 | + selectItemAt(lateralPosition); |
397 | + } |
398 | + } |
399 | + } else { |
400 | + selectItemAt(lateralPosition); |
401 | + } |
402 | + } |
403 | + |
404 | + function indicatorAt(x, y) { |
405 | + var item = row.childAt(x, y); |
406 | + return item && item.hasOwnProperty("ownIndex") ? item : null; |
407 | + } |
408 | + |
409 | + function resetCurrentItem() { |
410 | + d.firstItemSwitch = true; |
411 | + d.previousItem = undefined; |
412 | + currentItem = undefined; |
413 | + } |
414 | + |
415 | + function setCurrentItemIndex(index) { |
416 | + for (var i = 0; i < row.children.length; i++) { |
417 | + var item = row.children[i]; |
418 | + if (item.hasOwnProperty("ownIndex") && item.ownIndex === index) { |
419 | + if (currentItem !== item) currentItem = item; |
420 | + break; |
421 | + } |
422 | + } |
423 | + } |
424 | + |
425 | + function selectItemAt(lateralPosition) { |
426 | + var item = indicatorAt(lateralPosition, 0); |
427 | + if (item && item.opacity > 0) { |
428 | + currentItem = item; |
429 | + } else { |
430 | + // Select default item. |
431 | + var searchIndex = lateralPosition > width ? repeater.count - 1 : 0; |
432 | + |
433 | + for (var i = 0; i < row.children.length; i++) { |
434 | + if (row.children[i].hasOwnProperty("ownIndex") && row.children[i].ownIndex === searchIndex) { |
435 | + item = row.children[i]; |
436 | + break; |
437 | + } |
438 | + } |
439 | + if (currentItem !== item) currentItem = item; |
440 | + } |
441 | + } |
442 | + |
443 | + QtObject { |
444 | + id: d |
445 | + property bool firstItemSwitch: true |
446 | + property var previousItem |
447 | + } |
448 | + |
449 | + onCurrentItemChanged: { |
450 | + if (d.previousItem) { |
451 | + d.firstItemSwitch = false; |
452 | + } |
453 | + d.previousItem = currentItem; |
454 | + } |
455 | + |
456 | + Row { |
457 | + id: row |
458 | + anchors { |
459 | + top: parent.top |
460 | + bottom: parent.bottom |
461 | + } |
462 | + |
463 | + Repeater { |
464 | + id: repeater |
465 | + model: indicatorsModel |
466 | + visible: false |
467 | + |
468 | + onItemRemoved: { |
469 | + // current item removed. |
470 | + if (currentItem === item) { |
471 | + var i = 0; |
472 | + while (i < row.children.length) { |
473 | + var childItem = row.children[i]; |
474 | + if (childItem !== item) { |
475 | + setCurrentItemIndex(i); |
476 | + break; |
477 | + } |
478 | + i++; |
479 | + } |
480 | + } |
481 | + } |
482 | + |
483 | + delegate: IndicatorItem { |
484 | + id: item |
485 | + objectName: identifier+"-panelItem" |
486 | + |
487 | + property int ownIndex: index |
488 | + property bool overflow: row.width - x > overFlowWidth |
489 | + property bool hidden: !item.expanded && overflow |
490 | + |
491 | + height: row.height |
492 | + expanded: root.expanded |
493 | + selected: currentItem === this |
494 | + |
495 | + identifier: model.identifier |
496 | + busName: indicatorProperties.busName |
497 | + actionsObjectPath: indicatorProperties.actionsObjectPath |
498 | + menuObjectPath: indicatorProperties.menuObjectPath |
499 | + |
500 | + opacity: hidden ? 0.0 : 1.0 |
501 | + Behavior on opacity { NumberAnimation { duration: UbuntuAnimation.SnapDuration } } |
502 | + } |
503 | + } |
504 | + } |
505 | + |
506 | + Rectangle { |
507 | + id: highlight |
508 | + objectName: "highlight" |
509 | + |
510 | + anchors.bottom: row.bottom |
511 | + height: units.dp(2) |
512 | + color: root.hightlightColor |
513 | + visible: currentItem !== undefined |
514 | + opacity: 0.0 |
515 | + |
516 | + width: currentItem ? currentItem.width : 0 |
517 | + Behavior on width { |
518 | + enabled: !d.firstItemSwitch && expanded |
519 | + UbuntuNumberAnimation { duration: UbuntuAnimation.FastDuration; easing: UbuntuAnimation.StandardEasing } |
520 | + } |
521 | + |
522 | + // micromovements of the highlight line when user moves the finger across the items while pulling |
523 | + // the handle downwards. |
524 | + property real highlightCenterOffset: { |
525 | + if (!currentItem || lateralPosition == -1 || !enableLateralChanges) return 0; |
526 | + |
527 | + var itemMapped = root.mapToItem(currentItem, lateralPosition, 0); |
528 | + |
529 | + var distanceFromCenter = itemMapped.x - currentItem.width / 2; |
530 | + if (distanceFromCenter > 0) { |
531 | + distanceFromCenter = Math.max(0, distanceFromCenter - currentItem.width / 8); |
532 | + } else { |
533 | + distanceFromCenter = Math.min(0, distanceFromCenter + currentItem.width / 8); |
534 | + } |
535 | + |
536 | + if (currentItem && currentItem.ownIndex === 0 && distanceFromCenter < 0) { |
537 | + return 0; |
538 | + } else if (currentItem && currentItem.ownIndex === repeater.count-1 & distanceFromCenter > 0) { |
539 | + return 0; |
540 | + } |
541 | + return (distanceFromCenter / (currentItem.width / 4)) * units.gu(1); |
542 | + } |
543 | + Behavior on highlightCenterOffset { |
544 | + NumberAnimation { duration: UbuntuAnimation.FastDuration; easing: UbuntuAnimation.StandardEasing } |
545 | + } |
546 | + |
547 | + property real currentItemX: currentItem ? currentItem.x : 0 |
548 | + Behavior on currentItemX { |
549 | + id: currentItemXBehavior |
550 | + enabled: !d.firstItemSwitch && expanded |
551 | + NumberAnimation { duration: UbuntuAnimation.FastDuration; easing: UbuntuAnimation.StandardEasing } |
552 | + } |
553 | + x: currentItemX + highlightCenterOffset |
554 | + } |
555 | + |
556 | + states: [ |
557 | + State { |
558 | + name: "minimised" |
559 | + when: !expanded |
560 | + }, |
561 | + State { |
562 | + name: "expanded" |
563 | + when: expanded |
564 | + PropertyChanges { target: highlight; opacity: 0.9 } |
565 | + } |
566 | + ] |
567 | + |
568 | + transitions: [ |
569 | + Transition { |
570 | + PropertyAnimation { |
571 | + properties: "opacity"; |
572 | + duration: UbuntuAnimation.SnapDuration |
573 | + easing: UbuntuAnimation.StandardEasing |
574 | + } |
575 | + } |
576 | + ] |
577 | +} |
578 | |
579 | === renamed file 'qml/Panel/Indicators/DefaultIndicatorPage.qml' => 'qml/Panel/IndicatorPage.qml' |
580 | --- qml/Panel/Indicators/DefaultIndicatorPage.qml 2014-09-29 10:24:58 +0000 |
581 | +++ qml/Panel/IndicatorPage.qml 2014-10-15 16:33:46 +0000 |
582 | @@ -1,5 +1,5 @@ |
583 | /* |
584 | - * Copyright 2013 Canonical Ltd. |
585 | + * Copyright 2013-2014 Canonical Ltd. |
586 | * |
587 | * This program is free software; you can redistribute it and/or modify |
588 | * it under the terms of the GNU Lesser General Public License as published by |
589 | @@ -12,15 +12,12 @@ |
590 | * |
591 | * You should have received a copy of the GNU Lesser General Public License |
592 | * along with this program. If not, see <http://www.gnu.org/licenses/>. |
593 | - * |
594 | - * Authors: |
595 | - * Renato Araujo Oliveira Filho <renato@canonical.com> |
596 | - * Nick Dedekind <nick.dedekind@canonical.com> |
597 | */ |
598 | |
599 | import QtQuick 2.0 |
600 | import Ubuntu.Components 0.1 as Components |
601 | import Unity.Indicators 0.1 as Indicators |
602 | +import "Indicators" |
603 | |
604 | IndicatorBase { |
605 | id: main |
606 | @@ -125,7 +122,6 @@ |
607 | delegate: Loader { |
608 | id: loader |
609 | objectName: "menuItem" + index |
610 | - asynchronous: true |
611 | width: ListView.view.width |
612 | visible: status == Loader.Ready |
613 | |
614 | |
615 | === removed file 'qml/Panel/IndicatorRow.qml' |
616 | --- qml/Panel/IndicatorRow.qml 2014-05-07 13:59:58 +0000 |
617 | +++ qml/Panel/IndicatorRow.qml 1970-01-01 00:00:00 +0000 |
618 | @@ -1,162 +0,0 @@ |
619 | -/* |
620 | - * Copyright (C) 2013 Canonical, Ltd. |
621 | - * |
622 | - * This program is free software; you can redistribute it and/or modify |
623 | - * it under the terms of the GNU General Public License as published by |
624 | - * the Free Software Foundation; version 3. |
625 | - * |
626 | - * This program is distributed in the hope that it will be useful, |
627 | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
628 | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
629 | - * GNU General Public License for more details. |
630 | - * |
631 | - * You should have received a copy of the GNU General Public License |
632 | - * along with this program. If not, see <http://www.gnu.org/licenses/>. |
633 | - */ |
634 | - |
635 | -import QtQuick 2.0 |
636 | -import Ubuntu.Components 0.1 |
637 | -import Unity.Indicators 0.1 as Indicators |
638 | -import "../Components" |
639 | - |
640 | -Item { |
641 | - id: indicatorRow |
642 | - |
643 | - readonly property alias currentItem : itemView.currentItem |
644 | - readonly property alias currentItemIndex: itemView.currentIndex |
645 | - readonly property alias row: itemView |
646 | - property QtObject indicatorsModel: null |
647 | - property int overFlowWidth: width |
648 | - property bool showAll: false |
649 | - property real currentItemOffset: 0.0 |
650 | - property real unitProgress: 0.0 |
651 | - |
652 | - width: units.gu(40) |
653 | - height: units.gu(3) |
654 | - |
655 | - function setDefaultItem() { |
656 | - // The leftmost indicator |
657 | - setCurrentItemIndex(0); |
658 | - } |
659 | - |
660 | - function setCurrentItemIndex(index) { |
661 | - itemView.currentIndex = index; |
662 | - } |
663 | - |
664 | - function setCurrentItem(item) { |
665 | - if (item && item.hasOwnProperty("ownIndex")) { |
666 | - itemView.currentIndex = item.ownIndex; |
667 | - } else { |
668 | - itemView.currentIndex = -1; |
669 | - } |
670 | - } |
671 | - |
672 | - Timer { |
673 | - id: allVisible |
674 | - interval: 1000 |
675 | - |
676 | - onTriggered: { |
677 | - showAll = false; |
678 | - } |
679 | - } |
680 | - |
681 | - ListView { |
682 | - id: itemView |
683 | - objectName: "indicatorRowItems" |
684 | - interactive: false |
685 | - model: indicatorsModel ? indicatorsModel : null |
686 | - |
687 | - width: childrenRect.width |
688 | - height: indicatorRow.height |
689 | - anchors.right: parent.right |
690 | - orientation: ListView.Horizontal |
691 | - |
692 | - property int lastCount: 0 |
693 | - onCountChanged: { |
694 | - if (lastCount < count) { |
695 | - showAll = true; |
696 | - allVisible.start(); |
697 | - } |
698 | - lastCount = count; |
699 | - } |
700 | - |
701 | - delegate: Item { |
702 | - id: itemWrapper |
703 | - objectName: "item" + index |
704 | - height: indicatorRow.height |
705 | - width: indicatorItem.width |
706 | - opacity: 1 - indicatorRow.unitProgress |
707 | - y: 0 |
708 | - state: "standard" |
709 | - |
710 | - property int ownIndex: index |
711 | - property bool highlighted: indicatorRow.unitProgress > 0 ? ListView.isCurrentItem : false |
712 | - property bool dimmed: indicatorRow.unitProgress > 0 ? !ListView.isCurrentItem : false |
713 | - |
714 | - property bool hidden: !showAll && !highlighted && (indicatorRow.state == "locked" || indicatorRow.state == "commit") |
715 | - property bool overflow: row.width - itemWrapper.x > overFlowWidth |
716 | - |
717 | - IndicatorItem { |
718 | - id: indicatorItem |
719 | - identifier: model.identifier |
720 | - height: parent.height |
721 | - |
722 | - dimmed: itemWrapper.dimmed |
723 | - |
724 | - widgetSource: model.widgetSource |
725 | - indicatorProperties : model.indicatorProperties |
726 | - } |
727 | - |
728 | - states: [ |
729 | - State { |
730 | - name: "standard" |
731 | - when: !hidden && !overflow && !highlighted |
732 | - }, |
733 | - State { |
734 | - name: "highlighted" |
735 | - when: highlighted |
736 | - PropertyChanges { target: itemWrapper; opacity: 1.0 } |
737 | - }, |
738 | - State { |
739 | - name: "hidden" |
740 | - when: hidden || overflow |
741 | - PropertyChanges { target: itemWrapper; opacity: 0.0 } |
742 | - } |
743 | - ] |
744 | - |
745 | - Behavior on opacity { UbuntuNumberAnimation { duration: UbuntuAnimation.BriskDuration } } |
746 | - } |
747 | - } |
748 | - |
749 | - |
750 | - Rectangle { |
751 | - id: highlight |
752 | - color: Theme.palette.selected.foreground |
753 | - objectName: "highlight" |
754 | - height: units.dp(2) |
755 | - anchors.top: row.bottom |
756 | - visible: indicatorRow.currentItem != null |
757 | - |
758 | - property real intendedX: row.x + (indicatorRow.currentItem != null ? (indicatorRow.currentItem.x - row.originX) + centerOffset : 0) |
759 | - x: intendedX >= row.x ? (intendedX + width <= row.x + row.width ? intendedX : row.x + row.width - width) : row.x // listview boundaries |
760 | - width: indicatorRow.currentItem != null ? indicatorRow.currentItem.width : 0 |
761 | - |
762 | - property real centerOffset: { |
763 | - if (indicatorRow.currentItemOffset > 0.1) { |
764 | - return (indicatorRow.currentItemOffset - 0.1) * units.gu(0.4); |
765 | - } else if (indicatorRow.currentItemOffset < -0.1) { |
766 | - return (indicatorRow.currentItemOffset + 0.1) * units.gu(0.4); |
767 | - } |
768 | - return 0.0; |
769 | - } |
770 | - |
771 | - Behavior on width { |
772 | - enabled: unitProgress > 0; |
773 | - UbuntuNumberAnimation { duration: UbuntuAnimation.FastDuration } |
774 | - } |
775 | - Behavior on x { |
776 | - enabled: unitProgress > 0; |
777 | - UbuntuNumberAnimation { duration: UbuntuAnimation.FastDuration } |
778 | - } |
779 | - } |
780 | -} |
781 | |
782 | === removed file 'qml/Panel/Indicators.qml' |
783 | --- qml/Panel/Indicators.qml 2014-09-09 13:40:41 +0000 |
784 | +++ qml/Panel/Indicators.qml 1970-01-01 00:00:00 +0000 |
785 | @@ -1,415 +0,0 @@ |
786 | -/* |
787 | - * Copyright (C) 2013 Canonical, Ltd. |
788 | - * |
789 | - * This program is free software; you can redistribute it and/or modify |
790 | - * it under the terms of the GNU General Public License as published by |
791 | - * the Free Software Foundation; version 3. |
792 | - * |
793 | - * This program is distributed in the hope that it will be useful, |
794 | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
795 | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
796 | - * GNU General Public License for more details. |
797 | - * |
798 | - * You should have received a copy of the GNU General Public License |
799 | - * along with this program. If not, see <http://www.gnu.org/licenses/>. |
800 | - */ |
801 | - |
802 | -import QtQuick 2.0 |
803 | -import Ubuntu.Components 0.1 |
804 | -import Ubuntu.Gestures 0.1 |
805 | -import Unity.Indicators 0.1 as Indicators |
806 | - |
807 | -import "../Components" |
808 | -import "../Components/ListItems" |
809 | -import "Indicators" |
810 | - |
811 | -Showable { |
812 | - id: indicators |
813 | - |
814 | - property real openedHeight: units.gu(71) |
815 | - property int panelHeight: units.gu(3) |
816 | - property alias overFlowWidth: indicatorRow.overFlowWidth |
817 | - property alias showAll: indicatorRow.showAll |
818 | - // TODO: This should be sourced by device type (eg "desktop", "tablet", "phone"...) |
819 | - property string profile: indicatorProfile |
820 | - |
821 | - readonly property real hintValue: panelHeight + menuContent.headerHeight |
822 | - readonly property int lockThreshold: openedHeight / 2 |
823 | - property bool fullyOpened: height == openedHeight |
824 | - property bool partiallyOpened: height > panelHeight && !fullyOpened |
825 | - property bool fullyClosed: height <= panelHeight |
826 | - property bool contentEnabled: true |
827 | - property bool initalizeItem: true |
828 | - readonly property alias content: menuContent |
829 | - property real unitProgress: (height - panelHeight) / (openedHeight - panelHeight) |
830 | - property bool enableHint: true |
831 | - property real showHintBottomMargin: 0 |
832 | - |
833 | - signal showTapped(point position) |
834 | - |
835 | - // TODO: Perhaps we need a animation standard for showing/hiding? Each showable seems to |
836 | - // use its own values. Need to ask design about this. |
837 | - showAnimation: StandardAnimation { |
838 | - property: "height" |
839 | - to: openedHeight |
840 | - } |
841 | - |
842 | - hideAnimation: StandardAnimation { |
843 | - property: "height" |
844 | - duration: 350 |
845 | - to: panelHeight |
846 | - easing.type: Easing.OutCubic |
847 | - } |
848 | - |
849 | - onOpenedHeightChanged: { |
850 | - if (showAnimation.running) { |
851 | - showAnimation.restart(); |
852 | - } else if (indicators.shown) { |
853 | - height = openedHeight; |
854 | - } |
855 | - } |
856 | - |
857 | - height: panelHeight |
858 | - onHeightChanged: updateRevealProgressState(indicators.height - panelHeight - showHintBottomMargin, true) |
859 | - |
860 | - function updateRevealProgressState(revealProgress, enableRelease) { |
861 | - if (!showAnimation.running && !hideAnimation.running) { |
862 | - if (revealProgress === 0) { |
863 | - indicators.state = "initial"; |
864 | - } else if (enableHint && revealProgress > 0 && revealProgress <= hintValue) { |
865 | - indicators.state = "hint"; |
866 | - } else if ((!enableHint || revealProgress > hintValue) && revealProgress < lockThreshold) { |
867 | - indicators.state = "reveal"; |
868 | - } else if (revealProgress >= lockThreshold && lockThreshold > 0) { |
869 | - indicators.state = "locked"; |
870 | - } |
871 | - } |
872 | - } |
873 | - |
874 | - function calculateCurrentItem(xValue, useBuffer) { |
875 | - var rowCoordinates; |
876 | - var itemCoordinates; |
877 | - var currentItem; |
878 | - var distanceFromRightEdge; |
879 | - var bufferExceeded = false; |
880 | - |
881 | - if (indicators.state == "commit" || indicators.state == "locked" || showAnimation.running || hideAnimation.running) return; |
882 | - |
883 | - /* |
884 | - If user drags the indicator handle bar down a distance hintValue or less, this is 0. |
885 | - If bar is dragged down a distance greater than or equal to lockThreshold, this is 1. |
886 | - Otherwise it contains the bar's location as a fraction of the distance between hintValue (is 0) and lockThreshold (is 1). |
887 | - */ |
888 | - var verticalProgress = |
889 | - MathUtils.clamp((indicators.height - handle.height - hintValue) / |
890 | - (lockThreshold - hintValue), 0, 1); |
891 | - |
892 | - /* |
893 | - Vertical velocity check. Don't change the indicator if we're moving too quickly. |
894 | - */ |
895 | - var verticalSpeed = Math.abs(yVelocityCalculator.calculate()); |
896 | - if (verticalSpeed >= 0.05 && !initalizeItem) { |
897 | - return; |
898 | - } |
899 | - |
900 | - /* |
901 | - Percentage of an indicator icon's width the user's press can stray horizontally from the |
902 | - focused icon before we change focus to another icon. E.g. a value of 0.5 means you must |
903 | - go right a distance of half an icon's width before focus moves to the icon on the right |
904 | - */ |
905 | - var maxBufferThreshold = 0.5; |
906 | - |
907 | - /* |
908 | - To help users find the indicator of their choice while opening the indicators, we add logic to add a |
909 | - left/right buffer to each icon so it is harder for the focus to be moved accidentally to another icon, |
910 | - as the user moves their finger down, but yet allows them to switch indicator if they want. |
911 | - This buffer is wider the further the user's finger is from the top of the screen. |
912 | - */ |
913 | - var effectiveBufferThreshold = maxBufferThreshold * verticalProgress; |
914 | - |
915 | - rowCoordinates = indicatorRow.mapToItem(indicatorRow.row, xValue, 0); |
916 | - // get the current delegate |
917 | - currentItem = indicatorRow.row.itemAt(rowCoordinates.x, 0); |
918 | - if (currentItem) { |
919 | - itemCoordinates = indicatorRow.row.mapToItem(currentItem, rowCoordinates.x, 0); |
920 | - distanceFromRightEdge = (currentItem.width - itemCoordinates.x) / (currentItem.width); |
921 | - if (currentItem != indicatorRow.currentItem) { |
922 | - if (Math.abs(currentItem.ownIndex - indicatorRow.currentItemIndex) > 1) { |
923 | - bufferExceeded = true; |
924 | - } else { |
925 | - if (indicatorRow.currentItemIndex < currentItem.ownIndex && distanceFromRightEdge < (1 - effectiveBufferThreshold)) { |
926 | - bufferExceeded = true; |
927 | - } else if (indicatorRow.currentItemIndex > currentItem.ownIndex && distanceFromRightEdge > effectiveBufferThreshold) { |
928 | - bufferExceeded = true; |
929 | - } |
930 | - } |
931 | - if ((!useBuffer || (useBuffer && bufferExceeded)) || indicatorRow.currentItemIndex < 0 || indicatorRow.currentItem == null) { |
932 | - indicatorRow.setCurrentItem(currentItem); |
933 | - } |
934 | - |
935 | - // need to re-init the distanceFromRightEdge for offset calculation |
936 | - itemCoordinates = indicatorRow.row.mapToItem(indicatorRow.currentItem, rowCoordinates.x, 0); |
937 | - distanceFromRightEdge = (indicatorRow.currentItem.width - itemCoordinates.x) / (indicatorRow.currentItem.width); |
938 | - } |
939 | - indicatorRow.currentItemOffset = 1 - (distanceFromRightEdge * 2); |
940 | - } else if (initalizeItem) { |
941 | - indicatorRow.setDefaultItem(); |
942 | - indicatorRow.currentItemOffset = 0; |
943 | - } |
944 | - initalizeItem = indicatorRow.currentItem == null; |
945 | - } |
946 | - |
947 | - // eater |
948 | - MouseArea { |
949 | - anchors { |
950 | - top: parent.top |
951 | - bottom: handle.bottom |
952 | - left: parent.left |
953 | - right: parent.right |
954 | - } |
955 | - } |
956 | - |
957 | - VisibleIndicators { |
958 | - id: visibleIndicators |
959 | - } |
960 | - |
961 | - MenuContent { |
962 | - id: menuContent |
963 | - objectName: "menuContent" |
964 | - |
965 | - anchors { |
966 | - left: parent.left |
967 | - right: parent.right |
968 | - top: indicatorRow.bottom |
969 | - bottom: handle.top |
970 | - } |
971 | - indicatorsModel: visibleIndicators.model |
972 | - visible: indicators.partiallyOpened || indicators.fullyOpened |
973 | - clip: indicators.partiallyOpened |
974 | - enabled: contentEnabled |
975 | - |
976 | - //small shadow gradient at bottom of menu |
977 | - Rectangle { |
978 | - anchors { |
979 | - left: parent.left |
980 | - right: parent.right |
981 | - bottom: parent.bottom |
982 | - } |
983 | - height: units.gu(0.5) |
984 | - gradient: Gradient { |
985 | - GradientStop { position: 0.0; color: "transparent" } |
986 | - GradientStop { position: 1.0; color: "black" } |
987 | - } |
988 | - opacity: 0.4 |
989 | - } |
990 | - } |
991 | - |
992 | - Rectangle { |
993 | - id: handle |
994 | - |
995 | - color: menuContent.color |
996 | - |
997 | - anchors { |
998 | - left: parent.left |
999 | - right: parent.right |
1000 | - bottom: parent.bottom |
1001 | - } |
1002 | - height: Math.max(Math.min(handleImage.height, indicators.height - handleImage.height), 0) |
1003 | - clip: height < handleImage.height |
1004 | - visible: menuContent.visible |
1005 | - |
1006 | - BorderImage { |
1007 | - id: handleImage |
1008 | - source: "graphics/handle.sci" |
1009 | - height: panelHeight |
1010 | - anchors { |
1011 | - left: parent.left |
1012 | - right: parent.right |
1013 | - bottom: parent.bottom |
1014 | - } |
1015 | - } |
1016 | - MouseArea { //prevent clicks passing through |
1017 | - anchors.fill: parent |
1018 | - } |
1019 | - } |
1020 | - |
1021 | - IndicatorRow { |
1022 | - id: indicatorRow |
1023 | - objectName: "indicatorRow" |
1024 | - anchors { |
1025 | - left: parent.left |
1026 | - right: parent.right |
1027 | - } |
1028 | - height: indicators.panelHeight |
1029 | - indicatorsModel: visibleIndicators.model |
1030 | - state: indicators.state |
1031 | - unitProgress: indicators.unitProgress |
1032 | - |
1033 | - EdgeDragArea { |
1034 | - id: rowDragArea |
1035 | - anchors.fill: indicatorRow |
1036 | - direction: Direction.Downwards |
1037 | - maxSilenceTime: 2000 |
1038 | - distanceThreshold: 0 |
1039 | - |
1040 | - enabled: fullyOpened |
1041 | - onDraggingChanged: { |
1042 | - if (dragging) { |
1043 | - initalizeItem = true; |
1044 | - updateRevealProgressState(Math.max(touchSceneY - panelHeight, hintValue), false); |
1045 | - indicators.calculateCurrentItem(touchX, false); |
1046 | - } else { |
1047 | - indicators.state = "commit"; |
1048 | - indicatorRow.currentItemOffset = 0; |
1049 | - } |
1050 | - } |
1051 | - |
1052 | - onTouchXChanged: { |
1053 | - indicators.calculateCurrentItem(touchX, true); |
1054 | - } |
1055 | - onTouchSceneYChanged: { |
1056 | - updateRevealProgressState(Math.max(touchSceneY - panelHeight, hintValue), false); |
1057 | - yVelocityCalculator.trackedPosition = touchSceneY; |
1058 | - } |
1059 | - } |
1060 | - } |
1061 | - |
1062 | - Connections { |
1063 | - target: showAnimation |
1064 | - onRunningChanged: { |
1065 | - if (showAnimation.running) { |
1066 | - indicators.state = "commit"; |
1067 | - indicatorRow.currentItemOffset = 0; |
1068 | - } |
1069 | - } |
1070 | - } |
1071 | - |
1072 | - Connections { |
1073 | - target: hideAnimation |
1074 | - onRunningChanged: { |
1075 | - if (hideAnimation.running) { |
1076 | - indicators.state = "initial"; |
1077 | - initalizeItem = true; |
1078 | - indicatorRow.currentItemOffset = 0; |
1079 | - } |
1080 | - } |
1081 | - } |
1082 | - |
1083 | - QtObject { |
1084 | - id: d |
1085 | - property bool enableIndexChangeSignal: true |
1086 | - property var activeDragHandle: showDragHandle.dragging ? showDragHandle : hideDragHandle.dragging ? hideDragHandle : null |
1087 | - } |
1088 | - |
1089 | - Connections { |
1090 | - target: menuContent |
1091 | - onCurrentMenuIndexChanged: { |
1092 | - var oldActive = d.enableIndexChangeSignal; |
1093 | - if (!oldActive) return; |
1094 | - d.enableIndexChangeSignal = false; |
1095 | - |
1096 | - indicatorRow.setCurrentItemIndex(menuContent.currentMenuIndex); |
1097 | - |
1098 | - d.enableIndexChangeSignal = oldActive; |
1099 | - } |
1100 | - } |
1101 | - |
1102 | - Connections { |
1103 | - target: indicatorRow |
1104 | - onCurrentItemIndexChanged: { |
1105 | - var oldActive = d.enableIndexChangeSignal; |
1106 | - if (!oldActive) return; |
1107 | - d.enableIndexChangeSignal = false; |
1108 | - |
1109 | - menuContent.setCurrentMenuIndex(indicatorRow.currentItemIndex, fullyOpened || partiallyOpened); |
1110 | - |
1111 | - d.enableIndexChangeSignal = oldActive; |
1112 | - } |
1113 | - } |
1114 | - // connections to the active drag handle |
1115 | - Connections { |
1116 | - target: d.activeDragHandle |
1117 | - onTouchXChanged: { |
1118 | - indicators.calculateCurrentItem(d.activeDragHandle.touchX, true); |
1119 | - } |
1120 | - onTouchSceneYChanged: { |
1121 | - yVelocityCalculator.trackedPosition = d.activeDragHandle.touchSceneY; |
1122 | - } |
1123 | - } |
1124 | - |
1125 | - DragHandle { |
1126 | - id: showDragHandle |
1127 | - anchors.bottom: parent.bottom |
1128 | - // go beyond parent so that it stays reachable, at the top of the screen. |
1129 | - anchors.bottomMargin: showHintBottomMargin |
1130 | - anchors.left: parent.left |
1131 | - anchors.right: parent.right |
1132 | - height: panelHeight |
1133 | - direction: Direction.Downwards |
1134 | - enabled: !indicators.shown && indicators.available |
1135 | - hintDisplacement: enableHint ? indicators.hintValue : 0 |
1136 | - autoCompleteDragThreshold: maxTotalDragDistance / 2 |
1137 | - stretch: true |
1138 | - maxTotalDragDistance: openedHeight - panelHeight |
1139 | - distanceThreshold: panelHeight |
1140 | - |
1141 | - onTapped: showTapped(Qt.point(touchSceneX, touchSceneY)); |
1142 | - } |
1143 | - |
1144 | - DragHandle { |
1145 | - id: hideDragHandle |
1146 | - anchors.fill: handle |
1147 | - direction: Direction.Upwards |
1148 | - enabled: indicators.shown && indicators.available |
1149 | - hintDisplacement: indicators.hintValue |
1150 | - autoCompleteDragThreshold: maxTotalDragDistance / 6 |
1151 | - stretch: true |
1152 | - maxTotalDragDistance: openedHeight - panelHeight |
1153 | - distanceThreshold: 0 |
1154 | - } |
1155 | - |
1156 | - AxisVelocityCalculator { |
1157 | - id: yVelocityCalculator |
1158 | - } |
1159 | - |
1160 | - states: [ |
1161 | - State { |
1162 | - name: "initial" |
1163 | - }, |
1164 | - State { |
1165 | - name: "hint" |
1166 | - StateChangeScript { |
1167 | - script: { |
1168 | - if (d.activeDragHandle) { |
1169 | - calculateCurrentItem(d.activeDragHandle.touchX, false); |
1170 | - } |
1171 | - } |
1172 | - } |
1173 | - }, |
1174 | - State { |
1175 | - name: "reveal" |
1176 | - extend: "hint" |
1177 | - }, |
1178 | - State { |
1179 | - name: "locked" |
1180 | - extend: "hint" |
1181 | - }, |
1182 | - State { |
1183 | - name: "commit" |
1184 | - extend: "hint" |
1185 | - } |
1186 | - ] |
1187 | - state: "initial" |
1188 | - |
1189 | - transitions: [ |
1190 | - Transition { |
1191 | - NumberAnimation {targets: [indicatorRow, menuContent]; property: "y"; duration: 300; easing.type: Easing.OutCubic} |
1192 | - } |
1193 | - ] |
1194 | - |
1195 | - Component.onCompleted: initialise(); |
1196 | - function initialise() { |
1197 | - visibleIndicators.load(profile); |
1198 | - indicatorRow.setDefaultItem(); |
1199 | - } |
1200 | -} |
1201 | |
1202 | === removed file 'qml/Panel/Indicators/DefaultIndicatorWidget.qml' |
1203 | --- qml/Panel/Indicators/DefaultIndicatorWidget.qml 2014-08-20 08:39:09 +0000 |
1204 | +++ qml/Panel/Indicators/DefaultIndicatorWidget.qml 1970-01-01 00:00:00 +0000 |
1205 | @@ -1,119 +0,0 @@ |
1206 | -/* |
1207 | - * Copyright 2013 Canonical Ltd. |
1208 | - * |
1209 | - * This program is free software; you can redistribute it and/or modify |
1210 | - * it under the terms of the GNU Lesser General Public License as published by |
1211 | - * the Free Software Foundation; version 3. |
1212 | - * |
1213 | - * This program is distributed in the hope that it will be useful, |
1214 | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1215 | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1216 | - * GNU Lesser General Public License for more details. |
1217 | - * |
1218 | - * You should have received a copy of the GNU Lesser General Public License |
1219 | - * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1220 | - * |
1221 | - * Authors: |
1222 | - * Nick Dedekind <nick.dedekind@canonical.com> |
1223 | - */ |
1224 | - |
1225 | -import QtQuick 2.0 |
1226 | -import Ubuntu.Components 0.1 |
1227 | -import Ubuntu.Settings.Components 0.1 |
1228 | - |
1229 | -IndicatorBase { |
1230 | - id: indicatorWidget |
1231 | - |
1232 | - property int iconSize: units.gu(2) |
1233 | - property alias leftLabel: itemLeftLabel.text |
1234 | - property alias rightLabel: itemRightLabel.text |
1235 | - property var icons: undefined |
1236 | - |
1237 | - width: itemRow.width |
1238 | - enabled: false |
1239 | - |
1240 | - // FIXME: For now we will enable led indicator support only for messaging indicator |
1241 | - // in the future we should export a led API insted of doing that, |
1242 | - Loader { |
1243 | - id: indicatorLed |
1244 | - // only load source Component if the icons contains the new message icon |
1245 | - source: (indicatorWidget.icons && (String(indicatorWidget.icons).indexOf("indicator-messages-new") != -1)) ? Qt.resolvedUrl("IndicatorsLight.qml") : "" |
1246 | - } |
1247 | - |
1248 | - Row { |
1249 | - id: itemRow |
1250 | - objectName: "itemRow" |
1251 | - anchors { |
1252 | - top: parent.top |
1253 | - bottom: parent.bottom |
1254 | - horizontalCenter: parent.horizontalCenter |
1255 | - } |
1256 | - |
1257 | - Label { |
1258 | - id: itemLeftLabel |
1259 | - width: contentWidth + units.gu(1) |
1260 | - objectName: "leftLabel" |
1261 | - color: Theme.palette.selected.backgroundText |
1262 | - opacity: 0.8 |
1263 | - font.family: "Ubuntu" |
1264 | - fontSize: "medium" |
1265 | - anchors.verticalCenter: parent.verticalCenter |
1266 | - visible: text != "" |
1267 | - horizontalAlignment: Text.AlignHCenter |
1268 | - } |
1269 | - |
1270 | - Row { |
1271 | - id: iconRow |
1272 | - anchors { |
1273 | - top: parent.top |
1274 | - bottom: parent.bottom |
1275 | - } |
1276 | - |
1277 | - Repeater { |
1278 | - model: indicatorWidget.icons |
1279 | - |
1280 | - Item { |
1281 | - width: itemImage.width + units.gu(1) |
1282 | - height: iconRow.height |
1283 | - |
1284 | - StatusIcon { |
1285 | - id: itemImage |
1286 | - height: indicatorWidget.iconSize |
1287 | - anchors.centerIn: parent |
1288 | - source: modelData |
1289 | - sets: ["status", "actions"] |
1290 | - color: "#CCCCCC" |
1291 | - } |
1292 | - } |
1293 | - } |
1294 | - } |
1295 | - |
1296 | - Label { |
1297 | - id: itemRightLabel |
1298 | - width: contentWidth + units.gu(1) |
1299 | - objectName: "rightLabel" |
1300 | - color: Theme.palette.selected.backgroundText |
1301 | - opacity: 0.8 |
1302 | - font.family: "Ubuntu" |
1303 | - fontSize: "medium" |
1304 | - anchors.verticalCenter: parent.verticalCenter |
1305 | - visible: text != "" |
1306 | - horizontalAlignment: Text.AlignHCenter |
1307 | - } |
1308 | - } |
1309 | - |
1310 | - onRootActionStateChanged: { |
1311 | - if (rootActionState == undefined) { |
1312 | - leftLabel = ""; |
1313 | - rightLabel = ""; |
1314 | - icons = undefined; |
1315 | - enabled = false; |
1316 | - return; |
1317 | - } |
1318 | - |
1319 | - leftLabel = rootActionState.leftLabel ? rootActionState.leftLabel : ""; |
1320 | - rightLabel = rootActionState.rightLabel ? rootActionState.rightLabel : ""; |
1321 | - icons = rootActionState.icons; |
1322 | - enabled = rootActionState.visible; |
1323 | - } |
1324 | -} |
1325 | |
1326 | === modified file 'qml/Panel/Indicators/IndicatorBase.qml' |
1327 | --- qml/Panel/Indicators/IndicatorBase.qml 2014-10-15 16:33:45 +0000 |
1328 | +++ qml/Panel/Indicators/IndicatorBase.qml 2014-10-15 16:33:46 +0000 |
1329 | @@ -32,8 +32,6 @@ |
1330 | property string menuObjectPath |
1331 | property string rootMenuType: "com.canonical.indicator.root" |
1332 | |
1333 | - property string deviceMenuObjectPath: menuObjectPath |
1334 | - |
1335 | property alias menuModel: cachedModel.model |
1336 | property alias rootActionState: rootAction |
1337 | |
1338 | @@ -41,7 +39,7 @@ |
1339 | id: cachedModel |
1340 | busName: indicatorItem.busName |
1341 | actions: { "indicator": indicatorItem.actionsObjectPath } |
1342 | - menuObjectPath: indicatorItem.deviceMenuObjectPath |
1343 | + menuObjectPath: indicatorItem.menuObjectPath |
1344 | } |
1345 | |
1346 | RootActionState { |
1347 | |
1348 | === modified file 'qml/Panel/Indicators/VisibleIndicators.qml' |
1349 | --- qml/Panel/Indicators/VisibleIndicators.qml 2014-09-29 10:24:58 +0000 |
1350 | +++ qml/Panel/Indicators/VisibleIndicators.qml 2014-10-15 16:33:46 +0000 |
1351 | @@ -24,6 +24,10 @@ |
1352 | Item { |
1353 | property SortFilterProxyModel model: filterModel |
1354 | |
1355 | + function initialise(profile) { |
1356 | + indicatorsModel.load(profile); |
1357 | + } |
1358 | + |
1359 | SortFilterProxyModel { |
1360 | id: filterModel |
1361 | filterRole: Indicators.IndicatorsModelRole.IsVisible |
1362 | @@ -36,7 +40,6 @@ |
1363 | } |
1364 | } |
1365 | |
1366 | - |
1367 | Indicators.IndicatorsModel { |
1368 | id: indicatorsModel |
1369 | } |
1370 | @@ -78,8 +81,4 @@ |
1371 | } |
1372 | } |
1373 | } |
1374 | - |
1375 | - function load(profile) { |
1376 | - indicatorsModel.load(profile); |
1377 | - } |
1378 | } |
1379 | |
1380 | === renamed file 'qml/Panel/Indicators/client/IndicatorsPage.qml' => 'qml/Panel/Indicators/client/IndicatorRepresentation.qml' |
1381 | --- qml/Panel/Indicators/client/IndicatorsPage.qml 2013-08-14 09:07:45 +0000 |
1382 | +++ qml/Panel/Indicators/client/IndicatorRepresentation.qml 2014-10-15 16:33:46 +0000 |
1383 | @@ -21,13 +21,13 @@ |
1384 | import QtQuick 2.0 |
1385 | import Ubuntu.Components 0.1 |
1386 | import Ubuntu.Components.ListItems 0.1 as ListItem |
1387 | +import "../.." |
1388 | |
1389 | Page { |
1390 | - id: page |
1391 | + id: root |
1392 | |
1393 | title: indicatorProperties && indicatorProperties.title ? indicatorProperties.title : "" |
1394 | property variant indicatorProperties |
1395 | - property string pageSource : pageLoader.source |
1396 | |
1397 | anchors.fill: parent |
1398 | |
1399 | @@ -44,6 +44,7 @@ |
1400 | id: pageLoader |
1401 | objectName: "pageLoader" |
1402 | clip:true |
1403 | + asynchronous: true |
1404 | |
1405 | Rectangle { |
1406 | anchors.fill: pageLoader |
1407 | @@ -58,15 +59,25 @@ |
1408 | topMargin: units.gu(2) |
1409 | bottomMargin: units.gu(2) |
1410 | } |
1411 | - source : visualCheck.checked ? page.pageSource : "IndicatorsTree.qml" |
1412 | + sourceComponent: visualCheck.checked ? page : tree |
1413 | |
1414 | - onLoaded: { |
1415 | - for(var pName in indicatorProperties) { |
1416 | - if (item.hasOwnProperty(pName)) { |
1417 | - item[pName] = indicatorProperties[pName]; |
1418 | - } |
1419 | - } |
1420 | - item.start(); |
1421 | + Component { |
1422 | + id: page |
1423 | + IndicatorPage { |
1424 | + identifier: model.identifier |
1425 | + busName: indicatorProperties.busName |
1426 | + actionsObjectPath: indicatorProperties.actionsObjectPath |
1427 | + menuObjectPath: indicatorProperties.menuObjectPath |
1428 | + } |
1429 | + } |
1430 | + Component { |
1431 | + id: tree |
1432 | + IndicatorsTree { |
1433 | + identifier: model.identifier |
1434 | + busName: indicatorProperties.busName |
1435 | + actionsObjectPath: indicatorProperties.actionsObjectPath |
1436 | + menuObjectPath: indicatorProperties.menuObjectPath |
1437 | + } |
1438 | } |
1439 | } |
1440 | |
1441 | @@ -85,7 +96,7 @@ |
1442 | left: parent.left |
1443 | } |
1444 | text: "Back" |
1445 | - onClicked: page.pageStack.reset() |
1446 | + onClicked: root.pageStack.reset() |
1447 | } |
1448 | } |
1449 | } |
1450 | |
1451 | === modified file 'qml/Panel/Indicators/client/IndicatorsList.qml' |
1452 | --- qml/Panel/Indicators/client/IndicatorsList.qml 2014-01-30 14:54:01 +0000 |
1453 | +++ qml/Panel/Indicators/client/IndicatorsList.qml 2014-10-15 16:33:46 +0000 |
1454 | @@ -57,8 +57,8 @@ |
1455 | text: identifier |
1456 | |
1457 | onClicked: { |
1458 | - var new_page = Qt.createComponent("IndicatorsPage.qml"); |
1459 | - page.pageStack.push(new_page.createObject(pages), {"indicatorProperties" : model.indicatorProperties, "pageSource" : model.pageSource}); |
1460 | + var new_page = Qt.createComponent("IndicatorRepresentation.qml"); |
1461 | + page.pageStack.push(new_page.createObject(pages), {"indicatorProperties" : model.indicatorProperties }); |
1462 | } |
1463 | } |
1464 | } |
1465 | |
1466 | === modified file 'qml/Panel/Indicators/client/IndicatorsTree.qml' |
1467 | --- qml/Panel/Indicators/client/IndicatorsTree.qml 2013-11-24 02:23:56 +0000 |
1468 | +++ qml/Panel/Indicators/client/IndicatorsTree.qml 2014-10-15 16:33:46 +0000 |
1469 | @@ -20,36 +20,14 @@ |
1470 | import QtQuick 2.0 |
1471 | import Ubuntu.Components 0.1 |
1472 | import Unity.Indicators 0.1 as Indicators |
1473 | -import QMenuModel 0.1 |
1474 | -import Ubuntu.Components.ListItems 0.1 as ListItem |
1475 | - |
1476 | -Page { |
1477 | - id: page |
1478 | - anchors.fill: parent |
1479 | - |
1480 | - property string busName: unityModel.busName |
1481 | - property string actionsObjectPath |
1482 | - property string menuObjectPath |
1483 | - |
1484 | - property string deviceMenuObjectPath: menuObjectPath |
1485 | - |
1486 | - function start() { |
1487 | - } |
1488 | - |
1489 | - UnityMenuModel { |
1490 | - id: unityModel |
1491 | - busName: page.busName |
1492 | - actions: { "indicator": page.actionsObjectPath } |
1493 | - menuObjectPath: page.deviceMenuObjectPath |
1494 | - } |
1495 | - |
1496 | - Indicators.RootActionState { |
1497 | - menu: unityModel |
1498 | - } |
1499 | +import ".." |
1500 | + |
1501 | +IndicatorBase { |
1502 | + id: root |
1503 | |
1504 | Indicators.ModelPrinter { |
1505 | id: printer |
1506 | - model: unityModel |
1507 | + model: root.menuModel |
1508 | } |
1509 | |
1510 | Flickable { |
1511 | |
1512 | === added file 'qml/Panel/IndicatorsBar.qml' |
1513 | --- qml/Panel/IndicatorsBar.qml 1970-01-01 00:00:00 +0000 |
1514 | +++ qml/Panel/IndicatorsBar.qml 2014-10-15 16:33:46 +0000 |
1515 | @@ -0,0 +1,260 @@ |
1516 | +/* |
1517 | + * Copyright (C) 2014 Canonical, Ltd. |
1518 | + * |
1519 | + * This program is free software; you can redistribute it and/or modify |
1520 | + * it under the terms of the GNU General Public License as published by |
1521 | + * the Free Software Foundation; version 3. |
1522 | + * |
1523 | + * This program is distributed in the hope that it will be useful, |
1524 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1525 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1526 | + * GNU General Public License for more details. |
1527 | + * |
1528 | + * You should have received a copy of the GNU General Public License |
1529 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1530 | + */ |
1531 | + |
1532 | +import QtQuick 2.2 |
1533 | +import Ubuntu.Components 1.1 |
1534 | +import "../Components" |
1535 | + |
1536 | +Item { |
1537 | + id: root |
1538 | + property alias expanded: row.expanded |
1539 | + property alias interactive: flickable.interactive |
1540 | + property alias indicatorsModel: row.indicatorsModel |
1541 | + property alias unitProgress: row.unitProgress |
1542 | + property alias enableLateralChanges: row.enableLateralChanges |
1543 | + property alias overFlowWidth: row.overFlowWidth |
1544 | + readonly property alias currentItemIndex: row.currentItemIndex |
1545 | + property real lateralPosition: -1 |
1546 | + |
1547 | + function selectItemAt(lateralPosition) { |
1548 | + if (!expanded) { |
1549 | + row.resetCurrentItem(); |
1550 | + } |
1551 | + var mapped = root.mapToItem(row, lateralPosition, 0); |
1552 | + row.selectItemAt(mapped.x); |
1553 | + } |
1554 | + |
1555 | + function setCurrentItemIndex(index) { |
1556 | + if (!expanded) { |
1557 | + row.resetCurrentItem(); |
1558 | + } |
1559 | + row.setCurrentItemIndex(index); |
1560 | + } |
1561 | + |
1562 | + function addScrollOffset(scrollAmmout) { |
1563 | + if (scrollAmmout < 0) { // left scroll |
1564 | + if (flickable.contentX < 0) return; // already off the left. |
1565 | + if (flickable.contentX + scrollAmmout < 0) scrollAmmout = -flickable.contentX; // going to be off the left |
1566 | + } else { // right scroll |
1567 | + if (flickable.contentX + flickable.width > row.width) return; // already off the right. |
1568 | + if (flickable.contentX + flickable.width + scrollAmmout > row.width) { // going to be off the right |
1569 | + scrollAmmout = row.width - (flickable.contentX + flickable.width); |
1570 | + } |
1571 | + } |
1572 | + d.scrollOffset = d.scrollOffset + scrollAmmout; |
1573 | + } |
1574 | + |
1575 | + QtObject { |
1576 | + id: d |
1577 | + property var initialItem |
1578 | + // the non-expanded distance from row offset to center of initial item |
1579 | + property real originalDistanceFromRight: -1 |
1580 | + |
1581 | + // calculate the distance from row offset to center of initial item |
1582 | + property real distanceFromRight: { |
1583 | + if (originalDistanceFromRight == -1) return 0; |
1584 | + if (!initialItem) return 0; |
1585 | + return row.width - initialItem.x - initialItem.width /2; |
1586 | + } |
1587 | + |
1588 | + // offset to the intially selected expanded item |
1589 | + property real rowOffset: 0 |
1590 | + property real scrollOffset: 0 |
1591 | + property real alignmentAdjustment: 0 |
1592 | + property real combinedOffset: 0 |
1593 | + |
1594 | + // when the scroll offset changes, we need to reclaculate the relative lateral position |
1595 | + onScrollOffsetChanged: root.lateralPositionChanged() |
1596 | + |
1597 | + onInitialItemChanged: { |
1598 | + originalDistanceFromRight = initialItem ? (row.width - initialItem.x - initialItem.width/2) : -1; |
1599 | + } |
1600 | + |
1601 | + Behavior on alignmentAdjustment { |
1602 | + NumberAnimation { duration: UbuntuAnimation.BriskDuration; easing: UbuntuAnimation.StandardEasing} |
1603 | + } |
1604 | + |
1605 | + function alignIndicators() { |
1606 | + flickable.resetContentXComponents(); |
1607 | + |
1608 | + if (expanded && !flickable.moving) { |
1609 | + // gap between left and row? |
1610 | + if (row.width > flickable.width && flickable.contentX < 0) { |
1611 | + d.alignmentAdjustment += flickable.contentX; |
1612 | + // current item overlap on left |
1613 | + } else if (row.currentItem.x < flickable.contentX) { |
1614 | + d.alignmentAdjustment -= (row.currentItem.x - flickable.contentX); |
1615 | + // current item overlap on right |
1616 | + } else if (row.currentItem.x + row.currentItem.width > flickable.contentX + flickable.width) { |
1617 | + d.alignmentAdjustment -= ((row.currentItem.x + row.currentItem.width) - (flickable.contentX + flickable.width)); |
1618 | + } |
1619 | + } |
1620 | + } |
1621 | + } |
1622 | + |
1623 | + Rectangle { |
1624 | + id: grayLine |
1625 | + height: units.dp(2) |
1626 | + width: parent.width |
1627 | + anchors.bottom: parent.bottom |
1628 | + |
1629 | + color: "#4c4c4c" |
1630 | + opacity: expanded ? 1.0 : 0.0 |
1631 | + Behavior on opacity { NumberAnimation { duration: UbuntuAnimation.SnapDuration } } |
1632 | + } |
1633 | + |
1634 | + Item { |
1635 | + id: rowContainer |
1636 | + anchors.fill: parent |
1637 | + clip: expanded || row.width > rowContainer.width |
1638 | + |
1639 | + Flickable { |
1640 | + id: flickable |
1641 | + objectName: "flickable" |
1642 | + |
1643 | + anchors.fill: parent |
1644 | + contentWidth: row.width |
1645 | + interactive: false |
1646 | + // align right + offset from row selection + scrolling |
1647 | + contentX: row.width - flickable.width - d.combinedOffset |
1648 | + |
1649 | + // contentX can change by user interaction as well as user offset changes |
1650 | + // This function re-aligns the offsets so that the offsets match the contentX |
1651 | + function resetContentXComponents() { |
1652 | + d.scrollOffset += (flickable.contentX - (row.width - flickable.width - d.combinedOffset)); |
1653 | + } |
1654 | + |
1655 | + rebound: Transition { |
1656 | + NumberAnimation { |
1657 | + properties: "x" |
1658 | + duration: 600 |
1659 | + easing.type: Easing.OutCubic |
1660 | + } |
1661 | + } |
1662 | + |
1663 | + IndicatorItemRow { |
1664 | + id: row |
1665 | + objectName: "indicatorItemRow" |
1666 | + anchors { |
1667 | + top: parent.top |
1668 | + bottom: parent.bottom |
1669 | + } |
1670 | + |
1671 | + lateralPosition: { |
1672 | + if (root.lateralPosition == -1) return -1; |
1673 | + |
1674 | + var mapped = root.mapToItem(row, root.lateralPosition, 0); |
1675 | + return Math.min(Math.max(mapped.x, 0), row.width); |
1676 | + } |
1677 | + |
1678 | + onCurrentItemChanged: { |
1679 | + if (!currentItem) d.initialItem = undefined; |
1680 | + else if (!d.initialItem) d.initialItem = currentItem; |
1681 | + } |
1682 | + |
1683 | + MouseArea { |
1684 | + anchors.fill: parent |
1685 | + enabled: root.expanded |
1686 | + onClicked: { |
1687 | + row.selectItemAt(mouse.x); |
1688 | + d.alignIndicators(); |
1689 | + } |
1690 | + } |
1691 | + } |
1692 | + |
1693 | + } |
1694 | + } |
1695 | + |
1696 | + Timer { |
1697 | + id: alignmentTimer |
1698 | + interval: UbuntuAnimation.FastDuration // enough for row animation. |
1699 | + repeat: false |
1700 | + |
1701 | + onTriggered: d.alignIndicators(); |
1702 | + } |
1703 | + |
1704 | + states: [ |
1705 | + State { |
1706 | + name: "minimized" |
1707 | + when: !expanded |
1708 | + PropertyChanges { |
1709 | + target: d |
1710 | + rowOffset: 0 |
1711 | + scrollOffset: 0 |
1712 | + alignmentAdjustment: 0 |
1713 | + combinedOffset: 0 |
1714 | + restoreEntryValues: false |
1715 | + } |
1716 | + }, |
1717 | + State { |
1718 | + name: "expanded" |
1719 | + when: expanded && !interactive |
1720 | + |
1721 | + PropertyChanges { |
1722 | + target: d |
1723 | + combinedOffset: rowOffset + alignmentAdjustment - scrollOffset |
1724 | + } |
1725 | + PropertyChanges { |
1726 | + target: d |
1727 | + rowOffset: { |
1728 | + if (!initialItem) return 0; |
1729 | + if (distanceFromRight - initialItem.width <= 0) return 0; |
1730 | + |
1731 | + var rowOffset = distanceFromRight - originalDistanceFromRight; |
1732 | + return rowOffset; |
1733 | + } |
1734 | + restoreEntryValues: false |
1735 | + } |
1736 | + } |
1737 | + , State { |
1738 | + name: "interactive" |
1739 | + when: expanded && interactive |
1740 | + |
1741 | + StateChangeScript { |
1742 | + script: { |
1743 | + // don't use row offset anymore. |
1744 | + d.scrollOffset -= d.rowOffset; |
1745 | + d.rowOffset = 0; |
1746 | + d.initialItem = undefined; |
1747 | + alignmentTimer.start(); |
1748 | + } |
1749 | + } |
1750 | + PropertyChanges { |
1751 | + target: d |
1752 | + combinedOffset: rowOffset + alignmentAdjustment - scrollOffset |
1753 | + restoreEntryValues: false |
1754 | + } |
1755 | + } |
1756 | + ] |
1757 | + |
1758 | + transitions: [ |
1759 | + Transition { |
1760 | + from: "expanded" |
1761 | + to: "minimized" |
1762 | + PropertyAction { |
1763 | + target: d |
1764 | + properties: "rowOffset, scrollOffset, alignmentAdjustment" |
1765 | + value: 0 |
1766 | + } |
1767 | + PropertyAnimation { |
1768 | + target: d |
1769 | + properties: "combinedOffset" |
1770 | + duration: UbuntuAnimation.SnapDuration |
1771 | + easing: UbuntuAnimation.StandardEasing |
1772 | + } |
1773 | + } |
1774 | + ] |
1775 | +} |
1776 | |
1777 | === added file 'qml/Panel/IndicatorsMenu.qml' |
1778 | --- qml/Panel/IndicatorsMenu.qml 1970-01-01 00:00:00 +0000 |
1779 | +++ qml/Panel/IndicatorsMenu.qml 2014-10-15 16:33:46 +0000 |
1780 | @@ -0,0 +1,285 @@ |
1781 | +/* |
1782 | + * Copyright (C) 2014 Canonical, Ltd. |
1783 | + * |
1784 | + * This program is free software; you can redistribute it and/or modify |
1785 | + * it under the terms of the GNU General Public License as published by |
1786 | + * the Free Software Foundation; version 3. |
1787 | + * |
1788 | + * This program is distributed in the hope that it will be useful, |
1789 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1790 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1791 | + * GNU General Public License for more details. |
1792 | + * |
1793 | + * You should have received a copy of the GNU General Public License |
1794 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1795 | + */ |
1796 | + |
1797 | +import QtQuick 2.2 |
1798 | +import Ubuntu.Components 1.1 |
1799 | +import Ubuntu.Gestures 0.1 |
1800 | +import "../Components" |
1801 | + |
1802 | +Showable { |
1803 | + id: root |
1804 | + property alias indicatorsModel: bar.indicatorsModel |
1805 | + property alias showDragHandle: __showDragHandle |
1806 | + property alias hideDragHandle: __hideDragHandle |
1807 | + property alias overFlowWidth: bar.overFlowWidth |
1808 | + property alias verticalVelocityThreshold: yVelocityCalculator.velocityThreshold |
1809 | + property int minimizedPanelHeight: units.gu(3) |
1810 | + property int expandedPanelHeight: units.gu(7) |
1811 | + property real openedHeight: units.gu(71) |
1812 | + readonly property real unitProgress: Math.max(0, (height - minimizedPanelHeight) / (openedHeight - minimizedPanelHeight)) |
1813 | + readonly property bool fullyOpened: unitProgress >= 1 |
1814 | + readonly property bool partiallyOpened: unitProgress > 0 && unitProgress < 1.0 |
1815 | + readonly property bool fullyClosed: unitProgress == 0 |
1816 | + property bool enableHint: true |
1817 | + property bool contentEnabled: true |
1818 | + property color panelColor: "black" |
1819 | + |
1820 | + signal showTapped(point position) |
1821 | + |
1822 | + // TODO: Perhaps we need a animation standard for showing/hiding? Each showable seems to |
1823 | + // use its own values. Need to ask design about this. |
1824 | + showAnimation: StandardAnimation { |
1825 | + property: "height" |
1826 | + to: openedHeight |
1827 | + duration: UbuntuAnimation.BriskDuration |
1828 | + easing.type: Easing.OutCubic |
1829 | + } |
1830 | + |
1831 | + hideAnimation: StandardAnimation { |
1832 | + property: "height" |
1833 | + to: minimizedPanelHeight |
1834 | + duration: UbuntuAnimation.BriskDuration |
1835 | + easing.type: Easing.OutCubic |
1836 | + } |
1837 | + |
1838 | + height: minimizedPanelHeight |
1839 | + onHeightChanged: { |
1840 | + var revealProgress = root.height - minimizedPanelHeight; |
1841 | + |
1842 | + if (!showAnimation.running && !hideAnimation.running) { |
1843 | + if (revealProgress <= 0) { |
1844 | + root.state = "initial"; |
1845 | + } else { |
1846 | + root.state = "reveal"; |
1847 | + } |
1848 | + } |
1849 | + } |
1850 | + clip: root.partiallyOpened |
1851 | + |
1852 | + // eater |
1853 | + MouseArea { |
1854 | + anchors.fill: parent |
1855 | + } |
1856 | + |
1857 | + MenuContent { |
1858 | + id: content |
1859 | + objectName: "menuContent" |
1860 | + |
1861 | + anchors { |
1862 | + left: parent.left |
1863 | + right: parent.right |
1864 | + top: bar.bottom |
1865 | + } |
1866 | + height: openedHeight - bar.height - handle.height |
1867 | + indicatorsModel: root.indicatorsModel |
1868 | + visible: root.unitProgress > 0 |
1869 | + enabled: contentEnabled |
1870 | + currentMenuIndex: bar.currentItemIndex |
1871 | + } |
1872 | + |
1873 | + Handle { |
1874 | + id: handle |
1875 | + anchors { |
1876 | + left: parent.left |
1877 | + right: parent.right |
1878 | + bottom: parent.bottom |
1879 | + } |
1880 | + height: units.gu(2) |
1881 | + active: d.activeDragHandle ? true : false |
1882 | + |
1883 | + //small shadow gradient at bottom of menu |
1884 | + Rectangle { |
1885 | + anchors { |
1886 | + left: parent.left |
1887 | + right: parent.right |
1888 | + bottom: parent.top |
1889 | + } |
1890 | + height: units.gu(0.5) |
1891 | + gradient: Gradient { |
1892 | + GradientStop { position: 0.0; color: "transparent" } |
1893 | + GradientStop { position: 1.0; color: "black" } |
1894 | + } |
1895 | + opacity: 0.3 |
1896 | + } |
1897 | + } |
1898 | + |
1899 | + Rectangle { |
1900 | + anchors.fill: bar |
1901 | + color: panelColor |
1902 | + } |
1903 | + |
1904 | + IndicatorsBar { |
1905 | + id: bar |
1906 | + objectName: "indicatorsBar" |
1907 | + |
1908 | + anchors { |
1909 | + left: parent.left |
1910 | + right: parent.right |
1911 | + } |
1912 | + expanded: false |
1913 | + enableLateralChanges: false |
1914 | + lateralPosition: -1 |
1915 | + unitProgress: root.unitProgress |
1916 | + |
1917 | + height: expanded ? expandedPanelHeight : minimizedPanelHeight |
1918 | + Behavior on height { NumberAnimation { duration: UbuntuAnimation.SnapDuration; easing: UbuntuAnimation.StandardEasing } } |
1919 | + } |
1920 | + |
1921 | + ScrollCalculator { |
1922 | + id: leftScroller |
1923 | + width: units.gu(5) |
1924 | + anchors.left: bar.left |
1925 | + height: bar.height |
1926 | + |
1927 | + forceScrollingPercentage: 0.33 |
1928 | + stopScrollThreshold: units.gu(0.75) |
1929 | + direction: Qt.RightToLeft |
1930 | + lateralPosition: -1 |
1931 | + |
1932 | + onScroll: bar.addScrollOffset(-scrollAmount); |
1933 | + } |
1934 | + |
1935 | + ScrollCalculator { |
1936 | + id: rightScroller |
1937 | + width: units.gu(5) |
1938 | + anchors.right: bar.right |
1939 | + height: bar.height |
1940 | + |
1941 | + forceScrollingPercentage: 0.33 |
1942 | + stopScrollThreshold: units.gu(0.75) |
1943 | + direction: Qt.LeftToRight |
1944 | + lateralPosition: -1 |
1945 | + |
1946 | + onScroll: bar.addScrollOffset(scrollAmount); |
1947 | + } |
1948 | + |
1949 | + DragHandle { |
1950 | + id: __showDragHandle |
1951 | + anchors.bottom: parent.bottom |
1952 | + anchors.left: parent.left |
1953 | + anchors.right: parent.right |
1954 | + height: minimizedPanelHeight |
1955 | + direction: Direction.Downwards |
1956 | + enabled: !root.shown && root.available |
1957 | + autoCompleteDragThreshold: maxTotalDragDistance / 2 |
1958 | + stretch: true |
1959 | + distanceThreshold: minimizedPanelHeight |
1960 | + onTapped: showTapped(Qt.point(touchSceneX, touchSceneY)); |
1961 | + |
1962 | + // using hint regulates minimum to hint displacement, but in fullscreen mode, we need to do it manually. |
1963 | + overrideStartValue: enableHint ? minimizedPanelHeight : expandedPanelHeight + handle.height |
1964 | + maxTotalDragDistance: openedHeight - (enableHint ? minimizedPanelHeight : expandedPanelHeight + handle.height) |
1965 | + hintDisplacement: enableHint ? expandedPanelHeight - minimizedPanelHeight + handle.height : 0 |
1966 | + } |
1967 | + |
1968 | + DragHandle { |
1969 | + id: __hideDragHandle |
1970 | + anchors.fill: handle |
1971 | + direction: Direction.Upwards |
1972 | + enabled: root.shown && root.available |
1973 | + hintDisplacement: units.gu(3) |
1974 | + autoCompleteDragThreshold: maxTotalDragDistance / 6 |
1975 | + stretch: true |
1976 | + maxTotalDragDistance: openedHeight - expandedPanelHeight - handle.height |
1977 | + distanceThreshold: 0 |
1978 | + } |
1979 | + |
1980 | + PanelVelocityCalculator { |
1981 | + id: yVelocityCalculator |
1982 | + velocityThreshold: 0.5 |
1983 | + trackedValue: d.activeDragHandle ? d.activeDragHandle.touchSceneY : 0 |
1984 | + } |
1985 | + |
1986 | + Connections { |
1987 | + target: showAnimation |
1988 | + onRunningChanged: { |
1989 | + if (showAnimation.running) { |
1990 | + root.state = "commit"; |
1991 | + } |
1992 | + } |
1993 | + } |
1994 | + |
1995 | + Connections { |
1996 | + target: hideAnimation |
1997 | + onRunningChanged: { |
1998 | + if (hideAnimation.running) { |
1999 | + root.state = "initial"; |
2000 | + } |
2001 | + } |
2002 | + } |
2003 | + |
2004 | + QtObject { |
2005 | + id: d |
2006 | + property var activeDragHandle: showDragHandle.dragging ? showDragHandle : hideDragHandle.dragging ? hideDragHandle : null |
2007 | + |
2008 | + property real rowMappedLateralPosition: { |
2009 | + if (!d.activeDragHandle) return -1; |
2010 | + return d.activeDragHandle.mapToItem(bar, d.activeDragHandle.touchX, 0).x; |
2011 | + } |
2012 | + } |
2013 | + |
2014 | + states: [ |
2015 | + State { |
2016 | + name: "initial" |
2017 | + }, |
2018 | + State { |
2019 | + name: "reveal" |
2020 | + StateChangeScript { |
2021 | + script: { |
2022 | + yVelocityCalculator.reset(); |
2023 | + // initial item selection |
2024 | + bar.selectItemAt(d.activeDragHandle ? d.activeDragHandle.touchX : -1); |
2025 | + } |
2026 | + } |
2027 | + PropertyChanges { |
2028 | + target: bar |
2029 | + expanded: true |
2030 | + // changes to lateral touch position effect which indicator is selected |
2031 | + lateralPosition: d.rowMappedLateralPosition |
2032 | + // vertical velocity determines if changes in lateral position has an effect |
2033 | + enableLateralChanges: d.activeDragHandle && |
2034 | + !yVelocityCalculator.velocityAboveThreshold |
2035 | + } |
2036 | + // left scroll bar handling |
2037 | + PropertyChanges { |
2038 | + target: leftScroller |
2039 | + lateralPosition: { |
2040 | + if (!d.activeDragHandle) return -1; |
2041 | + var mapped = d.activeDragHandle.mapToItem(leftScroller, d.activeDragHandle.touchX, 0); |
2042 | + return mapped.x; |
2043 | + } |
2044 | + } |
2045 | + // right scroll bar handling |
2046 | + PropertyChanges { |
2047 | + target: rightScroller |
2048 | + lateralPosition: { |
2049 | + if (!d.activeDragHandle) return -1; |
2050 | + var mapped = d.activeDragHandle.mapToItem(rightScroller, d.activeDragHandle.touchX, 0); |
2051 | + return mapped.x; |
2052 | + } |
2053 | + } |
2054 | + }, |
2055 | + State { |
2056 | + name: "commit" |
2057 | + PropertyChanges { |
2058 | + target: bar |
2059 | + expanded: true |
2060 | + interactive: true |
2061 | + } |
2062 | + } |
2063 | + ] |
2064 | + state: "initial" |
2065 | +} |
2066 | |
2067 | === modified file 'qml/Panel/MenuContent.qml' |
2068 | --- qml/Panel/MenuContent.qml 2014-09-29 10:24:58 +0000 |
2069 | +++ qml/Panel/MenuContent.qml 2014-10-15 16:33:46 +0000 |
2070 | @@ -1,5 +1,5 @@ |
2071 | /* |
2072 | - * Copyright (C) 2013 Canonical, Ltd. |
2073 | + * Copyright (C) 2013-2014 Canonical, Ltd. |
2074 | * |
2075 | * This program is free software; you can redistribute it and/or modify |
2076 | * it under the terms of the GNU General Public License as published by |
2077 | @@ -14,125 +14,68 @@ |
2078 | * along with this program. If not, see <http://www.gnu.org/licenses/>. |
2079 | */ |
2080 | |
2081 | -import QtQuick 2.0 |
2082 | +import QtQuick 2.2 |
2083 | import QtQuick.Layouts 1.1 |
2084 | import Ubuntu.Components 1.1 |
2085 | import Unity.Indicators 0.1 as Indicators |
2086 | import Utils 0.1 |
2087 | import "../Components" |
2088 | -import "Indicators" |
2089 | |
2090 | Rectangle { |
2091 | id: content |
2092 | |
2093 | property QtObject indicatorsModel: null |
2094 | - readonly property alias currentMenuIndex: listViewHeader.currentIndex |
2095 | + property int currentMenuIndex: -1 |
2096 | color: "#221e1c" // FIXME not in palette yet |
2097 | - property real headerHeight: listViewHeader.height |
2098 | |
2099 | width: units.gu(40) |
2100 | height: units.gu(42) |
2101 | |
2102 | - function setCurrentMenuIndex(index, animate) { |
2103 | - // FIXME - https://bugreports.qt-project.org/browse/QTBUG-41229 |
2104 | - listViewHeader.currentIndex = -1; |
2105 | - listViewHeader.currentIndex = index; |
2106 | - } |
2107 | - |
2108 | - ListView { |
2109 | - id: listViewHeader |
2110 | - objectName: "indicatorsHeaderListView" |
2111 | - model: content.indicatorsModel |
2112 | - clip: true |
2113 | - |
2114 | - anchors { |
2115 | - left: parent.left |
2116 | - right: parent.right |
2117 | - } |
2118 | - height: units.gu(8.5) |
2119 | - |
2120 | - highlightFollowsCurrentItem: true |
2121 | - highlightMoveDuration: 0 |
2122 | - |
2123 | - orientation: ListView.Horizontal |
2124 | - snapMode: ListView.SnapOneItem |
2125 | - highlightRangeMode: ListView.StrictlyEnforceRange |
2126 | - boundsBehavior: Flickable.StopAtBounds |
2127 | - // Load all the indicator menus (a big number) |
2128 | - cacheBuffer: 1073741823 |
2129 | - |
2130 | - delegate: Header { |
2131 | - width: ListView.view.width |
2132 | - height: implicitHeight |
2133 | - |
2134 | - title: indicatorDelegate.title !== "" ? indicatorDelegate.title : identifier |
2135 | - |
2136 | - IndicatorDelegate { |
2137 | - id: indicatorDelegate |
2138 | - Component.onCompleted: { |
2139 | - for(var pName in indicatorProperties) { |
2140 | - if (indicatorDelegate.hasOwnProperty(pName)) { |
2141 | - indicatorDelegate[pName] = indicatorProperties[pName]; |
2142 | - } |
2143 | - } |
2144 | - } |
2145 | - } |
2146 | - } |
2147 | + onCurrentMenuIndexChanged: { |
2148 | + listViewContent.currentIndex = currentMenuIndex; |
2149 | } |
2150 | |
2151 | ListView { |
2152 | id: listViewContent |
2153 | objectName: "indicatorsContentListView" |
2154 | - anchors { |
2155 | - left: parent.left |
2156 | - right: parent.right |
2157 | - top: listViewHeader.bottom |
2158 | - bottom: parent.bottom |
2159 | - } |
2160 | + anchors.fill: parent |
2161 | model: content.indicatorsModel |
2162 | clip: true |
2163 | |
2164 | - currentIndex: listViewHeader.currentIndex |
2165 | + highlightFollowsCurrentItem: true |
2166 | interactive: false |
2167 | highlightMoveDuration: 0 |
2168 | orientation: ListView.Horizontal |
2169 | // Load all the indicator menus (a big number) |
2170 | cacheBuffer: 1073741823 |
2171 | |
2172 | + // for additions/removals. |
2173 | + onCountChanged: { |
2174 | + listViewContent.currentIndex = content.currentMenuIndex; |
2175 | + } |
2176 | + |
2177 | delegate: Loader { |
2178 | id: loader |
2179 | + |
2180 | width: ListView.view.width |
2181 | height: ListView.view.height |
2182 | objectName: identifier |
2183 | - |
2184 | - source: pageSource |
2185 | asynchronous: true |
2186 | |
2187 | + sourceComponent: IndicatorPage { |
2188 | + objectName: identifier + "-page" |
2189 | + |
2190 | + identifier: model.identifier |
2191 | + busName: indicatorProperties.busName |
2192 | + actionsObjectPath: indicatorProperties.actionsObjectPath |
2193 | + menuObjectPath: indicatorProperties.menuObjectPath |
2194 | + } |
2195 | + |
2196 | onVisibleChanged: { |
2197 | // Reset the indicator states |
2198 | - if (!visible && item && item["reset"]) { |
2199 | - item.reset() |
2200 | - } |
2201 | - } |
2202 | - |
2203 | - onLoaded: { |
2204 | - for(var pName in indicatorProperties) { |
2205 | - if (item.hasOwnProperty(pName)) { |
2206 | - item[pName] = indicatorProperties[pName] |
2207 | - } |
2208 | - } |
2209 | - } |
2210 | - |
2211 | - Binding { |
2212 | - target: loader.item |
2213 | - property: "identifier" |
2214 | - value: identifier |
2215 | - } |
2216 | - |
2217 | - Binding { |
2218 | - target: loader.item |
2219 | - property: "objectName" |
2220 | - value: identifier + "-page" |
2221 | + if (!visible && status == Loader.Ready) { |
2222 | + item.reset(); |
2223 | + } |
2224 | } |
2225 | } |
2226 | } |
2227 | |
2228 | === removed file 'qml/Panel/Panel.qml' |
2229 | --- qml/Panel/Panel.qml 2014-07-10 13:36:41 +0000 |
2230 | +++ qml/Panel/Panel.qml 1970-01-01 00:00:00 +0000 |
2231 | @@ -1,191 +0,0 @@ |
2232 | -/* |
2233 | - * Copyright (C) 2013 Canonical, Ltd. |
2234 | - * |
2235 | - * This program is free software; you can redistribute it and/or modify |
2236 | - * it under the terms of the GNU General Public License as published by |
2237 | - * the Free Software Foundation; version 3. |
2238 | - * |
2239 | - * This program is distributed in the hope that it will be useful, |
2240 | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
2241 | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
2242 | - * GNU General Public License for more details. |
2243 | - * |
2244 | - * You should have received a copy of the GNU General Public License |
2245 | - * along with this program. If not, see <http://www.gnu.org/licenses/>. |
2246 | - */ |
2247 | - |
2248 | -import QtQuick 2.0 |
2249 | -import Ubuntu.Components 0.1 |
2250 | -import Unity.Application 0.1 |
2251 | -import "../Components" |
2252 | -import "../Components/ListItems" |
2253 | - |
2254 | -Item { |
2255 | - id: root |
2256 | - readonly property real panelHeight: indicatorArea.y + d.indicatorHeight |
2257 | - property alias indicators: __indicators |
2258 | - property alias callHint: __callHint |
2259 | - property bool fullscreenMode: false |
2260 | - |
2261 | - Rectangle { |
2262 | - id: darkenedArea |
2263 | - property real darkenedOpacity: 0.6 |
2264 | - anchors { |
2265 | - top: parent.top |
2266 | - topMargin: panelHeight |
2267 | - left: parent.left |
2268 | - right: parent.right |
2269 | - bottom: parent.bottom |
2270 | - } |
2271 | - color: "black" |
2272 | - opacity: indicators.unitProgress * darkenedOpacity |
2273 | - |
2274 | - MouseArea { |
2275 | - anchors.fill: parent |
2276 | - enabled: indicators.shown |
2277 | - onClicked: if (indicators.fullyOpened) indicators.hide(); |
2278 | - } |
2279 | - } |
2280 | - |
2281 | - Item { |
2282 | - id: indicatorArea |
2283 | - objectName: "indicatorArea" |
2284 | - |
2285 | - anchors.fill: parent |
2286 | - |
2287 | - Behavior on anchors.topMargin { StandardAnimation {} } |
2288 | - |
2289 | - BorderImage { |
2290 | - id: dropShadow |
2291 | - anchors { |
2292 | - fill: indicators |
2293 | - leftMargin: -units.gu(1) |
2294 | - bottomMargin: -units.gu(1) |
2295 | - } |
2296 | - visible: indicators.height > indicators.panelHeight |
2297 | - source: "graphics/rectangular_dropshadow.sci" |
2298 | - } |
2299 | - |
2300 | - VerticalThinDivider { |
2301 | - id: indicatorDividor |
2302 | - anchors { |
2303 | - top: indicators.top |
2304 | - bottom: indicators.bottom |
2305 | - right: indicators.left |
2306 | - |
2307 | - topMargin: indicatorArea.anchors.topMargin + indicators.panelHeight |
2308 | - } |
2309 | - |
2310 | - width: units.dp(2) |
2311 | - source: "graphics/VerticalDivider.png" |
2312 | - } |
2313 | - |
2314 | - Rectangle { |
2315 | - id: indicatorAreaBackground |
2316 | - color: callHint.visible ? "green" : "black" |
2317 | - anchors { |
2318 | - top: parent.top |
2319 | - left: parent.left |
2320 | - right: parent.right |
2321 | - } |
2322 | - height: indicators.panelHeight |
2323 | - |
2324 | - Behavior on color { ColorAnimation { duration: UbuntuAnimation.FastDuration } } |
2325 | - } |
2326 | - |
2327 | - PanelSeparatorLine { |
2328 | - id: nonIndicatorAreaSeparatorLine |
2329 | - anchors { |
2330 | - top: indicatorAreaBackground.bottom |
2331 | - left: parent.left |
2332 | - right: indicators.left |
2333 | - } |
2334 | - saturation: 1 - indicators.unitProgress |
2335 | - } |
2336 | - |
2337 | - MouseArea { |
2338 | - anchors { |
2339 | - top: parent.top |
2340 | - left: parent.left |
2341 | - right: indicators.left |
2342 | - } |
2343 | - height: indicators.panelHeight |
2344 | - enabled: callHint.visible |
2345 | - onClicked: callHint.showLiveCall() |
2346 | - } |
2347 | - |
2348 | - Indicators { |
2349 | - id: __indicators |
2350 | - objectName: "indicators" |
2351 | - |
2352 | - anchors { |
2353 | - top: parent.top |
2354 | - right: parent.right |
2355 | - } |
2356 | - |
2357 | - width: root.width |
2358 | - shown: false |
2359 | - panelHeight: units.gu(3) |
2360 | - openedHeight: root.height |
2361 | - overFlowWidth: { |
2362 | - if (callHint.visible) { |
2363 | - return Math.max(root.width - (callHint.width + units.gu(2)), 0) |
2364 | - } |
2365 | - return root.width |
2366 | - } |
2367 | - |
2368 | - enableHint: !callHint.active && !fullscreenMode |
2369 | - showHintBottomMargin: fullscreenMode ? -panelHeight : 0 |
2370 | - |
2371 | - onShowTapped: { |
2372 | - if (callHint.active) { |
2373 | - callHint.showLiveCall(); |
2374 | - } |
2375 | - } |
2376 | - } |
2377 | - |
2378 | - ActiveCallHint { |
2379 | - id: __callHint |
2380 | - anchors { |
2381 | - top: parent.top |
2382 | - left: parent.left |
2383 | - } |
2384 | - height: indicators.panelHeight |
2385 | - visible: active && indicators.state == "initial" |
2386 | - } |
2387 | - |
2388 | - PanelSeparatorLine { |
2389 | - id: indicatorsSeparatorLine |
2390 | - visible: true |
2391 | - anchors { |
2392 | - top: indicators.bottom |
2393 | - left: indicatorDividor.left |
2394 | - right: indicators.right |
2395 | - } |
2396 | - } |
2397 | - } |
2398 | - |
2399 | - QtObject { |
2400 | - id: d |
2401 | - readonly property real indicatorHeight: indicators.panelHeight + indicatorsSeparatorLine.height |
2402 | - } |
2403 | - |
2404 | - states: [ |
2405 | - State { |
2406 | - name: "onscreen" //fully opaque and visible at top edge of screen |
2407 | - when: !fullscreenMode |
2408 | - PropertyChanges { |
2409 | - target: indicatorArea; |
2410 | - anchors.topMargin: 0 |
2411 | - } |
2412 | - }, |
2413 | - State { |
2414 | - name: "offscreen" //pushed off screen |
2415 | - when: fullscreenMode |
2416 | - PropertyChanges { |
2417 | - target: indicatorArea; |
2418 | - anchors.topMargin: indicators.state === "initial" ? -d.indicatorHeight : 0 |
2419 | - } |
2420 | - } |
2421 | - ] |
2422 | -} |
2423 | |
2424 | === added file 'qml/Panel/PanelVelocityCalculator.qml' |
2425 | --- qml/Panel/PanelVelocityCalculator.qml 1970-01-01 00:00:00 +0000 |
2426 | +++ qml/Panel/PanelVelocityCalculator.qml 2014-10-15 16:33:46 +0000 |
2427 | @@ -0,0 +1,54 @@ |
2428 | +/* |
2429 | + * Copyright (C) 2014 Canonical, Ltd. |
2430 | + * |
2431 | + * This program is free software; you can redistribute it and/or modify |
2432 | + * it under the terms of the GNU General Public License as published by |
2433 | + * the Free Software Foundation; version 3. |
2434 | + * |
2435 | + * This program is distributed in the hope that it will be useful, |
2436 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
2437 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
2438 | + * GNU General Public License for more details. |
2439 | + * |
2440 | + * You should have received a copy of the GNU General Public License |
2441 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
2442 | + */ |
2443 | + |
2444 | +import QtQuick 2.2 |
2445 | +import Ubuntu.Gestures 0.1 |
2446 | + |
2447 | +Item { |
2448 | + id: root |
2449 | + property real trackedValue: 0 |
2450 | + property bool velocityAboveThreshold: false |
2451 | + property real velocityThreshold: 0.4 |
2452 | + |
2453 | + function reset() { |
2454 | + velocityTimer.stop(); |
2455 | + velocityAboveThreshold = false; |
2456 | + calc.reset(); |
2457 | + } |
2458 | + |
2459 | + function update() { |
2460 | + calc.trackedPosition = trackedValue; |
2461 | + velocityAboveThreshold = Math.abs(calc.calculate()) > velocityThreshold; |
2462 | + |
2463 | + if (velocityAboveThreshold) { // only start timer if we're above the threshold. |
2464 | + velocityTimer.start(); |
2465 | + } else { |
2466 | + velocityTimer.stop(); |
2467 | + } |
2468 | + } |
2469 | + |
2470 | + onTrackedValueChanged: update(); |
2471 | + |
2472 | + AxisVelocityCalculator { |
2473 | + id: calc |
2474 | + } |
2475 | + |
2476 | + Timer { |
2477 | + id: velocityTimer |
2478 | + interval: 50 |
2479 | + onTriggered: update(); |
2480 | + } |
2481 | +} |
2482 | |
2483 | === modified file 'qml/Shell.qml' |
2484 | --- qml/Shell.qml 2014-10-08 20:36:48 +0000 |
2485 | +++ qml/Shell.qml 2014-10-15 16:33:46 +0000 |
2486 | @@ -36,6 +36,7 @@ |
2487 | import "Components" |
2488 | import "Notifications" |
2489 | import "Stages" |
2490 | +import "Panel/Indicators" |
2491 | import Unity.Notifications 1.0 as NotificationBackend |
2492 | import Unity.Session 0.1 |
2493 | import Unity.DashCommunicator 0.1 |
2494 | @@ -235,7 +236,7 @@ |
2495 | target: applicationsDisplayLoader.item |
2496 | property: "maximizedAppTopMargin" |
2497 | // Not just using panel.panelHeight as that changes depending on the focused app. |
2498 | - value: panel.indicators.panelHeight |
2499 | + value: panel.indicators.minimizedPanelHeight + units.dp(2) // dp(2) for orange line |
2500 | } |
2501 | Binding { |
2502 | target: applicationsDisplayLoader.item |
2503 | @@ -613,7 +614,17 @@ |
2504 | available: edgeDemo.panelEnabled && (!shell.locked || AccountsService.enableIndicatorsWhileLocked) && !greeter.hasLockedApp |
2505 | contentEnabled: edgeDemo.panelContentEnabled |
2506 | width: parent.width > units.gu(60) ? units.gu(40) : parent.width |
2507 | - panelHeight: units.gu(3) |
2508 | + |
2509 | + minimizedPanelHeight: units.gu(3) |
2510 | + expandedPanelHeight: units.gu(7) |
2511 | + |
2512 | + indicatorsModel: visibleIndicators.model |
2513 | + } |
2514 | + |
2515 | + VisibleIndicators { |
2516 | + id: visibleIndicators |
2517 | + // TODO: This should be sourced by device type (eg "desktop", "tablet", "phone"...) |
2518 | + Component.onCompleted: initialise(indicatorProfile) |
2519 | } |
2520 | |
2521 | property bool topmostApplicationIsFullscreen: |
2522 | @@ -676,9 +687,9 @@ |
2523 | model: NotificationBackend.Model |
2524 | margin: units.gu(1) |
2525 | |
2526 | - y: panel.panelHeight |
2527 | + y: topmostIsFullscreen ? 0 : panel.panelHeight |
2528 | width: parent.width |
2529 | - height: parent.height - panel.panelHeight |
2530 | + height: parent.height - (topmostIsFullscreen ? 0 : panel.panelHeight) |
2531 | |
2532 | states: [ |
2533 | State { |
2534 | |
2535 | === modified file 'tests/autopilot/unity8/indicators/tests/test_indicators.py' |
2536 | --- tests/autopilot/unity8/indicators/tests/test_indicators.py 2014-10-09 13:57:46 +0000 |
2537 | +++ tests/autopilot/unity8/indicators/tests/test_indicators.py 2014-10-15 16:33:46 +0000 |
2538 | @@ -61,7 +61,7 @@ |
2539 | self.skipTest('Nexus 10 does not have bluetooth at the moment.') |
2540 | |
2541 | def test_indicator_exists(self): |
2542 | - self.main_window._get_indicator_widget( |
2543 | + self.main_window._get_indicator_panel_item( |
2544 | self.indicator_name |
2545 | ) |
2546 | |
2547 | |
2548 | === modified file 'tests/autopilot/unity8/shell/emulators/main_window.py' |
2549 | --- tests/autopilot/unity8/shell/emulators/main_window.py 2014-08-12 17:30:05 +0000 |
2550 | +++ tests/autopilot/unity8/shell/emulators/main_window.py 2014-10-15 16:33:46 +0000 |
2551 | @@ -75,15 +75,15 @@ |
2552 | def get_pinentryField(self): |
2553 | return self.select_single(objectName="pinentryField") |
2554 | |
2555 | - def _get_indicator_widget(self, indicator_name): |
2556 | + def _get_indicator_panel_item(self, indicator_name): |
2557 | return self.select_single( |
2558 | - 'DefaultIndicatorWidget', |
2559 | - objectName=indicator_name+'-widget' |
2560 | + 'IndicatorItem', |
2561 | + objectName=indicator_name+'-panelItem' |
2562 | ) |
2563 | |
2564 | def _get_indicator_page(self, indicator_name): |
2565 | return self.select_single( |
2566 | - 'DefaultIndicatorPage', |
2567 | + 'IndicatorPage', |
2568 | objectName=indicator_name+'-page' |
2569 | ) |
2570 | |
2571 | @@ -93,12 +93,12 @@ |
2572 | |
2573 | :returns: The indicator page. |
2574 | """ |
2575 | - widget = self._get_indicator_widget(indicator_name) |
2576 | + widget = self._get_indicator_panel_item(indicator_name) |
2577 | start_x, start_y = input.get_center_point(widget) |
2578 | end_x = start_x |
2579 | end_y = self.height |
2580 | self.pointing_device.drag(start_x, start_y, end_x, end_y) |
2581 | - self.wait_select_single('Indicators', fullyOpened=True) |
2582 | + self.wait_select_single('IndicatorsMenu', fullyOpened=True) |
2583 | return self._get_indicator_page(indicator_name) |
2584 | |
2585 | @autopilot_logging.log_action(logger.info) |
2586 | |
2587 | === modified file 'tests/mocks/Unity/Indicators/Indicators.qmltypes' |
2588 | --- tests/mocks/Unity/Indicators/Indicators.qmltypes 2014-10-15 16:33:45 +0000 |
2589 | +++ tests/mocks/Unity/Indicators/Indicators.qmltypes 2014-10-15 16:33:46 +0000 |
2590 | @@ -105,10 +105,8 @@ |
2591 | values: { |
2592 | "Identifier": 0, |
2593 | "Position": 1, |
2594 | - "WidgetSource": 2, |
2595 | - "PageSource": 3, |
2596 | - "IndicatorProperties": 4, |
2597 | - "IsVisible": 5 |
2598 | + "IndicatorProperties": 2, |
2599 | + "IsVisible": 3 |
2600 | } |
2601 | } |
2602 | } |
2603 | |
2604 | === modified file 'tests/mocks/Unity/Indicators/IndicatorsModel.qml' |
2605 | --- tests/mocks/Unity/Indicators/IndicatorsModel.qml 2014-10-15 16:33:45 +0000 |
2606 | +++ tests/mocks/Unity/Indicators/IndicatorsModel.qml 2014-10-15 16:33:46 +0000 |
2607 | @@ -38,14 +38,14 @@ |
2608 | Indicators.UnityMenuModelCache.setCachedModelData("com.canonical.indicators.fake3", |
2609 | "/com/canonical/indicators/fake3", |
2610 | "/com/canonical/indicators/fake3", |
2611 | - getUnityMenuModelData("fake-indicator-sound", |
2612 | + getUnityMenuModelData("fake-indicator-messages", |
2613 | "Messages (F)", |
2614 | "", |
2615 | [ "image://theme/messages-new" ])); |
2616 | Indicators.UnityMenuModelCache.setCachedModelData("com.canonical.indicators.fake4", |
2617 | "/com/canonical/indicators/fake4", |
2618 | "/com/canonical/indicators/fake4", |
2619 | - getUnityMenuModelData("fake-indicator-power", |
2620 | + getUnityMenuModelData("fake-indicator-sound", |
2621 | "Sound (F)", |
2622 | "", |
2623 | [ "image://theme/audio-volume-high" ])); |
2624 | @@ -56,6 +56,13 @@ |
2625 | "Battery (F)", |
2626 | "", |
2627 | [ "image://theme/battery-020" ])); |
2628 | + Indicators.UnityMenuModelCache.setCachedModelData("com.canonical.indicators.fake6", |
2629 | + "/com/canonical/indicators/fake6", |
2630 | + "/com/canonical/indicators/fake6", |
2631 | + getUnityMenuModelData("fake-indicator-datetime", |
2632 | + "Upcoming Events (F)", |
2633 | + "12:04", |
2634 | + [])); |
2635 | } |
2636 | |
2637 | function getUnityMenuModelData(identifier, title, label, icons) { |
2638 | @@ -105,9 +112,7 @@ |
2639 | |
2640 | property var originalModelData: [ |
2641 | { |
2642 | - "identifier": "indicator-fake1", |
2643 | - "widgetSource": "Indicators/DefaultIndicatorWidget.qml", |
2644 | - "pageSource": "Indicators/DefaultIndicatorPage.qml", |
2645 | + "identifier": "fake-indicator-bluetooth", |
2646 | "indicatorProperties": { |
2647 | "enabled": true, |
2648 | "busName": "com.canonical.indicators.fake1", |
2649 | @@ -116,9 +121,7 @@ |
2650 | } |
2651 | }, |
2652 | { |
2653 | - "identifier": "indicator-fake2", |
2654 | - "widgetSource": "Indicators/DefaultIndicatorWidget.qml", |
2655 | - "pageSource": "Indicators/DefaultIndicatorPage.qml", |
2656 | + "identifier": "fake-indicator-network", |
2657 | "indicatorProperties": { |
2658 | "enabled": true, |
2659 | "busName": "com.canonical.indicators.fake2", |
2660 | @@ -127,9 +130,7 @@ |
2661 | } |
2662 | }, |
2663 | { |
2664 | - "identifier": "indicator-fake3", |
2665 | - "widgetSource": "Indicators/DefaultIndicatorWidget.qml", |
2666 | - "pageSource": "Indicators/DefaultIndicatorPage.qml", |
2667 | + "identifier": "fake-indicator-messages", |
2668 | "indicatorProperties": { |
2669 | "enabled": true, |
2670 | "busName": "com.canonical.indicators.fake3", |
2671 | @@ -138,9 +139,7 @@ |
2672 | } |
2673 | }, |
2674 | { |
2675 | - "identifier": "indicator-fake4", |
2676 | - "widgetSource": "Indicators/DefaultIndicatorWidget.qml", |
2677 | - "pageSource": "Indicators/DefaultIndicatorPage.qml", |
2678 | + "identifier": "fake-indicator-sound", |
2679 | "indicatorProperties": { |
2680 | "enabled": true, |
2681 | "busName": "com.canonical.indicators.fake4", |
2682 | @@ -149,15 +148,22 @@ |
2683 | } |
2684 | }, |
2685 | { |
2686 | - "identifier": "indicator-fake5", |
2687 | - "widgetSource": "Indicators/DefaultIndicatorWidget.qml", |
2688 | - "pageSource": "Indicators/DefaultIndicatorPage.qml", |
2689 | + "identifier": "fake-indicator-power", |
2690 | "indicatorProperties": { |
2691 | "enabled": true, |
2692 | "busName": "com.canonical.indicators.fake5", |
2693 | "menuObjectPath": "/com/canonical/indicators/fake5", |
2694 | "actionsObjectPath": "/com/canonical/indicators/fake5" |
2695 | } |
2696 | + }, |
2697 | + { |
2698 | + "identifier": "fake-indicator-datetime", |
2699 | + "indicatorProperties": { |
2700 | + "enabled": true, |
2701 | + "busName": "com.canonical.indicators.fake6", |
2702 | + "menuObjectPath": "/com/canonical/indicators/fake6", |
2703 | + "actionsObjectPath": "/com/canonical/indicators/fake6" |
2704 | + } |
2705 | } |
2706 | ] |
2707 | |
2708 | |
2709 | === modified file 'tests/mocks/Unity/Indicators/fakeindicatorsmodel.cpp' |
2710 | --- tests/mocks/Unity/Indicators/fakeindicatorsmodel.cpp 2014-10-15 16:33:45 +0000 |
2711 | +++ tests/mocks/Unity/Indicators/fakeindicatorsmodel.cpp 2014-10-15 16:33:46 +0000 |
2712 | @@ -110,8 +110,6 @@ |
2713 | { |
2714 | roles[IndicatorsModelRole::Identifier] = "identifier"; |
2715 | roles[IndicatorsModelRole::Position] = "position"; |
2716 | - roles[IndicatorsModelRole::WidgetSource] = "widgetSource"; |
2717 | - roles[IndicatorsModelRole::PageSource] = "pageSource"; |
2718 | roles[IndicatorsModelRole::IndicatorProperties] = "indicatorProperties"; |
2719 | } |
2720 | return roles; |
2721 | |
2722 | === modified file 'tests/qmltests/CMakeLists.txt' |
2723 | --- tests/qmltests/CMakeLists.txt 2014-10-15 16:33:45 +0000 |
2724 | +++ tests/qmltests/CMakeLists.txt 2014-10-15 16:33:46 +0000 |
2725 | @@ -12,7 +12,6 @@ |
2726 | set(qmltest_DEFAULT_TARGETS qmlunittests) |
2727 | set(qmltest_DEFAULT_NO_ADD_TEST FALSE) |
2728 | set(qmltest_DEFAULT_PROPERTIES ENVIRONMENT "QT_QPA_PLATFORM=minimal") |
2729 | -add_qml_test(Panel IndicatorItem) |
2730 | add_qml_test(utils/Unity/Test UnityTest) |
2731 | |
2732 | set(qmltest_DEFAULT_TARGETS qmluitests) |
2733 | @@ -72,13 +71,14 @@ |
2734 | add_qml_test(Notifications Notifications) |
2735 | add_qml_test(Notifications VisualSnapDecisionsQueue) |
2736 | add_qml_test(Panel ActiveCallHint) |
2737 | -add_qml_test(Panel IndicatorRow ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/tests/mocks/QMenuModel") |
2738 | -add_qml_test(Panel Indicators ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/tests/mocks/QMenuModel") |
2739 | +add_qml_test(Panel IndicatorItem) |
2740 | +add_qml_test(Panel IndicatorItemRow ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/tests/mocks/QMenuModel") |
2741 | +add_qml_test(Panel IndicatorPage ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/tests/mocks/QMenuModel") |
2742 | +add_qml_test(Panel IndicatorsBar ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/tests/mocks/QMenuModel") |
2743 | +add_qml_test(Panel IndicatorsMenu ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/tests/mocks/QMenuModel") |
2744 | add_qml_test(Panel MenuContent ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/tests/mocks/QMenuModel") |
2745 | add_qml_test(Panel Panel ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/tests/mocks/QMenuModel") |
2746 | add_qml_test(Panel SearchIndicator) |
2747 | -add_qml_test(Panel/Indicators DefaultIndicatorWidget ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/tests/mocks/QMenuModel") |
2748 | -add_qml_test(Panel/Indicators DefaultIndicatorPage ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/tests/mocks/QMenuModel") |
2749 | # These MenuItemFactory tests need the test/mocks/ to come before plugins/ |
2750 | add_qml_test(Panel/Indicators MenuItemFactory IMPORT_PATHS ${CMAKE_BINARY_DIR}/tests/mocks ${qmltest_DEFAULT_IMPORT_PATHS}) |
2751 | add_qml_test(Panel/Indicators MessageMenuItemFactory IMPORT_PATHS ${CMAKE_BINARY_DIR}/tests/mocks ${qmltest_DEFAULT_IMPORT_PATHS}) |
2752 | |
2753 | === added file 'tests/qmltests/Panel/IndicatorTest.qml' |
2754 | --- tests/qmltests/Panel/IndicatorTest.qml 1970-01-01 00:00:00 +0000 |
2755 | +++ tests/qmltests/Panel/IndicatorTest.qml 2014-10-15 16:33:46 +0000 |
2756 | @@ -0,0 +1,67 @@ |
2757 | +/* |
2758 | + * Copyright 2014 Canonical Ltd. |
2759 | + * |
2760 | + * This program is free software; you can redistribute it and/or modify |
2761 | + * it under the terms of the GNU General Public License as published by |
2762 | + * the Free Software Foundation; version 3. |
2763 | + * |
2764 | + * This program is distributed in the hope that it will be useful, |
2765 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
2766 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
2767 | + * GNU General Public License for more details. |
2768 | + * |
2769 | + * You should have received a copy of the GNU General Public License |
2770 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
2771 | + */ |
2772 | + |
2773 | +import QtQuick 2.1 |
2774 | +import QtQuick.Layouts 1.1 |
2775 | +import QtTest 1.0 |
2776 | +import "../../../qml/Panel" |
2777 | +import Ubuntu.Components 0.1 |
2778 | +import Unity.Test 0.1 as UT |
2779 | +import Unity.Indicators 0.1 as Indicators |
2780 | + |
2781 | +Rectangle { |
2782 | + id: root |
2783 | + color: "white" |
2784 | + |
2785 | + property alias indicatorsModel: __indicatorsModel |
2786 | + Indicators.IndicatorsModel { |
2787 | + id: __indicatorsModel |
2788 | + Component.onCompleted: load() |
2789 | + } |
2790 | + |
2791 | + function insertIndicator(index) { |
2792 | + var i; |
2793 | + var insertIndex = 0; |
2794 | + var done = false; |
2795 | + for (i = index; !done && i >= 1; i--) { |
2796 | + |
2797 | + var lookFor = indicatorsModel.originalModelData[i-1]["identifier"] |
2798 | + |
2799 | + var j; |
2800 | + for (j = indicatorsModel.modelData.length-1; !done && j >= 0; j--) { |
2801 | + if (indicatorsModel.modelData[j]["identifier"] === lookFor) { |
2802 | + insertIndex = j+1; |
2803 | + done = true; |
2804 | + } |
2805 | + } |
2806 | + } |
2807 | + indicatorsModel.insert(insertIndex, indicatorsModel.originalModelData[index]); |
2808 | + } |
2809 | + |
2810 | + function removeIndicator(index) { |
2811 | + var i; |
2812 | + for (i = 0; i < indicatorsModel.modelData.length; i++) { |
2813 | + if (indicatorsModel.modelData[i]["identifier"] === indicatorsModel.originalModelData[index]["identifier"]) { |
2814 | + indicatorsModel.remove(i); |
2815 | + break; |
2816 | + } |
2817 | + } |
2818 | + } |
2819 | + |
2820 | + function resetData() { |
2821 | + indicatorsModel.load(); |
2822 | + } |
2823 | +} |
2824 | |
2825 | === removed file 'tests/qmltests/Panel/Indicators/tst_DefaultIndicatorWidget.qml' |
2826 | --- tests/qmltests/Panel/Indicators/tst_DefaultIndicatorWidget.qml 2014-10-15 16:33:45 +0000 |
2827 | +++ tests/qmltests/Panel/Indicators/tst_DefaultIndicatorWidget.qml 1970-01-01 00:00:00 +0000 |
2828 | @@ -1,52 +0,0 @@ |
2829 | -/* |
2830 | - * Copyright 2013 Canonical Ltd. |
2831 | - * |
2832 | - * This program is free software; you can redistribute it and/or modify |
2833 | - * it under the terms of the GNU General Public License as published by |
2834 | - * the Free Software Foundation; version 3. |
2835 | - * |
2836 | - * This program is distributed in the hope that it will be useful, |
2837 | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
2838 | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
2839 | - * GNU General Public License for more details. |
2840 | - * |
2841 | - * You should have received a copy of the GNU General Public License |
2842 | - * along with this program. If not, see <http://www.gnu.org/licenses/>. |
2843 | - */ |
2844 | - |
2845 | -import QtQuick 2.0 |
2846 | -import QtTest 1.0 |
2847 | -import Unity.Test 0.1 as UT |
2848 | -import QMenuModel 0.1 |
2849 | -import "../../../../qml/Panel/Indicators" |
2850 | - |
2851 | -Item { |
2852 | - id: testView |
2853 | - width: units.gu(40) |
2854 | - height: units.gu(70) |
2855 | - |
2856 | - DefaultIndicatorWidget { |
2857 | - id: widget |
2858 | - |
2859 | - anchors { |
2860 | - left: parent.left |
2861 | - top: parent.top |
2862 | - } |
2863 | - |
2864 | - busName: "test" |
2865 | - actionsObjectPath: "test" |
2866 | - deviceMenuObjectPath: "test" |
2867 | - |
2868 | - rootMenuType: "" |
2869 | - |
2870 | - iconSize: units.gu(3.2) |
2871 | - height: units.gu(3) |
2872 | - } |
2873 | - |
2874 | - UT.UnityTestCase { |
2875 | - name: "DefaultIndicatorWidget" |
2876 | - when: windowShown |
2877 | - |
2878 | - // FIXME: add tests |
2879 | - } |
2880 | -} |
2881 | |
2882 | === modified file 'tests/qmltests/Panel/tst_ActiveCallHint.qml' |
2883 | --- tests/qmltests/Panel/tst_ActiveCallHint.qml 2014-09-11 14:53:35 +0000 |
2884 | +++ tests/qmltests/Panel/tst_ActiveCallHint.qml 2014-10-15 16:33:46 +0000 |
2885 | @@ -19,7 +19,6 @@ |
2886 | import Unity.Test 0.1 as UT |
2887 | import Ubuntu.Telephony 0.1 as Telephony |
2888 | import Unity.Application 0.1 |
2889 | -import ".." |
2890 | import "../../../qml/Panel" |
2891 | |
2892 | Item { |
2893 | |
2894 | === added file 'tests/qmltests/Panel/tst_IndicatorItem.qml' |
2895 | --- tests/qmltests/Panel/tst_IndicatorItem.qml 1970-01-01 00:00:00 +0000 |
2896 | +++ tests/qmltests/Panel/tst_IndicatorItem.qml 2014-10-15 16:33:46 +0000 |
2897 | @@ -0,0 +1,205 @@ |
2898 | +/* |
2899 | + * Copyright 2013-2014 Canonical Ltd. |
2900 | + * |
2901 | + * This program is free software; you can redistribute it and/or modify |
2902 | + * it under the terms of the GNU General Public License as published by |
2903 | + * the Free Software Foundation; version 3. |
2904 | + * |
2905 | + * This program is distributed in the hope that it will be useful, |
2906 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
2907 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
2908 | + * GNU General Public License for more details. |
2909 | + * |
2910 | + * You should have received a copy of the GNU General Public License |
2911 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
2912 | + */ |
2913 | + |
2914 | +import QtQuick 2.1 |
2915 | +import QtQuick.Layouts 1.1 |
2916 | +import QtTest 1.0 |
2917 | +import Ubuntu.Components 0.1 |
2918 | +import Unity.Test 0.1 as UT |
2919 | +import "../../../qml/Panel" |
2920 | + |
2921 | +Rectangle { |
2922 | + width: units.gu(80) |
2923 | + height: units.gu(30) |
2924 | + color: "white" |
2925 | + |
2926 | + RowLayout { |
2927 | + anchors.fill: parent |
2928 | + anchors.margins: units.gu(1) |
2929 | + |
2930 | + Rectangle { |
2931 | + id: itemArea |
2932 | + color: "blue" |
2933 | + Layout.fillWidth: true |
2934 | + Layout.fillHeight: true |
2935 | + |
2936 | + Rectangle { |
2937 | + color: "black" |
2938 | + anchors.fill: indicatorItem |
2939 | + } |
2940 | + |
2941 | + IndicatorItem { |
2942 | + id: indicatorItem |
2943 | + height: expanded ? units.gu(7) : units.gu(3) |
2944 | + anchors.centerIn: parent |
2945 | + identifier: "indicator-test" |
2946 | + |
2947 | + rootActionState { |
2948 | + title: titleLabel.text |
2949 | + leftLabel : leftLabel.text |
2950 | + rightLabel : rightLabel.text |
2951 | + icons : { |
2952 | + var icons = []; |
2953 | + var i = 0; |
2954 | + if (iconEnabled.checked) { |
2955 | + for (i = 0; i < String(iconCount.text); i++) { |
2956 | + icons.push("image://theme/audio-volume-high"); |
2957 | + } |
2958 | + } |
2959 | + return icons; |
2960 | + } |
2961 | + } |
2962 | + |
2963 | + Behavior on height { |
2964 | + NumberAnimation { |
2965 | + id: heightAnimation |
2966 | + duration: UbuntuAnimation.SnapDuration; easing: UbuntuAnimation.StandardEasing |
2967 | + } |
2968 | + } |
2969 | + } |
2970 | + } |
2971 | + |
2972 | + ColumnLayout { |
2973 | + Layout.alignment: Qt.AlignTop |
2974 | + Layout.fillWidth: false |
2975 | + |
2976 | + Button { |
2977 | + id: expandButton |
2978 | + Layout.fillWidth: true |
2979 | + text: indicatorItem.expanded ? "Collapse" : "Expand" |
2980 | + onClicked: indicatorItem.expanded = !indicatorItem.expanded |
2981 | + } |
2982 | + |
2983 | + Button { |
2984 | + id: selectButton |
2985 | + Layout.fillWidth: true |
2986 | + text: indicatorItem.selected ? "Unselect" : "Select" |
2987 | + onClicked: indicatorItem.selected = !indicatorItem.selected |
2988 | + } |
2989 | + |
2990 | + Rectangle { |
2991 | + Layout.preferredHeight: units.dp(1); |
2992 | + Layout.fillWidth: true; |
2993 | + color: "black" |
2994 | + } |
2995 | + |
2996 | + RowLayout { |
2997 | + CheckBox { id: iconEnabled; checked: true } |
2998 | + Label { text: "icons Count:" } |
2999 | + TextField { id: iconCount; text: "1"; enabled: iconEnabled.checked } |
3000 | + } |
3001 | + |
3002 | + RowLayout { |
3003 | + Label { text: "Left Label:" } |
3004 | + TextField { id: leftLabel; text: "Left"} |
3005 | + } |
3006 | + |
3007 | + RowLayout { |
3008 | + Label { text: "Right Label:" } |
3009 | + TextField { id: rightLabel; text: "Right"} |
3010 | + } |
3011 | + |
3012 | + RowLayout { |
3013 | + Label { text: "Title:" } |
3014 | + TextField { id: titleLabel; text: "Title"} |
3015 | + } |
3016 | + } |
3017 | + } |
3018 | + |
3019 | + UT.UnityTestCase { |
3020 | + name: "IndicatorItem" |
3021 | + when: windowShown |
3022 | + |
3023 | + function init() { |
3024 | + indicatorItem.selected = false; |
3025 | + indicatorItem.expanded = false; |
3026 | + indicatorItem.rootActionState.title = "Test Title"; |
3027 | + indicatorItem.rootActionState.leftLabel = "TestLeftLabel"; |
3028 | + indicatorItem.rootActionState.rightLabel = "TestRightLabel"; |
3029 | + indicatorItem.rootActionState.icons = [ "image://theme/audio-volume-high" ]; |
3030 | + |
3031 | + tryCompare(heightAnimation, "running", false); |
3032 | + } |
3033 | + |
3034 | + function test_expand() { |
3035 | + indicatorItem.expanded = true; |
3036 | + tryCompare(indicatorItem, "height", units.gu(7)); |
3037 | + indicatorItem.expanded = false; |
3038 | + tryCompare(indicatorItem, "height", units.gu(3)); |
3039 | + } |
3040 | + |
3041 | + function test_minimizedVisibility() { |
3042 | + compare(findChild(indicatorItem, "leftLabel").opacity, 1.0); |
3043 | + compare(findChild(indicatorItem, "rightLabel").opacity, 1.0); |
3044 | + compare(findChild(indicatorItem, "icons").opacity, 1.0); |
3045 | + compare(findChild(indicatorItem, "indicatorName").opacity, 0.0); |
3046 | + } |
3047 | + |
3048 | + function test_expandIcon() { |
3049 | + indicatorItem.expanded = true; |
3050 | + |
3051 | + tryCompare(findChild(indicatorItem, "leftLabel"), "opacity", 0.0); |
3052 | + tryCompare(findChild(indicatorItem, "rightLabel"), "opacity", 0.0); |
3053 | + tryCompare(findChild(indicatorItem, "icons"), "opacity", 1.0); |
3054 | + tryCompare(findChild(indicatorItem, "indicatorName"), "opacity", 1.0); |
3055 | + } |
3056 | + |
3057 | + function test_expandRightLabel() { |
3058 | + indicatorItem.expanded = true; |
3059 | + |
3060 | + indicatorItem.rootActionState.icons = []; |
3061 | + |
3062 | + tryCompare(findChild(indicatorItem, "leftLabel"), "opacity", 0.0); |
3063 | + tryCompare(findChild(indicatorItem, "rightLabel"), "opacity", 1.0); |
3064 | + tryCompare(findChild(indicatorItem, "icons"), "opacity", 0.0); |
3065 | + tryCompare(findChild(indicatorItem, "indicatorName"), "opacity", 1.0); |
3066 | + } |
3067 | + |
3068 | + function test_expandLeftLabel() { |
3069 | + indicatorItem.expanded = true; |
3070 | + |
3071 | + indicatorItem.rootActionState.rightLabel = ""; |
3072 | + indicatorItem.rootActionState.icons = []; |
3073 | + |
3074 | + tryCompare(findChild(indicatorItem, "rightLabel"), "opacity", 0.0); |
3075 | + tryCompare(findChild(indicatorItem, "leftLabel"), "opacity", 1.0); |
3076 | + tryCompare(findChild(indicatorItem, "icons"), "opacity", 0.0); |
3077 | + tryCompare(findChild(indicatorItem, "indicatorName"), "opacity", 1.0); |
3078 | + } |
3079 | + |
3080 | + function test_select() { |
3081 | + tryCompare(findChild(indicatorItem, "icon0"), "color", "#ededed"); |
3082 | + tryCompare(findChild(indicatorItem, "icon0"), "opacity", 1.0); |
3083 | + tryCompare(findChild(indicatorItem, "leftLabel"), "color", "#ededed"); |
3084 | + tryCompare(findChild(indicatorItem, "rightLabel"), "color", "#ededed"); |
3085 | + tryCompare(findChild(indicatorItem, "indicatorName"), "color", "#ededed"); |
3086 | + |
3087 | + indicatorItem.expanded = true; |
3088 | + tryCompare(findChild(indicatorItem, "icon0"), "color", "#4c4c4c"); |
3089 | + tryCompare(findChild(indicatorItem, "icon0"), "opacity", 0.6); |
3090 | + tryCompare(findChild(indicatorItem, "leftLabel"), "color", "#4c4c4c"); |
3091 | + tryCompare(findChild(indicatorItem, "rightLabel"), "color", "#4c4c4c"); |
3092 | + tryCompare(findChild(indicatorItem, "indicatorName"), "color", "#4c4c4c"); |
3093 | + |
3094 | + indicatorItem.selected = true; |
3095 | + tryCompare(findChild(indicatorItem, "icon0"), "color", "#ededed"); |
3096 | + tryCompare(findChild(indicatorItem, "icon0"), "opacity", 1.0); |
3097 | + tryCompare(findChild(indicatorItem, "leftLabel"), "color", "#ededed"); |
3098 | + tryCompare(findChild(indicatorItem, "rightLabel"), "color", "#ededed"); |
3099 | + tryCompare(findChild(indicatorItem, "indicatorName"), "color", "#ededed"); |
3100 | + } |
3101 | + } |
3102 | +} |
3103 | |
3104 | === removed file 'tests/qmltests/Panel/tst_IndicatorItem.qml' |
3105 | --- tests/qmltests/Panel/tst_IndicatorItem.qml 2014-10-15 16:33:45 +0000 |
3106 | +++ tests/qmltests/Panel/tst_IndicatorItem.qml 1970-01-01 00:00:00 +0000 |
3107 | @@ -1,50 +0,0 @@ |
3108 | -/* |
3109 | - * Copyright 2013 Canonical Ltd. |
3110 | - * |
3111 | - * This program is free software; you can redistribute it and/or modify |
3112 | - * it under the terms of the GNU General Public License as published by |
3113 | - * the Free Software Foundation; version 3. |
3114 | - * |
3115 | - * This program is distributed in the hope that it will be useful, |
3116 | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
3117 | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
3118 | - * GNU General Public License for more details. |
3119 | - * |
3120 | - * You should have received a copy of the GNU General Public License |
3121 | - * along with this program. If not, see <http://www.gnu.org/licenses/>. |
3122 | - */ |
3123 | - |
3124 | -import QtQuick 2.0 |
3125 | -import QtTest 1.0 |
3126 | -import ".." |
3127 | -import "../../../qml/Panel" |
3128 | -import Ubuntu.Components 0.1 |
3129 | -import Unity.Test 0.1 as UT |
3130 | - |
3131 | -Rectangle { |
3132 | - width: units.gu(10) |
3133 | - height: units.gu(5) |
3134 | - color: "black" |
3135 | - |
3136 | - IndicatorItem { |
3137 | - id: indicatorItem |
3138 | - anchors.fill: parent |
3139 | - } |
3140 | - |
3141 | - UT.UnityTestCase { |
3142 | - name: "IndicatorItem" |
3143 | - |
3144 | - function test_dimmed() { |
3145 | - indicatorItem.dimmed = false; |
3146 | - tryCompareFunction(function(){return indicatorItem.opacity}, 1.0); |
3147 | - indicatorItem.dimmed = true; |
3148 | - tryCompareFunction(function(){return indicatorItem.opacity < 1.0}, true); |
3149 | - } |
3150 | - |
3151 | - function test_empty() { |
3152 | - compare(indicatorItem.indicatorVisible, false, "IndicatorItem should not be visible."); |
3153 | - indicatorItem.widgetSource = "../../../qml/Panel/Indicators/DefaultIndicatorWidget.qml"; |
3154 | - tryCompare(indicatorItem, "indicatorVisible", true); |
3155 | - } |
3156 | - } |
3157 | -} |
3158 | |
3159 | === added file 'tests/qmltests/Panel/tst_IndicatorItemRow.qml' |
3160 | --- tests/qmltests/Panel/tst_IndicatorItemRow.qml 1970-01-01 00:00:00 +0000 |
3161 | +++ tests/qmltests/Panel/tst_IndicatorItemRow.qml 2014-10-15 16:33:46 +0000 |
3162 | @@ -0,0 +1,279 @@ |
3163 | +/* |
3164 | + * Copyright 2013-2014 Canonical Ltd. |
3165 | + * |
3166 | + * This program is free software; you can redistribute it and/or modify |
3167 | + * it under the terms of the GNU General Public License as published by |
3168 | + * the Free Software Foundation; version 3. |
3169 | + * |
3170 | + * This program is distributed in the hope that it will be useful, |
3171 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
3172 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
3173 | + * GNU General Public License for more details. |
3174 | + * |
3175 | + * You should have received a copy of the GNU General Public License |
3176 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
3177 | + */ |
3178 | + |
3179 | +import QtQuick 2.1 |
3180 | +import QtQuick.Layouts 1.1 |
3181 | +import QtTest 1.0 |
3182 | +import "../../../qml/Panel" |
3183 | +import Ubuntu.Components 0.1 |
3184 | +import Unity.Test 0.1 as UT |
3185 | +import Unity.Indicators 0.1 as Indicators |
3186 | + |
3187 | +IndicatorTest { |
3188 | + id: root |
3189 | + width: units.gu(100) |
3190 | + height: units.gu(40) |
3191 | + color: "white" |
3192 | + |
3193 | + RowLayout { |
3194 | + anchors.fill: parent |
3195 | + anchors.margins: units.gu(1) |
3196 | + |
3197 | + Rectangle { |
3198 | + Layout.fillWidth: true |
3199 | + Layout.fillHeight: true |
3200 | + |
3201 | + id: itemArea |
3202 | + color: "blue" |
3203 | + |
3204 | + Rectangle { |
3205 | + color: "black" |
3206 | + anchors.fill: indicatorsRow |
3207 | + } |
3208 | + |
3209 | + IndicatorItemRow { |
3210 | + id: indicatorsRow |
3211 | + height: expanded ? units.gu(7) : units.gu(3) |
3212 | + anchors.centerIn: parent |
3213 | + indicatorsModel: root.indicatorsModel |
3214 | + enableLateralChanges: ma.pressed |
3215 | + |
3216 | + Behavior on height { |
3217 | + NumberAnimation { |
3218 | + id: heightAnimation |
3219 | + duration: UbuntuAnimation.SnapDuration; easing: UbuntuAnimation.StandardEasing |
3220 | + } |
3221 | + } |
3222 | + |
3223 | + MouseArea { |
3224 | + id: ma |
3225 | + anchors.fill: parent |
3226 | + onPositionChanged: { |
3227 | + indicatorsRow.lateralPosition = mouse.x; |
3228 | + } |
3229 | + onPressed: { |
3230 | + if (pressed) { |
3231 | + indicatorsRow.lateralPosition = mouse.x; |
3232 | + indicatorsRow.selectItemAt(mouse.x); |
3233 | + } |
3234 | + } |
3235 | + } |
3236 | + } |
3237 | + } |
3238 | + |
3239 | + ColumnLayout { |
3240 | + Layout.alignment: Qt.AlignTop |
3241 | + Layout.fillWidth: false |
3242 | + |
3243 | + Button { |
3244 | + Layout.fillWidth: true |
3245 | + text: indicatorsRow.expanded ? "Collapse" : "Expand" |
3246 | + onClicked: indicatorsRow.expanded = !indicatorsRow.expanded |
3247 | + } |
3248 | + |
3249 | + Rectangle { |
3250 | + Layout.preferredHeight: units.dp(1); |
3251 | + Layout.fillWidth: true; |
3252 | + color: "black" |
3253 | + } |
3254 | + |
3255 | + Repeater { |
3256 | + model: indicatorsModel.originalModelData |
3257 | + RowLayout { |
3258 | + CheckBox { |
3259 | + checked: true |
3260 | + onCheckedChanged: checked ? insertIndicator(index) : removeIndicator(index); |
3261 | + } |
3262 | + Label { text: modelData["identifier"] } |
3263 | + } |
3264 | + } |
3265 | + } |
3266 | + } |
3267 | + |
3268 | + UT.UnityTestCase { |
3269 | + name: "IndicatorItemRow" |
3270 | + when: windowShown |
3271 | + |
3272 | + function init() { |
3273 | + root.resetData(); |
3274 | + |
3275 | + indicatorsRow.resetCurrentItem(); |
3276 | + indicatorsRow.lateralPosition = -1; |
3277 | + |
3278 | + indicatorsRow.expanded = false; |
3279 | + tryCompare(heightAnimation, "running", false); |
3280 | + tryCompare(findChild(indicatorsRow, "highlight"), "highlightCenterOffset", 0); |
3281 | + wait(1); // row seems to take a bit of time for item x values to update. |
3282 | + } |
3283 | + |
3284 | + function wait_for_expansion_to_settle() { |
3285 | + tryCompare(heightAnimation, "running", false); |
3286 | + wait(200); // put a little extra wait in for things to settle |
3287 | + } |
3288 | + |
3289 | + function test_indicatorRowChanges_data() { |
3290 | + return [ |
3291 | + { remove: [0, 2] }, |
3292 | + { remove: [0, 1, 2, 3, 4] }, |
3293 | + ]; |
3294 | + } |
3295 | + |
3296 | + // test the changes in the available indicators updates the |
3297 | + // indicators that are visible. |
3298 | + function test_indicatorRowChanges(data) { |
3299 | + var i; |
3300 | + var item; |
3301 | + var itemsToRemove = [0, 2]; |
3302 | + |
3303 | + verify(indicatorsModel.originalModelData.length > 0); |
3304 | + for (i = 0; i < indicatorsModel.originalModelData.length; i++) { |
3305 | + item = findChild(indicatorsRow, indicatorsModel.originalModelData[i]["identifier"] + "-panelItem"); |
3306 | + verify(item); |
3307 | + |
3308 | + compare(item.ownIndex, i, "Item at incorrect index"); |
3309 | + } |
3310 | + |
3311 | + for (i = data.remove.length-1; i >= 0; i--) { |
3312 | + removeIndicator(data.remove[i]); |
3313 | + } |
3314 | + |
3315 | + // test removals |
3316 | + for (i = 0; i < indicatorsModel.originalModelData.length; i++) { |
3317 | + item = findChild(indicatorsRow, indicatorsModel.originalModelData[i]["identifier"] + "-panelItem"); |
3318 | + |
3319 | + verify(data.remove.indexOf(i) !== -1 ? (item === null) : (item !== null)); |
3320 | + } |
3321 | + |
3322 | + // test insertion |
3323 | + for (i = 0; i < data.remove.length; i++) { |
3324 | + insertIndicator(data.remove[i]); |
3325 | + } |
3326 | + |
3327 | + for (i = 0; i < indicatorsModel.originalModelData.length; i++) { |
3328 | + item = findChild(indicatorsRow, indicatorsModel.originalModelData[i]["identifier"] + "-panelItem"); |
3329 | + verify(item); |
3330 | + |
3331 | + compare(item.ownIndex, i, "Item at incorrect index"); |
3332 | + } |
3333 | + } |
3334 | + |
3335 | + function test_validCurrentItem_data() { |
3336 | + return [ |
3337 | + { index: 0 }, |
3338 | + { index: 2 }, |
3339 | + { index: 4 } |
3340 | + ]; |
3341 | + } |
3342 | + |
3343 | + // test selecting the item at it's position sets the current item of the row. |
3344 | + function test_validCurrentItem(data) { |
3345 | + var dataItem = findChild(indicatorsRow, indicatorsModel.originalModelData[data.index]["identifier"] + "-panelItem"); |
3346 | + verify(dataItem !== null); |
3347 | + |
3348 | + indicatorsRow.selectItemAt(dataItem.x + dataItem.width/2); |
3349 | + compare(indicatorsRow.currentItem, dataItem); |
3350 | + } |
3351 | + |
3352 | + // tests item default selection (no item at position X) |
3353 | + function test_invalidCurrentItem() { |
3354 | + indicatorsRow.selectItemAt(-100); |
3355 | + var item = findChild(indicatorsRow, indicatorsModel.originalModelData[0]["identifier"] + "-panelItem"); |
3356 | + compare(indicatorsRow.currentItem, item); |
3357 | + } |
3358 | + |
3359 | + // testing that changing the lateral position offset of the row changes the current item. |
3360 | + function test_lateralPositionChangesCurrentItem_data() { |
3361 | + return [ |
3362 | + { tag: "0 -> 4", from: 0, to: 4 }, |
3363 | + { tag: "3 -> 1", from: 3, to: 1 } |
3364 | + ]; |
3365 | + } |
3366 | + |
3367 | + function test_lateralPositionChangesCurrentItem(data) { |
3368 | + indicatorsRow.expanded = true; |
3369 | + wait_for_expansion_to_settle(); |
3370 | + |
3371 | + var fromItem = findChild(indicatorsRow, indicatorsModel.originalModelData[data.from]["identifier"] + "-panelItem"); |
3372 | + verify(fromItem !== null); |
3373 | + |
3374 | + var toItem = findChild(indicatorsRow, indicatorsModel.originalModelData[data.to]["identifier"] + "-panelItem"); |
3375 | + verify(toItem !== null); |
3376 | + |
3377 | + var fromPosition = indicatorsRow.mapFromItem(fromItem, fromItem.width/2, fromItem.height/2); |
3378 | + var toPosition = indicatorsRow.mapFromItem(toItem, toItem.width/2, toItem.height/2); |
3379 | + |
3380 | + mousePress(indicatorsRow, fromPosition.x, fromPosition.y); |
3381 | + compare(indicatorsRow.currentItem, fromItem, "Initial item not selected"); |
3382 | + |
3383 | + // this uses the MouseArea above to change the indicatorRow lateralPosition |
3384 | + mouseFlick(indicatorsRow, fromPosition.x, fromPosition.y, toPosition.x, toPosition.y, false, false, units.gu(5), 30); |
3385 | + |
3386 | + mouseRelease(indicatorsRow, fromPosition.x, fromPosition.y); |
3387 | + compare(indicatorsRow.currentItem, toItem, "Current item did not change to expected item"); |
3388 | + } |
3389 | + |
3390 | + // testing that positive changes to the lateral position offset shifts the highlight offset to the right |
3391 | + function test_positiveLateralPositionChangesHighlightOffset() { |
3392 | + indicatorsRow.expanded = true; |
3393 | + wait_for_expansion_to_settle(); |
3394 | + |
3395 | + var highlight = findChild(indicatorsRow, "highlight"); |
3396 | + var item = findChild(indicatorsRow, indicatorsModel.originalModelData[2]["identifier"] + "-panelItem"); |
3397 | + verify(item !== null); |
3398 | + var mappedPosition = indicatorsRow.mapFromItem(item, item.width/2, item.height/2); |
3399 | + |
3400 | + mousePress(indicatorsRow, mappedPosition.x, mappedPosition.y); |
3401 | + var originalHightlightX = highlight.x; |
3402 | + var offset = 1; |
3403 | + while((highlight.x - originalHightlightX) <= units.gu(0.5) && offset < units.gu(10)) { |
3404 | + mouseMove(indicatorsRow, mappedPosition.x + offset, mappedPosition.y, 10); |
3405 | + offset = offset + 2; |
3406 | + } |
3407 | + // verify that we hit the offset |
3408 | + verify((highlight.x - originalHightlightX) >= units.gu(0.5)); |
3409 | + mouseRelease(indicatorsRow); |
3410 | + |
3411 | + // should go back to 0 |
3412 | + tryCompare(highlight, "highlightCenterOffset", 0); |
3413 | + } |
3414 | + |
3415 | + // testing that negative changes to the lateral position offset shifts the highlight offset to the left |
3416 | + function test_negativeLateralPositionChangesHighlightOffset() { |
3417 | + indicatorsRow.expanded = true; |
3418 | + wait_for_expansion_to_settle(); |
3419 | + |
3420 | + var highlight = findChild(indicatorsRow, "highlight"); |
3421 | + var item = findChild(indicatorsRow, indicatorsModel.originalModelData[2]["identifier"] + "-panelItem"); |
3422 | + verify(item !== null); |
3423 | + var mappedPosition = indicatorsRow.mapFromItem(item, item.width/2, item.height/2); |
3424 | + |
3425 | + mousePress(indicatorsRow, mappedPosition.x, mappedPosition.y); |
3426 | + var originalHightlightX = highlight.x; |
3427 | + var offset = 1; |
3428 | + while((highlight.x - originalHightlightX) >= -units.gu(0.5) && offset < units.gu(10)) { |
3429 | + mouseMove(indicatorsRow, mappedPosition.x - offset, mappedPosition.y, 10); |
3430 | + offset = offset + 2; |
3431 | + } |
3432 | + |
3433 | + // verify that we hit the offset |
3434 | + verify((highlight.x - originalHightlightX) <= -units.gu(0.5)); |
3435 | + mouseRelease(indicatorsRow); |
3436 | + |
3437 | + // should go back to 0 |
3438 | + tryCompare(findChild(indicatorsRow, "highlight"), "highlightCenterOffset", 0); |
3439 | + } |
3440 | + } |
3441 | +} |
3442 | |
3443 | === renamed file 'tests/qmltests/Panel/Indicators/tst_DefaultIndicatorPage.qml' => 'tests/qmltests/Panel/tst_IndicatorPage.qml' |
3444 | --- tests/qmltests/Panel/Indicators/tst_DefaultIndicatorPage.qml 2014-10-15 16:33:45 +0000 |
3445 | +++ tests/qmltests/Panel/tst_IndicatorPage.qml 2014-10-15 16:33:46 +0000 |
3446 | @@ -1,5 +1,5 @@ |
3447 | /* |
3448 | - * Copyright 2013 Canonical Ltd. |
3449 | + * Copyright 2013-2014 Canonical Ltd. |
3450 | * |
3451 | * This program is free software; you can redistribute it and/or modify |
3452 | * it under the terms of the GNU General Public License as published by |
3453 | @@ -18,14 +18,14 @@ |
3454 | import QtTest 1.0 |
3455 | import Unity.Test 0.1 as UT |
3456 | import Unity.Indicators 0.1 as Indicators |
3457 | -import "../../../../qml/Panel/Indicators" |
3458 | +import "../../../qml/Panel" |
3459 | |
3460 | Item { |
3461 | id: testView |
3462 | width: units.gu(40) |
3463 | height: units.gu(70) |
3464 | |
3465 | - DefaultIndicatorPage { |
3466 | + IndicatorPage { |
3467 | id: page |
3468 | anchors.fill: parent |
3469 | |
3470 | @@ -117,7 +117,7 @@ |
3471 | } |
3472 | |
3473 | UT.UnityTestCase { |
3474 | - name: "DefaultIndicatorPage" |
3475 | + name: "IndicatorPage" |
3476 | |
3477 | function init() { |
3478 | initializeMenuData([]); |
3479 | |
3480 | === removed file 'tests/qmltests/Panel/tst_IndicatorRow.qml' |
3481 | --- tests/qmltests/Panel/tst_IndicatorRow.qml 2014-10-15 16:33:45 +0000 |
3482 | +++ tests/qmltests/Panel/tst_IndicatorRow.qml 1970-01-01 00:00:00 +0000 |
3483 | @@ -1,158 +0,0 @@ |
3484 | -/* |
3485 | - * Copyright 2013 Canonical Ltd. |
3486 | - * |
3487 | - * This program is free software; you can redistribute it and/or modify |
3488 | - * it under the terms of the GNU General Public License as published by |
3489 | - * the Free Software Foundation; version 3. |
3490 | - * |
3491 | - * This program is distributed in the hope that it will be useful, |
3492 | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
3493 | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
3494 | - * GNU General Public License for more details. |
3495 | - * |
3496 | - * You should have received a copy of the GNU General Public License |
3497 | - * along with this program. If not, see <http://www.gnu.org/licenses/>. |
3498 | - */ |
3499 | - |
3500 | -import QtQuick 2.0 |
3501 | -import QtTest 1.0 |
3502 | -import Unity.Test 0.1 as UT |
3503 | -import ".." |
3504 | -import "../../../qml/Panel" |
3505 | -import Unity.Indicators 0.1 as Indicators |
3506 | - |
3507 | -/* |
3508 | - This tests the IndicatorRow component by using a fake model to stage data in the indicators |
3509 | - A view will show with indicators at the top, as does in the shell. |
3510 | -*/ |
3511 | -Item { |
3512 | - id: rootItem |
3513 | - width: units.gu(40) |
3514 | - height: units.gu(60) |
3515 | - |
3516 | - PanelBackground { |
3517 | - anchors.fill: indicatorRow |
3518 | - } |
3519 | - |
3520 | - IndicatorRow { |
3521 | - id: indicatorRow |
3522 | - anchors { |
3523 | - left: parent.left |
3524 | - right: parent.right |
3525 | - } |
3526 | - |
3527 | - indicatorsModel: indicatorModel |
3528 | - |
3529 | - Component.onCompleted: indicatorModel.load("test1") |
3530 | - } |
3531 | - |
3532 | - Indicators.IndicatorsModel { |
3533 | - id: indicatorModel |
3534 | - } |
3535 | - |
3536 | - UT.UnityTestCase { |
3537 | - name: "IndicatorRow" |
3538 | - when: windowShown |
3539 | - |
3540 | - function init() { |
3541 | - indicatorModel.load("test1"); |
3542 | - |
3543 | - indicatorRow.state = "initial"; |
3544 | - indicatorRow.setCurrentItemIndex(-1); |
3545 | - indicatorRow.unitProgress = 0.0; |
3546 | - } |
3547 | - |
3548 | - function get_indicator_item(index) { |
3549 | - return findChild(indicatorRow.row, "item" + index); |
3550 | - } |
3551 | - |
3552 | - function test_set_current_item() { |
3553 | - indicatorRow.setCurrentItemIndex(0); |
3554 | - compare(indicatorRow.indicatorsModel.data(indicatorRow.currentItemIndex, Indicators.IndicatorsModelRole.Identifier), |
3555 | - "indicator-fake1", |
3556 | - "Incorrect item at position 0"); |
3557 | - |
3558 | - indicatorRow.setCurrentItemIndex(1); |
3559 | - compare(indicatorRow.indicatorsModel.data(indicatorRow.currentItemIndex, Indicators.IndicatorsModelRole.Identifier), |
3560 | - "indicator-fake2", |
3561 | - "Incorrect item at position 1"); |
3562 | - |
3563 | - indicatorRow.setCurrentItemIndex(2); |
3564 | - compare(indicatorRow.indicatorsModel.data(indicatorRow.currentItemIndex, Indicators.IndicatorsModelRole.Identifier), |
3565 | - "indicator-fake3", |
3566 | - "Incorrect item at position 2"); |
3567 | - } |
3568 | - |
3569 | - function test_highlight_data() { |
3570 | - return [ |
3571 | - { index: 0, progress: 0.0, current: false, other: false }, |
3572 | - { index: 0, progress: 0.1, current: true, other: false }, |
3573 | - { index: 0, progress: 0.5, current: true, other: false }, |
3574 | - { index: 0, progress: 1.0, current: true, other: false }, |
3575 | - { index: 2, progress: 0.0, current: false, other: false }, |
3576 | - { index: 2, progress: 0.1, current: true, other: false }, |
3577 | - { index: 2, progress: 0.5, current: true, other: false }, |
3578 | - { index: 2, progress: 1.0, current: true, other: false } |
3579 | - ]; |
3580 | - } |
3581 | - |
3582 | - function test_highlight(data) { |
3583 | - indicatorRow.unitProgress = data.progress; |
3584 | - indicatorRow.setCurrentItemIndex(data.index); |
3585 | - |
3586 | - compare(indicatorRow.currentItem.highlighted, data.current, "Indicator hightlight did not match for current item"); |
3587 | - |
3588 | - for (var i = 0; i < indicatorRow.row.count; i++) { |
3589 | - compare(get_indicator_item(i).highlighted, i === data.index ? data.current: data.other, "Indicator hightlight did not match for item iter"); |
3590 | - } |
3591 | - } |
3592 | - |
3593 | - function test_opacity_data() { |
3594 | - return [ |
3595 | - { index: 0, progress: 0.0, current: 1.0, other: 1.0 }, |
3596 | - { index: 0, progress: 0.1, current: 1.0, other: 0.9 }, |
3597 | - { index: 0, progress: 0.5, current: 1.0, other: 0.5 }, |
3598 | - { index: 0, progress: 1.0, current: 1.0, other: 0.0 }, |
3599 | - { index: 2, progress: 0.0, current: 1.0, other: 1.0 }, |
3600 | - { index: 2, progress: 0.1, current: 1.0, other: 0.9 }, |
3601 | - { index: 2, progress: 0.5, current: 1.0, other: 0.5 }, |
3602 | - { index: 2, progress: 1.0, current: 1.0, other: 0.0 } |
3603 | - ]; |
3604 | - } |
3605 | - |
3606 | - function test_opacity(data) { |
3607 | - indicatorRow.unitProgress = data.progress; |
3608 | - indicatorRow.setCurrentItemIndex(data.index); |
3609 | - |
3610 | - tryCompare(indicatorRow.currentItem, "opacity", data.current); |
3611 | - |
3612 | - for (var i = 0; i < indicatorRow.row.count; i++) { |
3613 | - tryCompare(get_indicator_item(i), "opacity", i === data.index ? data.current: data.other); |
3614 | - } |
3615 | - } |
3616 | - |
3617 | - function test_dimmed_data() { |
3618 | - return [ |
3619 | - { index: 0, progress: 0.0, current: false, other: false }, |
3620 | - { index: 0, progress: 0.1, current: false, other: true }, |
3621 | - { index: 0, progress: 0.5, current: false, other: true }, |
3622 | - { index: 0, progress: 1.0, current: false, other: true }, |
3623 | - { index: 2, progress: 0.0, current: false, other: false }, |
3624 | - { index: 2, progress: 0.1, current: false, other: true }, |
3625 | - { index: 2, progress: 0.5, current: false, other: true }, |
3626 | - { index: 2, progress: 1.0, current: false, other: true } |
3627 | - ]; |
3628 | - } |
3629 | - |
3630 | - function test_dimmed(data) { |
3631 | - indicatorRow.unitProgress = data.progress; |
3632 | - indicatorRow.setCurrentItemIndex(data.index); |
3633 | - |
3634 | - compare(indicatorRow.currentItem.dimmed, data.current, "Indicator dim did not match for current item"); |
3635 | - |
3636 | - for (var i = 0; i < indicatorRow.row.count; i++) { |
3637 | - compare(get_indicator_item(i).dimmed, i === data.index ? data.current: data.other, "Indicator dim did not match for item iter"); |
3638 | - } |
3639 | - } |
3640 | - } |
3641 | -} |
3642 | |
3643 | === removed file 'tests/qmltests/Panel/tst_Indicators.qml' |
3644 | --- tests/qmltests/Panel/tst_Indicators.qml 2014-10-15 16:33:45 +0000 |
3645 | +++ tests/qmltests/Panel/tst_Indicators.qml 1970-01-01 00:00:00 +0000 |
3646 | @@ -1,231 +0,0 @@ |
3647 | -/* |
3648 | - * Copyright 2013 Canonical Ltd. |
3649 | - * |
3650 | - * This program is free software; you can redistribute it and/or modify |
3651 | - * it under the terms of the GNU General Public License as published by |
3652 | - * the Free Software Foundation; version 3. |
3653 | - * |
3654 | - * This program is distributed in the hope that it will be useful, |
3655 | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
3656 | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
3657 | - * GNU General Public License for more details. |
3658 | - * |
3659 | - * You should have received a copy of the GNU General Public License |
3660 | - * along with this program. If not, see <http://www.gnu.org/licenses/>. |
3661 | - */ |
3662 | - |
3663 | -import QtQuick 2.0 |
3664 | -import QtTest 1.0 |
3665 | -import Unity.Test 0.1 as UT |
3666 | -import Ubuntu.Components 0.1 as UC |
3667 | -import ".." |
3668 | -import "../../../qml/Panel" |
3669 | -import "../../../qml/Components" |
3670 | - |
3671 | -/* |
3672 | - This tests the Indicators component by using a fake model to stage data in the indicators |
3673 | - A view will show with indicators at the top, as does in the shell. There is a clickable area |
3674 | - marked "Click Me" which can be used to expose the indicators. |
3675 | -*/ |
3676 | -Item { |
3677 | - id: shell |
3678 | - width: units.gu(40) |
3679 | - height: units.gu(80) |
3680 | - |
3681 | - PanelBackground { |
3682 | - anchors.fill: indicators |
3683 | - } |
3684 | - |
3685 | - Indicators { |
3686 | - id: indicators |
3687 | - anchors { |
3688 | - right: parent.right |
3689 | - } |
3690 | - width: (shell.width > units.gu(60)) ? units.gu(40) : shell.width |
3691 | - y: 0 |
3692 | - shown: false |
3693 | - profile: "test1" |
3694 | - |
3695 | - openedHeight: parent.height - button.height |
3696 | - } |
3697 | - |
3698 | - UC.Button { |
3699 | - id: button |
3700 | - text: indicators.shown ? "Hide" : "Show" |
3701 | - anchors { |
3702 | - bottom: shell.bottom |
3703 | - left: parent.left |
3704 | - right: parent.right |
3705 | - } |
3706 | - height: 50 |
3707 | - |
3708 | - onClicked: { |
3709 | - if (!indicators.shown) { |
3710 | - indicators.show(); |
3711 | - } else { |
3712 | - indicators.hide(); |
3713 | - } |
3714 | - } |
3715 | - } |
3716 | - |
3717 | - UT.UnityTestCase { |
3718 | - name: "Indicators" |
3719 | - when: windowShown |
3720 | - |
3721 | - function init() { |
3722 | - indicators.initialise(); |
3723 | - |
3724 | - indicators.hide(); |
3725 | - tryCompare(indicators.hideAnimation, "running", false); |
3726 | - tryCompare(indicators, "state", "initial"); |
3727 | - } |
3728 | - |
3729 | - // Showing the indicators should fully open the indicator panel. |
3730 | - function test_show() { |
3731 | - indicators.show() |
3732 | - tryCompare(indicators, "fullyOpened", true); |
3733 | - } |
3734 | - |
3735 | - // Test the change in the revealer lateral position changes the current panel menu to fit the position |
3736 | - // of the indicator in the row. |
3737 | - function test_change_revealer_lateral_position() |
3738 | - { |
3739 | - // tests changing the lateral position of the revealer activates the correct indicator items. |
3740 | - |
3741 | - var indicatorRow = findChild(indicators, "indicatorRow") |
3742 | - verify(indicatorRow !== null); |
3743 | - var indicatorRowItems = findChild(indicatorRow, "indicatorRowItems"); |
3744 | - verify(indicatorRowItems !== null); |
3745 | - |
3746 | - for (var i = 0; i < indicatorRowItems.count; i++) { |
3747 | - var indicatorItem = findChild(indicatorRowItems, "item" + i); |
3748 | - |
3749 | - if (!indicatorItem.visible) |
3750 | - continue; |
3751 | - |
3752 | - var indicatorPosition = indicators.mapFromItem(indicatorItem, |
3753 | - indicatorItem.width/2, indicatorItem.height/2); |
3754 | - |
3755 | - touchFlick(indicators, |
3756 | - indicatorPosition.x, indicatorPosition.y, |
3757 | - indicatorPosition.x, indicators.openedHeight * 0.4, |
3758 | - true /* beginTouch */, false /* endTouch */); |
3759 | - |
3760 | - compare(indicatorRow.currentItem, indicatorItem, |
3761 | - "Incorrect item activated at position " + i); |
3762 | - |
3763 | - touchFlick(indicators, |
3764 | - indicatorPosition.x, indicators.openedHeight * 0.4, |
3765 | - indicatorPosition.x, indicatorPosition.y, |
3766 | - false /* beginTouch */, true /* endTouch */); |
3767 | - |
3768 | - // wait until fully closed |
3769 | - tryCompare(indicators, "height", indicators.panelHeight); |
3770 | - } |
3771 | - } |
3772 | - |
3773 | - // values for specific state changes are subject to internal decisions, so we can't |
3774 | - // determine the true height value which would cause the state to change without making |
3775 | - // too many assuptyions |
3776 | - // However, we can assume that a partially opened panel will not be initial, and fully |
3777 | - // opened panel will be locked. |
3778 | - |
3779 | - function test_progress_changes_state_to_not_initial() { |
3780 | - indicators.height = indicators.openedHeight / 2 |
3781 | - compare(indicators.state!="initial", true, |
3782 | - "Indicators should not be in initial state when partially opened."); |
3783 | - } |
3784 | - |
3785 | - function test_progress_changes_state_to_locked() { |
3786 | - indicators.height = indicators.openedHeight - indicators.panelHeight |
3787 | - compare(indicators.state, "locked", "Indicators should be locked when fully opened."); |
3788 | - } |
3789 | - |
3790 | - function test_partially_open() { |
3791 | - indicators.height = indicators.openedHeight / 2 |
3792 | - compare(indicators.partiallyOpened, true, |
3793 | - "Indicator should show as partially opened when height is half of openedHeight"); |
3794 | - compare(indicators.fullyOpened, false, |
3795 | - "Indicator should not show as fully opened when height is half of openedHeight"); |
3796 | - } |
3797 | - |
3798 | - function test_fully_open() { |
3799 | - indicators.height = indicators.openedHeight |
3800 | - compare(indicators.partiallyOpened, false); |
3801 | - compare(indicators.fullyOpened, true); |
3802 | - } |
3803 | - |
3804 | - function init_invisible_indicator(identifier) { |
3805 | - tryCompareFunction(function() { return findChild(indicators, identifier+"-delegate") !== undefined }, true); |
3806 | - var item = findChild(indicators, identifier+"-delegate"); |
3807 | - verify(item !== null); |
3808 | - |
3809 | - item.enabled = false; |
3810 | - } |
3811 | - |
3812 | - function test_row_visible_menuContent_visible_data() { return [ |
3813 | - {tag: "first", visible: [false, true, true, true, true] }, |
3814 | - {tag: "adjacent", visible: [true, false, false, true, true] }, |
3815 | - {tag: "bounds", visible: [false, true, true, true, false] }, |
3816 | - {tag: "disjoint", visible: [true, false, true, false, true] }, |
3817 | - {tag: "last", visible: [true, true, true, true, false] }]; |
3818 | - } |
3819 | - |
3820 | - function test_row_visible_menuContent_visible(data) { |
3821 | - indicators.show(); |
3822 | - |
3823 | - var contentListView = findChild(indicators, "indicatorsContentListView"); |
3824 | - var indicatorRowItems = findChild(indicators, "indicatorRowItems"); |
3825 | - |
3826 | - var count = data.visible.length |
3827 | - for (var i = 0; i< data.visible.length; i++) { |
3828 | - if (data.visible[i] === false) { |
3829 | - init_invisible_indicator("indicator-fake" + (i + 1)); |
3830 | - count--; |
3831 | - } |
3832 | - } |
3833 | - |
3834 | - tryCompare(indicatorRowItems, "count", count); |
3835 | - |
3836 | - for (i = 0; i < data.visible.length; i++) { |
3837 | - var widgetName = "indicator-fake" + (i + 1 + "-widget"); |
3838 | - var pageName = "indicator-fake" + (i + 1 + "-page"); |
3839 | - |
3840 | - // check for item |
3841 | - tryCompareFunction(function() { return findChild(indicatorRowItems, widgetName) !== null }, data.visible[i]); |
3842 | - |
3843 | - // check for tab |
3844 | - tryCompareFunction(function() { return findChild(contentListView, pageName) !== null }, data.visible[i]); |
3845 | - } |
3846 | - } |
3847 | - |
3848 | - function test_indicator_visible_correct_menu_data() { return [ |
3849 | - {tag: "current-first", currentIndex: 0, visible: [false, true, true, true, true], expectedIndex: 0, expextedMenu: "indicator-fake2" }, |
3850 | - {tag: "current-last", currentIndex: 4, visible: [true, true, true, true, false], expectedIndex: 3, expextedMenu: "indicator-fake4" }, |
3851 | - {tag: "after", currentIndex: 0, visible: [true, false, true, true, true], expectedIndex: 0, expextedMenu: "indicator-fake1" }, |
3852 | - {tag: "before", currentIndex: 1, visible: [false, true, true, true, true], expectedIndex: 1, expextedMenu: "indicator-fake2" }]; |
3853 | - } |
3854 | - |
3855 | - function test_indicator_visible_correct_menu(data) { |
3856 | - var contentListView = findChild(indicators, "indicatorsContentListView"); |
3857 | - var indicatorRow = findChild(indicators, "indicatorRow"); |
3858 | - |
3859 | - indicators.show(); |
3860 | - indicatorRow.setCurrentItemIndex(data.currentIndex); |
3861 | - tryCompare(indicators, "fullyOpened", true); |
3862 | - |
3863 | - for (var i = 0; i< data.visible.length; i++) { |
3864 | - if (data.visible[i] === false) { |
3865 | - init_invisible_indicator("indicator-fake" + (i + 1)); |
3866 | - } |
3867 | - } |
3868 | - |
3869 | - // check for current selected item |
3870 | - tryCompare(indicatorRow, "currentItemIndex", data.expectedIndex); |
3871 | - |
3872 | - // check for current selected tab |
3873 | - tryCompareFunction(function() { return findChild(contentListView, data.expextedMenu) === contentListView.currentItem }, true); |
3874 | - |
3875 | - } |
3876 | - } |
3877 | -} |
3878 | |
3879 | === added file 'tests/qmltests/Panel/tst_IndicatorsBar.qml' |
3880 | --- tests/qmltests/Panel/tst_IndicatorsBar.qml 1970-01-01 00:00:00 +0000 |
3881 | +++ tests/qmltests/Panel/tst_IndicatorsBar.qml 2014-10-15 16:33:46 +0000 |
3882 | @@ -0,0 +1,178 @@ |
3883 | +/* |
3884 | + * Copyright 2013-2014 Canonical Ltd. |
3885 | + * |
3886 | + * This program is free software; you can redistribute it and/or modify |
3887 | + * it under the terms of the GNU General Public License as published by |
3888 | + * the Free Software Foundation; version 3. |
3889 | + * |
3890 | + * This program is distributed in the hope that it will be useful, |
3891 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
3892 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
3893 | + * GNU General Public License for more details. |
3894 | + * |
3895 | + * You should have received a copy of the GNU General Public License |
3896 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
3897 | + */ |
3898 | + |
3899 | +import QtQuick 2.1 |
3900 | +import QtQuick.Layouts 1.1 |
3901 | +import QtTest 1.0 |
3902 | +import "../../../qml/Panel" |
3903 | +import Ubuntu.Components 0.1 |
3904 | +import Unity.Test 0.1 as UT |
3905 | +import Unity.Indicators 0.1 as Indicators |
3906 | + |
3907 | +IndicatorTest { |
3908 | + id: root |
3909 | + width: units.gu(100) |
3910 | + height: units.gu(40) |
3911 | + |
3912 | + |
3913 | + RowLayout { |
3914 | + anchors.fill: parent |
3915 | + anchors.margins: units.gu(1) |
3916 | + |
3917 | + Rectangle { |
3918 | + id: itemArea |
3919 | + color: "blue" |
3920 | + Layout.fillWidth: true |
3921 | + Layout.fillHeight: true |
3922 | + |
3923 | + Rectangle { |
3924 | + color: "black" |
3925 | + anchors.fill: indicatorsBar |
3926 | + } |
3927 | + |
3928 | + IndicatorsBar { |
3929 | + id: indicatorsBar |
3930 | + height: expanded ? units.gu(7) : units.gu(3) |
3931 | + width: units.gu(30) |
3932 | + anchors.centerIn: parent |
3933 | + indicatorsModel: root.indicatorsModel |
3934 | + |
3935 | + Behavior on height { |
3936 | + NumberAnimation { |
3937 | + id: heightAnimation |
3938 | + duration: UbuntuAnimation.SnapDuration; easing: UbuntuAnimation.StandardEasing |
3939 | + } |
3940 | + } |
3941 | + |
3942 | + MouseArea { |
3943 | + anchors.fill: parent |
3944 | + enabled: !indicatorsBar.expanded |
3945 | + onPressed: { |
3946 | + indicatorsBar.selectItemAt(mouse.x); |
3947 | + indicatorsBar.expanded = true |
3948 | + } |
3949 | + } |
3950 | + } |
3951 | + } |
3952 | + |
3953 | + ColumnLayout { |
3954 | + Layout.alignment: Qt.AlignTop |
3955 | + Layout.fillWidth: false |
3956 | + |
3957 | + Button { |
3958 | + Layout.fillWidth: true |
3959 | + text: indicatorsBar.expanded ? "Collapse" : "Expand" |
3960 | + onClicked: indicatorsBar.expanded = !indicatorsBar.expanded |
3961 | + } |
3962 | + |
3963 | + Rectangle { |
3964 | + Layout.preferredHeight: units.dp(1); |
3965 | + Layout.fillWidth: true; |
3966 | + color: "black" |
3967 | + } |
3968 | + |
3969 | + Repeater { |
3970 | + model: indicatorsModel.originalModelData |
3971 | + RowLayout { |
3972 | + CheckBox { |
3973 | + checked: true |
3974 | + onCheckedChanged: checked ? insertIndicator(index) : removeIndicator(index); |
3975 | + } |
3976 | + Label { text: modelData["identifier"] } |
3977 | + } |
3978 | + } |
3979 | + } |
3980 | + } |
3981 | + |
3982 | + UT.UnityTestCase { |
3983 | + name: "IndicatorsBar" |
3984 | + when: windowShown |
3985 | + |
3986 | + function init() { |
3987 | + indicatorsBar.expanded = false; |
3988 | + tryCompare(heightAnimation, "running", false); |
3989 | + } |
3990 | + |
3991 | + function test_expandSelectedItem_data() { |
3992 | + return [ |
3993 | + { index: 0 }, |
3994 | + { index: 2 }, |
3995 | + { index: 4 } |
3996 | + ]; |
3997 | + } |
3998 | + |
3999 | + function wait_for_expansion_to_settle() { |
4000 | + tryCompare(heightAnimation, "running", false); |
4001 | + wait(200); // put a little extra wait in for things to settle |
4002 | + } |
4003 | + |
4004 | + // Rough check that expanding a selected item keeps it within the area of the original item. |
4005 | + function test_expandSelectedItem(data) { |
4006 | + var dataItem = findChild(indicatorsBar, indicatorsModel.originalModelData[data.index]["identifier"] + "-panelItem"); |
4007 | + verify(dataItem !== null); |
4008 | + |
4009 | + var mappedPosition = indicatorsBar.mapFromItem(dataItem, dataItem.width/2, dataItem.height/2); |
4010 | + |
4011 | + indicatorsBar.selectItemAt(mappedPosition.x); |
4012 | + indicatorsBar.expanded = true; |
4013 | + wait_for_expansion_to_settle(); |
4014 | + |
4015 | + var mappedRect = indicatorsBar.mapFromItem(dataItem, 0, 0, dataItem.width, dataItem.height); |
4016 | + |
4017 | + // mappedPosition contained within mappedRect |
4018 | + verify(mappedRect.x <= mappedPosition.x); |
4019 | + verify(mappedRect.x + mappedRect.width >= mappedPosition.x); |
4020 | + } |
4021 | + |
4022 | + function test_scrollOffset() { |
4023 | + indicatorsBar.expanded = true; |
4024 | + wait_for_expansion_to_settle(); |
4025 | + |
4026 | + var lastItemIndex = indicatorsModel.originalModelData.length-1; |
4027 | + var dataItem = findChild(indicatorsBar, indicatorsModel.originalModelData[lastItemIndex]["identifier"] + "-panelItem"); |
4028 | + verify(dataItem !== null); |
4029 | + |
4030 | + var row = findChild(indicatorsBar, "indicatorItemRow"); |
4031 | + // test will not work without these conditions |
4032 | + verify(row.width >= indicatorsBar.width + dataItem.width); |
4033 | + |
4034 | + var mappedPosition = indicatorsBar.mapFromItem(dataItem, dataItem.width/2, dataItem.height/2); |
4035 | + indicatorsBar.addScrollOffset(-dataItem.width); |
4036 | + var newMappedPosition = indicatorsBar.mapFromItem(dataItem, dataItem.width/2, dataItem.height/2); |
4037 | + |
4038 | + compare(mappedPosition.x, newMappedPosition.x - dataItem.width); |
4039 | + } |
4040 | + |
4041 | + function test_selectItemWhenExpanded_data() { |
4042 | + return [ |
4043 | + { index: 3 }, |
4044 | + { index: 4 } |
4045 | + ]; |
4046 | + } |
4047 | + |
4048 | + function test_selectItemWhenExpanded(data) { |
4049 | + indicatorsBar.expanded = true; |
4050 | + wait_for_expansion_to_settle(); |
4051 | + |
4052 | + var dataItem = findChild(indicatorsBar, indicatorsModel.originalModelData[data.index]["identifier"] + "-panelItem"); |
4053 | + if (indicatorsBar.mapFromItem(dataItem, dataItem.width/2, dataItem.height/2).x < 0) { |
4054 | + skip("Out of bounds"); |
4055 | + } |
4056 | + mouseClick(dataItem, dataItem.width/2, dataItem.height/2); |
4057 | + verify(dataItem.selected === true); |
4058 | + } |
4059 | + } |
4060 | +} |
4061 | |
4062 | === added file 'tests/qmltests/Panel/tst_IndicatorsMenu.qml' |
4063 | --- tests/qmltests/Panel/tst_IndicatorsMenu.qml 1970-01-01 00:00:00 +0000 |
4064 | +++ tests/qmltests/Panel/tst_IndicatorsMenu.qml 2014-10-15 16:33:46 +0000 |
4065 | @@ -0,0 +1,247 @@ |
4066 | +/* |
4067 | + * Copyright 2013-2014 Canonical Ltd. |
4068 | + * |
4069 | + * This program is free software; you can redistribute it and/or modify |
4070 | + * it under the terms of the GNU General Public License as published by |
4071 | + * the Free Software Foundation; version 3. |
4072 | + * |
4073 | + * This program is distributed in the hope that it will be useful, |
4074 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
4075 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
4076 | + * GNU General Public License for more details. |
4077 | + * |
4078 | + * You should have received a copy of the GNU General Public License |
4079 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
4080 | + */ |
4081 | + |
4082 | +import QtQuick 2.1 |
4083 | +import QtQuick.Layouts 1.1 |
4084 | +import QtTest 1.0 |
4085 | +import "../../../qml/Panel" |
4086 | +import Ubuntu.Components 0.1 |
4087 | +import Unity.Test 0.1 as UT |
4088 | +import Unity.Indicators 0.1 as Indicators |
4089 | + |
4090 | +IndicatorTest { |
4091 | + id: root |
4092 | + width: units.gu(80) |
4093 | + height: units.gu(71) |
4094 | + color: "white" |
4095 | + |
4096 | + property string indicatorProfile: "phone" |
4097 | + |
4098 | + RowLayout { |
4099 | + anchors.fill: parent |
4100 | + anchors.margins: units.gu(1) |
4101 | + |
4102 | + Rectangle { |
4103 | + Layout.fillWidth: true |
4104 | + Layout.fillHeight: true |
4105 | + |
4106 | + id: itemArea |
4107 | + color: "blue" |
4108 | + |
4109 | + IndicatorsMenu { |
4110 | + id: indicatorsMenu |
4111 | + width: units.gu(40) |
4112 | + anchors { |
4113 | + top: parent.top |
4114 | + right: parent.right |
4115 | + } |
4116 | + minimizedPanelHeight: units.gu(3) |
4117 | + expandedPanelHeight: units.gu(7) |
4118 | + openedHeight: parent.height |
4119 | + indicatorsModel: root.indicatorsModel |
4120 | + shown: false |
4121 | + } |
4122 | + } |
4123 | + |
4124 | + ColumnLayout { |
4125 | + Layout.alignment: Qt.AlignTop |
4126 | + Layout.fillWidth: false |
4127 | + |
4128 | + Button { |
4129 | + Layout.fillWidth: true |
4130 | + text: indicatorsMenu.shown ? "Hide" : "Show" |
4131 | + onClicked: { |
4132 | + if (indicatorsMenu.shown) { |
4133 | + indicatorsMenu.hide(); |
4134 | + } else { |
4135 | + indicatorsMenu.show(); |
4136 | + } |
4137 | + } |
4138 | + } |
4139 | + |
4140 | + Rectangle { |
4141 | + Layout.preferredHeight: units.dp(1); |
4142 | + Layout.fillWidth: true; |
4143 | + color: "black" |
4144 | + } |
4145 | + |
4146 | + Repeater { |
4147 | + model: indicatorsModel.originalModelData |
4148 | + RowLayout { |
4149 | + CheckBox { |
4150 | + checked: true |
4151 | + onCheckedChanged: checked ? insertIndicator(index) : removeIndicator(index); |
4152 | + } |
4153 | + Label { text: modelData["identifier"] } |
4154 | + } |
4155 | + } |
4156 | + } |
4157 | + } |
4158 | + |
4159 | + UT.UnityTestCase { |
4160 | + id: testCase |
4161 | + name: "IndicatorsMenu" |
4162 | + when: windowShown |
4163 | + |
4164 | + function init() { |
4165 | + indicatorsMenu.hide(); |
4166 | + tryCompare(indicatorsMenu.hideAnimation, "running", false); |
4167 | + compare(indicatorsMenu.state, "initial"); |
4168 | + |
4169 | + indicatorsMenu.verticalVelocityThreshold = 0.5 |
4170 | + } |
4171 | + |
4172 | + function get_indicator_item(index) { |
4173 | + var indicatorItem = findChild(indicatorsMenu, indicatorsModel.originalModelData[index]["identifier"] + "-panelItem"); |
4174 | + verify(indicatorItem !== null); |
4175 | + |
4176 | + return indicatorItem; |
4177 | + } |
4178 | + |
4179 | + // Showing the indicators should fully open the indicator panel. |
4180 | + function test_showAndHide() { |
4181 | + indicatorsMenu.show(); |
4182 | + tryCompare(indicatorsMenu, "fullyOpened", true); |
4183 | + |
4184 | + indicatorsMenu.hide(); |
4185 | + tryCompare(indicatorsMenu, "fullyClosed", true); |
4186 | + } |
4187 | + |
4188 | + // Test that closing the indicators ends up in the correct position. |
4189 | + function test_hideEndsInCorrectPosition() { |
4190 | + var indicatorsBar = findChild(indicatorsMenu, "indicatorsBar"); |
4191 | + var flickable = findChild(indicatorsBar, "flickable"); |
4192 | + |
4193 | + var originalContentX = flickable.contentX; |
4194 | + |
4195 | + indicatorsMenu.show(); |
4196 | + indicatorsBar.setCurrentItemIndex(0); |
4197 | + tryCompare(indicatorsMenu, "fullyOpened", true); |
4198 | + |
4199 | + indicatorsMenu.hide(); |
4200 | + tryCompare(flickable, "contentX", originalContentX); |
4201 | + } |
4202 | + |
4203 | + function test_progress_changes_state_to_reveal() { |
4204 | + indicatorsMenu.height = indicatorsMenu.openedHeight / 2; |
4205 | + compare(indicatorsMenu.state, "reveal", "Indicators should be revealing when partially opened."); |
4206 | + |
4207 | + indicatorsMenu.height = indicatorsMenu.openedHeight; |
4208 | + compare(indicatorsMenu.state, "reveal", "Indicators should still be revealing when fully opened."); |
4209 | + } |
4210 | + |
4211 | + function test_open_state() { |
4212 | + compare(indicatorsMenu.fullyClosed, true, "Indicator should show as fully closed."); |
4213 | + compare(indicatorsMenu.partiallyOpened, false, "Indicator should not show as partially opened"); |
4214 | + compare(indicatorsMenu.fullyOpened, false, "Indicator should not show as fully opened"); |
4215 | + |
4216 | + indicatorsMenu.height = indicatorsMenu.openedHeight / 2 |
4217 | + compare(indicatorsMenu.fullyClosed, false, "Indicator should not show as fully closed."); |
4218 | + compare(indicatorsMenu.partiallyOpened, true, "Indicator should show as partially opened"); |
4219 | + compare(indicatorsMenu.fullyOpened, false, "Indicator should not show as fully opened"); |
4220 | + |
4221 | + indicatorsMenu.height = indicatorsMenu.openedHeight; |
4222 | + compare(indicatorsMenu.fullyClosed, false, "Indicator should not show as fully closed."); |
4223 | + compare(indicatorsMenu.partiallyOpened, false, "Indicator should show as partially opened"); |
4224 | + compare(indicatorsMenu.fullyOpened, true, "Indicator should not show as fully opened"); |
4225 | + } |
4226 | + |
4227 | + // Pressing on the indicator panel should activate the indicator hints |
4228 | + // and expose the header |
4229 | + function test_hint() { |
4230 | + var indicatorItem = get_indicator_item(0); |
4231 | + var mappedPosition = root.mapFromItem(indicatorItem, indicatorItem.width/2, indicatorItem.height/2); |
4232 | + |
4233 | + touchPress(indicatorsMenu, mappedPosition.x, indicatorsMenu.minimizedPanelHeight / 2); |
4234 | + |
4235 | + // hint animation should be run, meaning that indicators will move downwards |
4236 | + // by hintValue pixels without any drag taking place |
4237 | + tryCompareFunction(function() { return indicatorsMenu.height }, indicatorsMenu.expandedPanelHeight + units.gu(2)); |
4238 | + tryCompare(indicatorsMenu, "partiallyOpened", true); |
4239 | + |
4240 | + touchRelease(indicatorsMenu, mappedPosition.x, indicatorsMenu.minimizedPanelHeight / 2); |
4241 | + } |
4242 | + |
4243 | + // tests swiping on an indicator item activates the correct item. |
4244 | + function test_swipeForCurrentItem() |
4245 | + { |
4246 | + var indicatorItemRow = findChild(indicatorsMenu, "indicatorItemRow"); |
4247 | + verify(indicatorItemRow !== null); |
4248 | + |
4249 | + for (var i = 0; i < indicatorsModel.originalModelData.length; i++) { |
4250 | + var indicatorItem = get_indicator_item(i); |
4251 | + |
4252 | + var mappedPosition = root.mapFromItem(indicatorItem, indicatorItem.width/2, indicatorItem.height/2); |
4253 | + |
4254 | + touchFlick(indicatorsMenu, |
4255 | + mappedPosition.x, mappedPosition.y, |
4256 | + mappedPosition.x, indicatorsMenu.openedHeight / 2, |
4257 | + true /* beginTouch */, false /* endTouch */); |
4258 | + |
4259 | + compare(indicatorItemRow.currentItem, indicatorItem, |
4260 | + "Incorrect item activated at position " + i); |
4261 | + |
4262 | + touchFlick(indicatorItemRow, |
4263 | + mappedPosition.x, indicatorsMenu.openedHeight / 2, |
4264 | + mappedPosition.x, mappedPosition.y, |
4265 | + false /* beginTouch */, true /* endTouch */); |
4266 | + |
4267 | + // wait until fully closed |
4268 | + tryCompare(indicatorsMenu, "fullyClosed", true); |
4269 | + } |
4270 | + } |
4271 | + |
4272 | + // Test the vertical velocity check when flicking the indicators open at an angle. |
4273 | + // If the vertical velocity is above a specific point, we shouldnt change active indicators |
4274 | + // if the x position changes |
4275 | + function test_verticalVelocityDetector() { |
4276 | + indicatorsMenu.verticalVelocityThreshold = 0; |
4277 | + verify(indicatorsModel.originalModelData.length >= 2); |
4278 | + |
4279 | + var indicatorItemRow = findChild(indicatorsMenu, "indicatorItemRow"); |
4280 | + verify(indicatorItemRow !== null); |
4281 | + |
4282 | + // Get the first indicator |
4283 | + var firstItem = get_indicator_item(0); |
4284 | + var firstItemMappedPosition = root.mapFromItem(firstItem, firstItem.width/2, firstItem.height/2); |
4285 | + |
4286 | + // 1) Drag the mouse down to hint a bit |
4287 | + touchFlick(indicatorsMenu, |
4288 | + firstItemMappedPosition.x, indicatorsMenu.minimizedPanelHeight / 2, |
4289 | + firstItemMappedPosition.x, indicatorsMenu.minimizedPanelHeight * 2, |
4290 | + true /* beginTouch */, false /* endTouch */); |
4291 | + |
4292 | + tryCompare(indicatorItemRow, "currentItem", firstItem) |
4293 | + |
4294 | + // next time position will have moved. |
4295 | + var nextItem = get_indicator_item(1); |
4296 | + var nextItemMappedPosition = root.mapFromItem(nextItem, nextItem.width/2, nextItem.height/2); |
4297 | + |
4298 | + // 1) Flick mouse down to bottom |
4299 | + touchFlick(indicatorsMenu, |
4300 | + firstItemMappedPosition.x, indicatorsMenu.minimizedPanelHeight * 2, |
4301 | + nextItemMappedPosition.x, indicatorsMenu.openedHeight / 3, |
4302 | + false /* beginTouch */, false /* endTouch */, |
4303 | + units.gu(50) /* speed */, 5 /* iterations */); // more samples needed for accurate velocity |
4304 | + |
4305 | + compare(indicatorItemRow.currentItem, firstItem, "First indicator should still be the current item"); |
4306 | + // after waiting in the same spot with touch down, it should update to the next item. |
4307 | + tryCompare(indicatorItemRow, "currentItem", nextItem); |
4308 | + |
4309 | + touchRelease(indicatorsMenu, nextItemMappedPosition.x, indicatorsMenu.openedHeight / 3); |
4310 | + } |
4311 | + } |
4312 | +} |
4313 | |
4314 | === modified file 'tests/qmltests/Panel/tst_MenuContent.qml' |
4315 | --- tests/qmltests/Panel/tst_MenuContent.qml 2014-10-15 16:33:45 +0000 |
4316 | +++ tests/qmltests/Panel/tst_MenuContent.qml 2014-10-15 16:33:46 +0000 |
4317 | @@ -1,5 +1,5 @@ |
4318 | /* |
4319 | - * Copyright 2013 Canonical Ltd. |
4320 | + * Copyright 2013-2014 Canonical Ltd. |
4321 | * |
4322 | * This program is free software; you can redistribute it and/or modify |
4323 | * it under the terms of the GNU General Public License as published by |
4324 | @@ -17,12 +17,11 @@ |
4325 | import QtQuick 2.0 |
4326 | import QtTest 1.0 |
4327 | import Unity.Test 0.1 as UT |
4328 | -import ".." |
4329 | import "../../../qml/Panel" |
4330 | import Unity.Indicators 0.1 as Indicators |
4331 | |
4332 | -Item { |
4333 | - id: shell |
4334 | +IndicatorTest { |
4335 | + id: root |
4336 | width: units.gu(40) |
4337 | height: units.gu(70) |
4338 | |
4339 | @@ -30,15 +29,9 @@ |
4340 | Item { id: greeter } |
4341 | Item { id: handle } |
4342 | |
4343 | - |
4344 | - Indicators.IndicatorsModel { |
4345 | - id: indicatorsModel |
4346 | - Component.onCompleted: load("test1") |
4347 | - } |
4348 | - |
4349 | MenuContent { |
4350 | id: menuContent |
4351 | - indicatorsModel: indicatorsModel |
4352 | + indicatorsModel: root.indicatorsModel |
4353 | height: parent.height - 50 |
4354 | } |
4355 | |
4356 | @@ -107,7 +100,7 @@ |
4357 | |
4358 | // Check that the correct menus are displayed for the requested item. |
4359 | function test_show_menu() { |
4360 | - var menuCount = indicatorsModel.count; |
4361 | + var menuCount = root.indicatorsModel.count; |
4362 | verify(menuCount > 0, "Menu count should be greater than zero"); |
4363 | |
4364 | var listView = menu_content_test.findChild(menuContent, "indicatorsContentListView") |
4365 | @@ -126,14 +119,13 @@ |
4366 | |
4367 | // Tests QTBUG-30632 - asynchronous loader crashes when changing index quickly. |
4368 | function test_multi_activate() { |
4369 | - var menuCount = indicatorsModel.count; |
4370 | + var menuCount = root.indicatorsModel.count; |
4371 | verify(menuCount > 0, "Menu count should be greater than zero"); |
4372 | |
4373 | for (var i = 0; i < 100; i++) { |
4374 | activate_content(i % menuCount); |
4375 | compare(menuContent.currentMenuIndex, i%menuCount); |
4376 | } |
4377 | - wait(100); |
4378 | } |
4379 | } |
4380 | } |
4381 | |
4382 | === added file 'tests/qmltests/Panel/tst_Panel.qml' |
4383 | --- tests/qmltests/Panel/tst_Panel.qml 1970-01-01 00:00:00 +0000 |
4384 | +++ tests/qmltests/Panel/tst_Panel.qml 2014-10-15 16:33:46 +0000 |
4385 | @@ -0,0 +1,297 @@ |
4386 | +/* |
4387 | + * Copyright 2013-2014 Canonical Ltd. |
4388 | + * |
4389 | + * This program is free software; you can redistribute it and/or modify |
4390 | + * it under the terms of the GNU General Public License as published by |
4391 | + * the Free Software Foundation; version 3. |
4392 | + * |
4393 | + * This program is distributed in the hope that it will be useful, |
4394 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
4395 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
4396 | + * GNU General Public License for more details. |
4397 | + * |
4398 | + * You should have received a copy of the GNU General Public License |
4399 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
4400 | + */ |
4401 | + |
4402 | +import QtQuick 2.1 |
4403 | +import QtQuick.Layouts 1.1 |
4404 | +import QtTest 1.0 |
4405 | +import Unity.Test 0.1 as UT |
4406 | +import Ubuntu.Components 0.1 |
4407 | +import Unity.Indicators 0.1 as Indicators |
4408 | +import Ubuntu.Telephony 0.1 as Telephony |
4409 | +import "../../../qml/Panel" |
4410 | + |
4411 | +IndicatorTest { |
4412 | + id: root |
4413 | + width: units.gu(100) |
4414 | + height: units.gu(71) |
4415 | + color: "white" |
4416 | + |
4417 | + property string indicatorProfile: "phone" |
4418 | + |
4419 | + RowLayout { |
4420 | + anchors.fill: parent |
4421 | + anchors.margins: units.gu(1) |
4422 | + clip: true |
4423 | + |
4424 | + Rectangle { |
4425 | + Layout.fillWidth: true |
4426 | + Layout.fillHeight: true |
4427 | + |
4428 | + id: itemArea |
4429 | + color: "blue" |
4430 | + |
4431 | + Panel { |
4432 | + id: panel |
4433 | + anchors.fill: parent |
4434 | + indicators { |
4435 | + width: parent.width > units.gu(60) ? units.gu(40) : parent.width |
4436 | + indicatorsModel: root.indicatorsModel |
4437 | + } |
4438 | + |
4439 | + property real panelAndSeparatorHeight: panel.indicators.minimizedPanelHeight + units.dp(2) |
4440 | + } |
4441 | + } |
4442 | + |
4443 | + ColumnLayout { |
4444 | + Layout.alignment: Qt.AlignTop |
4445 | + Layout.fillWidth: false |
4446 | + |
4447 | + Button { |
4448 | + Layout.fillWidth: true |
4449 | + text: panel.indicators.shown ? "Hide" : "Show" |
4450 | + onClicked: { |
4451 | + if (panel.indicators.shown) { |
4452 | + panel.indicators.hide(); |
4453 | + } else { |
4454 | + panel.indicators.show(); |
4455 | + } |
4456 | + } |
4457 | + } |
4458 | + |
4459 | + Button { |
4460 | + text: panel.fullscreenMode ? "Maximize" : "FullScreen" |
4461 | + Layout.fillWidth: true |
4462 | + onClicked: panel.fullscreenMode = !panel.fullscreenMode |
4463 | + } |
4464 | + |
4465 | + Button { |
4466 | + Layout.fillWidth: true |
4467 | + text: callManager.hasCalls ? "Called" : "No Calls" |
4468 | + onClicked: { |
4469 | + if (callManager.foregroundCall) { |
4470 | + callManager.foregroundCall = null; |
4471 | + } else { |
4472 | + callManager.foregroundCall = phoneCall; |
4473 | + } |
4474 | + } |
4475 | + } |
4476 | + |
4477 | + Rectangle { |
4478 | + Layout.preferredHeight: units.dp(1); |
4479 | + Layout.fillWidth: true; |
4480 | + color: "black" |
4481 | + } |
4482 | + |
4483 | + Repeater { |
4484 | + model: indicatorsModel.originalModelData |
4485 | + RowLayout { |
4486 | + CheckBox { |
4487 | + checked: true |
4488 | + onCheckedChanged: checked ? insertIndicator(index) : removeIndicator(index); |
4489 | + } |
4490 | + Label { text: modelData["identifier"] } |
4491 | + } |
4492 | + } |
4493 | + } |
4494 | + } |
4495 | + |
4496 | + Telephony.CallEntry { |
4497 | + id: phoneCall |
4498 | + phoneNumber: "+447812221111" |
4499 | + } |
4500 | + |
4501 | + UT.UnityTestCase { |
4502 | + name: "Panel" |
4503 | + when: windowShown |
4504 | + |
4505 | + function init() { |
4506 | + panel.fullscreenMode = false; |
4507 | + callManager.foregroundCall = null; |
4508 | + |
4509 | + panel.indicators.hide(); |
4510 | + // Wait for animation to complete |
4511 | + tryCompare(panel.indicators.hideAnimation, "running", false); |
4512 | + |
4513 | + // Wait for the indicators to get into position. |
4514 | + // (switches between normal and fullscreen modes are animated) |
4515 | + var indicatorArea = findChild(panel, "indicatorArea"); |
4516 | + tryCompare(indicatorArea, "y", 0); |
4517 | + } |
4518 | + |
4519 | + function get_indicator_item(index) { |
4520 | + var indicatorItem = findChild(panel, indicatorsModel.originalModelData[index]["identifier"]+"-panelItem"); |
4521 | + verify(indicatorItem !== null); |
4522 | + |
4523 | + return indicatorItem; |
4524 | + } |
4525 | + |
4526 | + function test_drag_show_data() { |
4527 | + return [ |
4528 | + { tag: "pinned", fullscreen: false, call: null, |
4529 | + indicatorY: 0 }, |
4530 | + { tag: "fullscreen", fullscreen: true, call: null, |
4531 | + indicatorY: -panel.panelAndSeparatorHeight }, |
4532 | + { tag: "pinned-callActive", fullscreen: false, call: phoneCall, |
4533 | + indicatorY: 0}, |
4534 | + { tag: "fullscreen-callActive", fullscreen: true, call: phoneCall, |
4535 | + indicatorY: -panel.panelAndSeparatorHeight } |
4536 | + ]; |
4537 | + } |
4538 | + |
4539 | + // Dragging from a indicator item in the panel will gradually expose the |
4540 | + // indicators, first by running the hint animation, then after dragging down will |
4541 | + // expose more of the panel, binding it to the selected indicator and opening it's menu. |
4542 | + // Tested from first Y pixel to check for swipe from offscreen. |
4543 | + function test_drag_show(data) { |
4544 | + panel.fullscreenMode = data.fullscreen; |
4545 | + callManager.foregroundCall = data.call; |
4546 | + |
4547 | + var indicatorRow = findChild(panel.indicators, "indicatorItemRow"); |
4548 | + verify(indicatorRow !== null); |
4549 | + |
4550 | + var menuContent = findChild(panel.indicators, "menuContent"); |
4551 | + verify(menuContent !== null); |
4552 | + |
4553 | + var indicatorArea = findChild(panel, "indicatorArea"); |
4554 | + verify(indicatorArea !== null); |
4555 | + |
4556 | + // Wait for the indicators to get into position. |
4557 | + // (switches between normal and fullscreen modes are animated) |
4558 | + tryCompareFunction(function() { return indicatorArea.y }, data.indicatorY); |
4559 | + |
4560 | + for (var i = 0; i < indicatorsModel.originalModelData.length; i++) { |
4561 | + var indicatorItem = get_indicator_item(i); |
4562 | + |
4563 | + var startXPosition = root.mapFromItem(indicatorItem, indicatorItem.width / 2, 0).x; |
4564 | + var startYPosition = root.mapFromItem(panel, 0, 0).y; |
4565 | + |
4566 | + touchFlick(panel, |
4567 | + startXPosition, startYPosition, |
4568 | + startXPosition, panel.height, |
4569 | + true /* beginTouch */, false /* endTouch */, units.gu(5), 15); |
4570 | + |
4571 | + // Indicators height should follow the drag, and therefore increase accordingly. |
4572 | + // They should be at least half-way through the screen |
4573 | + tryCompareFunction( |
4574 | + function() {return panel.indicators.height >= panel.height * 0.5}, |
4575 | + true); |
4576 | + |
4577 | + touchRelease(panel, startXPosition, panel.height); |
4578 | + |
4579 | + compare(indicatorRow.currentItemIndex, i, "Indicator item should be activated at position " + i); |
4580 | + compare(menuContent.currentMenuIndex, i, "Menu conetent should be activated for item at position " + i); |
4581 | + |
4582 | + // init for next indicatorItem |
4583 | + panel.indicators.hide(); |
4584 | + tryCompare(panel.indicators.hideAnimation, "running", false); |
4585 | + tryCompare(panel.indicators, "state", "initial"); |
4586 | + } |
4587 | + } |
4588 | + |
4589 | + function test_drag_hide_data() { |
4590 | + return [ |
4591 | + { tag: "pinned", fullscreen: false, call: null, |
4592 | + indicatorY: 0 }, |
4593 | + { tag: "fullscreen", fullscreen: true, call: null, |
4594 | + indicatorY: -panel.panelAndSeparatorHeight }, |
4595 | + { tag: "pinned-callActive", fullscreen: false, call: phoneCall, |
4596 | + indicatorY: 0}, |
4597 | + { tag: "fullscreen-callActive", fullscreen: true, call: phoneCall, |
4598 | + indicatorY: -panel.panelAndSeparatorHeight } |
4599 | + ]; |
4600 | + } |
4601 | + |
4602 | + // Dragging the shown indicators up from bottom of panel will hide the indicators |
4603 | + // Tested from last Y pixel to check for swipe from offscreen. |
4604 | + function test_drag_hide(data) { |
4605 | + panel.fullscreenMode = data.fullscreen; |
4606 | + callManager.foregroundCall = data.call; |
4607 | + |
4608 | + var indicatorRow = findChild(panel.indicators, "indicatorItemRow"); |
4609 | + verify(indicatorRow !== null); |
4610 | + |
4611 | + var menuContent = findChild(panel.indicators, "menuContent"); |
4612 | + verify(menuContent !== null); |
4613 | + |
4614 | + var indicatorArea = findChild(panel, "indicatorArea"); |
4615 | + verify(indicatorArea !== null); |
4616 | + |
4617 | + // Wait for the indicators to get into position. |
4618 | + // (switches between normal and fullscreen modes are animated) |
4619 | + tryCompareFunction(function() { return indicatorArea.y }, data.indicatorY); |
4620 | + |
4621 | + var startXPosition = root.mapFromItem(panel.indicators, panel.indicators.width / 2, 0).x; |
4622 | + var startYPosition = root.mapFromItem(panel, 0, panel.height).y; |
4623 | + |
4624 | + panel.indicators.show(); |
4625 | + tryCompare(panel.indicators.showAnimation, "running", false); |
4626 | + tryCompare(panel.indicators, "unitProgress", 1); |
4627 | + |
4628 | + |
4629 | + touchFlick(panel.indicators, |
4630 | + startXPosition, startYPosition, |
4631 | + startXPosition, 0, |
4632 | + true /* beginTouch */, false /* endTouch */, units.gu(5), 15); |
4633 | + |
4634 | + // Indicators height should follow the drag, and therefore increase accordingly. |
4635 | + // They should be at least half-way through the screen |
4636 | + tryCompareFunction( |
4637 | + function() {return panel.indicators.height <= panel.height * 0.5}, |
4638 | + true); |
4639 | + |
4640 | + touchRelease(panel.indicators, startXPosition, 0); |
4641 | + |
4642 | + tryCompare(panel.indicators.hideAnimation, "running", true); |
4643 | + tryCompare(panel.indicators.hideAnimation, "running", false); |
4644 | + tryCompare(panel.indicators, "state", "initial"); |
4645 | + } |
4646 | + |
4647 | + function test_hint_data() { |
4648 | + return [ |
4649 | + { tag: "normal", fullscreen: false, call: null, hintExpected: true}, |
4650 | + { tag: "fullscreen", fullscreen: true, call: null, hintExpected: false}, |
4651 | + { tag: "call hint", fullscreen: false, call: phoneCall, hintExpected: false}, |
4652 | + ]; |
4653 | + } |
4654 | + |
4655 | + function test_hint(data) { |
4656 | + panel.fullscreenMode = data.fullscreen; |
4657 | + callManager.foregroundCall = data.call; |
4658 | + |
4659 | + if (data.fullscreen) { |
4660 | + // Wait for the indicators to get into position. |
4661 | + // (switches between normal and fullscreen modes are animated) |
4662 | + var indicatorArea = findChild(panel, "indicatorArea"); |
4663 | + tryCompare(indicatorArea, "y", -panel.panelHeight); |
4664 | + } |
4665 | + |
4666 | + var indicatorItem = get_indicator_item(0); |
4667 | + var mappedPosition = root.mapFromItem(indicatorItem, indicatorItem.width / 2, indicatorItem.height / 2); |
4668 | + |
4669 | + touchPress(panel, mappedPosition.x, panel.indicators.minimizedPanelHeight / 2); |
4670 | + |
4671 | + // Give some time for a hint animation to change things, if any |
4672 | + wait(500); |
4673 | + |
4674 | + // no hint animation when fullscreen |
4675 | + compare(panel.indicators.fullyClosed, !data.hintExpected, "Indicator should be fully closed"); |
4676 | + compare(panel.indicators.partiallyOpened, data.hintExpected, "Indicator should be partialy opened"); |
4677 | + compare(panel.indicators.fullyOpened, false, "Indicator should not be fully opened"); |
4678 | + |
4679 | + touchRelease(panel, mappedPosition.x, panel.minimizedPanelHeight / 2); |
4680 | + } |
4681 | + } |
4682 | +} |
4683 | |
4684 | === removed file 'tests/qmltests/Panel/tst_Panel.qml' |
4685 | --- tests/qmltests/Panel/tst_Panel.qml 2014-07-10 13:36:41 +0000 |
4686 | +++ tests/qmltests/Panel/tst_Panel.qml 1970-01-01 00:00:00 +0000 |
4687 | @@ -1,337 +0,0 @@ |
4688 | -/* |
4689 | - * Copyright 2013 Canonical Ltd. |
4690 | - * |
4691 | - * This program is free software; you can redistribute it and/or modify |
4692 | - * it under the terms of the GNU General Public License as published by |
4693 | - * the Free Software Foundation; version 3. |
4694 | - * |
4695 | - * This program is distributed in the hope that it will be useful, |
4696 | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
4697 | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
4698 | - * GNU General Public License for more details. |
4699 | - * |
4700 | - * You should have received a copy of the GNU General Public License |
4701 | - * along with this program. If not, see <http://www.gnu.org/licenses/>. |
4702 | - */ |
4703 | - |
4704 | -import QtQuick 2.0 |
4705 | -import QtTest 1.0 |
4706 | -import Unity.Test 0.1 as UT |
4707 | -import Ubuntu.Components 0.1 as UC |
4708 | -import Ubuntu.Telephony 0.1 as Telephony |
4709 | -import ".." |
4710 | -import "../../../qml/Panel" |
4711 | - |
4712 | -/* |
4713 | - This tests the Panel component using a fake model to stage data in the indicators |
4714 | - A view will show with indicators at the top, as does in the shell. This can be controlled |
4715 | - as in the shell. |
4716 | -*/ |
4717 | -Item { |
4718 | - id: shell |
4719 | - width: units.gu(40) |
4720 | - height: units.gu(80) |
4721 | - |
4722 | - Panel { |
4723 | - id: panel |
4724 | - anchors { |
4725 | - left: parent.left |
4726 | - right: parent.right |
4727 | - } |
4728 | - height: parent.height - row.height |
4729 | - fullscreenMode: false |
4730 | - |
4731 | - indicators { |
4732 | - profile: "test1" |
4733 | - panelHeight: units.gu(5) |
4734 | - } |
4735 | - callHint { |
4736 | - height: units.gu(4) |
4737 | - } |
4738 | - |
4739 | - property real panelAndSeparatorHeight: panel.indicators.panelHeight + units.dp(2) |
4740 | - } |
4741 | - |
4742 | - |
4743 | - Row { |
4744 | - id: row |
4745 | - anchors { |
4746 | - bottom: shell.bottom |
4747 | - left: parent.left |
4748 | - right: parent.right |
4749 | - } |
4750 | - height: 50 |
4751 | - |
4752 | - UC.Button { |
4753 | - text: panel.indicators.shown ? "Hide" : "Show" |
4754 | - anchors { |
4755 | - top: parent.top |
4756 | - bottom: parent.bottom |
4757 | - } |
4758 | - width: parent.width/3 |
4759 | - |
4760 | - onClicked: { |
4761 | - if (panel.indicators.shown) { |
4762 | - panel.indicators.hide(); |
4763 | - } else { |
4764 | - panel.indicators.show(); |
4765 | - } |
4766 | - } |
4767 | - } |
4768 | - |
4769 | - UC.Button { |
4770 | - text: panel.fullscreenMode ? "Maximize" : "FullScreen" |
4771 | - anchors { |
4772 | - top: parent.top |
4773 | - bottom: parent.bottom |
4774 | - } |
4775 | - width: parent.width/3 |
4776 | - |
4777 | - onClicked: panel.fullscreenMode = !panel.fullscreenMode |
4778 | - } |
4779 | - |
4780 | - UC.Button { |
4781 | - text: callManager.hasCalls ? "Called" : "No Calls" |
4782 | - anchors { |
4783 | - top: parent.top |
4784 | - bottom: parent.bottom |
4785 | - } |
4786 | - width: parent.width/3 |
4787 | - |
4788 | - onClicked: { |
4789 | - if (callManager.foregroundCall) { |
4790 | - callManager.foregroundCall = null; |
4791 | - } else { |
4792 | - callManager.foregroundCall = phoneCall; |
4793 | - } |
4794 | - } |
4795 | - } |
4796 | - } |
4797 | - |
4798 | - Telephony.CallEntry { |
4799 | - id: phoneCall |
4800 | - phoneNumber: "+447812221111" |
4801 | - } |
4802 | - |
4803 | - UT.UnityTestCase { |
4804 | - name: "Panel" |
4805 | - when: windowShown |
4806 | - |
4807 | - function init() { |
4808 | - panel.indicators.initialise(); |
4809 | - panel.fullscreenMode = false; |
4810 | - |
4811 | - panel.indicators.hide(); |
4812 | - // Wait for animation to complete |
4813 | - tryCompare(panel.indicators.hideAnimation, "running", false); |
4814 | - callManager.foregroundCall = null; |
4815 | - |
4816 | - // Wait for the indicators to get into position. |
4817 | - // (switches between normal and fullscreen modes are animated) |
4818 | - var indicatorArea = findChild(panel, "indicatorArea"); |
4819 | - tryCompare(indicatorArea, "y", 0); |
4820 | - } |
4821 | - |
4822 | - function get_indicator_item(index) { |
4823 | - var indicatorRow = findChild(panel.indicators, "indicatorRow"); |
4824 | - verify(indicatorRow !== null); |
4825 | - |
4826 | - return findChild(indicatorRow.row, "item" + index); |
4827 | - } |
4828 | - |
4829 | - function get_indicator_item_position(index) { |
4830 | - var indicatorRow = findChild(panel.indicators, "indicatorRow"); |
4831 | - verify(indicatorRow !== null); |
4832 | - |
4833 | - var indicatorItem = get_indicator_item(index); |
4834 | - verify(indicatorItem !== null); |
4835 | - |
4836 | - return panel.mapFromItem(indicatorItem, indicatorItem.width/2, indicatorItem.height/2); |
4837 | - } |
4838 | - |
4839 | - // Pressing on the indicator panel should activate the indicator hints |
4840 | - // and expose a portion of the conent. |
4841 | - function test_hint() { |
4842 | - var indicatorItemCoord = get_indicator_item_position(0); |
4843 | - |
4844 | - touchPress(panel, indicatorItemCoord.x, panel.indicators.panelHeight / 2); |
4845 | - |
4846 | - // hint animation should be run, meaning that indicators will move downwards |
4847 | - // by hintValue pixels without any drag taking place |
4848 | - tryCompareFunction(function() { return panel.indicators.height }, |
4849 | - panel.indicators.panelHeight + panel.indicators.hintValue); |
4850 | - tryCompare(panel.indicators, "partiallyOpened", true); |
4851 | - tryCompare(panel.indicators, "fullyOpened", false); |
4852 | - |
4853 | - touchRelease(panel, indicatorItemCoord.x, panel.indicators.panelHeight/2); |
4854 | - } |
4855 | - |
4856 | - // Pressing on the top edge of the screen should have no effect if the panel |
4857 | - // is hidden (fullscreen), which is the case when a fullscreen app is being shown |
4858 | - function test_noHintOnFullscreenMode() { |
4859 | - panel.fullscreenMode = true; |
4860 | - // Wait for the indicators to get into position. |
4861 | - // (switches between normal and fullscreen modes are animated) |
4862 | - var indicatorArea = findChild(panel, "indicatorArea"); |
4863 | - tryCompare(indicatorArea, "y", -panel.panelHeight); |
4864 | - |
4865 | - var indicatorItemCoord = get_indicator_item_position(0); |
4866 | - |
4867 | - touchPress(panel, indicatorItemCoord.x, panel.indicators.panelHeight / 2); |
4868 | - |
4869 | - // Give some time for a hint animation to change things, if any |
4870 | - wait(500); |
4871 | - |
4872 | - // no hint animation when fullscreen |
4873 | - compare(panel.indicators.partiallyOpened, false, |
4874 | - "Indicator should not be partially opened when panel is pressed in" + |
4875 | - " fullscreenmode"); |
4876 | - compare(panel.indicators.fullyOpened, false, "Indicator should not be partially" + |
4877 | - " opened when panel is pressed in fullscreenmode"); |
4878 | - |
4879 | - touchRelease(panel, indicatorItemCoord.x, panel.panelHeight/2); |
4880 | - } |
4881 | - |
4882 | - // Pressing on the top edge of the indicator should have no effect if the panel |
4883 | - // has an active call |
4884 | - function test_noHintOnActiveCall() { |
4885 | - callManager.foregroundCall = phoneCall; |
4886 | - |
4887 | - var indicatorItemCoord = get_indicator_item_position(0); |
4888 | - |
4889 | - touchPress(panel, indicatorItemCoord.x, panel.callHint.height + panel.indicators.panelHeight / 2); |
4890 | - |
4891 | - // Give some time for a hint animation to change things, if any |
4892 | - wait(500); |
4893 | - |
4894 | - // no hint animation when fullscreen |
4895 | - compare(panel.indicators.partiallyOpened, false, |
4896 | - "Indicator should not be partially opened when panel is pressed in" + |
4897 | - " fullscreenmode"); |
4898 | - compare(panel.indicators.fullyOpened, false, "Indicator should not be partially" + |
4899 | - " opened when panel is pressed in fullscreenmode"); |
4900 | - |
4901 | - touchRelease(panel, indicatorItemCoord.x, panel.panelHeight/2); |
4902 | - } |
4903 | - |
4904 | - function test_drag_show_data() { |
4905 | - return [ |
4906 | - { tag: "pinned", fullscreenFlag: false, alreadyOpen: false, call: null, |
4907 | - indicatorY: 0 }, |
4908 | - { tag: "fullscreen", fullscreenFlag: true, alreadyOpen: false, call: null, |
4909 | - indicatorY: -panel.panelAndSeparatorHeight }, |
4910 | - { tag: "pinned-alreadyOpen", fullscreenFlag: false, alreadyOpen: true, call: null, |
4911 | - indicatorY: 0 }, |
4912 | - { tag: "fullscreen-alreadyOpen", fullscreenFlag: true, alreadyOpen: true, call: null, |
4913 | - indicatorY: 0 }, |
4914 | - { tag: "pinned-callActive", fullscreenFlag: false, alreadyOpen: false, call: phoneCall, |
4915 | - indicatorY: 0}, |
4916 | - { tag: "fullscreen-callActive", fullscreenFlag: true, alreadyOpen: false, call: phoneCall, |
4917 | - indicatorY: -panel.panelAndSeparatorHeight } |
4918 | - ]; |
4919 | - } |
4920 | - |
4921 | - // Dragging from a indicator item in the panel will gradually expose the |
4922 | - // indicators, first by running the hint animation, then after dragging down will |
4923 | - // expose more of the panel, binding it to the selected indicator and opening it's menu. |
4924 | - function test_drag_show(data) { |
4925 | - panel.fullscreenMode = data.fullscreenFlag; |
4926 | - callManager.foregroundCall = data.call; |
4927 | - |
4928 | - if (data.alreadyOpen) { |
4929 | - panel.indicators.show(); |
4930 | - tryCompare(panel.indicators, "fullyOpened", true); |
4931 | - } |
4932 | - |
4933 | - var indicatorRow = findChild(panel.indicators, "indicatorRow"); |
4934 | - verify(indicatorRow !== null); |
4935 | - |
4936 | - var menuContent = findChild(panel.indicators, "menuContent"); |
4937 | - verify(menuContent !== null); |
4938 | - |
4939 | - var indicatorArea = findChild(panel, "indicatorArea"); |
4940 | - verify(indicatorArea !== null); |
4941 | - |
4942 | - // Wait for the indicators to get into position. |
4943 | - // (switches between normal and fullscreen modes are animated) |
4944 | - tryCompareFunction(function() { return indicatorArea.y }, data.indicatorY); |
4945 | - |
4946 | - // do this for each indicator item |
4947 | - for (var i = 0; i < indicatorRow.row.count; i++) { |
4948 | - |
4949 | - var indicatorItem = get_indicator_item(i); |
4950 | - verify(indicatorItem !== null); |
4951 | - |
4952 | - if (!indicatorItem.visible) |
4953 | - continue; |
4954 | - |
4955 | - var indicatorItemCoord = get_indicator_item_position(i); |
4956 | - |
4957 | - touchPress(panel, |
4958 | - indicatorItemCoord.x, panel.indicators.panelHeight / 2); |
4959 | - |
4960 | - // 1) Drag the mouse down |
4961 | - touchFlick(panel, |
4962 | - indicatorItemCoord.x, panel.indicators.panelHeight / 2, |
4963 | - indicatorItemCoord.x, panel.height, |
4964 | - false /* beginTouch */, false /* endTouch */); |
4965 | - |
4966 | - // Indicators height should follow the drag, and therefore increase accordingly. |
4967 | - // They should be at least half-way through the screen |
4968 | - tryCompareFunction( |
4969 | - function() {return panel.indicators.height >= panel.height * 0.5}, |
4970 | - true); |
4971 | - |
4972 | - touchRelease(panel, indicatorItemCoord.x, panel.height); |
4973 | - |
4974 | - compare(indicatorRow.currentItem, indicatorItem, |
4975 | - "Incorrect item activated at position " + i); |
4976 | - compare(menuContent.currentMenuIndex, i, "Menu conetent should be enabled for item at position " + i); |
4977 | - |
4978 | - // init for next indicatorItem |
4979 | - if (!data.alreadyOpen) { |
4980 | - panel.indicators.hide(); |
4981 | - tryCompare(panel.indicators.hideAnimation, "running", false); |
4982 | - tryCompare(panel.indicators, "state", "initial"); |
4983 | - } |
4984 | - } |
4985 | - } |
4986 | - |
4987 | - // Test the vertical velocity check when flicking the indicators open at an angle. |
4988 | - // If the vertical velocity is above a specific point, we shouldnt change active indicators |
4989 | - // if the x position changes |
4990 | - function test_vertical_velocity_detector() { |
4991 | - panel.fullscreenMode = false; |
4992 | - |
4993 | - var indicatorRow = findChild(panel.indicators, "indicatorRow"); |
4994 | - verify(indicatorRow !== null); |
4995 | - |
4996 | - // Get the first indicator |
4997 | - var indicatorItemFirst = get_indicator_item(0); |
4998 | - verify(indicatorItemFirst !== null); |
4999 | - |
5000 | - var indicatorItemCoordFirst = get_indicator_item_position(0); |
Playing with this some in silo 6 there are a few things I'm noticing:
* Indicators that are marked as not visible aren't showing up in the expanded panel
* Selecting an expanded item that is partially on screen doesn't pull it to be completely on screen
* Putting your finger on the bottom bar allows you to slide between the indicators. So if you grab the bar and close, you probably change indicators along the way (which is odd)
Otherwise I really love it :-)