Merge lp:~tpeeters/ubuntu-ui-toolkit/10-headAnimate into lp:ubuntu-ui-toolkit/staging

Proposed by Tim Peeters
Status: Superseded
Proposed branch: lp:~tpeeters/ubuntu-ui-toolkit/10-headAnimate
Merge into: lp:ubuntu-ui-toolkit/staging
Prerequisite: lp:~tpeeters/ubuntu-ui-toolkit/07-tabsUnitTests
Diff against target: 1053 lines (+392/-125)
16 files modified
modules/Ubuntu/Components/AppHeader.qml (+5/-0)
modules/Ubuntu/Components/Icon10.qml (+1/-1)
modules/Ubuntu/Components/MainView.qml (+1/-0)
modules/Ubuntu/Components/PageStack.qml (+7/-6)
modules/Ubuntu/Components/PageWrapperUtils.js (+3/-1)
modules/Ubuntu/Components/Styles/PageHeadStyle.qml (+2/-0)
modules/Ubuntu/Components/Themes/Ambiance/PageHeadStyle.qml (+167/-30)
tests/autopilot/ubuntuuitoolkit/_custom_proxy_objects/_header.py (+19/-0)
tests/autopilot/ubuntuuitoolkit/tests/components/test_header.py (+2/-0)
tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_tabs.TabsTestCase.deprecated_TabBar.qml (+61/-0)
tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_tabs.TabsTestCase.new_header.qml (+43/-0)
tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_tabs.py (+14/-56)
tests/resources/header/header.qml (+4/-6)
tests/resources/navigation/MyCustomPage.qml (+17/-25)
tests/unit_x11/tst_components/tst_headActions.qml (+13/-0)
tests/unit_x11/tst_components/tst_pagestack_new_header.qml (+33/-0)
To merge this branch: bzr merge lp:~tpeeters/ubuntu-ui-toolkit/10-headAnimate
Reviewer Review Type Date Requested Status
PS Jenkins bot continuous-integration Approve
Zsombor Egri Approve
Review via email: mp+231850@code.launchpad.net

This proposal has been superseded by a proposal from 2014-08-26.

Commit message

Add header animations

Description of the change

Add header animations

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Zsombor Egri (zsombi) wrote :

Looks good, can go in.

review: Approve
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
1211. By Tim Peeters

merge staging

1212. By Tim Peeters

clean

1213. By Tim Peeters

merge sourceOverflow

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)

