Merge lp:~aacid/unity8/properRangesHorizontalCategories into lp:unity8

Proposed by Albert Astals Cid on 2015-01-14
Status: Merged
Approved by: Andrea Cimitan on 2015-01-26
Approved revision: 1548
Merged at revision: 1588
Proposed branch: lp:~aacid/unity8/properRangesHorizontalCategories
Merge into: lp:unity8
Prerequisite: lp:~aacid/unity8/dash_ranges_on_move
Diff against target: 291 lines (+116/-55)
5 files modified
qml/Components/Carousel.qml (+6/-2)
qml/Dash/CardCarousel.qml (+6/-2)
qml/Dash/CardHorizontalList.qml (+7/-2)
qml/Dash/DashRenderer.qml (+6/-1)
qml/Dash/GenericScopeView.qml (+91/-48)
To merge this branch: bzr merge lp:~aacid/unity8/properRangesHorizontalCategories
Reviewer Review Type Date Requested Status
Andrea Cimitan (community) 2015-01-14 Approve on 2015-01-26
PS Jenkins bot continuous-integration Approve on 2015-01-14
Review via email: mp+246399@code.launchpad.net

Commit Message

Implement proper updateRanges for horizontal items (i.e. Carousel, Horizontal List)

Saves lots of unneeded card creation, e.g DashContent::test_noDelegateCreationDestructionOnMove number of buttons goes down from 1395 to 773 on my computer

Description of the Change

 * Are there any related MPs required for this MP to build/function as expected?
Prerequisite

 * Did you perform an exploratory manual test run of your code change and any related functionality?
Yes

 * Did you make sure that your branch does not contain spurious tags?
Yes

 * If you changed the packaging (debian), did you subscribe the ubuntu-unity team to this MP?
N/A

 * If you changed the UI, has there been a design review?
N/A

To post a comment you must log in.
Albert Astals Cid (aacid) wrote :

The diff in updateRanges is not great, basically what i did is add the

if (item.growsVertically) {
   // old code untouched here
} else {
   // new code
}

1548. By Albert Astals Cid on 2015-01-14

Didn't want to commit this

Albert Astals Cid (aacid) wrote :

The failed qmluitest should go away with r1548, let's see CI re-run the tests

Andrea Cimitan (cimi) wrote :

 * Did you perform an exploratory manual test run of the code change and any related functionality?
y
 * Did CI run pass? If not, please explain why.
y
 * Did you make sure that the branch does not contain spurious tags?
