Merge lp:~tpeeters/ubuntu-ui-toolkit/headlock into lp:ubuntu-ui-toolkit/staging
- headlock
- Merge into staging
Status: | Superseded | ||||||||
---|---|---|---|---|---|---|---|---|---|
Proposed branch: | lp:~tpeeters/ubuntu-ui-toolkit/headlock | ||||||||
Merge into: | lp:ubuntu-ui-toolkit/staging | ||||||||
Diff against target: |
1986 lines (+1027/-341) 22 files modified
components.api (+16/-1) modules/Ubuntu/Components/AppHeader.qml (+104/-15) modules/Ubuntu/Components/MainView.qml (+2/-1) modules/Ubuntu/Components/MainView12.qml (+18/-8) modules/Ubuntu/Components/Page10.qml (+3/-31) modules/Ubuntu/Components/Page11.qml (+6/-3) modules/Ubuntu/Components/Page13.qml (+85/-0) modules/Ubuntu/Components/PageHeadConfiguration.qdoc (+202/-0) modules/Ubuntu/Components/PageHeadConfiguration11.qml (+3/-155) modules/Ubuntu/Components/PageHeadConfiguration13.qml (+30/-0) modules/Ubuntu/Components/Tabs.qml (+4/-1) modules/Ubuntu/Components/pageUtils.js (+47/-0) modules/Ubuntu/Components/qmldir (+5/-1) modules/Ubuntu/Test/UbuntuTestCase.qml (+20/-2) tests/autopilot/ubuntuuitoolkit/_custom_proxy_objects/_header.py (+4/-1) tests/resources/header/lockedToolbar.deprecated.qml (+0/-52) tests/unit_x11/tst_components/tst_header_actions.qml (+11/-19) tests/unit_x11/tst_components/tst_header_contents_width.qml (+5/-10) tests/unit_x11/tst_components/tst_header_visible.qml (+288/-0) tests/unit_x11/tst_components/tst_page11.qml (+1/-1) tests/unit_x11/tst_components/tst_page13.qml (+141/-0) tests/unit_x11/tst_components/tst_pagestack.new_header.qml (+32/-40) |
||||||||
To merge this branch: | bzr merge lp:~tpeeters/ubuntu-ui-toolkit/headlock | ||||||||
Related bugs: |
|
||||||||
Related blueprints: |
Additional new header features
(Undefined)
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
PS Jenkins bot | continuous-integration | Approve | |
Ubuntu SDK team | Pending | ||
Review via email: mp+253121@code.launchpad.net |
Commit message
Add visible and locked properties to Page.head.
Description of the change
Add visible and locked properties to Page.head.
This MR has two pre-requisites that must land first:
1 - https:/
2 - https:/
PS Jenkins bot (ps-jenkins) wrote : | # |
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:1462
http://
Executed test runs:
UNSTABLE: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
UNSTABLE: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:1474
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
- 1475. By Tim Peeters
-
update components.api
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:1475
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
- 1476. By Tim Peeters
-
flake8
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:1476
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
- 1477. By Tim Peeters
-
mere wait_for_
head_animation branch - 1478. By Tim Peeters
-
clean
- 1479. By Tim Peeters
-
use waitForHeaderAn
imation( mainView) in tst_page13.qml - 1480. By Tim Peeters
-
merge staging
- 1481. By Tim Peeters
-
merge staging
- 1482. By Tim Peeters
-
update components.api
- 1483. By Tim Peeters
-
merge waitForHeaderAn
imation prerequisite branch
Unmerged revisions
Preview Diff
1 | === modified file 'components.api' |
2 | --- components.api 2015-03-10 13:58:52 +0000 |
3 | +++ components.api 2015-03-23 15:53:11 +0000 |
4 | @@ -246,7 +246,17 @@ |
5 | property Flickable flickable |
6 | property list<Action> actions |
7 | Page 1.1 |
8 | -Page10 |
9 | +Toolkit10.Page |
10 | + readonly property PageHeadConfiguration head |
11 | +Page 1.3 |
12 | +PageTreeNode |
13 | + property string title |
14 | + property Flickable flickable |
15 | + readonly property PageHeadConfiguration head |
16 | +Page 1.3 |
17 | +PageTreeNode |
18 | + property string title |
19 | + property Flickable flickable |
20 | readonly property PageHeadConfiguration head |
21 | PageHeadConfiguration 1.1 |
22 | Object |
23 | @@ -256,6 +266,10 @@ |
24 | property string preset |
25 | readonly property PageHeadSections sections |
26 | property color foregroundColor |
27 | +PageHeadConfiguration 1.3 |
28 | +Toolkit12.PageHeadConfiguration |
29 | + property bool locked |
30 | + property bool visible |
31 | PageHeadSections 1.1 |
32 | QtObject |
33 | property bool enabled |
34 | @@ -692,6 +706,7 @@ |
35 | function tryCompareFunction(func, expectedResult, timeout) |
36 | function typeString(string) |
37 | function warningFormat(line, column, message) |
38 | + function waitForHeaderAnimation(mainView) |
39 | plugins.qmltypes |
40 | name: "FilterBehavior" |
41 | prototype: "QObject" |
42 | |
43 | === modified file 'modules/Ubuntu/Components/AppHeader.qml' |
44 | --- modules/Ubuntu/Components/AppHeader.qml 2015-03-03 13:47:48 +0000 |
45 | +++ modules/Ubuntu/Components/AppHeader.qml 2015-03-23 15:53:11 +0000 |
46 | @@ -1,5 +1,5 @@ |
47 | /* |
48 | - * Copyright 2013-2014 Canonical Ltd. |
49 | + * Copyright 2013-2015 Canonical Ltd. |
50 | * |
51 | * This program is free software; you can redistribute it and/or modify |
52 | * it under the terms of the GNU Lesser General Public License as published by |
53 | @@ -60,7 +60,8 @@ |
54 | internal.movementEnded(); |
55 | } |
56 | |
57 | - visible: title || contents || tabsModel |
58 | + // with PageHeadConfiguration 1.2, always be visible. |
59 | + visible: title || contents || tabsModel || internal.newConfig |
60 | onVisibleChanged: { |
61 | internal.checkFlickableMargins(); |
62 | } |
63 | @@ -69,6 +70,9 @@ |
64 | Show the header |
65 | */ |
66 | function show() { |
67 | + if (internal.newConfig) { |
68 | + header.config.visible = true; |
69 | + } |
70 | header.y = 0; |
71 | } |
72 | |
73 | @@ -76,7 +80,10 @@ |
74 | Hide the header |
75 | */ |
76 | function hide() { |
77 | - header.y = - header.height; |
78 | + if (internal.newConfig) { |
79 | + header.config.visible = false; |
80 | + } |
81 | + header.y = -header.height; |
82 | } |
83 | |
84 | /*! |
85 | @@ -84,15 +91,22 @@ |
86 | */ |
87 | property string title: "" |
88 | onTitleChanged: { |
89 | - header.show(); |
90 | + // deprecated for new versions of PageHeadConfiguration |
91 | + if (!internal.newConfig) { |
92 | + header.show(); |
93 | + } |
94 | } |
95 | |
96 | /*! |
97 | The contents of the header. If this is set, \l title will be ignored. |
98 | + DEPRECATED and replaced by Page.head.contents. |
99 | */ |
100 | property Item contents: null |
101 | onContentsChanged: { |
102 | - header.show(); |
103 | + // deprecated for new versions of PageHeadConfiguration |
104 | + if (!internal.newConfig) { |
105 | + header.show(); |
106 | + } |
107 | } |
108 | |
109 | /*! |
110 | @@ -151,9 +165,10 @@ |
111 | */ |
112 | property Flickable flickable: null |
113 | onFlickableChanged: { |
114 | - internal.checkFlickableMargins(); |
115 | internal.connectFlickable(); |
116 | - header.show(); |
117 | + if (!internal.newConfig || !header.config.locked) { |
118 | + header.show(); |
119 | + } |
120 | } |
121 | |
122 | /*! |
123 | @@ -163,12 +178,68 @@ |
124 | |
125 | /*! |
126 | Configuration of the header. |
127 | + FIXME: Must be of type PageHeadConfiguration. Setting that as the property type |
128 | + however will use the latest version (1.3) and a Page that uses an older |
129 | + version (1.1) will no longer work. |
130 | */ |
131 | - property PageHeadConfiguration config: null |
132 | + property Object config: null |
133 | + onConfigChanged: { |
134 | + // set internal.newConfig because when we rely on the binding, |
135 | + // the value of newConfig may be updated after executing the code below. |
136 | + internal.newConfig = config && config.hasOwnProperty("visible") && |
137 | + config.hasOwnProperty("locked"); |
138 | + internal.connectFlickable(); |
139 | + |
140 | + if (internal.newConfig && header.config.locked &&!header.config.visible) { |
141 | + header.hide(); |
142 | + } else { |
143 | + header.show(); |
144 | + } |
145 | + } |
146 | + Connections { |
147 | + target: header.config |
148 | + ignoreUnknownSignals: true // PageHeadConfiguration <1.2 lacks the signals below |
149 | + onVisibleChanged: { |
150 | + if (header.config.visible) { |
151 | + header.show(); |
152 | + } else { |
153 | + header.hide(); |
154 | + } |
155 | + internal.checkFlickableMargins(); |
156 | + } |
157 | + onLockedChanged: { |
158 | + internal.connectFlickable(); |
159 | + if (!header.config.locked) { |
160 | + internal.movementEnded(); |
161 | + } |
162 | + } |
163 | + } |
164 | + |
165 | + /*! |
166 | + The header is not fully opened or fully closed. |
167 | + |
168 | + This property is true if the header is animating towards a fully |
169 | + opened or fully closed state, or if the header is moving due to user |
170 | + interaction with the flickable. |
171 | + |
172 | + The value of moving is always false when using an old version of |
173 | + PageHeadConfiguration (which does not have the visible property). |
174 | + |
175 | + Used in tst_header_locked_visible.qml. |
176 | + */ |
177 | + readonly property bool moving: internal.newConfig && |
178 | + ((config.visible && header.y !== 0) || |
179 | + (!config.visible && header.y !== -header.height)) |
180 | |
181 | QtObject { |
182 | id: internal |
183 | |
184 | + // This property is updated in header.onConfigChanged to ensure it |
185 | + // is updated before other functions are called in onConfigChanged. |
186 | + property bool newConfig: header.config && |
187 | + header.config.hasOwnProperty("locked") && |
188 | + header.config.hasOwnProperty("visible") |
189 | + |
190 | /*! |
191 | Track the y-position inside the flickable. |
192 | */ |
193 | @@ -183,20 +254,26 @@ |
194 | Disconnect previous flickable, and connect the new one. |
195 | */ |
196 | function connectFlickable() { |
197 | + // Finish the current header movement in case the current |
198 | + // flickable is disconnected while scrolling: |
199 | + internal.movementEnded(); |
200 | + |
201 | if (previousFlickable) { |
202 | previousFlickable.contentYChanged.disconnect(internal.scrollContents); |
203 | previousFlickable.movementEnded.disconnect(internal.movementEnded); |
204 | previousFlickable.interactiveChanged.disconnect(internal.interactiveChanged); |
205 | + previousFlickable = null; |
206 | } |
207 | - if (flickable) { |
208 | + if (flickable && !(internal.newConfig && header.config.locked)) { |
209 | // Connect flicking to movements of the header |
210 | previousContentY = flickable.contentY; |
211 | flickable.contentYChanged.connect(internal.scrollContents); |
212 | flickable.movementEnded.connect(internal.movementEnded); |
213 | flickable.interactiveChanged.connect(internal.interactiveChanged); |
214 | flickable.contentHeightChanged.connect(internal.contentHeightChanged); |
215 | + previousFlickable = flickable; |
216 | } |
217 | - previousFlickable = flickable; |
218 | + internal.checkFlickableMargins(); |
219 | } |
220 | |
221 | /*! |
222 | @@ -216,9 +293,14 @@ |
223 | Fully show or hide the header, depending on its current y. |
224 | */ |
225 | function movementEnded() { |
226 | - if (flickable && flickable.contentY < 0) header.show(); |
227 | - else if (header.y < -header.height/2) header.hide(); |
228 | - else header.show(); |
229 | + if (!(internal.newConfig && header.config.locked)) { |
230 | + if ( (flickable && flickable.contentY < 0) || |
231 | + (header.y > -header.height/2)) { |
232 | + header.show(); |
233 | + } else { |
234 | + header.hide(); |
235 | + } |
236 | + } |
237 | } |
238 | |
239 | /* |
240 | @@ -241,13 +323,20 @@ |
241 | */ |
242 | function checkFlickableMargins() { |
243 | if (header.flickable) { |
244 | - var headerHeight = header.visible ? header.height : 0 |
245 | + var headerHeight = 0; |
246 | + if (header.visible && !(internal.newConfig && |
247 | + header.config.locked && |
248 | + !header.config.visible)) { |
249 | + headerHeight = header.height; |
250 | + } |
251 | + |
252 | if (flickable.topMargin !== headerHeight) { |
253 | + var oldContentY = flickable.contentY; |
254 | var previousHeaderHeight = flickable.topMargin; |
255 | flickable.topMargin = headerHeight; |
256 | // push down contents when header grows, |
257 | // pull up contents when header shrinks. |
258 | - flickable.contentY -= headerHeight - previousHeaderHeight; |
259 | + flickable.contentY = oldContentY - headerHeight + previousHeaderHeight; |
260 | } |
261 | } |
262 | } |
263 | |
264 | === modified file 'modules/Ubuntu/Components/MainView.qml' |
265 | --- modules/Ubuntu/Components/MainView.qml 2015-03-03 13:47:48 +0000 |
266 | +++ modules/Ubuntu/Components/MainView.qml 2015-03-23 15:53:11 +0000 |
267 | @@ -125,6 +125,7 @@ |
268 | AppHeader { |
269 | // This objectName is used in the MainView autopilot custom proxy object |
270 | // in order to select the application header. |
271 | + // Also used in tst_header_locked_visible.qml. |
272 | objectName: "MainView_Header" |
273 | id: headerItem |
274 | property real bottomY: headerItem.y + headerItem.height |
275 | @@ -136,7 +137,7 @@ |
276 | flickable: internal.activePage ? internal.activePage.flickable : null |
277 | pageStack: internal.activePage ? internal.activePage.pageStack : null |
278 | |
279 | - PageHeadConfiguration { |
280 | + Toolkit.PageHeadConfiguration { |
281 | id: headerConfig |
282 | // for backwards compatibility with deprecated tools property |
283 | actions: internal.activePage ? |
284 | |
285 | === modified file 'modules/Ubuntu/Components/MainView12.qml' |
286 | --- modules/Ubuntu/Components/MainView12.qml 2015-03-03 12:53:42 +0000 |
287 | +++ modules/Ubuntu/Components/MainView12.qml 2015-03-23 15:53:11 +0000 |
288 | @@ -69,6 +69,7 @@ |
289 | AppHeader { |
290 | // This objectName is used in the MainView autopilot custom proxy object |
291 | // in order to select the application header. |
292 | + // Also used in tst_header_locked_visible.qml. |
293 | objectName: "MainView_Header" |
294 | id: headerItem |
295 | property real bottomY: headerItem.y + headerItem.height |
296 | @@ -80,10 +81,11 @@ |
297 | flickable: internal.activePage ? internal.activePage.flickable : null |
298 | pageStack: internal.activePage ? internal.activePage.pageStack : null |
299 | |
300 | - contents: internal.activePage ? |
301 | + contents: internal.activePage && |
302 | + internal.activePage.hasOwnProperty("__customHeaderContents") ? |
303 | internal.activePage.__customHeaderContents : null |
304 | |
305 | - PageHeadConfiguration { |
306 | + Toolkit.PageHeadConfiguration { |
307 | id: defaultConfig |
308 | // Used when there is no active Page, or a Page 1.0 is used which |
309 | // does not have a PageHeadConfiguration. |
310 | @@ -114,9 +116,13 @@ |
311 | target: Qt.application |
312 | onActiveChanged: { |
313 | if (Qt.application.active) { |
314 | - headerItem.animate = false; |
315 | - headerItem.show(); |
316 | - headerItem.animate = true; |
317 | + if (!(headerItem.config && |
318 | + headerItem.config.hasOwnProperty("locked") && |
319 | + headerItem.locked)) { |
320 | + headerItem.animate = false; |
321 | + headerItem.show(); |
322 | + headerItem.animate = true; |
323 | + } |
324 | } |
325 | } |
326 | } |
327 | @@ -127,11 +133,15 @@ |
328 | |
329 | // Even when using MainView 1.1, we still support Page 1.0. |
330 | // PageBase (=Page 1.0) is the superclass of Page 1.1. |
331 | - property PageBase activePage: isPage(mainView.activeLeafNode) ? mainView.activeLeafNode : null |
332 | + property Item activePage: isPage(mainView.activeLeafNode) ? mainView.activeLeafNode : null |
333 | |
334 | function isPage(item) { |
335 | - return item && item.hasOwnProperty("__isPageTreeNode") && item.__isPageTreeNode && |
336 | - item.hasOwnProperty("title") && item.hasOwnProperty("tools"); |
337 | + return item && item.hasOwnProperty("__isPageTreeNode") && |
338 | + item.__isPageTreeNode && |
339 | + item.hasOwnProperty("title") && |
340 | + item.hasOwnProperty("flickable") && |
341 | + item.hasOwnProperty("active") && |
342 | + item.hasOwnProperty("pageStack") |
343 | } |
344 | } |
345 | |
346 | |
347 | === modified file 'modules/Ubuntu/Components/Page10.qml' |
348 | --- modules/Ubuntu/Components/Page10.qml 2015-03-03 13:47:48 +0000 |
349 | +++ modules/Ubuntu/Components/Page10.qml 2015-03-23 15:53:11 +0000 |
350 | @@ -15,7 +15,8 @@ |
351 | */ |
352 | |
353 | import QtQuick 2.4 |
354 | -import Ubuntu.Components 1.2 as Toolkit |
355 | +import Ubuntu.Components 1.0 as Toolkit |
356 | +import "pageUtils.js" as Utils |
357 | |
358 | /*! |
359 | \internal |
360 | @@ -53,7 +54,7 @@ |
361 | */ |
362 | property Item __customHeaderContents: null |
363 | |
364 | - property Flickable flickable: internal.getFlickableChild(page) |
365 | + property Flickable flickable: Utils.getFlickableChild(page) |
366 | |
367 | /*! \internal */ |
368 | onActiveChanged: { |
369 | @@ -95,34 +96,5 @@ |
370 | when: internal.header && !internal.header.useDeprecatedToolbar && |
371 | page.tools !== null |
372 | } |
373 | - |
374 | - function isVerticalFlickable(object) { |
375 | - if (object && object.hasOwnProperty("flickableDirection") && object.hasOwnProperty("contentHeight")) { |
376 | - var direction = object.flickableDirection; |
377 | - if ( ((direction === Flickable.AutoFlickDirection) && (object.contentHeight !== object.height) ) |
378 | - || direction === Flickable.VerticalFlick |
379 | - || direction === Flickable.HorizontalAndVerticalFlick) { |
380 | - return true; |
381 | - } |
382 | - } |
383 | - return false; |
384 | - } |
385 | - |
386 | - /*! |
387 | - Return the first flickable child of this page. |
388 | - */ |
389 | - function getFlickableChild(item) { |
390 | - if (item && item.hasOwnProperty("children")) { |
391 | - for (var i=0; i < item.children.length; i++) { |
392 | - var child = item.children[i]; |
393 | - if (internal.isVerticalFlickable(child)) { |
394 | - if (child.anchors.top === page.top || child.anchors.fill === page) { |
395 | - return item.children[i]; |
396 | - } |
397 | - } |
398 | - } |
399 | - } |
400 | - return null; |
401 | - } |
402 | } |
403 | } |
404 | |
405 | === modified file 'modules/Ubuntu/Components/Page11.qml' |
406 | --- modules/Ubuntu/Components/Page11.qml 2015-03-03 12:53:42 +0000 |
407 | +++ modules/Ubuntu/Components/Page11.qml 2015-03-23 15:53:11 +0000 |
408 | @@ -15,24 +15,27 @@ |
409 | */ |
410 | |
411 | import QtQuick 2.4 |
412 | +import Ubuntu.Components 1.0 as Toolkit10 |
413 | +import Ubuntu.Components 1.1 as Toolkit11 |
414 | |
415 | /*! \internal */ |
416 | // Documentation in Page.qdoc |
417 | -Page10 { |
418 | +Toolkit10.Page { |
419 | id: page |
420 | /*! |
421 | \qmlproperty PageHeadConfiguration head |
422 | */ |
423 | readonly property alias head: headerConfig |
424 | - PageHeadConfiguration { |
425 | + Toolkit11.PageHeadConfiguration { |
426 | id: headerConfig |
427 | +// visible: false |
428 | } |
429 | |
430 | onToolsChanged: { |
431 | print("Page.tools is a deprecated property. Please use Page.head instead."); |
432 | } |
433 | |
434 | - Object { |
435 | + Toolkit11.Object { |
436 | id: internal |
437 | |
438 | // Note: The bindings below need to check whether headerConfig.contents |
439 | |
440 | === added file 'modules/Ubuntu/Components/Page13.qml' |
441 | --- modules/Ubuntu/Components/Page13.qml 1970-01-01 00:00:00 +0000 |
442 | +++ modules/Ubuntu/Components/Page13.qml 2015-03-23 15:53:11 +0000 |
443 | @@ -0,0 +1,85 @@ |
444 | +/* |
445 | + * Copyright 2015 Canonical Ltd. |
446 | + * |
447 | + * This program is free software; you can redistribute it and/or modify |
448 | + * it under the terms of the GNU Lesser General Public License as published by |
449 | + * the Free Software Foundation; version 3. |
450 | + * |
451 | + * This program is distributed in the hope that it will be useful, |
452 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
453 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
454 | + * GNU Lesser General Public License for more details. |
455 | + * |
456 | + * You should have received a copy of the GNU Lesser General Public License |
457 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
458 | + */ |
459 | + |
460 | +import QtQuick 2.4 |
461 | +import Ubuntu.Components 1.3 as Toolkit13 |
462 | +import "pageUtils.js" as Utils |
463 | + |
464 | +/*! |
465 | + \internal |
466 | + Documentation is in Page.qdoc |
467 | +*/ |
468 | +PageTreeNode { |
469 | + id: page |
470 | + anchors { |
471 | + left: parent ? parent.left : undefined |
472 | + bottom: parent ? parent.bottom : undefined |
473 | + } |
474 | + // Set width and height so that a parent Loader can be automatically resized |
475 | + // to the size of the loaded Page. |
476 | + width: parentNode ? parentNode.width - page.x : undefined |
477 | + height: parentNode ? page.flickable ? parentNode.height : parentNode.height - internal.headerHeight : undefined |
478 | + |
479 | + isLeaf: true |
480 | + property string title: parentNode && parentNode.hasOwnProperty("title") ? parentNode.title : "" |
481 | + property Flickable flickable: Utils.getFlickableChild(page) |
482 | + |
483 | + /*! |
484 | + \qmlproperty PageHeadConfiguration head |
485 | + */ |
486 | + readonly property alias head: headerConfig |
487 | + Toolkit13.PageHeadConfiguration { |
488 | + id: headerConfig |
489 | + } |
490 | + |
491 | + Object { |
492 | + id: internal |
493 | + |
494 | + property AppHeader header: page.__propagated && page.__propagated.header ? page.__propagated.header : null |
495 | + // Used to position the Page when there is no flickable. |
496 | + // When there is a flickable, the header will automatically position it. |
497 | + // FIXME TIM: Check this with the new API |
498 | + property real headerHeight: internal.header && internal.header.visible ? internal.header.height : 0 |
499 | + |
500 | + // Note: The bindings below need to check whether headerConfig.contents |
501 | + // is valid in the "value", even when that is required in the Binding's "when" |
502 | + // property, to avoid TypeErrors while/after a page becomes (in)active. |
503 | + // |
504 | + // Note 2: contents.parent binding is made by PageHeadStyle. |
505 | + property bool hasParent: headerConfig.contents && |
506 | + headerConfig.contents.parent |
507 | + |
508 | + Binding { |
509 | + target: headerConfig.contents |
510 | + property: "visible" |
511 | + value: page.active |
512 | + when: headerConfig.contents |
513 | + } |
514 | + Binding { |
515 | + target: headerConfig.contents |
516 | + property: "anchors.verticalCenter" |
517 | + value: internal.hasParent ? headerConfig.contents.parent.verticalCenter : |
518 | + undefined |
519 | + when: headerConfig.contents |
520 | + } |
521 | + Binding { |
522 | + target: headerConfig.contents |
523 | + property: "anchors.left" |
524 | + value: internal.hasParent ? headerConfig.contents.parent.left : undefined |
525 | + when: headerConfig.contents |
526 | + } |
527 | + } |
528 | +} |
529 | |
530 | === added file 'modules/Ubuntu/Components/PageHeadConfiguration.qdoc' |
531 | --- modules/Ubuntu/Components/PageHeadConfiguration.qdoc 1970-01-01 00:00:00 +0000 |
532 | +++ modules/Ubuntu/Components/PageHeadConfiguration.qdoc 2015-03-23 15:53:11 +0000 |
533 | @@ -0,0 +1,202 @@ |
534 | +/* |
535 | + * Copyright 2014-2015 Canonical Ltd. |
536 | + * |
537 | + * This program is free software; you can redistribute it and/or modify |
538 | + * it under the terms of the GNU Lesser General Public License as published by |
539 | + * the Free Software Foundation; version 3. |
540 | + * |
541 | + * This program is distributed in the hope that it will be useful, |
542 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
543 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
544 | + * GNU Lesser General Public License for more details. |
545 | + * |
546 | + * You should have received a copy of the GNU Lesser General Public License |
547 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
548 | + */ |
549 | + |
550 | +/*! |
551 | + \qmltype PageHeadConfiguration |
552 | + \inqmlmodule Ubuntu.Components 1.1 |
553 | + \ingroup ubuntu |
554 | + \since Ubuntu.Components 1.1 |
555 | + \brief Page.head is used to configure the header for a \l Page. |
556 | + |
557 | + For examples how to use Page.head, see \l Page. |
558 | + */ |
559 | + |
560 | +/*! |
561 | + List of actions to show in the header. |
562 | + |
563 | + Example: |
564 | + \qml |
565 | + Page { |
566 | + title: "Custom header actions" |
567 | + head.actions: [ |
568 | + Action { |
569 | + iconName: "save" |
570 | + text: i18n.tr("Save") |
571 | + }, |
572 | + Action { |
573 | + iconName: "add" |
574 | + text: i18n.tr("Add") |
575 | + } |
576 | + ] |
577 | + } |
578 | + \endqml |
579 | + \qmlproperty list<Action> PageHeadConfiguration::actions |
580 | + */ |
581 | + |
582 | +/*! |
583 | + \qmlproperty Action PageHeadConfiguration::backAction |
584 | + Overrides the default \l PageStack back button and the |
585 | + \l Tabs drawer button in the header. |
586 | + |
587 | + Example: |
588 | + \qml |
589 | + Page { |
590 | + title: "Back Action Page" |
591 | + head.backAction: Action { |
592 | + iconName: "close" |
593 | + onTriggered: { |
594 | + console.log("Run custom back action") |
595 | + } |
596 | + } |
597 | + } |
598 | + \endqml |
599 | + */ |
600 | + |
601 | +/*! |
602 | + \qmlproperty Item PageHeadConfiguration::contents |
603 | + Set this property to show this Item in the header instead of |
604 | + the title. Use a \l TextField here for implementing search in header. |
605 | + |
606 | + The parent of this Item will be binded while the \l Page is active. |
607 | + The header contents will automatically be anchored to the left and |
608 | + vertically centered inside the header. |
609 | + |
610 | + Example: |
611 | + \qml |
612 | + Page { |
613 | + title: "Invisible title" |
614 | + head.contents: Rectangle { |
615 | + color: UbuntuColors.orange |
616 | + height: units.gu(5) |
617 | + width: parent ? parent.width - units.gu(2) : undefined |
618 | + } |
619 | + } |
620 | + \endqml |
621 | + |
622 | + See \l PageHeadState for an example that shows how search mode can |
623 | + be implemented. |
624 | + */ |
625 | + |
626 | +// FIXME: The example below can be much simplified using PageHeadState |
627 | +// when bug #1345775 has been fixed. |
628 | +/*! |
629 | + \qmlproperty string PageHeadConfiguration::preset |
630 | + Choose a preset for the header visuals and behavior. |
631 | + The default is an empty string "". |
632 | + By setting this to "select", title will be hidden and |
633 | + actions will be represented by icons with a label. |
634 | + |
635 | + Example: |
636 | + \qml |
637 | + import QtQuick 2.4 |
638 | + import Ubuntu.Components 1.2 |
639 | + |
640 | + MainView { |
641 | + id: mainView |
642 | + width: units.gu(40) |
643 | + height: units.gu(50) |
644 | + |
645 | + Page { |
646 | + id: page |
647 | + title: "Demo" |
648 | + |
649 | + state: "default" |
650 | + states: [ |
651 | + PageHeadState { |
652 | + name: "default" |
653 | + head: page.head |
654 | + actions: [ |
655 | + Action { |
656 | + iconName: "contact" |
657 | + text: "Contact" |
658 | + } |
659 | + ] |
660 | + }, |
661 | + State { |
662 | + id: selectState |
663 | + name: "select" |
664 | + |
665 | + property Action leaveSelect: Action { |
666 | + iconName: "back" |
667 | + text: "Back" |
668 | + onTriggered: page.state = "default" |
669 | + } |
670 | + property list<Action> actions: [ |
671 | + Action { |
672 | + iconName: "select" |
673 | + text: "Select All" |
674 | + }, |
675 | + Action { |
676 | + iconName: "delete" |
677 | + text: "Delete" |
678 | + } |
679 | + ] |
680 | + PropertyChanges { |
681 | + target: page.head |
682 | + backAction: selectState.leaveSelect |
683 | + actions: selectState.actions |
684 | + preset: "select" |
685 | + } |
686 | + } |
687 | + ] |
688 | + |
689 | + Label { |
690 | + anchors.centerIn: parent |
691 | + text: "Use back button to leave selection mode." |
692 | + visible: page.state == "select" |
693 | + } |
694 | + |
695 | + Button { |
696 | + anchors.centerIn: parent |
697 | + onClicked: page.state = "select" |
698 | + visible: page.state != "select" |
699 | + text: "selection mode" |
700 | + } |
701 | + } |
702 | + } |
703 | + \endqml |
704 | + */ |
705 | + |
706 | +/*! |
707 | + \qmlproperty PageHeadSections PageHeadConfiguration::sections |
708 | + Defines the sections in the page header divider. |
709 | + */ |
710 | + |
711 | +/*! |
712 | + \qmlproperty color PageHeadConfiguration::foregroundColor |
713 | + The color of the text and icons. |
714 | + */ |
715 | + |
716 | +/*! |
717 | + \qmlproperty bool PageHeadConfiguration::locked |
718 | + \since 1.2 |
719 | + When the \l Page is active, the locked property controls the behavior |
720 | + of the header. A locked header stays visible or invisible, depending |
721 | + on the value of the \l visible property. An unlocked header automatically |
722 | + shows and hides if the \l Page has a flickable in which the user |
723 | + scrolls up or down. |
724 | + Default value: false |
725 | + */ |
726 | + |
727 | +/*! |
728 | + \qmlproperty bool PageHeadConfiguration::visible |
729 | + \since 1.2 |
730 | + Update the value of the visible property to show or hide the header. |
731 | + This works both when the header is \l locked and unlocked. An unlocked |
732 | + header can also become visible or hidden when the user scrolls the |
733 | + active \l Page's flickable. The value of the visible property will be |
734 | + updated at the end of the showing/hiding animation of the header. |
735 | + */ |
736 | |
737 | === renamed file 'modules/Ubuntu/Components/PageHeadConfiguration.qml' => 'modules/Ubuntu/Components/PageHeadConfiguration11.qml' |
738 | --- modules/Ubuntu/Components/PageHeadConfiguration.qml 2015-03-03 13:47:48 +0000 |
739 | +++ modules/Ubuntu/Components/PageHeadConfiguration11.qml 2015-03-23 15:53:11 +0000 |
740 | @@ -15,92 +15,24 @@ |
741 | */ |
742 | |
743 | import QtQuick 2.4 |
744 | -import Ubuntu.Components 1.2 |
745 | +import Ubuntu.Components 1.1 |
746 | |
747 | /*! |
748 | - \qmltype PageHeadConfiguration |
749 | - \inqmlmodule Ubuntu.Components 1.1 |
750 | - \ingroup ubuntu |
751 | - \since Ubuntu.Components 1.1 |
752 | - \brief Page.head is used to configure the header for a \l Page. |
753 | - |
754 | - For examples how to use Page.head, see \l Page. |
755 | + \internal |
756 | + Documented in PageHeadConfiguration.qdoc |
757 | */ |
758 | Object { |
759 | // To be used inside a Page only. |
760 | id: headerConfig |
761 | |
762 | - /*! |
763 | - List of actions to show in the header. |
764 | - |
765 | - Example: |
766 | - \qml |
767 | - Page { |
768 | - title: "Custom header actions" |
769 | - head.actions: [ |
770 | - Action { |
771 | - iconName: "save" |
772 | - text: i18n.tr("Save") |
773 | - }, |
774 | - Action { |
775 | - iconName: "add" |
776 | - text: i18n.tr("Add") |
777 | - } |
778 | - ] |
779 | - } |
780 | - \endqml |
781 | - */ |
782 | property list<Action> actions |
783 | - |
784 | - /*! |
785 | - Overrides the default \l PageStack back button and the |
786 | - \l Tabs drawer button in the header. |
787 | - |
788 | - Example: |
789 | - \qml |
790 | - Page { |
791 | - title: "Back Action Page" |
792 | - head.backAction: Action { |
793 | - iconName: "close" |
794 | - onTriggered: { |
795 | - console.log("Run custom back action") |
796 | - } |
797 | - } |
798 | - } |
799 | - \endqml |
800 | - */ |
801 | property Action backAction: null |
802 | - |
803 | - /*! |
804 | - Set this property to show this Item in the header instead of |
805 | - the title. Use a \l TextField here for implementing search in header. |
806 | - |
807 | - The parent of this Item will be binded while the \l Page is active. |
808 | - The header contents will automatically be anchored to the left and |
809 | - vertically centered inside the header. |
810 | - |
811 | - Example: |
812 | - \qml |
813 | - Page { |
814 | - title: "Invisible title" |
815 | - head.contents: Rectangle { |
816 | - color: UbuntuColors.orange |
817 | - height: units.gu(5) |
818 | - width: parent ? parent.width - units.gu(2) : undefined |
819 | - } |
820 | - } |
821 | - \endqml |
822 | - |
823 | - See \l PageHeadState for an example that shows how search mode can |
824 | - be implemented. |
825 | - */ |
826 | property Item contents: null |
827 | |
828 | QtObject { |
829 | id: internal |
830 | property Item oldContents: null |
831 | } |
832 | - |
833 | onContentsChanged: { |
834 | if (internal.oldContents) { |
835 | // FIX: bug #1341814 and #1400297 |
836 | @@ -111,97 +43,13 @@ |
837 | internal.oldContents = contents; |
838 | } |
839 | |
840 | - // FIXME: The example below can be much simplified using PageHeadState |
841 | - // when bug #1345775 has been fixed. |
842 | - /*! |
843 | - Choose a preset for the header visuals and behavior. |
844 | - The default is an empty string "". |
845 | - By setting this to "select", title will be hidden and |
846 | - actions will be represented by icons with a label. |
847 | - |
848 | - Example: |
849 | - \qml |
850 | - import QtQuick 2.4 |
851 | - import Ubuntu.Components 1.2 |
852 | - |
853 | - MainView { |
854 | - id: mainView |
855 | - width: units.gu(40) |
856 | - height: units.gu(50) |
857 | - |
858 | - Page { |
859 | - id: page |
860 | - title: "Demo" |
861 | - |
862 | - state: "default" |
863 | - states: [ |
864 | - PageHeadState { |
865 | - name: "default" |
866 | - head: page.head |
867 | - actions: [ |
868 | - Action { |
869 | - iconName: "contact" |
870 | - text: "Contact" |
871 | - } |
872 | - ] |
873 | - }, |
874 | - State { |
875 | - id: selectState |
876 | - name: "select" |
877 | - |
878 | - property Action leaveSelect: Action { |
879 | - iconName: "back" |
880 | - text: "Back" |
881 | - onTriggered: page.state = "default" |
882 | - } |
883 | - property list<Action> actions: [ |
884 | - Action { |
885 | - iconName: "select" |
886 | - text: "Select All" |
887 | - }, |
888 | - Action { |
889 | - iconName: "delete" |
890 | - text: "Delete" |
891 | - } |
892 | - ] |
893 | - PropertyChanges { |
894 | - target: page.head |
895 | - backAction: selectState.leaveSelect |
896 | - actions: selectState.actions |
897 | - preset: "select" |
898 | - } |
899 | - } |
900 | - ] |
901 | - |
902 | - Label { |
903 | - anchors.centerIn: parent |
904 | - text: "Use back button to leave selection mode." |
905 | - visible: page.state == "select" |
906 | - } |
907 | - |
908 | - Button { |
909 | - anchors.centerIn: parent |
910 | - onClicked: page.state = "select" |
911 | - visible: page.state != "select" |
912 | - text: "selection mode" |
913 | - } |
914 | - } |
915 | - } |
916 | - \endqml |
917 | - */ |
918 | property string preset: "" |
919 | - |
920 | /*! |
921 | \qmlproperty PageHeadSections sections |
922 | - Defines the sections in the page header divider. |
923 | */ |
924 | readonly property alias sections: headSections |
925 | PageHeadSections { |
926 | id: headSections |
927 | } |
928 | - |
929 | - /*! |
930 | - The color of the text and icons. |
931 | - */ |
932 | property color foregroundColor: Theme.palette.selected.backgroundText |
933 | } |
934 | |
935 | === added file 'modules/Ubuntu/Components/PageHeadConfiguration13.qml' |
936 | --- modules/Ubuntu/Components/PageHeadConfiguration13.qml 1970-01-01 00:00:00 +0000 |
937 | +++ modules/Ubuntu/Components/PageHeadConfiguration13.qml 2015-03-23 15:53:11 +0000 |
938 | @@ -0,0 +1,30 @@ |
939 | +/* |
940 | + * Copyright 2015 Canonical Ltd. |
941 | + * |
942 | + * This program is free software; you can redistribute it and/or modify |
943 | + * it under the terms of the GNU Lesser General Public License as published by |
944 | + * the Free Software Foundation; version 3. |
945 | + * |
946 | + * This program is distributed in the hope that it will be useful, |
947 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
948 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
949 | + * GNU Lesser General Public License for more details. |
950 | + * |
951 | + * You should have received a copy of the GNU Lesser General Public License |
952 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
953 | + */ |
954 | + |
955 | +import Ubuntu.Components 1.2 as Toolkit12 |
956 | + |
957 | +/*! |
958 | + \internal |
959 | + documented in PageHeadConfiguration.qdoc |
960 | + */ |
961 | +Toolkit12.PageHeadConfiguration { |
962 | + id: headerConfig |
963 | + |
964 | + property bool locked: false |
965 | + |
966 | + // auto-updated by AppHeader, but may be set by the developer |
967 | + property bool visible |
968 | +} |
969 | |
970 | === modified file 'modules/Ubuntu/Components/Tabs.qml' |
971 | --- modules/Ubuntu/Components/Tabs.qml 2015-03-05 09:35:06 +0000 |
972 | +++ modules/Ubuntu/Components/Tabs.qml 2015-03-23 15:53:11 +0000 |
973 | @@ -310,7 +310,10 @@ |
974 | if (tabBar && tabBar.__styleInstance && tabBar.__styleInstance.hasOwnProperty("sync")) { |
975 | tabBar.__styleInstance.sync(); |
976 | } |
977 | - if (tabs.active && internal.header) { |
978 | + if ((tabs.active && internal.header) && |
979 | + !(internal.header.config && |
980 | + internal.header.config.hasOwnProperty("locked") && |
981 | + internal.header.config.locked)) { |
982 | internal.header.show(); |
983 | } |
984 | // deprecated, however use it till we remove it completely |
985 | |
986 | === added file 'modules/Ubuntu/Components/pageUtils.js' |
987 | --- modules/Ubuntu/Components/pageUtils.js 1970-01-01 00:00:00 +0000 |
988 | +++ modules/Ubuntu/Components/pageUtils.js 2015-03-23 15:53:11 +0000 |
989 | @@ -0,0 +1,47 @@ |
990 | +/* |
991 | + * Copyright 2015 Canonical Ltd. |
992 | + * |
993 | + * This program is free software; you can redistribute it and/or modify |
994 | + * it under the terms of the GNU Lesser General Public License as published by |
995 | + * the Free Software Foundation; version 3. |
996 | + * |
997 | + * This program is distributed in the hope that it will be useful, |
998 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
999 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1000 | + * GNU Lesser General Public License for more details. |
1001 | + * |
1002 | + * You should have received a copy of the GNU Lesser General Public License |
1003 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1004 | + */ |
1005 | + |
1006 | +/*! |
1007 | + Return true if the object is a Flickable that can be flicked in vertical direction. |
1008 | + */ |
1009 | +function isVerticalFlickable(object) { |
1010 | + if (object && object.hasOwnProperty("flickableDirection") && object.hasOwnProperty("contentHeight")) { |
1011 | + var direction = object.flickableDirection; |
1012 | + if ( ((direction === Flickable.AutoFlickDirection) && (object.contentHeight !== object.height) ) |
1013 | + || direction === Flickable.VerticalFlick |
1014 | + || direction === Flickable.HorizontalAndVerticalFlick) { |
1015 | + return true; |
1016 | + } |
1017 | + } |
1018 | + return false; |
1019 | +} |
1020 | + |
1021 | +/*! |
1022 | + Return the first child of the item that is flickable in the vertical direction. |
1023 | + */ |
1024 | +function getFlickableChild(item) { |
1025 | + if (item && item.hasOwnProperty("children")) { |
1026 | + for (var i=0; i < item.children.length; i++) { |
1027 | + var child = item.children[i]; |
1028 | + if (isVerticalFlickable(child)) { |
1029 | + if (child.anchors.top === page.top || child.anchors.fill === page) { |
1030 | + return item.children[i]; |
1031 | + } |
1032 | + } |
1033 | + } |
1034 | + } |
1035 | + return null; |
1036 | +} |
1037 | |
1038 | === modified file 'modules/Ubuntu/Components/qmldir' |
1039 | --- modules/Ubuntu/Components/qmldir 2015-03-02 13:39:03 +0000 |
1040 | +++ modules/Ubuntu/Components/qmldir 2015-03-23 15:53:11 +0000 |
1041 | @@ -98,7 +98,7 @@ |
1042 | UbuntuListView 1.1 UbuntuListView11.qml |
1043 | internal PageBase Page10.qml |
1044 | Page 1.1 Page11.qml |
1045 | -PageHeadConfiguration 1.1 PageHeadConfiguration.qml |
1046 | +PageHeadConfiguration 1.1 PageHeadConfiguration11.qml |
1047 | PageHeadSections 1.1 PageHeadSections.qml |
1048 | PageHeadState 1.1 PageHeadState.qml |
1049 | Icon 1.1 Icon11.qml |
1050 | @@ -111,3 +111,7 @@ |
1051 | #version 1.2 |
1052 | MainView 1.2 MainView12.qml |
1053 | Captions 1.2 Captions.qml |
1054 | + |
1055 | +#version 1.3 |
1056 | +Page 1.3 Page13.qml |
1057 | +PageHeadConfiguration 1.3 PageHeadConfiguration13.qml |
1058 | |
1059 | === modified file 'modules/Ubuntu/Test/UbuntuTestCase.qml' |
1060 | --- modules/Ubuntu/Test/UbuntuTestCase.qml 2015-03-03 13:47:48 +0000 |
1061 | +++ modules/Ubuntu/Test/UbuntuTestCase.qml 2015-03-23 15:53:11 +0000 |
1062 | @@ -115,10 +115,10 @@ |
1063 | var iy = 0; |
1064 | |
1065 | for (var step=0; step < steps; step++) { |
1066 | - if (ix < abs_dx) { |
1067 | + if (Math.abs(ix) < abs_dx) { |
1068 | ix += step_dx; |
1069 | } |
1070 | - if (iy < abs_dy) { |
1071 | + if (Math.abs(iy) < abs_dy) { |
1072 | iy += step_dy; |
1073 | } |
1074 | mouseMove(item, x + ix, y + iy, stepdelay); |
1075 | @@ -237,4 +237,22 @@ |
1076 | function warningFormat(line, column, message) { |
1077 | return util.callerFile() + ":" + line + ":" + column + ": " + message; |
1078 | } |
1079 | + |
1080 | + /*! |
1081 | + Wait for animations of the header and the style inside the header to finish. |
1082 | + The MainView that has the header that may animate must be passed as an argument. |
1083 | + */ |
1084 | + function waitForHeaderAnimation(mainView) { |
1085 | + var header = findChild(mainView, "MainView_Header"); |
1086 | + verify(header !== null, "Could not find header."); |
1087 | + var headerStyle = findChild(header, "PageHeadStyle"); |
1088 | + verify(headerStyle !== null, "Could not find header style."); |
1089 | + |
1090 | + // Wait for the header to start to move: |
1091 | + wait(50); |
1092 | + // Wait for animation of the style inside the header (when pushing/popping): |
1093 | + tryCompareFunction(function(){ return headerStyle.animating }, false); |
1094 | + // Wait for the header to finish showing/hiding: |
1095 | + tryCompareFunction(function(){ return header.moving }, false); |
1096 | + } |
1097 | } |
1098 | |
1099 | === modified file 'tests/autopilot/ubuntuuitoolkit/_custom_proxy_objects/_header.py' |
1100 | --- tests/autopilot/ubuntuuitoolkit/_custom_proxy_objects/_header.py 2015-03-04 21:57:25 +0000 |
1101 | +++ tests/autopilot/ubuntuuitoolkit/_custom_proxy_objects/_header.py 2015-03-23 15:53:11 +0000 |
1102 | @@ -1,6 +1,6 @@ |
1103 | # -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*- |
1104 | # |
1105 | -# Copyright (C) 2012, 2013, 2014 Canonical Ltd. |
1106 | +# Copyright (C) 2012-2015 Canonical Ltd. |
1107 | # |
1108 | # This program is free software; you can redistribute it and/or modify |
1109 | # it under the terms of the GNU Lesser General Public License as published by |
1110 | @@ -64,6 +64,9 @@ |
1111 | # so no need to wait. |
1112 | return |
1113 | |
1114 | + # Wait showing/hiding animation of the header. |
1115 | + self.moving.wait_for(False) |
1116 | + |
1117 | @autopilot_logging.log_action(logger.info) |
1118 | def switch_to_section_by_index(self, index): |
1119 | """Select a section in the header divider |
1120 | |
1121 | === removed file 'tests/resources/header/lockedToolbar.deprecated.qml' |
1122 | --- tests/resources/header/lockedToolbar.deprecated.qml 2015-03-06 12:42:00 +0000 |
1123 | +++ tests/resources/header/lockedToolbar.deprecated.qml 1970-01-01 00:00:00 +0000 |
1124 | @@ -1,52 +0,0 @@ |
1125 | -/* |
1126 | - * Copyright (C) 2014 Canonical Ltd. |
1127 | - * |
1128 | - * This program is free software; you can redistribute it and/or modify |
1129 | - * it under the terms of the GNU Lesser General Public License as published by |
1130 | - * the Free Software Foundation; version 3. |
1131 | - * |
1132 | - * This program is distributed in the hope that it will be useful, |
1133 | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1134 | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1135 | - * GNU Lesser General Public License for more details. |
1136 | - * |
1137 | - * You should have received a copy of the GNU Lesser General Public License |
1138 | - * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1139 | - */ |
1140 | - |
1141 | -import QtQuick 2.0 |
1142 | -import Ubuntu.Components 1.1 |
1143 | - |
1144 | -MainView { |
1145 | - width: units.gu(50) |
1146 | - height: units.gu(80) |
1147 | - id: mainView |
1148 | - |
1149 | - Page { |
1150 | - id: page |
1151 | - title: "test page" |
1152 | - Label { |
1153 | - anchors.centerIn: parent |
1154 | - text: "testing the toolbar" |
1155 | - } |
1156 | - tools: ToolbarItems { |
1157 | - id: toolbarItems |
1158 | - ToolbarButton { |
1159 | - text: "action1" |
1160 | - } |
1161 | - } |
1162 | - } |
1163 | - |
1164 | - ToolbarItems { |
1165 | - id: lockedTools |
1166 | - ToolbarButton { |
1167 | - text: "locked" |
1168 | - } |
1169 | - locked: true |
1170 | - opened: true |
1171 | - } |
1172 | - |
1173 | - Component.onCompleted: { |
1174 | - page.tools = lockedTools; |
1175 | - } |
1176 | -} |
1177 | |
1178 | === modified file 'tests/unit_x11/tst_components/tst_header_actions.qml' |
1179 | --- tests/unit_x11/tst_components/tst_header_actions.qml 2015-03-06 12:42:00 +0000 |
1180 | +++ tests/unit_x11/tst_components/tst_header_actions.qml 2015-03-23 15:53:11 +0000 |
1181 | @@ -1,5 +1,5 @@ |
1182 | /* |
1183 | - * Copyright 2014 Canonical Ltd. |
1184 | + * Copyright 2014-2015 Canonical Ltd. |
1185 | * |
1186 | * This program is free software; you can redistribute it and/or modify |
1187 | * it under the terms of the GNU Lesser General Public License as published by |
1188 | @@ -14,9 +14,9 @@ |
1189 | * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1190 | */ |
1191 | |
1192 | -import QtQuick 2.2 |
1193 | +import QtQuick 2.4 |
1194 | import Ubuntu.Test 1.0 |
1195 | -import Ubuntu.Components 1.1 |
1196 | +import Ubuntu.Components 1.2 |
1197 | |
1198 | // NOTE: Other parts of the page head API are tested with autopilot in |
1199 | // ubuntuuitoolkit.tests.components.test_header |
1200 | @@ -28,7 +28,6 @@ |
1201 | MainView { |
1202 | id: mainView |
1203 | anchors.fill: parent |
1204 | - useDeprecatedToolbar: false |
1205 | |
1206 | PageStack { |
1207 | id: pageStack |
1208 | @@ -61,55 +60,48 @@ |
1209 | when: windowShown |
1210 | id: testCase |
1211 | |
1212 | - property var app_header |
1213 | property var back_button |
1214 | property var custom_back_button |
1215 | - property var head_style |
1216 | |
1217 | function initTestCase() { |
1218 | - testCase.app_header = findChild(mainView, "MainView_Header"); |
1219 | + var app_header = findChild(mainView, "MainView_Header"); |
1220 | testCase.back_button = findChild(app_header, "backButton"); |
1221 | testCase.custom_back_button = findChild(app_header, "customBackButton"); |
1222 | - testCase.head_style = findChild(app_header, "PageHeadStyle"); |
1223 | |
1224 | - wait_for_animation(); |
1225 | + waitForHeaderAnimation(mainView); |
1226 | compare(page2.head.backAction, null, "Back action set by default."); |
1227 | compare(back_button.visible, false, "Back button visible with only 1 page on the stack."); |
1228 | compare(custom_back_button.visible, false, "Custom back button visible without custom back action.") |
1229 | } |
1230 | |
1231 | - function wait_for_animation() { |
1232 | - tryCompareFunction(function(){return testCase.head_style.animating}, false); |
1233 | - } |
1234 | - |
1235 | function test_default_back_button() { |
1236 | pageStack.push(page2); |
1237 | - wait_for_animation(); |
1238 | + waitForHeaderAnimation(mainView); |
1239 | compare(back_button.visible, true, "Back button not visible with 2 pages on stack."); |
1240 | compare(custom_back_button.visible, false, "Showing custom back button without custom back action."); |
1241 | pageStack.pop(); |
1242 | - wait_for_animation(); |
1243 | + waitForHeaderAnimation(mainView); |
1244 | } |
1245 | |
1246 | function test_custom_back_button() { |
1247 | page2.head.backAction = customBackAction; |
1248 | pageStack.push(page2); |
1249 | - wait_for_animation(); |
1250 | + waitForHeaderAnimation(mainView); |
1251 | compare(back_button.visible, false, "Default back button visible with custom back action."); |
1252 | compare(custom_back_button.visible, true, "Custom back button invisible with back action."); |
1253 | pageStack.pop(); |
1254 | - wait_for_animation(); |
1255 | + waitForHeaderAnimation(mainView); |
1256 | page2.head.backAction = null; |
1257 | } |
1258 | |
1259 | function test_no_back_button() { |
1260 | page2.head.backAction = invisibleAction; |
1261 | pageStack.push(page2); |
1262 | - wait_for_animation(); |
1263 | + waitForHeaderAnimation(mainView); |
1264 | compare(back_button.visible, false, "Default back button visible with invisible custom back action."); |
1265 | compare(custom_back_button.visible, false, "Custom back button visible with invisible custom back action."); |
1266 | pageStack.pop(); |
1267 | - wait_for_animation(); |
1268 | + waitForHeaderAnimation(mainView); |
1269 | page2.head.backAction = null; |
1270 | } |
1271 | } |
1272 | |
1273 | === modified file 'tests/unit_x11/tst_components/tst_header_contents_width.qml' |
1274 | --- tests/unit_x11/tst_components/tst_header_contents_width.qml 2015-03-03 13:20:06 +0000 |
1275 | +++ tests/unit_x11/tst_components/tst_header_contents_width.qml 2015-03-23 15:53:11 +0000 |
1276 | @@ -14,9 +14,9 @@ |
1277 | * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1278 | */ |
1279 | |
1280 | -import QtQuick 2.2 |
1281 | +import QtQuick 2.4 |
1282 | import Ubuntu.Test 1.0 |
1283 | -import Ubuntu.Components 1.1 |
1284 | +import Ubuntu.Components 1.2 |
1285 | |
1286 | Item { |
1287 | width: units.gu(50) |
1288 | @@ -25,7 +25,6 @@ |
1289 | MainView { |
1290 | id: mainView |
1291 | anchors.fill: parent |
1292 | - useDeprecatedToolbar: false |
1293 | |
1294 | Tabs { |
1295 | id: tabs |
1296 | @@ -69,12 +68,8 @@ |
1297 | |
1298 | property var head_style |
1299 | |
1300 | - function wait_for_animation() { |
1301 | - tryCompareFunction(function(){return testCase.head_style.animating}, false); |
1302 | - } |
1303 | function initTestCase() { |
1304 | - testCase.head_style = findChild(mainView, "PageHeadStyle"); |
1305 | - testCase.wait_for_animation(); |
1306 | + waitForHeaderAnimation(mainView); |
1307 | } |
1308 | |
1309 | function test_header_contents_width_bug1408481() { |
1310 | @@ -82,14 +77,14 @@ |
1311 | testCase.verify(initialWidth > 0, "Initial width has a positive value."); |
1312 | // Select the tab that has more actions. |
1313 | tabs.selectedTabIndex = 1; |
1314 | - testCase.wait_for_animation(); |
1315 | + waitForHeaderAnimation(mainView); |
1316 | // Now less space is available for the header contents, so that the action buttons fit. |
1317 | testCase.verify(searchField.width < initialWidth, "Contents width is reduced."); |
1318 | // Without this wait(), the test does not reproduce bug 1408481. |
1319 | wait(100); |
1320 | // Select the first tab again: |
1321 | tabs.selectedTabIndex = 0; |
1322 | - testCase.wait_for_animation(); |
1323 | + waitForHeaderAnimation(mainView); |
1324 | // Without actions in tab one, the full width is available again for contents |
1325 | testCase.verify(searchField.width === initialWidth, "Contents width is reset."); |
1326 | } |
1327 | |
1328 | === added file 'tests/unit_x11/tst_components/tst_header_visible.qml' |
1329 | --- tests/unit_x11/tst_components/tst_header_visible.qml 1970-01-01 00:00:00 +0000 |
1330 | +++ tests/unit_x11/tst_components/tst_header_visible.qml 2015-03-23 15:53:11 +0000 |
1331 | @@ -0,0 +1,288 @@ |
1332 | +/* |
1333 | + * Copyright (C) 2015 Canonical Ltd. |
1334 | + * |
1335 | + * This program is free software; you can redistribute it and/or modify |
1336 | + * it under the terms of the GNU Lesser General Public License as published by |
1337 | + * the Free Software Foundation; version 3. |
1338 | + * |
1339 | + * This program is distributed in the hope that it will be useful, |
1340 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1341 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1342 | + * GNU Lesser General Public License for more details. |
1343 | + * |
1344 | + * You should have received a copy of the GNU Lesser General Public License |
1345 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1346 | + */ |
1347 | + |
1348 | +import QtQuick 2.4 |
1349 | +import Ubuntu.Components 1.3 |
1350 | +import Ubuntu.Test 1.0 |
1351 | + |
1352 | +Item { |
1353 | + width: units.gu(50) |
1354 | + height: units.gu(70) |
1355 | + |
1356 | + MainView { |
1357 | + id: mainView |
1358 | + width: units.gu(50) |
1359 | + height: units.gu(70) |
1360 | + |
1361 | + PageStack { |
1362 | + id: stack |
1363 | + Component.onCompleted: stack.push(page) |
1364 | + |
1365 | + Page { |
1366 | + id: page |
1367 | + title: "Auto-hide" |
1368 | + head { |
1369 | + locked: lockedSwitch.checked |
1370 | + onVisibleChanged: { |
1371 | + visibleSwitch.checked = page.head.visible |
1372 | + } |
1373 | + } |
1374 | + Flickable { |
1375 | + id: flickable |
1376 | + anchors.fill: parent |
1377 | + contentHeight: units.gu(200) |
1378 | + Rectangle { |
1379 | + color: "green" |
1380 | + opacity: 0.3 |
1381 | + anchors { |
1382 | + left: parent.left |
1383 | + right: parent.right |
1384 | + top: parent.top |
1385 | + } |
1386 | + height: 1 |
1387 | + } |
1388 | + |
1389 | + Grid { |
1390 | + id: switchGrid |
1391 | + columns: 2 |
1392 | + spacing: units.gu(1) |
1393 | + anchors { |
1394 | + top: parent.top |
1395 | + left: parent.left |
1396 | + leftMargin: units.gu(5) |
1397 | + topMargin: units.gu(15) |
1398 | + } |
1399 | + Switch { |
1400 | + id: lockedSwitch |
1401 | + checked: false |
1402 | + } |
1403 | + Label { |
1404 | + text: "header locked" |
1405 | + } |
1406 | + Switch { |
1407 | + id: visibleSwitch |
1408 | + checked: page.head.visible |
1409 | + onClicked: page.head.visible = checked |
1410 | + } |
1411 | + Label { |
1412 | + text: "header visible" |
1413 | + } |
1414 | + } |
1415 | + Label { |
1416 | + id: label |
1417 | + anchors { |
1418 | + horizontalCenter: parent.horizontalCenter |
1419 | + top: switchGrid.bottom |
1420 | + topMargin: units.gu(15) |
1421 | + } |
1422 | + text: "Flick me" |
1423 | + } |
1424 | + Button { |
1425 | + anchors { |
1426 | + horizontalCenter: parent.horizontalCenter |
1427 | + top: label.bottom |
1428 | + topMargin: units.gu(5) |
1429 | + } |
1430 | + text: "Click me" |
1431 | + onTriggered: stack.push(otherPage) |
1432 | + } |
1433 | + } |
1434 | + } |
1435 | + Page { |
1436 | + id: otherPage |
1437 | + title: "On stack" |
1438 | + visible: false |
1439 | + |
1440 | + Label { |
1441 | + anchors.centerIn: parent |
1442 | + text: "Stacked" |
1443 | + } |
1444 | + } |
1445 | + Page { |
1446 | + id: titleLessPage |
1447 | + visible: false |
1448 | + } |
1449 | + } |
1450 | + } |
1451 | + |
1452 | + UbuntuTestCase { |
1453 | + name: "HeaderLockedVisible" |
1454 | + when: windowShown |
1455 | + id: testCase |
1456 | + |
1457 | + property var header |
1458 | + function initTestCase() { |
1459 | + testCase.header = findChild(mainView, "MainView_Header"); |
1460 | + } |
1461 | + |
1462 | + function init() { |
1463 | + page.head.visible = true; |
1464 | + page.head.locked = false; |
1465 | + otherPage.head.visible = true; |
1466 | + otherPage.head.locked = false; |
1467 | + wait_for_visible(true, "Header is not visible initially."); |
1468 | + compare(stack.currentPage, page, "Wrong Page on PageStack initially."); |
1469 | + compare(page.head.locked, false, "Header is not locked initially."); |
1470 | + } |
1471 | + |
1472 | + function scroll(dy) { |
1473 | + var p = centerOf(mainView); |
1474 | + // Use mouseWheel to scroll because mouseDrag is very unreliable |
1475 | + // and does not properly handle negative values for dy. |
1476 | + mouseWheel(mainView, p.x, p.y, 0, 2*dy); |
1477 | + } |
1478 | + |
1479 | + function scroll_down() { |
1480 | + scroll(-header.height); |
1481 | + } |
1482 | + |
1483 | + function scroll_up() { |
1484 | + scroll(header.height); |
1485 | + } |
1486 | + |
1487 | + function wait_for_visible(visible, errorMessage) { |
1488 | + waitForHeaderAnimation(mainView); |
1489 | + compare(stack.currentPage.head.visible, visible, errorMessage); |
1490 | + var mismatchMessage = " Page.head.visible does not match header visibility."; |
1491 | + if (visible) { |
1492 | + compare(header.y, 0, errorMessage + mismatchMessage); |
1493 | + } else { |
1494 | + compare(header.y, -header.height, errorMessage + mismatchMessage); |
1495 | + } |
1496 | + } |
1497 | + |
1498 | + function test_set_visible_to_hide_and_show() { |
1499 | + page.head.visible = false; |
1500 | + wait_for_visible(false, "Cannot hide unlocked header by setting visible to false."); |
1501 | + page.head.visible = true; |
1502 | + wait_for_visible(true, "Cannot show unlocked header by setting visible to true."); |
1503 | + |
1504 | + page.head.locked = true; |
1505 | + page.head.visible = false; |
1506 | + wait_for_visible(false, "Cannot hide locked header by setting visible to false."); |
1507 | + page.head.visible = true; |
1508 | + wait_for_visible(true, "Cannot show locked header by setting visible to true."); |
1509 | + } |
1510 | + |
1511 | + function test_scroll_when_unlocked_updates_visible() { |
1512 | + scroll_down(); |
1513 | + wait_for_visible(false, "Scrolling down does not hide header."); |
1514 | + scroll_up(); |
1515 | + wait_for_visible(true, "Scrolling up does not show header."); |
1516 | + } |
1517 | + |
1518 | + function test_scroll_when_locked_does_not_update_visible() { |
1519 | + // Note that with a locked header, scrolling up and down does not |
1520 | + // cause the header to move, so the wait_for_visible() calls below |
1521 | + // will return almost instantly. |
1522 | + page.head.locked = true; |
1523 | + scroll_down(); |
1524 | + wait_for_visible(true, "Scrolling down hides locked header."); |
1525 | + scroll_up(); |
1526 | + wait_for_visible(true, "Scrolling up hides locked header."); |
1527 | + |
1528 | + page.head.visible = false; |
1529 | + waitForHeaderAnimation(mainView); |
1530 | + scroll_down(); |
1531 | + wait_for_visible(false, "Scrolling down shows locked header."); |
1532 | + scroll_up(); |
1533 | + wait_for_visible(false, "Scrolling up shows locked header."); |
1534 | + } |
1535 | + |
1536 | + function test_locking_updates_visible() { |
1537 | + // locked = false, visible = true. |
1538 | + page.head.locked = true; |
1539 | + wait_for_visible(true, "Locking hides header."); |
1540 | + page.head.locked = false; |
1541 | + wait_for_visible(true, "Unlocking hides header."); |
1542 | + |
1543 | + page.head.locked = true; |
1544 | + page.head.visible = false; |
1545 | + waitForHeaderAnimation(mainView); |
1546 | + // When the flickable is scrolled to the top, unlocking the header must show |
1547 | + // the header because you cannot scroll more up to reveal it: |
1548 | + page.head.locked = false; |
1549 | + wait_for_visible(true, "Unlocking header when flickable is at Y beginning "+ |
1550 | + "does not show header."); |
1551 | + |
1552 | + scroll_down(); |
1553 | + wait_for_visible(false, "Scrolling down does not hide header."); |
1554 | + page.head.locked = true; |
1555 | + wait_for_visible(false, "Locking shows header."); |
1556 | + // When flickable is scrolled down, unlocking header does not show header |
1557 | + // because the user can scroll up to reveal it: |
1558 | + page.head.locked = false; |
1559 | + wait_for_visible(false, "Unlocking shows header when flickable is not at " + |
1560 | + "Y beginning."); |
1561 | + } |
1562 | + |
1563 | + function test_activate_page_shows_header() { |
1564 | + page.head.visible = false; |
1565 | + waitForHeaderAnimation(mainView); |
1566 | + |
1567 | + // Header becomes visible when new Page becomes active: |
1568 | + stack.push(otherPage); |
1569 | + wait_for_visible(true, "Pushing page on stack does not show header."); |
1570 | + |
1571 | + // Header becomes visible when Page with previously hidden header |
1572 | + // becomes active: |
1573 | + stack.pop(); |
1574 | + wait_for_visible(true, "Activating unlocked Page does not make header visible."); |
1575 | + } |
1576 | + |
1577 | + function test_activate_hides_locked_hidden_header() { |
1578 | + otherPage.head.locked = true; |
1579 | + otherPage.head.visible = false; |
1580 | + |
1581 | + stack.push(otherPage); |
1582 | + wait_for_visible(false, "Pushing Page with locked hidden header shows header."); |
1583 | + compare(otherPage.head.locked, true, "Pushing Page unlocks header."); |
1584 | + compare(page.head.locked, false, "Pushing Page locks previous header."); |
1585 | + |
1586 | + stack.pop(); |
1587 | + wait_for_visible(true, "Popping to a Page with unlocked header does not show header."); |
1588 | + compare(otherPage.head.locked, true, "Popping Page unlocks previous header."); |
1589 | + compare(page.head.locked, false, "Popping Page locks header."); |
1590 | + } |
1591 | + |
1592 | + function test_hidden_locked_header_stays_hidden() { |
1593 | + page.head.locked = true; |
1594 | + page.head.visible = false; |
1595 | + waitForHeaderAnimation(mainView); |
1596 | + stack.push(otherPage); |
1597 | + waitForHeaderAnimation(mainView); |
1598 | + stack.pop(); |
1599 | + wait_for_visible(false, "Popping to a Page with locked hidden header shows header."); |
1600 | + } |
1601 | + |
1602 | + function test_page_with_no_title_on_pagestack_has_back_button_bug1402054() { |
1603 | + page.head.visible = false; |
1604 | + waitForHeaderAnimation(mainView); |
1605 | + stack.push(titleLessPage); |
1606 | + wait_for_visible(true, "Page with no title hides the header."); |
1607 | + |
1608 | + var backButton = findChild(testCase.header, "backButton"); |
1609 | + verify(null !== backButton, "Header has no back button."); |
1610 | + compare(backButton.visible, true, "Page with no title hides the back button."); |
1611 | + |
1612 | + var center = centerOf(backButton); |
1613 | + mouseClick(backButton, center.x, center.y); |
1614 | + waitForHeaderAnimation(mainView); |
1615 | + compare(stack.depth, 1, "Clicking back button of page with no title does not "+ |
1616 | + "pop the page from the PageStack."); |
1617 | + } |
1618 | + } |
1619 | +} |
1620 | |
1621 | === renamed file 'tests/unit_x11/tst_components/tst_page.qml' => 'tests/unit_x11/tst_components/tst_page11.qml' |
1622 | --- tests/unit_x11/tst_components/tst_page.qml 2015-03-03 13:20:06 +0000 |
1623 | +++ tests/unit_x11/tst_components/tst_page11.qml 2015-03-23 15:53:11 +0000 |
1624 | @@ -54,7 +54,7 @@ |
1625 | } |
1626 | |
1627 | TestCase { |
1628 | - name: "PageAPI" |
1629 | + name: "Page11API" |
1630 | when: windowShown |
1631 | |
1632 | function initTestCase() { |
1633 | |
1634 | === added file 'tests/unit_x11/tst_components/tst_page13.qml' |
1635 | --- tests/unit_x11/tst_components/tst_page13.qml 1970-01-01 00:00:00 +0000 |
1636 | +++ tests/unit_x11/tst_components/tst_page13.qml 2015-03-23 15:53:11 +0000 |
1637 | @@ -0,0 +1,141 @@ |
1638 | +/* |
1639 | + * Copyright 2015 Canonical Ltd. |
1640 | + * |
1641 | + * This program is free software; you can redistribute it and/or modify |
1642 | + * it under the terms of the GNU Lesser General Public License as published by |
1643 | + * the Free Software Foundation; version 3. |
1644 | + * |
1645 | + * This program is distributed in the hope that it will be useful, |
1646 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1647 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1648 | + * GNU Lesser General Public License for more details. |
1649 | + * |
1650 | + * You should have received a copy of the GNU Lesser General Public License |
1651 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1652 | + */ |
1653 | + |
1654 | +import QtQuick 2.4 |
1655 | +import Ubuntu.Test 1.0 |
1656 | +import Ubuntu.Components 1.3 |
1657 | + |
1658 | +Item { |
1659 | + width: 400 |
1660 | + height: 600 |
1661 | + |
1662 | + Flickable { |
1663 | + id: testFlickable |
1664 | + } |
1665 | + |
1666 | + MainView { |
1667 | + anchors.fill: parent |
1668 | + id: mainView |
1669 | + Page { |
1670 | + id: page |
1671 | + Flickable { |
1672 | + id: pageFlickable |
1673 | + anchors.fill: parent |
1674 | + contentHeight: column.height |
1675 | + |
1676 | + Column { |
1677 | + id: column |
1678 | + Repeater { |
1679 | + model: 100 |
1680 | + Label { |
1681 | + text: "line "+index |
1682 | + } |
1683 | + } |
1684 | + } |
1685 | + } |
1686 | + } |
1687 | + } |
1688 | + |
1689 | + UbuntuTestCase { |
1690 | + id: testCase |
1691 | + name: "Page13API" |
1692 | + when: windowShown |
1693 | + |
1694 | + property var header |
1695 | + property var headerStyle |
1696 | + function initTestCase() { |
1697 | + testCase.header = findChild(mainView, "MainView_Header"); |
1698 | + testCase.headerStyle = findChild(mainView, "PageHeadStyle"); |
1699 | + } |
1700 | + |
1701 | + function init() { |
1702 | + compare(page.title, "", "Page title is set by default."); |
1703 | + compare(page.active, true, "Page is inactive by default."); |
1704 | + compare(page.pageStack, null, "Page has a PageStack by default."); |
1705 | + } |
1706 | + |
1707 | + function test_title() { |
1708 | + var newTitle = "Hello World!"; |
1709 | + page.title = newTitle; |
1710 | + compare(page.title, newTitle, "Could not set page title."); |
1711 | + page.title = ""; |
1712 | + compare(page.title, "", "Could not unset page title."); |
1713 | + } |
1714 | + |
1715 | + function test_header_title() { |
1716 | + var newTitle = "Hello header!"; |
1717 | + page.title = newTitle; |
1718 | + var header = mainView.__propagated.header; |
1719 | + compare(header.title, newTitle, "Header title does not match active page title."); |
1720 | + page.title = ""; |
1721 | + } |
1722 | + |
1723 | + function test_flickable_bug1200642_bug1192591() { |
1724 | + var header = page.__propagated.header; |
1725 | + compare(page.flickable, pageFlickable, |
1726 | + "Flickable is not correctly detected."); |
1727 | + compare(header.flickable, pageFlickable, |
1728 | + "Header flickable is not correctly set."); |
1729 | + |
1730 | + page.flickable = testFlickable; |
1731 | + compare(page.flickable, testFlickable, "Flickable could not be set."); |
1732 | + compare(header.flickable, testFlickable, |
1733 | + "Header flickable was not update correctly."); |
1734 | + |
1735 | + page.flickable = null; |
1736 | + compare(page.flickable, null, "Flickable cannot be unset."); |
1737 | + compare(header.flickable, null, |
1738 | + "Header flickable was not correctly unset."); |
1739 | + } |
1740 | + |
1741 | + function wait_for_header_animation() { |
1742 | + // Wait for the header to start to move: |
1743 | + wait(50); |
1744 | + // Wait for animation of the style inside the header (when pushing/popping): |
1745 | + tryCompareFunction(function(){ return testCase.headerStyle.animating }, false); |
1746 | + // Wait for the header to finish showing/hiding: |
1747 | + tryCompareFunction(function(){ return testCase.header.moving }, false); |
1748 | + } |
1749 | + |
1750 | + function test_flickableY_bug1201452() { |
1751 | + var headerHeight = testCase.header.height |
1752 | + var flickableY = 150; |
1753 | + page.flickable.contentY = flickableY; |
1754 | + compare(page.flickable.contentY, flickableY, |
1755 | + "Flickable.contentY could not be set."); |
1756 | + compare(page.flickable.topMargin, headerHeight, |
1757 | + "topMargin of the flickable does not equal header height."); |
1758 | + |
1759 | + page.head.locked = true; |
1760 | + page.head.visible = false; |
1761 | + wait_for_header_animation(); |
1762 | + |
1763 | + compare(page.flickable.topMargin, 0, |
1764 | + "topMargin is not 0 when header is locked hidden."); |
1765 | + compare(page.flickable.contentY, flickableY + headerHeight, |
1766 | + "contentY was not updated properly when header was hidden."); |
1767 | + |
1768 | + page.head.locked.locked = false; |
1769 | + page.head.visible = true; |
1770 | + wait_for_header_animation(); |
1771 | + |
1772 | + compare(page.flickable.contentY, flickableY, |
1773 | + "Hiding and showing header changes flickable.contentY."); |
1774 | + compare(page.flickable.topMargin, headerHeight, |
1775 | + "topMargin was not updated when header became visible."); |
1776 | + } |
1777 | + } |
1778 | +} |
1779 | |
1780 | === modified file 'tests/unit_x11/tst_components/tst_pagestack.new_header.qml' |
1781 | --- tests/unit_x11/tst_components/tst_pagestack.new_header.qml 2015-03-06 12:42:00 +0000 |
1782 | +++ tests/unit_x11/tst_components/tst_pagestack.new_header.qml 2015-03-23 15:53:11 +0000 |
1783 | @@ -1,5 +1,5 @@ |
1784 | /* |
1785 | - * Copyright 2012-2014 Canonical Ltd. |
1786 | + * Copyright 2012-2015 Canonical Ltd. |
1787 | * |
1788 | * This program is free software; you can redistribute it and/or modify |
1789 | * it under the terms of the GNU Lesser General Public License as published by |
1790 | @@ -16,7 +16,7 @@ |
1791 | |
1792 | import QtQuick 2.2 |
1793 | import Ubuntu.Test 1.0 |
1794 | -import Ubuntu.Components 1.1 |
1795 | +import Ubuntu.Components 1.2 |
1796 | |
1797 | // pagestack tests for deprecated toolbar are in |
1798 | // unit/tst_components/tst_pagestack_deprecated_toolbar.qml |
1799 | @@ -28,7 +28,6 @@ |
1800 | MainView { |
1801 | id: mainView |
1802 | anchors.fill: parent |
1803 | - useDeprecatedToolbar: false |
1804 | PageStack { |
1805 | id: pageStack |
1806 | Page { |
1807 | @@ -73,43 +72,36 @@ |
1808 | when: windowShown |
1809 | id: testCase |
1810 | |
1811 | - property var head_style |
1812 | - |
1813 | function initTestCase() { |
1814 | - testCase.head_style = findChild(mainView, "PageHeadStyle"); |
1815 | - wait_for_animation(); |
1816 | + waitForHeaderAnimation(mainView); |
1817 | compare(pageStack.currentPage, null, "is not set by default"); |
1818 | compare(pageStack.__propagated, mainView.__propagated, "propagated property of pageStack equals mainView.__propagated") |
1819 | compare(mainView.__propagated.header.title, "", "empty title by default"); |
1820 | } |
1821 | |
1822 | - function wait_for_animation() { |
1823 | - tryCompareFunction(function(){return testCase.head_style.animating}, false); |
1824 | - } |
1825 | - |
1826 | function test_depth() { |
1827 | compare(pageStack.depth, 0, "depth is 0 by default"); |
1828 | pageStack.push(page1); |
1829 | - wait_for_animation(); |
1830 | + waitForHeaderAnimation(mainView); |
1831 | compare(pageStack.depth, 1, "depth is correctly increased when pushing a page"); |
1832 | pageStack.push(page2); |
1833 | - wait_for_animation(); |
1834 | + waitForHeaderAnimation(mainView); |
1835 | compare(pageStack.depth, 2, "depth is correctly updated when pushing a page"); |
1836 | pageStack.pop(); |
1837 | - wait_for_animation(); |
1838 | + waitForHeaderAnimation(mainView); |
1839 | compare(pageStack.depth, 1, "depth is correctly decreased when popping a page"); |
1840 | pageStack.clear(); |
1841 | - wait_for_animation(); |
1842 | + waitForHeaderAnimation(mainView); |
1843 | compare(pageStack.depth, 0, "depth is after clearing"); |
1844 | } |
1845 | |
1846 | function test_currentPage() { |
1847 | compare(pageStack.currentPage, null, "currentPage is null by default"); |
1848 | pageStack.push(page1); |
1849 | - wait_for_animation(); |
1850 | + waitForHeaderAnimation(mainView); |
1851 | compare(pageStack.currentPage, page1, "currentPage properly updated"); |
1852 | pageStack.clear(); |
1853 | - wait_for_animation(); |
1854 | + waitForHeaderAnimation(mainView); |
1855 | compare(pageStack.currentPage, null, "currentPage properly reset"); |
1856 | } |
1857 | |
1858 | @@ -117,60 +109,60 @@ |
1859 | compare(pageStack.depth, 0, "depth is 0 initially"); |
1860 | pageStack.push(page1); |
1861 | pageStack.push(page2); |
1862 | - wait_for_animation(); |
1863 | + waitForHeaderAnimation(mainView); |
1864 | compare(pageStack.currentPage, page2, "last pushed page is on top"); |
1865 | pageStack.pop(); |
1866 | - wait_for_animation(); |
1867 | + waitForHeaderAnimation(mainView); |
1868 | compare(pageStack.currentPage, page1, "popping puts previously pushed page on top"); |
1869 | pageStack.clear(); |
1870 | - wait_for_animation(); |
1871 | + waitForHeaderAnimation(mainView); |
1872 | } |
1873 | |
1874 | function test_active_bug1260116() { |
1875 | pageStack.push(page1); |
1876 | - wait_for_animation(); |
1877 | + waitForHeaderAnimation(mainView); |
1878 | |
1879 | compare(page1.active, true, "Page is active after pushing"); |
1880 | pageStack.push(page2); |
1881 | - wait_for_animation(); |
1882 | + waitForHeaderAnimation(mainView); |
1883 | |
1884 | compare(page1.active, false, "Page no longer active after pushing a new page"); |
1885 | compare(page2.active, true, "New page is active after pushing"); |
1886 | pageStack.pop(); |
1887 | - wait_for_animation(); |
1888 | + waitForHeaderAnimation(mainView); |
1889 | compare(page1.active, true, "Page re-activated when on top of the stack"); |
1890 | compare(page2.active, false, "Page no longer active after being popped"); |
1891 | pageStack.clear(); |
1892 | - wait_for_animation(); |
1893 | + waitForHeaderAnimation(mainView); |
1894 | |
1895 | compare(pageInStack.active, false, "Page defined inside PageStack is not active by default"); |
1896 | pageStack.push(pageInStack); |
1897 | - wait_for_animation(); |
1898 | + waitForHeaderAnimation(mainView); |
1899 | compare(pageInStack.active, true, "Pushing a page on PageStack makes it active"); |
1900 | pageStack.pop(); |
1901 | - wait_for_animation(); |
1902 | + waitForHeaderAnimation(mainView); |
1903 | compare(pageInStack.active, false, "Popping a page from PageStack makes it inactive"); |
1904 | pageStack.clear(); |
1905 | - wait_for_animation(); |
1906 | + waitForHeaderAnimation(mainView); |
1907 | } |
1908 | |
1909 | function test_title_bug1143345_bug1317902() { |
1910 | pageStack.push(page1); |
1911 | - wait_for_animation(); |
1912 | + waitForHeaderAnimation(mainView); |
1913 | compare(mainView.__propagated.header.title, "Title 1", "Header title is correctly set by page"); |
1914 | page1.title = "New title"; |
1915 | compare(mainView.__propagated.header.title, "New title", "Header title correctly updated by page"); |
1916 | pageStack.push(page2); |
1917 | - wait_for_animation(); |
1918 | + waitForHeaderAnimation(mainView); |
1919 | compare(mainView.__propagated.header.title, "Title 2", "Header title is correctly set by page"); |
1920 | pageStack.clear(); |
1921 | page1.title = "Title 1"; |
1922 | |
1923 | pageStack.push(pageWithPage); |
1924 | - wait_for_animation(); |
1925 | + waitForHeaderAnimation(mainView); |
1926 | compare(mainView.__propagated.header.title, pageWithPage.title, "Embedded page sets title of outer page"); |
1927 | pageStack.clear(); |
1928 | - wait_for_animation(); |
1929 | + waitForHeaderAnimation(mainView); |
1930 | } |
1931 | |
1932 | function get_tabs_button() { |
1933 | @@ -182,36 +174,36 @@ |
1934 | function test_tabs_inside_stack_bug1187850() { |
1935 | compare(get_tabs_button(), null, "Without tabs there is no visible tabs button."); |
1936 | pageStack.push(tabs); |
1937 | - wait_for_animation(); |
1938 | + waitForHeaderAnimation(mainView); |
1939 | compare(pageStack.currentPage, tabs, "Tabs can be pushed on a PageStack"); |
1940 | compare(tabs.active, true, "Tabs on top of a PageStack are active"); |
1941 | compare(get_tabs_button().visible, true, "Pushing tabs on pagestack enables the tabs button"); |
1942 | pageStack.push(page1); |
1943 | - wait_for_animation(); |
1944 | + waitForHeaderAnimation(mainView); |
1945 | compare(pageStack.currentPage, page1, "A page can be pushed on top of a Tabs"); |
1946 | compare(tabs.active, false, "Tabs on a PageStack, but not on top, are inactive"); |
1947 | compare(get_tabs_button(), null, "Contents of inactive Tabs is not applied to header"); |
1948 | pageStack.pop(); |
1949 | - wait_for_animation(); |
1950 | + waitForHeaderAnimation(mainView); |
1951 | compare(tabs.active, true, "Tabs on top of PageStack is active"); |
1952 | compare(get_tabs_button().visible, true, "Active Tabs controls header contents"); |
1953 | pageStack.clear(); |
1954 | - wait_for_animation(); |
1955 | + waitForHeaderAnimation(mainView); |
1956 | } |
1957 | |
1958 | function test_pop_to_tabs_bug1316736() { |
1959 | pageStack.push(tabs); |
1960 | - wait_for_animation(); |
1961 | + waitForHeaderAnimation(mainView); |
1962 | tabs.selectedTabIndex = 1; |
1963 | pageStack.push(page1); |
1964 | - wait_for_animation(); |
1965 | + waitForHeaderAnimation(mainView); |
1966 | compare(tabs.active, false, "Tabs on a PageStack, but not on top, are inactive"); |
1967 | pageStack.pop(); |
1968 | - wait_for_animation(); |
1969 | + waitForHeaderAnimation(mainView); |
1970 | compare(tabs.active, true, "Tabs on top of PageStack is active"); |
1971 | compare(tabs.selectedTabIndex, 1, "Pushing and popping another page on top of Tabs does not change selectedTabsIndex"); |
1972 | pageStack.clear(); |
1973 | - wait_for_animation(); |
1974 | + waitForHeaderAnimation(mainView); |
1975 | } |
1976 | |
1977 | function test_push_return_values() { |
1978 | @@ -225,7 +217,7 @@ |
1979 | compare(pushedPage.title, "Page from QML file", |
1980 | "PageStack.push() returns Page created from QML file"); |
1981 | pageStack.clear(); |
1982 | - wait_for_animation(); |
1983 | + waitForHeaderAnimation(mainView); |
1984 | } |
1985 | } |
1986 | } |
FAILED: Continuous integration, rev:1455 jenkins. qa.ubuntu. com/job/ ubuntu- sdk-team- ubuntu- ui-toolkit- staging- ci/1556/ jenkins. qa.ubuntu. com/job/ generic- deb-autopilot- vivid-touch/ 1800/console jenkins. qa.ubuntu. com/job/ ubuntu- sdk-team- ubuntu- ui-toolkit- staging- vivid-amd64- ci/283/ console jenkins. qa.ubuntu. com/job/ ubuntu- sdk-team- ubuntu- ui-toolkit- staging- vivid-armhf- ci/286/ console jenkins. qa.ubuntu. com/job/ ubuntu- sdk-team- ubuntu- ui-toolkit- staging- vivid-i386- ci/283/ console jenkins. qa.ubuntu. com/job/ generic- mediumtests- builder- vivid-armhf/ 1798/console
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild: s-jenkins. ubuntu- ci:8080/ job/ubuntu- sdk-team- ubuntu- ui-toolkit- staging- ci/1556/ rebuild
http://