Merge lp:~tpeeters/ubuntu-ui-toolkit/headerHeightInit into lp:ubuntu-ui-toolkit

Proposed by Tim Peeters
Status: Merged
Approved by: Cris Dywan
Approved revision: 926
Merged at revision: 907
Proposed branch: lp:~tpeeters/ubuntu-ui-toolkit/headerHeightInit
Merge into: lp:ubuntu-ui-toolkit
Diff against target: 216 lines (+76/-35)
4 files modified
modules/Ubuntu/Components/Header.qml (+25/-1)
modules/Ubuntu/Components/Page.qml (+4/-28)
tests/unit/tst_components/tst_page.qml (+9/-4)
tests/unit_x11/tst_components/tst_header.qml (+38/-2)
To merge this branch: bzr merge lp:~tpeeters/ubuntu-ui-toolkit/headerHeightInit
Reviewer Review Type Date Requested Status
Cris Dywan Approve
PS Jenkins bot continuous-integration Approve
Francis Ginther (community) Approve
Review via email: mp+199468@code.launchpad.net

Description of the change

Fix the positioning of a flickable in a Page which has a parent that is not a PageTreeNode.

To post a comment you must log in.
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)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Tim Peeters (tpeeters) wrote :
Revision history for this message
Tim Peeters (tpeeters) wrote :

no breakage on maguro with file manager, calculator, clock, calendar, gallery.

Revision history for this message
Tim Peeters (tpeeters) wrote :

UITK autopilot tests passed on maguro: https://pastebin.canonical.com/102317/

MR is ready to go.

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: Approve (continuous-integration)
Revision history for this message
Cris Dywan (kalikiana) wrote :

How about instead of moving the alignment test inside an Item, add a second one, to actually test that both behave the same?

And for the page test flickableY + header.height is expected now instead of just flickableY, I wonder if headerHeight can be checked also here to know the value is right? Since the existing case should not have changed but the test doesn't check.

review: Needs Information
Revision history for this message
Tim Peeters (tpeeters) wrote :

> How about instead of moving the alignment test inside an Item, add a second
> one, to actually test that both behave the same?

ok, done.

> And for the page test flickableY + header.height is expected now instead of
> just flickableY, I wonder if headerHeight can be checked also here to know the
> value is right? Since the existing case should not have changed but the test
> doesn't check.

Added checks for headerHeight, and clarified in the test why things are happening the way they are.

Revision history for this message
Tim Peeters (tpeeters) wrote :

Code in tst_page.qml mixes two conventions for having a semicolon at the end of a line. I'm not fixing that here to keep the diff small and focussed on what matters to fix the bug. Reported https://bugs.launchpad.net/ubuntu-ui-toolkit/+bug/1266453

Revision history for this message
Tim Peeters (tpeeters) wrote :

I didn't test the changes on device yet. Don't happrove until I do that.

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)
Revision history for this message
Cris Dywan (kalikiana) wrote :

FAIL! : components::DatePickerAPI::test_1_changeDateToNextMonth() Uncaught exception: Cannot read property 'children' of null
   Loc: [(0)]

It's failed on that before but I guess it's a race condition - unless somebody switched Qt on the Jenkins over new year's eve.

I appreciate the test clarifications, in general I'm happy for it to go in minus the weird failures.

review: Approve
Revision history for this message
Tim Peeters (tpeeters) wrote :

I created a bug for the jenkins failure: https://bugs.launchpad.net/ubuntu-ui-toolkit/+bug/1266515

Revision history for this message
Tim Peeters (tpeeters) wrote :

Tested on device with gallery, file-manager, notes. ubuntuuitoolkit autopilot tests passed.

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)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Cris Dywan (kalikiana) wrote :

I can live with that work-around as the value we need is correct.

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)
Revision history for this message
Francis Ginther (fginther) wrote :

This can be re-approved, the autolanding failed due to a CI issue.

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)
919. By Tim Peeters

change to test jenkins

920. By Tim Peeters

add TODO

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

Tests fail because contentY gets an incorrect intermediate value. It is immediately updated to the correct value afterwards, but the test catches the wrong one. It doesn't cause problems in practise but it is not clear to me why the intermediate wrong value is there. Investigating...

921. By Tim Peeters

debugging

922. By Tim Peeters

remove initializeFlickablePosition. This is done automatically by the ListView

923. By Tim Peeters

put test back

924. By Tim Peeters

remove debugging code

925. By Tim Peeters

remove debugging code

Revision history for this message
Tim Peeters (tpeeters) wrote :

this is the change that matters and should fix the CI results: http://bazaar.launchpad.net/~tpeeters/ubuntu-ui-toolkit/headerHeightInit/revision/922

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

the diff since last happroval, to make reviewing easier:

=== modified file modules/Ubuntu/Components/Page.qml
--- modules/Ubuntu/Components/Page.qml 2013-12-19 16:22:20 +0000
+++ modules/Ubuntu/Components/Page.qml 2014-01-09 12:00:26 +0000
@@ -192,12 +192,6 @@
             }
         }

