Merge lp:~faenil/ubuntu-ui-toolkit/scrollbar_defaultTopBottomMargins into lp:ubuntu-ui-toolkit/staging
- scrollbar_defaultTopBottomMargins
- Merge into staging
Status: | Merged |
---|---|
Approved by: | Zoltan Balogh |
Approved revision: | 1907 |
Merged at revision: | 1910 |
Proposed branch: | lp:~faenil/ubuntu-ui-toolkit/scrollbar_defaultTopBottomMargins |
Merge into: | lp:ubuntu-ui-toolkit/staging |
Diff against target: |
512 lines (+393/-15) 5 files modified
examples/ubuntu-ui-toolkit-gallery/Template.qml (+1/-4) src/Ubuntu/Components/1.3/ScrollView.qml (+7/-0) src/Ubuntu/Components/1.3/Scrollbar.qml (+48/-10) tests/unit_x11/tst_components/tst_scrollbar.qml (+26/-1) tests/unit_x11/tst_components/tst_scrollbar_header.qml (+311/-0) |
To merge this branch: | bzr merge lp:~faenil/ubuntu-ui-toolkit/scrollbar_defaultTopBottomMargins |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
ubuntu-sdk-build-bot | continuous-integration | Approve | |
Zsombor Egri | Approve | ||
Review via email: mp+289946@code.launchpad.net |
Commit message
Change Scrollbar default top and bottom anchor margins. Tests included.
Description of the change
With this MR Scrollbar will default to using Flickable.topMargin and Flickable.
This is to workaround the fact that Header and BottomEdgeHint modify Flickable.
The solution was brainstormed with timp, zsombi, kalikiana.
If the developer wants to have custom Flickable top/bottomMargin (content margins), he will have to also modify Scrollbar margins.
This usecase will be addressed by a future MR, as the solution is still being brainstormed.
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote : | # |
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote : | # |
FAILED: Continuous integration, rev:1904
https:/
Executed test runs:
None: https:/
Click here to trigger a rebuild:
https:/
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote : | # |
FAILED: Continuous integration, rev:1904
https:/
Executed test runs:
None: https:/
Click here to trigger a rebuild:
https:/
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote : | # |
FAILED: Continuous integration, rev:1904
https:/
Executed test runs:
None: https:/
Click here to trigger a rebuild:
https:/
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote : | # |
FAILED: Continuous integration, rev:1904
https:/
Executed test runs:
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
None: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
Click here to trigger a rebuild:
https:/
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote : | # |
FAILED: Continuous integration, rev:1905
https:/
Executed test runs:
None: https:/
Click here to trigger a rebuild:
https:/
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote : | # |
FAILED: Continuous integration, rev:1905
https:/
Executed test runs:
None: https:/
Click here to trigger a rebuild:
https:/
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote : | # |
FAILED: Continuous integration, rev:1905
https:/
Executed test runs:
None: https:/
Click here to trigger a rebuild:
https:/
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote : | # |
FAILED: Continuous integration, rev:1905
https:/
Executed test runs:
None: https:/
Click here to trigger a rebuild:
https:/
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote : | # |
FAILED: Continuous integration, rev:1905
https:/
Executed test runs:
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
None: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
Click here to trigger a rebuild:
https:/
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote : | # |
PASSED: Continuous integration, rev:1906
https:/
Executed test runs:
None: https:/
Click here to trigger a rebuild:
https:/
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote : | # |
PASSED: Continuous integration, rev:1906
https:/
Executed test runs:
None: https:/
Click here to trigger a rebuild:
https:/
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote : | # |
PASSED: Continuous integration, rev:1906
https:/
Executed test runs:
None: https:/
Click here to trigger a rebuild:
https:/
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote : | # |
PASSED: Continuous integration, rev:1906
https:/
Executed test runs:
None: https:/
Click here to trigger a rebuild:
https:/
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote : | # |
PASSED: Continuous integration, rev:1906
https:/
Executed test runs:
SUCCESS: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
SUCCESS: https:/
None: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
Click here to trigger a rebuild:
https:/
Zsombor Egri (zsombi) wrote : | # |
Great fix, nice tests, that's my boy :)
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote : | # |
PASSED: Continuous integration, rev:1907
https:/
Executed test runs:
None: https:/
Click here to trigger a rebuild:
https:/
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote : | # |
PASSED: Continuous integration, rev:1907
https:/
Executed test runs:
None: https:/
Click here to trigger a rebuild:
https:/
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote : | # |
PASSED: Continuous integration, rev:1907
https:/
Executed test runs:
None: https:/
Click here to trigger a rebuild:
https:/
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote : | # |
FAILED: Continuous integration, rev:1907
https:/
Executed test runs:
None: https:/
Click here to trigger a rebuild:
https:/
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote : | # |
PASSED: Continuous integration, rev:1907
https:/
Executed test runs:
None: https:/
Click here to trigger a rebuild:
https:/
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote : | # |
PASSED: Continuous integration, rev:1907
https:/
Executed test runs:
None: https:/
Click here to trigger a rebuild:
https:/
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote : | # |
PASSED: Continuous integration, rev:1907
https:/
Executed test runs:
None: https:/
Click here to trigger a rebuild:
https:/
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote : | # |
PASSED: Continuous integration, rev:1907
https:/
Executed test runs:
None: https:/
Click here to trigger a rebuild:
https:/
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote : | # |
FAILED: Continuous integration, rev:1907
https:/
Executed test runs:
SUCCESS: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
FAILURE: https:/
None: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
Click here to trigger a rebuild:
https:/
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote : | # |
PASSED: Continuous integration, rev:1907
https:/
Executed test runs:
None: https:/
Click here to trigger a rebuild:
https:/
Preview Diff
1 | === modified file 'examples/ubuntu-ui-toolkit-gallery/Template.qml' |
2 | --- examples/ubuntu-ui-toolkit-gallery/Template.qml 2016-01-13 16:14:08 +0000 |
3 | +++ examples/ubuntu-ui-toolkit-gallery/Template.qml 2016-03-24 10:43:42 +0000 |
4 | @@ -34,19 +34,16 @@ |
5 | } |
6 | |
7 | ScrollView { |
8 | - //anchors.fill: parent |
9 | - //anchors.topMargin: template.header.flickable ? 0 : template.header.height |
10 | objectName: "TemplateScrollView" |
11 | anchors { |
12 | fill: parent |
13 | topMargin: template.header.flickable ? 0 : template.header.height |
14 | } |
15 | + |
16 | Flickable { |
17 | id: templateFlickable |
18 | objectName: "TemplateFlickable" |
19 | anchors.fill: parent |
20 | - topMargin: units.gu(2) |
21 | - bottomMargin: units.gu(2) |
22 | contentHeight: column.height |
23 | interactive: contentHeight > height |
24 | Column { |
25 | |
26 | === modified file 'src/Ubuntu/Components/1.3/ScrollView.qml' |
27 | --- src/Ubuntu/Components/1.3/ScrollView.qml 2016-02-18 12:39:14 +0000 |
28 | +++ src/Ubuntu/Components/1.3/ScrollView.qml 2016-03-24 10:43:42 +0000 |
29 | @@ -30,6 +30,13 @@ |
30 | migrate to ScrollView, to ensure the UX is ready for convergent devices and is consistent with the |
31 | rest of the platform. |
32 | |
33 | + ScrollView wraps \l {Scrollbar}(s) in a view, and provides additional features such as: |
34 | + \list |
35 | + \li - Keyboard navigation and focus handling, for a complete convergent experience. |
36 | + \li - Automatic position handling of vertical and horizontal scrollbars, preventing them from |
37 | + overlapping one another when both on screen. |
38 | + \endlist |
39 | + |
40 | Adding scrollbars and keyboard input handling to a QML item is as simple as wrapping that item in a |
41 | ScrollView, as shown in the following example: |
42 | |
43 | |
44 | === modified file 'src/Ubuntu/Components/1.3/Scrollbar.qml' |
45 | --- src/Ubuntu/Components/1.3/Scrollbar.qml 2016-02-25 12:59:27 +0000 |
46 | +++ src/Ubuntu/Components/1.3/Scrollbar.qml 2016-03-24 10:43:42 +0000 |
47 | @@ -18,14 +18,19 @@ |
48 | import Ubuntu.Components 1.3 as Toolkit |
49 | |
50 | /*! |
51 | - \qmltype ScrollBar |
52 | + \qmltype Scrollbar |
53 | \inqmlmodule Ubuntu.Components 1.1 |
54 | \ingroup ubuntu |
55 | - \brief The ScrollBar component provides scrolling functionality for |
56 | + \brief The Scrollbar component provides scrolling functionality for |
57 | scrollable views (i.e. Flickable, ListView). |
58 | |
59 | - The ScrollBar can be set to any flickable and has built-in anchoring setup |
60 | - to the attached flickable's front, rear, top or bottom. the scrollbar can |
61 | + \b NOTE: the Scrollbar component was revamped for OTA9 and used for the implementation |
62 | + of \l ScrollView. Apps targeting system version OTA9 (or newer) should use ScrollView instead |
63 | + of Scrollbar, as it features convergent-ready features, such as (but not limited to) |
64 | + keyboard input handling. |
65 | + |
66 | + The Scrollbar can be set to any flickable and has built-in anchoring setup |
67 | + to the attached flickable's front, rear, top or bottom. The scrollbar can |
68 | also be aligned using anchors, however the built-in align functionality |
69 | makes sure to have the proper alignemt applied based on theme and layout |
70 | direction (RTL or LTR). |
71 | @@ -57,6 +62,43 @@ |
72 | } |
73 | } |
74 | \endqml |
75 | + |
76 | + \section1 Vertical Scrollbar and Flickable behaviour |
77 | + |
78 | + Since Flickable's topMargin and bottomMargin are modified by Ubuntu components |
79 | + such as \l BottomEdgeHint and \l Header in their positioning logic, the Scrollbar component |
80 | + uses the value of those properties to its top and bottom anchors margins, by default. This is |
81 | + to prevent any overlap with BottomEdgeHint or Header (see \l {Vertical Scrollbar and Header behaviour} |
82 | + for more info about that). In case you need to specify custom Flickable |
83 | + content margins (note: we're talking about content margins, not anchors ones), you will also have to |
84 | + override the top and bottom anchors margins of the Scrollbar accordingly. |
85 | + |
86 | + \section1 Vertical Scrollbar and Header behaviour |
87 | + |
88 | + The thumb of the Scrollbar should not move or resize unexpectedly. It would be confusing, |
89 | + for instance, if it moved under the user's finger (or pointer) while he's dragging it. |
90 | + |
91 | + Because the size and position of the thumb in a scrollbar is related to the size of the |
92 | + trough (or track) it slides in, it is important that the trough does not resize or move while the |
93 | + user is interacting with the component. |
94 | + |
95 | + In the context of a \l Page with a \l Header that slides in and out dynamically when the user |
96 | + flicks the surface (see \l {Header::flickable}), a vertical Scrollbar that is linked |
97 | + to the same flickable surface as the Header behaves as described below: |
98 | + |
99 | + \list |
100 | + \li - when the Header is exposed, the Scrollbar component sits right below it, \ |
101 | + thus avoiding overlaps; |
102 | + |
103 | + \li - when the Header hides due to the user either flicking the surface or dragging \ |
104 | + the thumb, the trough of the Scrollbar does not resize or move, thus avoiding \ |
105 | + unexpected changes in thumb's position or size. As a side effect, the space \ |
106 | + above the Scrollbar, previously occupied by Header, stays empty until the Header \ |
107 | + is exposed again. |
108 | + |
109 | + \endlist |
110 | + \br |
111 | + This behaviour is intended and makes for a less confusing User Experience. |
112 | */ |
113 | |
114 | Toolkit.StyledItem { |
115 | @@ -135,9 +177,9 @@ |
116 | right: internals.rightAnchor(__viewport ? __viewport : flickableItem) |
117 | rightMargin: internals.rightAnchorMargin() |
118 | top: internals.topAnchor(__viewport ? __viewport : flickableItem) |
119 | - topMargin: internals.topAnchorMargin() |
120 | + topMargin: (flickableItem ? flickableItem.topMargin : 0) + internals.topAnchorMargin() |
121 | bottom: internals.bottomAnchor(__viewport ? __viewport : flickableItem) |
122 | - bottomMargin: internals.bottomAnchorMargin() |
123 | + bottomMargin: (flickableItem ? flickableItem.bottomMargin : 0) + internals.bottomAnchorMargin() |
124 | } |
125 | |
126 | /*! |
127 | @@ -183,7 +225,6 @@ |
128 | && __buddyScrollbar.align === Qt.AlignLeading |
129 | && __buddyScrollbar.__styleInstance.isScrollable) |
130 | return __buddyScrollbar.__styleInstance.troughThicknessSteppersStyle |
131 | - //return buddyScrollbar.__styleInstance.indicatorThickness |
132 | // *ELSE FALLTHROUGH* |
133 | default: |
134 | return 0 |
135 | @@ -209,7 +250,6 @@ |
136 | && __buddyScrollbar.align === Qt.AlignTrailing |
137 | && __buddyScrollbar.__styleInstance.isScrollable) |
138 | return __buddyScrollbar.__styleInstance.troughThicknessSteppersStyle |
139 | - //return buddyScrollbar.__styleInstance.indicatorThickness |
140 | // *ELSE FALLTHROUGH* |
141 | default: |
142 | return 0 |
143 | @@ -234,7 +274,6 @@ |
144 | && __buddyScrollbar.align === Qt.AlignTop |
145 | && __buddyScrollbar.__styleInstance.isScrollable) |
146 | return __buddyScrollbar.__styleInstance.troughThicknessSteppersStyle |
147 | - //return buddyScrollbar.__styleInstance.indicatorThickness |
148 | // *ELSE FALLTHROUGH* |
149 | |
150 | default: |
151 | @@ -260,7 +299,6 @@ |
152 | && __buddyScrollbar.align === Qt.AlignBottom |
153 | && __buddyScrollbar.__styleInstance.isScrollable) |
154 | return __buddyScrollbar.__styleInstance.troughThicknessSteppersStyle |
155 | - //return buddyScrollbar.__styleInstance.indicatorThickness |
156 | // *ELSE FALLTHROUGH* |
157 | default: |
158 | return 0 |
159 | |
160 | === modified file 'tests/unit_x11/tst_components/tst_scrollbar.qml' |
161 | --- tests/unit_x11/tst_components/tst_scrollbar.qml 2016-02-25 17:22:48 +0000 |
162 | +++ tests/unit_x11/tst_components/tst_scrollbar.qml 2016-03-24 10:43:42 +0000 |
163 | @@ -867,7 +867,32 @@ |
164 | flickableSanityCheck.rightMargin = -units.gu(3) |
165 | flickableSanityCheck.bottomMargin = -units.gu(4) |
166 | performStyleSanityCheck(scrollbarSanityCheck) |
167 | - |
168 | + } |
169 | + |
170 | + //Test that Scrollbar defaults to Flickable.topMargin/bottomMargin (content margins) |
171 | + //as its ANCHORS margins |
172 | + function test_topBottomMargins(data) { |
173 | + var freshTestItem = getFreshFlickable(data.alignment) |
174 | + var flickable = freshTestItem.flickable |
175 | + var scrollbar = freshTestItem.scrollbar |
176 | + |
177 | + compare(scrollbar.__styleInstance.isScrollable, true, "The view is not scrollable.") |
178 | + compare(scrollbar.__styleInstance.alwaysOnScrollbars, false, "This test assumes overlay scrollbars (if you need to change this, fix the expected margins).") |
179 | + compare(scrollbar.anchors.topMargin, flickable.topMargin, "Wrong anchors.topMargin.") |
180 | + compare(scrollbar.anchors.bottomMargin, flickable.bottomMargin, "Wrong anchors.bottomMargin.") |
181 | + |
182 | + flickable.topMargin = units.gu(1) |
183 | + compare(scrollbar.anchors.topMargin, units.gu(1), "Wrong anchors.topMargin.") |
184 | + compare(scrollbar.anchors.bottomMargin, flickable.bottomMargin, "Wrong anchors.bottomMargin.") |
185 | + |
186 | + flickable.bottomMargin = units.gu(3) |
187 | + compare(scrollbar.anchors.topMargin, units.gu(1), "Wrong anchors.topMargin.") |
188 | + compare(scrollbar.anchors.bottomMargin, units.gu(3), "Wrong anchors.bottomMargin.") |
189 | + |
190 | + flickable.topMargin = 0 |
191 | + flickable.bottomMargin = units.gu(6) |
192 | + compare(scrollbar.anchors.topMargin, 0, "Wrong anchors.topMargin.") |
193 | + compare(scrollbar.anchors.bottomMargin, units.gu(6), "Wrong anchors.bottomMargin.") |
194 | } |
195 | } |
196 | } |
197 | |
198 | === added file 'tests/unit_x11/tst_components/tst_scrollbar_header.qml' |
199 | --- tests/unit_x11/tst_components/tst_scrollbar_header.qml 1970-01-01 00:00:00 +0000 |
200 | +++ tests/unit_x11/tst_components/tst_scrollbar_header.qml 2016-03-24 10:43:42 +0000 |
201 | @@ -0,0 +1,311 @@ |
202 | +/* |
203 | + * Copyright 2016 Canonical Ltd. |
204 | + * |
205 | + * This program is free software; you can redistribute it and/or modify |
206 | + * it under the terms of the GNU Lesser General Public License as published by |
207 | + * the Free Software Foundation; version 3. |
208 | + * |
209 | + * This program is distributed in the hope that it will be useful, |
210 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
211 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
212 | + * GNU Lesser General Public License for more details. |
213 | + * |
214 | + * You should have received a copy of the GNU Lesser General Public License |
215 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
216 | + * |
217 | + * Author: Andrea Bernabei <andrea.bernabei@canonical.com> |
218 | + */ |
219 | + |
220 | +import QtQuick 2.4 |
221 | +import QtTest 1.0 |
222 | +import Ubuntu.Test 1.0 |
223 | +import Ubuntu.Components 1.3 |
224 | +import Ubuntu.Components.Styles 1.3 |
225 | +import QtQml.Models 2.1 |
226 | + |
227 | +Item { |
228 | + id: main |
229 | + width: units.gu(50) |
230 | + height: units.gu(100) |
231 | + |
232 | + Component { |
233 | + id: flickableComp |
234 | + Item { |
235 | + id: item |
236 | + width: units.gu(20) |
237 | + height: units.gu(30) |
238 | + property alias flickable: freshFlickable |
239 | + property alias scrollbar: freshScrollbar |
240 | + property alias content: content |
241 | + property alias scrollbarAlignment: freshScrollbar.align |
242 | + |
243 | + //Don't change this to a ListView, this usecase has to be simple, |
244 | + //we don't want the difficulties added by ListView, i.e. delegates |
245 | + //size estimation, dynamic contentWidth/Height, etc |
246 | + Flickable { |
247 | + id: freshFlickable |
248 | + anchors.fill: parent |
249 | + contentHeight: content.height |
250 | + contentWidth: content.width |
251 | + clip: true |
252 | + Rectangle { |
253 | + id: content |
254 | + width: units.gu(40) |
255 | + //make this much taller than the flickable to avoid timing issues when |
256 | + //detecting if the flickable is flicking in the tests |
257 | + height: units.gu(200) |
258 | + color: "blue" |
259 | + } |
260 | + } |
261 | + Scrollbar { |
262 | + id: freshScrollbar |
263 | + flickableItem: parent.flickable |
264 | + } |
265 | + } |
266 | + } |
267 | + |
268 | + SignalSpy { |
269 | + id: signalSpy |
270 | + } |
271 | + SignalSpy { |
272 | + id: anotherSignalSpy |
273 | + } |
274 | + |
275 | + Flickable { |
276 | + anchors.fill: parent |
277 | + Column { |
278 | + id: column |
279 | + Repeater { |
280 | + model: layoutsModel |
281 | + } |
282 | + } |
283 | + } |
284 | + |
285 | + VisualItemModel { |
286 | + id: layoutsModel |
287 | + Item { |
288 | + width: childrenRect.width |
289 | + height: childrenRect.height |
290 | + Flickable { |
291 | + id: randomFlickable |
292 | + } |
293 | + |
294 | + //complex PageHeader example taken from the PageHeader tutorial |
295 | + //https://developer.ubuntu.com/en/blog/2016/02/24/pageheader-tutorial/ |
296 | + MainView { |
297 | + id: mainView_movingHeaderTest |
298 | + width: units.gu(50) |
299 | + height: units.gu(80) |
300 | + clip: true |
301 | + |
302 | + property alias page: pageItem |
303 | + property alias standardHeader: standardHeaderItem |
304 | + property alias editHeader: editHeaderItem |
305 | + |
306 | + Page { |
307 | + id: pageItem |
308 | + header: standardHeaderItem |
309 | + |
310 | + onHeaderChanged: console.log("NEW HEADER") |
311 | + Flickable { |
312 | + id: flickable_movingHeaderTest |
313 | + anchors.fill: parent |
314 | + //just make sure the scrollbar is scrollable |
315 | + contentHeight: mainView_movingHeaderTest.height * 2 |
316 | + contentWidth: mainView_movingHeaderTest.width * 2 |
317 | + Label { |
318 | + text: "Use the icons in the header." |
319 | + visible: standardHeaderItem.visible |
320 | + } |
321 | + } |
322 | + Scrollbar { |
323 | + id: scrollbar_movingHeaderTest |
324 | + flickableItem: flickable_movingHeaderTest |
325 | + } |
326 | + |
327 | + PageHeader { |
328 | + id: standardHeaderItem |
329 | + visible: pageItem.header === standardHeaderItem |
330 | + title: "Default title" |
331 | + flickable: flickable_movingHeaderTest |
332 | + trailingActionBar.actions: [ |
333 | + Action { |
334 | + iconName: "edit" |
335 | + text: "Edit" |
336 | + onTriggered: pageItem.header = editHeaderItem |
337 | + } |
338 | + ] |
339 | + } |
340 | + PageHeader { |
341 | + id: editHeaderItem |
342 | + visible: pageItem.header === editHeaderItem |
343 | + flickable: flickable_movingHeaderTest |
344 | + property Component delegate: Component { |
345 | + AbstractButton { |
346 | + id: button |
347 | + action: modelData |
348 | + width: label.width + units.gu(4) |
349 | + height: parent.height |
350 | + Rectangle { |
351 | + color: UbuntuColors.slate |
352 | + opacity: 0.1 |
353 | + anchors.fill: parent |
354 | + visible: button.pressed |
355 | + } |
356 | + Label { |
357 | + anchors.centerIn: parent |
358 | + id: label |
359 | + text: action.text |
360 | + font.weight: text === "Confirm" |
361 | + ? Font.Normal |
362 | + : Font.Light |
363 | + } |
364 | + } |
365 | + } |
366 | + leadingActionBar { |
367 | + anchors.leftMargin: 0 |
368 | + actions: Action { |
369 | + text: "Cancel" |
370 | + iconName: "close" |
371 | + onTriggered: pageItem.header = standardHeaderItem |
372 | + } |
373 | + delegate: editHeaderItem.delegate |
374 | + } |
375 | + trailingActionBar { |
376 | + anchors.rightMargin: 0 |
377 | + actions: Action { |
378 | + text: "Confirm" |
379 | + iconName: "tick" |
380 | + onTriggered: pageItem.header = standardHeaderItem |
381 | + } |
382 | + delegate: editHeaderItem.delegate |
383 | + } |
384 | + extension: Toolbar { |
385 | + anchors { |
386 | + left: parent.left |
387 | + right: parent.right |
388 | + bottom: parent.bottom |
389 | + } |
390 | + trailingActionBar.actions: [ |
391 | + Action { iconName: "bookmark-new" }, |
392 | + Action { iconName: "add" }, |
393 | + Action { iconName: "edit-select-all" }, |
394 | + Action { iconName: "edit-copy" }, |
395 | + Action { iconName: "select" } |
396 | + ] |
397 | + leadingActionBar.actions: Action { |
398 | + iconName: "delete" |
399 | + text: "delete" |
400 | + onTriggered: print("Delete action triggered") |
401 | + } |
402 | + } |
403 | + } |
404 | + |
405 | + } |
406 | + } |
407 | + |
408 | + } |
409 | + } |
410 | + |
411 | + ScrollbarTestCase { |
412 | + name: "Scrollbar" |
413 | + |
414 | + function getMovingHeaderView() { |
415 | + var wrapper = movingHeaderHandlingItem.createObject(column) |
416 | + verify(wrapper !== null, "Error: dynamic item creation failed.") |
417 | + currComponent = wrapper |
418 | + return currComponent |
419 | + } |
420 | + |
421 | + function cleanup() { |
422 | + if (currComponent) { |
423 | + currComponent.destroy() |
424 | + currComponent = null |
425 | + } |
426 | + gc() |
427 | + } |
428 | + |
429 | + function checkScrollbarPositionRelativeToPage(scrollbar, page, expectedY, msgPrefix) { |
430 | + compare(scrollbar.mapToItem(page).y, expectedY, msgPrefix + ": Scrollbar does not start below the header.") |
431 | + } |
432 | + |
433 | + function test_handlingOfMovingHeader_data() { |
434 | + return [ |
435 | + { tag: "Standard header", header: standardHeaderItem }, |
436 | + { tag: "Edit header (with extensions)", header: editHeaderItem }, |
437 | + //Setting header to null means using the old header, and: |
438 | + //- We don't support this behaviour when using the old header |
439 | + //- There is no API to get the height of the old header, so we can't test it |
440 | + //{ tag: "Null header", header: null } |
441 | + ] |
442 | + } |
443 | + function test_handlingOfMovingHeader(data) { |
444 | + var page = pageItem |
445 | + var header = data.header |
446 | + |
447 | + page.header = header |
448 | + console.log(page.header, header.flickable) |
449 | + |
450 | + //make sure the currently tested header is the one driving the flickable changes |
451 | + //FIXME: this should not be needed after #1560458 is fixed |
452 | + header.flickable = null |
453 | + header.flickable = flickable_movingHeaderTest |
454 | + |
455 | + compare(page.header, header, "Handling of moving header: wrong header.") |
456 | + compare(scrollbar_movingHeaderTest.__styleInstance.isVertical, true, "Scrollbar is not vertical.") |
457 | + compare(scrollbar_movingHeaderTest.__styleInstance.isScrollable, true, "Scrollbar is not scrollable.") |
458 | + |
459 | + //don't do the rest of the checks on the null header, just check that it's aligning with the old header implementation |
460 | + //(page.head.contents.height) |
461 | + if (data.header === null) { |
462 | + checkScrollbarPositionRelativeToPage(scrollbar_movingHeaderTest, page, page.head.contents.height, data.tag) |
463 | + return |
464 | + } else { |
465 | + header.flickable = flickable_movingHeaderTest |
466 | + compare(header.flickable, flickable_movingHeaderTest, "Wrong PageHeader flickable.") |
467 | + checkScrollbarPositionRelativeToPage(scrollbar_movingHeaderTest, page, page.header.height, data.tag) |
468 | + } |
469 | + |
470 | + var tmpHeaderHeight = header.height |
471 | + page.header.height += units.gu(1) |
472 | + //make sure the header actually has a different height now |
473 | + verify(scrollbar_movingHeaderTest.height !== tmpHeaderHeight, "Header height changed value.") |
474 | + checkScrollbarPositionRelativeToPage(scrollbar_movingHeaderTest, page, page.header.height, |
475 | + data.tag + ", after changing height") |
476 | + |
477 | + //now link the header to a null flickable and check that scrollbar is covered |
478 | + //the header (yes, we're checking that it creates bad UX, because we're expecting the |
479 | + //developer to set the anchors accordingly so that we don't need to add inter-components |
480 | + //dependencies. The test Page does not handle this on purpose, so the header |
481 | + //should cover the scrollbar) |
482 | + header.flickable = null |
483 | + compare(header.flickable, null, "Wrong PageHeader flickable.") |
484 | + expectFailContinue("Standard header", "Waiting on Header bug #1560458") |
485 | + checkScrollbarPositionRelativeToPage(scrollbar_movingHeaderTest, page, 0, data.tag) |
486 | + |
487 | + //reassign the correct flickable and check again |
488 | + header.flickable = flickable_movingHeaderTest |
489 | + compare(header.flickable, flickable_movingHeaderTest, "Wrong PageHeader flickable.") |
490 | + checkScrollbarPositionRelativeToPage(scrollbar_movingHeaderTest, page, page.header.height, data.tag + ", scrollbar") |
491 | + |
492 | + header.visible = false |
493 | + compare(header.visible, false, "Header visibility did not change, should have been false.") |
494 | + expectFailContinue("", "Waiting on Header bug #1560458") |
495 | + checkScrollbarPositionRelativeToPage(scrollbar_movingHeaderTest, page, 0, data.tag + ", invisible header") |
496 | + |
497 | + header.visible = true |
498 | + compare(header.visible, true, "Header visibility did not change, should have been true.") |
499 | + checkScrollbarPositionRelativeToPage(scrollbar_movingHeaderTest, page, page.header.height, data.tag + ", visible header") |
500 | + |
501 | + //even if the header has opacity 0, we should still take it into account. This is a standard in |
502 | + //QtQuick, you don't ignore a component just because opacity is 0, as that is also used for animations |
503 | + header.opacity = 0.0 |
504 | + compare(header.opacity, 0.0, "Header opacity did not change, should have been 0.") |
505 | + checkScrollbarPositionRelativeToPage(scrollbar_movingHeaderTest, page, page.header.height, data.tag + ", 0.0 header opacity") |
506 | + |
507 | + header.opacity = 1.0 |
508 | + compare(header.opacity, 1.0, "Header opacity did not change, should have been 1.") |
509 | + checkScrollbarPositionRelativeToPage(scrollbar_movingHeaderTest, page, page.header.height, data.tag + ", 1.0 header opacity") |
510 | + } |
511 | + } |
512 | +} |
FAILED: Continuous integration, rev:1904 /jenkins. ubuntu. com/ubuntu- sdk/job/ ubuntu- ui-toolkit- ci-armhf- stable/ 568/ /jenkins. ubuntu. com/ubuntu- sdk/job/ generic- update- mp/2055/ console
https:/
Executed test runs:
None: https:/
Click here to trigger a rebuild: /jenkins. ubuntu. com/ubuntu- sdk/job/ ubuntu- ui-toolkit- ci-armhf- stable/ 568/rebuild
https:/