y

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'qml/Components/Carousel.qml'
2--- qml/Components/Carousel.qml 2014-10-23 11:59:22 +0000
3+++ qml/Components/Carousel.qml 2015-01-14 11:17:41 +0000
4@@ -1,5 +1,5 @@
5 /*
6- * Copyright (C) 2013 Canonical, Ltd.
7+ * Copyright (C) 2013-2015 Canonical, Ltd.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11@@ -14,7 +14,7 @@
12 * along with this program. If not, see <http://www.gnu.org/licenses/>.
13 */
14
15-import QtQuick 2.0
16+import QtQuick 2.3
17 import Ubuntu.Components 0.1
18 import "carousel.js" as CarouselJS
19
20@@ -38,6 +38,8 @@
21 property alias tileAspectRatio: listView.tileAspectRatio
22 /// Used to cache some delegates for performance reasons. See the ListView documentation for details
23 property alias cacheBuffer: listView.cacheBuffer
24+ property alias displayMarginBeginning: listView.displayMarginBeginning
25+ property alias displayMarginEnd: listView.displayMarginEnd
26 /// Width of the "draw buffer" in pixel. The drawBuffer is an additional area at start/end where
27 /// items drawn, even if it is not in the visible area.
28 /// cacheBuffer controls only the to retain delegates outside the visible area (and is used on top of the drawBuffer)
29@@ -51,6 +53,8 @@
30 readonly property alias currentItem: listView.currentItem
31 /// exposes the distance to the next row (only one row in carousel, so it's the topMargins)
32 readonly property alias verticalSpacing: listView.verticalMargin
33+ /// the width of the internal list
34+ readonly property alias innerWidth: listView.width
35
36 implicitHeight: listView.tileHeight * selectedItemScaleFactor
37 opacity: listView.highlightIndex === -1 ? 1 : 0.6
38
39=== modified file 'qml/Dash/CardCarousel.qml'
40--- qml/Dash/CardCarousel.qml 2014-11-03 09:41:51 +0000
41+++ qml/Dash/CardCarousel.qml 2015-01-14 11:17:41 +0000
42@@ -1,5 +1,5 @@
43 /*
44- * Copyright (C) 2013 Canonical, Ltd.
45+ * Copyright (C) 2013-2015 Canonical, Ltd.
46 *
47 * This program is free software; you can redistribute it and/or modify
48 * it under the terms of the GNU General Public License as published by
49@@ -23,6 +23,8 @@
50
51 expandedHeight: carousel.implicitHeight + units.gu(6)
52 collapsedHeight: expandedHeight
53+ growsVertically: false
54+ innerWidth: carousel.innerWidth
55
56 Carousel {
57 id: carousel
58@@ -32,7 +34,9 @@
59 // and push others back.
60 minimumTileWidth: cardTool.cardWidth / selectedItemScaleFactor
61 selectedItemScaleFactor: cardTool.carouselSelectedItemScaleFactor
62- cacheBuffer: 1404 // 18px * 13gu * 6
63+ cacheBuffer: cardCarousel.cacheBuffer
64+ displayMarginBeginning: cardCarousel.displayMarginBeginning
65+ displayMarginEnd: cardCarousel.displayMarginEnd
66 model: cardCarousel.model
67
68 property real fontScale: 1 / selectedItemScaleFactor
69
70=== modified file 'qml/Dash/CardHorizontalList.qml'
71--- qml/Dash/CardHorizontalList.qml 2014-11-05 08:37:55 +0000
72+++ qml/Dash/CardHorizontalList.qml 2015-01-14 11:17:41 +0000
73@@ -1,5 +1,5 @@
74 /*
75- * Copyright (C) 2014 Canonical, Ltd.
76+ * Copyright (C) 2014-2015 Canonical, Ltd.
77 *
78 * This program is free software; you can redistribute it and/or modify
79 * it under the terms of the GNU General Public License as published by
80@@ -14,7 +14,7 @@
81 * along with this program. If not, see <http://www.gnu.org/licenses/>.
82 */
83
84-import QtQuick 2.2
85+import QtQuick 2.3
86 import Ubuntu.Components 1.1
87 import "../Components"
88
89@@ -23,6 +23,8 @@
90
91 expandedHeight: cardTool.cardHeight + units.gu(2)
92 collapsedHeight: expandedHeight
93+ growsVertically: false
94+ innerWidth: Math.max(0, listView.width)
95 clip: true
96
97 ListView {
98@@ -36,6 +38,9 @@
99 spacing: units.gu(1)
100 model: root.model
101 orientation: ListView.Horizontal
102+ cacheBuffer: root.cacheBuffer
103+ displayMarginBeginning: root.displayMarginBeginning
104+ displayMarginEnd: root.displayMarginEnd
105
106 delegate: Loader {
107 id: loader
108
109=== modified file 'qml/Dash/DashRenderer.qml'
110--- qml/Dash/DashRenderer.qml 2014-11-07 16:16:12 +0000
111+++ qml/Dash/DashRenderer.qml 2015-01-14 11:17:41 +0000
112@@ -1,5 +1,5 @@
113 /*
114- * Copyright (C) 2013 Canonical, Ltd.
115+ * Copyright (C) 2013-2015 Canonical, Ltd.
116 *
117 * This program is free software; you can redistribute it and/or modify
118 * it under the terms of the GNU General Public License as published by
119@@ -31,6 +31,11 @@
120
121 property real originY: 0
122
123+ property bool growsVertically: true
124+
125+ // If growsVertically the width of the item inside the renderer
126+ property real innerWidth: 0
127+
128 // The model to renderer
129 property var model
130
131
132=== modified file 'qml/Dash/GenericScopeView.qml'
133--- qml/Dash/GenericScopeView.qml 2015-01-14 11:17:41 +0000
134+++ qml/Dash/GenericScopeView.qml 2015-01-14 11:17:41 +0000
135@@ -1,5 +1,5 @@
136 /*
137- * Copyright (C) 2013-2014 Canonical, Ltd.
138+ * Copyright (C) 2013-2015 Canonical, Ltd.
139 *
140 * This program is free software; you can redistribute it and/or modify
141 * it under the terms of the GNU General Public License as published by
142@@ -401,59 +401,102 @@
143 }
144
145 if (item && item.hasOwnProperty("displayMarginBeginning")) {
146- // A item view creates its delegates synchronously from
147- // -displayMarginBeginning
148- // to
149- // height + displayMarginEnd
150- // Around that area it adds the cacheBuffer area where delegates are created async
151- //
152- // We adjust displayMarginBeginning and displayMarginEnd so
153- // * In non visible scopes nothing is considered visible and we set cacheBuffer
154- // so that creates the items that would be in the viewport asynchronously
155- // * For the current scope set the visible range to the viewport and then
156- // use cacheBuffer to create extra items for categoryView.height * 1.5
157- // to make scrolling nicer by mantaining a higher number of
158- // cached items
159- // * For non current but visible scopes (i.e. when the user changes from one scope
160- // to the next, we set the visible range to the viewport so
161- // items are not culled (invisible) but still use no cacheBuffer
162- // (it will be set once the scope is the current one)
163- var displayMarginBeginning = baseItem.y;
164- displayMarginBeginning = -Math.max(-displayMarginBeginning, 0);
165- displayMarginBeginning = -Math.min(-displayMarginBeginning, baseItem.height);
166- displayMarginBeginning = Math.round(displayMarginBeginning);
167- var displayMarginEnd = -baseItem.height + seeAll.height + categoryView.height - baseItem.y;
168- displayMarginEnd = -Math.max(-displayMarginEnd, 0);
169- displayMarginEnd = -Math.min(-displayMarginEnd, baseItem.height);
170- displayMarginEnd = Math.round(displayMarginEnd);
171- if (scopeView.isCurrent || scopeView.visibleToParent) {
172- item.displayMarginBeginning = displayMarginBeginning;
173- item.displayMarginEnd = displayMarginEnd;
174- if (holdingList && holdingList.moving) {
175- // If we are moving we need to reset the cache buffer of the
176- // view that was not visible (i.e. !wasCurrentOnMoveStart) to 0 since
177- // otherwise the cache buffer we had set to preload the items of the
178- // visible range will trigger some item creations and we want move to
179- // be as smooth as possible meaning no need creations
180- if (!wasCurrentOnMoveStart) {
181+ if (item.growsVertically) {
182+ // A item view creates its delegates synchronously from
183+ // -displayMarginBeginning
184+ // to
185+ // height + displayMarginEnd
186+ // Around that area it adds the cacheBuffer area where delegates are created async
187+ //
188+ // We adjust displayMarginBeginning and displayMarginEnd so
189+ // * In non visible scopes nothing is considered visible and we set cacheBuffer
190+ // so that creates the items that would be in the viewport asynchronously
191+ // * For the current scope set the visible range to the viewport and then
192+ // use cacheBuffer to create extra items for categoryView.height * 1.5
193+ // to make scrolling nicer by mantaining a higher number of
194+ // cached items
195+ // * For non current but visible scopes (i.e. when the user changes from one scope
196+ // to the next, we set the visible range to the viewport so
197+ // items are not culled (invisible) but still use no cacheBuffer
198+ // (it will be set once the scope is the current one)
199+ var displayMarginBeginning = baseItem.y;
200+ displayMarginBeginning = -Math.max(-displayMarginBeginning, 0);
201+ displayMarginBeginning = -Math.min(-displayMarginBeginning, baseItem.height);
202+ displayMarginBeginning = Math.round(displayMarginBeginning);
203+ var displayMarginEnd = -baseItem.height + seeAll.height + categoryView.height - baseItem.y;
204+ displayMarginEnd = -Math.max(-displayMarginEnd, 0);
205+ displayMarginEnd = -Math.min(-displayMarginEnd, baseItem.height);
206+ displayMarginEnd = Math.round(displayMarginEnd);
207+
208+ if (scopeView.isCurrent || scopeView.visibleToParent) {
209+ item.displayMarginBeginning = displayMarginBeginning;
210+ item.displayMarginEnd = displayMarginEnd;
211+ if (holdingList && holdingList.moving) {
212+ // If we are moving we need to reset the cache buffer of the
213+ // view that was not visible (i.e. !wasCurrentOnMoveStart) to 0 since
214+ // otherwise the cache buffer we had set to preload the items of the
215+ // visible range will trigger some item creations and we want move to
216+ // be as smooth as possible meaning no need creations
217+ if (!wasCurrentOnMoveStart) {
218+ item.cacheBuffer = 0;
219+ }
220+ } else {
221+ item.cacheBuffer = categoryView.height * 1.5;
222+ }
223+ } else {
224+ var visibleRange = baseItem.height + displayMarginEnd + displayMarginBeginning;
225+ if (visibleRange < 0) {
226+ item.displayMarginBeginning = displayMarginBeginning;
227+ item.displayMarginEnd = displayMarginEnd;
228 item.cacheBuffer = 0;
229+ } else {
230+ // This should be visibleRange/2 in each of the properties
231+ // but some item views still (like GridView) like creating sync delegates even if
232+ // the visible range is 0 so let's make sure the visible range is negative
233+ item.displayMarginBeginning = displayMarginBeginning - visibleRange;
234+ item.displayMarginEnd = displayMarginEnd - visibleRange;
235+ item.cacheBuffer = visibleRange;
236 }
237- } else {
238- item.cacheBuffer = categoryView.height * 1.5;
239 }
240 } else {
241- var visibleRange = baseItem.height + displayMarginEnd + displayMarginBeginning;
242- if (visibleRange < 0) {
243- item.displayMarginBeginning = displayMarginBeginning;
244- item.displayMarginEnd = displayMarginEnd;
245+ var buffer = wasCurrentOnMoveStart ? categoryView.height * 1.5 : 0;
246+ var onViewport = baseItem.y + baseItem.height > 0 &&
247+ baseItem.y < categoryView.height;
248+ var onBufferViewport = baseItem.y + baseItem.height > -buffer &&
249+ baseItem.y < categoryView.height + buffer;
250+ if (!onBufferViewport) {
251+ // If not on the buffered viewport, don't load anything
252+ item.displayMarginBeginning = 0;
253+ item.displayMarginEnd = -item.innerWidth;
254 item.cacheBuffer = 0;
255 } else {
256- // This should be visibleRange/2 in each of the properties
257- // but some item views still (like GridView) like creating sync delegates even if
258- // the visible range is 0 so let's make sure the visible range is negative
259- item.displayMarginBeginning = displayMarginBeginning - visibleRange;
260- item.displayMarginEnd = displayMarginEnd - visibleRange;
261- item.cacheBuffer = visibleRange;
262+ if (onViewport && (scopeView.isCurrent || scopeView.visibleToParent)) {
263+ // If on the buffered viewport and the viewport and the on a visible scope
264+ // Set displayMargin so that cards are rendered
265+ // And if not moving the parent list also give it some extra asynchronously
266+ // buffering
267+ item.displayMarginBeginning = 0;
268+ item.displayMarginEnd = 0;
269+ if (holdingList && holdingList.moving) {
270+ // If we are moving we need to reset the cache buffer of the
271+ // view that was not visible (i.e. !wasCurrentOnMoveStart) to 0 since
272+ // otherwise the cache buffer we had set to preload the items of the
273+ // visible range will trigger some item creations and we want move to
274+ // be as smooth as possible meaning no need creations
275+ if (!wasCurrentOnMoveStart) {
276+ item.cacheBuffer = 0;
277+ }
278+ } else {
279+ item.cacheBuffer = baseItem.width * 1.5;
280+ }
281+ } else {
282+ // If on the buffered viewport but either not in the real viewport
283+ // or in the viewport of the non current scope, use displayMargin + cacheBuffer
284+ // to render asynchronously the width of cards
285+ item.displayMarginBeginning = 0;
286+ item.displayMarginEnd = -item.innerWidth;
287+ item.cacheBuffer = item.innerWidth;
288+ }
289 }
290 }
291 }

Subscribers

People subscribed via source and target branches