- Connections {
- target: page
- onFlickableChanged: internal.initializeFlickablePosition()
- }
- Component.onCompleted: internal.initializeFlickablePosition()
-
         function isVerticalFlickable(object) {
             if (object && object.hasOwnProperty("flickableDirection") && object.hasOwnProperty("contentHeight")) {
                 var direction = object.flickableDirection;
@@ -226,16 +220,5 @@
             }
             return null;
         }
-
- function initializeFlickablePosition() {
- if (page.flickable) {
- // compensating for header height and setting flickable.topMargin is done
- // automatically by the header when its flickable property is set.
- if (page.flickable.hasOwnProperty("headerItem") && page.flickable.headerItem) {
- // flickable is a ListView with a headerItem
- page.flickable.contentY -= page.flickable.headerItem.height;
- }
- }
- }
     }
 }

926. By Tim Peeters

merge trunk

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

To clarify why the last change (removing the initializeFlickablePosition()) makes sense:

(MHeader = header of the mainview/page - this shows the current page title or the tabbar)
(LVHeader = the header inside the listview, specified by ListView.header property)

- In previous versions of the code, I used to set the contentY of the flickable to -MHeader.height,
because that ignored LVHeader, I then subtracted LVHeader.height from it.

- In the new version of the code, I don't set the contentY to -MHeader.height, but when MHeader.height is updated (or initialized), I SUBTRACT MHeader.height from contentY.

- It turns out that the listview already updates contentY when an LVHeader is used. In the previous version of our code, this update was overridden by setting the ListView.contentY to -MHeader.height, but now in the new version where we subtract MHeader.height from contentY instead of setting it, our code to accomodate for LVHeader.height in initializeFlickablePosition() is no longer needed. That's already done automatically by the ListView.

Revision history for this message
Cris Dywan (kalikiana) wrote :

