Merge lp:~ahayzen/music-app/remix-add-card-view into lp:music-app/remix
- remix-add-card-view
- Merge into remix
Status: | Merged |
---|---|
Approved by: | Victor Thompson |
Approved revision: | 653 |
Merged at revision: | 653 |
Proposed branch: | lp:~ahayzen/music-app/remix-add-card-view |
Merge into: | lp:music-app/remix |
Prerequisite: | lp:~ahayzen/music-app/remix-remove-blurred-background |
Diff against target: |
541 lines (+378/-123) 4 files modified
MusicAlbums.qml (+21/-123) common/Card.qml (+157/-0) common/CardView.qml (+41/-0) common/ColumnFlow.qml (+159/-0) |
To merge this branch: | bzr merge lp:~ahayzen/music-app/remix-add-card-view |
Related bugs: | |
Related blueprints: |
Music Remix for RTM
(Essential)
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Victor Thompson | Approve | ||
Ubuntu Phone Apps Jenkins Bot | continuous-integration | Approve | |
Andrew Hayzen | Abstain | ||
Review via email: mp+236257@code.launchpad.net |
Commit message
* Add CardView and Card
* Implement in Albums tab
Description of the change
* Add CardView and Card
* Implement in Albums tab
A few rough edges and hard coded things but wanted an initial review.
- 642. By Andrew Hayzen
-
* Cleanup old code
Andrew Hayzen (ahayzen) wrote : | # |
- 643. By Andrew Hayzen
-
* Remove unused imports
- 644. By Andrew Hayzen
-
* Further tidying
- 645. By Andrew Hayzen
-
* Tweak overlay opacity
Victor Thompson (vthompson) wrote : | # |
Per the design spec, please 1) add more spacing before the album name and after the artist name, 2) verify that design agrees with the font sizes (look a little big), and 3) we need to verify if the card view is to be used for an Albums view.
- 646. By Andrew Hayzen
-
* Change spacing for labels
* Change font sizes - 647. By Andrew Hayzen
-
* Merge of /remix
Andrew Hayzen (ahayzen) wrote : | # |
OK so I have fixed the label issues, verified the font size with design and also discussed the pages that will use CardView.
<ahayzen> jounih, for the Albums tab are we expecting to use the cardview?
<jounih> ahayzen: I think we could use the cardview for everything for now. Maybe some of the views would work better as a listview but we can start off with cards for everything
<jounih> what do you think?
<ahayzen> jounih, my understanding was the 'start' page would be cardview... the albums would be cards.... the artists and songs tabs make sense to be a list i think...and the playlists is up for debate
<jounih> ahayzen: playlists definitely cards - albums and playlists are very similar. OK to use listview for artists and songs - i’ll need to provide a design for that, i’ll do it now
<ahayzen> jounih, yep agreed thanks :)
After discussions with nik he recommended to use the Flow {} component to do the staggered grid, so I am going to investigate that and therefore blocking myself for this mp until a decision is made there.
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote : | # |
PASSED: Continuous integration, rev:647
http://
Executed test runs:
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
- 648. By Andrew Hayzen
-
* Move to using Flow {}
- 649. By Andrew Hayzen
-
* Move to ColumnFlow {}
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote : | # |
PASSED: Continuous integration, rev:649
http://
Executed test runs:
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Andrew Hayzen (ahayzen) wrote : | # |
Unblocking myself as we have now moved to ColumnFlow {}, please rereview.
- 650. By Andrew Hayzen
-
* Merge of trunk
- 651. By Andrew Hayzen
-
* Add upstream location
- 652. By Andrew Hayzen
-
* Merge of trunk
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote : | # |
PASSED: Continuous integration, rev:650
http://
Executed test runs:
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote : | # |
PASSED: Continuous integration, rev:652
http://
Executed test runs:
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Victor Thompson (vthompson) wrote : | # |
See 1 inline comment. Also, I had tried to implement search with this feature and It seems that sometimes the first column would not start at the very top when it reEval's the layout (http://
- 653. By Andrew Hayzen
-
* Fix so that when items are removed from the model there are no gaps
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote : | # |
PASSED: Continuous integration, rev:653
http://
Executed test runs:
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Victor Thompson (vthompson) wrote : | # |
LGTM! This is a very welcomed improvement!
Preview Diff
1 | === modified file 'MusicAlbums.qml' | |||
2 | --- MusicAlbums.qml 2014-09-20 15:41:33 +0000 | |||
3 | +++ MusicAlbums.qml 2014-10-06 19:09:48 +0000 | |||
4 | @@ -19,37 +19,17 @@ | |||
5 | 19 | 19 | ||
6 | 20 | import QtQuick 2.3 | 20 | import QtQuick 2.3 |
7 | 21 | import Ubuntu.Components 1.1 | 21 | import Ubuntu.Components 1.1 |
8 | 22 | import Ubuntu.Components.Popups 1.0 | ||
9 | 23 | import Ubuntu.MediaScanner 0.1 | 22 | import Ubuntu.MediaScanner 0.1 |
10 | 24 | import Ubuntu.Thumbnailer 0.1 | ||
11 | 25 | import QtMultimedia 5.0 | ||
12 | 26 | import QtQuick.LocalStorage 2.0 | ||
13 | 27 | import QtGraphicalEffects 1.0 | ||
14 | 28 | import "settings.js" as Settings | ||
15 | 29 | import "playlists.js" as Playlists | ||
16 | 30 | import "common" | 23 | import "common" |
17 | 31 | 24 | ||
18 | 25 | |||
19 | 32 | MusicPage { | 26 | MusicPage { |
21 | 33 | id: mainpage | 27 | id: albumsPage |
22 | 34 | objectName: "albumsPage" | 28 | objectName: "albumsPage" |
23 | 35 | title: i18n.tr("Albums") | 29 | title: i18n.tr("Albums") |
24 | 36 | 30 | ||
41 | 37 | // TODO: This ListView is empty and causes the header to get painted with the desired background color because the | 31 | CardView { |
42 | 38 | // page is now vertically flickable. | 32 | id: albumCardView |
27 | 39 | ListView { | ||
28 | 40 | anchors.fill: parent | ||
29 | 41 | anchors.bottomMargin: musicToolbar.mouseAreaOffset + musicToolbar.minimizedHeight | ||
30 | 42 | } | ||
31 | 43 | |||
32 | 44 | GridView { | ||
33 | 45 | id: albumlist | ||
34 | 46 | anchors.fill: parent | ||
35 | 47 | anchors.leftMargin: units.gu(1) | ||
36 | 48 | anchors.top: parent.top | ||
37 | 49 | anchors.topMargin: mainView.header.height + units.gu(1) | ||
38 | 50 | anchors.bottomMargin: units.gu(1) | ||
39 | 51 | cellHeight: height/3 | ||
40 | 52 | cellWidth: height/3 | ||
43 | 53 | model: SortFilterModel { | 33 | model: SortFilterModel { |
44 | 54 | id: albumsModelFilter | 34 | id: albumsModelFilter |
45 | 55 | property alias rowCount: albumsModel.rowCount | 35 | property alias rowCount: albumsModel.rowCount |
46 | @@ -60,106 +40,24 @@ | |||
47 | 60 | sort.property: "title" | 40 | sort.property: "title" |
48 | 61 | sort.order: Qt.AscendingOrder | 41 | sort.order: Qt.AscendingOrder |
49 | 62 | } | 42 | } |
147 | 63 | 43 | delegate: Card { | |
148 | 64 | delegate: albumDelegate | 44 | id: albumCard |
149 | 65 | flow: GridView.TopToBottom | 45 | imageSource: model.art |
150 | 66 | 46 | objectName: "albumsPageGridItem" + index | |
151 | 67 | Component { | 47 | primaryText: model.title |
152 | 68 | id: albumDelegate | 48 | secondaryText: model.artist |
153 | 69 | Item { | 49 | |
154 | 70 | property string artist: model.artist | 50 | onClicked: { |
155 | 71 | property string album: model.title | 51 | songsPage.album = model.title; |
156 | 72 | property var covers: [{art: model.art}] | 52 | songsPage.covers = [{art: model.art}] |
157 | 73 | 53 | songsPage.genre = undefined | |
158 | 74 | id: albumItem | 54 | songsPage.isAlbum = true |
159 | 75 | height: albumlist.cellHeight - units.gu(1) | 55 | songsPage.line1 = model.artist |
160 | 76 | objectName: "albumsPageGridItem" + index | 56 | songsPage.line2 = model.title |
161 | 77 | width: albumlist.cellHeight - units.gu(1) | 57 | songsPage.title = i18n.tr("Album") |
162 | 78 | anchors.margins: units.gu(1) | 58 | |
163 | 79 | 59 | mainPageStack.push(songsPage) | |
67 | 80 | CoverRow { | ||
68 | 81 | id: albumShape | ||
69 | 82 | anchors { | ||
70 | 83 | top: parent.top | ||
71 | 84 | left: parent.left | ||
72 | 85 | verticalCenter: parent.verticalCenter | ||
73 | 86 | } | ||
74 | 87 | count: albumItem.covers.length | ||
75 | 88 | size: albumItem.width | ||
76 | 89 | covers: albumItem.covers | ||
77 | 90 | spacing: units.gu(2) | ||
78 | 91 | } | ||
79 | 92 | Item { // Background so can see text in current state | ||
80 | 93 | id: albumBg | ||
81 | 94 | anchors { | ||
82 | 95 | bottom: parent.bottom | ||
83 | 96 | left: parent.left | ||
84 | 97 | right: parent.right | ||
85 | 98 | } | ||
86 | 99 | height: units.gu(6) | ||
87 | 100 | clip: true | ||
88 | 101 | UbuntuShape{ | ||
89 | 102 | anchors { | ||
90 | 103 | bottom: parent.bottom | ||
91 | 104 | left: parent.left | ||
92 | 105 | right: parent.right | ||
93 | 106 | } | ||
94 | 107 | height: albumShape.height | ||
95 | 108 | radius: "medium" | ||
96 | 109 | color: styleMusic.common.black | ||
97 | 110 | opacity: 0.6 | ||
98 | 111 | } | ||
99 | 112 | } | ||
100 | 113 | Label { | ||
101 | 114 | id: albumArtist | ||
102 | 115 | objectName: "albums-albumartist" | ||
103 | 116 | anchors.bottom: parent.bottom | ||
104 | 117 | anchors.bottomMargin: units.gu(1) | ||
105 | 118 | anchors.left: parent.left | ||
106 | 119 | anchors.leftMargin: units.gu(1) | ||
107 | 120 | anchors.right: parent.right | ||
108 | 121 | anchors.rightMargin: units.gu(1) | ||
109 | 122 | color: styleMusic.common.white | ||
110 | 123 | elide: Text.ElideRight | ||
111 | 124 | text: model.artist | ||
112 | 125 | fontSize: "x-small" | ||
113 | 126 | } | ||
114 | 127 | Label { | ||
115 | 128 | id: albumLabel | ||
116 | 129 | anchors.bottom: parent.bottom | ||
117 | 130 | anchors.bottomMargin: units.gu(3) | ||
118 | 131 | anchors.left: parent.left | ||
119 | 132 | anchors.leftMargin: units.gu(1) | ||
120 | 133 | anchors.right: parent.right | ||
121 | 134 | anchors.rightMargin: units.gu(1) | ||
122 | 135 | color: styleMusic.common.white | ||
123 | 136 | elide: Text.ElideRight | ||
124 | 137 | text: model.title | ||
125 | 138 | fontSize: "small" | ||
126 | 139 | font.weight: Font.DemiBold | ||
127 | 140 | } | ||
128 | 141 | |||
129 | 142 | |||
130 | 143 | MouseArea { | ||
131 | 144 | anchors.fill: parent | ||
132 | 145 | onClicked: { | ||
133 | 146 | songsPage.album = model.title; | ||
134 | 147 | songsPage.covers = [{art: model.art}] | ||
135 | 148 | songsPage.genre = undefined | ||
136 | 149 | songsPage.isAlbum = true | ||
137 | 150 | songsPage.line1 = model.artist | ||
138 | 151 | songsPage.line2 = model.title | ||
139 | 152 | songsPage.title = i18n.tr("Album") | ||
140 | 153 | |||
141 | 154 | mainPageStack.push(songsPage) | ||
142 | 155 | } | ||
143 | 156 | |||
144 | 157 | // TODO: If http://pad.lv/1354753 is fixed to expose whether the Shape should appear pressed, update this as well. | ||
145 | 158 | onPressedChanged: albumShape.pressed = pressed | ||
146 | 159 | } | ||
164 | 160 | } | 60 | } |
165 | 161 | } | 61 | } |
166 | 162 | } | 62 | } |
167 | 163 | } | 63 | } |
168 | 164 | |||
169 | 165 | |||
170 | 166 | 64 | ||
171 | === added file 'common/Card.qml' | |||
172 | --- common/Card.qml 1970-01-01 00:00:00 +0000 | |||
173 | +++ common/Card.qml 2014-10-06 19:09:48 +0000 | |||
174 | @@ -0,0 +1,157 @@ | |||
175 | 1 | /* | ||
176 | 2 | * Copyright (C) 2014 | ||
177 | 3 | * Andrew Hayzen <ahayzen@gmail.com> | ||
178 | 4 | * | ||
179 | 5 | * This program is free software; you can redistribute it and/or modify | ||
180 | 6 | * it under the terms of the GNU General Public License as published by | ||
181 | 7 | * the Free Software Foundation; version 3. | ||
182 | 8 | * | ||
183 | 9 | * This program is distributed in the hope that it will be useful, | ||
184 | 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
185 | 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
186 | 12 | * GNU General Public License for more details. | ||
187 | 13 | * | ||
188 | 14 | * You should have received a copy of the GNU General Public License | ||
189 | 15 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
190 | 16 | */ | ||
191 | 17 | |||
192 | 18 | import QtQuick 2.3 | ||
193 | 19 | import Ubuntu.Components 1.1 | ||
194 | 20 | |||
195 | 21 | |||
196 | 22 | Rectangle { | ||
197 | 23 | id: card | ||
198 | 24 | color: "transparent" | ||
199 | 25 | height: cardColumn.childrenRect.height + 2 * bg.anchors.margins | ||
200 | 26 | |||
201 | 27 | property alias imageSource: image.source | ||
202 | 28 | property alias primaryText: primaryLabel.text | ||
203 | 29 | property alias secondaryText: secondaryLabel.text | ||
204 | 30 | |||
205 | 31 | signal clicked(var mouse) | ||
206 | 32 | signal pressAndHold(var mouse) | ||
207 | 33 | |||
208 | 34 | /* Animations */ | ||
209 | 35 | Behavior on height { | ||
210 | 36 | UbuntuNumberAnimation { | ||
211 | 37 | |||
212 | 38 | } | ||
213 | 39 | } | ||
214 | 40 | |||
215 | 41 | Behavior on width { | ||
216 | 42 | UbuntuNumberAnimation { | ||
217 | 43 | |||
218 | 44 | } | ||
219 | 45 | } | ||
220 | 46 | |||
221 | 47 | Behavior on x { | ||
222 | 48 | UbuntuNumberAnimation { | ||
223 | 49 | |||
224 | 50 | } | ||
225 | 51 | } | ||
226 | 52 | |||
227 | 53 | Behavior on y { | ||
228 | 54 | UbuntuNumberAnimation { | ||
229 | 55 | |||
230 | 56 | } | ||
231 | 57 | } | ||
232 | 58 | |||
233 | 59 | /* Background for card */ | ||
234 | 60 | Rectangle { | ||
235 | 61 | id: bg | ||
236 | 62 | anchors { | ||
237 | 63 | fill: parent | ||
238 | 64 | margins: units.gu(1) | ||
239 | 65 | } | ||
240 | 66 | color: "#2c2c34" | ||
241 | 67 | } | ||
242 | 68 | |||
243 | 69 | /* Column containing image and labels */ | ||
244 | 70 | Column { | ||
245 | 71 | id: cardColumn | ||
246 | 72 | anchors { | ||
247 | 73 | fill: bg | ||
248 | 74 | } | ||
249 | 75 | spacing: units.gu(0.5) | ||
250 | 76 | |||
251 | 77 | Image { | ||
252 | 78 | id: image | ||
253 | 79 | height: parent.width | ||
254 | 80 | width: parent.width | ||
255 | 81 | |||
256 | 82 | onStatusChanged: { | ||
257 | 83 | if (status === Image.Error) { | ||
258 | 84 | source = Qt.resolvedUrl("../images/music-app-cover@30.png") | ||
259 | 85 | } | ||
260 | 86 | } | ||
261 | 87 | } | ||
262 | 88 | |||
263 | 89 | Rectangle { | ||
264 | 90 | color: "transparent" | ||
265 | 91 | height: units.gu(1) | ||
266 | 92 | width: units.gu(1) | ||
267 | 93 | } | ||
268 | 94 | |||
269 | 95 | Label { | ||
270 | 96 | id: primaryLabel | ||
271 | 97 | anchors { | ||
272 | 98 | left: parent.left | ||
273 | 99 | leftMargin: units.gu(1) | ||
274 | 100 | right: parent.right | ||
275 | 101 | rightMargin: units.gu(1) | ||
276 | 102 | } | ||
277 | 103 | color: "#FFF" | ||
278 | 104 | elide: Text.ElideRight | ||
279 | 105 | fontSize: "small" | ||
280 | 106 | opacity: 1.0 | ||
281 | 107 | wrapMode: Text.WordWrap | ||
282 | 108 | } | ||
283 | 109 | |||
284 | 110 | Label { | ||
285 | 111 | id: secondaryLabel | ||
286 | 112 | anchors { | ||
287 | 113 | left: parent.left | ||
288 | 114 | leftMargin: units.gu(1) | ||
289 | 115 | right: parent.right | ||
290 | 116 | rightMargin: units.gu(1) | ||
291 | 117 | } | ||
292 | 118 | color: "#FFF" | ||
293 | 119 | elide: Text.ElideRight | ||
294 | 120 | fontSize: "small" | ||
295 | 121 | opacity: 0.4 | ||
296 | 122 | wrapMode: Text.WordWrap | ||
297 | 123 | } | ||
298 | 124 | |||
299 | 125 | Rectangle { | ||
300 | 126 | color: "transparent" | ||
301 | 127 | height: units.gu(1.5) | ||
302 | 128 | width: units.gu(1) | ||
303 | 129 | } | ||
304 | 130 | } | ||
305 | 131 | |||
306 | 132 | /* Overlay for when card is pressed */ | ||
307 | 133 | Rectangle { | ||
308 | 134 | id: overlay | ||
309 | 135 | anchors { | ||
310 | 136 | fill: bg | ||
311 | 137 | } | ||
312 | 138 | color: "#000" | ||
313 | 139 | opacity: 0 | ||
314 | 140 | |||
315 | 141 | Behavior on opacity { | ||
316 | 142 | UbuntuNumberAnimation { | ||
317 | 143 | |||
318 | 144 | } | ||
319 | 145 | } | ||
320 | 146 | } | ||
321 | 147 | |||
322 | 148 | /* Capture mouse events */ | ||
323 | 149 | MouseArea { | ||
324 | 150 | anchors { | ||
325 | 151 | fill: parent | ||
326 | 152 | } | ||
327 | 153 | onClicked: card.clicked(mouse) | ||
328 | 154 | onPressAndHold: card.pressAndHold(mouse) | ||
329 | 155 | onPressedChanged: overlay.opacity = pressed ? 0.3 : 0 | ||
330 | 156 | } | ||
331 | 157 | } | ||
332 | 0 | 158 | ||
333 | === added file 'common/CardView.qml' | |||
334 | --- common/CardView.qml 1970-01-01 00:00:00 +0000 | |||
335 | +++ common/CardView.qml 2014-10-06 19:09:48 +0000 | |||
336 | @@ -0,0 +1,41 @@ | |||
337 | 1 | /* | ||
338 | 2 | * Copyright (C) 2014 | ||
339 | 3 | * Andrew Hayzen <ahayzen@gmail.com> | ||
340 | 4 | * | ||
341 | 5 | * This program is free software; you can redistribute it and/or modify | ||
342 | 6 | * it under the terms of the GNU General Public License as published by | ||
343 | 7 | * the Free Software Foundation; version 3. | ||
344 | 8 | * | ||
345 | 9 | * This program is distributed in the hope that it will be useful, | ||
346 | 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
347 | 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
348 | 12 | * GNU General Public License for more details. | ||
349 | 13 | * | ||
350 | 14 | * You should have received a copy of the GNU General Public License | ||
351 | 15 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
352 | 16 | */ | ||
353 | 17 | |||
354 | 18 | import QtQuick 2.3 | ||
355 | 19 | import Ubuntu.Components 1.1 | ||
356 | 20 | |||
357 | 21 | |||
358 | 22 | Flickable { | ||
359 | 23 | anchors { | ||
360 | 24 | fill: parent | ||
361 | 25 | margins: units.gu(1) | ||
362 | 26 | } | ||
363 | 27 | |||
364 | 28 | // dont use flow.contentHeight as it is inaccurate due to height of labels | ||
365 | 29 | // changing as they load | ||
366 | 30 | contentHeight: flow.childrenRect.height | ||
367 | 31 | contentWidth: width | ||
368 | 32 | |||
369 | 33 | property alias delegate: flow.delegate | ||
370 | 34 | property alias model: flow.model | ||
371 | 35 | |||
372 | 36 | ColumnFlow { | ||
373 | 37 | id: flow | ||
374 | 38 | columns: parseInt(width / units.gu(15)) | ||
375 | 39 | width: parent.width | ||
376 | 40 | } | ||
377 | 41 | } | ||
378 | 0 | 42 | ||
379 | === added file 'common/ColumnFlow.qml' | |||
380 | --- common/ColumnFlow.qml 1970-01-01 00:00:00 +0000 | |||
381 | +++ common/ColumnFlow.qml 2014-10-06 19:09:48 +0000 | |||
382 | @@ -0,0 +1,159 @@ | |||
383 | 1 | /* | ||
384 | 2 | * Copyright (C) 2014 | ||
385 | 3 | * Andrew Hayzen <ahayzen@gmail.com> | ||
386 | 4 | * Michael Spencer <sonrisesoftware@gmail.com> | ||
387 | 5 | * | ||
388 | 6 | * This program is free software; you can redistribute it and/or modify | ||
389 | 7 | * it under the terms of the GNU General Public License as published by | ||
390 | 8 | * the Free Software Foundation; version 3. | ||
391 | 9 | * | ||
392 | 10 | * This program is distributed in the hope that it will be useful, | ||
393 | 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
394 | 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
395 | 13 | * GNU General Public License for more details. | ||
396 | 14 | * | ||
397 | 15 | * You should have received a copy of the GNU General Public License | ||
398 | 16 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
399 | 17 | * | ||
400 | 18 | * Upstream location: | ||
401 | 19 | * https://github.com/iBeliever/ubuntu-ui-extras/blob/master/ColumnFlow.qml | ||
402 | 20 | */ | ||
403 | 21 | |||
404 | 22 | import QtQuick 2.3 | ||
405 | 23 | |||
406 | 24 | |||
407 | 25 | Item { | ||
408 | 26 | id: columnFlow | ||
409 | 27 | property int columns: 1 | ||
410 | 28 | property bool repeaterCompleted: false | ||
411 | 29 | property alias model: repeater.model | ||
412 | 30 | property alias delegate: repeater.delegate | ||
413 | 31 | property int contentHeight: 0 | ||
414 | 32 | |||
415 | 33 | onColumnsChanged: reEvalColumns() | ||
416 | 34 | onModelChanged: reEvalColumns() | ||
417 | 35 | onWidthChanged: updateWidths() | ||
418 | 36 | |||
419 | 37 | function updateWidths() { | ||
420 | 38 | if (repeaterCompleted) { | ||
421 | 39 | var count = 0 | ||
422 | 40 | |||
423 | 41 | //add the first <column> elements | ||
424 | 42 | for (var i = 0; count < columns && i < columnFlow.children.length; i++) { | ||
425 | 43 | //print(i, count) | ||
426 | 44 | if (!columnFlow.children[i] || String(columnFlow.children[i]).indexOf("QQuickRepeater") == 0) | ||
427 | 45 | //|| !columnFlow.children[i].visible) // CUSTOM - view is invisible at start | ||
428 | 46 | continue | ||
429 | 47 | |||
430 | 48 | columnFlow.children[i].width = width / columns | ||
431 | 49 | |||
432 | 50 | count++ | ||
433 | 51 | } | ||
434 | 52 | } | ||
435 | 53 | } | ||
436 | 54 | |||
437 | 55 | function reEvalColumns() { | ||
438 | 56 | if (columnFlow.repeaterCompleted === false) | ||
439 | 57 | return | ||
440 | 58 | |||
441 | 59 | if (columns === 0) { | ||
442 | 60 | contentHeight = 0 | ||
443 | 61 | return | ||
444 | 62 | } | ||
445 | 63 | |||
446 | 64 | var i, j | ||
447 | 65 | var columnHeights = new Array(columns); | ||
448 | 66 | var lastItem = new Array(columns) | ||
449 | 67 | var lastI = -1 | ||
450 | 68 | var count = 0 | ||
451 | 69 | |||
452 | 70 | //add the first <column> elements | ||
453 | 71 | for (i = 0; count < columns && i < columnFlow.children.length; i++) { | ||
454 | 72 | // CUSTOM - ignore if has just been removed | ||
455 | 73 | if (i === repeater.removeHintIndex && columnFlow.children[i] === repeater.removeHintItem) { | ||
456 | 74 | continue | ||
457 | 75 | } | ||
458 | 76 | |||
459 | 77 | if (!columnFlow.children[i] || String(columnFlow.children[i]).indexOf("QQuickRepeater") == 0) | ||
460 | 78 | //|| !columnFlow.children[i].visible) // CUSTOM - view is invisible at start | ||
461 | 79 | continue | ||
462 | 80 | |||
463 | 81 | lastItem[count] = i | ||
464 | 82 | |||
465 | 83 | columnHeights[count] = columnFlow.children[i].height | ||
466 | 84 | columnFlow.children[i].anchors.top = columnFlow.top | ||
467 | 85 | columnFlow.children[i].anchors.left = (lastI === -1 ? columnFlow.left : columnFlow.children[lastI].right) | ||
468 | 86 | columnFlow.children[i].anchors.right = undefined | ||
469 | 87 | columnFlow.children[i].width = columnFlow.width / columns | ||
470 | 88 | |||
471 | 89 | lastI = i | ||
472 | 90 | count++ | ||
473 | 91 | } | ||
474 | 92 | |||
475 | 93 | //add the other elements | ||
476 | 94 | for (i = i; i < columnFlow.children.length; i++) { | ||
477 | 95 | var highestHeight = Number.MAX_VALUE | ||
478 | 96 | var newColumn = 0 | ||
479 | 97 | |||
480 | 98 | // CUSTOM - ignore if has just been removed | ||
481 | 99 | if (i === repeater.removeHintIndex && columnFlow.children[i] === repeater.removeHintItem) { | ||
482 | 100 | continue | ||
483 | 101 | } | ||
484 | 102 | |||
485 | 103 | if (!columnFlow.children[i] || String(columnFlow.children[i]).indexOf("QQuickRepeater") == 0) | ||
486 | 104 | //|| !columnFlow.children[i].visible) // CUSTOM - view is invisible at start | ||
487 | 105 | continue | ||
488 | 106 | |||
489 | 107 | // find the shortest column | ||
490 | 108 | for (j = 0; j < columns; j++) { | ||
491 | 109 | if (columnHeights[j] !== null && columnHeights[j] < highestHeight) { | ||
492 | 110 | newColumn = j | ||
493 | 111 | highestHeight = columnHeights[j] | ||
494 | 112 | } | ||
495 | 113 | } | ||
496 | 114 | |||
497 | 115 | // add the element to the shortest column | ||
498 | 116 | columnFlow.children[i].anchors.top = columnFlow.children[lastItem[newColumn]].bottom | ||
499 | 117 | columnFlow.children[i].anchors.left = columnFlow.children[lastItem[newColumn]].left | ||
500 | 118 | columnFlow.children[i].anchors.right = columnFlow.children[lastItem[newColumn]].right | ||
501 | 119 | |||
502 | 120 | lastItem[newColumn] = i | ||
503 | 121 | columnHeights[newColumn] += columnFlow.children[i].height | ||
504 | 122 | } | ||
505 | 123 | |||
506 | 124 | var cHeight = 0 | ||
507 | 125 | |||
508 | 126 | for (i = 0; i < columnHeights.length; i++) { | ||
509 | 127 | if (columnHeights[i]) | ||
510 | 128 | cHeight = Math.max(cHeight, columnHeights[i]) | ||
511 | 129 | } | ||
512 | 130 | |||
513 | 131 | contentHeight = cHeight | ||
514 | 132 | updateWidths() | ||
515 | 133 | } | ||
516 | 134 | |||
517 | 135 | Repeater { | ||
518 | 136 | id: repeater | ||
519 | 137 | model: columnFlow.model | ||
520 | 138 | Component.onCompleted: { | ||
521 | 139 | columnFlow.repeaterCompleted = true | ||
522 | 140 | columnFlow.reEvalColumns() | ||
523 | 141 | } | ||
524 | 142 | |||
525 | 143 | // Provide a hint of the removed item | ||
526 | 144 | property int removeHintIndex: -1 // CUSTOM | ||
527 | 145 | property var removeHintItem // CUSTOM | ||
528 | 146 | |||
529 | 147 | onItemAdded: columnFlow.reEvalColumns() // CUSTOM - ms2 models are live | ||
530 | 148 | onItemRemoved: { | ||
531 | 149 | removeHintIndex = index | ||
532 | 150 | removeHintItem = item | ||
533 | 151 | |||
534 | 152 | columnFlow.reEvalColumns() // CUSTOM - ms2 models are live | ||
535 | 153 | |||
536 | 154 | // Set back to null to allow freeing of memory | ||
537 | 155 | removeHintIndex = -1 | ||
538 | 156 | removeHintItem = undefined | ||
539 | 157 | } | ||
540 | 158 | } | ||
541 | 159 | } |
I ran autopilot on a utopic VM against #642 and it passed.
$ autopilot3 run music_app Workspace/ sdk/remix- add-card- view/tests/ autopilot
Loading tests from: /home/andy/
Tests running... request. QueryExtension' >
<class 'Xlib.protocol.
Ran 18 tests in 289.682s
OK