Merge lp:~ahayzen/music-app/toolbar-as-panel into lp:music-app/trusty

Proposed by Andrew Hayzen
Status: Merged
Approved by: Victor Thompson
Approved revision: 389
Merged at revision: 392
Proposed branch: lp:~ahayzen/music-app/toolbar-as-panel
Merge into: lp:music-app/trusty
Diff against target: 1961 lines (+745/-1011)
3 files modified
MusicNowPlaying.qml (+8/-15)
MusicToolbar.qml (+737/-993)
music-app.qml (+0/-3)
To merge this branch: bzr merge lp:~ahayzen/music-app/toolbar-as-panel
Reviewer Review Type Date Requested Status
Victor Thompson Approve
Ubuntu Phone Apps Jenkins Bot continuous-integration Approve
Review via email: mp+211723@code.launchpad.net

Commit message

* Migrate musicToolbar to use Panel component

Description of the change

* Migrate musicToolbar to use Panel component

Please retest all buttons in the toolbar, they should be:
- clickable
- dragging on Y axis should show/hide toolbar

Retest all of the show/hide states of the toolbar

To post a comment you must log in.
Revision history for this message
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote :
review: Approve (continuous-integration)
Revision history for this message
Andrew Hayzen (ahayzen) wrote :

Marking as WIP while investigating a warning.

Revision history for this message
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote :
review: Approve (continuous-integration)
Revision history for this message
Andrew Hayzen (ahayzen) wrote :

Hmm the Panel seems to block some mouse events (drag/scrolling) to the rest of the page if it is shown.

Revision history for this message
Victor Thompson (vthompson) wrote :

Things to fix:
1. Can not scroll/flick in the Now Playing page when the toolbar is up.
2. The Back button on the Now Playing page does not show/hide with toolbar. However, we might actually want this to behave this way if we leave the back button at the top of the panel when it is flicked all the way open.
3. The Back button does not work when the toolbar is up in the Now Playing page
4. The toolbar being up prevents the user from navigating the regular views/tabs of the app.

Otherwise looks good so far!

review: Needs Fixing
Revision history for this message
Andrew Hayzen (ahayzen) wrote :

Ok so we have a bug tracking the issues 1), 4) and possibly 3) here [1]. There is a workaround (to set the panel as __closeOnContentsClicks: false) or we can wait until the bug is fixed?

1 - https://bugs.launchpad.net/ubuntu-ui-toolkit/+bug/1295720

387. By Andrew Hayzen

* Add temporary workaround for Panel

Revision history for this message
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote :
review: Approve (continuous-integration)
388. By Andrew Hayzen

* Fix for back button not being hidden/shown correctly

Revision history for this message
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote :
review: Approve (continuous-integration)
Revision history for this message
Victor Thompson (vthompson) wrote :

Awesome! I think all 4 of the previous issues have been resolved. It seems like autohiding the toolbar doesn't work quite right. On the phone the toolbar never autohides. However, on the desktop (in narrow mode) autohide does work when the toolbar is brought up using the Alt shortcut. The autohide timer probably just needs to be restarted when the toolbar is exposed.

review: Needs Fixing
389. By Andrew Hayzen

* Start autohide timer when the toolbar is exposed

Revision history for this message
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote :
review: Approve (continuous-integration)
Revision history for this message
Victor Thompson (vthompson) wrote :