This surprisingly makes sense :-D It also explains the earlier issue with the tests but these can stay, they're nicer now anyway.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'modules/Ubuntu/Components/Header.qml'
2--- modules/Ubuntu/Components/Header.qml 2013-12-02 18:54:08 +0000
3+++ modules/Ubuntu/Components/Header.qml 2014-01-09 13:31:04 +0000
4@@ -49,9 +49,15 @@
5 }
6
7 /*! \internal */
8- onHeightChanged: internal.movementEnded()
9+ onHeightChanged: {
10+ internal.checkFlickableMargins();
11+ internal.movementEnded();
12+ }
13
14 visible: title || contents
15+ onVisibleChanged: {
16+ internal.checkFlickableMargins();
17+ }
18
19 /*!
20 Show the header
21@@ -86,6 +92,7 @@
22 */
23 property Flickable flickable: null
24 onFlickableChanged: {
25+ internal.checkFlickableMargins();
26 internal.connectFlickable();
27 header.show();
28 }
29@@ -158,6 +165,23 @@
30 function interactiveChanged() {
31 if (flickable && !flickable.interactive) header.show();
32 }
33+
34+ /*
35+ Check the topMargin of the flickable and set it if needed to avoid
36+ contents becoming unavailable behind the header.
37+ */
38+ function checkFlickableMargins() {
39+ if (header.flickable) {
40+ var headerHeight = header.visible ? header.height : 0
41+ if (flickable.topMargin !== headerHeight) {
42+ var previousHeaderHeight = flickable.topMargin;
43+ flickable.topMargin = headerHeight;
44+ // push down contents when header grows,
45+ // pull up contents when header shrinks.
46+ flickable.contentY -= headerHeight - previousHeaderHeight;
47+ }
48+ }
49+ }
50 }
51
52 style: Theme.createStyleComponent("HeaderStyle.qml", header)
53
54=== modified file 'modules/Ubuntu/Components/Page.qml'
55--- modules/Ubuntu/Components/Page.qml 2013-11-26 14:19:38 +0000
56+++ modules/Ubuntu/Components/Page.qml 2014-01-09 13:31:04 +0000
57@@ -170,6 +170,10 @@
58 property Header header: page.__propagated && page.__propagated.header ? page.__propagated.header : null
59 property Toolbar toolbar: page.__propagated && page.__propagated.toolbar ? page.__propagated.toolbar : null
60
61+ // Used to position the Page when there is no flickable.
62+ // When there is a flickable, the header will automatically position it.
63+ property real headerHeight: internal.header && internal.header.visible ? internal.header.height : 0
64+
65 onHeaderChanged: internal.updateHeaderAndToolbar()
66 onToolbarChanged: internal.updateHeaderAndToolbar()
67
68@@ -188,14 +192,6 @@
69 }
70 }
71
72- Connections {
73- target: page
74- onFlickableChanged: internal.updateFlickablePosition()
75- }
76- Component.onCompleted: internal.updateFlickablePosition()
77-
78- property real headerHeight: internal.header && internal.header.visible ? internal.header.height : 0
79-
80 function isVerticalFlickable(object) {
81 if (object && object.hasOwnProperty("flickableDirection") && object.hasOwnProperty("contentHeight")) {
82 var direction = object.flickableDirection;
83@@ -224,25 +220,5 @@
84 }
85 return null;
86 }
87-
88- Binding {
89- target: page.flickable
90- property: "topMargin"
91- value: internal.headerHeight
92- when: page.flickable
93- }
94-
95- function updateFlickablePosition() {
96- if (page.flickable) {
97- // Set-up the top-margin of the contents of the Flickable so that
98- // the contents is never hidden by the header
99- var displacement = headerHeight;
100- if (page.flickable.hasOwnProperty("headerItem") && page.flickable.headerItem) {
101- // flickable is a ListView with a headerItem
102- displacement += page.flickable.headerItem.height;
103- }
104- page.flickable.contentY = -displacement;
105- }
106- }
107 }
108 }
109
110=== modified file 'tests/unit/tst_components/tst_page.qml'
111--- tests/unit/tst_components/tst_page.qml 2013-09-03 10:51:40 +0000
112+++ tests/unit/tst_components/tst_page.qml 2014-01-09 13:31:04 +0000
113@@ -126,16 +126,21 @@
114 function test_flickableY_bug1201452() {
115 var pageTitle = "Hello bug!";
116 page.title = pageTitle;
117- compare(page.__propagated.header.visible, true, "header is visible when title is set")
118- compare(page.__propagated.header.height > 0, true, "header has a height when title is set")
119+ var header = page.__propagated.header;
120+ compare(header.visible, true, "header is visible when title is set")
121+ compare(header.height > 0, true, "header has a height when title is set")
122+ var headerHeight = header.height
123 var flickableY = 150;
124 page.flickable.contentY = flickableY;
125 compare(page.flickable.contentY, flickableY, "flickable.contentY can be set");
126+ compare(page.flickable.topMargin, headerHeight, "topMargin of the flickable equals header height");
127 page.title = "";
128- compare(page.__propagated.header.visible, false, "header is hidden when title is unset")
129- compare(page.flickable.contentY, flickableY, "Making header invisible does not reset flickable.contentY");
130+ compare(header.visible, false, "header is hidden when title is unset")
131+ compare(page.flickable.topMargin, 0, "topMargin becomes 0 because header is hidden"); // used to be headerHeight
132+ compare(page.flickable.contentY, flickableY + headerHeight, "contentY is updated when header is made invisible to compensate for the change in topMargin");
133 page.title = pageTitle;
134 compare(page.flickable.contentY, flickableY, "Making header visible again does not reset flickable.contentY");
135+ compare(page.flickable.topMargin, headerHeight, "topMargin is updated when header becomes visible.")
136 }
137 }
138 }
139
140=== modified file 'tests/unit_x11/tst_components/tst_header.qml'
141--- tests/unit_x11/tst_components/tst_header.qml 2013-11-11 11:15:53 +0000
142+++ tests/unit_x11/tst_components/tst_header.qml 2014-01-09 13:31:04 +0000
143@@ -22,11 +22,15 @@
144 width: units.gu(50)
145 height: units.gu(80)
146
147+ id: root
148+ property real listViewHeaderHeight: units.gu(5)
149+
150 MainView {
151 id: mainViewHeader
152 anchors.fill: parent
153
154 Page {
155+ id: page
156 title: "listview"
157
158 ListView {
159@@ -36,7 +40,7 @@
160 header: Rectangle {
161 color: "red"
162 width: parent.width
163- height: units.gu(5)
164+ height: root.listViewHeaderHeight
165 }
166 model: 500
167 delegate: Label {
168@@ -44,6 +48,33 @@
169 }
170 }
171 }
172+
173+ Item {
174+ // Wrapping the Page inside this Item should not
175+ // affect the header alignment, see bug #1261907.
176+ anchors.fill: parent
177+ id: wrappingItem
178+
179+ Page {
180+ id: wrappedPage
181+ title: "listview"
182+
183+ ListView {
184+ anchors.fill: parent
185+ id: wrappedListView
186+
187+ header: Rectangle {
188+ color: "red"
189+ width: parent.width
190+ height: root.listViewHeaderHeight
191+ }
192+ model: 500
193+ delegate: Label {
194+ text: "number " +index
195+ }
196+ }
197+ }
198+ }
199 }
200
201 TestCase {
202@@ -51,8 +82,13 @@
203 when: windowShown
204
205 function test_ListViewHeaderAlignment_bug1202277() {
206- compare(listView.contentY, -listView.headerItem.height - mainViewHeader.__propagated.header.height,
207+ compare(listView.contentY, -root.listViewHeaderHeight - mainViewHeader.__propagated.header.height,
208 "ListView header is aligned with the MainView header");
209 }
210+
211+ function test_WrappedListViewHeaderAlignment_bug1261907() {
212+ compare(wrappedListView.contentY, -root.listViewHeaderHeight - mainViewHeader.__propagated.header.height,
213+ "ListView header inside wrapped Page is aligned with the MainView header");
214+ }
215 }
216 }

Subscribers

People subscribed via source and target branches

to status/vote changes: