Merge lp:~vthompson/music-app/remix-do-not-show-artist-in-albumspage into lp:music-app/trusty
- remix-do-not-show-artist-in-albumspage
- Merge into trusty
Status: | Superseded |
---|---|
Proposed branch: | lp:~vthompson/music-app/remix-do-not-show-artist-in-albumspage |
Merge into: | lp:music-app/trusty |
Diff against target: |
6798 lines (+2635/-2615) (has conflicts) 32 files modified
MusicAlbums.qml (+21/-123) MusicArtists.qml (+37/-87) MusicNowPlaying.qml (+377/-219) MusicPlaylists.qml (+34/-10) MusicSettings.qml (+0/-11) MusicStart.qml (+37/-474) MusicToolbar.qml (+161/-953) MusicTracks.qml (+14/-15) MusicaddtoPlaylist.qml (+0/-1) Player.qml (+5/-1) Style.qml (+2/-2) click/apparmor.json (+12/-2) com.ubuntu.music_music.desktop.in.in (+3/-0) common/AlbumsPage.qml (+117/-7) common/BlurredBackground.qml (+12/-14) common/BlurredHeader.qml (+69/-0) common/Card.qml (+151/-0) common/CardView.qml (+61/-0) common/ColumnFlow.qml (+160/-0) common/CoverGrid.qml (+78/-0) common/CoverRow.qml (+2/-0) common/ListItemActions/DeletePlaylist.qml (+0/-29) common/ListItemActions/EditPlaylist.qml (+0/-35) common/MusicPage.qml (+4/-0) common/MusicRow.qml (+24/-5) common/SongsPage.qml (+275/-162) music-app.qml (+27/-36) po/ca@valencia.po (+459/-0) po/com.ubuntu.music.pot (+150/-148) po/pt_BR.po (+179/-151) tests/autopilot/music_app/__init__.py (+104/-84) tests/autopilot/music_app/tests/test_music.py (+60/-46) Text conflict in MusicPlaylists.qml Text conflict in common/AlbumsPage.qml Conflict adding file po/ca@valencia.po. Moved existing file to po/ca@valencia.po.moved. Text conflict in po/pt_BR.po |
To merge this branch: | bzr merge lp:~vthompson/music-app/remix-do-not-show-artist-in-albumspage |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Music App Developers | Pending | ||
Review via email: mp+239083@code.launchpad.net |
This proposal has been superseded by a proposal from 2014-10-21.
Commit message
Do not show the artist in the grid of albums
Description of the change
Do not show the artist in the grid of albums
Unmerged revisions
- 682. By Victor Thompson
-
Do not show the artist in the grid of albums
- 681. By Andrew Hayzen
-
* Add back confinement. Fixes: https:/
/bugs.launchpad .net/bugs/ 1315386. Approved by Victor Thompson, Ubuntu Phone Apps Jenkins Bot.
- 680. By Launchpad Translations on behalf of music-app-dev
-
Launchpad automatic translations update.
- 679. By Andrew Hayzen
-
* Use CardView in Recent Tab
* Use Recent as default if >0 recent items otherwise use Albums Tab.Approved by Ubuntu Phone Apps Jenkins Bot, Victor Thompson.
- 678. By Andrew Hayzen
-
* Set sourceSize of images.
Approved by Ubuntu Phone Apps Jenkins Bot, Victor Thompson.
- 677. By Victor Thompson
-
Force AlbumsPage's SongsModel to filter upon startup.
Approved by Ubuntu Phone Apps Jenkins Bot, Andrew Hayzen.
- 676. By Victor Thompson
-
Fix playlist deletion and renaming in recent table. Fixes: https:/
/bugs.launchpad .net/bugs/ 1382170. Approved by Andrew Hayzen, Ubuntu Phone Apps Jenkins Bot.
- 675. By Launchpad Translations on behalf of music-app-dev
-
Launchpad automatic translations update.
- 674. By Launchpad Translations on behalf of music-app-dev
-
Launchpad automatic translations update.
- 673. By Andrew Hayzen
-
* Add support for CardView in AlbumsPage.qml
* Add support for header property in CardView.qml
* Add BlurredHeader.qml
* Make AlbumsPage.qml and SongsPage.qml use BlurredHeader.qml.Approved by Victor Thompson, Ubuntu Phone Apps Jenkins Bot.
Preview Diff
1 | === modified file 'MusicAlbums.qml' |
2 | --- MusicAlbums.qml 2014-09-20 15:41:33 +0000 |
3 | +++ MusicAlbums.qml 2014-10-21 15:31:33 +0000 |
4 | @@ -19,37 +19,17 @@ |
5 | |
6 | import QtQuick 2.3 |
7 | import Ubuntu.Components 1.1 |
8 | -import Ubuntu.Components.Popups 1.0 |
9 | import Ubuntu.MediaScanner 0.1 |
10 | -import Ubuntu.Thumbnailer 0.1 |
11 | -import QtMultimedia 5.0 |
12 | -import QtQuick.LocalStorage 2.0 |
13 | -import QtGraphicalEffects 1.0 |
14 | -import "settings.js" as Settings |
15 | -import "playlists.js" as Playlists |
16 | import "common" |
17 | |
18 | + |
19 | MusicPage { |
20 | - id: mainpage |
21 | + id: albumsPage |
22 | objectName: "albumsPage" |
23 | title: i18n.tr("Albums") |
24 | |
25 | - // TODO: This ListView is empty and causes the header to get painted with the desired background color because the |
26 | - // page is now vertically flickable. |
27 | - ListView { |
28 | - anchors.fill: parent |
29 | - anchors.bottomMargin: musicToolbar.mouseAreaOffset + musicToolbar.minimizedHeight |
30 | - } |
31 | - |
32 | - GridView { |
33 | - id: albumlist |
34 | - anchors.fill: parent |
35 | - anchors.leftMargin: units.gu(1) |
36 | - anchors.top: parent.top |
37 | - anchors.topMargin: mainView.header.height + units.gu(1) |
38 | - anchors.bottomMargin: units.gu(1) |
39 | - cellHeight: height/3 |
40 | - cellWidth: height/3 |
41 | + CardView { |
42 | + id: albumCardView |
43 | model: SortFilterModel { |
44 | id: albumsModelFilter |
45 | property alias rowCount: albumsModel.rowCount |
46 | @@ -60,106 +40,24 @@ |
47 | sort.property: "title" |
48 | sort.order: Qt.AscendingOrder |
49 | } |
50 | - |
51 | - delegate: albumDelegate |
52 | - flow: GridView.TopToBottom |
53 | - |
54 | - Component { |
55 | - id: albumDelegate |
56 | - Item { |
57 | - property string artist: model.artist |
58 | - property string album: model.title |
59 | - property var covers: [{art: model.art}] |
60 | - |
61 | - id: albumItem |
62 | - height: albumlist.cellHeight - units.gu(1) |
63 | - objectName: "albumsPageGridItem" + index |
64 | - width: albumlist.cellHeight - units.gu(1) |
65 | - anchors.margins: units.gu(1) |
66 | - |
67 | - CoverRow { |
68 | - id: albumShape |
69 | - anchors { |
70 | - top: parent.top |
71 | - left: parent.left |
72 | - verticalCenter: parent.verticalCenter |
73 | - } |
74 | - count: albumItem.covers.length |
75 | - size: albumItem.width |
76 | - covers: albumItem.covers |
77 | - spacing: units.gu(2) |
78 | - } |
79 | - Item { // Background so can see text in current state |
80 | - id: albumBg |
81 | - anchors { |
82 | - bottom: parent.bottom |
83 | - left: parent.left |
84 | - right: parent.right |
85 | - } |
86 | - height: units.gu(6) |
87 | - clip: true |
88 | - UbuntuShape{ |
89 | - anchors { |
90 | - bottom: parent.bottom |
91 | - left: parent.left |
92 | - right: parent.right |
93 | - } |
94 | - height: albumShape.height |
95 | - radius: "medium" |
96 | - color: styleMusic.common.black |
97 | - opacity: 0.6 |
98 | - } |
99 | - } |
100 | - Label { |
101 | - id: albumArtist |
102 | - objectName: "albums-albumartist" |
103 | - anchors.bottom: parent.bottom |
104 | - anchors.bottomMargin: units.gu(1) |
105 | - anchors.left: parent.left |
106 | - anchors.leftMargin: units.gu(1) |
107 | - anchors.right: parent.right |
108 | - anchors.rightMargin: units.gu(1) |
109 | - color: styleMusic.common.white |
110 | - elide: Text.ElideRight |
111 | - text: model.artist |
112 | - fontSize: "x-small" |
113 | - } |
114 | - Label { |
115 | - id: albumLabel |
116 | - anchors.bottom: parent.bottom |
117 | - anchors.bottomMargin: units.gu(3) |
118 | - anchors.left: parent.left |
119 | - anchors.leftMargin: units.gu(1) |
120 | - anchors.right: parent.right |
121 | - anchors.rightMargin: units.gu(1) |
122 | - color: styleMusic.common.white |
123 | - elide: Text.ElideRight |
124 | - text: model.title |
125 | - fontSize: "small" |
126 | - font.weight: Font.DemiBold |
127 | - } |
128 | - |
129 | - |
130 | - MouseArea { |
131 | - anchors.fill: parent |
132 | - onClicked: { |
133 | - songsPage.album = model.title; |
134 | - songsPage.covers = [{art: model.art}] |
135 | - songsPage.genre = undefined |
136 | - songsPage.isAlbum = true |
137 | - songsPage.line1 = model.artist |
138 | - songsPage.line2 = model.title |
139 | - songsPage.title = i18n.tr("Album") |
140 | - |
141 | - mainPageStack.push(songsPage) |
142 | - } |
143 | - |
144 | - // TODO: If http://pad.lv/1354753 is fixed to expose whether the Shape should appear pressed, update this as well. |
145 | - onPressedChanged: albumShape.pressed = pressed |
146 | - } |
147 | + delegate: Card { |
148 | + id: albumCard |
149 | + coverSources: [{art: model.art}] |
150 | + objectName: "albumsPageGridItem" + index |
151 | + primaryText: model.title |
152 | + secondaryText: model.artist |
153 | + |
154 | + onClicked: { |
155 | + songsPage.album = model.title; |
156 | + songsPage.covers = [{art: model.art}] |
157 | + songsPage.genre = undefined |
158 | + songsPage.isAlbum = true |
159 | + songsPage.line1 = model.artist |
160 | + songsPage.line2 = model.title |
161 | + songsPage.title = i18n.tr("Album") |
162 | + |
163 | + mainPageStack.push(songsPage) |
164 | } |
165 | } |
166 | } |
167 | } |
168 | - |
169 | - |
170 | |
171 | === modified file 'MusicArtists.qml' |
172 | --- MusicArtists.qml 2014-09-20 15:41:33 +0000 |
173 | +++ MusicArtists.qml 2014-10-21 15:31:33 +0000 |
174 | @@ -36,98 +36,48 @@ |
175 | objectName: "artistsPage" |
176 | title: i18n.tr("Artists") |
177 | |
178 | - ListView { |
179 | - id: artistlist |
180 | - anchors.fill: parent |
181 | - anchors.bottomMargin: musicToolbar.mouseAreaOffset + musicToolbar.minimizedHeight |
182 | + CardView { |
183 | + id: artistCardView |
184 | + itemWidth: units.gu(12) |
185 | model: ArtistsModel { |
186 | id: artistsModel |
187 | albumArtists: true |
188 | store: musicStore |
189 | } |
190 | - |
191 | - delegate: artistDelegate |
192 | - |
193 | - Component { |
194 | - id: artistDelegate |
195 | - |
196 | - ListItem.Standard { |
197 | - id: track |
198 | - objectName: "artistsPageListItem" + index |
199 | - height: styleMusic.common.itemHeight |
200 | - |
201 | - AlbumsModel { |
202 | - id: albumArtistModel |
203 | - albumArtist: model.artist |
204 | - store: musicStore |
205 | - } |
206 | - |
207 | - Repeater { |
208 | - id: albumArtistModelRepeater |
209 | - model: albumArtistModel |
210 | - delegate: Item { |
211 | - property string art: model.art |
212 | - } |
213 | - property var covers: [] |
214 | - signal finished() |
215 | - |
216 | - onFinished: { |
217 | - musicRow.covers = covers |
218 | - } |
219 | - onItemAdded: { |
220 | - covers.push({art: item.art}); |
221 | - |
222 | - if (index === count - 1) { |
223 | - finished(); |
224 | - } |
225 | - } |
226 | - } |
227 | - |
228 | - SongsModel { |
229 | - id: songArtistModel |
230 | - albumArtist: model.artist |
231 | - store: musicStore |
232 | - } |
233 | - |
234 | - MusicRow { |
235 | - id: musicRow |
236 | - column: Column { |
237 | - spacing: units.gu(1) |
238 | - Label { |
239 | - id: trackArtistAlbum |
240 | - color: styleMusic.common.music |
241 | - fontSize: "medium" |
242 | - objectName: "artists-artist" |
243 | - text: model.artist |
244 | - } |
245 | - Label { |
246 | - id: trackArtistAlbums |
247 | - color: styleMusic.common.subtitle |
248 | - fontSize: "x-small" |
249 | - text: i18n.tr("%1 album", "%1 albums", albumArtistModel.rowCount).arg(albumArtistModel.rowCount) |
250 | - } |
251 | - Label { |
252 | - id: trackArtistAlbumTracks |
253 | - color: styleMusic.common.subtitle |
254 | - fontSize: "x-small" |
255 | - text: i18n.tr("%1 song", "%1 songs", songArtistModel.rowCount).arg(songArtistModel.rowCount) |
256 | - } |
257 | - } |
258 | - } |
259 | - |
260 | - MouseArea { |
261 | - anchors.fill: parent |
262 | - onClicked: { |
263 | - albumsPage.artist = model.artist |
264 | - albumsPage.covers = musicRow.covers |
265 | - albumsPage.title = i18n.tr("Artist") |
266 | - |
267 | - mainPageStack.push(albumsPage) |
268 | - } |
269 | - |
270 | - // TODO: If http://pad.lv/1354753 is fixed to expose whether the Shape should appear pressed, update this as well. |
271 | - onPressedChanged: musicRow.pressed = pressed |
272 | - } |
273 | + delegate: Card { |
274 | + id: artistCard |
275 | + coverSources: [{art: "image://artistart/artist=" + model.artist + "&album=" + artistCard.album}] |
276 | + objectName: "artistsPageGridItem" + index |
277 | + primaryText: model.artist |
278 | + secondaryTextVisible: false |
279 | + |
280 | + property string album: "" |
281 | + |
282 | + AlbumsModel { |
283 | + id: albumArtistModel |
284 | + albumArtist: model.artist |
285 | + store: musicStore |
286 | + } |
287 | + |
288 | + Repeater { |
289 | + id: albumArtistModelRepeater |
290 | + model: albumArtistModel |
291 | + delegate: Item { |
292 | + property string album: model.title |
293 | + } |
294 | + |
295 | + onItemAdded: { |
296 | + artistCard.album = item.album |
297 | + } |
298 | + } |
299 | + |
300 | + |
301 | + onClicked: { |
302 | + albumsPage.artist = model.artist; |
303 | + albumsPage.covers = artistCard.coverSources |
304 | + albumsPage.title = i18n.tr("Artist") |
305 | + |
306 | + mainPageStack.push(albumsPage) |
307 | } |
308 | } |
309 | } |
310 | |
311 | === modified file 'MusicNowPlaying.qml' |
312 | --- MusicNowPlaying.qml 2014-09-20 15:41:33 +0000 |
313 | +++ MusicNowPlaying.qml 2014-10-21 15:31:33 +0000 |
314 | @@ -17,7 +17,6 @@ |
315 | * along with this program. If not, see <http://www.gnu.org/licenses/>. |
316 | */ |
317 | |
318 | - |
319 | import QtMultimedia 5.0 |
320 | import QtQuick 2.3 |
321 | import QtQuick.LocalStorage 2.0 |
322 | @@ -29,65 +28,363 @@ |
323 | |
324 | MusicPage { |
325 | id: nowPlaying |
326 | + flickable: isListView ? queuelist : null // Ensures that the header is shown in fullview |
327 | objectName: "nowPlayingPage" |
328 | - title: i18n.tr("Now Playing") |
329 | + title: isListView ? i18n.tr("Queue") : i18n.tr("Now playing") |
330 | visible: false |
331 | |
332 | - property int ensureVisibleIndex: 0 // ensure first index is visible at startup |
333 | + property bool isListView: false |
334 | + |
335 | + onIsListViewChanged: { |
336 | + if (isListView) { |
337 | + positionAt(player.currentIndex); |
338 | + } |
339 | + } |
340 | + |
341 | + head.backAction: Action { |
342 | + iconName: "back"; |
343 | + objectName: "backButton" |
344 | + onTriggered: { |
345 | + mainPageStack.pop(); |
346 | + |
347 | + while (mainPageStack.depth > 1) { // jump back to the tab layer if via SongsPage |
348 | + mainPageStack.pop(); |
349 | + } |
350 | + } |
351 | + } |
352 | + |
353 | + head { |
354 | + actions: [ |
355 | + Action { |
356 | + objectName: "clearQueue" |
357 | + iconName: "delete" |
358 | + visible: isListView |
359 | + onTriggered: { |
360 | + head.backAction.trigger() |
361 | + trackQueue.model.clear() |
362 | + } |
363 | + }, |
364 | + Action { |
365 | + objectName: "toggleView" |
366 | + iconName: "media-playlist" |
367 | + onTriggered: { |
368 | + isListView = !isListView |
369 | + } |
370 | + } |
371 | + ] |
372 | + } |
373 | + |
374 | + function positionAt(index) { |
375 | + queuelist.positionViewAtIndex(index, ListView.Center); |
376 | + } |
377 | |
378 | Rectangle { |
379 | + id: fullview |
380 | anchors.fill: parent |
381 | - color: styleMusic.nowPlaying.backgroundColor |
382 | - opacity: 0.75 // change later |
383 | - MouseArea { // Block events to lower layers |
384 | - anchors.fill: parent |
385 | - } |
386 | - } |
387 | - |
388 | - Component.onCompleted: { |
389 | - onToolbarShownChanged.connect(jumpToCurrent) |
390 | - } |
391 | - |
392 | - Connections { |
393 | - target: player |
394 | - onCurrentIndexChanged: { |
395 | - if (player.source === "") { |
396 | - return; |
397 | - } |
398 | - |
399 | - queuelist.currentIndex = player.currentIndex; |
400 | - |
401 | - customdebug("MusicQueue update currentIndex: " + player.source); |
402 | - |
403 | - // Always jump to current track |
404 | - nowPlaying.jumpToCurrent(musicToolbar.opened, nowPlaying, musicToolbar.currentTab) |
405 | - |
406 | - } |
407 | - } |
408 | - |
409 | - function jumpToCurrent(shown, currentPage, currentTab) |
410 | - { |
411 | - // If the toolbar is shown, the page is now playing and snaptrack is enabled |
412 | - if (shown && currentPage === nowPlaying && Settings.getSetting("snaptrack") === "1") |
413 | - { |
414 | - // Then position the view at the current index |
415 | - queuelist.positionViewAtIndex(queuelist.currentIndex, ListView.Beginning); |
416 | - } |
417 | - } |
418 | - |
419 | - function positionAt(index) { |
420 | - queuelist.positionViewAtIndex(index, ListView.Beginning); |
421 | - queuelist.contentY -= header.height; |
422 | + color: "transparent" |
423 | + visible: !isListView |
424 | + |
425 | + BlurredBackground { |
426 | + id: blurredBackground |
427 | + anchors.top: parent.top |
428 | + anchors.topMargin: mainView.header.height |
429 | + height: units.gu(27) |
430 | + art: albumImage.firstSource |
431 | + |
432 | + CoverGrid { |
433 | + id: albumImage |
434 | + anchors { |
435 | + centerIn: parent |
436 | + } |
437 | + covers: [{art: player.currentMetaArt, author: player.currentMetaArtist, album: player.currentMetaAlbum}] |
438 | + size: units.gu(18) |
439 | + } |
440 | + } |
441 | + |
442 | + /* Full toolbar */ |
443 | + Item { |
444 | + id: musicToolbarFullContainer |
445 | + anchors.top: blurredBackground.bottom |
446 | + anchors.topMargin: units.gu(4) |
447 | + width: blurredBackground.width |
448 | + |
449 | + /* Column for labels in wideAspect */ |
450 | + Column { |
451 | + id: nowPlayingWideAspectLabels |
452 | + spacing: units.gu(1) |
453 | + anchors { |
454 | + left: parent.left |
455 | + leftMargin: units.gu(2) |
456 | + right: parent.right |
457 | + rightMargin: units.gu(2) |
458 | + } |
459 | + |
460 | + /* Title of track */ |
461 | + Label { |
462 | + id: nowPlayingWideAspectTitle |
463 | + anchors { |
464 | + left: parent.left |
465 | + leftMargin: units.gu(1) |
466 | + right: parent.right |
467 | + rightMargin: units.gu(1) |
468 | + } |
469 | + color: styleMusic.playerControls.labelColor |
470 | + elide: Text.ElideRight |
471 | + fontSize: "x-large" |
472 | + objectName: "playercontroltitle" |
473 | + text: trackQueue.model.count === 0 ? "" : player.currentMetaTitle === "" ? player.currentMetaFile : player.currentMetaTitle |
474 | + } |
475 | + |
476 | + /* Artist of track */ |
477 | + Label { |
478 | + id: nowPlayingWideAspectArtist |
479 | + anchors { |
480 | + left: parent.left |
481 | + leftMargin: units.gu(1) |
482 | + right: parent.right |
483 | + rightMargin: units.gu(1) |
484 | + } |
485 | + color: styleMusic.nowPlaying.labelSecondaryColor |
486 | + elide: Text.ElideRight |
487 | + fontSize: "small" |
488 | + text: trackQueue.model.count === 0 ? "" : player.currentMetaArtist |
489 | + } |
490 | + } |
491 | + |
492 | + /* Progress bar component */ |
493 | + MouseArea { |
494 | + id: musicToolbarFullProgressContainer |
495 | + anchors.left: parent.left |
496 | + anchors.leftMargin: units.gu(3) |
497 | + anchors.right: parent.right |
498 | + anchors.rightMargin: units.gu(3) |
499 | + anchors.top: nowPlayingWideAspectLabels.bottom |
500 | + anchors.topMargin: units.gu(3) |
501 | + height: units.gu(3) |
502 | + width: parent.width |
503 | + |
504 | + /* Position label */ |
505 | + Label { |
506 | + id: musicToolbarFullPositionLabel |
507 | + anchors.top: progressSliderMusic.bottom |
508 | + anchors.topMargin: units.gu(-2) |
509 | + anchors.left: parent.left |
510 | + color: styleMusic.nowPlaying.labelSecondaryColor |
511 | + fontSize: "small" |
512 | + height: parent.height |
513 | + horizontalAlignment: Text.AlignHCenter |
514 | + text: durationToString(player.position) |
515 | + verticalAlignment: Text.AlignVCenter |
516 | + width: units.gu(3) |
517 | + } |
518 | + |
519 | + Slider { |
520 | + id: progressSliderMusic |
521 | + anchors.left: parent.left |
522 | + anchors.right: parent.right |
523 | + objectName: "progressSliderShape" |
524 | + |
525 | + function formatValue(v) { |
526 | + if (seeking) { // update position label while dragging |
527 | + musicToolbarFullPositionLabel.text = durationToString(v) |
528 | + } |
529 | + |
530 | + return durationToString(v) |
531 | + } |
532 | + |
533 | + property bool seeking: false |
534 | + property bool seeked: false |
535 | + |
536 | + onSeekingChanged: { |
537 | + if (seeking === false) { |
538 | + musicToolbarFullPositionLabel.text = durationToString(player.position) |
539 | + } |
540 | + } |
541 | + |
542 | + Component.onCompleted: { |
543 | + Theme.palette.selected.foreground = UbuntuColors.blue |
544 | + } |
545 | + |
546 | + onPressedChanged: { |
547 | + seeking = pressed |
548 | + if (!pressed) { |
549 | + seeked = true |
550 | + player.seek(value) |
551 | + } |
552 | + } |
553 | + |
554 | + Connections { |
555 | + target: player |
556 | + onDurationChanged: { |
557 | + musicToolbarFullDurationLabel.text = durationToString(player.duration) |
558 | + progressSliderMusic.maximumValue = player.duration |
559 | + } |
560 | + onPositionChanged: { |
561 | + // seeked is a workaround for bug 1310706 as the first position after a seek is sometimes invalid (0) |
562 | + if (progressSliderMusic.seeking === false && !progressSliderMusic.seeked) { |
563 | + progressSliderMusic.value = player.position |
564 | + musicToolbarFullPositionLabel.text = durationToString(player.position) |
565 | + musicToolbarFullDurationLabel.text = durationToString(player.duration) |
566 | + } |
567 | + |
568 | + progressSliderMusic.seeked = false; |
569 | + } |
570 | + onStopped: { |
571 | + musicToolbarFullPositionLabel.text = durationToString(0); |
572 | + musicToolbarFullDurationLabel.text = durationToString(0); |
573 | + } |
574 | + } |
575 | + } |
576 | + |
577 | + /* Duration label */ |
578 | + Label { |
579 | + id: musicToolbarFullDurationLabel |
580 | + anchors.top: progressSliderMusic.bottom |
581 | + anchors.topMargin: units.gu(-2) |
582 | + anchors.right: parent.right |
583 | + color: styleMusic.nowPlaying.labelSecondaryColor |
584 | + fontSize: "small" |
585 | + height: parent.height |
586 | + horizontalAlignment: Text.AlignHCenter |
587 | + text: durationToString(player.duration) |
588 | + verticalAlignment: Text.AlignVCenter |
589 | + width: units.gu(3) |
590 | + } |
591 | + } |
592 | + |
593 | + /* Repeat button */ |
594 | + MouseArea { |
595 | + id: nowPlayingRepeatButton |
596 | + anchors.right: nowPlayingPreviousButton.left |
597 | + anchors.rightMargin: units.gu(1) |
598 | + anchors.verticalCenter: nowPlayingPlayButton.verticalCenter |
599 | + height: units.gu(6) |
600 | + opacity: player.repeat && !emptyPage.noMusic ? 1 : .4 |
601 | + width: height |
602 | + onClicked: player.repeat = !player.repeat |
603 | + |
604 | + Icon { |
605 | + id: repeatIcon |
606 | + height: units.gu(3) |
607 | + width: height |
608 | + anchors.verticalCenter: parent.verticalCenter |
609 | + anchors.horizontalCenter: parent.horizontalCenter |
610 | + color: "white" |
611 | + name: "media-playlist-repeat" |
612 | + objectName: "repeatShape" |
613 | + opacity: player.repeat && !emptyPage.noMusic ? 1 : .4 |
614 | + } |
615 | + } |
616 | + |
617 | + /* Previous button */ |
618 | + MouseArea { |
619 | + id: nowPlayingPreviousButton |
620 | + anchors.right: nowPlayingPlayButton.left |
621 | + anchors.rightMargin: units.gu(1) |
622 | + anchors.verticalCenter: nowPlayingPlayButton.verticalCenter |
623 | + height: units.gu(6) |
624 | + opacity: trackQueue.model.count === 0 ? .4 : 1 |
625 | + width: height |
626 | + onClicked: player.previousSong() |
627 | + |
628 | + Icon { |
629 | + id: nowPlayingPreviousIndicator |
630 | + height: units.gu(3) |
631 | + width: height |
632 | + anchors.verticalCenter: parent.verticalCenter |
633 | + anchors.horizontalCenter: parent.horizontalCenter |
634 | + color: "white" |
635 | + name: "media-skip-backward" |
636 | + objectName: "previousShape" |
637 | + opacity: 1 |
638 | + } |
639 | + } |
640 | + |
641 | + /* Play/Pause button */ |
642 | + MouseArea { |
643 | + id: nowPlayingPlayButton |
644 | + anchors.horizontalCenter: parent.horizontalCenter |
645 | + anchors.top: musicToolbarFullProgressContainer.bottom |
646 | + anchors.topMargin: units.gu(2) |
647 | + height: units.gu(12) |
648 | + width: height |
649 | + onClicked: player.toggle() |
650 | + |
651 | + Icon { |
652 | + id: nowPlayingPlayIndicator |
653 | + height: units.gu(6) |
654 | + width: height |
655 | + anchors.verticalCenter: parent.verticalCenter |
656 | + anchors.horizontalCenter: parent.horizontalCenter |
657 | + opacity: emptyPage.noMusic ? .4 : 1 |
658 | + color: "white" |
659 | + name: player.playbackState === MediaPlayer.PlayingState ? "media-playback-pause" : "media-playback-start" |
660 | + objectName: "playShape" |
661 | + } |
662 | + } |
663 | + |
664 | + /* Next button */ |
665 | + MouseArea { |
666 | + id: nowPlayingNextButton |
667 | + anchors.left: nowPlayingPlayButton.right |
668 | + anchors.leftMargin: units.gu(1) |
669 | + anchors.verticalCenter: nowPlayingPlayButton.verticalCenter |
670 | + height: units.gu(6) |
671 | + opacity: trackQueue.model.count === 0 ? .4 : 1 |
672 | + width: height |
673 | + onClicked: player.nextSong() |
674 | + |
675 | + Icon { |
676 | + id: nowPlayingNextIndicator |
677 | + height: units.gu(3) |
678 | + width: height |
679 | + anchors.verticalCenter: parent.verticalCenter |
680 | + anchors.horizontalCenter: parent.horizontalCenter |
681 | + color: "white" |
682 | + name: "media-skip-forward" |
683 | + objectName: "forwardShape" |
684 | + opacity: 1 |
685 | + } |
686 | + } |
687 | + |
688 | + /* Shuffle button */ |
689 | + MouseArea { |
690 | + id: nowPlayingShuffleButton |
691 | + anchors.left: nowPlayingNextButton.right |
692 | + anchors.leftMargin: units.gu(1) |
693 | + anchors.verticalCenter: nowPlayingPlayButton.verticalCenter |
694 | + height: units.gu(6) |
695 | + opacity: player.shuffle && !emptyPage.noMusic ? 1 : .4 |
696 | + width: height |
697 | + onClicked: player.shuffle = !player.shuffle |
698 | + |
699 | + Icon { |
700 | + id: shuffleIcon |
701 | + height: units.gu(3) |
702 | + width: height |
703 | + anchors.verticalCenter: parent.verticalCenter |
704 | + anchors.horizontalCenter: parent.horizontalCenter |
705 | + color: "white" |
706 | + name: "media-playlist-shuffle" |
707 | + objectName: "shuffleShape" |
708 | + opacity: player.shuffle && !emptyPage.noMusic ? 1 : .4 |
709 | + } |
710 | + } |
711 | + } |
712 | } |
713 | |
714 | ListView { |
715 | id: queuelist |
716 | - objectName: "nowPlayingQueueList" |
717 | - anchors.fill: parent |
718 | - anchors.bottomMargin: musicToolbar.mouseAreaOffset + musicToolbar.minimizedHeight |
719 | + anchors { |
720 | + fill: parent |
721 | + topMargin: units.gu(2) |
722 | + } |
723 | delegate: queueDelegate |
724 | + footer: Item { |
725 | + height: mainView.height - (styleMusic.common.expandHeight + queuelist.currentHeight) + units.gu(8) |
726 | + } |
727 | model: trackQueue.model |
728 | - highlightFollowsCurrentItem: false |
729 | + objectName: "nowPlayingQueueList" |
730 | state: "normal" |
731 | states: [ |
732 | State { |
733 | @@ -105,33 +402,29 @@ |
734 | } |
735 | } |
736 | ] |
737 | - footer: Item { |
738 | - height: mainView.height - (styleMusic.common.expandHeight + queuelist.currentHeight) + units.gu(8) |
739 | - } |
740 | + visible: isListView |
741 | |
742 | - property int normalHeight: units.gu(12) |
743 | - property int currentHeight: units.gu(40) |
744 | + property int normalHeight: units.gu(6) |
745 | property int transitionDuration: 250 // transition length of animations |
746 | |
747 | onCountChanged: { |
748 | customdebug("Queue: Now has: " + queuelist.count + " tracks") |
749 | } |
750 | |
751 | - onMovementStarted: { |
752 | - musicToolbar.hideToolbar(); |
753 | - } |
754 | - |
755 | Component { |
756 | id: queueDelegate |
757 | ListItemWithActions { |
758 | id: queueListItem |
759 | - color: "transparent" |
760 | + color: player.currentIndex === index ? "#2c2c34" : "transparent" |
761 | height: queuelist.normalHeight |
762 | objectName: "nowPlayingListItem" + index |
763 | - state: queuelist.currentIndex == index && !reordering ? "current" : "" |
764 | + showDivider: false |
765 | + state: "" |
766 | |
767 | leftSideAction: Remove { |
768 | onTriggered: { |
769 | + var removedIndex = index |
770 | + |
771 | if (queuelist.count === 1) { |
772 | player.stop() |
773 | musicToolbar.goBack() |
774 | @@ -139,12 +432,12 @@ |
775 | player.nextSong(player.isPlaying); |
776 | } |
777 | |
778 | - if (index < player.currentIndex) { |
779 | + queuelist.model.remove(index); |
780 | + |
781 | + if (removedIndex < player.currentIndex) { |
782 | // update index as the old has been removed |
783 | player.currentIndex -= 1; |
784 | } |
785 | - |
786 | - queuelist.model.remove(index); |
787 | } |
788 | } |
789 | reorderable: true |
790 | @@ -177,14 +470,10 @@ |
791 | } |
792 | } |
793 | |
794 | - // TODO: If http://pad.lv/1354753 is fixed to expose whether the Shape should appear pressed, update this as well. |
795 | - onPressedChanged: trackImage.pressed = pressed |
796 | - |
797 | Rectangle { |
798 | id: trackContainer; |
799 | anchors { |
800 | fill: parent |
801 | - margins: units.gu(1) |
802 | } |
803 | color: "transparent" |
804 | |
805 | @@ -204,159 +493,28 @@ |
806 | to: units.gu(0.5) |
807 | } |
808 | |
809 | - CoverRow { |
810 | - id: trackImage |
811 | - |
812 | - anchors { |
813 | - top: parent.top |
814 | - left: parent.left |
815 | - leftMargin: units.gu(1.5) |
816 | - } |
817 | - count: 1 |
818 | - size: (queueListItem.state === "current" |
819 | - ? (mainView.wideAspect |
820 | - ? queuelist.currentHeight |
821 | - : mainView.width - (trackImage.anchors.leftMargin * 2)) |
822 | - : queuelist.normalHeight) - units.gu(2) |
823 | - covers: [{art: model.art}] |
824 | - |
825 | - spacing: units.gu(2) |
826 | - |
827 | - Item { // Background so can see text in current state |
828 | - id: albumBg |
829 | - visible: false |
830 | - anchors { |
831 | - bottom: parent.bottom |
832 | - left: parent.left |
833 | - right: parent.right |
834 | - } |
835 | - height: units.gu(9) |
836 | - clip: true |
837 | - UbuntuShape{ |
838 | - anchors { |
839 | - bottom: parent.bottom |
840 | - left: parent.left |
841 | - right: parent.right |
842 | - } |
843 | - height: trackImage.height |
844 | - radius: "medium" |
845 | - color: styleMusic.common.black |
846 | - opacity: 0.6 |
847 | - } |
848 | - } |
849 | - |
850 | - function calcAnchors() { |
851 | - if (trackImage.height > queuelist.normalHeight && mainView.wideAspect) { |
852 | - trackImage.anchors.left = undefined |
853 | - trackImage.anchors.horizontalCenter = trackImage.parent.horizontalCenter |
854 | - } else { |
855 | - trackImage.anchors.left = trackImage.parent.left |
856 | - trackImage.anchors.horizontalCenter = undefined |
857 | - } |
858 | - |
859 | - trackImage.width = trackImage.height; // force width to match height |
860 | - } |
861 | - |
862 | - Connections { |
863 | - target: mainView |
864 | - onWideAspectChanged: trackImage.calcAnchors() |
865 | - } |
866 | - |
867 | - onHeightChanged: { |
868 | - calcAnchors() |
869 | - } |
870 | - Behavior on height { |
871 | - NumberAnimation { |
872 | - target: trackImage; |
873 | - property: "height"; |
874 | - duration: queuelist.transitionDuration; |
875 | - } |
876 | - } |
877 | - } |
878 | - Label { |
879 | - id: nowPlayingArtist |
880 | - objectName: "artistLabel" |
881 | - color: styleMusic.nowPlaying.labelSecondaryColor |
882 | - elide: Text.ElideRight |
883 | - height: units.gu(1) |
884 | - text: model.author |
885 | - fontSize: 'small' |
886 | - width: parent.width - trackImage.width - units.gu(3.5) |
887 | - x: trackImage.x + trackImage.width + units.gu(1) |
888 | - y: trackImage.y + units.gu(1) |
889 | - } |
890 | - Label { |
891 | - id: nowPlayingTitle |
892 | - objectName: "titleLabel" |
893 | - color: styleMusic.common.white |
894 | - elide: Text.ElideRight |
895 | - height: units.gu(1) |
896 | - text: model.title |
897 | - fontSize: 'medium' |
898 | - width: parent.width - trackImage.width - units.gu(3.5) |
899 | - x: trackImage.x + trackImage.width + units.gu(1) |
900 | - y: nowPlayingArtist.y + nowPlayingArtist.height + units.gu(1.25) |
901 | - } |
902 | - Label { |
903 | - id: nowPlayingAlbum |
904 | - objectName: "albumLabel" |
905 | - color: styleMusic.nowPlaying.labelSecondaryColor |
906 | - elide: Text.ElideRight |
907 | - height: units.gu(1) |
908 | - text: model.album |
909 | - fontSize: 'x-small' |
910 | - width: parent.width - trackImage.width - units.gu(3.5) |
911 | - x: trackImage.x + trackImage.width + units.gu(1) |
912 | - y: nowPlayingTitle.y + nowPlayingTitle.height + units.gu(1.25) |
913 | - } |
914 | - } |
915 | - |
916 | - states: State { |
917 | - name: "current" |
918 | - PropertyChanges { |
919 | - target: queueListItem |
920 | - height: trackImage.size + (trackContainer.anchors.margins * 2) |
921 | - } |
922 | - PropertyChanges { |
923 | - target: nowPlayingArtist |
924 | - width: trackImage.width - units.gu(4) |
925 | - x: trackImage.x + units.gu(2) |
926 | - y: trackImage.y + trackImage.height - albumBg.height + units.gu(1) |
927 | - color: styleMusic.common.white |
928 | - } |
929 | - PropertyChanges { |
930 | - target: nowPlayingTitle |
931 | - width: trackImage.width - units.gu(4) |
932 | - x: trackImage.x + units.gu(2) |
933 | - y: nowPlayingArtist.y + nowPlayingArtist.height + units.gu(1.25) |
934 | - color: styleMusic.common.white |
935 | - font.weight: Font.DemiBold |
936 | - } |
937 | - PropertyChanges { |
938 | - target: nowPlayingAlbum |
939 | - width: trackImage.width - units.gu(4) |
940 | - x: trackImage.x + units.gu(2) |
941 | - y: nowPlayingTitle.y + nowPlayingTitle.height + units.gu(1.25) |
942 | - color: styleMusic.common.white |
943 | - } |
944 | - PropertyChanges { |
945 | - target: albumBg |
946 | - visible: true |
947 | - } |
948 | - } |
949 | - transitions: Transition { |
950 | - from: ",current" |
951 | - to: "current," |
952 | - NumberAnimation { |
953 | - duration: queuelist.transitionDuration |
954 | - properties: "height,opacity,width,x,y" |
955 | - } |
956 | - |
957 | - onRunningChanged: { |
958 | - if (running === false && ensureVisibleIndex != -1) |
959 | - { |
960 | - queuelist.positionViewAtIndex(ensureVisibleIndex, ListView.Beginning); |
961 | - ensureVisibleIndex = -1; |
962 | + MusicRow { |
963 | + id: musicRow |
964 | + covers: [{art: model.art, album: model.album, author: model.author}] |
965 | + showCovers: false |
966 | + coverSize: units.gu(6) |
967 | + column: Column { |
968 | + Label { |
969 | + id: trackTitle |
970 | + color: player.currentIndex === index ? UbuntuColors.blue |
971 | + : styleMusic.common.music |
972 | + fontSize: "small" |
973 | + objectName: "titleLabel" |
974 | + text: model.title |
975 | + } |
976 | + |
977 | + Label { |
978 | + id: trackArtist |
979 | + color: styleMusic.common.subtitle |
980 | + fontSize: "x-small" |
981 | + objectName: "artistLabel" |
982 | + text: model.author |
983 | + } |
984 | } |
985 | } |
986 | } |
987 | |
988 | === modified file 'MusicPlaylists.qml' |
989 | --- MusicPlaylists.qml 2014-10-19 06:28:03 +0000 |
990 | +++ MusicPlaylists.qml 2014-10-21 15:31:33 +0000 |
991 | @@ -23,36 +23,37 @@ |
992 | import Ubuntu.Components.Popups 1.0 |
993 | import QtMultimedia 5.0 |
994 | import QtQuick.LocalStorage 2.0 |
995 | +<<<<<<< TREE |
996 | import "meta-database.js" as Library |
997 | import "settings.js" as Settings |
998 | import "scrobble.js" as Scrobble |
999 | +======= |
1000 | +>>>>>>> MERGE-SOURCE |
1001 | import "playlists.js" as Playlists |
1002 | import "common" |
1003 | -import "common/ListItemActions" |
1004 | |
1005 | // page for the playlists |
1006 | MusicPage { |
1007 | - id: listspage |
1008 | + id: playlistsPage |
1009 | objectName: "playlistsPage" |
1010 | // TRANSLATORS: this is the name of the playlists page shown in the tab header. |
1011 | // Remember to keep the translation short to fit the screen width |
1012 | title: i18n.tr("Playlists") |
1013 | |
1014 | property string playlistTracks: "" |
1015 | - property string oldPlaylistName: "" |
1016 | property string inPlaylist: "" |
1017 | |
1018 | - tools: ToolbarItems { |
1019 | - ToolbarButton { |
1020 | - action: Action { |
1021 | + head { |
1022 | + actions: [ |
1023 | + Action { |
1024 | objectName: "newplaylistButton" |
1025 | - text: i18n.tr("New playlist") |
1026 | iconName: "add" |
1027 | onTriggered: { |
1028 | customdebug("New playlist.") |
1029 | PopupUtils.open(newPlaylistDialog, mainView) |
1030 | } |
1031 | } |
1032 | +<<<<<<< TREE |
1033 | } |
1034 | } |
1035 | |
1036 | @@ -120,11 +121,15 @@ |
1037 | } |
1038 | |
1039 | ListView { |
1040 | +======= |
1041 | + ] |
1042 | + } |
1043 | + |
1044 | + CardView { |
1045 | +>>>>>>> MERGE-SOURCE |
1046 | id: playlistslist |
1047 | - objectName: "playlistsListView" |
1048 | - anchors.fill: parent |
1049 | - anchors.bottomMargin: musicToolbar.mouseAreaOffset + musicToolbar.minimizedHeight |
1050 | model: playlistModel.model |
1051 | +<<<<<<< TREE |
1052 | delegate: playlistDelegate |
1053 | onCountChanged: { |
1054 | customdebug("onCountChanged: " + playlistslist.count) |
1055 | @@ -199,6 +204,25 @@ |
1056 | } |
1057 | } |
1058 | } |
1059 | +======= |
1060 | + objectName: "playlistsCardView" |
1061 | + delegate: Card { |
1062 | + id: playlistCard |
1063 | + coverSources: Playlists.getPlaylistCovers(name) |
1064 | + primaryText: name |
1065 | + secondaryText: i18n.tr("%1 song", "%1 songs", count).arg(count) |
1066 | + |
1067 | + onClicked: { |
1068 | + albumTracksModel.filterPlaylistTracks(name) |
1069 | + songsPage.isAlbum = false |
1070 | + songsPage.line1 = i18n.tr("Playlist") |
1071 | + songsPage.line2 = model.name |
1072 | + songsPage.covers = coverSources |
1073 | + songsPage.genre = undefined |
1074 | + songsPage.title = i18n.tr("Playlist") |
1075 | + |
1076 | + mainPageStack.push(songsPage) |
1077 | +>>>>>>> MERGE-SOURCE |
1078 | } |
1079 | } |
1080 | } |
1081 | |
1082 | === modified file 'MusicSettings.qml' |
1083 | --- MusicSettings.qml 2014-09-20 10:50:45 +0000 |
1084 | +++ MusicSettings.qml 2014-10-21 15:31:33 +0000 |
1085 | @@ -30,17 +30,6 @@ |
1086 | title: i18n.tr("Settings") |
1087 | contentsHeight: parent.height; |
1088 | |
1089 | - onVisibleChanged: { |
1090 | - if (visible === true) |
1091 | - { |
1092 | - musicToolbar.disableToolbar() |
1093 | - } |
1094 | - else |
1095 | - { |
1096 | - musicToolbar.enableToolbar() |
1097 | - } |
1098 | - } |
1099 | - |
1100 | onCancelClicked: PopupUtils.close(musicSettings) |
1101 | onConfirmClicked: { |
1102 | PopupUtils.close(musicSettings) |
1103 | |
1104 | === modified file 'MusicStart.qml' |
1105 | --- MusicStart.qml 2014-09-20 15:41:33 +0000 |
1106 | +++ MusicStart.qml 2014-10-21 15:31:33 +0000 |
1107 | @@ -32,482 +32,45 @@ |
1108 | |
1109 | MusicPage { |
1110 | id: mainpage |
1111 | - title: i18n.tr("Music") |
1112 | + title: i18n.tr("Recent") |
1113 | |
1114 | - /* Dev button for search. |
1115 | - Button { |
1116 | - id: searchButton |
1117 | - text: i18n.tr("Search") |
1118 | - anchors.top: parent.top |
1119 | - anchors.topMargin: units.gu(2) |
1120 | - anchors.bottom: recentlyPlayed.top |
1121 | - anchors.bottomMargin: units.gu(1) |
1122 | - height: units.gu(4) |
1123 | - onClicked: { |
1124 | - PopupUtils.open(Qt.resolvedUrl("MusicSearch.qml"), mainView, |
1125 | - { |
1126 | - title: i18n.tr("Search") |
1127 | - } ) |
1128 | - } |
1129 | + head { |
1130 | + actions: [ |
1131 | + Action { |
1132 | + iconName: "delete" |
1133 | + onTriggered: { |
1134 | + Library.clearRecentHistory() |
1135 | + recentModel.filterRecent() |
1136 | + } |
1137 | + } |
1138 | + ] |
1139 | } |
1140 | - */ |
1141 | - Flickable{ |
1142 | - id: musicFlickable |
1143 | - anchors.fill: parent |
1144 | - |
1145 | - width: mainpage.width |
1146 | - height: mainpage.height |
1147 | - |
1148 | - contentHeight: mainView.hasRecent ? recentlyPlayed.height + recentlist.height + genres.height + genrelist.height + albums.height + albumlist.height + units.gu(4) |
1149 | - : genres.height + genrelist.height + albums.height + albumlist.height + units.gu(3) |
1150 | - contentWidth: width |
1151 | - |
1152 | - focus: true |
1153 | - |
1154 | - ListItem.Standard { |
1155 | - id: recentlyPlayed |
1156 | - Label { |
1157 | - anchors { |
1158 | - verticalCenter: parent.verticalCenter |
1159 | - left: parent.left |
1160 | - leftMargin: units.gu(2) |
1161 | - } |
1162 | - text: i18n.tr("Recent") |
1163 | - color: styleMusic.common.music |
1164 | - } |
1165 | - visible: mainView.hasRecent |
1166 | - } |
1167 | - |
1168 | - ListView { |
1169 | - id: recentlist |
1170 | - anchors.top: recentlyPlayed.bottom |
1171 | - anchors.topMargin: units.gu(1) |
1172 | - width: parent.width |
1173 | - spacing: units.gu(1) |
1174 | - height: units.gu(18) |
1175 | - // TODO: Update when view counts are collected |
1176 | - model: recentModel.model |
1177 | - delegate: recentDelegate |
1178 | - header: Item { |
1179 | - id: recentSpacer |
1180 | - width: units.gu(1) |
1181 | - } |
1182 | - footer: Item { |
1183 | - id: clearRecent |
1184 | - width: recentlist.height - units.gu(2) |
1185 | - height: width |
1186 | - visible: mainView.hasRecent && !loading.visible |
1187 | - Button { |
1188 | - id: clearRecentButton |
1189 | - anchors.centerIn: parent |
1190 | - text: i18n.tr("Clear History") |
1191 | - onClicked: { |
1192 | - Library.clearRecentHistory() |
1193 | - mainView.hasRecent = false |
1194 | - recentModel.filterRecent() |
1195 | - } |
1196 | - } |
1197 | - } |
1198 | - orientation: ListView.Horizontal |
1199 | - visible: mainView.hasRecent |
1200 | - |
1201 | - Component { |
1202 | - id: recentDelegate |
1203 | - Item { |
1204 | - property string title: model.title |
1205 | - property string title2: model.title2 !== "Playlist" ? model.title2 : i18n.tr("Playlist") |
1206 | - property var covers: type === "playlist" ? Playlists.getPlaylistCovers(title) : (model.art !== undefined ? [{art: model.art}] : [{author: model.title2, album: model.title}]) |
1207 | - property string type: model.type |
1208 | - property string time: model.time |
1209 | - property string key: model.key |
1210 | - id: recentItem |
1211 | - height: recentlist.height - units.gu(1) |
1212 | - width: height |
1213 | - CoverRow { |
1214 | - id: recentShape |
1215 | - anchors { |
1216 | - top: parent.top |
1217 | - left: parent.left |
1218 | - verticalCenter: parent.verticalCenter |
1219 | - } |
1220 | - count: recentItem.covers.length |
1221 | - size: recentItem.width |
1222 | - covers: recentItem.covers |
1223 | - spacing: units.gu(2) |
1224 | - } |
1225 | - Item { // Background so can see text in current state |
1226 | - id: albumBg |
1227 | - anchors { |
1228 | - bottom: parent.bottom |
1229 | - left: parent.left |
1230 | - right: parent.right |
1231 | - } |
1232 | - height: units.gu(6) |
1233 | - clip: true |
1234 | - UbuntuShape{ |
1235 | - anchors { |
1236 | - bottom: parent.bottom |
1237 | - left: parent.left |
1238 | - right: parent.right |
1239 | - } |
1240 | - height: recentShape.height |
1241 | - radius: "medium" |
1242 | - color: styleMusic.common.black |
1243 | - opacity: 0.6 |
1244 | - } |
1245 | - } |
1246 | - Label { |
1247 | - id: albumArtist |
1248 | - anchors.bottom: parent.bottom |
1249 | - anchors.bottomMargin: units.gu(3) |
1250 | - anchors.left: parent.left |
1251 | - anchors.leftMargin: units.gu(1) |
1252 | - anchors.right: parent.right |
1253 | - anchors.rightMargin: units.gu(1) |
1254 | - color: styleMusic.common.white |
1255 | - elide: Text.ElideRight |
1256 | - text: title |
1257 | - fontSize: "small" |
1258 | - font.weight: Font.DemiBold |
1259 | - } |
1260 | - Label { |
1261 | - id: albumLabel |
1262 | - anchors.left: parent.left |
1263 | - anchors.leftMargin: units.gu(1) |
1264 | - anchors.bottom: parent.bottom |
1265 | - anchors.bottomMargin: units.gu(1) |
1266 | - anchors.right: parent.right |
1267 | - anchors.rightMargin: units.gu(1) |
1268 | - color: styleMusic.common.white |
1269 | - elide: Text.ElideRight |
1270 | - text: title2 |
1271 | - fontSize: "x-small" |
1272 | - } |
1273 | - MouseArea { |
1274 | - anchors.fill: parent |
1275 | - onClicked: { |
1276 | - if (type === "playlist") { |
1277 | - albumTracksModel.filterPlaylistTracks(key) |
1278 | - } else { |
1279 | - songsPage.album = title; |
1280 | - } |
1281 | - songsPage.genre = undefined; |
1282 | - |
1283 | - songsPage.line1 = title2 |
1284 | - songsPage.line2 = title |
1285 | - songsPage.covers = recentItem.covers |
1286 | - songsPage.isAlbum = (type === "album") |
1287 | - songsPage.title = songsPage.isAlbum ? i18n.tr("Album") : i18n.tr("Playlist") |
1288 | - |
1289 | - mainPageStack.push(songsPage) |
1290 | - } |
1291 | - |
1292 | - // TODO: If http://pad.lv/1354753 is fixed to expose whether the Shape should appear pressed, update this as well. |
1293 | - onPressedChanged: recentShape.pressed = pressed |
1294 | - } |
1295 | - } |
1296 | - } |
1297 | - } |
1298 | - |
1299 | - ListItem.ThinDivider { |
1300 | - id: genreDivider |
1301 | - anchors.top: mainView.hasRecent ? recentlist.bottom : parent.top |
1302 | - visible: genrelist.count > 1 |
1303 | - } |
1304 | - ListItem.Standard { |
1305 | - id: genres |
1306 | - anchors.top: genreDivider.bottom |
1307 | - visible: genrelist.count > 1 |
1308 | - Label { |
1309 | - anchors { |
1310 | - verticalCenter: parent.verticalCenter |
1311 | - left: parent.left |
1312 | - leftMargin: units.gu(2) |
1313 | - } |
1314 | - text: i18n.tr("Genres") |
1315 | - color: styleMusic.common.music |
1316 | - } |
1317 | - } |
1318 | - // TODO: add music genres. frequency of play? most tracks? |
1319 | - ListView { |
1320 | - id: genrelist |
1321 | - width: parent.width |
1322 | - anchors.top: genres.bottom |
1323 | - anchors.topMargin: units.gu(1) |
1324 | - spacing: units.gu(1) |
1325 | - height: units.gu(18) |
1326 | - visible: genrelist.count > 1 |
1327 | - model: SortFilterModel { |
1328 | - id: genresModelFilter |
1329 | - model: GenresModel { |
1330 | - id: genresModel |
1331 | - store: musicStore |
1332 | - } |
1333 | - filter.property: "genre" |
1334 | - filter.pattern: /\S+/ |
1335 | - } |
1336 | - |
1337 | - delegate: genreDelegate |
1338 | - header: Item { |
1339 | - id: genreSpacer |
1340 | - width: units.gu(1) |
1341 | - } |
1342 | - orientation: ListView.Horizontal |
1343 | - |
1344 | - Component { |
1345 | - id: genreDelegate |
1346 | - Item { |
1347 | - id: genreItem |
1348 | - objectName: "genreItemObject" |
1349 | - height: genrelist.height - units.gu(1) |
1350 | - width: height |
1351 | - |
1352 | - Repeater { |
1353 | - id: albumGenreModelRepeater |
1354 | - model: AlbumsModel { |
1355 | - genre: model.genre |
1356 | - store: musicStore |
1357 | - } |
1358 | - |
1359 | - delegate: Item { |
1360 | - property string art: model.art |
1361 | - } |
1362 | - property var covers: [] |
1363 | - signal finished() |
1364 | - |
1365 | - onFinished: { |
1366 | - genreShape.count = count |
1367 | - genreShape.covers = covers |
1368 | - } |
1369 | - onItemAdded: { |
1370 | - covers.push({art: item.art}); |
1371 | - |
1372 | - if (index === count - 1) { |
1373 | - finished(); |
1374 | - } |
1375 | - } |
1376 | - } |
1377 | - |
1378 | - SongsModel { |
1379 | - id: songGenreModel |
1380 | - genre: model.genre |
1381 | - store: musicStore |
1382 | - } |
1383 | - |
1384 | - CoverRow { |
1385 | - id: genreShape |
1386 | - anchors { |
1387 | - top: parent.top |
1388 | - left: parent.left |
1389 | - verticalCenter: parent.verticalCenter |
1390 | - } |
1391 | - count: 0 |
1392 | - size: genreItem.width |
1393 | - covers: [] |
1394 | - spacing: units.gu(2) |
1395 | - } |
1396 | - MouseArea { |
1397 | - anchors.fill: parent |
1398 | - onClicked: { |
1399 | - songsPage.album = undefined |
1400 | - songsPage.covers = genreShape.covers |
1401 | - songsPage.genre = model.genre |
1402 | - songsPage.isAlbum = true |
1403 | - songsPage.line1 = i18n.tr("Genre") |
1404 | - songsPage.line2 = model.genre |
1405 | - songsPage.title = i18n.tr("Genre") |
1406 | - |
1407 | - mainPageStack.push(songsPage) |
1408 | - } |
1409 | - |
1410 | - // TODO: If http://pad.lv/1354753 is fixed to expose whether the Shape should appear pressed, update this as well. |
1411 | - onPressedChanged: genreShape.pressed = pressed |
1412 | - } |
1413 | - Item { // Background so can see text in current state |
1414 | - id: genreBg |
1415 | - anchors { |
1416 | - bottom: parent.bottom |
1417 | - left: parent.left |
1418 | - right: parent.right |
1419 | - } |
1420 | - height: units.gu(5.5) |
1421 | - clip: true |
1422 | - UbuntuShape{ |
1423 | - anchors { |
1424 | - bottom: parent.bottom |
1425 | - left: parent.left |
1426 | - right: parent.right |
1427 | - } |
1428 | - height: genreShape.height |
1429 | - radius: "medium" |
1430 | - color: styleMusic.common.black |
1431 | - opacity: 0.6 |
1432 | - } |
1433 | - } |
1434 | - Label { |
1435 | - id: genreLabel |
1436 | - anchors.bottom: parent.bottom |
1437 | - anchors.bottomMargin: units.gu(1) |
1438 | - anchors.left: parent.left |
1439 | - anchors.leftMargin: units.gu(1) |
1440 | - anchors.right: parent.right |
1441 | - anchors.rightMargin: units.gu(1) |
1442 | - color: styleMusic.common.white |
1443 | - elide: Text.ElideRight |
1444 | - text: model.genre |
1445 | - fontSize: "small" |
1446 | - font.weight: Font.DemiBold |
1447 | - } |
1448 | - Label { |
1449 | - id: genreTotal |
1450 | - anchors.bottom: parent.bottom |
1451 | - anchors.bottomMargin: units.gu(3) |
1452 | - anchors.left: parent.left |
1453 | - anchors.leftMargin: units.gu(1) |
1454 | - anchors.right: parent.right |
1455 | - anchors.rightMargin: units.gu(1) |
1456 | - color: styleMusic.common.white |
1457 | - elide: Text.ElideRight |
1458 | - text: i18n.tr("%1 song", "%1 songs", songGenreModel.rowCount).arg(songGenreModel.rowCount) |
1459 | - fontSize: "x-small" |
1460 | - } |
1461 | - } |
1462 | - } |
1463 | - } |
1464 | - |
1465 | - ListItem.ThinDivider { |
1466 | - id: albumsDivider |
1467 | - anchors.top: genrelist.visible |
1468 | - ? genrelist.bottom |
1469 | - : (mainView.hasRecent ? recentlist.bottom : parent.top) |
1470 | - } |
1471 | - ListItem.Standard { |
1472 | - id: albums |
1473 | - Label { |
1474 | - anchors { |
1475 | - verticalCenter: parent.verticalCenter |
1476 | - left: parent.left |
1477 | - leftMargin: units.gu(2) |
1478 | - } |
1479 | - text: i18n.tr("Albums") |
1480 | - color: styleMusic.common.music |
1481 | - } |
1482 | - anchors.top: albumsDivider.bottom |
1483 | - } |
1484 | - |
1485 | - ListView { |
1486 | - id: albumlist |
1487 | - width: parent.width |
1488 | - anchors.top: albums.bottom |
1489 | - anchors.topMargin: units.gu(1) |
1490 | - spacing: units.gu(1) |
1491 | - height: units.gu(18) |
1492 | - model: SortFilterModel { |
1493 | - id: albumsModelFilter |
1494 | - property alias rowCount: albumsModel.rowCount |
1495 | - model: AlbumsModel { |
1496 | - id: albumsModel |
1497 | - store: musicStore |
1498 | - } |
1499 | - sort.property: "title" |
1500 | - sort.order: Qt.AscendingOrder |
1501 | - } |
1502 | - delegate: albumDelegate |
1503 | - header: Item { |
1504 | - id: albumSpacer |
1505 | - width: units.gu(1) |
1506 | - } |
1507 | - orientation: ListView.Horizontal |
1508 | - |
1509 | - Component { |
1510 | - id: albumDelegate |
1511 | - Item { |
1512 | - property string artist: model.artist |
1513 | - property string album: model.title |
1514 | - property var covers: [{art: model.art}] |
1515 | - |
1516 | - id: albumItem |
1517 | - objectName: "albumItemObject" |
1518 | - height: albumlist.height - units.gu(1) |
1519 | - width: height |
1520 | - CoverRow { |
1521 | - id: albumShape |
1522 | - anchors { |
1523 | - top: parent.top |
1524 | - left: parent.left |
1525 | - verticalCenter: parent.verticalCenter |
1526 | - } |
1527 | - count: albumItem.covers.length |
1528 | - size: albumItem.width |
1529 | - covers: albumItem.covers |
1530 | - spacing: units.gu(2) |
1531 | - } |
1532 | - MouseArea { |
1533 | - anchors.fill: parent |
1534 | - onClicked: { |
1535 | - songsPage.album = album |
1536 | - songsPage.covers = covers |
1537 | - songsPage.genre = undefined |
1538 | - songsPage.isAlbum = true |
1539 | - songsPage.line1 = artist |
1540 | - songsPage.line2 = album |
1541 | - songsPage.title = i18n.tr("Album") |
1542 | - |
1543 | - mainPageStack.push(songsPage) |
1544 | - } |
1545 | - |
1546 | - // TODO: If http://pad.lv/1354753 is fixed to expose whether the Shape should appear pressed, update this as well. |
1547 | - onPressedChanged: albumShape.pressed = pressed |
1548 | - } |
1549 | - Item { // Background so can see text in current state |
1550 | - id: albumBg |
1551 | - anchors { |
1552 | - bottom: parent.bottom |
1553 | - left: parent.left |
1554 | - right: parent.right |
1555 | - } |
1556 | - height: units.gu(6) |
1557 | - clip: true |
1558 | - UbuntuShape{ |
1559 | - anchors { |
1560 | - bottom: parent.bottom |
1561 | - left: parent.left |
1562 | - right: parent.right |
1563 | - } |
1564 | - height: albumShape.height |
1565 | - radius: "medium" |
1566 | - color: styleMusic.common.black |
1567 | - opacity: 0.6 |
1568 | - } |
1569 | - } |
1570 | - Label { |
1571 | - id: albumLabel |
1572 | - anchors.bottom: parent.bottom |
1573 | - anchors.bottomMargin: units.gu(1) |
1574 | - anchors.left: parent.left |
1575 | - anchors.leftMargin: units.gu(1) |
1576 | - anchors.right: parent.right |
1577 | - anchors.rightMargin: units.gu(1) |
1578 | - color: styleMusic.common.white |
1579 | - elide: Text.ElideRight |
1580 | - text: artist |
1581 | - fontSize: "x-small" |
1582 | - } |
1583 | - Label { |
1584 | - id: albumLabel2 |
1585 | - anchors.bottom: parent.bottom |
1586 | - anchors.bottomMargin: units.gu(3) |
1587 | - anchors.left: parent.left |
1588 | - anchors.leftMargin: units.gu(1) |
1589 | - anchors.right: parent.right |
1590 | - anchors.rightMargin: units.gu(1) |
1591 | - color: styleMusic.common.white |
1592 | - elide: Text.ElideRight |
1593 | - text: album |
1594 | - fontSize: "small" |
1595 | - font.weight: Font.DemiBold |
1596 | - } |
1597 | - } |
1598 | + |
1599 | + CardView { |
1600 | + id: recentCardView |
1601 | + model: recentModel.model |
1602 | + delegate: Card { |
1603 | + id: albumCard |
1604 | + coverSources: model.type === "playlist" ? Playlists.getPlaylistCovers(title) : (model.art !== undefined ? [{art: model.art}] : [{author: model.title2, album: model.title}]) |
1605 | + objectName: "albumsPageGridItem" + index |
1606 | + primaryText: model.title |
1607 | + secondaryText: model.title2 !== "Playlist" ? model.title2 : i18n.tr("Playlist") |
1608 | + |
1609 | + onClicked: { |
1610 | + if (type === "playlist") { |
1611 | + albumTracksModel.filterPlaylistTracks(model.key) |
1612 | + } else { |
1613 | + songsPage.album = title; |
1614 | + } |
1615 | + songsPage.genre = undefined; |
1616 | + |
1617 | + songsPage.line1 = secondaryText |
1618 | + songsPage.line2 = primaryText |
1619 | + songsPage.covers = coverSources |
1620 | + songsPage.isAlbum = (type === "album") |
1621 | + songsPage.title = songsPage.isAlbum ? i18n.tr("Album") : i18n.tr("Playlist") |
1622 | + |
1623 | + mainPageStack.push(songsPage) |
1624 | } |
1625 | } |
1626 | } |
1627 | |
1628 | === modified file 'MusicToolbar.qml' |
1629 | --- MusicToolbar.qml 2014-09-23 20:45:41 +0000 |
1630 | +++ MusicToolbar.qml 2014-10-21 15:31:33 +0000 |
1631 | @@ -22,6 +22,7 @@ |
1632 | import QtMultimedia 5.0 |
1633 | import Ubuntu.Components 1.1 |
1634 | import Ubuntu.Components.Popups 1.0 |
1635 | +import "common" |
1636 | import "settings.js" as Settings |
1637 | |
1638 | Item { |
1639 | @@ -35,59 +36,13 @@ |
1640 | property var currentPage: null |
1641 | property var currentSheet: [] |
1642 | property var currentTab: null |
1643 | - property var previousPage: null |
1644 | |
1645 | // Properties and signals for the toolbar |
1646 | - property var cachedStates: [] |
1647 | - property bool shown: false |
1648 | - property int transitionDuration: 100 |
1649 | - |
1650 | property alias currentHeight: musicToolbarPanel.height |
1651 | - property alias minimizedHeight: musicToolbarPanel.minimizedHeight |
1652 | - property alias expandedHeight: musicToolbarPanel.expandedHeight |
1653 | - property alias fullHeight: musicToolbarPanel.fullHeight |
1654 | - property alias mouseAreaOffset: musicToolbarPanel.hintSize |
1655 | - |
1656 | - property alias animating: musicToolbarPanel.animating |
1657 | property alias opened: musicToolbarPanel.opened |
1658 | |
1659 | - // Alias for autopilot |
1660 | - property alias currentMode: musicToolbarPanel.currentMode |
1661 | - |
1662 | - Connections { |
1663 | - id: pageStackConn |
1664 | - target: mainPageStack |
1665 | - |
1666 | - onCurrentPageChanged: { |
1667 | - previousPage = currentPage; |
1668 | - |
1669 | - // If going back from nowPlaying jump back to tabs |
1670 | - if (previousPage === nowPlaying && mainPageStack.currentPage !== nowPlaying) { |
1671 | - while (mainPageStack.depth > 1) { |
1672 | - mainPageStack.pop(mainPageStack.currentPage) |
1673 | - } |
1674 | - } |
1675 | - } |
1676 | - } |
1677 | - |
1678 | /* Helper functions */ |
1679 | |
1680 | - // Disable the toolbar for this page/view (eg a dialog) |
1681 | - function disableToolbar() |
1682 | - { |
1683 | - cachedStates.push(state); |
1684 | - musicToolbarPanel.state = "hidden"; |
1685 | - } |
1686 | - |
1687 | - // Enable the toolbar (run when closing a page that disabled it) |
1688 | - function enableToolbar() |
1689 | - { |
1690 | - if (cachedStates.length > 0) |
1691 | - { |
1692 | - musicToolbarPanel.state = cachedStates.pop(); |
1693 | - } |
1694 | - } |
1695 | - |
1696 | // Back button has been pressed, jump up pageStack or back to parent page |
1697 | function goBack() |
1698 | { |
1699 | @@ -98,18 +53,6 @@ |
1700 | else if (mainPageStack !== null && mainPageStack.depth > 1) { |
1701 | mainPageStack.pop(currentPage) |
1702 | } |
1703 | - |
1704 | - startAutohideTimer() |
1705 | - } |
1706 | - |
1707 | - // Hide the toolbar |
1708 | - function hideToolbar() |
1709 | - { |
1710 | - if (!wideAspect) { |
1711 | - musicToolbarPanel.close(); |
1712 | - } |
1713 | - |
1714 | - toolbarAutoHideTimer.stop(); // cancel any autohide |
1715 | } |
1716 | |
1717 | // Remove sheet as it has been closed |
1718 | @@ -126,8 +69,6 @@ |
1719 | function setPage(childPage) |
1720 | { |
1721 | currentPage = childPage; |
1722 | - // note: If pageStack tracking is needed readd here |
1723 | - //currentPageStack = pageStack === undefined ? null : pageStack; |
1724 | } |
1725 | |
1726 | // Set the current sheet (overrides page) |
1727 | @@ -135,32 +76,6 @@ |
1728 | currentSheet.push(sheet) |
1729 | } |
1730 | |
1731 | - // Show the toolbar |
1732 | - function showToolbar() |
1733 | - { |
1734 | - startAutohideTimer(); // always attempt to autohide toolbar |
1735 | - |
1736 | - if (!musicToolbarPanel.opened) { |
1737 | - musicToolbarPanel.open(); |
1738 | - } |
1739 | - } |
1740 | - |
1741 | - // Start the autohidetimer |
1742 | - function startAutohideTimer() |
1743 | - { |
1744 | - toolbarAutoHideTimer.restart(); |
1745 | - } |
1746 | - |
1747 | - Connections { |
1748 | - target: mainView |
1749 | - onWideAspectChanged: { |
1750 | - // Force toolbar to show if in wideAspect |
1751 | - if (wideAspect && !opened) { |
1752 | - showToolbar(); |
1753 | - } |
1754 | - } |
1755 | - } |
1756 | - |
1757 | Panel { |
1758 | id: musicToolbarPanel |
1759 | anchors { |
1760 | @@ -168,543 +83,9 @@ |
1761 | right: parent.right |
1762 | bottom: parent.bottom |
1763 | } |
1764 | - height: currentMode === "full" ? fullHeight : expandedHeight |
1765 | - locked: wideAspect |
1766 | - |
1767 | - __closeOnContentsClicks: false // TODO: fix bug 1295720 |
1768 | - |
1769 | - // The current mode of the controls |
1770 | - property string currentMode: wideAspect || (currentPage === nowPlaying) |
1771 | - ? "full" : "expanded" |
1772 | - |
1773 | - // Properties for the different heights |
1774 | - property int minimizedHeight: units.gu(0.5) |
1775 | - property int expandedHeight: units.gu(8) |
1776 | - property int fullHeight: units.gu(11) |
1777 | - |
1778 | - onCurrentModeChanged: { |
1779 | - musicToolbarFullProgressMouseArea.enabled = currentMode === "full" |
1780 | - } |
1781 | - |
1782 | - onOpenedChanged: { |
1783 | - onToolbarShownChanged(opened, currentPage, currentTab); |
1784 | - |
1785 | - if (opened) { |
1786 | - startAutohideTimer(); |
1787 | - } |
1788 | - } |
1789 | - |
1790 | - /* Full toolbar */ |
1791 | - Rectangle { |
1792 | - id: musicToolbarFullContainer |
1793 | - anchors { |
1794 | - fill: parent |
1795 | - } |
1796 | - color: styleMusic.toolbar.fullBackgroundColor |
1797 | - visible: musicToolbarPanel.currentMode === "full" |
1798 | - |
1799 | - /* Buttons component */ |
1800 | - Rectangle { |
1801 | - id: musicToolbarFullButtonsContainer |
1802 | - anchors.left: parent.left |
1803 | - anchors.top: musicToolbarFullProgressContainer.bottom |
1804 | - color: "transparent" |
1805 | - height: parent.height - musicToolbarFullProgressContainer.height |
1806 | - width: parent.width |
1807 | - |
1808 | - /* Column for labels in wideAspect */ |
1809 | - Column { |
1810 | - id: nowPlayingWideAspectLabels |
1811 | - anchors { |
1812 | - left: parent.left |
1813 | - leftMargin: units.gu(1) |
1814 | - right: nowPlayingRepeatButton.left |
1815 | - rightMargin: units.gu(1) |
1816 | - verticalCenter: parent.verticalCenter |
1817 | - } |
1818 | - visible: wideAspect |
1819 | - |
1820 | - /* Clicking in the area shows the queue */ |
1821 | - function trigger() { |
1822 | - if (trackQueue.model.count !== 0 && currentPage !== nowPlaying) { |
1823 | - tabs.pushNowPlaying(); |
1824 | - } |
1825 | - else if (currentPage === nowPlaying) { |
1826 | - musicToolbar.goBack(); |
1827 | - } |
1828 | - } |
1829 | - |
1830 | - /* Title of track */ |
1831 | - Label { |
1832 | - id: nowPlayingWideAspectTitle |
1833 | - anchors { |
1834 | - left: parent.left |
1835 | - leftMargin: units.gu(1) |
1836 | - right: parent.right |
1837 | - rightMargin: units.gu(1) |
1838 | - } |
1839 | - color: styleMusic.playerControls.labelColor |
1840 | - elide: Text.ElideRight |
1841 | - fontSize: "medium" |
1842 | - objectName: "playercontroltitle" |
1843 | - text: trackQueue.model.count === 0 ? "" : player.currentMetaTitle === "" ? player.currentMetaFile : player.currentMetaTitle |
1844 | - } |
1845 | - |
1846 | - /* Artist of track */ |
1847 | - Label { |
1848 | - id: nowPlayingWideAspectArtist |
1849 | - anchors { |
1850 | - left: parent.left |
1851 | - leftMargin: units.gu(1) |
1852 | - right: parent.right |
1853 | - rightMargin: units.gu(1) |
1854 | - } |
1855 | - color: styleMusic.playerControls.labelColor |
1856 | - elide: Text.ElideRight |
1857 | - fontSize: "small" |
1858 | - text: trackQueue.model.count === 0 ? "" : player.currentMetaArtist |
1859 | - } |
1860 | - |
1861 | - /* Album of track */ |
1862 | - Label { |
1863 | - id: nowPlayingWideAspectAlbum |
1864 | - anchors { |
1865 | - left: parent.left |
1866 | - leftMargin: units.gu(1) |
1867 | - right: parent.right |
1868 | - rightMargin: units.gu(1) |
1869 | - } |
1870 | - color: styleMusic.playerControls.labelColor |
1871 | - elide: Text.ElideRight |
1872 | - fontSize: "small" |
1873 | - text: trackQueue.model.count === 0 ? "" : player.currentMetaAlbum |
1874 | - } |
1875 | - } |
1876 | - |
1877 | - /* Repeat button */ |
1878 | - Item { |
1879 | - id: nowPlayingRepeatButton |
1880 | - objectName: "repeatShape" |
1881 | - anchors.right: nowPlayingPreviousButton.left |
1882 | - anchors.rightMargin: units.gu(1) |
1883 | - anchors.verticalCenter: parent.verticalCenter |
1884 | - height: units.gu(6) |
1885 | - opacity: player.repeat && !emptyPage.noMusic ? 1 : .4 |
1886 | - width: height |
1887 | - |
1888 | - function trigger() { |
1889 | - if (emptyPage.noMusic) { |
1890 | - return; |
1891 | - } |
1892 | - |
1893 | - // Invert repeat settings |
1894 | - player.repeat = !player.repeat |
1895 | - } |
1896 | - |
1897 | - Image { |
1898 | - id: repeatIcon |
1899 | - height: units.gu(3) |
1900 | - width: height |
1901 | - anchors.verticalCenter: parent.verticalCenter |
1902 | - anchors.horizontalCenter: parent.horizontalCenter |
1903 | - source: Qt.resolvedUrl("images/media-playlist-repeat.svg") |
1904 | - verticalAlignment: Text.AlignVCenter |
1905 | - opacity: player.repeat && !emptyPage.noMusic ? 1 : .4 |
1906 | - } |
1907 | - } |
1908 | - |
1909 | - /* Previous button */ |
1910 | - Item { |
1911 | - id: nowPlayingPreviousButton |
1912 | - anchors.right: nowPlayingPlayButton.left |
1913 | - anchors.rightMargin: units.gu(1) |
1914 | - anchors.verticalCenter: parent.verticalCenter |
1915 | - height: units.gu(6) |
1916 | - objectName: "previousShape" |
1917 | - opacity: trackQueue.model.count === 0 ? .4 : 1 |
1918 | - width: height |
1919 | - |
1920 | - function trigger() { |
1921 | - if (trackQueue.model.count === 0) { |
1922 | - return; |
1923 | - } |
1924 | - |
1925 | - player.previousSong() |
1926 | - } |
1927 | - |
1928 | - Image { |
1929 | - id: nowPlayingPreviousIndicator |
1930 | - height: units.gu(3) |
1931 | - width: height |
1932 | - anchors.horizontalCenter: parent.horizontalCenter |
1933 | - anchors.verticalCenter: parent.verticalCenter |
1934 | - source: Qt.resolvedUrl("images/media-skip-backward.svg") |
1935 | - opacity: 1 |
1936 | - } |
1937 | - } |
1938 | - |
1939 | - /* Play/Pause button */ |
1940 | - Rectangle { |
1941 | - id: nowPlayingPlayButton |
1942 | - anchors.horizontalCenter: parent.horizontalCenter |
1943 | - anchors.verticalCenter: parent.verticalCenter |
1944 | - antialiasing: true |
1945 | - color: styleMusic.toolbar.fullOuterPlayCircleColor |
1946 | - height: units.gu(12) |
1947 | - radius: height / 2 |
1948 | - width: height |
1949 | - |
1950 | - // draws the outter shadow/highlight |
1951 | - Rectangle { |
1952 | - id: sourceOutterFull |
1953 | - anchors { fill: parent; margins: -units.gu(0.1) } |
1954 | - radius: (width / 2) |
1955 | - antialiasing: true |
1956 | - gradient: Gradient { |
1957 | - GradientStop { position: 0.0; color: "black" } |
1958 | - GradientStop { position: 0.5; color: "transparent" } |
1959 | - GradientStop { position: 1.0; color: UbuntuColors.warmGrey } |
1960 | - } |
1961 | - |
1962 | - Rectangle { |
1963 | - anchors.horizontalCenter: parent.horizontalCenter |
1964 | - anchors.verticalCenter: parent.verticalCenter |
1965 | - antialiasing: true |
1966 | - color: styleMusic.toolbar.fullOuterPlayCircleColor |
1967 | - height: nowPlayingPlayButton.height - units.gu(.1) |
1968 | - radius: height / 2 |
1969 | - width: height |
1970 | - |
1971 | - Rectangle { |
1972 | - id: nowPlayingPlayButtonInner |
1973 | - anchors.horizontalCenter: parent.horizontalCenter |
1974 | - anchors.verticalCenter: parent.verticalCenter |
1975 | - antialiasing: true |
1976 | - color: styleMusic.toolbar.fullInnerPlayCircleColor |
1977 | - height: units.gu(7) |
1978 | - radius: height / 2 |
1979 | - width: height |
1980 | - |
1981 | - // draws the inner shadow/highlight |
1982 | - Rectangle { |
1983 | - id: sourceInnerFull |
1984 | - anchors { fill: parent; margins: -units.gu(0.1) } |
1985 | - radius: (width / 2) |
1986 | - antialiasing: true |
1987 | - gradient: Gradient { |
1988 | - GradientStop { position: 0.0; color: UbuntuColors.warmGrey } |
1989 | - GradientStop { position: 0.5; color: "transparent" } |
1990 | - GradientStop { position: 1.0; color: "black" } |
1991 | - } |
1992 | - |
1993 | - Rectangle { |
1994 | - anchors.horizontalCenter: parent.horizontalCenter |
1995 | - anchors.verticalCenter: parent.verticalCenter |
1996 | - antialiasing: true |
1997 | - color: styleMusic.toolbar.fullInnerPlayCircleColor |
1998 | - height: nowPlayingPlayButtonInner.height - units.gu(.1) |
1999 | - objectName: "playShape" |
2000 | - radius: height / 2 |
2001 | - width: height |
2002 | - |
2003 | - function trigger() { |
2004 | - if (emptyPage.noMusic) { |
2005 | - return; |
2006 | - } |
2007 | - |
2008 | - if (trackQueue.model.count === 0) { |
2009 | - playRandomSong(); |
2010 | - } |
2011 | - else { |
2012 | - player.toggle(); |
2013 | - } |
2014 | - } |
2015 | - |
2016 | - Image { |
2017 | - id: nowPlayingPlayIndicator |
2018 | - height: units.gu(6) |
2019 | - width: height |
2020 | - anchors.horizontalCenter: parent.horizontalCenter |
2021 | - anchors.verticalCenter: parent.verticalCenter |
2022 | - opacity: emptyPage.noMusic ? .4 : 1 |
2023 | - source: player.playbackState === MediaPlayer.PlayingState ? |
2024 | - Qt.resolvedUrl("images/media-playback-pause.svg") : Qt.resolvedUrl("images/media-playback-start.svg") |
2025 | - } |
2026 | - } |
2027 | - } |
2028 | - } |
2029 | - } |
2030 | - } |
2031 | - } |
2032 | - |
2033 | - /* Next button */ |
2034 | - Item { |
2035 | - id: nowPlayingNextButton |
2036 | - anchors.left: nowPlayingPlayButton.right |
2037 | - anchors.leftMargin: units.gu(1) |
2038 | - anchors.verticalCenter: parent.verticalCenter |
2039 | - height: units.gu(6) |
2040 | - objectName: "forwardShape" |
2041 | - opacity: trackQueue.model.count === 0 ? .4 : 1 |
2042 | - width: height |
2043 | - |
2044 | - function trigger() { |
2045 | - if (trackQueue.model.count === 0 || emptyPage.noMusic) { |
2046 | - return; |
2047 | - } |
2048 | - |
2049 | - player.nextSong() |
2050 | - } |
2051 | - |
2052 | - Image { |
2053 | - id: nowPlayingNextIndicator |
2054 | - height: units.gu(3) |
2055 | - width: height |
2056 | - anchors.horizontalCenter: parent.horizontalCenter |
2057 | - anchors.verticalCenter: parent.verticalCenter |
2058 | - source: Qt.resolvedUrl("images/media-skip-forward.svg") |
2059 | - opacity: 1 |
2060 | - } |
2061 | - } |
2062 | - |
2063 | - /* Shuffle button */ |
2064 | - Item { |
2065 | - id: nowPlayingShuffleButton |
2066 | - objectName: "shuffleShape" |
2067 | - anchors.left: nowPlayingNextButton.right |
2068 | - anchors.leftMargin: units.gu(1) |
2069 | - anchors.verticalCenter: parent.verticalCenter |
2070 | - height: units.gu(6) |
2071 | - opacity: player.shuffle && !emptyPage.noMusic ? 1 : .4 |
2072 | - width: height |
2073 | - |
2074 | - function trigger() { |
2075 | - if (emptyPage.noMusic) { |
2076 | - return; |
2077 | - } |
2078 | - |
2079 | - // Invert shuffle settings |
2080 | - player.shuffle = !player.shuffle |
2081 | - } |
2082 | - |
2083 | - Image { |
2084 | - id: shuffleIcon |
2085 | - height: units.gu(3) |
2086 | - width: height |
2087 | - anchors.verticalCenter: parent.verticalCenter |
2088 | - anchors.horizontalCenter: parent.horizontalCenter |
2089 | - source: Qt.resolvedUrl("images/media-playlist-shuffle.svg") |
2090 | - opacity: player.shuffle && !emptyPage.noMusic ? 1 : .4 |
2091 | - } |
2092 | - } |
2093 | - |
2094 | - /* Search button in wideAspect */ |
2095 | - Item { |
2096 | - id: nowPlayingSearchButton |
2097 | - objectName: "searchShape" |
2098 | - anchors { |
2099 | - right: parent.right |
2100 | - rightMargin: units.gu(1) |
2101 | - verticalCenter: parent.verticalCenter |
2102 | - } |
2103 | - height: units.gu(6) |
2104 | - opacity: !emptyPage.noMusic ? 1 : .4 |
2105 | - width: height |
2106 | - visible: wideAspect |
2107 | - |
2108 | - function trigger() { |
2109 | - if (emptyPage.noMusic) { |
2110 | - return; |
2111 | - } |
2112 | - |
2113 | - if (!searchSheet.sheetVisible) { |
2114 | - PopupUtils.open(searchSheet.sheet, |
2115 | - mainView, { title: i18n.tr("Search")} ) |
2116 | - } |
2117 | - } |
2118 | - |
2119 | - Image { |
2120 | - id: searchIcon |
2121 | - anchors { |
2122 | - horizontalCenter: parent.horizontalCenter |
2123 | - verticalCenter: parent.verticalCenter |
2124 | - } |
2125 | - height: units.gu(3) |
2126 | - opacity: !emptyPage.noMusic ? 1 : .4 |
2127 | - source: Qt.resolvedUrl("images/search.svg") |
2128 | - width: height |
2129 | - } |
2130 | - } |
2131 | - } |
2132 | - |
2133 | - /* Progress bar component */ |
2134 | - Rectangle { |
2135 | - id: musicToolbarFullProgressContainer |
2136 | - anchors.left: parent.left |
2137 | - anchors.top: parent.top |
2138 | - color: styleMusic.toolbar.fullBackgroundColor |
2139 | - height: units.gu(3) |
2140 | - width: parent.width |
2141 | - |
2142 | - /* Position label */ |
2143 | - Label { |
2144 | - id: musicToolbarFullPositionLabel |
2145 | - anchors.left: parent.left |
2146 | - anchors.leftMargin: units.gu(2) |
2147 | - anchors.top: parent.top |
2148 | - color: styleMusic.nowPlaying.labelColor |
2149 | - fontSize: "x-small" |
2150 | - height: parent.height |
2151 | - horizontalAlignment: Text.AlignHCenter |
2152 | - text: durationToString(player.position) |
2153 | - verticalAlignment: Text.AlignVCenter |
2154 | - width: units.gu(3) |
2155 | - } |
2156 | - |
2157 | - /* Progress bar */ |
2158 | - Rectangle { |
2159 | - id: musicToolbarFullProgressBarContainer |
2160 | - objectName: "progressBarShape" |
2161 | - anchors.left: musicToolbarFullPositionLabel.right |
2162 | - anchors.leftMargin: units.gu(2) |
2163 | - anchors.right: musicToolbarFullDurationLabel.left |
2164 | - anchors.rightMargin: units.gu(2) |
2165 | - anchors.verticalCenter: parent.verticalCenter |
2166 | - color: "transparent" |
2167 | - height: units.gu(1); |
2168 | - state: trackQueue.model.count === 0 ? "disabled" : "enabled" |
2169 | - |
2170 | - states: [ |
2171 | - State { |
2172 | - name: "disabled" |
2173 | - PropertyChanges { |
2174 | - target: musicToolbarFullProgressMouseArea |
2175 | - enabled: false |
2176 | - } |
2177 | - PropertyChanges { |
2178 | - target: musicToolbarFullProgressTrough |
2179 | - visible: false |
2180 | - } |
2181 | - PropertyChanges { |
2182 | - target: musicToolbarFullProgressHandle |
2183 | - visible: false |
2184 | - } |
2185 | - }, |
2186 | - State { |
2187 | - name: "enabled" |
2188 | - PropertyChanges { |
2189 | - target: musicToolbarFullProgressMouseArea |
2190 | - enabled: true |
2191 | - } |
2192 | - PropertyChanges { |
2193 | - target: musicToolbarFullProgressTrough |
2194 | - visible: true |
2195 | - } |
2196 | - PropertyChanges { |
2197 | - target: musicToolbarFullProgressHandle |
2198 | - visible: true |
2199 | - } |
2200 | - } |
2201 | - ] |
2202 | - |
2203 | - property bool seeking: false |
2204 | - |
2205 | - onSeekingChanged: { |
2206 | - if (seeking === false) { |
2207 | - musicToolbarFullPositionLabel.text = durationToString(player.position) |
2208 | - } |
2209 | - } |
2210 | - |
2211 | - Connections { |
2212 | - target: player |
2213 | - onDurationChanged: { |
2214 | - console.debug("Duration changed: " + player.duration) |
2215 | - musicToolbarFullDurationLabel.text = durationToString(player.duration) |
2216 | - } |
2217 | - onPositionChanged: { |
2218 | - if (musicToolbarFullProgressBarContainer.seeking === false) |
2219 | - { |
2220 | - musicToolbarFullPositionLabel.text = durationToString(player.position) |
2221 | - musicToolbarFullDurationLabel.text = durationToString(player.duration) |
2222 | - musicToolbarFullProgressHandle.x = (player.position / player.duration) * musicToolbarFullProgressBarContainer.width |
2223 | - - musicToolbarFullProgressHandle.width / 2; |
2224 | - } |
2225 | - } |
2226 | - onStopped: { |
2227 | - musicToolbarFullProgressHandle.x = -musicToolbarFullProgressHandle.width / 2; |
2228 | - |
2229 | - musicToolbarFullPositionLabel.text = durationToString(0); |
2230 | - musicToolbarFullDurationLabel.text = durationToString(0); |
2231 | - } |
2232 | - } |
2233 | - |
2234 | - // Black background behind the progress bar |
2235 | - Rectangle { |
2236 | - id: musicToolbarFullProgressBackground |
2237 | - anchors.verticalCenter: parent.verticalCenter; |
2238 | - color: styleMusic.toolbar.fullProgressBackgroundColor; |
2239 | - height: parent.height; |
2240 | - radius: units.gu(0.5) |
2241 | - width: parent.width; |
2242 | - } |
2243 | - |
2244 | - // The orange fill of the progress bar |
2245 | - Rectangle { |
2246 | - id: musicToolbarFullProgressTrough |
2247 | - anchors.verticalCenter: parent.verticalCenter; |
2248 | - antialiasing: true |
2249 | - color: styleMusic.toolbar.fullProgressTroughColor; |
2250 | - height: parent.height; |
2251 | - radius: units.gu(0.5) |
2252 | - width: musicToolbarFullProgressHandle.x + (height / 2); // +radius |
2253 | - } |
2254 | - |
2255 | - // The current position (handle) of the progress bar |
2256 | - Rectangle { |
2257 | - id: musicToolbarFullProgressHandle |
2258 | - anchors.verticalCenter: musicToolbarFullProgressBackground.verticalCenter |
2259 | - antialiasing: true |
2260 | - color: styleMusic.nowPlaying.progressHandleColor |
2261 | - height: units.gu(1.5) |
2262 | - radius: height / 2 |
2263 | - width: height |
2264 | - |
2265 | - // On X change update the position string |
2266 | - onXChanged: { |
2267 | - if (musicToolbarFullProgressBarContainer.seeking) { |
2268 | - var fraction = (x + (width / 2)) / parent.width; |
2269 | - musicToolbarFullPositionLabel.text = durationToString(fraction * player.duration) |
2270 | - } |
2271 | - } |
2272 | - } |
2273 | - } |
2274 | - |
2275 | - /* Duration label */ |
2276 | - Label { |
2277 | - id: musicToolbarFullDurationLabel |
2278 | - anchors.right: parent.right |
2279 | - anchors.rightMargin: units.gu(2) |
2280 | - anchors.top: parent.top |
2281 | - color: styleMusic.nowPlaying.labelColor |
2282 | - fontSize: "x-small" |
2283 | - height: parent.height |
2284 | - horizontalAlignment: Text.AlignHCenter |
2285 | - text: durationToString(player.duration) |
2286 | - verticalAlignment: Text.AlignVCenter |
2287 | - width: units.gu(3) |
2288 | - } |
2289 | - |
2290 | - /* Border at the bottom */ |
2291 | - Rectangle { |
2292 | - anchors.bottom: parent.bottom |
2293 | - anchors.left: parent.left |
2294 | - anchors.right: parent.right |
2295 | - color: styleMusic.common.white |
2296 | - height: units.gu(0.1) |
2297 | - opacity: 0.1 |
2298 | - } |
2299 | - } |
2300 | - } |
2301 | + height: units.gu(7.25) |
2302 | + locked: true |
2303 | + opened: true |
2304 | |
2305 | /* Expanded toolbar */ |
2306 | Rectangle { |
2307 | @@ -713,12 +94,13 @@ |
2308 | fill: parent |
2309 | } |
2310 | color: "transparent" |
2311 | - visible: musicToolbarPanel.currentMode === "expanded" |
2312 | |
2313 | Rectangle { |
2314 | id: musicToolbarPlayerControls |
2315 | - anchors.fill: parent |
2316 | - color: styleMusic.playerControls.backgroundColor |
2317 | + anchors { |
2318 | + fill: parent |
2319 | + } |
2320 | + color: "#000" |
2321 | state: trackQueue.model.count === 0 ? "disabled" : "enabled" |
2322 | states: [ |
2323 | State { |
2324 | @@ -745,39 +127,55 @@ |
2325 | } |
2326 | ] |
2327 | |
2328 | + /* Disabled (empty state) controls */ |
2329 | Rectangle { |
2330 | id: disabledPlayerControlsGroup |
2331 | - anchors.fill: parent |
2332 | + anchors { |
2333 | + bottom: playerControlsProgressBar.top |
2334 | + left: parent.left |
2335 | + right: parent.right |
2336 | + top: parent.top |
2337 | + } |
2338 | color: "transparent" |
2339 | - visible: trackQueue.model.count === 0 |
2340 | |
2341 | Label { |
2342 | id: noSongsInQueueLabel |
2343 | anchors { |
2344 | left: parent.left |
2345 | + leftMargin: units.gu(2) |
2346 | right: disabledPlayerControlsPlayButton.left |
2347 | - margins: units.gu(1) |
2348 | - top: parent.top |
2349 | + rightMargin: units.gu(2) |
2350 | + verticalCenter: parent.verticalCenter |
2351 | } |
2352 | color: styleMusic.playerControls.labelColor |
2353 | - text: i18n.tr("Tap play to shuffle music") |
2354 | + text: i18n.tr("Tap to shuffle music") |
2355 | fontSize: "large" |
2356 | wrapMode: Text.WordWrap |
2357 | maximumLineCount: 2 |
2358 | } |
2359 | |
2360 | - Rectangle { |
2361 | + /* Play/Pause button */ |
2362 | + Icon { |
2363 | id: disabledPlayerControlsPlayButton |
2364 | - anchors.right: parent.right |
2365 | - anchors.rightMargin: units.gu(1) |
2366 | - anchors.verticalCenter: parent.verticalCenter |
2367 | - antialiasing: true |
2368 | - color: "#444" |
2369 | - height: units.gu(7) |
2370 | - radius: height / 2 |
2371 | + anchors { |
2372 | + right: parent.right |
2373 | + rightMargin: units.gu(3) |
2374 | + verticalCenter: parent.verticalCenter |
2375 | + } |
2376 | + color: "#FFF" |
2377 | + height: units.gu(2.5) |
2378 | + name: player.playbackState === MediaPlayer.PlayingState ? |
2379 | + "media-playback-pause" : "media-playback-start" |
2380 | + objectName: "disabledSmallPlayShape" |
2381 | width: height |
2382 | + } |
2383 | |
2384 | - function trigger() { |
2385 | + /* Click to shuffle music */ |
2386 | + MouseArea { |
2387 | + anchors { |
2388 | + fill: parent |
2389 | + } |
2390 | + onClicked: { |
2391 | if (emptyPage.noMusic) { |
2392 | return; |
2393 | } |
2394 | @@ -789,230 +187,54 @@ |
2395 | player.toggle(); |
2396 | } |
2397 | } |
2398 | - |
2399 | - // draws the outer shadow/highlight |
2400 | - Rectangle { |
2401 | - id: disabledSourceOutter |
2402 | - anchors { fill: parent; margins: -units.gu(0.1) } |
2403 | - radius: (width / 2) |
2404 | - antialiasing: true |
2405 | - gradient: Gradient { |
2406 | - GradientStop { position: 0.0; color: "black" } |
2407 | - GradientStop { position: 0.5; color: "transparent" } |
2408 | - GradientStop { position: 1.0; color: UbuntuColors.warmGrey } |
2409 | - } |
2410 | - |
2411 | - Rectangle { |
2412 | - anchors.verticalCenter: parent.verticalCenter |
2413 | - anchors.horizontalCenter: parent.horizontalCenter |
2414 | - antialiasing: true |
2415 | - color: "#444" |
2416 | - height: playerControlsPlayButton.height - units.gu(.1) |
2417 | - radius: height / 2 |
2418 | - width: height |
2419 | - |
2420 | - Rectangle { |
2421 | - id: disabledPlayerControlsPlayInnerCircle |
2422 | - anchors.horizontalCenter: parent.horizontalCenter |
2423 | - anchors.verticalCenter: parent.verticalCenter |
2424 | - antialiasing: true |
2425 | - height: units.gu(4.5) |
2426 | - radius: height / 2 |
2427 | - width: height |
2428 | - color: styleMusic.toolbar.fullInnerPlayCircleColor |
2429 | - |
2430 | - // draws the inner shadow/highlight |
2431 | - Rectangle { |
2432 | - id: disabledSourceInner |
2433 | - anchors { fill: parent; margins: -units.gu(0.1) } |
2434 | - radius: (width / 2) |
2435 | - antialiasing: true |
2436 | - gradient: Gradient { |
2437 | - GradientStop { position: 0.0; color: UbuntuColors.warmGrey } |
2438 | - GradientStop { position: 0.5; color: "transparent" } |
2439 | - GradientStop { position: 1.0; color: "black" } |
2440 | - } |
2441 | - |
2442 | - Rectangle { |
2443 | - anchors.verticalCenter: parent.verticalCenter |
2444 | - anchors.horizontalCenter: parent.horizontalCenter |
2445 | - antialiasing: true |
2446 | - height: playerControlsPlayInnerCircle.height - units.gu(.1) |
2447 | - radius: height / 2 |
2448 | - width: height |
2449 | - color: styleMusic.toolbar.fullInnerPlayCircleColor |
2450 | - |
2451 | - Image { |
2452 | - id: disabledPlayIndicator |
2453 | - height: units.gu(4) |
2454 | - width: height |
2455 | - anchors.horizontalCenter: parent.horizontalCenter |
2456 | - anchors.verticalCenter: parent.verticalCenter |
2457 | - opacity: emptyPage.noMusic ? .4 : 1 |
2458 | - source: player.playbackState === MediaPlayer.PlayingState ? |
2459 | - Qt.resolvedUrl("images/media-playback-pause.svg") : Qt.resolvedUrl("images/media-playback-start.svg") |
2460 | - } |
2461 | - } |
2462 | - } |
2463 | - } |
2464 | - } |
2465 | - } |
2466 | } |
2467 | } |
2468 | |
2469 | + /* Enabled (queue > 0) controls */ |
2470 | Rectangle { |
2471 | id: enabledPlayerControlsGroup |
2472 | - anchors.fill: parent |
2473 | + anchors { |
2474 | + bottom: playerControlsProgressBar.top |
2475 | + left: parent.left |
2476 | + right: parent.right |
2477 | + top: parent.top |
2478 | + } |
2479 | color: "transparent" |
2480 | - visible: trackQueue.model.count !== 0 |
2481 | - |
2482 | - /* Settings button */ |
2483 | - // TODO: Enable settings when it is practical |
2484 | - /* Rectangle { |
2485 | - id: playerControlsSettings |
2486 | - anchors.right: parent.right |
2487 | - anchors.verticalCenter: parent.verticalCenter |
2488 | - width: units.gu(6) |
2489 | - height: width |
2490 | - color: "transparent" |
2491 | - |
2492 | - Image { |
2493 | - anchors.horizontalCenter: parent.horizontalCenter |
2494 | - anchors.verticalCenter: parent.verticalCenter |
2495 | - height: units.gu(3) |
2496 | - source: Qt.resolvedUrl("images/settings.png") |
2497 | - width: height |
2498 | - } |
2499 | - |
2500 | - MouseArea { |
2501 | - anchors.fill: parent |
2502 | - onClicked: { |
2503 | - console.debug('Debug: Show settings') |
2504 | - PopupUtils.open(Qt.resolvedUrl("MusicSettings.qml"), mainView, |
2505 | - { |
2506 | - title: i18n.tr("Settings") |
2507 | - } ) |
2508 | - } |
2509 | - } |
2510 | - } */ |
2511 | - |
2512 | - /* Play/Pause button TODO: image and colours needs updating */ |
2513 | - Rectangle { |
2514 | - id: playerControlsPlayButton |
2515 | - anchors.right: parent.right |
2516 | - anchors.rightMargin: units.gu(1) |
2517 | - anchors.verticalCenter: parent.verticalCenter |
2518 | - antialiasing: true |
2519 | - color: "#444" |
2520 | - height: units.gu(7) |
2521 | - objectName: "smallPlayShape" |
2522 | - radius: height / 2 |
2523 | - width: height |
2524 | - |
2525 | - function trigger() { |
2526 | - if (emptyPage.noMusic) { |
2527 | - return; |
2528 | - } |
2529 | - |
2530 | - if (trackQueue.model.count === 0) { |
2531 | - playRandomSong(); |
2532 | - } |
2533 | - else { |
2534 | - player.toggle(); |
2535 | - } |
2536 | - } |
2537 | - |
2538 | - // draws the outer shadow/highlight |
2539 | - Rectangle { |
2540 | - id: sourceOutter |
2541 | - anchors { fill: parent; margins: -units.gu(0.1) } |
2542 | - radius: (width / 2) |
2543 | - antialiasing: true |
2544 | - gradient: Gradient { |
2545 | - GradientStop { position: 0.0; color: "black" } |
2546 | - GradientStop { position: 0.5; color: "transparent" } |
2547 | - GradientStop { position: 1.0; color: UbuntuColors.warmGrey } |
2548 | - } |
2549 | - |
2550 | - Rectangle { |
2551 | - anchors.verticalCenter: parent.verticalCenter |
2552 | - anchors.horizontalCenter: parent.horizontalCenter |
2553 | - antialiasing: true |
2554 | - color: "#444" |
2555 | - height: playerControlsPlayButton.height - units.gu(.1) |
2556 | - radius: height / 2 |
2557 | - width: height |
2558 | - |
2559 | - Rectangle { |
2560 | - id: playerControlsPlayInnerCircle |
2561 | - anchors.horizontalCenter: parent.horizontalCenter |
2562 | - anchors.verticalCenter: parent.verticalCenter |
2563 | - antialiasing: true |
2564 | - height: units.gu(4.5) |
2565 | - radius: height / 2 |
2566 | - width: height |
2567 | - color: styleMusic.toolbar.fullInnerPlayCircleColor |
2568 | - |
2569 | - // draws the inner shadow/highlight |
2570 | - Rectangle { |
2571 | - id: sourceInner |
2572 | - anchors { fill: parent; margins: -units.gu(0.1) } |
2573 | - radius: (width / 2) |
2574 | - antialiasing: true |
2575 | - gradient: Gradient { |
2576 | - GradientStop { position: 0.0; color: UbuntuColors.warmGrey } |
2577 | - GradientStop { position: 0.5; color: "transparent" } |
2578 | - GradientStop { position: 1.0; color: "black" } |
2579 | - } |
2580 | - |
2581 | - Rectangle { |
2582 | - anchors.verticalCenter: parent.verticalCenter |
2583 | - anchors.horizontalCenter: parent.horizontalCenter |
2584 | - antialiasing: true |
2585 | - height: playerControlsPlayInnerCircle.height - units.gu(.1) |
2586 | - radius: height / 2 |
2587 | - width: height |
2588 | - color: styleMusic.toolbar.fullInnerPlayCircleColor |
2589 | - |
2590 | - Image { |
2591 | - id: playindicator |
2592 | - height: units.gu(4) |
2593 | - width: height |
2594 | - anchors.horizontalCenter: parent.horizontalCenter |
2595 | - anchors.verticalCenter: parent.verticalCenter |
2596 | - opacity: emptyPage.noMusic ? .4 : 1 |
2597 | - source: player.playbackState === MediaPlayer.PlayingState ? |
2598 | - Qt.resolvedUrl("images/media-playback-pause.svg") : Qt.resolvedUrl("images/media-playback-start.svg") |
2599 | - } |
2600 | - } |
2601 | - } |
2602 | - } |
2603 | - } |
2604 | - } |
2605 | + |
2606 | + /* Album art in player controls */ |
2607 | + CoverGrid { |
2608 | + id: playerControlsImage |
2609 | + anchors { |
2610 | + bottom: parent.bottom |
2611 | + left: parent.left |
2612 | + top: parent.top |
2613 | + } |
2614 | + covers: [{art: player.currentMetaArt, author: player.currentMetaArtist, album: player.currentMetaArt}] |
2615 | + size: parent.height |
2616 | } |
2617 | |
2618 | - /* Container holding the labels for the toolbar */ |
2619 | - Rectangle { |
2620 | - id: playerControlLabelContainer |
2621 | - anchors.bottom: parent.bottom |
2622 | - anchors.left: parent.left |
2623 | - anchors.right: playerControlsPlayButton.left |
2624 | - anchors.top: parent.top |
2625 | - color: "transparent" |
2626 | + /* Column of meta labels */ |
2627 | + Column { |
2628 | + id: playerControlsLabels |
2629 | + anchors { |
2630 | + left: playerControlsImage.right |
2631 | + leftMargin: units.gu(1.5) |
2632 | + right: playerControlsPlayButton.left |
2633 | + rightMargin: units.gu(1) |
2634 | + verticalCenter: parent.verticalCenter |
2635 | + } |
2636 | |
2637 | /* Title of track */ |
2638 | Label { |
2639 | id: playerControlsTitle |
2640 | - anchors.left: parent.left |
2641 | - anchors.leftMargin: units.gu(1) |
2642 | - anchors.right: parent.right |
2643 | - anchors.rightMargin: units.gu(1) |
2644 | - anchors.top: parent.top |
2645 | - anchors.topMargin: units.gu(1) |
2646 | - color: styleMusic.playerControls.labelColor |
2647 | + anchors { |
2648 | + left: parent.left |
2649 | + right: parent.right |
2650 | + } |
2651 | + color: "#FFF" |
2652 | elide: Text.ElideRight |
2653 | - fontSize: "medium" |
2654 | - objectName: "playercontroltitle" |
2655 | + fontSize: "small" |
2656 | + font.weight: Font.DemiBold |
2657 | text: player.currentMetaTitle === "" |
2658 | ? player.source : player.currentMetaTitle |
2659 | } |
2660 | @@ -1020,119 +242,105 @@ |
2661 | /* Artist of track */ |
2662 | Label { |
2663 | id: playerControlsArtist |
2664 | - anchors.left: parent.left |
2665 | - anchors.leftMargin: units.gu(1) |
2666 | - anchors.right: parent.right |
2667 | - anchors.rightMargin: units.gu(1) |
2668 | - anchors.top: playerControlsTitle.bottom |
2669 | - color: styleMusic.playerControls.labelColor |
2670 | + anchors { |
2671 | + left: parent.left |
2672 | + right: parent.right |
2673 | + } |
2674 | + color: "#FFF" |
2675 | elide: Text.ElideRight |
2676 | fontSize: "small" |
2677 | + opacity: 0.4 |
2678 | text: player.currentMetaArtist |
2679 | } |
2680 | - |
2681 | - /* Album of track */ |
2682 | - Label { |
2683 | - id: playerControlsAlbum |
2684 | - anchors.left: parent.left |
2685 | - anchors.leftMargin: units.gu(1) |
2686 | - anchors.right: parent.right |
2687 | - anchors.rightMargin: units.gu(1) |
2688 | - anchors.top: playerControlsArtist.bottom |
2689 | - color: styleMusic.playerControls.labelColor |
2690 | - elide: Text.ElideRight |
2691 | - fontSize: "small" |
2692 | - text: player.currentMetaAlbum |
2693 | - } |
2694 | - } |
2695 | - |
2696 | + } |
2697 | + |
2698 | + /* Play/Pause button */ |
2699 | + Icon { |
2700 | + id: playerControlsPlayButton |
2701 | + anchors { |
2702 | + right: parent.right |
2703 | + rightMargin: units.gu(3) |
2704 | + verticalCenter: parent.verticalCenter |
2705 | + } |
2706 | + color: "#FFF" |
2707 | + height: units.gu(2.5) |
2708 | + name: player.playbackState === MediaPlayer.PlayingState ? |
2709 | + "media-playback-pause" : "media-playback-start" |
2710 | + objectName: "playShape" |
2711 | + width: height |
2712 | + } |
2713 | + |
2714 | + MouseArea { |
2715 | + anchors { |
2716 | + bottom: parent.bottom |
2717 | + horizontalCenter: playerControlsPlayButton.horizontalCenter |
2718 | + top: parent.top |
2719 | + } |
2720 | + onClicked: player.toggle() |
2721 | + width: units.gu(8) |
2722 | + |
2723 | + Rectangle { |
2724 | + anchors { |
2725 | + fill: parent |
2726 | + } |
2727 | + color: "#FFF" |
2728 | + opacity: parent.pressed ? 0.1 : 0 |
2729 | + |
2730 | + Behavior on opacity { |
2731 | + UbuntuNumberAnimation { |
2732 | + duration: UbuntuAnimation.FastDuration |
2733 | + } |
2734 | + } |
2735 | + } |
2736 | + } |
2737 | + |
2738 | + /* Mouse area to jump to now playing */ |
2739 | Rectangle { |
2740 | - anchors.fill: playerControlLabelContainer |
2741 | + anchors { |
2742 | + bottom: parent.bottom |
2743 | + left: parent.left |
2744 | + right: playerControlsLabels.right |
2745 | + top: parent.top |
2746 | + } |
2747 | color: "transparent" |
2748 | + objectName: "jumpNowPlaying" |
2749 | function trigger() { |
2750 | tabs.pushNowPlaying(); |
2751 | } |
2752 | } |
2753 | } |
2754 | - } |
2755 | - } |
2756 | - |
2757 | - /* Object which provides the progress bar when toolbar is minimized */ |
2758 | - Rectangle { |
2759 | - id: musicToolbarSmallProgressBackground |
2760 | - anchors { |
2761 | - bottom: parent.top |
2762 | - left: parent.left |
2763 | - right: parent.right |
2764 | - } |
2765 | - color: styleMusic.common.black |
2766 | - height: musicToolbarPanel.minimizedHeight |
2767 | - visible: (!musicToolbarPanel.animating && |
2768 | - !musicToolbarPanel.opened) |
2769 | - || musicToolbarPanel.currentMode == "expanded" |
2770 | - |
2771 | - Rectangle { |
2772 | - id: musicToolbarSmallProgressHint |
2773 | - anchors.left: parent.left |
2774 | - anchors.top: parent.top |
2775 | - color: styleMusic.nowPlaying.progressForegroundColor |
2776 | - height: parent.height |
2777 | - width: 0 |
2778 | - |
2779 | - Connections { |
2780 | - target: player |
2781 | - onPositionChanged: { |
2782 | - musicToolbarSmallProgressHint.width = (player.position / player.duration) * musicToolbarSmallProgressBackground.width |
2783 | - } |
2784 | - onStopped: { |
2785 | - musicToolbarSmallProgressHint.width = 0; |
2786 | - } |
2787 | - } |
2788 | - } |
2789 | - } |
2790 | - |
2791 | - /* Mouse events for the progress bar |
2792 | - is after musicToolbarMouseArea so that it captures mouse events for dragging */ |
2793 | - MouseArea { |
2794 | - id: musicToolbarFullProgressMouseArea |
2795 | - height: units.gu(2) |
2796 | - width: musicToolbarFullProgressBarContainer.width |
2797 | - x: musicToolbarFullProgressBarContainer.x |
2798 | - y: musicToolbarFullProgressBarContainer.y |
2799 | - |
2800 | - drag.axis: Drag.XAxis |
2801 | - drag.minimumX: -(musicToolbarFullProgressHandle.width / 2) |
2802 | - drag.maximumX: musicToolbarFullProgressBarContainer.width - (musicToolbarFullProgressHandle.width / 2) |
2803 | - drag.target: musicToolbarFullProgressHandle |
2804 | - |
2805 | - onPressed: { |
2806 | - musicToolbarFullProgressBarContainer.seeking = true; |
2807 | - |
2808 | - // Jump the handle to the current mouse position |
2809 | - musicToolbarFullProgressHandle.x = mouse.x - (musicToolbarFullProgressHandle.width / 2); |
2810 | - } |
2811 | - |
2812 | - onReleased: { |
2813 | - var fraction = mouse.x / musicToolbarFullProgressBarContainer.width; |
2814 | - |
2815 | - // Limit the bounds of the fraction |
2816 | - fraction = fraction < 0 ? 0 : fraction |
2817 | - fraction = fraction > 1 ? 1 : fraction |
2818 | - |
2819 | - player.seek((fraction) * player.duration); |
2820 | - musicToolbarFullProgressBarContainer.seeking = false; |
2821 | - } |
2822 | - } |
2823 | - |
2824 | - // Timer for autohide |
2825 | - Timer { |
2826 | - id: toolbarAutoHideTimer |
2827 | - interval: 5000 |
2828 | - repeat: false |
2829 | - running: false |
2830 | - onTriggered: { |
2831 | - if (currentPage !== nowPlaying) { // don't autohide on now playing |
2832 | - hideToolbar(); |
2833 | + |
2834 | + /* Object which provides the progress bar when toolbar is minimized */ |
2835 | + Rectangle { |
2836 | + id: playerControlsProgressBar |
2837 | + anchors { |
2838 | + bottom: parent.bottom |
2839 | + left: parent.left |
2840 | + right: parent.right |
2841 | + } |
2842 | + color: styleMusic.common.black |
2843 | + height: units.gu(0.25) |
2844 | + |
2845 | + Rectangle { |
2846 | + id: playerControlsProgressBarHint |
2847 | + anchors { |
2848 | + left: parent.left |
2849 | + top: parent.top |
2850 | + } |
2851 | + color: UbuntuColors.blue |
2852 | + height: parent.height |
2853 | + width: 0 |
2854 | + |
2855 | + Connections { |
2856 | + target: player |
2857 | + onPositionChanged: { |
2858 | + playerControlsProgressBarHint.width = (player.position / player.duration) * playerControlsProgressBar.width |
2859 | + } |
2860 | + onStopped: { |
2861 | + playerControlsProgressBarHint.width = 0; |
2862 | + } |
2863 | + } |
2864 | + } |
2865 | } |
2866 | } |
2867 | } |
2868 | |
2869 | === modified file 'MusicTracks.qml' |
2870 | --- MusicTracks.qml 2014-09-20 15:41:33 +0000 |
2871 | +++ MusicTracks.qml 2014-10-21 15:31:33 +0000 |
2872 | @@ -36,8 +36,10 @@ |
2873 | |
2874 | ListView { |
2875 | id: tracklist |
2876 | - anchors.fill: parent |
2877 | - anchors.bottomMargin: musicToolbar.mouseAreaOffset + musicToolbar.minimizedHeight |
2878 | + anchors { |
2879 | + fill: parent |
2880 | + topMargin: units.gu(2) |
2881 | + } |
2882 | highlightFollowsCurrentItem: false |
2883 | objectName: "trackstab-listview" |
2884 | model: SortFilterModel { |
2885 | @@ -59,7 +61,8 @@ |
2886 | color: "transparent" |
2887 | objectName: "tracksPageListItem" + index |
2888 | width: parent.width |
2889 | - height: styleMusic.common.itemHeight |
2890 | + height: units.gu(7) |
2891 | + showDivider: false |
2892 | |
2893 | rightSideActions: [ |
2894 | AddToQueue { |
2895 | @@ -77,29 +80,25 @@ |
2896 | |
2897 | MusicRow { |
2898 | id: musicRow |
2899 | + anchors.verticalCenter: parent.verticalCenter |
2900 | covers: [{art: model.art}] |
2901 | + isSquare: true |
2902 | + coverSize: units.gu(6) |
2903 | + spacing: units.gu(2) |
2904 | column: Column { |
2905 | - spacing: units.gu(1) |
2906 | - Label { |
2907 | - id: trackArtist |
2908 | - color: styleMusic.common.subtitle |
2909 | - fontSize: "x-small" |
2910 | - text: model.author |
2911 | - } |
2912 | - |
2913 | Label { |
2914 | id: trackTitle |
2915 | color: styleMusic.common.music |
2916 | - fontSize: "medium" |
2917 | + fontSize: "small" |
2918 | objectName: "tracktitle" |
2919 | text: model.title |
2920 | } |
2921 | |
2922 | Label { |
2923 | - id: trackAlbum |
2924 | + id: trackArtist |
2925 | color: styleMusic.common.subtitle |
2926 | - fontSize: "xx-small" |
2927 | - text: model.album |
2928 | + fontSize: "x-small" |
2929 | + text: model.author |
2930 | } |
2931 | } |
2932 | } |
2933 | |
2934 | === modified file 'MusicaddtoPlaylist.qml' |
2935 | --- MusicaddtoPlaylist.qml 2014-09-20 10:50:45 +0000 |
2936 | +++ MusicaddtoPlaylist.qml 2014-10-21 15:31:33 +0000 |
2937 | @@ -65,7 +65,6 @@ |
2938 | ListView { |
2939 | id: addtoPlaylistView |
2940 | anchors { |
2941 | - bottomMargin: musicToolbar.mouseAreaOffset + musicToolbar.minimizedHeight |
2942 | fill: parent |
2943 | } |
2944 | clip: true |
2945 | |
2946 | === modified file 'Player.qml' |
2947 | --- Player.qml 2014-09-20 15:41:33 +0000 |
2948 | +++ Player.qml 2014-10-21 15:31:33 +0000 |
2949 | @@ -187,7 +187,11 @@ |
2950 | else { |
2951 | var obj = trackQueue.model.get(player.currentIndex); |
2952 | currentMetaAlbum = obj.album; |
2953 | - currentMetaArt = obj.art; |
2954 | + |
2955 | + if (obj.art !== undefined) { // FIXME: protect against not art property in playlists |
2956 | + currentMetaArt = obj.art; |
2957 | + } |
2958 | + |
2959 | currentMetaArtist = obj.author; |
2960 | currentMetaFile = obj.filename; |
2961 | currentMetaTitle = obj.title; |
2962 | |
2963 | === modified file 'Style.qml' |
2964 | --- Style.qml 2014-09-20 10:50:45 +0000 |
2965 | +++ Style.qml 2014-10-21 15:31:33 +0000 |
2966 | @@ -34,8 +34,8 @@ |
2967 | property QtObject common: QtObject { |
2968 | property color black: "#000000"; |
2969 | property color white: "#FFFFFF"; |
2970 | - property color music: "#333333"; |
2971 | - property color subtitle: "#666666"; |
2972 | + property color music: "#FFFFFF"; |
2973 | + property color subtitle: "#999999"; |
2974 | property color expandedColor: "#000000"; |
2975 | property int albumSize: units.gu(10); |
2976 | property int itemHeight: units.gu(12); |
2977 | |
2978 | === modified file 'click/apparmor.json' |
2979 | --- click/apparmor.json 2014-07-01 23:13:50 +0000 |
2980 | +++ click/apparmor.json 2014-10-21 15:31:33 +0000 |
2981 | @@ -1,7 +1,17 @@ |
2982 | { |
2983 | "policy_version": 1.2, |
2984 | - "template": "unconfined", |
2985 | "policy_groups": [ |
2986 | - "content_exchange" |
2987 | + "audio", |
2988 | + "content_exchange", |
2989 | + "music_files_read", |
2990 | + "networking", |
2991 | + "usermetrics" |
2992 | + ], |
2993 | + "read_path": [ |
2994 | + "@{HOME}/.cache/media-art/", |
2995 | + "@{HOME}/.cache/mediascanner-2.0/" |
2996 | + ], |
2997 | + "write_path": [ |
2998 | + "@{HOME}/Music/Imported/" |
2999 | ] |
3000 | } |
3001 | |
3002 | === modified file 'com.ubuntu.music_music.desktop.in.in' |
3003 | --- com.ubuntu.music_music.desktop.in.in 2014-07-21 14:49:14 +0000 |
3004 | +++ com.ubuntu.music_music.desktop.in.in 2014-10-21 15:31:33 +0000 |
3005 | @@ -9,4 +9,7 @@ |
3006 | StartupNotify=true |
3007 | X-Ubuntu-Touch=true |
3008 | X-Ubuntu-Single-Instance=true |
3009 | +X-Ubuntu-Splash-Show-Header=true |
3010 | +_X-Ubuntu-Splash-Title=Music |
3011 | +X-Ubuntu-Splash-Color=#1e1e23 |
3012 | X-Ubuntu-Default-Department-ID=sound-video |
3013 | |
3014 | === modified file 'common/AlbumsPage.qml' |
3015 | --- common/AlbumsPage.qml 2014-10-07 02:15:06 +0000 |
3016 | +++ common/AlbumsPage.qml 2014-10-21 15:31:33 +0000 |
3017 | @@ -28,26 +28,116 @@ |
3018 | |
3019 | MusicPage { |
3020 | id: albumStackPage |
3021 | - anchors.bottomMargin: units.gu(.5) |
3022 | objectName: "albumsArtistPage" |
3023 | visible: false |
3024 | |
3025 | - property string artist: "" |
3026 | + property string artist: "Unknown Artist" |
3027 | property var covers: [] |
3028 | |
3029 | - ListView { |
3030 | - id: albumtrackslist |
3031 | + CardView { |
3032 | + id: artistAlbumView |
3033 | anchors { |
3034 | - bottomMargin: wideAspect ? musicToolbar.fullHeight : musicToolbar.mouseAreaOffset + musicToolbar.minimizedHeight |
3035 | fill: parent |
3036 | } |
3037 | - delegate: albumTracksDelegate |
3038 | - header: artistHeaderDelegate |
3039 | + header: BlurredHeader { |
3040 | + rightColumn: Column { |
3041 | + spacing: units.gu(2) |
3042 | + Button { |
3043 | + id: shuffleRow |
3044 | + height: units.gu(4) |
3045 | + strokeColor: UbuntuColors.green |
3046 | + width: units.gu(15) |
3047 | + Text { |
3048 | + anchors { |
3049 | + centerIn: parent |
3050 | + } |
3051 | + color: "white" |
3052 | + text: i18n.tr("Shuffle") |
3053 | + } |
3054 | + MouseArea { |
3055 | + anchors.fill: parent |
3056 | + onClicked: shuffleModel(songArtistModel) |
3057 | + } |
3058 | + } |
3059 | + Button { |
3060 | + id: queueAllRow |
3061 | + height: units.gu(4) |
3062 | + strokeColor: UbuntuColors.green |
3063 | + width: units.gu(15) |
3064 | + Text { |
3065 | + anchors { |
3066 | + centerIn: parent |
3067 | + } |
3068 | + color: "white" |
3069 | + text: i18n.tr("Queue all") |
3070 | + } |
3071 | + MouseArea { |
3072 | + anchors.fill: parent |
3073 | + onClicked: addQueueFromModel(songArtistModel) |
3074 | + } |
3075 | + } |
3076 | + Button { |
3077 | + id: playRow |
3078 | + color: UbuntuColors.green |
3079 | + height: units.gu(4) |
3080 | + text: i18n.tr("Play all") |
3081 | + width: units.gu(15) |
3082 | + MouseArea { |
3083 | + anchors.fill: parent |
3084 | + onClicked: trackClicked(songArtistModel, 0, true) |
3085 | + } |
3086 | + } |
3087 | + } |
3088 | + coverSources: albumStackPage.covers |
3089 | + height: units.gu(30) |
3090 | + bottomColumn: Column { |
3091 | + Label { |
3092 | + id: artistLabel |
3093 | + anchors { |
3094 | + left: parent.left |
3095 | + right: parent.right |
3096 | + } |
3097 | + color: styleMusic.common.music |
3098 | + elide: Text.ElideRight |
3099 | + fontSize: "x-large" |
3100 | + maximumLineCount: 1 |
3101 | + objectName: "artistLabel" |
3102 | + text: artist |
3103 | + wrapMode: Text.NoWrap |
3104 | + } |
3105 | + |
3106 | + Item { |
3107 | + height: units.gu(1) |
3108 | + width: parent.width |
3109 | + } |
3110 | + |
3111 | + Label { |
3112 | + id: artistCount |
3113 | + anchors { |
3114 | + left: parent.left |
3115 | + right: parent.right |
3116 | + } |
3117 | + color: styleMusic.common.subtitle |
3118 | + elide: Text.ElideRight |
3119 | + fontSize: "small" |
3120 | + maximumLineCount: 1 |
3121 | + text: i18n.tr("%1 album", "%1 albums", artistsModel.count).arg(artistsModel.count) |
3122 | + } |
3123 | + } |
3124 | + |
3125 | + SongsModel { |
3126 | + id: songArtistModel |
3127 | + albumArtist: albumStackPage.artist |
3128 | + store: musicStore |
3129 | + } |
3130 | + } |
3131 | + itemWidth: units.gu(12) |
3132 | model: AlbumsModel { |
3133 | id: artistsModel |
3134 | albumArtist: albumStackPage.artist |
3135 | store: musicStore |
3136 | } |
3137 | +<<<<<<< TREE |
3138 | width: parent.width |
3139 | |
3140 | Component { |
3141 | @@ -408,6 +498,26 @@ |
3142 | } |
3143 | } |
3144 | } |
3145 | +======= |
3146 | + delegate: Card { |
3147 | + id: albumCard |
3148 | + coverSources: [{art: model.art}] |
3149 | + objectName: "albumsPageGridItem" + index |
3150 | + primaryText: model.title |
3151 | + secondaryTextVisible: false |
3152 | + |
3153 | + onClicked: { |
3154 | + songsPage.album = model.title; |
3155 | + |
3156 | + songsPage.line1 = model.artist |
3157 | + songsPage.line2 = model.title |
3158 | + songsPage.isAlbum = true |
3159 | + songsPage.covers = [{art: model.art}] |
3160 | + songsPage.genre = undefined |
3161 | + songsPage.title = i18n.tr("Album") |
3162 | + |
3163 | + mainPageStack.push(songsPage) |
3164 | +>>>>>>> MERGE-SOURCE |
3165 | } |
3166 | } |
3167 | } |
3168 | |
3169 | === modified file 'common/BlurredBackground.qml' |
3170 | --- common/BlurredBackground.qml 2014-09-20 15:41:33 +0000 |
3171 | +++ common/BlurredBackground.qml 2014-10-21 15:31:33 +0000 |
3172 | @@ -23,8 +23,14 @@ |
3173 | |
3174 | // Blurred background |
3175 | Rectangle { |
3176 | - anchors.fill: parent |
3177 | - property string art: player.currentMetaFile === "" ? Qt.resolvedUrl("../images/music-app-cover@30.png") : player.currentMetaArt |
3178 | + width: parent.width |
3179 | + property string art // : player.currentMetaFile === "" ? Qt.resolvedUrl("../images/music-app-cover@30.png") : player.currentMetaArt |
3180 | + |
3181 | + // dark layer |
3182 | + Rectangle { |
3183 | + anchors.fill: parent |
3184 | + color: "black" |
3185 | + } |
3186 | |
3187 | // the album art |
3188 | Image { |
3189 | @@ -32,27 +38,19 @@ |
3190 | anchors.horizontalCenter: parent.horizontalCenter |
3191 | anchors.verticalCenter: parent.verticalCenter |
3192 | source: art // this has to be fixed for the default cover art to work - cant find in this dir |
3193 | - height: Math.max(parent.height, parent.width) |
3194 | + fillMode: Image.PreserveAspectCrop |
3195 | + height: parent.height |
3196 | width: Math.max(parent.height, parent.width) |
3197 | visible: false |
3198 | - onStatusChanged: { |
3199 | - if (status === Image.Error) { |
3200 | - source = Qt.resolvedUrl("../images/music-app-cover@30.png") |
3201 | - } |
3202 | - } |
3203 | } |
3204 | + |
3205 | // the blur |
3206 | FastBlur { |
3207 | id: backgroundBlur |
3208 | anchors.fill: backgroundImage |
3209 | source: backgroundImage |
3210 | radius: units.dp(42) |
3211 | - } |
3212 | - // transparent white layer |
3213 | - Rectangle { |
3214 | - anchors.fill: parent |
3215 | - color: "white" |
3216 | - opacity: 0.7 |
3217 | + opacity: 0.2 |
3218 | } |
3219 | onArtChanged: { |
3220 | // TODO: This is a work around for LP:1261078 and LP:1306845. Ideally, |
3221 | |
3222 | === added file 'common/BlurredHeader.qml' |
3223 | --- common/BlurredHeader.qml 1970-01-01 00:00:00 +0000 |
3224 | +++ common/BlurredHeader.qml 2014-10-21 15:31:33 +0000 |
3225 | @@ -0,0 +1,69 @@ |
3226 | +/* |
3227 | + * Copyright (C) 2014 |
3228 | + * Andrew Hayzen <ahayzen@gmail.com> |
3229 | + * Victor Thompson <victor.thompson@gmail.com> |
3230 | + * |
3231 | + * This program is free software; you can redistribute it and/or modify |
3232 | + * it under the terms of the GNU General Public License as published by |
3233 | + * the Free Software Foundation; version 3. |
3234 | + * |
3235 | + * This program is distributed in the hope that it will be useful, |
3236 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
3237 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
3238 | + * GNU General Public License for more details. |
3239 | + * |
3240 | + * You should have received a copy of the GNU General Public License |
3241 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
3242 | + */ |
3243 | + |
3244 | +import QtQuick 2.3 |
3245 | +import Ubuntu.Components 1.1 |
3246 | +import Ubuntu.Components.ListItems 1.0 as ListItem |
3247 | + |
3248 | +ListItem.Standard { |
3249 | + id: albumInfo |
3250 | + width: parent.width |
3251 | + |
3252 | + property alias bottomColumn: bottomColumnLoader.sourceComponent |
3253 | + property alias coverSources: coversImage.covers |
3254 | + property alias rightColumn: rightColumnLoader.sourceComponent |
3255 | + |
3256 | + BlurredBackground { |
3257 | + id: blurredBackground |
3258 | + height: parent.height |
3259 | + art: coversImage.firstSource |
3260 | + } |
3261 | + |
3262 | + CoverGrid { |
3263 | + id: coversImage |
3264 | + anchors { |
3265 | + bottomMargin: units.gu(2) |
3266 | + left: parent.left |
3267 | + leftMargin: units.gu(2) |
3268 | + rightMargin: units.gu(2) |
3269 | + top: parent.top |
3270 | + topMargin: units.gu(3) |
3271 | + } |
3272 | + size: units.gu(18) |
3273 | + } |
3274 | + |
3275 | + Loader { |
3276 | + id: rightColumnLoader |
3277 | + anchors { |
3278 | + bottom: coversImage.bottom |
3279 | + left: coversImage.right |
3280 | + leftMargin: units.gu(2) |
3281 | + } |
3282 | + } |
3283 | + |
3284 | + Loader { |
3285 | + id: bottomColumnLoader |
3286 | + anchors { |
3287 | + left: coversImage.left |
3288 | + right: parent.right |
3289 | + rightMargin: units.gu(2) |
3290 | + top: coversImage.bottom |
3291 | + topMargin: units.gu(1) |
3292 | + } |
3293 | + } |
3294 | +} |
3295 | |
3296 | === added file 'common/Card.qml' |
3297 | --- common/Card.qml 1970-01-01 00:00:00 +0000 |
3298 | +++ common/Card.qml 2014-10-21 15:31:33 +0000 |
3299 | @@ -0,0 +1,151 @@ |
3300 | +/* |
3301 | + * Copyright (C) 2014 |
3302 | + * Andrew Hayzen <ahayzen@gmail.com> |
3303 | + * |
3304 | + * This program is free software; you can redistribute it and/or modify |
3305 | + * it under the terms of the GNU General Public License as published by |
3306 | + * the Free Software Foundation; version 3. |
3307 | + * |
3308 | + * This program is distributed in the hope that it will be useful, |
3309 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
3310 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
3311 | + * GNU General Public License for more details. |
3312 | + * |
3313 | + * You should have received a copy of the GNU General Public License |
3314 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
3315 | + */ |
3316 | + |
3317 | +import QtQuick 2.3 |
3318 | +import Ubuntu.Components 1.1 |
3319 | + |
3320 | + |
3321 | +Rectangle { |
3322 | + id: card |
3323 | + color: "transparent" |
3324 | + height: cardColumn.childrenRect.height + 2 * bg.anchors.margins |
3325 | + |
3326 | + property alias coverSources: coverGrid.covers |
3327 | + property alias primaryText: primaryLabel.text |
3328 | + property alias secondaryText: secondaryLabel.text |
3329 | + property alias secondaryTextVisible: secondaryLabel.visible |
3330 | + |
3331 | + signal clicked(var mouse) |
3332 | + signal pressAndHold(var mouse) |
3333 | + |
3334 | + /* Animations */ |
3335 | + Behavior on height { |
3336 | + UbuntuNumberAnimation { |
3337 | + |
3338 | + } |
3339 | + } |
3340 | + |
3341 | + Behavior on width { |
3342 | + UbuntuNumberAnimation { |
3343 | + |
3344 | + } |
3345 | + } |
3346 | + |
3347 | + Behavior on x { |
3348 | + UbuntuNumberAnimation { |
3349 | + |
3350 | + } |
3351 | + } |
3352 | + |
3353 | + Behavior on y { |
3354 | + UbuntuNumberAnimation { |
3355 | + |
3356 | + } |
3357 | + } |
3358 | + |
3359 | + /* Background for card */ |
3360 | + Rectangle { |
3361 | + id: bg |
3362 | + anchors { |
3363 | + fill: parent |
3364 | + margins: units.gu(1) |
3365 | + } |
3366 | + color: "#2c2c34" |
3367 | + } |
3368 | + |
3369 | + /* Column containing image and labels */ |
3370 | + Column { |
3371 | + id: cardColumn |
3372 | + anchors { |
3373 | + fill: bg |
3374 | + } |
3375 | + spacing: units.gu(0.5) |
3376 | + |
3377 | + CoverGrid { |
3378 | + id: coverGrid |
3379 | + size: parent.width |
3380 | + } |
3381 | + |
3382 | + Rectangle { |
3383 | + color: "transparent" |
3384 | + height: units.gu(1) |
3385 | + width: units.gu(1) |
3386 | + } |
3387 | + |
3388 | + Label { |
3389 | + id: primaryLabel |
3390 | + anchors { |
3391 | + left: parent.left |
3392 | + leftMargin: units.gu(1) |
3393 | + right: parent.right |
3394 | + rightMargin: units.gu(1) |
3395 | + } |
3396 | + color: "#FFF" |
3397 | + elide: Text.ElideRight |
3398 | + fontSize: "small" |
3399 | + opacity: 1.0 |
3400 | + wrapMode: Text.WordWrap |
3401 | + } |
3402 | + |
3403 | + Label { |
3404 | + id: secondaryLabel |
3405 | + anchors { |
3406 | + left: parent.left |
3407 | + leftMargin: units.gu(1) |
3408 | + right: parent.right |
3409 | + rightMargin: units.gu(1) |
3410 | + } |
3411 | + color: "#FFF" |
3412 | + elide: Text.ElideRight |
3413 | + fontSize: "small" |
3414 | + opacity: 0.4 |
3415 | + wrapMode: Text.WordWrap |
3416 | + } |
3417 | + |
3418 | + Rectangle { |
3419 | + color: "transparent" |
3420 | + height: units.gu(1.5) |
3421 | + width: units.gu(1) |
3422 | + } |
3423 | + } |
3424 | + |
3425 | + /* Overlay for when card is pressed */ |
3426 | + Rectangle { |
3427 | + id: overlay |
3428 | + anchors { |
3429 | + fill: bg |
3430 | + } |
3431 | + color: "#000" |
3432 | + opacity: 0 |
3433 | + |
3434 | + Behavior on opacity { |
3435 | + UbuntuNumberAnimation { |
3436 | + |
3437 | + } |
3438 | + } |
3439 | + } |
3440 | + |
3441 | + /* Capture mouse events */ |
3442 | + MouseArea { |
3443 | + anchors { |
3444 | + fill: parent |
3445 | + } |
3446 | + onClicked: card.clicked(mouse) |
3447 | + onPressAndHold: card.pressAndHold(mouse) |
3448 | + onPressedChanged: overlay.opacity = pressed ? 0.3 : 0 |
3449 | + } |
3450 | +} |
3451 | |
3452 | === added file 'common/CardView.qml' |
3453 | --- common/CardView.qml 1970-01-01 00:00:00 +0000 |
3454 | +++ common/CardView.qml 2014-10-21 15:31:33 +0000 |
3455 | @@ -0,0 +1,61 @@ |
3456 | +/* |
3457 | + * Copyright (C) 2014 |
3458 | + * Andrew Hayzen <ahayzen@gmail.com> |
3459 | + * |
3460 | + * This program is free software; you can redistribute it and/or modify |
3461 | + * it under the terms of the GNU General Public License as published by |
3462 | + * the Free Software Foundation; version 3. |
3463 | + * |
3464 | + * This program is distributed in the hope that it will be useful, |
3465 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
3466 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
3467 | + * GNU General Public License for more details. |
3468 | + * |
3469 | + * You should have received a copy of the GNU General Public License |
3470 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
3471 | + */ |
3472 | + |
3473 | +import QtQuick 2.3 |
3474 | +import Ubuntu.Components 1.1 |
3475 | + |
3476 | + |
3477 | +Flickable { |
3478 | + anchors { |
3479 | + fill: parent |
3480 | + } |
3481 | + |
3482 | + // dont use flow.contentHeight as it is inaccurate due to height of labels |
3483 | + // changing as they load |
3484 | + contentHeight: headerLoader.childrenRect.height + flowContainer.height |
3485 | + contentWidth: width |
3486 | + |
3487 | + property alias count: flow.count |
3488 | + property alias delegate: flow.delegate |
3489 | + property alias header: headerLoader.sourceComponent |
3490 | + property alias model: flow.model |
3491 | + property real itemWidth: units.gu(15) |
3492 | + |
3493 | + Loader { |
3494 | + id: headerLoader |
3495 | + width: parent.width |
3496 | + } |
3497 | + |
3498 | + Item { |
3499 | + id: flowContainer |
3500 | + anchors { |
3501 | + top: headerLoader.bottom |
3502 | + } |
3503 | + height: flow.childrenRect.height + flow.anchors.margins * 2 |
3504 | + width: parent.width |
3505 | + |
3506 | + ColumnFlow { |
3507 | + id: flow |
3508 | + anchors { |
3509 | + fill: parent |
3510 | + margins: units.gu(1) |
3511 | + } |
3512 | + |
3513 | + columns: parseInt(width / itemWidth) |
3514 | + } |
3515 | + } |
3516 | +} |
3517 | |
3518 | === added file 'common/ColumnFlow.qml' |
3519 | --- common/ColumnFlow.qml 1970-01-01 00:00:00 +0000 |
3520 | +++ common/ColumnFlow.qml 2014-10-21 15:31:33 +0000 |
3521 | @@ -0,0 +1,160 @@ |
3522 | +/* |
3523 | + * Copyright (C) 2014 |
3524 | + * Andrew Hayzen <ahayzen@gmail.com> |
3525 | + * Michael Spencer <sonrisesoftware@gmail.com> |
3526 | + * |
3527 | + * This program is free software; you can redistribute it and/or modify |
3528 | + * it under the terms of the GNU General Public License as published by |
3529 | + * the Free Software Foundation; version 3. |
3530 | + * |
3531 | + * This program is distributed in the hope that it will be useful, |
3532 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
3533 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
3534 | + * GNU General Public License for more details. |
3535 | + * |
3536 | + * You should have received a copy of the GNU General Public License |
3537 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
3538 | + * |
3539 | + * Upstream location: |
3540 | + * https://github.com/iBeliever/ubuntu-ui-extras/blob/master/ColumnFlow.qml |
3541 | + */ |
3542 | + |
3543 | +import QtQuick 2.3 |
3544 | + |
3545 | + |
3546 | +Item { |
3547 | + id: columnFlow |
3548 | + property int columns: 1 |
3549 | + property bool repeaterCompleted: false |
3550 | + property alias count: repeater.count |
3551 | + property alias model: repeater.model |
3552 | + property alias delegate: repeater.delegate |
3553 | + property int contentHeight: 0 |
3554 | + |
3555 | + onColumnsChanged: reEvalColumns() |
3556 | + onModelChanged: reEvalColumns() |
3557 | + onWidthChanged: updateWidths() |
3558 | + |
3559 | + function updateWidths() { |
3560 | + if (repeaterCompleted) { |
3561 | + var count = 0 |
3562 | + |
3563 | + //add the first <column> elements |
3564 | + for (var i = 0; count < columns && i < columnFlow.children.length; i++) { |
3565 | + //print(i, count) |
3566 | + if (!columnFlow.children[i] || String(columnFlow.children[i]).indexOf("QQuickRepeater") == 0) |
3567 | + //|| !columnFlow.children[i].visible) // CUSTOM - view is invisible at start |
3568 | + continue |
3569 | + |
3570 | + columnFlow.children[i].width = width / columns |
3571 | + |
3572 | + count++ |
3573 | + } |
3574 | + } |
3575 | + } |
3576 | + |
3577 | + function reEvalColumns() { |
3578 | + if (columnFlow.repeaterCompleted === false) |
3579 | + return |
3580 | + |
3581 | + if (columns === 0) { |
3582 | + contentHeight = 0 |
3583 | + return |
3584 | + } |
3585 | + |
3586 | + var i, j |
3587 | + var columnHeights = new Array(columns); |
3588 | + var lastItem = new Array(columns) |
3589 | + var lastI = -1 |
3590 | + var count = 0 |
3591 | + |
3592 | + //add the first <column> elements |
3593 | + for (i = 0; count < columns && i < columnFlow.children.length; i++) { |
3594 | + // CUSTOM - ignore if has just been removed |
3595 | + if (i === repeater.removeHintIndex && columnFlow.children[i] === repeater.removeHintItem) { |
3596 | + continue |
3597 | + } |
3598 | + |
3599 | + if (!columnFlow.children[i] || String(columnFlow.children[i]).indexOf("QQuickRepeater") == 0) |
3600 | + //|| !columnFlow.children[i].visible) // CUSTOM - view is invisible at start |
3601 | + continue |
3602 | + |
3603 | + lastItem[count] = i |
3604 | + |
3605 | + columnHeights[count] = columnFlow.children[i].height |
3606 | + columnFlow.children[i].anchors.top = columnFlow.top |
3607 | + columnFlow.children[i].anchors.left = (lastI === -1 ? columnFlow.left : columnFlow.children[lastI].right) |
3608 | + columnFlow.children[i].anchors.right = undefined |
3609 | + columnFlow.children[i].width = columnFlow.width / columns |
3610 | + |
3611 | + lastI = i |
3612 | + count++ |
3613 | + } |
3614 | + |
3615 | + //add the other elements |
3616 | + for (i = i; i < columnFlow.children.length; i++) { |
3617 | + var highestHeight = Number.MAX_VALUE |
3618 | + var newColumn = 0 |
3619 | + |
3620 | + // CUSTOM - ignore if has just been removed |
3621 | + if (i === repeater.removeHintIndex && columnFlow.children[i] === repeater.removeHintItem) { |
3622 | + continue |
3623 | + } |
3624 | + |
3625 | + if (!columnFlow.children[i] || String(columnFlow.children[i]).indexOf("QQuickRepeater") == 0) |
3626 | + //|| !columnFlow.children[i].visible) // CUSTOM - view is invisible at start |
3627 | + continue |
3628 | + |
3629 | + // find the shortest column |
3630 | + for (j = 0; j < columns; j++) { |
3631 | + if (columnHeights[j] !== null && columnHeights[j] < highestHeight) { |
3632 | + newColumn = j |
3633 | + highestHeight = columnHeights[j] |
3634 | + } |
3635 | + } |
3636 | + |
3637 | + // add the element to the shortest column |
3638 | + columnFlow.children[i].anchors.top = columnFlow.children[lastItem[newColumn]].bottom |
3639 | + columnFlow.children[i].anchors.left = columnFlow.children[lastItem[newColumn]].left |
3640 | + columnFlow.children[i].anchors.right = columnFlow.children[lastItem[newColumn]].right |
3641 | + |
3642 | + lastItem[newColumn] = i |
3643 | + columnHeights[newColumn] += columnFlow.children[i].height |
3644 | + } |
3645 | + |
3646 | + var cHeight = 0 |
3647 | + |
3648 | + for (i = 0; i < columnHeights.length; i++) { |
3649 | + if (columnHeights[i]) |
3650 | + cHeight = Math.max(cHeight, columnHeights[i]) |
3651 | + } |
3652 | + |
3653 | + contentHeight = cHeight |
3654 | + updateWidths() |
3655 | + } |
3656 | + |
3657 | + Repeater { |
3658 | + id: repeater |
3659 | + model: columnFlow.model |
3660 | + Component.onCompleted: { |
3661 | + columnFlow.repeaterCompleted = true |
3662 | + columnFlow.reEvalColumns() |
3663 | + } |
3664 | + |
3665 | + // Provide a hint of the removed item |
3666 | + property int removeHintIndex: -1 // CUSTOM |
3667 | + property var removeHintItem // CUSTOM |
3668 | + |
3669 | + onItemAdded: columnFlow.reEvalColumns() // CUSTOM - ms2 models are live |
3670 | + onItemRemoved: { |
3671 | + removeHintIndex = index |
3672 | + removeHintItem = item |
3673 | + |
3674 | + columnFlow.reEvalColumns() // CUSTOM - ms2 models are live |
3675 | + |
3676 | + // Set back to null to allow freeing of memory |
3677 | + removeHintIndex = -1 |
3678 | + removeHintItem = undefined |
3679 | + } |
3680 | + } |
3681 | +} |
3682 | |
3683 | === added file 'common/CoverGrid.qml' |
3684 | --- common/CoverGrid.qml 1970-01-01 00:00:00 +0000 |
3685 | +++ common/CoverGrid.qml 2014-10-21 15:31:33 +0000 |
3686 | @@ -0,0 +1,78 @@ |
3687 | +/* |
3688 | + * Copyright (C) 2013, 2014 |
3689 | + * Andrew Hayzen <ahayzen@gmail.com> |
3690 | + * Nekhelesh Ramananthan <krnekhelesh@gmail.com> |
3691 | + * Victor Thompson <victor.thompson@gmail.com> |
3692 | + * |
3693 | + * This program is free software; you can redistribute it and/or modify |
3694 | + * it under the terms of the GNU General Public License as published by |
3695 | + * the Free Software Foundation; version 3. |
3696 | + * |
3697 | + * This program is distributed in the hope that it will be useful, |
3698 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
3699 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
3700 | + * GNU General Public License for more details. |
3701 | + * |
3702 | + * You should have received a copy of the GNU General Public License |
3703 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
3704 | + */ |
3705 | + |
3706 | +import QtQuick 2.3 |
3707 | +import Ubuntu.Components 1.1 |
3708 | + |
3709 | +Rectangle { |
3710 | + id: coverGrid |
3711 | + color: "transparent" |
3712 | + height: size |
3713 | + width: size |
3714 | + |
3715 | + // Property (array) to store the cover images |
3716 | + property var covers |
3717 | + |
3718 | + // Property to set the size of the cover image |
3719 | + property int size |
3720 | + |
3721 | + property string firstSource |
3722 | + |
3723 | + onCoversChanged: { |
3724 | + if (covers !== undefined) { |
3725 | + while (covers.length > 4) { // remove any covers after 4 |
3726 | + covers.pop() |
3727 | + } |
3728 | + } |
3729 | + } |
3730 | + |
3731 | + // Flow of the cover arts in either 1, 1x1, 2x1, 2x2 |
3732 | + Flow { |
3733 | + id: imageRow |
3734 | + anchors { |
3735 | + fill: parent |
3736 | + } |
3737 | + |
3738 | + Repeater { |
3739 | + id: repeat |
3740 | + model: coverGrid.covers.length === 0 ? 1 : coverGrid.covers.length |
3741 | + delegate: Image { |
3742 | + fillMode: Image.PreserveAspectCrop |
3743 | + height: coverGrid.size / (coverGrid.covers.length > 1 ? 2 : 1) |
3744 | + width: coverGrid.size / (coverGrid.covers.length > 2 && !(coverGrid.covers.length === 3 && index === 2) ? 2 : 1) |
3745 | + source: coverGrid.covers.length !== 0 && coverGrid.covers[index] !== "" && coverGrid.covers[index] !== undefined |
3746 | + ? (coverGrid.covers[index].art !== undefined |
3747 | + ? coverGrid.covers[index].art |
3748 | + : "image://albumart/artist=" + coverGrid.covers[index].author + "&album=" + coverGrid.covers[index].album) |
3749 | + : undefined |
3750 | + sourceSize.height: height |
3751 | + sourceSize.width: width |
3752 | + |
3753 | + onStatusChanged: { |
3754 | + if (status === Image.Error) { |
3755 | + source = Qt.resolvedUrl("../images/music-app-cover@30.png") |
3756 | + } else if (status === Image.Ready && index === 0) { |
3757 | + firstSource = source |
3758 | + } |
3759 | + } |
3760 | + } |
3761 | + } |
3762 | + } |
3763 | +} |
3764 | + |
3765 | |
3766 | === modified file 'common/CoverRow.qml' |
3767 | --- common/CoverRow.qml 2014-09-20 15:41:33 +0000 |
3768 | +++ common/CoverRow.qml 2014-10-21 15:31:33 +0000 |
3769 | @@ -63,6 +63,8 @@ |
3770 | ? coverRow.covers[index].art |
3771 | : "image://albumart/artist=" + coverRow.covers[index].author + "&album=" + coverRow.covers[index].album) |
3772 | : Qt.resolvedUrl("../images/music-app-cover@30.png") |
3773 | + sourceSize.height: height |
3774 | + sourceSize.width: width |
3775 | onStatusChanged: { |
3776 | if (status === Image.Error) { |
3777 | source = Qt.resolvedUrl("../images/music-app-cover@30.png") |
3778 | |
3779 | === removed file 'common/ListItemActions/DeletePlaylist.qml' |
3780 | --- common/ListItemActions/DeletePlaylist.qml 2014-09-20 10:50:45 +0000 |
3781 | +++ common/ListItemActions/DeletePlaylist.qml 1970-01-01 00:00:00 +0000 |
3782 | @@ -1,29 +0,0 @@ |
3783 | -/* |
3784 | - * Copyright (C) 2014 Andrew Hayzen <ahayzen@gmail.com> |
3785 | - * Daniel Holm <d.holmen@gmail.com> |
3786 | - * Victor Thompson <victor.thompson@gmail.com> |
3787 | - * |
3788 | - * This program is free software; you can redistribute it and/or modify |
3789 | - * it under the terms of the GNU General Public License as published by |
3790 | - * the Free Software Foundation; version 3. |
3791 | - * |
3792 | - * This program is distributed in the hope that it will be useful, |
3793 | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
3794 | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
3795 | - * GNU General Public License for more details. |
3796 | - * |
3797 | - * You should have received a copy of the GNU General Public License |
3798 | - * along with this program. If not, see <http://www.gnu.org/licenses/>. |
3799 | - */ |
3800 | - |
3801 | -import QtQuick 2.3 |
3802 | -import Ubuntu.Components 1.1 |
3803 | -import Ubuntu.Components.Popups 1.0 |
3804 | - |
3805 | -Action { |
3806 | - iconName: "delete" |
3807 | - // TRANSLATORS: this refers to deleting a playlist |
3808 | - text: i18n.tr("Delete") |
3809 | - |
3810 | - property bool primed: false |
3811 | -} |
3812 | |
3813 | === removed file 'common/ListItemActions/EditPlaylist.qml' |
3814 | --- common/ListItemActions/EditPlaylist.qml 2014-09-20 10:50:45 +0000 |
3815 | +++ common/ListItemActions/EditPlaylist.qml 1970-01-01 00:00:00 +0000 |
3816 | @@ -1,35 +0,0 @@ |
3817 | -/* |
3818 | - * Copyright (C) 2014 Andrew Hayzen <ahayzen@gmail.com> |
3819 | - * Daniel Holm <d.holmen@gmail.com> |
3820 | - * Victor Thompson <victor.thompson@gmail.com> |
3821 | - * |
3822 | - * This program is free software; you can redistribute it and/or modify |
3823 | - * it under the terms of the GNU General Public License as published by |
3824 | - * the Free Software Foundation; version 3. |
3825 | - * |
3826 | - * This program is distributed in the hope that it will be useful, |
3827 | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
3828 | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
3829 | - * GNU General Public License for more details. |
3830 | - * |
3831 | - * You should have received a copy of the GNU General Public License |
3832 | - * along with this program. If not, see <http://www.gnu.org/licenses/>. |
3833 | - */ |
3834 | - |
3835 | -import QtQuick 2.3 |
3836 | -import Ubuntu.Components 1.1 |
3837 | -import Ubuntu.Components.Popups 1.0 |
3838 | - |
3839 | -Action { |
3840 | - iconName: "edit" |
3841 | - // TRANSLATORS: this refers to editing a playlist |
3842 | - text: i18n.tr("Edit") |
3843 | - |
3844 | - property bool primed: false |
3845 | - |
3846 | - onTriggered: { |
3847 | - customdebug("Edit playlist") |
3848 | - oldPlaylistName = model.name |
3849 | - PopupUtils.open(editPlaylistDialog, mainView) |
3850 | - } |
3851 | -} |
3852 | |
3853 | === modified file 'common/MusicPage.qml' |
3854 | --- common/MusicPage.qml 2014-08-20 17:35:52 +0000 |
3855 | +++ common/MusicPage.qml 2014-10-21 15:31:33 +0000 |
3856 | @@ -23,6 +23,10 @@ |
3857 | // generic page for music, could be useful for bottomedge implementation |
3858 | Page { |
3859 | id: thisPage |
3860 | + anchors { |
3861 | + bottomMargin: musicToolbar.visible ? musicToolbar.currentHeight : 0 |
3862 | + fill: parent |
3863 | + } |
3864 | |
3865 | onVisibleChanged: { |
3866 | if (visible) { |
3867 | |
3868 | === modified file 'common/MusicRow.qml' |
3869 | --- common/MusicRow.qml 2014-09-20 10:50:45 +0000 |
3870 | +++ common/MusicRow.qml 2014-10-21 15:31:33 +0000 |
3871 | @@ -24,35 +24,54 @@ |
3872 | Row { |
3873 | anchors { |
3874 | left: parent.left |
3875 | - leftMargin: units.gu(1) |
3876 | + leftMargin: units.gu(2) |
3877 | right: parent.right |
3878 | - rightMargin: units.gu(1) |
3879 | + rightMargin: units.gu(2) |
3880 | } |
3881 | |
3882 | property alias covers: coverRow.covers |
3883 | + property bool showCovers: true |
3884 | + property bool isSquare: false |
3885 | property alias pressed: coverRow.pressed |
3886 | property alias column: columnComponent.sourceComponent |
3887 | + property real coverSize: styleMusic.common.albumSize |
3888 | |
3889 | spacing: units.gu(1) |
3890 | |
3891 | CoverRow { |
3892 | id: coverRow |
3893 | + visible: showCovers && !isSquare |
3894 | anchors { |
3895 | top: parent.top |
3896 | topMargin: units.gu(1) |
3897 | } |
3898 | count: covers.length |
3899 | covers: [] |
3900 | - size: styleMusic.common.albumSize |
3901 | + size: coverSize |
3902 | + } |
3903 | + |
3904 | + CoverGrid { |
3905 | + id: coverSquare |
3906 | + anchors { |
3907 | + verticalCenter: parent.verticalCenter |
3908 | + topMargin: units.gu(0.5) |
3909 | + bottomMargin: units.gu(0.5) |
3910 | + leftMargin: units.gu(2) |
3911 | + } |
3912 | + covers: coverRow.covers |
3913 | + size: coverSize |
3914 | + visible: showCovers && isSquare |
3915 | } |
3916 | |
3917 | Loader { |
3918 | id: columnComponent |
3919 | anchors { |
3920 | top: parent.top |
3921 | - topMargin: units.gu(2) |
3922 | + topMargin: units.gu(1) |
3923 | } |
3924 | - width: parent.width - coverRow.width - parent.spacing |
3925 | + width: !showCovers ? parent.width - parent.spacing |
3926 | + : (isSquare ? parent.width - coverSquare.width - parent.spacing |
3927 | + : parent.width - coverRow.width - parent.spacing) |
3928 | |
3929 | onSourceComponentChanged: { |
3930 | for (var i=0; i < item.children.length; i++) { |
3931 | |
3932 | === modified file 'common/SongsPage.qml' |
3933 | --- common/SongsPage.qml 2014-09-20 15:41:33 +0000 |
3934 | +++ common/SongsPage.qml 2014-10-21 15:31:33 +0000 |
3935 | @@ -20,6 +20,7 @@ |
3936 | import QtQuick 2.3 |
3937 | import Ubuntu.Components 1.1 |
3938 | import Ubuntu.Components.ListItems 1.0 as ListItem |
3939 | +import Ubuntu.Components.Popups 1.0 |
3940 | import Ubuntu.MediaScanner 0.1 |
3941 | import Ubuntu.Thumbnailer 0.1 |
3942 | import QtQuick.LocalStorage 2.0 |
3943 | @@ -29,7 +30,6 @@ |
3944 | |
3945 | MusicPage { |
3946 | id: songStackPage |
3947 | - anchors.bottomMargin: units.gu(.5) |
3948 | objectName: "songsPage" |
3949 | visible: false |
3950 | |
3951 | @@ -44,6 +44,47 @@ |
3952 | property alias album: songsModel.album |
3953 | property alias genre: songsModel.genre |
3954 | |
3955 | + state: songStackPage.line1 === i18n.tr("Playlist") ? "playlist" : "album" |
3956 | + states: [ |
3957 | + PageHeadState { |
3958 | + id: albumState |
3959 | + name: "album" |
3960 | + PropertyChanges { |
3961 | + target: songStackPage.head |
3962 | + backAction: albumState.backAction |
3963 | + actions: albumState.actions |
3964 | + } |
3965 | + }, |
3966 | + PageHeadState { |
3967 | + id: playlistState |
3968 | + |
3969 | + name: "playlist" |
3970 | + actions: [ |
3971 | + Action { |
3972 | + objectName: "editPlaylist" |
3973 | + iconName: "edit" |
3974 | + onTriggered: { |
3975 | + var dialog = PopupUtils.open(editPlaylistDialog, mainView) |
3976 | + dialog.oldPlaylistName = line2 |
3977 | + } |
3978 | + }, |
3979 | + Action { |
3980 | + objectName: "deletePlaylist" |
3981 | + iconName: "delete" |
3982 | + onTriggered: { |
3983 | + var dialog = PopupUtils.open(removePlaylistDialog, mainView) |
3984 | + dialog.oldPlaylistName = line2 |
3985 | + } |
3986 | + } |
3987 | + ] |
3988 | + PropertyChanges { |
3989 | + target: songStackPage.head |
3990 | + backAction: playlistState.backAction |
3991 | + actions: playlistState.actions |
3992 | + } |
3993 | + } |
3994 | + ] |
3995 | + |
3996 | SongsModel { |
3997 | id: songsModel |
3998 | store: musicStore |
3999 | @@ -52,160 +93,141 @@ |
4000 | ListView { |
4001 | id: albumtrackslist |
4002 | anchors { |
4003 | - bottomMargin: wideAspect ? musicToolbar.fullHeight : musicToolbar.mouseAreaOffset + musicToolbar.minimizedHeight |
4004 | fill: parent |
4005 | } |
4006 | delegate: albumTracksDelegate |
4007 | model: isAlbum ? songsModel : albumTracksModel.model |
4008 | objectName: "songspage-listview" |
4009 | width: parent.width |
4010 | - header: ListItem.Standard { |
4011 | - id: albumInfo |
4012 | - height: units.gu(22) |
4013 | - |
4014 | - CoverRow { |
4015 | - id: albumImage |
4016 | - anchors { |
4017 | - top: parent.top |
4018 | - left: parent.left |
4019 | - margins: units.gu(1) |
4020 | - } |
4021 | - count: songStackPage.covers.length |
4022 | - size: units.gu(20) |
4023 | - covers: songStackPage.covers |
4024 | + header: BlurredHeader { |
4025 | + rightColumn: Column { |
4026 | spacing: units.gu(2) |
4027 | - } |
4028 | - |
4029 | - Label { |
4030 | - id: albumArtist |
4031 | - objectName: "songsPageHeaderAlbumArtist" |
4032 | - wrapMode: Text.NoWrap |
4033 | - maximumLineCount: 1 |
4034 | - fontSize: "small" |
4035 | - color: styleMusic.common.subtitle |
4036 | - anchors.left: albumImage.right |
4037 | - anchors.leftMargin: units.gu(1) |
4038 | - anchors.top: parent.top |
4039 | - anchors.topMargin: units.gu(1.5) |
4040 | - anchors.right: parent.right |
4041 | - anchors.rightMargin: units.gu(1.5) |
4042 | - elide: Text.ElideRight |
4043 | - text: line1 |
4044 | - } |
4045 | - Label { |
4046 | - id: albumLabel |
4047 | - wrapMode: Text.NoWrap |
4048 | - maximumLineCount: 2 |
4049 | - fontSize: "medium" |
4050 | - color: styleMusic.common.music |
4051 | - anchors.left: albumImage.right |
4052 | - anchors.leftMargin: units.gu(1) |
4053 | - anchors.top: albumArtist.bottom |
4054 | - anchors.topMargin: units.gu(0.8) |
4055 | - anchors.right: parent.right |
4056 | - anchors.rightMargin: units.gu(1.5) |
4057 | - elide: Text.ElideRight |
4058 | - text: line2 |
4059 | - } |
4060 | - Label { |
4061 | - id: albumYear |
4062 | - wrapMode: Text.NoWrap |
4063 | - maximumLineCount: 1 |
4064 | - fontSize: "x-small" |
4065 | - color: styleMusic.common.subtitle |
4066 | - anchors.left: albumImage.right |
4067 | - anchors.leftMargin: units.gu(1) |
4068 | - anchors.top: albumLabel.bottom |
4069 | - anchors.topMargin: units.gu(2) |
4070 | - anchors.right: parent.right |
4071 | - anchors.rightMargin: units.gu(1.5) |
4072 | - elide: Text.ElideRight |
4073 | - text: isAlbum && line1 !== i18n.tr("Genre") ? year + " | " + i18n.tr("%1 song", "%1 songs", albumtrackslist.count).arg(albumtrackslist.count) |
4074 | - : i18n.tr("%1 song", "%1 songs", albumtrackslist.count).arg(albumtrackslist.count) |
4075 | - |
4076 | - } |
4077 | - |
4078 | - // Play |
4079 | - Rectangle { |
4080 | - id: playRow |
4081 | - anchors.top: albumYear.bottom |
4082 | - anchors.topMargin: units.gu(1) |
4083 | - anchors.left: albumImage.right |
4084 | - anchors.leftMargin: units.gu(1) |
4085 | - color: "transparent" |
4086 | - height: units.gu(4) |
4087 | - width: units.gu(15) |
4088 | - Icon { |
4089 | - id: playTrack |
4090 | - objectName: "songspage-playtrack" |
4091 | - anchors.verticalCenter: parent.verticalCenter |
4092 | - name: "media-playback-start" |
4093 | - height: styleMusic.common.expandedItem |
4094 | - width: styleMusic.common.expandedItem |
4095 | - } |
4096 | - Label { |
4097 | - anchors.left: playTrack.right |
4098 | - anchors.leftMargin: units.gu(0.5) |
4099 | - anchors.verticalCenter: parent.verticalCenter |
4100 | - fontSize: "small" |
4101 | - color: styleMusic.common.subtitle |
4102 | - width: parent.width - playTrack.width - units.gu(1) |
4103 | + Button { |
4104 | + id: shuffleRow |
4105 | + height: units.gu(4) |
4106 | + strokeColor: UbuntuColors.green |
4107 | + width: units.gu(15) |
4108 | + Text { |
4109 | + anchors { |
4110 | + centerIn: parent |
4111 | + } |
4112 | + color: "white" |
4113 | + text: i18n.tr("Shuffle") |
4114 | + } |
4115 | + MouseArea { |
4116 | + anchors.fill: parent |
4117 | + onClicked: { |
4118 | + shuffleModel(albumtrackslist.model) // play track |
4119 | + |
4120 | + if (isAlbum && songStackPage.line1 !== i18n.tr("Genre")) { |
4121 | + Library.addRecent(songStackPage.line2, songStackPage.line1, songStackPage.covers[0], songStackPage.line2, "album") |
4122 | + recentModel.filterRecent() |
4123 | + } else if (songStackPage.line1 === i18n.tr("Playlist")) { |
4124 | + Library.addRecent(songStackPage.line2, "Playlist", songStackPage.covers[0], songStackPage.line2, "playlist") |
4125 | + recentModel.filterRecent() |
4126 | + } |
4127 | + } |
4128 | + } |
4129 | + } |
4130 | + Button { |
4131 | + id: queueAllRow |
4132 | + height: units.gu(4) |
4133 | + strokeColor: UbuntuColors.green |
4134 | + width: units.gu(15) |
4135 | + Text { |
4136 | + anchors { |
4137 | + centerIn: parent |
4138 | + } |
4139 | + color: "white" |
4140 | + text: i18n.tr("Queue all") |
4141 | + } |
4142 | + MouseArea { |
4143 | + anchors.fill: parent |
4144 | + onClicked: addQueueFromModel(albumtrackslist.model) |
4145 | + } |
4146 | + } |
4147 | + Button { |
4148 | + id: playRow |
4149 | + color: UbuntuColors.green |
4150 | + height: units.gu(4) |
4151 | text: i18n.tr("Play all") |
4152 | - wrapMode: Text.WordWrap |
4153 | - maximumLineCount: 3 |
4154 | - } |
4155 | - MouseArea { |
4156 | - anchors.fill: parent |
4157 | - onClicked: { |
4158 | - trackClicked(albumtrackslist.model, 0) // play track |
4159 | + width: units.gu(15) |
4160 | + MouseArea { |
4161 | + anchors.fill: parent |
4162 | + onClicked: { |
4163 | + trackClicked(albumtrackslist.model, 0) // play track |
4164 | |
4165 | - if (isAlbum && songStackPage.line1 !== i18n.tr("Genre")) { |
4166 | - Library.addRecent(songStackPage.line2, songStackPage.line1, songStackPage.covers[0], songStackPage.line2, "album") |
4167 | - mainView.hasRecent = true |
4168 | - recentModel.filterRecent() |
4169 | - } else if (songStackPage.line1 === i18n.tr("Playlist")) { |
4170 | - Library.addRecent(songStackPage.line2, "Playlist", songStackPage.covers[0], songStackPage.line2, "playlist") |
4171 | - mainView.hasRecent = true |
4172 | - recentModel.filterRecent() |
4173 | + if (isAlbum && songStackPage.line1 !== i18n.tr("Genre")) { |
4174 | + Library.addRecent(songStackPage.line2, songStackPage.line1, songStackPage.covers[0], songStackPage.line2, "album") |
4175 | + recentModel.filterRecent() |
4176 | + } else if (songStackPage.line1 === i18n.tr("Playlist")) { |
4177 | + Library.addRecent(songStackPage.line2, "Playlist", songStackPage.covers[0], songStackPage.line2, "playlist") |
4178 | + recentModel.filterRecent() |
4179 | + } |
4180 | } |
4181 | } |
4182 | } |
4183 | } |
4184 | - |
4185 | - // Queue |
4186 | - Rectangle { |
4187 | - id: queueAllRow |
4188 | - anchors.top: playRow.bottom |
4189 | - anchors.topMargin: units.gu(1) |
4190 | - anchors.left: albumImage.right |
4191 | - anchors.leftMargin: units.gu(1) |
4192 | - color: "transparent" |
4193 | - height: units.gu(4) |
4194 | - width: units.gu(15) |
4195 | - Icon { |
4196 | - id: queueAll |
4197 | - objectName: "songspage-queue-all" |
4198 | - anchors.verticalCenter: parent.verticalCenter |
4199 | - name: "add" |
4200 | - height: styleMusic.common.expandedItem |
4201 | - width: styleMusic.common.expandedItem |
4202 | - } |
4203 | - Label { |
4204 | - anchors.left: queueAll.right |
4205 | - anchors.leftMargin: units.gu(0.5) |
4206 | - anchors.verticalCenter: parent.verticalCenter |
4207 | - fontSize: "small" |
4208 | - color: styleMusic.common.subtitle |
4209 | - width: parent.width - queueAll.width - units.gu(1) |
4210 | - text: i18n.tr("Add to queue") |
4211 | - wrapMode: Text.WordWrap |
4212 | - maximumLineCount: 3 |
4213 | - } |
4214 | - MouseArea { |
4215 | - anchors.fill: parent |
4216 | - onClicked: { |
4217 | - addQueueFromModel(albumtrackslist.model) |
4218 | - } |
4219 | + coverSources: songStackPage.covers |
4220 | + height: songStackPage.line1 !== i18n.tr("Playlist") && |
4221 | + songStackPage.line1 !== i18n.tr("Genre") ? |
4222 | + units.gu(33) : units.gu(30) |
4223 | + bottomColumn: Column { |
4224 | + Label { |
4225 | + id: albumLabel |
4226 | + anchors { |
4227 | + left: parent.left |
4228 | + right: parent.right |
4229 | + } |
4230 | + color: styleMusic.common.music |
4231 | + elide: Text.ElideRight |
4232 | + fontSize: "x-large" |
4233 | + maximumLineCount: 1 |
4234 | + text: line2 |
4235 | + wrapMode: Text.NoWrap |
4236 | + } |
4237 | + |
4238 | + Item { |
4239 | + height: units.gu(0.75) |
4240 | + width: parent.width |
4241 | + visible: albumArtist.visible |
4242 | + } |
4243 | + |
4244 | + Label { |
4245 | + id: albumArtist |
4246 | + anchors { |
4247 | + left: parent.left |
4248 | + right: parent.right |
4249 | + } |
4250 | + color: styleMusic.common.subtitle |
4251 | + elide: Text.ElideRight |
4252 | + fontSize: "small" |
4253 | + maximumLineCount: 1 |
4254 | + objectName: "songsPageHeaderAlbumArtist" |
4255 | + text: line1 |
4256 | + visible: text !== i18n.tr("Playlist") && |
4257 | + text !== i18n.tr("Genre") |
4258 | + wrapMode: Text.NoWrap |
4259 | + } |
4260 | + |
4261 | + Item { |
4262 | + height: units.gu(1) |
4263 | + width: parent.width |
4264 | + } |
4265 | + |
4266 | + Label { |
4267 | + id: albumYear |
4268 | + anchors { |
4269 | + left: parent.left |
4270 | + right: parent.right |
4271 | + } |
4272 | + color: styleMusic.common.subtitle |
4273 | + elide: Text.ElideRight |
4274 | + fontSize: "small" |
4275 | + maximumLineCount: 1 |
4276 | + text: isAlbum && line1 !== i18n.tr("Genre") ? year + " | " + i18n.tr("%1 song", "%1 songs", albumtrackslist.count).arg(albumtrackslist.count) |
4277 | + : i18n.tr("%1 song", "%1 songs", albumtrackslist.count).arg(albumtrackslist.count) |
4278 | + wrapMode: Text.NoWrap |
4279 | } |
4280 | } |
4281 | } |
4282 | @@ -219,7 +241,8 @@ |
4283 | objectName: "songsPageListItem" + index |
4284 | iconFrame: false |
4285 | progression: false |
4286 | - height: styleMusic.common.itemHeight |
4287 | + showDivider: false |
4288 | + height: units.gu(6) |
4289 | |
4290 | leftSideAction: songStackPage.line1 === i18n.tr("Playlist") |
4291 | ? playlistRemoveAction.item : null |
4292 | @@ -239,11 +262,9 @@ |
4293 | |
4294 | if (isAlbum && songStackPage.line1 !== i18n.tr("Genre")) { |
4295 | Library.addRecent(songStackPage.line2, songStackPage.line1, model.art, songStackPage.line2, "album") |
4296 | - mainView.hasRecent = true |
4297 | recentModel.filterRecent() |
4298 | } else if (songStackPage.line1 === i18n.tr("Playlist")) { |
4299 | Library.addRecent(songStackPage.line2, "Playlist", songStackPage.covers[0], songStackPage.line2, "playlist") |
4300 | - mainView.hasRecent = true |
4301 | recentModel.filterRecent() |
4302 | } |
4303 | } |
4304 | @@ -272,30 +293,23 @@ |
4305 | |
4306 | MusicRow { |
4307 | id: musicRow |
4308 | - covers: model.art !== undefined ? [{art: model.art}] : [{author: model.author, album: model.album}] |
4309 | + covers: [] |
4310 | + showCovers: false |
4311 | column: Column { |
4312 | - spacing: units.gu(1) |
4313 | + Label { |
4314 | + id: trackTitle |
4315 | + color: styleMusic.common.music |
4316 | + fontSize: "small" |
4317 | + objectName: "songspage-tracktitle" |
4318 | + text: model.title |
4319 | + } |
4320 | + |
4321 | Label { |
4322 | id: trackArtist |
4323 | color: styleMusic.common.subtitle |
4324 | fontSize: "x-small" |
4325 | text: model.author |
4326 | } |
4327 | - |
4328 | - Label { |
4329 | - id: trackTitle |
4330 | - color: styleMusic.common.subtitle |
4331 | - fontSize: "medium" |
4332 | - objectName: "songspage-tracktitle" |
4333 | - text: model.title |
4334 | - } |
4335 | - |
4336 | - Label { |
4337 | - id: trackAlbum |
4338 | - color: styleMusic.common.subtitle |
4339 | - fontSize: "xx-small" |
4340 | - text: model.album |
4341 | - } |
4342 | } |
4343 | } |
4344 | |
4345 | @@ -309,4 +323,103 @@ |
4346 | } |
4347 | } |
4348 | } |
4349 | + |
4350 | + // Edit name of playlist dialog |
4351 | + Component { |
4352 | + id: editPlaylistDialog |
4353 | + Dialog { |
4354 | + id: dialogEditPlaylist |
4355 | + // TRANSLATORS: this is a title of a dialog with a prompt to rename a playlist |
4356 | + title: i18n.tr("Change name") |
4357 | + text: i18n.tr("Enter the new name of the playlist.") |
4358 | + |
4359 | + property alias oldPlaylistName: playlistName.placeholderText |
4360 | + |
4361 | + TextField { |
4362 | + id: playlistName |
4363 | + inputMethodHints: Qt.ImhNoPredictiveText |
4364 | + |
4365 | + onPlaceholderTextChanged: text = placeholderText |
4366 | + } |
4367 | + Label { |
4368 | + id: editplaylistoutput |
4369 | + color: "red" |
4370 | + visible: false |
4371 | + } |
4372 | + |
4373 | + Button { |
4374 | + text: i18n.tr("Change") |
4375 | + color: styleMusic.dialog.confirmButtonColor |
4376 | + onClicked: { |
4377 | + editplaylistoutput.visible = true |
4378 | + |
4379 | + if (playlistName.text.length > 0) { // make sure something is acually inputed |
4380 | + console.debug("Debug: User changed name from "+playlistName.placeholderText+" to "+playlistName.text) |
4381 | + |
4382 | + if (Playlists.renamePlaylist(playlistName.placeholderText, playlistName.text) === true) { |
4383 | + playlistModel.filterPlaylists() |
4384 | + |
4385 | + if (Library.recentContainsPlaylist(playlistName.placeholderText)) { |
4386 | + Library.recentRenamePlaylist(playlistName.placeholderText, playlistName.text) |
4387 | + recentModel.filterRecent() |
4388 | + } |
4389 | + |
4390 | + PopupUtils.close(dialogEditPlaylist) |
4391 | + |
4392 | + line2 = playlistName.text |
4393 | + } |
4394 | + else { |
4395 | + editplaylistoutput.text = i18n.tr("Playlist already exists") |
4396 | + } |
4397 | + } |
4398 | + else { |
4399 | + editplaylistoutput.text = i18n.tr("Please type in a name.") |
4400 | + } |
4401 | + } |
4402 | + } |
4403 | + Button { |
4404 | + text: i18n.tr("Cancel") |
4405 | + color: styleMusic.dialog.cancelButtonColor |
4406 | + onClicked: PopupUtils.close(dialogEditPlaylist) |
4407 | + } |
4408 | + } |
4409 | + } |
4410 | + |
4411 | + // Remove playlist dialog |
4412 | + Component { |
4413 | + id: removePlaylistDialog |
4414 | + Dialog { |
4415 | + id: dialogRemovePlaylist |
4416 | + // TRANSLATORS: this is a title of a dialog with a prompt to delete a playlist |
4417 | + title: i18n.tr("Are you sure?") |
4418 | + text: i18n.tr("This will delete your playlist.") |
4419 | + |
4420 | + property string oldPlaylistName |
4421 | + |
4422 | + Button { |
4423 | + text: i18n.tr("Remove") |
4424 | + color: styleMusic.dialog.confirmButtonColor |
4425 | + onClicked: { |
4426 | + // removing playlist |
4427 | + Playlists.removePlaylist(dialogRemovePlaylist.oldPlaylistName) |
4428 | + |
4429 | + playlistModel.filterPlaylists(); |
4430 | + |
4431 | + if (Library.recentContainsPlaylist(dialogRemovePlaylist.oldPlaylistName)) { |
4432 | + Library.recentRemovePlaylist(dialogRemovePlaylist.oldPlaylistName) |
4433 | + recentModel.filterRecent() |
4434 | + } |
4435 | + |
4436 | + PopupUtils.close(dialogRemovePlaylist) |
4437 | + |
4438 | + musicToolbar.goBack() |
4439 | + } |
4440 | + } |
4441 | + Button { |
4442 | + text: i18n.tr("Cancel") |
4443 | + color: styleMusic.dialog.cancelButtonColor |
4444 | + onClicked: PopupUtils.close(dialogRemovePlaylist) |
4445 | + } |
4446 | + } |
4447 | + } |
4448 | } |
4449 | |
4450 | === modified file 'music-app.qml' |
4451 | --- music-app.qml 2014-10-16 22:19:13 +0000 |
4452 | +++ music-app.qml 2014-10-21 15:31:33 +0000 |
4453 | @@ -40,18 +40,13 @@ |
4454 | id: mainView |
4455 | useDeprecatedToolbar: false |
4456 | |
4457 | - // Use toolbar color for header |
4458 | - headerColor: styleMusic.toolbar.fullBackgroundColor |
4459 | - backgroundColor: styleMusic.toolbar.fullBackgroundColor |
4460 | + backgroundColor: "#1e1e23" |
4461 | + headerColor: "#1e1e23" |
4462 | |
4463 | // Global keyboard shortcuts |
4464 | focus: true |
4465 | Keys.onPressed: { |
4466 | - if (event.key === Qt.Key_Alt) { |
4467 | - // On alt key press show toolbar and start autohide timer |
4468 | - musicToolbar.showToolbar(); |
4469 | - } |
4470 | - else if(event.key === Qt.Key_Escape) { |
4471 | + if(event.key === Qt.Key_Escape) { |
4472 | musicToolbar.goBack(); // Esc Go back |
4473 | } |
4474 | else if(event.modifiers === Qt.AltModifier) { |
4475 | @@ -94,13 +89,11 @@ |
4476 | } |
4477 | break; |
4478 | case Qt.Key_J: // Ctrl+J Jump to playing song |
4479 | - nowPlaying.visible = true; |
4480 | - nowPlaying.positionAt(player.currentIndex); |
4481 | - musicToolbar.showToolbar(); |
4482 | + tabs.pushNowPlaying() |
4483 | + nowPlaying.isListView = true; |
4484 | break; |
4485 | case Qt.Key_N: // Ctrl+N Show now playing |
4486 | - nowPlaying.visible = true; |
4487 | - musicToolbar.showToolbar(); |
4488 | + tabs.pushNowPlaying() |
4489 | break; |
4490 | case Qt.Key_P: // Ctrl+P Toggle playing state |
4491 | player.toggle(); |
4492 | @@ -218,7 +211,6 @@ |
4493 | |
4494 | // Add album to recent list |
4495 | Library.addRecent(songsAlbumArtistModel.album, songsAlbumArtistModel.artist, songsAlbumArtistModel.art, songsAlbumArtistModel.album, "album") |
4496 | - mainView.hasRecent = true |
4497 | recentModel.filterRecent() |
4498 | } |
4499 | |
4500 | @@ -583,7 +575,9 @@ |
4501 | // TODO: Switch tabs back and forth to get the background color in the |
4502 | // header to work properly. |
4503 | tabs.selectedTabIndex = 1 |
4504 | - tabs.selectedTabIndex = 0 |
4505 | + |
4506 | + // goto Recent if there are items otherwise go to Albums |
4507 | + tabs.selectedTabIndex = Library.isRecentEmpty() ? 2 : 0 |
4508 | |
4509 | // Run post load |
4510 | tabs.ensurePopulated(tabs.selectedTab); |
4511 | @@ -591,28 +585,20 @@ |
4512 | if (args.values.url) { |
4513 | uriHandler.process(args.values.url, true); |
4514 | } |
4515 | - |
4516 | - // Show toolbar and start timer if there is music |
4517 | - if (!emptyPage.noMusic) { |
4518 | - musicToolbar.showToolbar(); |
4519 | - musicToolbar.startAutohideTimer(); |
4520 | - } |
4521 | } |
4522 | |
4523 | // VARIABLES |
4524 | property string musicName: i18n.tr("Music") |
4525 | property string appVersion: '1.2' |
4526 | - property bool hasRecent: !Library.isRecentEmpty() |
4527 | property bool scrobble: false |
4528 | property string lastfmusername |
4529 | property string lastfmpassword |
4530 | property string timestamp // used to scrobble |
4531 | property var chosenElement: null |
4532 | - property bool toolbarShown: musicToolbar.shown |
4533 | + property bool toolbarShown: musicToolbar.visible |
4534 | property bool selectedAlbum: false |
4535 | |
4536 | signal listItemSwiping(int i) |
4537 | - signal onToolbarShownChanged(bool shown, var currentPage, var currentTab) |
4538 | |
4539 | property bool wideAspect: width >= units.gu(70) && loadedUI |
4540 | property bool loadedUI: false // property to detect if the UI has finished |
4541 | @@ -693,9 +679,6 @@ |
4542 | |
4543 | // Show the Now Playing page and make sure the track is visible |
4544 | tabs.pushNowPlaying(); |
4545 | - nowPlaying.ensureVisibleIndex = index; |
4546 | - |
4547 | - musicToolbar.showToolbar(); |
4548 | } |
4549 | else { |
4550 | player.source = file; |
4551 | @@ -711,10 +694,9 @@ |
4552 | } |
4553 | |
4554 | // Show the Now Playing page and make sure the track is visible |
4555 | - tabs.pushNowPlaying(); |
4556 | - nowPlaying.ensureVisibleIndex = index; |
4557 | - |
4558 | - musicToolbar.showToolbar(); |
4559 | + if (!nowPlaying.isListView) { |
4560 | + tabs.pushNowPlaying(); |
4561 | + } |
4562 | } |
4563 | |
4564 | function playRandomSong(shuffle) |
4565 | @@ -730,6 +712,17 @@ |
4566 | trackClicked(allSongsModel, index, true) |
4567 | } |
4568 | |
4569 | + function shuffleModel(model) |
4570 | + { |
4571 | + var now = new Date(); |
4572 | + var seed = now.getSeconds(); |
4573 | + var index = Math.floor(model.count * Math.random(seed)); |
4574 | + |
4575 | + player.shuffle = true; |
4576 | + |
4577 | + trackClicked(model, index, true) |
4578 | + } |
4579 | + |
4580 | // Load mediascanner store |
4581 | MediaStore { |
4582 | id: musicStore |
4583 | @@ -881,10 +874,6 @@ |
4584 | id: searchSheet |
4585 | } |
4586 | |
4587 | - // Blurred background |
4588 | - BlurredBackground { |
4589 | - } |
4590 | - |
4591 | // Popover for tracks, queue and add to playlist, for example |
4592 | Component { |
4593 | id: trackPopoverComponent |
4594 | @@ -987,6 +976,7 @@ |
4595 | |
4596 | MusicToolbar { |
4597 | id: musicToolbar |
4598 | + visible: nowPlaying.isListView || !nowPlaying.visible |
4599 | objectName: "musicToolbarObject" |
4600 | z: 200 // put on top of everything else |
4601 | } |
4602 | @@ -997,7 +987,6 @@ |
4603 | Tabs { |
4604 | id: tabs |
4605 | anchors { |
4606 | - bottomMargin: wideAspect ? musicToolbar.fullHeight : undefined |
4607 | fill: parent |
4608 | } |
4609 | |
4610 | @@ -1124,6 +1113,8 @@ |
4611 | if (mainPageStack.currentPage !== nowPlaying) { |
4612 | mainPageStack.push(nowPlaying); |
4613 | } |
4614 | + |
4615 | + nowPlaying.isListView = false; // ensure full view |
4616 | } |
4617 | |
4618 | Component.onCompleted: musicToolbar.currentTab = selectedTab |
4619 | |
4620 | === added file 'po/ca@valencia.po' |
4621 | --- po/ca@valencia.po 1970-01-01 00:00:00 +0000 |
4622 | +++ po/ca@valencia.po 2014-10-21 15:31:33 +0000 |
4623 | @@ -0,0 +1,459 @@ |
4624 | +# Catalan (Valencian) translation for music-app |
4625 | +# Copyright (c) 2014 Rosetta Contributors and Canonical Ltd 2014 |
4626 | +# This file is distributed under the same license as the music-app package. |
4627 | +# FIRST AUTHOR <EMAIL@ADDRESS>, 2014. |
4628 | +# |
4629 | +msgid "" |
4630 | +msgstr "" |
4631 | +"Project-Id-Version: music-app\n" |
4632 | +"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n" |
4633 | +"POT-Creation-Date: 2014-10-20 15:09+0100\n" |
4634 | +"PO-Revision-Date: 2014-10-17 05:37+0000\n" |
4635 | +"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" |
4636 | +"Language-Team: Catalan (Valencian) <ca@valencia@li.org>\n" |
4637 | +"MIME-Version: 1.0\n" |
4638 | +"Content-Type: text/plain; charset=UTF-8\n" |
4639 | +"Content-Transfer-Encoding: 8bit\n" |
4640 | +"Plural-Forms: nplurals=2; plural=n != 1;\n" |
4641 | +"X-Launchpad-Export-Date: 2014-10-21 07:54+0000\n" |
4642 | +"X-Generator: Launchpad (build 17203)\n" |
4643 | + |
4644 | +#: ../LoginLastFM.qml:48 ../MusicSettings.qml:134 ../MusicSettings.qml:142 |
4645 | +msgid "Last.fm" |
4646 | +msgstr "Last.fm" |
4647 | + |
4648 | +#: ../LoginLastFM.qml:54 |
4649 | +msgid "Login to be able to scrobble." |
4650 | +msgstr "Inicia una sessió per poder navegar." |
4651 | + |
4652 | +#: ../LoginLastFM.qml:62 |
4653 | +msgid "Username" |
4654 | +msgstr "Nom d'usuari" |
4655 | + |
4656 | +#: ../LoginLastFM.qml:72 |
4657 | +msgid "Password" |
4658 | +msgstr "Contrasenya" |
4659 | + |
4660 | +#: ../LoginLastFM.qml:94 |
4661 | +msgid "Login" |
4662 | +msgstr "Inicia la sessió" |
4663 | + |
4664 | +#: ../LoginLastFM.qml:101 |
4665 | +msgid "Trying to login..." |
4666 | +msgstr "S'està intentant iniciar la sessió..." |
4667 | + |
4668 | +#: ../LoginLastFM.qml:115 |
4669 | +msgid "Login Successful" |
4670 | +msgstr "Inici de sessió correcte" |
4671 | + |
4672 | +#: ../LoginLastFM.qml:121 |
4673 | +msgid "Login Failed" |
4674 | +msgstr "Error en l'inici de sessió" |
4675 | + |
4676 | +#: ../LoginLastFM.qml:127 |
4677 | +msgid "You forgot to set your username and/or password" |
4678 | +msgstr "Vos heu oblidat d'establir el vostre nom d'usuari i/o la contrasenya" |
4679 | + |
4680 | +#: ../MusicAlbums.qml:29 |
4681 | +msgid "Albums" |
4682 | +msgstr "Àlbums" |
4683 | + |
4684 | +#: ../MusicAlbums.qml:57 ../MusicStart.qml:71 ../common/AlbumsPage.qml:155 |
4685 | +msgid "Album" |
4686 | +msgstr "Àlbum" |
4687 | + |
4688 | +#: ../MusicArtists.qml:37 |
4689 | +msgid "Artists" |
4690 | +msgstr "Artistes" |
4691 | + |
4692 | +#: ../MusicArtists.qml:78 |
4693 | +msgid "Artist" |
4694 | +msgstr "Artista" |
4695 | + |
4696 | +#: ../MusicNowPlaying.qml:33 |
4697 | +msgid "Queue" |
4698 | +msgstr "" |
4699 | + |
4700 | +#: ../MusicNowPlaying.qml:33 |
4701 | +msgid "Now playing" |
4702 | +msgstr "" |
4703 | + |
4704 | +#. TRANSLATORS: this is the name of the playlists page shown in the tab header. |
4705 | +#. Remember to keep the translation short to fit the screen width |
4706 | +#: ../MusicPlaylists.qml:35 |
4707 | +msgid "Playlists" |
4708 | +msgstr "Llistes de reproducció" |
4709 | + |
4710 | +#: ../MusicPlaylists.qml:61 ../MusicaddtoPlaylist.qml:105 |
4711 | +#: ../common/SongsPage.qml:228 ../common/SongsPage.qml:229 |
4712 | +#, qt-format |
4713 | +msgid "%1 song" |
4714 | +msgid_plural "%1 songs" |
4715 | +msgstr[0] "%1 tema" |
4716 | +msgstr[1] "%1 temes" |
4717 | + |
4718 | +#: ../MusicPlaylists.qml:66 ../MusicPlaylists.qml:70 ../MusicStart.qml:57 |
4719 | +#: ../MusicStart.qml:71 ../common/SongsPage.qml:47 ../common/SongsPage.qml:125 |
4720 | +#: ../common/SongsPage.qml:163 ../common/SongsPage.qml:172 |
4721 | +#: ../common/SongsPage.qml:208 ../common/SongsPage.qml:247 |
4722 | +#: ../common/SongsPage.qml:249 ../common/SongsPage.qml:266 |
4723 | +msgid "Playlist" |
4724 | +msgstr "Llista de reproducció" |
4725 | + |
4726 | +#: ../MusicSearch.qml:44 ../MusicSearch.qml:75 ../music-app.qml:88 |
4727 | +#: ../music-app.qml:134 ../music-app.qml:140 |
4728 | +msgid "Search" |
4729 | +msgstr "Cerca" |
4730 | + |
4731 | +#: ../MusicSettings.qml:30 ../music-app.qml:184 |
4732 | +msgid "Settings" |
4733 | +msgstr "Paràmetres" |
4734 | + |
4735 | +#: ../MusicSettings.qml:70 |
4736 | +msgid "Equaliser" |
4737 | +msgstr "Equalitzador" |
4738 | + |
4739 | +#: ../MusicSettings.qml:71 |
4740 | +msgid "Default" |
4741 | +msgstr "Per defecte" |
4742 | + |
4743 | +#: ../MusicSettings.qml:72 |
4744 | +msgid "Acoustic" |
4745 | +msgstr "Acústic" |
4746 | + |
4747 | +#: ../MusicSettings.qml:73 |
4748 | +msgid "Classical" |
4749 | +msgstr "Clàssica" |
4750 | + |
4751 | +#: ../MusicSettings.qml:74 |
4752 | +msgid "Electronic" |
4753 | +msgstr "Electrònica" |
4754 | + |
4755 | +#: ../MusicSettings.qml:75 |
4756 | +msgid "Flat" |
4757 | +msgstr "Pla" |
4758 | + |
4759 | +#: ../MusicSettings.qml:76 |
4760 | +msgid "Hip Hop" |
4761 | +msgstr "Hip Hop" |
4762 | + |
4763 | +#: ../MusicSettings.qml:77 |
4764 | +msgid "Jazz" |
4765 | +msgstr "Jazz" |
4766 | + |
4767 | +#: ../MusicSettings.qml:78 |
4768 | +msgid "Metal" |
4769 | +msgstr "Metal" |
4770 | + |
4771 | +#: ../MusicSettings.qml:79 |
4772 | +msgid "Pop" |
4773 | +msgstr "Pop" |
4774 | + |
4775 | +#: ../MusicSettings.qml:80 |
4776 | +msgid "Rock" |
4777 | +msgstr "Rock" |
4778 | + |
4779 | +#: ../MusicSettings.qml:81 |
4780 | +msgid "Custom" |
4781 | +msgstr "Personalitzada" |
4782 | + |
4783 | +#: ../MusicSettings.qml:101 |
4784 | +msgid "" |
4785 | +"Snap to current song \n" |
4786 | +"when opening toolbar" |
4787 | +msgstr "" |
4788 | +"Salta a la cançó actual \n" |
4789 | +"quan s'estiga obrint una barra d'eines" |
4790 | + |
4791 | +#: ../MusicSettings.qml:121 |
4792 | +msgid "Accounts" |
4793 | +msgstr "Comptes" |
4794 | + |
4795 | +#: ../MusicSettings.qml:135 |
4796 | +msgid "Login to scrobble and import playlists" |
4797 | +msgstr "Inicieu una sessió per navegar i importar llistes de reproducció" |
4798 | + |
4799 | +#: ../MusicSettings.qml:158 |
4800 | +msgid "Music Streaming" |
4801 | +msgstr "Transmissió de música" |
4802 | + |
4803 | +#: ../MusicSettings.qml:168 |
4804 | +msgid "Ubuntu One" |
4805 | +msgstr "Ubuntu One" |
4806 | + |
4807 | +#: ../MusicSettings.qml:169 |
4808 | +msgid "Sign in to stream your cloud music" |
4809 | +msgstr "Inicieu una sessió per transmetre la vostra música al núvol" |
4810 | + |
4811 | +#: ../MusicSettings.qml:185 |
4812 | +msgid "Stream only on Wi-Fi" |
4813 | +msgstr "Transmet únicament amb la connexió inalàmbrica" |
4814 | + |
4815 | +#: ../MusicSettings.qml:219 |
4816 | +msgid "Clean everything!" |
4817 | +msgstr "Neteja-ho tot" |
4818 | + |
4819 | +#: ../MusicStart.qml:35 |
4820 | +msgid "Recent" |
4821 | +msgstr "Recents" |
4822 | + |
4823 | +#: ../MusicToolbar.qml:150 |
4824 | +msgid "Tap to shuffle music" |
4825 | +msgstr "" |
4826 | + |
4827 | +#: ../MusicTracks.qml:35 |
4828 | +msgid "Songs" |
4829 | +msgstr "Temes" |
4830 | + |
4831 | +#: ../MusicaddtoPlaylist.qml:41 |
4832 | +msgid "Select playlist" |
4833 | +msgstr "Seleccioneu una llista de reproducció" |
4834 | + |
4835 | +#: ../MusicaddtoPlaylist.qml:48 |
4836 | +msgid "New playlist" |
4837 | +msgstr "Llista de reproducció nova" |
4838 | + |
4839 | +#: ../common/AlbumsPage.qml:55 ../common/SongsPage.qml:115 |
4840 | +msgid "Shuffle" |
4841 | +msgstr "" |
4842 | + |
4843 | +#: ../common/AlbumsPage.qml:72 ../common/SongsPage.qml:142 |
4844 | +msgid "Queue all" |
4845 | +msgstr "" |
4846 | + |
4847 | +#: ../common/AlbumsPage.qml:83 ../common/SongsPage.qml:153 |
4848 | +msgid "Play all" |
4849 | +msgstr "Reprodueix-ho tot" |
4850 | + |
4851 | +#: ../common/AlbumsPage.qml:124 |
4852 | +#, qt-format |
4853 | +msgid "%1 album" |
4854 | +msgid_plural "%1 albums" |
4855 | +msgstr[0] "%1 àlbum" |
4856 | +msgstr[1] "%1 àlbums" |
4857 | + |
4858 | +#: ../common/ListItemActions/AddToPlaylist.qml:25 ../music-app.qml:905 |
4859 | +msgid "Add to playlist" |
4860 | +msgstr "Afig a la llista de reproducció" |
4861 | + |
4862 | +#: ../common/ListItemActions/AddToQueue.qml:25 |
4863 | +msgid "Add to Queue" |
4864 | +msgstr "Afig a la cua" |
4865 | + |
4866 | +#: ../common/ListItemActions/Remove.qml:27 ../common/SongsPage.qml:400 |
4867 | +msgid "Remove" |
4868 | +msgstr "Suprimeix-la" |
4869 | + |
4870 | +#: ../common/LoadingSpinnerComponent.qml:47 |
4871 | +msgid "Loading..." |
4872 | +msgstr "S'està carregant..." |
4873 | + |
4874 | +#: ../common/SongsPage.qml:122 ../common/SongsPage.qml:160 |
4875 | +#: ../common/SongsPage.qml:173 ../common/SongsPage.qml:209 |
4876 | +#: ../common/SongsPage.qml:228 ../common/SongsPage.qml:263 |
4877 | +msgid "Genre" |
4878 | +msgstr "Gènere" |
4879 | + |
4880 | +#. TRANSLATORS: this is a title of a dialog with a prompt to rename a playlist |
4881 | +#: ../common/SongsPage.qml:333 |
4882 | +msgid "Change name" |
4883 | +msgstr "Canvia el nom" |
4884 | + |
4885 | +#: ../common/SongsPage.qml:334 |
4886 | +msgid "Enter the new name of the playlist." |
4887 | +msgstr "Escriviu un nom nou per a la llista de reproducció." |
4888 | + |
4889 | +#: ../common/SongsPage.qml:351 |
4890 | +msgid "Change" |
4891 | +msgstr "Canvia" |
4892 | + |
4893 | +#: ../common/SongsPage.qml:372 ../music-app.qml:959 |
4894 | +msgid "Playlist already exists" |
4895 | +msgstr "Ja existeix la llista de reproducció" |
4896 | + |
4897 | +#: ../common/SongsPage.qml:376 ../music-app.qml:964 |
4898 | +msgid "Please type in a name." |
4899 | +msgstr "Escriviu un nom" |
4900 | + |
4901 | +#: ../common/SongsPage.qml:381 ../common/SongsPage.qml:420 |
4902 | +#: ../music-app.qml:499 ../music-app.qml:970 |
4903 | +msgid "Cancel" |
4904 | +msgstr "Cancel·la" |
4905 | + |
4906 | +#. TRANSLATORS: this is a title of a dialog with a prompt to delete a playlist |
4907 | +#: ../common/SongsPage.qml:394 |
4908 | +msgid "Are you sure?" |
4909 | +msgstr "" |
4910 | + |
4911 | +#: ../common/SongsPage.qml:395 |
4912 | +msgid "This will delete your playlist." |
4913 | +msgstr "" |
4914 | + |
4915 | +#: ../common/SwipeDelete.qml:52 ../common/SwipeDelete.qml:88 |
4916 | +msgid "Clear" |
4917 | +msgstr "Esborra" |
4918 | + |
4919 | +#: ../meta-database.js:90 ../meta-database.js:92 |
4920 | +msgid "Unknown Album" |
4921 | +msgstr "Àlbum desconegut" |
4922 | + |
4923 | +#: ../meta-database.js:91 |
4924 | +msgid "Unknown Artist" |
4925 | +msgstr "Artista desconegut" |
4926 | + |
4927 | +#: ../music-app.qml:135 |
4928 | +msgid "Search Track" |
4929 | +msgstr "Cerca de temes" |
4930 | + |
4931 | +#: ../music-app.qml:147 |
4932 | +msgid "Next" |
4933 | +msgstr "Següent" |
4934 | + |
4935 | +#: ../music-app.qml:148 |
4936 | +msgid "Next Track" |
4937 | +msgstr "Tema següent" |
4938 | + |
4939 | +#: ../music-app.qml:154 |
4940 | +msgid "Pause" |
4941 | +msgstr "Posa en pausa" |
4942 | + |
4943 | +#: ../music-app.qml:154 |
4944 | +msgid "Play" |
4945 | +msgstr "Reprodueix" |
4946 | + |
4947 | +#: ../music-app.qml:156 |
4948 | +msgid "Pause Playback" |
4949 | +msgstr "Posa la reproducció en pausa" |
4950 | + |
4951 | +#: ../music-app.qml:156 |
4952 | +msgid "Continue or start playback" |
4953 | +msgstr "Continua o inicia la reproducció" |
4954 | + |
4955 | +#: ../music-app.qml:161 |
4956 | +msgid "Back" |
4957 | +msgstr "Arrere" |
4958 | + |
4959 | +#: ../music-app.qml:162 |
4960 | +msgid "Go back to last page" |
4961 | +msgstr "Torna a la pàgina anterior" |
4962 | + |
4963 | +#: ../music-app.qml:170 |
4964 | +msgid "Previous" |
4965 | +msgstr "Anterior" |
4966 | + |
4967 | +#: ../music-app.qml:171 |
4968 | +msgid "Previous Track" |
4969 | +msgstr "Tema anterior" |
4970 | + |
4971 | +#: ../music-app.qml:176 |
4972 | +msgid "Stop" |
4973 | +msgstr "Para" |
4974 | + |
4975 | +#: ../music-app.qml:177 |
4976 | +msgid "Stop Playback" |
4977 | +msgstr "Para la reproducció" |
4978 | + |
4979 | +#: ../music-app.qml:185 |
4980 | +msgid "Music Settings" |
4981 | +msgstr "Paràmetres de la música" |
4982 | + |
4983 | +#. TRANSLATORS: This string represents that the target destination filepath does not start with ~/Music/Imported/ |
4984 | +#: ../music-app.qml:342 |
4985 | +msgid "Filepath must start with" |
4986 | +msgstr "El camí del fitxer ha de començar per" |
4987 | + |
4988 | +#. TRANSLATORS: This string represents that a blank filepath destination has been used |
4989 | +#: ../music-app.qml:368 |
4990 | +msgid "Filepath must be a file" |
4991 | +msgstr "El camí del fitxer ha d'apuntar a un fitxer" |
4992 | + |
4993 | +#. TRANSLATORS: This string represents that there was failure moving the file to the target destination |
4994 | +#: ../music-app.qml:374 |
4995 | +msgid "Failed to move file" |
4996 | +msgstr "Ha fallat el trasllat del fitxer" |
4997 | + |
4998 | +#: ../music-app.qml:453 |
4999 | +msgid "Waiting for file(s)..." |
5000 | +msgstr "S'estan esperant els fitxers..." |