Unmerged revisions

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'modules/Ubuntu/Components/AppHeader.qml'
2--- modules/Ubuntu/Components/AppHeader.qml 2014-07-17 10:59:18 +0000
3+++ modules/Ubuntu/Components/AppHeader.qml 2014-08-26 11:41:08 +0000
4@@ -37,6 +37,11 @@
5 */
6 property bool animate: true
7
8+ /*!
9+ Animate changing to new title/actions inside the header.
10+ */
11+ property bool animateContents: false
12+
13 Behavior on y {
14 enabled: animate && !(header.flickable && header.flickable.moving)
15 SmoothedAnimation {
16
17=== modified file 'modules/Ubuntu/Components/Icon10.qml'
18--- modules/Ubuntu/Components/Icon10.qml 2014-07-31 14:14:56 +0000
19+++ modules/Ubuntu/Components/Icon10.qml 2014-08-26 11:41:08 +0000
20@@ -83,7 +83,7 @@
21 visible: active
22
23 // Whether or not a color has been set.
24- property bool active: keyColorOut != Qt.rgba(0.0, 0.0, 0.0, 0.0)
25+ property bool active: keyColorOut != Qt.rgba(0.0, 0.0, 0.0, 0.0) && source
26
27 property Image source: active && image.status == Image.Ready ? image : null
28 property color keyColorOut: Qt.rgba(0.0, 0.0, 0.0, 0.0)
29
30=== modified file 'modules/Ubuntu/Components/MainView.qml'
31--- modules/Ubuntu/Components/MainView.qml 2014-08-18 13:34:29 +0000
32+++ modules/Ubuntu/Components/MainView.qml 2014-08-26 11:41:08 +0000
33@@ -341,6 +341,7 @@
34 id: headerItem
35 property real bottomY: headerItem.y + headerItem.height
36 animate: canvas.animate
37+ animateContents: canvas.animate
38
39 title: internal.activePage ? internal.activePage.title : ""
40 flickable: internal.activePage ? internal.activePage.flickable : null
41
42=== modified file 'modules/Ubuntu/Components/PageStack.qml'
43--- modules/Ubuntu/Components/PageStack.qml 2014-08-12 10:03:13 +0000
44+++ modules/Ubuntu/Components/PageStack.qml 2014-08-26 11:41:08 +0000
45@@ -163,7 +163,6 @@
46 function push(page, properties) {
47 if (internal.stack.size() > 0) internal.stack.top().active = false;
48 internal.stack.push(internal.createWrapper(page, properties));
49- internal.stack.top().active = true;
50 internal.stackUpdated();
51 }
52
53@@ -181,8 +180,6 @@
54 if (internal.stack.top().canDestroy) internal.stack.top().destroyObject();
55 internal.stack.pop();
56 internal.stackUpdated();
57-
58- if (internal.stack.size() > 0) internal.stack.top().active = true;
59 }
60
61 /*!
62@@ -216,9 +213,13 @@
63 }
64
65 function stackUpdated() {
66- pageStack.depth =+ stack.size();
67- if (pageStack.depth > 0) currentPage = stack.top().object;
68- else currentPage = null;
69+ pageStack.depth = stack.size();
70+ if (pageStack.depth > 0) {
71+ internal.stack.top().active = true;
72+ currentPage = stack.top().object;
73+ } else {
74+ currentPage = null;
75+ }
76 }
77 }
78
79
80=== modified file 'modules/Ubuntu/Components/PageWrapperUtils.js'
81--- modules/Ubuntu/Components/PageWrapperUtils.js 2013-05-24 13:51:12 +0000
82+++ modules/Ubuntu/Components/PageWrapperUtils.js 2014-08-26 11:41:08 +0000
83@@ -101,8 +101,10 @@
84 */
85 function destroyObject(pageWrapper) {
86 if (pageWrapper.canDestroy) {
87- pageWrapper.object.destroy();
88 pageWrapper.object = null;
89+ // Rely on garbage collector to destroy the object after all
90+ // (other) references are gone. PageHeadStyle uses actions etc.
91+ // of the page to show a fade-out animation after it was popped.
92 pageWrapper.canDestroy = false;
93 }
94 }
95
96=== modified file 'modules/Ubuntu/Components/Styles/PageHeadStyle.qml'
97--- modules/Ubuntu/Components/Styles/PageHeadStyle.qml 2014-06-26 14:24:41 +0000
98+++ modules/Ubuntu/Components/Styles/PageHeadStyle.qml 2014-08-26 11:41:08 +0000
99@@ -53,7 +53,9 @@
100 property int fontWeight
101
102 /*!
103+ \deprecated
104 The color of the title text.
105+ Use \l Page.head.foregroundColor instead.
106 */
107 property color textColor
108
109
110=== modified file 'modules/Ubuntu/Components/Themes/Ambiance/PageHeadStyle.qml'
111--- modules/Ubuntu/Components/Themes/Ambiance/PageHeadStyle.qml 2014-08-22 21:29:46 +0000
112+++ modules/Ubuntu/Components/Themes/Ambiance/PageHeadStyle.qml 2014-08-26 11:41:08 +0000
113@@ -29,9 +29,127 @@
114 textColor: styledItem.config.foregroundColor
115 textLeftMargin: units.gu(2)
116 maximumNumberOfActions: 3
117+ objectName: "PageHeadStyle"
118+
119+ // workaround because autopilot cannot select the SequentalAnimation
120+ // Needed in AppHeader.wait_for_animation() autopilot proxy object and
121+ // in tst_pagestack_new_header.qml unit test.
122+ property bool animating: changeAnimation.running
123
124 implicitHeight: headerStyle.contentHeight + separator.height + separatorBottom.height
125
126+ Component.onCompleted: buffer.update()
127+
128+ Object {
129+ id: buffer
130+
131+ property PageHeadConfiguration config
132+ property string title
133+ property Item pageStack: null
134+ property int pageStackDepth: 0
135+ property var tabsModel: null
136+
137+ function update() {
138+ buffer.config = styledItem.config;
139+ buffer.title = styledItem.title;
140+ buffer.pageStack = styledItem.pageStack;
141+ buffer.pageStackDepth = buffer.pageStack ? buffer.pageStack.depth : 0;
142+ buffer.tabsModel = styledItem.tabsModel ? styledItem.tabsModel : null;
143+ }
144+
145+ // Calling changeAnimation.start() a second time has no effect,
146+ // so below we can call it whenever something changes.
147+ Connections {
148+ target: styledItem
149+ onConfigChanged: buffer.updateConfigAndTitle()
150+ onTitleChanged: buffer.updateConfigAndTitle()
151+ onPageStackChanged: buffer.updateConfigAndTitle()
152+ onTabsModelChanged: buffer.updateConfigAndTitle()
153+ }
154+
155+ function updateConfigAndTitle() {
156+ if (styledItem.animateContents) {
157+ changeAnimation.start();
158+ } else {
159+ buffer.update();
160+ }
161+ }
162+
163+ SequentialAnimation {
164+ id: changeAnimation
165+ objectName: "changeAnimation"
166+ ParallelAnimation {
167+ UbuntuNumberAnimation {
168+ target: foreground
169+ property: "opacity"
170+ from: 1.0
171+ to: 0.0
172+ }
173+ UbuntuNumberAnimation {
174+ target: leftButtonContainer
175+ property: "opacity"
176+ from: 1.0
177+ to: 0.0
178+ }
179+ UbuntuNumberAnimation {
180+ target: actionsContainer
181+ property: "opacity"
182+ from: 1.0
183+ to: 0.0
184+ }
185+ UbuntuNumberAnimation {
186+ target: leftAnchor
187+ properties: "anchors.leftMargin"
188+ from: 0.0
189+ to: -units.gu(5)
190+ }
191+ UbuntuNumberAnimation {
192+ target: rightAnchor
193+ properties: "anchors.rightMargin"
194+ from: 0
195+ to: -units.gu(5)
196+ }
197+ }
198+ ScriptAction {
199+ script: {
200+ buffer.update();
201+ }
202+ }
203+ ParallelAnimation {
204+ UbuntuNumberAnimation {
205+ target: foreground
206+ property: "opacity"
207+ from: 0.0
208+ to: 1.0
209+ }
210+ UbuntuNumberAnimation {
211+ target: leftButtonContainer
212+ property: "opacity"
213+ from: 0.0
214+ to: 1.0
215+ }
216+ UbuntuNumberAnimation {
217+ target: actionsContainer
218+ property: "opacity"
219+ from: 0.0
220+ to: 1.0
221+ }
222+ UbuntuNumberAnimation {
223+ target: leftAnchor
224+ properties: "anchors.leftMargin"
225+ from: -units.gu(5)
226+ to: 0
227+ }
228+ UbuntuNumberAnimation {
229+ target: rightAnchor
230+ properties: "anchors.rightMargin"
231+ from: -units.gu(5)
232+ to: 0
233+ }
234+ }
235+ }
236+ }
237+
238 // FIXME: Workaround to get sectionsRepeater.count in autopilot tests,
239 // see also FIXME in AppHeader where this property is used.
240 property alias __sections_repeater_for_autopilot: sectionsRepeater
241@@ -46,7 +164,7 @@
242 source: headerStyle.separatorSource
243 height: sectionsRow.visible ? units.gu(3) : units.gu(2)
244
245- property PageHeadSections sections: styledItem.config.sections
246+ property PageHeadSections sections: buffer.config.sections
247
248 Row {
249 id: sectionsRow
250@@ -121,9 +239,30 @@
251 }
252
253 Item {
254+ id: leftAnchor
255+ anchors {
256+ top: parent.top
257+ bottom: parent.bottom
258+ left: parent.left
259+ leftMargin: 0
260+ }
261+ width: 0
262+ }
263+ Item {
264+ id: rightAnchor
265+ anchors {
266+ top: parent.top
267+ bottom: parent.bottom
268+ right: parent.right
269+ rightMargin: 0
270+ }
271+ width: 0
272+ }
273+
274+ Item {
275 id: leftButtonContainer
276 anchors {
277- left: parent.left
278+ left: leftAnchor.right
279 top: parent.top
280 leftMargin: width > 0 ? units.gu(1) : 0
281 }
282@@ -133,10 +272,10 @@
283 PageHeadButton {
284 id: customBackButton
285 objectName: "customBackButton"
286- action: styledItem.config.backAction
287- visible: null !== styledItem.config.backAction &&
288- styledItem.config.backAction.visible
289- color: styledItem.config.foregroundColor
290+ action: buffer.config.backAction
291+ visible: null !== buffer.config.backAction &&
292+ buffer.config.backAction.visible
293+ color: buffer.config.foregroundColor
294 }
295
296 PageHeadButton {
297@@ -144,16 +283,14 @@
298 objectName: "backButton"
299
300 iconName: "back"
301- visible: styledItem.pageStack !== null &&
302- styledItem.pageStack !== undefined &&
303- styledItem.pageStack.depth > 1 &&
304- !styledItem.config.backAction
305+ visible: buffer.pageStackDepth > 1 &&
306+ !buffer.config.backAction
307
308 text: "back"
309- color: styledItem.config.foregroundColor
310+ color: buffer.config.foregroundColor
311
312 onTriggered: {
313- styledItem.pageStack.pop();
314+ buffer.pageStack.pop();
315 }
316 }
317
318@@ -162,12 +299,11 @@
319 objectName: "tabsButton"
320
321 iconName: "navigation-menu"
322- visible: styledItem.tabsModel !== null &&
323- styledItem.tabsModel !== undefined &&
324+ visible: buffer.tabsModel !== null &&
325 !backButton.visible &&
326 !customBackButton.visible
327- text: visible ? styledItem.tabsModel.count + " tabs" : ""
328- color: styledItem.config.foregroundColor
329+ text: visible ? buffer.tabsModel.count + " tabs" : ""
330+ color: buffer.config.foregroundColor
331
332 onTriggered: PopupUtils.open(tabsPopoverComponent, tabsButton)
333
334@@ -187,11 +323,11 @@
335 right: parent.right
336 }
337 Repeater {
338- model: styledItem.tabsModel
339+ model: buffer.tabsModel
340 AbstractButton {
341 objectName: "tabButton" + index
342 onClicked: {
343- styledItem.tabsModel.selectedIndex = index;
344+ buffer.tabsModel.selectedIndex = index;
345 tabsPopover.hide();
346 }
347 implicitHeight: units.gu(6) + bottomDividerLine.height
348@@ -224,7 +360,7 @@
349 ListItem.ThinDivider {
350 id: bottomDividerLine
351 anchors.bottom: parent.bottom
352- visible: index < styledItem.tabsModel.count - 1
353+ visible: index < buffer.tabsModel.count - 1
354 }
355 }
356 }
357@@ -238,12 +374,12 @@
358 id: foreground
359 anchors {
360 left: leftButtonContainer.right
361- right: actionsContainer.left
362 top: parent.top
363 // don't keep a margin if there is already a button with spacing
364 leftMargin: leftButtonContainer.width > 0 ? 0 : headerStyle.textLeftMargin
365 }
366 height: headerStyle.contentHeight
367+ width: parent.width - leftButtonContainer.width - actionsContainer.width
368
369 Label {
370 objectName: "header_title_label"
371@@ -254,10 +390,10 @@
372 right: parent.right
373 verticalCenter: parent.verticalCenter
374 }
375- text: styledItem.title
376+ text: buffer.title
377 font.weight: headerStyle.fontWeight
378 fontSize: headerStyle.fontSize
379- color: headerStyle.textColor
380+ color: buffer.config.foregroundColor
381 elide: Text.ElideRight
382 }
383
384@@ -267,7 +403,7 @@
385 // when the bindings below is no longer active
386 id: contentsContainer
387 anchors.fill: parent
388- visible: styledItem.contents || styledItem.config.contents
389+ visible: styledItem.contents || buffer.config.contents
390 }
391 Binding {
392 target: styledItem.contents
393@@ -282,17 +418,17 @@
394 when: styledItem.contents
395 }
396 Binding {
397- target: styledItem.config.contents
398+ target: buffer.config.contents
399 property: "parent"
400 value: contentsContainer
401- when: styledItem.config.contents && !styledItem.contents
402+ when: buffer.config.contents && !styledItem.contents
403 }
404 }
405
406 Row {
407 id: actionsContainer
408
409- property var visibleActions: getVisibleActions(styledItem.config.actions)
410+ property var visibleActions: getVisibleActions(buffer.config.actions)
411 function getVisibleActions(actions) {
412 var visibleActionList = [];
413 for (var i in actions) {
414@@ -316,7 +452,7 @@
415
416 anchors {
417 top: parent.top
418- right: parent.right
419+ right: rightAnchor.left
420 rightMargin: units.gu(1)
421 }
422 width: childrenRect.width
423@@ -328,7 +464,7 @@
424 id: actionButton
425 objectName: action.objectName + "_header_button"
426 action: actionsContainer.visibleActions[index]
427- color: styledItem.config.foregroundColor
428+ color: buffer.config.foregroundColor
429 }
430 }
431
432@@ -337,8 +473,9 @@
433 objectName: "actions_overflow_button"
434 visible: numberOfSlots.requested > numberOfSlots.right
435 iconName: "contextual-menu"
436- color: styledItem.config.foregroundColor
437+ color: buffer.config.foregroundColor
438 height: actionsContainer.height
439+
440 onTriggered: PopupUtils.open(actionsOverflowPopoverComponent, actionsOverflowButton)
441
442 Component {
443@@ -396,7 +533,7 @@
444
445 Icon {
446 id: actionIcon
447- name: action.iconName
448+ source: action.iconSource
449 color: Theme.palette.selected.backgroundText
450 anchors {
451 verticalCenter: parent.verticalCenter
452
453=== modified file 'tests/autopilot/ubuntuuitoolkit/_custom_proxy_objects/_header.py'
454--- tests/autopilot/ubuntuuitoolkit/_custom_proxy_objects/_header.py 2014-08-20 06:45:28 +0000
455+++ tests/autopilot/ubuntuuitoolkit/_custom_proxy_objects/_header.py 2014-08-26 11:41:08 +0000
456@@ -67,6 +67,7 @@
457 raise _common.ToolkitException('Old header has no sections')
458
459 try:
460+ self.wait_for_animation()
461 object_name = "section_button_" + str(index)
462 button = self.select_single(objectName=object_name)
463 except dbus.StateNotFoundError:
464@@ -79,6 +80,7 @@
465 if self.useDeprecatedToolbar:
466 raise _common.ToolkitException('Old header has no sections')
467
468+ self.wait_for_animation()
469 sectionsProperties = self.select_single(
470 'QQuickItem', objectName='sectionsProperties')
471 return sectionsProperties.selectedIndex
472@@ -89,12 +91,14 @@
473 if self.useDeprecatedToolbar:
474 raise _common.ToolkitException('Old header has no back button')
475 try:
476+ self.wait_for_animation()
477 back_button = self.select_single(objectName='backButton')
478 except dbus.StateNotFoundError:
479 raise _common.ToolkitException('Missing back button in header')
480 if not back_button.visible:
481 raise _common.ToolkitException('Back button in header not visible')
482 self.pointing_device.click_object(back_button)
483+ self.wait_for_animation()
484
485 def click_custom_back_button(self):
486 self._show_if_not_visible()
487@@ -103,6 +107,7 @@
488 raise _common.ToolkitException(
489 'Old header has no custom back button')
490 try:
491+ self.wait_for_animation()
492 custom_back_button = self.select_single(
493 objectName='customBackButton')
494 except dbus.StateNotFoundError:
495@@ -112,6 +117,7 @@
496 raise _common.ToolkitException(
497 'Custom back button in header not visible')
498 self.pointing_device.click_object(custom_back_button)
499+ self.wait_for_animation()
500
501 def _get_animating(self):
502 if self.useDeprecatedToolbar:
503@@ -120,6 +126,14 @@
504 else:
505 return False
506
507+ def wait_for_animation(self):
508+ try:
509+ style = self.select_single(objectName='PageHeadStyle')
510+ style.animating.wait_for(False)
511+ except dbus.StateNotFoundError:
512+ raise _common.ToolkitException(
513+ 'AppHeader is not using the new PageHeadStyle')
514+
515 @autopilot_logging.log_action(logger.info)
516 def switch_to_next_tab(self):
517 """Open the next tab.
518@@ -143,6 +157,7 @@
519 self._get_animating().wait_for(False)
520
521 def _switch_to_next_tab_in_drawer(self):
522+ self.wait_for_animation()
523 tabs_model_properties = self.select_single(
524 'QQuickItem', objectName='tabsModelProperties')
525 next_tab_index = (tabs_model_properties.selectedIndex
526@@ -167,6 +182,7 @@
527 self._switch_to_tab_in_drawer_by_index(index)
528
529 def _switch_to_tab_in_drawer_by_index(self, index):
530+ self.wait_for_animation()
531 try:
532 tabs_drawer_button = self.select_single(objectName='tabsButton')
533 except dbus.StateNotFoundError:
534@@ -187,6 +203,7 @@
535 "Tab button {0} not found.".format(index))
536
537 self.pointing_device.click_object(tab_button)
538+ self.wait_for_animation()
539
540 def click_action_button(self, action_object_name):
541 """Click an action button of the header.
542@@ -200,8 +217,10 @@
543
544 button = self._get_action_button(action_object_name)
545 self.pointing_device.click_object(button)
546+ self.wait_for_animation()
547
548 def _get_action_button(self, action_object_name):
549+ self.wait_for_animation()
550 try:
551 object_name = action_object_name + "_header_button"
552 button = self.select_single(objectName=object_name)
553
554=== modified file 'tests/autopilot/ubuntuuitoolkit/tests/components/test_header.py'
555--- tests/autopilot/ubuntuuitoolkit/tests/components/test_header.py 2014-07-31 08:21:14 +0000
556+++ tests/autopilot/ubuntuuitoolkit/tests/components/test_header.py 2014-08-26 11:41:08 +0000
557@@ -81,6 +81,7 @@
558 objectName='push_button')
559 self.pointing_device.move_to_object(pushButton)
560 self.pointing_device.click()
561+ self.header.wait_for_animation()
562
563 self.assertEqual(label.visible, False)
564 headerContents = self.header.select_single(
565@@ -94,6 +95,7 @@
566 objectName='push_button')
567 self.pointing_device.move_to_object(pushButton)
568 self.pointing_device.click()
569+ self.header.wait_for_animation()
570
571 headerContents = self.header.select_single(
572 objectName='orange_header_contents')
573
574=== added file 'tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_tabs.TabsTestCase.deprecated_TabBar.qml'
575--- tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_tabs.TabsTestCase.deprecated_TabBar.qml 1970-01-01 00:00:00 +0000
576+++ tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_tabs.TabsTestCase.deprecated_TabBar.qml 2014-08-26 11:41:08 +0000
577@@ -0,0 +1,61 @@
578+/*
579+ * Copyright 2014 Canonical Ltd.
580+ *
581+ * This program is free software; you can redistribute it and/or modify
582+ * it under the terms of the GNU Lesser General Public License as published by
583+ * the Free Software Foundation; version 3.
584+ *
585+ * This program is distributed in the hope that it will be useful,
586+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
587+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
588+ * GNU Lesser General Public License for more details.
589+ *
590+ * You should have received a copy of the GNU Lesser General Public License
591+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
592+ */
593+
594+import QtQuick 2.2
595+import Ubuntu.Components 1.1
596+
597+MainView {
598+ width: units.gu(70)
599+ height: units.gu(60)
600+ useDeprecatedToolbar: true
601+
602+ Tabs {
603+ id: tabs
604+ Tab {
605+ objectName: "tab1"
606+ title: "Tab1"
607+ Page {
608+ tools: ToolbarItems {
609+ ToolbarButton {
610+ text: "Test1"
611+ }
612+ }
613+ }
614+ }
615+ Tab {
616+ objectName: "tab2"
617+ title: "Tab2"
618+ Page {
619+ tools: ToolbarItems {
620+ ToolbarButton {
621+ text: "Test2"
622+ }
623+ }
624+ }
625+ }
626+ Tab {
627+ objectName: "tab3"
628+ title: "Tab3"
629+ Page {
630+ tools: ToolbarItems {
631+ ToolbarButton {
632+ text: "Test3"
633+ }
634+ }
635+ }
636+ }
637+ }
638+}
639
640=== added file 'tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_tabs.TabsTestCase.new_header.qml'
641--- tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_tabs.TabsTestCase.new_header.qml 1970-01-01 00:00:00 +0000
642+++ tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_tabs.TabsTestCase.new_header.qml 2014-08-26 11:41:08 +0000
643@@ -0,0 +1,43 @@
644+/*
645+ * Copyright 2014 Canonical Ltd.
646+ *
647+ * This program is free software; you can redistribute it and/or modify
648+ * it under the terms of the GNU Lesser General Public License as published by
649+ * the Free Software Foundation; version 3.
650+ *
651+ * This program is distributed in the hope that it will be useful,
652+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
653+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
654+ * GNU Lesser General Public License for more details.
655+ *
656+ * You should have received a copy of the GNU Lesser General Public License
657+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
658+ */
659+
660+import QtQuick 2.2
661+import Ubuntu.Components 1.1
662+
663+MainView {
664+ width: units.gu(70)
665+ height: units.gu(60)
666+ useDeprecatedToolbar: false
667+
668+ Tabs {
669+ id: tabs
670+ Tab {
671+ objectName: "tab1"
672+ title: "Tab1"
673+ Page { }
674+ }
675+ Tab {
676+ objectName: "tab2"
677+ title: "Tab2"
678+ Page { }
679+ }
680+ Tab {
681+ objectName: "tab3"
682+ title: "Tab3"
683+ Page { }
684+ }
685+ }
686+}
687
688=== modified file 'tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_tabs.py'
689--- tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_tabs.py 2014-06-02 23:21:48 +0000
690+++ tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_tabs.py 2014-08-26 11:41:08 +0000
691@@ -14,6 +14,8 @@
692 # You should have received a copy of the GNU Lesser General Public License
693 # along with this program. If not, see <http://www.gnu.org/licenses/>.
694
695+import os
696+
697 try:
698 from unittest import mock
699 except ImportError:
700@@ -23,64 +25,20 @@
701 from ubuntuuitoolkit import tests
702
703
704-TEST_TABS_QML_FORMAT = ("""
705-import QtQuick 2.0
706-import Ubuntu.Components 1.0
707-
708-MainView {{
709- width: units.gu(70)
710- height: units.gu(60)
711- useDeprecatedToolbar: {use_deprecated_toolbar}
712-
713- Tabs {{
714- id: tabs
715- Tab {{
716- objectName: "tab1"
717- title: "Tab1"
718- Page {{
719- tools: ToolbarItems {{
720- ToolbarButton {{
721- text: "Test1"
722- }}
723- }}
724- }}
725- }}
726- Tab {{
727- objectName: "tab2"
728- title: "Tab2"
729- Page {{
730- tools: ToolbarItems {{
731- ToolbarButton {{
732- text: "Test2"
733- }}
734- }}
735- }}
736- }}
737- Tab {{
738- objectName: "tab3"
739- title: "Tab3"
740- Page {{
741- tools: ToolbarItems {{
742- ToolbarButton {{
743- text: "Test3"
744- }}
745- }}
746- }}
747- }}
748- }}
749-}}
750-""")
751-
752-
753-class TabsTestCase(tests.QMLStringAppTestCase):
754+class TabsTestCase(tests.QMLFileAppTestCase):
755+
756+ path = os.path.abspath(__file__)
757+ dir_path = os.path.dirname(path)
758+ deprecated_tabbar_test_qml_file_path = os.path.join(
759+ dir_path, 'test_tabs.TabsTestCase.deprecated_TabBar.qml')
760+ new_header_test_qml_file_path = os.path.join(
761+ dir_path, 'test_tabs.TabsTestCase.new_header.qml')
762
763 scenarios = [
764- ('deprecated tabs', dict(
765- test_qml=TEST_TABS_QML_FORMAT.format(
766- use_deprecated_toolbar='true'))),
767- ('drawer tabs', dict(
768- test_qml=TEST_TABS_QML_FORMAT.format(
769- use_deprecated_toolbar='false')))
770+ ('deprecated TabBar',
771+ dict(test_qml_file_path=deprecated_tabbar_test_qml_file_path)),
772+ ('new header',
773+ dict(test_qml_file_path=new_header_test_qml_file_path))
774 ]
775
776 def test_tabs_custom_proxy_object(self):
777
778=== modified file 'tests/resources/header/header.qml'
779--- tests/resources/header/header.qml 2014-07-31 14:09:45 +0000
780+++ tests/resources/header/header.qml 2014-08-26 11:41:08 +0000
781@@ -206,12 +206,10 @@
782 anchors.centerIn: parent
783 text: "Use back button to return"
784 }
785- tools: ToolbarItems {
786- ToolbarButton {
787- action: Action {
788- iconName: "settings"
789- text: "settings"
790- }
791+ head {
792+ actions: Action {
793+ iconName: "settings"
794+ text: "settings"
795 }
796 }
797 }
798
799=== modified file 'tests/resources/navigation/MyCustomPage.qml'
800--- tests/resources/navigation/MyCustomPage.qml 2014-06-24 11:15:30 +0000
801+++ tests/resources/navigation/MyCustomPage.qml 2014-08-26 11:41:08 +0000
802@@ -15,7 +15,7 @@
803 */
804
805 import QtQuick 2.0
806-import Ubuntu.Components 1.0
807+import Ubuntu.Components 1.1
808
809 Page {
810 title: i18n.tr("My custom page")
811@@ -30,32 +30,24 @@
812 horizontalCenter: parent.horizontalCenter
813 }
814
815- text: i18n.tr("This is an external page\nwith a locked toolbar.")
816+ text: i18n.tr("This is an external page.")
817 color: "#757373"
818 }
819 }
820
821- tools: ToolbarItems {
822- ToolbarButton {
823- action: Action {
824- text: "action 1"
825- iconName: "outgoing-call"
826- }
827- }
828- ToolbarButton {
829- action: Action {
830- text: "action 2"
831- iconName: "missed-call"
832- }
833- }
834- ToolbarButton {
835- action: Action {
836- text: "another one"
837- iconName: "contact"
838- }
839- }
840-
841- opened: true
842- locked: true
843- }
844+ head.actions: [
845+ Action {
846+ text: "action 1"
847+ iconName: "outgoing-call"
848+ },
849+ Action {
850+ text: "action 2"
851+ iconSource: "call_icon.png"
852+ iconName: "missed-call"
853+ },
854+ Action {
855+ text: "another one"
856+ iconName: "contact"
857+ }
858+ ]
859 }
860
861=== modified file 'tests/unit_x11/tst_components/tst_headActions.qml'
862--- tests/unit_x11/tst_components/tst_headActions.qml 2014-07-28 18:41:55 +0000
863+++ tests/unit_x11/tst_components/tst_headActions.qml 2014-08-26 11:41:08 +0000
864@@ -64,39 +64,52 @@
865 property var app_header
866 property var back_button
867 property var custom_back_button
868+ property var head_animation
869
870 function initTestCase() {
871 testCase.app_header = findChild(mainView, "MainView_Header");
872 testCase.back_button = findChild(app_header, "backButton");
873 testCase.custom_back_button = findChild(app_header, "customBackButton");
874+ testCase.head_animation = findChild(app_header, "PageHeadStyle");
875
876+ waitHeadAnimation();
877 compare(page2.head.backAction, null, "Back action set by default.");
878 compare(back_button.visible, false, "Back button visible with only 1 page on the stack.");
879 compare(custom_back_button.visible, false, "Custom back button visible without custom back action.")
880 }
881
882+ function waitHeadAnimation() {
883+ tryCompareFunction(function(){return testCase.head_animation.animating}, false);
884+ }
885+
886 function test_default_back_button() {
887 pageStack.push(page2);
888+ waitHeadAnimation();
889 compare(back_button.visible, true, "Back button not visible with 2 pages on stack.");
890 compare(custom_back_button.visible, false, "Showing custom back button without custom back action.");
891 pageStack.pop();
892+ waitHeadAnimation();
893 }
894
895 function test_custom_back_button() {
896 page2.head.backAction = customBackAction;
897 pageStack.push(page2);
898+ waitHeadAnimation();
899 compare(back_button.visible, false, "Default back button visible with custom back action.");
900 compare(custom_back_button.visible, true, "Custom back button invisible with back action.");
901 pageStack.pop();
902+ waitHeadAnimation();
903 page2.head.backAction = null;
904 }
905
906 function test_no_back_button() {
907 page2.head.backAction = invisibleAction;
908 pageStack.push(page2);
909+ waitHeadAnimation();
910 compare(back_button.visible, false, "Default back button visible with invisible custom back action.");
911 compare(custom_back_button.visible, false, "Custom back button visible with invisible custom back action.");
912 pageStack.pop();
913+ waitHeadAnimation();
914 page2.head.backAction = null;
915 }
916 }
917
918=== modified file 'tests/unit_x11/tst_components/tst_pagestack_new_header.qml'
919--- tests/unit_x11/tst_components/tst_pagestack_new_header.qml 2014-08-18 10:40:45 +0000
920+++ tests/unit_x11/tst_components/tst_pagestack_new_header.qml 2014-08-26 11:41:08 +0000
921@@ -27,6 +27,7 @@
922
923 MainView {
924 id: mainView
925+ anchors.fill: parent
926 useDeprecatedToolbar: false
927 PageStack {
928 id: pageStack
929@@ -65,7 +66,13 @@
930 when: windowShown
931 id: testCase
932
933+ function waitPageHeadAnimation() {
934+ var pageHeadStyle = findChild(mainView, "PageHeadStyle");
935+ tryCompare(pageHeadStyle, "animating", false);
936+ }
937+
938 function initTestCase() {
939+ waitPageHeadAnimation();
940 compare(pageStack.currentPage, null, "is not set by default");
941 compare(pageStack.__propagated, mainView.__propagated, "propagated property of pageStack equals mainView.__propagated")
942 compare(mainView.__propagated.header.title, "", "empty title by default");
943@@ -74,55 +81,73 @@
944 function test_depth() {
945 compare(pageStack.depth, 0, "depth is 0 by default");
946 pageStack.push(page1);
947+ waitPageHeadAnimation();
948 compare(pageStack.depth, 1, "depth is correctly increased when pushing a page");
949 pageStack.push(page2);
950+ waitPageHeadAnimation();
951 compare(pageStack.depth, 2, "depth is correctly updated when pushing a page");
952 pageStack.pop();
953+ waitPageHeadAnimation();
954 compare(pageStack.depth, 1, "depth is correctly decreased when popping a page");
955 pageStack.clear();
956+ waitPageHeadAnimation();
957 compare(pageStack.depth, 0, "depth is after clearing");
958 }
959
960 function test_currentPage() {
961 compare(pageStack.currentPage, null, "currentPage is null by default");
962 pageStack.push(page1);
963+ waitPageHeadAnimation();
964 compare(pageStack.currentPage, page1, "currentPage properly updated");
965 pageStack.clear();
966+ waitPageHeadAnimation();
967 compare(pageStack.currentPage, null, "currentPage properly reset");
968 }
969
970 function test_active_bug1260116() {
971 pageStack.push(page1);
972+ waitPageHeadAnimation();
973 compare(page1.active, true, "Page is active after pushing");
974 pageStack.push(page2);
975+ waitPageHeadAnimation();
976 compare(page1.active, false, "Page no longer active after pushing a new page");
977 compare(page2.active, true, "New page is active after pushing");
978 pageStack.pop();
979+ waitPageHeadAnimation();
980 compare(page1.active, true, "Page re-activated when on top of the stack");
981 compare(page2.active, false, "Page no longer active after being popped");
982 pageStack.clear();
983+ waitPageHeadAnimation();
984
985 compare(pageInStack.active, false, "Page defined inside PageStack is not active by default");
986 pageStack.push(pageInStack);
987+ waitPageHeadAnimation();
988 compare(pageInStack.active, true, "Pushing a page on PageStack makes it active");
989 pageStack.pop();
990+ waitPageHeadAnimation();
991 compare(pageInStack.active, false, "Popping a page from PageStack makes it inactive");
992 pageStack.clear();
993+ waitPageHeadAnimation();
994 }
995
996 function test_title_bug1143345_bug1317902() {
997 pageStack.push(page1);
998+ waitPageHeadAnimation();
999 compare(mainView.__propagated.header.title, "Title 1", "Header title is correctly set by page");
1000 page1.title = "New title";
1001 compare(mainView.__propagated.header.title, "New title", "Header title correctly updated by page");
1002 pageStack.push(page2);
1003+ waitPageHeadAnimation();
1004 compare(mainView.__propagated.header.title, "Title 2", "Header title is correctly set by page");
1005 pageStack.clear();
1006+ waitPageHeadAnimation();
1007 page1.title = "Title 1";
1008
1009 pageStack.push(pageWithPage);
1010+ waitPageHeadAnimation();
1011 compare(mainView.__propagated.header.title, pageWithPage.title, "Embedded page sets title of outer page");
1012 pageStack.clear();
1013+ waitPageHeadAnimation();
1014 }
1015
1016 function get_tabs_button() {
1017@@ -134,28 +159,36 @@
1018 function test_tabs_inside_stack_bug1187850() {
1019 compare(get_tabs_button(), null, "Without tabs there is no visible tabs button.");
1020 pageStack.push(tabs);
1021+ waitPageHeadAnimation();
1022 compare(pageStack.currentPage, tabs, "Tabs can be pushed on a PageStack");
1023 compare(tabs.active, true, "Tabs on top of a PageStack are active");
1024 compare(get_tabs_button().visible, true, "Pushing tabs on pagestack enables the tabs button");
1025 pageStack.push(page1);
1026+ waitPageHeadAnimation();
1027 compare(pageStack.currentPage, page1, "A page can be pushed on top of a Tabs");
1028 compare(tabs.active, false, "Tabs on a PageStack, but not on top, are inactive");
1029 compare(get_tabs_button(), null, "Contents of inactive Tabs is not applied to header");
1030 pageStack.pop();
1031+ waitPageHeadAnimation();
1032 compare(tabs.active, true, "Tabs on top of PageStack is active");
1033 compare(get_tabs_button().visible, true, "Active Tabs controls header contents");
1034 pageStack.clear();
1035+ waitPageHeadAnimation();
1036 }
1037
1038 function test_pop_to_tabs_bug1316736() {
1039 pageStack.push(tabs);
1040+ waitPageHeadAnimation();
1041 tabs.selectedTabIndex = 1;
1042 pageStack.push(page1);
1043+ waitPageHeadAnimation();
1044 compare(tabs.active, false, "Tabs on a PageStack, but not on top, are inactive");
1045 pageStack.pop();
1046+ waitPageHeadAnimation();
1047 compare(tabs.active, true, "Tabs on top of PageStack is active");
1048 compare(tabs.selectedTabIndex, 1, "Pushing and popping another page on top of Tabs does not change selectedTabsIndex");
1049 pageStack.clear();
1050+ waitPageHeadAnimation();
1051 }
1052 }
1053 }

Subscribers

People subscribed via source and target branches