Perfect, thanks!

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'MusicNowPlaying.qml'
2--- MusicNowPlaying.qml 2014-03-07 16:20:51 +0000
3+++ MusicNowPlaying.qml 2014-03-23 01:31:10 +0000
4@@ -816,8 +816,10 @@
5
6 Rectangle {
7 id: nowPlayingBackButton
8- anchors.left: parent.left
9- anchors.right: parent.right
10+ anchors {
11+ left: parent.left
12+ right: parent.right
13+ }
14 color: styleMusic.toolbar.fullBackgroundColor
15 height: units.gu(3.1)
16
17@@ -825,29 +827,20 @@
18 states: [
19 State {
20 name: "shown"
21- PropertyChanges {
22+ AnchorChanges {
23 target: nowPlayingBackButton
24- y: 0
25+ anchors.top: parent.top
26 }
27 },
28 State {
29 name: "hidden"
30- PropertyChanges {
31+ AnchorChanges {
32 target: nowPlayingBackButton
33- y: -height
34+ anchors.bottom: parent.top
35 }
36 }
37 ]
38
39- transitions: Transition {
40- from: "hidden,shown"
41- to: "shown,hidden"
42- NumberAnimation {
43- duration: 100
44- properties: "y"
45- }
46- }
47-
48 Image {
49 id: expandItem
50 anchors.horizontalCenter: parent.horizontalCenter
51
52=== modified file 'MusicToolbar.qml'
53--- MusicToolbar.qml 2014-03-08 22:09:12 +0000
54+++ MusicToolbar.qml 2014-03-23 01:31:10 +0000
55@@ -23,13 +23,12 @@
56 import Ubuntu.Components.Popups 0.1
57 import "settings.js" as Settings
58
59-Rectangle {
60- id: musicToolbarContainer
61- color: "transparent"
62- height: fullHeight
63- state: "minimized"
64- width: parent.width
65- x: parent.x
66+Item {
67+ anchors {
68+ bottom: parent.bottom
69+ left: parent.left
70+ right: parent.right
71+ }
72
73 // Properties storing the current page info
74 property var currentParentPage: null
75@@ -38,143 +37,18 @@
76 property var currentSheet: []
77 property var currentTab: null
78
79- // The current mode of the controls
80- property string currentMode: wideAspect || currentPage === nowPlaying
81- ? "full" : "expanded"
82-
83- // Properties for the different heights
84- property int minimizedHeight: units.gu(0.5)
85- property int expandedHeight: units.gu(8)
86- property int fullHeight: units.gu(11)
87- property int mouseAreaOffset: units.gu(2)
88-
89 // Properties and signals for the toolbar
90 property var cachedStates: []
91 property bool shown: false
92 property int transitionDuration: 100
93
94- onYChanged: {
95- y: parent.height
96- if (y > mainView.height - units.gu(1) && currentMode === "full")
97- musicToolbarSmallProgressBackground.opacity = 1
98- else if (y <= mainView.height - units.gu(1) && currentMode === "full")
99- musicToolbarSmallProgressBackground.opacity = 0
100- }
101-
102- // Shown/hide relevant child items depending on mode
103- onCurrentModeChanged: {
104- musicToolbarExpandedContainer.visible = currentMode !== "full"
105- musicToolbarFullContainer.visible = currentMode === "full"
106-
107- // Update the container state if required
108- if (state !== "minimized" || wideAspect)
109- {
110- state = currentMode
111- shown = true;
112- }
113- }
114-
115- // Emit toolbarShownChanged signal when the toolbar is shown/hidden
116- onShownChanged: {
117- onToolbarShownChanged(shown, currentPage, currentTab);
118- musicToolbar.opened = shown;
119- }
120-
121- states: [
122- // State for when the toolbar is hidden
123- State {
124- name: "hidden"
125- PropertyChanges {
126- target: musicToolbarContainer
127- y: parent.height
128- }
129- PropertyChanges {
130- target: musicToolbarMouseArea
131- anchors.topMargin: 0
132- }
133- PropertyChanges {
134- target: musicToolbarSmallProgressBackground
135- opacity: 0
136- }
137- PropertyChanges {
138- target: musicToolbarFullProgressMouseArea
139- visible: false
140- }
141- },
142- // State for when the toolbar is minimized
143- State {
144- name: "minimized"
145- PropertyChanges {
146- target: musicToolbarContainer
147- y: parent.height - minimizedHeight
148- }
149- PropertyChanges {
150- target: musicToolbarMouseArea
151- anchors.topMargin: -mouseAreaOffset // should allow drag from outside the item
152- }
153- PropertyChanges {
154- target: musicToolbarSmallProgressBackground
155- opacity: 1
156- }
157- PropertyChanges {
158- target: musicToolbarFullProgressMouseArea
159- visible: false
160- }
161- },
162- // State for when the toolbar is shown
163- State {
164- name: "expanded"
165- PropertyChanges {
166- target: musicToolbarContainer
167- y: parent.height - expandedHeight - minimizedHeight
168- }
169- PropertyChanges {
170- target: musicToolbarMouseArea
171- anchors.topMargin: 0
172- }
173- PropertyChanges {
174- target: musicToolbarSmallProgressBackground
175- opacity: 1
176- }
177- PropertyChanges {
178- target: musicToolbarFullProgressMouseArea
179- visible: false
180- }
181- },
182- // State for when the toolbar is shown on the now playing page
183- State {
184- name: "full"
185- PropertyChanges {
186- target: musicToolbarContainer
187- y: parent.height - fullHeight
188- }
189- PropertyChanges {
190- target: musicToolbarMouseArea
191- anchors.topMargin: 0
192- }
193- PropertyChanges {
194- target: musicToolbarSmallProgressBackground
195- opacity: 0
196- }
197- PropertyChanges {
198- target: musicToolbarFullProgressMouseArea
199- visible: true
200- }
201- }
202- ]
203-
204- transitions: Transition {
205- from: "minimized,minimized,expanded,expanded,full,full"
206- to: "expanded,full,minimized,full,minimized,expanded"
207- NumberAnimation {
208- duration: transitionDuration
209- properties: "y,opacity"
210- }
211-
212- onRunningChanged: {
213- musicToolbar.animating = running;
214- }
215- }
216+ property alias minimizedHeight: musicToolbarPanel.minimizedHeight
217+ property alias expandedHeight: musicToolbarPanel.expandedHeight
218+ property alias fullHeight: musicToolbarPanel.fullHeight
219+ property alias mouseAreaOffset: musicToolbarPanel.hintSize
220+
221+ property alias animating: musicToolbarPanel.animating
222+ property alias opened: musicToolbarPanel.opened
223
224 /* Helper functions */
225
226@@ -182,7 +56,7 @@
227 function disableToolbar()
228 {
229 cachedStates.push(state);
230- state = "hidden";
231+ musicToolbarPanel.state = "hidden";
232 }
233
234 // Enable the toolbar (run when closing a page that disabled it)
235@@ -190,7 +64,7 @@
236 {
237 if (cachedStates.length > 0)
238 {
239- state = cachedStates.pop();
240+ musicToolbarPanel.state = cachedStates.pop();
241 }
242 }
243
244@@ -210,15 +84,14 @@
245 currentParentPage.visible = true
246 }
247
248- musicToolbar.hideToolbar();
249+ hideToolbar();
250 }
251
252 // Hide the toolbar
253 function hideToolbar()
254 {
255 if (!wideAspect) {
256- musicToolbarContainer.state = "minimized";
257- shown = false;
258+ musicToolbarPanel.close();
259 }
260
261 toolbarAutoHideTimer.stop(); // cancel any autohide
262@@ -250,9 +123,11 @@
263 // Show the toolbar
264 function showToolbar()
265 {
266- musicToolbarContainer.state = currentMode;
267 startAutohideTimer(); // always attempt to autohide toolbar
268- shown = true;
269+
270+ if (!musicToolbarPanel.opened) {
271+ musicToolbarPanel.open();
272+ }
273 }
274
275 // Start the autohidetimer
276@@ -261,129 +136,191 @@
277 toolbarAutoHideTimer.restart();
278 }
279
280- /* Mouse area to block events going to items under the toolbar */
281- MouseArea {
282- anchors.fill: parent
283- onClicked: mouse.accepted = true
284- }
285-
286- /* Expanded toolbar */
287- Rectangle {
288- id: musicToolbarExpandedContainer
289- color: "transparent"
290- anchors.left: parent.left
291- anchors.top: musicToolbarSmallProgressBackground.bottom
292- height: expandedHeight
293- width: parent.width
294-
295+ Panel {
296+ id: musicToolbarPanel
297+ anchors {
298+ left: parent.left
299+ right: parent.right
300+ bottom: parent.bottom
301+ }
302+ height: currentMode === "full" ? fullHeight : expandedHeight
303+ locked: wideAspect
304+
305+ __closeOnContentsClicks: false // TODO: fix bug 1295720
306+
307+ // The current mode of the controls
308+ property string currentMode: wideAspect || currentPage === nowPlaying
309+ ? "full" : "expanded"
310+
311+ // Properties for the different heights
312+ property int minimizedHeight: units.gu(0.5)
313+ property int expandedHeight: units.gu(8)
314+ property int fullHeight: units.gu(11)
315+
316+ onCurrentModeChanged: {
317+ musicToolbarFullProgressMouseArea.enabled = currentMode === "full"
318+ }
319+
320+ onOpenedChanged: {
321+ onToolbarShownChanged(opened, currentPage, currentTab);
322+
323+ if (opened) {
324+ startAutohideTimer();
325+ }
326+ }
327+
328+ /* Full toolbar */
329 Rectangle {
330- id: musicToolbarPlayerControls
331- anchors.fill: parent
332- color: styleMusic.playerControls.backgroundColor
333- state: trackQueue.model.count === 0 ? "disabled" : "enabled"
334-
335- states: [
336- State {
337- name: "disabled"
338- PropertyChanges {
339- target: disabledPlayerControlsGroup
340- visible: true
341- }
342- PropertyChanges {
343- target: enabledPlayerControlsGroup
344- visible: false
345- }
346- },
347- State {
348- name: "enabled"
349- PropertyChanges {
350- target: disabledPlayerControlsGroup
351- visible: false
352- }
353- PropertyChanges {
354- target: enabledPlayerControlsGroup
355- visible: true
356- }
357- }
358- ]
359-
360- Rectangle {
361- id: disabledPlayerControlsGroup
362- anchors.fill: parent
363- color: "transparent"
364- visible: trackQueue.model.count === 0
365-
366- Label {
367- id: noSongsInQueueLabel
368- anchors.left: parent.left
369- anchors.margins: units.gu(1)
370- anchors.top: parent.top
371- color: styleMusic.playerControls.labelColor
372- text: i18n.tr("No songs queued")
373- fontSize: "large"
374- }
375-
376- Label {
377- id: tabToStartPlayingLabel
378- color: styleMusic.playerControls.labelColor
379- anchors.left: parent.left
380- anchors.margins: units.gu(1)
381- anchors.top: noSongsInQueueLabel.bottom
382- text: i18n.tr("Tap on a song to start playing")
383- }
384+ id: musicToolbarFullContainer
385+ anchors {
386+ fill: parent
387 }
388+ color: styleMusic.toolbar.fullBackgroundColor
389+ visible: musicToolbarPanel.currentMode === "full"
390
391+ /* Buttons component */
392 Rectangle {
393- id: enabledPlayerControlsGroup
394- anchors.fill: parent
395+ id: musicToolbarFullButtonsContainer
396+ anchors.left: parent.left
397+ anchors.top: musicToolbarFullProgressContainer.bottom
398 color: "transparent"
399- visible: trackQueue.model.count !== 0
400-
401- /* Settings button */
402- // TODO: Enable settings when it is practical
403- /* Rectangle {
404- id: playerControlsSettings
405- anchors.right: parent.right
406- anchors.verticalCenter: parent.verticalCenter
407- width: units.gu(6)
408- height: width
409- color: "transparent"
410-
411- Image {
412- anchors.horizontalCenter: parent.horizontalCenter
413- anchors.verticalCenter: parent.verticalCenter
414- height: units.gu(3)
415- source: Qt.resolvedUrl("images/settings.png")
416- width: height
417- }
418-
419- MouseArea {
420- anchors.fill: parent
421- onClicked: {
422- console.debug('Debug: Show settings')
423- PopupUtils.open(Qt.resolvedUrl("MusicSettings.qml"), mainView,
424- {
425- title: i18n.tr("Settings")
426- } )
427- }
428- }
429- } */
430-
431- /* Play/Pause button TODO: image and colours needs updating */
432+ height: parent.height - musicToolbarFullProgressContainer.height
433+ width: parent.width
434+
435+ /* Column for labels in wideAspect */
436+ Column {
437+ id: nowPlayingWideAspectLabels
438+ anchors {
439+ left: parent.left
440+ leftMargin: units.gu(1)
441+ right: nowPlayingRepeatButton.left
442+ rightMargin: units.gu(1)
443+ verticalCenter: parent.verticalCenter
444+ }
445+ visible: wideAspect
446+
447+ /* Clicking in the area shows the queue */
448+ function trigger() {
449+ if (trackQueue.model.count !== 0 && currentPage !== nowPlaying) {
450+ nowPlaying.visible = true;
451+ }
452+ }
453+
454+ /* Title of track */
455+ Label {
456+ id: nowPlayingWideAspectTitle
457+ anchors {
458+ left: parent.left
459+ leftMargin: units.gu(1)
460+ right: parent.right
461+ rightMargin: units.gu(1)
462+ }
463+ color: styleMusic.playerControls.labelColor
464+ elide: Text.ElideRight
465+ fontSize: "medium"
466+ objectName: "playercontroltitle"
467+ text: trackQueue.model.count === 0 ? "" : player.currentMetaTitle === "" ? player.currentMetaFile : player.currentMetaTitle
468+ }
469+
470+ /* Artist of track */
471+ Label {
472+ id: nowPlayingWideAspectArtist
473+ anchors {
474+ left: parent.left
475+ leftMargin: units.gu(1)
476+ right: parent.right
477+ rightMargin: units.gu(1)
478+ }
479+ color: styleMusic.playerControls.labelColor
480+ elide: Text.ElideRight
481+ fontSize: "small"
482+ text: trackQueue.model.count === 0 ? "" : player.currentMetaArtist
483+ }
484+
485+ /* Album of track */
486+ Label {
487+ id: nowPlayingWideAspectAlbum
488+ anchors {
489+ left: parent.left
490+ leftMargin: units.gu(1)
491+ right: parent.right
492+ rightMargin: units.gu(1)
493+ }
494+ color: styleMusic.playerControls.labelColor
495+ elide: Text.ElideRight
496+ fontSize: "small"
497+ text: trackQueue.model.count === 0 ? "" : player.currentMetaAlbum
498+ }
499+ }
500+
501+ /* Repeat button */
502+ Item {
503+ id: nowPlayingRepeatButton
504+ objectName: "repeatShape"
505+ anchors.right: nowPlayingPreviousButton.left
506+ anchors.rightMargin: units.gu(1)
507+ anchors.verticalCenter: parent.verticalCenter
508+ height: units.gu(6)
509+ opacity: player.repeat ? 1 : .4
510+ width: height
511+
512+ function trigger() {
513+ // Invert repeat settings
514+ player.repeat = !player.repeat
515+ }
516+
517+ Image {
518+ id: repeatIcon
519+ height: units.gu(3)
520+ width: height
521+ anchors.verticalCenter: parent.verticalCenter
522+ anchors.horizontalCenter: parent.horizontalCenter
523+ source: Qt.resolvedUrl("images/media-playlist-repeat.svg")
524+ verticalAlignment: Text.AlignVCenter
525+ opacity: player.repeat ? 1 : .4
526+ }
527+ }
528+
529+ /* Previous button */
530+ Item {
531+ id: nowPlayingPreviousButton
532+ anchors.right: nowPlayingPlayButton.left
533+ anchors.rightMargin: units.gu(1)
534+ anchors.verticalCenter: parent.verticalCenter
535+ height: units.gu(6)
536+ objectName: "previousshape"
537+ opacity: trackQueue.model.count === 0 ? .4 : 1
538+ width: height
539+
540+ function trigger() {
541+ player.previousSong()
542+ }
543+
544+ Image {
545+ id: nowPlayingPreviousIndicator
546+ height: units.gu(3)
547+ width: height
548+ anchors.horizontalCenter: parent.horizontalCenter
549+ anchors.verticalCenter: parent.verticalCenter
550+ source: Qt.resolvedUrl("images/media-skip-backward.svg")
551+ opacity: 1
552+ }
553+ }
554+
555+ /* Play/Pause button */
556 Rectangle {
557- id: playerControlsPlayButton
558- anchors.right: parent.right
559- anchors.rightMargin: units.gu(1)
560+ id: nowPlayingPlayButton
561+ anchors.horizontalCenter: parent.horizontalCenter
562 anchors.verticalCenter: parent.verticalCenter
563 antialiasing: true
564- color: "#444"
565- height: units.gu(7)
566+ color: styleMusic.toolbar.fullOuterPlayCircleColor
567+ height: units.gu(12)
568 radius: height / 2
569 width: height
570
571- // draws the outer shadow/highlight
572+ // draws the outter shadow/highlight
573 Rectangle {
574- id: sourceOutter
575+ id: sourceOutterFull
576 anchors { fill: parent; margins: -units.gu(0.1) }
577 radius: (width / 2)
578 antialiasing: true
579@@ -394,27 +331,27 @@
580 }
581
582 Rectangle {
583+ anchors.horizontalCenter: parent.horizontalCenter
584 anchors.verticalCenter: parent.verticalCenter
585- anchors.horizontalCenter: parent.horizontalCenter
586 antialiasing: true
587- color: "#444"
588- height: playerControlsPlayButton.height - units.gu(.1)
589+ color: styleMusic.toolbar.fullOuterPlayCircleColor
590+ height: nowPlayingPlayButton.height - units.gu(.1)
591 radius: height / 2
592 width: height
593
594 Rectangle {
595- id: playerControlsPlayInnerCircle
596+ id: nowPlayingPlayButtonInner
597 anchors.horizontalCenter: parent.horizontalCenter
598 anchors.verticalCenter: parent.verticalCenter
599 antialiasing: true
600- height: units.gu(4.5)
601- radius: height / 2
602- width: height
603 color: styleMusic.toolbar.fullInnerPlayCircleColor
604+ height: units.gu(7)
605+ radius: height / 2
606+ width: height
607
608 // draws the inner shadow/highlight
609 Rectangle {
610- id: sourceInner
611+ id: sourceInnerFull
612 anchors { fill: parent; margins: -units.gu(0.1) }
613 radius: (width / 2)
614 antialiasing: true
615@@ -425,21 +362,26 @@
616 }
617
618 Rectangle {
619+ anchors.horizontalCenter: parent.horizontalCenter
620 anchors.verticalCenter: parent.verticalCenter
621- anchors.horizontalCenter: parent.horizontalCenter
622 antialiasing: true
623- height: playerControlsPlayInnerCircle.height - units.gu(.1)
624+ color: styleMusic.toolbar.fullInnerPlayCircleColor
625+ height: nowPlayingPlayButtonInner.height - units.gu(.1)
626+ objectName: "nowPlayingPlayShape"
627 radius: height / 2
628 width: height
629- color: styleMusic.toolbar.fullInnerPlayCircleColor
630+
631+ function trigger() {
632+ player.toggle();
633+ }
634
635 Image {
636- id: playindicator
637- height: units.gu(4)
638+ id: nowPlayingPlayIndicator
639+ height: units.gu(6)
640 width: height
641 anchors.horizontalCenter: parent.horizontalCenter
642 anchors.verticalCenter: parent.verticalCenter
643- opacity: 1
644+ opacity: trackQueue.model.count === 0 ? .4 : 1
645 source: player.playbackState === MediaPlayer.PlayingState ?
646 Qt.resolvedUrl("images/media-playback-pause.svg") : Qt.resolvedUrl("images/media-playback-start.svg")
647 }
648@@ -448,775 +390,577 @@
649 }
650 }
651 }
652-
653- MouseArea {
654- objectName: "playshape" // objectName doesn't work on Rectangle?
655-
656- anchors.fill: parent
657-
658- function inCircle(x, y) {
659- /*
660- Function that returns true if the mouse is inside the circle
661- Length = root((y2-y1)^2 + (x2-x1)^2)
662- */
663- x = Math.pow(x - (width / 2), 2);
664- y = Math.pow(y - (height / 2), 2);
665-
666- return Math.pow((x + y), 0.5) <= parent.radius;
667- }
668-
669- onClicked: {
670- var accepted = inCircle(mouse.x, mouse.y);
671-
672- mouse.accepted = accepted;
673-
674- if (accepted)
675- {
676- player.toggle();
677- }
678- }
679- }
680- }
681-
682- /* Container holding the labels for the toolbar */
683- Rectangle {
684- id: playerControlLabelContainer
685- anchors.bottom: parent.bottom
686- anchors.left: parent.left
687- anchors.right: playerControlsPlayButton.left
688- anchors.top: parent.top
689- color: "transparent"
690-
691- MouseArea {
692- anchors.fill: parent
693- onClicked: {
694- nowPlaying.visible = true
695- }
696- }
697-
698- /* Title of track */
699- Label {
700- id: playerControlsTitle
701- anchors.left: parent.left
702- anchors.leftMargin: units.gu(1)
703- anchors.right: parent.right
704- anchors.rightMargin: units.gu(1)
705- anchors.top: parent.top
706- anchors.topMargin: units.gu(1)
707- color: styleMusic.playerControls.labelColor
708- elide: Text.ElideRight
709- fontSize: "medium"
710- objectName: "playercontroltitle"
711- text: player.currentMetaTitle === ""
712- ? player.source : player.currentMetaTitle
713- }
714-
715- /* Artist of track */
716- Label {
717- id: playerControlsArtist
718- anchors.left: parent.left
719- anchors.leftMargin: units.gu(1)
720- anchors.right: parent.right
721- anchors.rightMargin: units.gu(1)
722- anchors.top: playerControlsTitle.bottom
723- color: styleMusic.playerControls.labelColor
724- elide: Text.ElideRight
725- fontSize: "small"
726- text: player.currentMetaArtist
727- }
728-
729- /* Album of track */
730- Label {
731- id: playerControlsAlbum
732- anchors.left: parent.left
733- anchors.leftMargin: units.gu(1)
734- anchors.right: parent.right
735- anchors.rightMargin: units.gu(1)
736- anchors.top: playerControlsArtist.bottom
737- color: styleMusic.playerControls.labelColor
738- elide: Text.ElideRight
739- fontSize: "small"
740- text: player.currentMetaAlbum
741- }
742- }
743- }
744- }
745- }
746-
747- /* Full toolbar */
748- Rectangle {
749- id: musicToolbarFullContainer
750- anchors.left: parent.left
751- anchors.top: parent.top
752- color: styleMusic.toolbar.fullBackgroundColor
753- height: fullHeight
754- width: parent.width
755-
756- /* Buttons component */
757- Rectangle {
758- id: musicToolbarFullButtonsContainer
759- anchors.left: parent.left
760- anchors.top: musicToolbarFullProgressContainer.bottom
761- color: "transparent"
762- height: parent.height - musicToolbarFullProgressContainer.height
763- width: parent.width
764-
765- /* Column for labels in wideAspect */
766- Column {
767- id: nowPlayingWideAspectLabels
768- anchors {
769- left: parent.left
770- leftMargin: units.gu(1)
771- right: nowPlayingRepeatButton.left
772- rightMargin: units.gu(1)
773- verticalCenter: parent.verticalCenter
774- }
775- visible: wideAspect
776-
777- /* Title of track */
778- Label {
779- id: nowPlayingWideAspectTitle
780- anchors {
781- left: parent.left
782- leftMargin: units.gu(1)
783- right: parent.right
784- rightMargin: units.gu(1)
785- }
786- color: styleMusic.playerControls.labelColor
787- elide: Text.ElideRight
788- fontSize: "medium"
789- objectName: "playercontroltitle"
790- text: trackQueue.model.count === 0 ? "" : player.currentMetaTitle === "" ? player.currentMetaFile : player.currentMetaTitle
791- }
792-
793- /* Artist of track */
794- Label {
795- id: nowPlayingWideAspectArtist
796- anchors {
797- left: parent.left
798- leftMargin: units.gu(1)
799- right: parent.right
800- rightMargin: units.gu(1)
801- }
802- color: styleMusic.playerControls.labelColor
803- elide: Text.ElideRight
804- fontSize: "small"
805- text: trackQueue.model.count === 0 ? "" : player.currentMetaArtist
806- }
807-
808- /* Album of track */
809- Label {
810- id: nowPlayingWideAspectAlbum
811- anchors {
812- left: parent.left
813- leftMargin: units.gu(1)
814- right: parent.right
815- rightMargin: units.gu(1)
816- }
817- color: styleMusic.playerControls.labelColor
818- elide: Text.ElideRight
819- fontSize: "small"
820- text: trackQueue.model.count === 0 ? "" : player.currentMetaAlbum
821- }
822- }
823- /* Clicking in the area shows the queue */
824- MouseArea {
825- anchors {
826- fill: nowPlayingWideAspectLabels
827- }
828- enabled: trackQueue.model.count !== 0
829- onClicked: {
830- nowPlaying.visible = true;
831- }
832- }
833-
834- /* Repeat button */
835- Item {
836- id: nowPlayingRepeatButton
837- objectName: "repeatShape"
838- anchors.right: nowPlayingPreviousButton.left
839- anchors.rightMargin: units.gu(1)
840- anchors.verticalCenter: parent.verticalCenter
841- height: units.gu(6)
842- opacity: player.repeat ? 1 : .4
843- width: height
844-
845- Image {
846- id: repeatIcon
847- height: units.gu(3)
848- width: height
849- anchors.verticalCenter: parent.verticalCenter
850- anchors.horizontalCenter: parent.horizontalCenter
851- source: Qt.resolvedUrl("images/media-playlist-repeat.svg")
852- verticalAlignment: Text.AlignVCenter
853- opacity: player.repeat ? 1 : .4
854- }
855-
856- MouseArea {
857- anchors.fill: parent
858-
859- onClicked: {
860- // Invert repeat settings
861- player.repeat = !player.repeat
862- }
863- }
864- }
865-
866- /* Previous button */
867- Item {
868- id: nowPlayingPreviousButton
869- anchors.right: nowPlayingPlayButton.left
870- anchors.rightMargin: units.gu(1)
871- anchors.verticalCenter: parent.verticalCenter
872- height: units.gu(6)
873- objectName: "previousshape"
874- opacity: trackQueue.model.count === 0 ? .4 : 1
875- width: height
876-
877- Image {
878- id: nowPlayingPreviousIndicator
879- height: units.gu(3)
880- width: height
881- anchors.horizontalCenter: parent.horizontalCenter
882- anchors.verticalCenter: parent.verticalCenter
883- source: Qt.resolvedUrl("images/media-skip-backward.svg")
884- opacity: 1
885- }
886-
887- MouseArea {
888- anchors.fill: parent
889- id: nowPlayingPreviousMouseArea
890- onClicked:
891- {
892- player.previousSong()
893- }
894- }
895- }
896-
897- /* Play/Pause button */
898- Rectangle {
899- id: nowPlayingPlayButton
900- anchors.horizontalCenter: parent.horizontalCenter
901- anchors.verticalCenter: parent.verticalCenter
902- antialiasing: true
903- color: styleMusic.toolbar.fullOuterPlayCircleColor
904- height: units.gu(12)
905- radius: height / 2
906- width: height
907-
908- // draws the outter shadow/highlight
909- Rectangle {
910- id: sourceOutterFull
911- anchors { fill: parent; margins: -units.gu(0.1) }
912- radius: (width / 2)
913- antialiasing: true
914- gradient: Gradient {
915- GradientStop { position: 0.0; color: "black" }
916- GradientStop { position: 0.5; color: "transparent" }
917- GradientStop { position: 1.0; color: UbuntuColors.warmGrey }
918- }
919-
920- Rectangle {
921- anchors.horizontalCenter: parent.horizontalCenter
922- anchors.verticalCenter: parent.verticalCenter
923- antialiasing: true
924- color: styleMusic.toolbar.fullOuterPlayCircleColor
925- height: nowPlayingPlayButton.height - units.gu(.1)
926- radius: height / 2
927- width: height
928-
929- Rectangle {
930- id: nowPlayingPlayButtonInner
931- anchors.horizontalCenter: parent.horizontalCenter
932- anchors.verticalCenter: parent.verticalCenter
933- antialiasing: true
934- color: styleMusic.toolbar.fullInnerPlayCircleColor
935- height: units.gu(7)
936- radius: height / 2
937- width: height
938-
939- // draws the inner shadow/highlight
940- Rectangle {
941- id: sourceInnerFull
942- anchors { fill: parent; margins: -units.gu(0.1) }
943- radius: (width / 2)
944- antialiasing: true
945- gradient: Gradient {
946- GradientStop { position: 0.0; color: UbuntuColors.warmGrey }
947- GradientStop { position: 0.5; color: "transparent" }
948- GradientStop { position: 1.0; color: "black" }
949- }
950-
951- Rectangle {
952- anchors.horizontalCenter: parent.horizontalCenter
953- anchors.verticalCenter: parent.verticalCenter
954- antialiasing: true
955- color: styleMusic.toolbar.fullInnerPlayCircleColor
956- height: nowPlayingPlayButtonInner.height - units.gu(.1)
957- radius: height / 2
958- width: height
959-
960- Image {
961- id: nowPlayingPlayIndicator
962- height: units.gu(6)
963- width: height
964- anchors.horizontalCenter: parent.horizontalCenter
965- anchors.verticalCenter: parent.verticalCenter
966- opacity: trackQueue.model.count === 0 ? .4 : 1
967- source: player.playbackState === MediaPlayer.PlayingState ?
968- Qt.resolvedUrl("images/media-playback-pause.svg") : Qt.resolvedUrl("images/media-playback-start.svg")
969- }
970-
971- MouseArea {
972- objectName: "nowPlayingPlayShape"
973- anchors.fill: parent
974- id: nowPlayingPlayMouseArea
975-
976- function inCircle(x, y) {
977- /*
978- Function that returns true if the mouse is inside the circle
979- Length = root((y2-y1)^2 + (x2-x1)^2)
980- */
981- x = Math.pow(x - (width / 2), 2);
982- y = Math.pow(y - (height / 2), 2);
983-
984- return Math.pow((x + y), 0.5) <= parent.radius;
985- }
986-
987- onClicked:
988- {
989- if (!inCircle(mouse.x, mouse.y))
990- {
991- return;
992- }
993-
994- player.toggle();
995- }
996- }
997- }
998- }
999- }
1000- }
1001- }
1002- }
1003-
1004- /* Next button */
1005- Item {
1006- id: nowPlayingNextButton
1007- anchors.left: nowPlayingPlayButton.right
1008- anchors.leftMargin: units.gu(1)
1009- anchors.verticalCenter: parent.verticalCenter
1010- height: units.gu(6)
1011- objectName: "forwardshape"
1012- opacity: trackQueue.model.count === 0 ? .4 : 1
1013- width: height
1014-
1015- Image {
1016- id: nowPlayingNextIndicator
1017- height: units.gu(3)
1018- width: height
1019- anchors.horizontalCenter: parent.horizontalCenter
1020- anchors.verticalCenter: parent.verticalCenter
1021- source: Qt.resolvedUrl("images/media-skip-forward.svg")
1022- opacity: 1
1023- }
1024-
1025- MouseArea {
1026- anchors.fill: parent
1027- id: nowPlayingNextMouseArea
1028- onClicked:
1029- {
1030+ }
1031+
1032+ /* Next button */
1033+ Item {
1034+ id: nowPlayingNextButton
1035+ anchors.left: nowPlayingPlayButton.right
1036+ anchors.leftMargin: units.gu(1)
1037+ anchors.verticalCenter: parent.verticalCenter
1038+ height: units.gu(6)
1039+ objectName: "forwardshape"
1040+ opacity: trackQueue.model.count === 0 ? .4 : 1
1041+ width: height
1042+
1043+ function trigger() {
1044 player.nextSong()
1045 }
1046+
1047+ Image {
1048+ id: nowPlayingNextIndicator
1049+ height: units.gu(3)
1050+ width: height
1051+ anchors.horizontalCenter: parent.horizontalCenter
1052+ anchors.verticalCenter: parent.verticalCenter
1053+ source: Qt.resolvedUrl("images/media-skip-forward.svg")
1054+ opacity: 1
1055+ }
1056 }
1057- }
1058-
1059- /* Shuffle button */
1060- Item {
1061- id: nowPlayingShuffleButton
1062- objectName: "shuffleShape"
1063- anchors.left: nowPlayingNextButton.right
1064- anchors.leftMargin: units.gu(1)
1065- anchors.verticalCenter: parent.verticalCenter
1066- height: units.gu(6)
1067- opacity: player.shuffle ? 1 : .4
1068- width: height
1069-
1070- Image {
1071- id: shuffleIcon
1072- height: units.gu(3)
1073- width: height
1074+
1075+ /* Shuffle button */
1076+ Item {
1077+ id: nowPlayingShuffleButton
1078+ objectName: "shuffleShape"
1079+ anchors.left: nowPlayingNextButton.right
1080+ anchors.leftMargin: units.gu(1)
1081 anchors.verticalCenter: parent.verticalCenter
1082- anchors.horizontalCenter: parent.horizontalCenter
1083- source: Qt.resolvedUrl("images/media-playlist-shuffle.svg")
1084+ height: units.gu(6)
1085 opacity: player.shuffle ? 1 : .4
1086- }
1087-
1088- MouseArea {
1089- anchors.fill: parent
1090-
1091- onClicked: {
1092+ width: height
1093+
1094+ function trigger() {
1095 // Invert shuffle settings
1096 player.shuffle = !player.shuffle
1097 }
1098- }
1099- }
1100-
1101- /* Search button in wideAspect */
1102- Item {
1103- id: nowPlayingSearchButton
1104- objectName: "searchShape"
1105- anchors {
1106- right: parent.right
1107- rightMargin: units.gu(1)
1108- verticalCenter: parent.verticalCenter
1109- }
1110- height: units.gu(6)
1111- width: height
1112- visible: wideAspect
1113-
1114- Image {
1115- id: searchIcon
1116+
1117+ Image {
1118+ id: shuffleIcon
1119+ height: units.gu(3)
1120+ width: height
1121+ anchors.verticalCenter: parent.verticalCenter
1122+ anchors.horizontalCenter: parent.horizontalCenter
1123+ source: Qt.resolvedUrl("images/media-playlist-shuffle.svg")
1124+ opacity: player.shuffle ? 1 : .4
1125+ }
1126+ }
1127+
1128+ /* Search button in wideAspect */
1129+ Item {
1130+ id: nowPlayingSearchButton
1131+ objectName: "searchShape"
1132 anchors {
1133- horizontalCenter: parent.horizontalCenter
1134+ right: parent.right
1135+ rightMargin: units.gu(1)
1136 verticalCenter: parent.verticalCenter
1137 }
1138- height: units.gu(3)
1139- source: Qt.resolvedUrl("images/search.svg")
1140+ height: units.gu(6)
1141 width: height
1142- }
1143-
1144- MouseArea {
1145- anchors {
1146- fill: parent
1147- }
1148-
1149- onClicked: {
1150+ visible: wideAspect
1151+
1152+ function trigger() {
1153 if (!searchSheet.sheetVisible) {
1154 PopupUtils.open(searchSheet.sheet,
1155 mainView, { title: i18n.tr("Search")} )
1156 }
1157 }
1158+
1159+ Image {
1160+ id: searchIcon
1161+ anchors {
1162+ horizontalCenter: parent.horizontalCenter
1163+ verticalCenter: parent.verticalCenter
1164+ }
1165+ height: units.gu(3)
1166+ source: Qt.resolvedUrl("images/search.svg")
1167+ width: height
1168+ }
1169+ }
1170+ }
1171+
1172+ /* Progress bar component */
1173+ Rectangle {
1174+ id: musicToolbarFullProgressContainer
1175+ anchors.left: parent.left
1176+ anchors.top: parent.top
1177+ color: styleMusic.toolbar.fullBackgroundColor
1178+ height: units.gu(3)
1179+ width: parent.width
1180+
1181+ /* Position label */
1182+ Label {
1183+ id: musicToolbarFullPositionLabel
1184+ anchors.left: parent.left
1185+ anchors.leftMargin: units.gu(2)
1186+ anchors.top: parent.top
1187+ color: styleMusic.nowPlaying.labelColor
1188+ fontSize: "x-small"
1189+ height: parent.height
1190+ horizontalAlignment: Text.AlignHCenter
1191+ text: durationToString(player.position)
1192+ verticalAlignment: Text.AlignVCenter
1193+ width: units.gu(3)
1194+ }
1195+
1196+ /* Progress bar */
1197+ Rectangle {
1198+ id: musicToolbarFullProgressBarContainer
1199+ anchors.left: musicToolbarFullPositionLabel.right
1200+ anchors.leftMargin: units.gu(2)
1201+ anchors.right: musicToolbarFullDurationLabel.left
1202+ anchors.rightMargin: units.gu(2)
1203+ anchors.verticalCenter: parent.verticalCenter
1204+ color: "transparent"
1205+ height: units.gu(1);
1206+ state: trackQueue.model.count === 0 ? "disabled" : "enabled"
1207+
1208+ states: [
1209+ State {
1210+ name: "disabled"
1211+ PropertyChanges {
1212+ target: musicToolbarFullProgressMouseArea
1213+ enabled: false
1214+ }
1215+ PropertyChanges {
1216+ target: musicToolbarFullProgressTrough
1217+ visible: false
1218+ }
1219+ PropertyChanges {
1220+ target: musicToolbarFullProgressHandle
1221+ visible: false
1222+ }
1223+ },
1224+ State {
1225+ name: "enabled"
1226+ PropertyChanges {
1227+ target: musicToolbarFullProgressMouseArea
1228+ enabled: true
1229+ }
1230+ PropertyChanges {
1231+ target: musicToolbarFullProgressTrough
1232+ visible: true
1233+ }
1234+ PropertyChanges {
1235+ target: musicToolbarFullProgressHandle
1236+ visible: true
1237+ }
1238+ }
1239+ ]
1240+
1241+ property bool seeking: false
1242+
1243+ onSeekingChanged: {
1244+ if (seeking === false) {
1245+ musicToolbarFullPositionLabel.text = durationToString(player.position)
1246+ }
1247+ }
1248+
1249+ Connections {
1250+ target: player
1251+ onPositionChanged: {
1252+ if (musicToolbarFullProgressBarContainer.seeking === false)
1253+ {
1254+ musicToolbarFullProgressHandle.x = (player.position / player.duration) * musicToolbarFullProgressBarContainer.width
1255+ - musicToolbarFullProgressHandle.width / 2;
1256+ }
1257+ }
1258+ }
1259+
1260+ // Black background behind the progress bar
1261+ Rectangle {
1262+ id: musicToolbarFullProgressBackground
1263+ anchors.verticalCenter: parent.verticalCenter;
1264+ color: styleMusic.toolbar.fullProgressBackgroundColor;
1265+ height: parent.height;
1266+ radius: units.gu(0.5)
1267+ width: parent.width;
1268+ }
1269+
1270+ // The orange fill of the progress bar
1271+ Rectangle {
1272+ id: musicToolbarFullProgressTrough
1273+ anchors.verticalCenter: parent.verticalCenter;
1274+ antialiasing: true
1275+ color: styleMusic.toolbar.fullProgressTroughColor;
1276+ height: parent.height;
1277+ radius: units.gu(0.5)
1278+ width: musicToolbarFullProgressHandle.x + (height / 2); // +radius
1279+ }
1280+
1281+ // The current position (handle) of the progress bar
1282+ Rectangle {
1283+ id: musicToolbarFullProgressHandle
1284+ anchors.verticalCenter: musicToolbarFullProgressBackground.verticalCenter
1285+ antialiasing: true
1286+ color: styleMusic.nowPlaying.progressHandleColor
1287+ height: units.gu(1.5)
1288+ radius: height / 2
1289+ width: height
1290+
1291+ // On X change update the position string
1292+ onXChanged: {
1293+ var fraction = (x + (width / 2)) / parent.width;
1294+ musicToolbarFullPositionLabel.text = durationToString(fraction * player.duration)
1295+ }
1296+ }
1297+ }
1298+
1299+ /* Duration label */
1300+ Label {
1301+ id: musicToolbarFullDurationLabel
1302+ anchors.right: parent.right
1303+ anchors.rightMargin: units.gu(2)
1304+ anchors.top: parent.top
1305+ color: styleMusic.nowPlaying.labelColor
1306+ fontSize: "x-small"
1307+ height: parent.height
1308+ horizontalAlignment: Text.AlignHCenter
1309+ text: durationToString(player.duration)
1310+ verticalAlignment: Text.AlignVCenter
1311+ width: units.gu(3)
1312+ }
1313+
1314+ /* Border at the bottom */
1315+ Rectangle {
1316+ anchors.bottom: parent.bottom
1317+ anchors.left: parent.left
1318+ anchors.right: parent.right
1319+ color: styleMusic.common.white
1320+ height: units.gu(0.1)
1321+ opacity: 0.1
1322 }
1323 }
1324 }
1325
1326- /* Progress bar component */
1327+ /* Expanded toolbar */
1328 Rectangle {
1329- id: musicToolbarFullProgressContainer
1330- anchors.left: parent.left
1331- anchors.top: parent.top
1332- color: styleMusic.toolbar.fullBackgroundColor
1333- height: units.gu(3)
1334- width: parent.width
1335-
1336- /* Position label */
1337- Label {
1338- id: musicToolbarFullPositionLabel
1339- anchors.left: parent.left
1340- anchors.leftMargin: units.gu(2)
1341- anchors.top: parent.top
1342- color: styleMusic.nowPlaying.labelColor
1343- fontSize: "x-small"
1344- height: parent.height
1345- horizontalAlignment: Text.AlignHCenter
1346- text: durationToString(player.position)
1347- verticalAlignment: Text.AlignVCenter
1348- width: units.gu(3)
1349+ id: musicToolbarExpandedContainer
1350+ anchors {
1351+ fill: parent
1352 }
1353+ color: "transparent"
1354+ visible: musicToolbarPanel.currentMode === "expanded"
1355
1356- /* Progress bar */
1357 Rectangle {
1358- id: musicToolbarFullProgressBarContainer
1359- anchors.left: musicToolbarFullPositionLabel.right
1360- anchors.leftMargin: units.gu(2)
1361- anchors.right: musicToolbarFullDurationLabel.left
1362- anchors.rightMargin: units.gu(2)
1363- anchors.verticalCenter: parent.verticalCenter
1364- color: "transparent"
1365- height: units.gu(1);
1366+ id: musicToolbarPlayerControls
1367+ anchors.fill: parent
1368+ color: styleMusic.playerControls.backgroundColor
1369 state: trackQueue.model.count === 0 ? "disabled" : "enabled"
1370
1371 states: [
1372 State {
1373 name: "disabled"
1374 PropertyChanges {
1375- target: musicToolbarFullProgressMouseArea
1376- enabled: false
1377- }
1378- PropertyChanges {
1379- target: musicToolbarFullProgressTrough
1380- visible: false
1381- }
1382- PropertyChanges {
1383- target: musicToolbarFullProgressHandle
1384+ target: disabledPlayerControlsGroup
1385+ visible: true
1386+ }
1387+ PropertyChanges {
1388+ target: enabledPlayerControlsGroup
1389 visible: false
1390 }
1391 },
1392 State {
1393 name: "enabled"
1394 PropertyChanges {
1395- target: musicToolbarFullProgressMouseArea
1396- enabled: true
1397- }
1398- PropertyChanges {
1399- target: musicToolbarFullProgressTrough
1400- visible: true
1401- }
1402- PropertyChanges {
1403- target: musicToolbarFullProgressHandle
1404+ target: disabledPlayerControlsGroup
1405+ visible: false
1406+ }
1407+ PropertyChanges {
1408+ target: enabledPlayerControlsGroup
1409 visible: true
1410 }
1411 }
1412 ]
1413
1414- property bool seeking: false
1415-
1416- onSeekingChanged: {
1417- if (seeking === false) {
1418- musicToolbarFullPositionLabel.text = durationToString(player.position)
1419- }
1420- }
1421+ Rectangle {
1422+ id: disabledPlayerControlsGroup
1423+ anchors.fill: parent
1424+ color: "transparent"
1425+ visible: trackQueue.model.count === 0
1426+
1427+ Label {
1428+ id: noSongsInQueueLabel
1429+ anchors.left: parent.left
1430+ anchors.margins: units.gu(1)
1431+ anchors.top: parent.top
1432+ color: styleMusic.playerControls.labelColor
1433+ text: i18n.tr("No songs queued")
1434+ fontSize: "large"
1435+ }
1436+
1437+ Label {
1438+ id: tabToStartPlayingLabel
1439+ color: styleMusic.playerControls.labelColor
1440+ anchors.left: parent.left
1441+ anchors.margins: units.gu(1)
1442+ anchors.top: noSongsInQueueLabel.bottom
1443+ text: i18n.tr("Tap on a song to start playing")
1444+ }
1445+ }
1446+
1447+ Rectangle {
1448+ id: enabledPlayerControlsGroup
1449+ anchors.fill: parent
1450+ color: "transparent"
1451+ visible: trackQueue.model.count !== 0
1452+
1453+ /* Settings button */
1454+ // TODO: Enable settings when it is practical
1455+ /* Rectangle {
1456+ id: playerControlsSettings
1457+ anchors.right: parent.right
1458+ anchors.verticalCenter: parent.verticalCenter
1459+ width: units.gu(6)
1460+ height: width
1461+ color: "transparent"
1462+
1463+ Image {
1464+ anchors.horizontalCenter: parent.horizontalCenter
1465+ anchors.verticalCenter: parent.verticalCenter
1466+ height: units.gu(3)
1467+ source: Qt.resolvedUrl("images/settings.png")
1468+ width: height
1469+ }
1470+
1471+ MouseArea {
1472+ anchors.fill: parent
1473+ onClicked: {
1474+ console.debug('Debug: Show settings')
1475+ PopupUtils.open(Qt.resolvedUrl("MusicSettings.qml"), mainView,
1476+ {
1477+ title: i18n.tr("Settings")
1478+ } )
1479+ }
1480+ }
1481+ } */
1482+
1483+ /* Play/Pause button TODO: image and colours needs updating */
1484+ Rectangle {
1485+ id: playerControlsPlayButton
1486+ anchors.right: parent.right
1487+ anchors.rightMargin: units.gu(1)
1488+ anchors.verticalCenter: parent.verticalCenter
1489+ antialiasing: true
1490+ color: "#444"
1491+ height: units.gu(7)
1492+ radius: height / 2
1493+ width: height
1494+
1495+ function trigger() {
1496+ player.toggle();
1497+ }
1498+
1499+ // draws the outer shadow/highlight
1500+ Rectangle {
1501+ id: sourceOutter
1502+ anchors { fill: parent; margins: -units.gu(0.1) }
1503+ radius: (width / 2)
1504+ antialiasing: true
1505+ gradient: Gradient {
1506+ GradientStop { position: 0.0; color: "black" }
1507+ GradientStop { position: 0.5; color: "transparent" }
1508+ GradientStop { position: 1.0; color: UbuntuColors.warmGrey }
1509+ }
1510+
1511+ Rectangle {
1512+ anchors.verticalCenter: parent.verticalCenter
1513+ anchors.horizontalCenter: parent.horizontalCenter
1514+ antialiasing: true
1515+ color: "#444"
1516+ height: playerControlsPlayButton.height - units.gu(.1)
1517+ radius: height / 2
1518+ width: height
1519+
1520+ Rectangle {
1521+ id: playerControlsPlayInnerCircle
1522+ anchors.horizontalCenter: parent.horizontalCenter
1523+ anchors.verticalCenter: parent.verticalCenter
1524+ antialiasing: true
1525+ height: units.gu(4.5)
1526+ radius: height / 2
1527+ width: height
1528+ color: styleMusic.toolbar.fullInnerPlayCircleColor
1529+
1530+ // draws the inner shadow/highlight
1531+ Rectangle {
1532+ id: sourceInner
1533+ anchors { fill: parent; margins: -units.gu(0.1) }
1534+ radius: (width / 2)
1535+ antialiasing: true
1536+ gradient: Gradient {
1537+ GradientStop { position: 0.0; color: UbuntuColors.warmGrey }
1538+ GradientStop { position: 0.5; color: "transparent" }
1539+ GradientStop { position: 1.0; color: "black" }
1540+ }
1541+
1542+ Rectangle {
1543+ anchors.verticalCenter: parent.verticalCenter
1544+ anchors.horizontalCenter: parent.horizontalCenter
1545+ antialiasing: true
1546+ height: playerControlsPlayInnerCircle.height - units.gu(.1)
1547+ radius: height / 2
1548+ width: height
1549+ color: styleMusic.toolbar.fullInnerPlayCircleColor
1550+
1551+ Image {
1552+ id: playindicator
1553+ height: units.gu(4)
1554+ width: height
1555+ anchors.horizontalCenter: parent.horizontalCenter
1556+ anchors.verticalCenter: parent.verticalCenter
1557+ opacity: 1
1558+ source: player.playbackState === MediaPlayer.PlayingState ?
1559+ Qt.resolvedUrl("images/media-playback-pause.svg") : Qt.resolvedUrl("images/media-playback-start.svg")
1560+ }
1561+ }
1562+ }
1563+ }
1564+ }
1565+ }
1566+ }
1567+
1568+ /* Container holding the labels for the toolbar */
1569+ Rectangle {
1570+ id: playerControlLabelContainer
1571+ anchors.bottom: parent.bottom
1572+ anchors.left: parent.left
1573+ anchors.right: playerControlsPlayButton.left
1574+ anchors.top: parent.top
1575+ color: "transparent"
1576+
1577+ /* Title of track */
1578+ Label {
1579+ id: playerControlsTitle
1580+ anchors.left: parent.left
1581+ anchors.leftMargin: units.gu(1)
1582+ anchors.right: parent.right
1583+ anchors.rightMargin: units.gu(1)
1584+ anchors.top: parent.top
1585+ anchors.topMargin: units.gu(1)
1586+ color: styleMusic.playerControls.labelColor
1587+ elide: Text.ElideRight
1588+ fontSize: "medium"
1589+ objectName: "playercontroltitle"
1590+ text: player.currentMetaTitle === ""
1591+ ? player.source : player.currentMetaTitle
1592+ }
1593+
1594+ /* Artist of track */
1595+ Label {
1596+ id: playerControlsArtist
1597+ anchors.left: parent.left
1598+ anchors.leftMargin: units.gu(1)
1599+ anchors.right: parent.right
1600+ anchors.rightMargin: units.gu(1)
1601+ anchors.top: playerControlsTitle.bottom
1602+ color: styleMusic.playerControls.labelColor
1603+ elide: Text.ElideRight
1604+ fontSize: "small"
1605+ text: player.currentMetaArtist
1606+ }
1607+
1608+ /* Album of track */
1609+ Label {
1610+ id: playerControlsAlbum
1611+ anchors.left: parent.left
1612+ anchors.leftMargin: units.gu(1)
1613+ anchors.right: parent.right
1614+ anchors.rightMargin: units.gu(1)
1615+ anchors.top: playerControlsArtist.bottom
1616+ color: styleMusic.playerControls.labelColor
1617+ elide: Text.ElideRight
1618+ fontSize: "small"
1619+ text: player.currentMetaAlbum
1620+ }
1621+ }
1622+
1623+ Rectangle {
1624+ anchors.fill: playerControlLabelContainer
1625+ color: "transparent"
1626+ function trigger() {
1627+ nowPlaying.visible = true;
1628+ }
1629+ }
1630+ }
1631+ }
1632+ }
1633+
1634+ /* Object which provides the progress bar when toolbar is minimized */
1635+ Rectangle {
1636+ id: musicToolbarSmallProgressBackground
1637+ anchors {
1638+ bottom: parent.top
1639+ left: parent.left
1640+ right: parent.right
1641+ }
1642+ color: styleMusic.common.black
1643+ height: musicToolbarPanel.minimizedHeight
1644+ visible: (!musicToolbarPanel.animating &&
1645+ !musicToolbarPanel.opened)
1646+ || musicToolbarPanel.currentMode == "expanded"
1647+
1648+ Rectangle {
1649+ id: musicToolbarSmallProgressHint
1650+ anchors.left: parent.left
1651+ anchors.top: parent.top
1652+ color: styleMusic.nowPlaying.progressForegroundColor
1653+ height: parent.height
1654+ width: 0
1655
1656 Connections {
1657 target: player
1658 onPositionChanged: {
1659- if (musicToolbarFullProgressBarContainer.seeking === false)
1660- {
1661- musicToolbarFullProgressHandle.x = (player.position / player.duration) * musicToolbarFullProgressBarContainer.width
1662- - musicToolbarFullProgressHandle.width / 2;
1663- }
1664- }
1665- }
1666-
1667- // Black background behind the progress bar
1668- Rectangle {
1669- id: musicToolbarFullProgressBackground
1670- anchors.verticalCenter: parent.verticalCenter;
1671- color: styleMusic.toolbar.fullProgressBackgroundColor;
1672- height: parent.height;
1673- radius: units.gu(0.5)
1674- width: parent.width;
1675- }
1676-
1677- // The orange fill of the progress bar
1678- Rectangle {
1679- id: musicToolbarFullProgressTrough
1680- anchors.verticalCenter: parent.verticalCenter;
1681- antialiasing: true
1682- color: styleMusic.toolbar.fullProgressTroughColor;
1683- height: parent.height;
1684- radius: units.gu(0.5)
1685- width: musicToolbarFullProgressHandle.x + (height / 2); // +radius
1686- }
1687-
1688- // The current position (handle) of the progress bar
1689- Rectangle {
1690- id: musicToolbarFullProgressHandle
1691- anchors.verticalCenter: musicToolbarFullProgressBackground.verticalCenter
1692- antialiasing: true
1693- color: styleMusic.nowPlaying.progressHandleColor
1694- height: units.gu(1.5)
1695- radius: height / 2
1696- width: height
1697-
1698- // On X change update the position string
1699- onXChanged: {
1700- var fraction = (x + (width / 2)) / parent.width;
1701- musicToolbarFullPositionLabel.text = durationToString(fraction * player.duration)
1702- }
1703- }
1704- }
1705-
1706- /* Duration label */
1707- Label {
1708- id: musicToolbarFullDurationLabel
1709- anchors.right: parent.right
1710- anchors.rightMargin: units.gu(2)
1711- anchors.top: parent.top
1712- color: styleMusic.nowPlaying.labelColor
1713- fontSize: "x-small"
1714- height: parent.height
1715- horizontalAlignment: Text.AlignHCenter
1716- text: durationToString(player.duration)
1717- verticalAlignment: Text.AlignVCenter
1718- width: units.gu(3)
1719- }
1720-
1721- /* Border at the bottom */
1722- Rectangle {
1723- anchors.bottom: parent.bottom
1724- anchors.left: parent.left
1725- anchors.right: parent.right
1726- color: styleMusic.common.white
1727- height: units.gu(0.1)
1728- opacity: 0.1
1729- }
1730- }
1731- }
1732-
1733- /* Object which provides the progress bar when toolbar is minimized */
1734- Rectangle {
1735- id: musicToolbarSmallProgressBackground
1736- anchors.left: parent.left
1737- anchors.top: parent.top
1738- color: styleMusic.common.black
1739- height: minimizedHeight
1740- width: parent.width
1741-
1742- Rectangle {
1743- id: musicToolbarSmallProgressHint
1744- anchors.left: parent.left
1745- anchors.top: parent.top
1746- color: styleMusic.nowPlaying.progressForegroundColor
1747- height: parent.height
1748- width: 0
1749-
1750- Connections {
1751- target: player
1752- onPositionChanged: {
1753- musicToolbarSmallProgressHint.width = (player.position / player.duration) * musicToolbarSmallProgressBackground.width
1754- }
1755- }
1756- }
1757- }
1758-
1759- /* Object which captures mouse drags to show/hide the toolbar */
1760- MouseArea {
1761- id: musicToolbarMouseArea
1762- anchors.fill: parent
1763- enabled: !wideAspect
1764-
1765- property bool changed: false
1766- property int startContainerY: 0
1767- property int startMouseY: 0
1768-
1769- // Settings for dragging the container
1770- drag.axis: Drag.YAxis
1771- drag.maximumY: musicToolbarContainer.parent.height - minimizedHeight
1772- drag.minimumY: currentMode === "full" ?
1773- musicToolbarContainer.parent.height - fullHeight :
1774- musicToolbarContainer.parent.height - expandedHeight - minimizedHeight
1775- drag.target: musicToolbarContainer
1776-
1777- propagateComposedEvents: true
1778- onClicked: mouse.accepted = changed // pass clicked evented to children unless changed (YAxis)
1779-
1780- onMouseYChanged: {
1781- // Mouse has been accepted with YAxis changed and set changed to true
1782- mouse.accepted = true;
1783- changed = true;
1784- }
1785-
1786- onPressAndHold: {
1787- // If the item hasn't moved then run the hint animation
1788- if (musicToolbarContainer.y === startContainerY)
1789- {
1790- musicToolbarContainerHintAnimation.start();
1791- mouse.accepted = true; // mouse has been accepted
1792- }
1793- else
1794- {
1795- mouse.accepted = false;
1796- }
1797- }
1798-
1799- onPressed: {
1800- mouse.accepted = false; // mouse not accepted yet
1801-
1802- // Record starting positions for later
1803- startContainerY = musicToolbarContainer.y;
1804- startMouseY = mouse.y;
1805-
1806- // Restart autohide timer on mouse press inside toolbar
1807- startAutohideTimer();
1808- }
1809-
1810- onReleased: {
1811- mouse.accepted = changed; // mouse is accepted if the YAxis has changed
1812- changed = false; // reset changed
1813-
1814- // fix for flicker on first run (needs a value to have been set?)
1815- musicToolbarContainer.y = musicToolbarContainer.y;
1816-
1817- var diff = musicToolbarContainer.y - startContainerY;
1818-
1819- if (diff > units.gu(3))
1820- {
1821- hideToolbar();
1822- }
1823- else if (diff < -units.gu(3))
1824- {
1825- showToolbar();
1826- }
1827- else
1828- {
1829- musicToolbarContainerReset.start();
1830- }
1831- }
1832-
1833- // On pressandhold reveal part of the toolbar as a hint
1834- NumberAnimation {
1835- id: musicToolbarContainerHintAnimation
1836- target: musicToolbarContainer
1837- property: "y"
1838- duration: musicToolbarContainer.transitionDuration
1839- to: musicToolbarContainer.parent.height - minimizedHeight - units.gu(1.5)
1840- }
1841-
1842- // Animation to reset the toolbar if it hasn't been dragged far enough
1843- NumberAnimation {
1844- id: musicToolbarContainerReset
1845- target: musicToolbarContainer
1846- property: "y"
1847- duration: musicToolbarContainer.transitionDuration
1848- to: musicToolbarMouseArea.startContainerY
1849- }
1850- }
1851-
1852- /* Mouse events for the progress bar
1853- is after musicToolbarMouseArea so that it captures mouse events for dragging */
1854- MouseArea {
1855- id: musicToolbarFullProgressMouseArea
1856- height: units.gu(2)
1857- width: musicToolbarFullProgressBarContainer.width
1858- x: musicToolbarFullProgressBarContainer.x
1859- y: musicToolbarFullProgressBarContainer.y
1860-
1861- drag.axis: Drag.XAxis
1862- drag.minimumX: -(musicToolbarFullProgressHandle.width / 2)
1863- drag.maximumX: musicToolbarFullProgressBarContainer.width - (musicToolbarFullProgressHandle.width / 2)
1864- drag.target: musicToolbarFullProgressHandle
1865-
1866- onPressed: {
1867- musicToolbarFullProgressBarContainer.seeking = true;
1868-
1869- // Jump the handle to the current mouse position
1870- musicToolbarFullProgressHandle.x = mouse.x - (musicToolbarFullProgressHandle.width / 2);
1871- }
1872-
1873- onReleased: {
1874- var fraction = mouse.x / musicToolbarFullProgressBarContainer.width;
1875-
1876- // Limit the bounds of the fraction
1877- fraction = fraction < 0 ? 0 : fraction
1878- fraction = fraction > 1 ? 1 : fraction
1879-
1880- player.seek((fraction) * player.duration);
1881- musicToolbarFullProgressBarContainer.seeking = false;
1882- }
1883- }
1884-
1885- // Timer for autohide
1886- Timer {
1887- id: toolbarAutoHideTimer
1888- interval: 5000
1889- repeat: false
1890- running: false
1891- onTriggered: {
1892- if (currentPage !== nowPlaying) { // don't autohide on now playing
1893- hideToolbar();
1894+ musicToolbarSmallProgressHint.width = (player.position / player.duration) * musicToolbarSmallProgressBackground.width
1895+ }
1896+ }
1897+ }
1898+ }
1899+
1900+ /* Mouse events for the progress bar
1901+ is after musicToolbarMouseArea so that it captures mouse events for dragging */
1902+ MouseArea {
1903+ id: musicToolbarFullProgressMouseArea
1904+ height: units.gu(2)
1905+ width: musicToolbarFullProgressBarContainer.width
1906+ x: musicToolbarFullProgressBarContainer.x
1907+ y: musicToolbarFullProgressBarContainer.y
1908+
1909+ drag.axis: Drag.XAxis
1910+ drag.minimumX: -(musicToolbarFullProgressHandle.width / 2)
1911+ drag.maximumX: musicToolbarFullProgressBarContainer.width - (musicToolbarFullProgressHandle.width / 2)
1912+ drag.target: musicToolbarFullProgressHandle
1913+
1914+ onPressed: {
1915+ musicToolbarFullProgressBarContainer.seeking = true;
1916+
1917+ // Jump the handle to the current mouse position
1918+ musicToolbarFullProgressHandle.x = mouse.x - (musicToolbarFullProgressHandle.width / 2);
1919+ }
1920+
1921+ onReleased: {
1922+ var fraction = mouse.x / musicToolbarFullProgressBarContainer.width;
1923+
1924+ // Limit the bounds of the fraction
1925+ fraction = fraction < 0 ? 0 : fraction
1926+ fraction = fraction > 1 ? 1 : fraction
1927+
1928+ player.seek((fraction) * player.duration);
1929+ musicToolbarFullProgressBarContainer.seeking = false;
1930+ }
1931+ }
1932+
1933+ // Timer for autohide
1934+ Timer {
1935+ id: toolbarAutoHideTimer
1936+ interval: 5000
1937+ repeat: false
1938+ running: false
1939+ onTriggered: {
1940+ if (currentPage !== nowPlaying) { // don't autohide on now playing
1941+ hideToolbar();
1942+ }
1943 }
1944 }
1945 }
1946 }
1947+
1948
1949=== modified file 'music-app.qml'
1950--- music-app.qml 2014-03-20 03:05:59 +0000
1951+++ music-app.qml 2014-03-23 01:31:10 +0000
1952@@ -934,9 +934,6 @@
1953 id: musicToolbar
1954 objectName: "musicToolbarObject"
1955 z: 200 // put on top of everything else
1956-
1957- property bool animating: false
1958- property bool opened: false
1959 }
1960
1961 PageStack {

Subscribers

People subscribed via source and target branches

to status/vote changes: