on xenial help sign in
only instantiate one Audio element per preview.
040c362Michael Zanetti
Dash/Music/MusicPreview.qml+143−123
@@ -52,154 +52,174 @@ GenericPreview {
52 Component {
52 Component {
53 id: descriptionComponent
53 id: descriptionComponent
54
54
55− Column {
55+ Item {
56 height: childrenRect.height
56 height: childrenRect.height
57+ Audio {
58+ id: audioPlayer
59+ objectName: "audioPlayer"
60+ property real percent: audioPlayer.position * 100 / audioPlayer.duration
61+ property string uri
62+ source: uri
63+
64+ Component.onDestruction: {
65+ audioPlayer.stop();
66+ }
67+
68+ onErrorStringChanged: print("Audio player error:", errorString)
57
69
58− ThinDivider {
70+ }
59− objectName: "topDivider"
71+ Connections {
72+ target: root
73+ onIsCurrentChanged: {
74+ if (!root.isCurrent) {
75+ audioPlayer.stop();
76+ }
77+ }
78+ }
79+
80+ Column {
60 anchors {
81 anchors {
61 left: parent.left
82 left: parent.left
62 right: parent.right
83 right: parent.right
63 }
84 }
64− visible: trackRepeater.count > 0
65− }
66
85
67− Repeater {
86+ height: childrenRect.height
68− id: trackRepeater
87+
88+ ThinDivider {
69− objectName: "trackRepeater"
89+ objectName: "topDivider"
90+ anchors {
91+ left: parent.left
92+ right: parent.right
93+ }
94+ visible: trackRepeater.count > 0
95+ }
70
96
71− model: previewData.tracks
97+ Repeater {
98+ id: trackRepeater
99+ objectName: "trackRepeater"
72
100
73− signal stopPlayback()
101+ model: previewData.tracks
74
102
75− delegate: Item {
103+ delegate: Item {
104+ id: trackItem
76− objectName: "trackItem" + index
105+ objectName: "trackItem" + index
77− width: parent.width
78− height: units.gu(5)
79− Row {
80− id: trackRow
81 width: parent.width
106 width: parent.width
82− spacing: units.gu(1)
107+ height: units.gu(5)
83− property int column1Width: units.gu(3)
108+ property bool isPlayingItem: false
84− property int column2Width: width - (2 * spacing) - column1Width - column3Width
109+
85− property int column3Width: units.gu(4)
110+ Connections {
86− anchors.verticalCenter: parent.verticalCenter
111+ target: audioPlayer
87−
112+ onUriChanged: trackItem.isPlayingItem = false;
88− UbuntuShape {
89− id: playButtonShape
90− objectName: "playButton"
91− width: trackRow.column1Width
92− height: width
93− Icon {
94− width: units.gu(2)
95− height: width
96− anchors.centerIn: playButtonShape
97− name: audioPlayer.playbackState == Audio.PlayingState ? "media-playback-pause" : "media-playback-start"
98− color: "white"
99− opacity: .9
100− }
101− MouseArea {
102− anchors.fill: parent
103− onClicked: {
104− if (audioPlayer.playbackState == Audio.PlayingState) {
105− audioPlayer.pause();
106− } else if (audioPlayer.playbackState == Audio.PausedState){
107− audioPlayer.play();
108− } else {
109− trackRepeater.stopPlayback();
110− audioPlayer.play();
111− }
112− }
113− }
114 }
113 }
115
114
116− Label {
115+ function play() {
117− objectName: "trackTitleLabel"
116+ audioPlayer.stop();
118− fontSize: "small"
117+ audioPlayer.uri = "";
119− opacity: 0.9
118+ audioPlayer.uri = model.uri;
120− color: "white"
119+ isPlayingItem = true;
121− horizontalAlignment: Text.AlignLeft
120+ audioPlayer.play();
121+ }
122+
123+ Row {
124+ id: trackRow
125+ width: parent.width
126+ spacing: units.gu(1)
127+ property int column1Width: units.gu(3)
128+ property int column2Width: width - (2 * spacing) - column1Width - column3Width
129+ property int column3Width: units.gu(4)
122 anchors.verticalCenter: parent.verticalCenter
130 anchors.verticalCenter: parent.verticalCenter
123− width: parent.column2Width
124− text: title
125− style: Text.Raised
126− styleColor: "black"
127− elide: Text.ElideRight
128
131
129 UbuntuShape {
132 UbuntuShape {
130− id: progressBarFill
133+ id: playButtonShape
131− objectName: "progressBarFill"
134+ objectName: "playButton"
132− color: UbuntuColors.orange
135+ width: trackRow.column1Width
133− anchors.left: progressBarImage.left
136+ height: width
134− anchors.right: progressBarImage.right
137+ Icon {
135− anchors.verticalCenter: progressBarImage.verticalCenter
138+ width: units.gu(2)
136− height: units.dp(2)
139+ height: width
137− anchors.margins: units.dp(2)
140+ anchors.centerIn: playButtonShape
138− anchors.rightMargin: maxWidth - (maxWidth * audioPlayer.percent / 100) + units.dp(2)
141+ name: audioPlayer.playbackState == Audio.PlayingState && trackItem.isPlayingItem ? "media-playback-pause" : "media-playback-start"
139− visible: progressBarImage.visible
142+ color: "white"
140− property int maxWidth: progressBarImage.width - units.dp(4)
143+ opacity: .9
144+ }
145+ MouseArea {
146+ anchors.fill: parent
147+ onClicked: {
148+ if (trackItem.isPlayingItem) {
149+ if (audioPlayer.playbackState == Audio.PlayingState) {
150+ audioPlayer.pause();
151+ } else if (audioPlayer.playbackState == Audio.PausedState){
152+ audioPlayer.play();
141− }
153+ }
142− Image {
154+ } else {
143− id: progressBarImage
155+ trackItem.play();
144− anchors {
156+ }
145− left: parent.left
157+ }
146− top: parent.bottom
147− right: parent.right
148 }
158 }
149− height: units.dp(6)
150− visible: audioPlayer.playbackState != Audio.StoppedState
151− source: "graphics/music_progress_bg.png"
152−
153 }
159 }
154− }
155− Label {
156− id: valueLabel
157− objectName: "timeLabel"
158− fontSize: "small"
159− opacity: 0.9
160− color: "white"
161− anchors.verticalCenter: parent.verticalCenter
162− horizontalAlignment: Text.AlignRight
163− width: parent.column3Width
164− text: length
165− style: Text.Raised
166− styleColor: "black"
167− }
168− }
169−
170− ThinDivider {
171− anchors {
172− left: parent.left
173− bottom: parent.bottom
174− right: parent.right
175− }
176− }
177
160
178− Audio {
161+ Label {
179− id: audioPlayer
162+ objectName: "trackTitleLabel"
180− objectName: "audioPlayer"
163+ fontSize: "small"
181− source: uri
164+ opacity: 0.9
182− property real percent: audioPlayer.position * 100 / audioPlayer.duration
165+ color: "white"
166+ horizontalAlignment: Text.AlignLeft
167+ anchors.verticalCenter: parent.verticalCenter
168+ width: parent.column2Width
169+ text: title
170+ style: Text.Raised
171+ styleColor: "black"
172+ elide: Text.ElideRight
173+
174+ UbuntuShape {
175+ id: progressBarFill
176+ objectName: "progressBarFill"
177+ color: UbuntuColors.orange
178+ anchors.left: progressBarImage.left
179+ anchors.right: progressBarImage.right
180+ anchors.verticalCenter: progressBarImage.verticalCenter
181+ height: units.dp(2)
182+ anchors.margins: units.dp(2)
183+ anchors.rightMargin: maxWidth - (maxWidth * audioPlayer.percent / 100) + units.dp(2)
184+ visible: progressBarImage.visible
185+ property int maxWidth: progressBarImage.width - units.dp(4)
186+ }
187+ Image {
188+ id: progressBarImage
189+ anchors {
190+ left: parent.left
191+ top: parent.bottom
192+ right: parent.right
193+ }
194+ height: units.dp(6)
195+ visible: audioPlayer.playbackState != Audio.StoppedState && trackItem.isPlayingItem
196+ source: "graphics/music_progress_bg.png"
183
197
184− Component.onDestruction: {
198+ }
185− audioPlayer.stop();
199+ }
200+ Label {
201+ id: valueLabel
202+ objectName: "timeLabel"
203+ fontSize: "small"
204+ opacity: 0.9
205+ color: "white"
206+ anchors.verticalCenter: parent.verticalCenter
207+ horizontalAlignment: Text.AlignRight
208+ width: parent.column3Width
209+ text: length
210+ style: Text.Raised
211+ styleColor: "black"
212+ }
186 }
213 }
187
214
188− onErrorStringChanged: print("Audio player error:", errorString)
215+ ThinDivider {
189−
216+ anchors {
190− }
217+ left: parent.left
191− Connections {
218+ bottom: parent.bottom
192− target: root
219+ right: parent.right
193− onIsCurrentChanged: {
194− if (!root.isCurrent) {
195− audioPlayer.stop();
196 }
220 }
197 }
221 }
198 }
222 }
199− Connections {
200− target: trackRepeater
201− onStopPlayback: audioPlayer.stop();
202− }
203 }
223 }
204 }
224 }
205 }
225 }
tests/qmltests/Dash/Music/tst_MusicPreview.qml+10−11
@@ -112,9 +112,7 @@ Rectangle {
112 var track1PlayButton = findChild(track1Item, "playButton");
112 var track1PlayButton = findChild(track1Item, "playButton");
113 var track2PlayButton = findChild(track2Item, "playButton");
113 var track2PlayButton = findChild(track2Item, "playButton");
114
114
115− var track0AudioPlayer = findInvisibleChild(track0Item, "audioPlayer");
115+ var audioPlayer = findInvisibleChild(musicPreview, "audioPlayer");
116− var track1AudioPlayer = findInvisibleChild(track1Item, "audioPlayer");
117− var track2AudioPlayer = findInvisibleChild(track1Item, "audioPlayer");
118
116
119 // All progress bars must be hidden in the beginning
117 // All progress bars must be hidden in the beginning
120 compare(track0ProgressBar.visible, false);
118 compare(track0ProgressBar.visible, false);
@@ -124,7 +122,8 @@ Rectangle {
124 // Playing track 0 should make progress bar 0 visible
122 // Playing track 0 should make progress bar 0 visible
125 mouseClick(track0PlayButton, track0PlayButton.width / 2, track0PlayButton.height / 2);
123 mouseClick(track0PlayButton, track0PlayButton.width / 2, track0PlayButton.height / 2);
126
124
127− tryCompare(track0AudioPlayer, "playbackState", Audio.PlayingState);
125+ tryCompare(audioPlayer, "playbackState", Audio.PlayingState);
126+ compare(audioPlayer.uri, musicPreview.previewData.tracks.get(0).uri)
128
127
129 tryCompare(track0ProgressBar, "visible", true);
128 tryCompare(track0ProgressBar, "visible", true);
130 tryCompare(track1ProgressBar, "visible", false);
129 tryCompare(track1ProgressBar, "visible", false);
@@ -132,18 +131,20 @@ Rectangle {
132
131
133 // Clicking the button again should pause it. The progress bar should stay visible
132 // Clicking the button again should pause it. The progress bar should stay visible
134 mouseClick(track0PlayButton, track0PlayButton.width / 2, track0PlayButton.height / 2);
133 mouseClick(track0PlayButton, track0PlayButton.width / 2, track0PlayButton.height / 2);
135− tryCompare(track0AudioPlayer, "playbackState", Audio.PausedState);
134+ tryCompare(audioPlayer, "playbackState", Audio.PausedState);
135+ compare(audioPlayer.uri, musicPreview.previewData.tracks.get(0).uri)
136 tryCompare(track0ProgressBar, "visible", true);
136 tryCompare(track0ProgressBar, "visible", true);
137
137
138 // Continue playback
138 // Continue playback
139 mouseClick(track0PlayButton, track0PlayButton.width / 2, track0PlayButton.height / 2);
139 mouseClick(track0PlayButton, track0PlayButton.width / 2, track0PlayButton.height / 2);
140− tryCompare(track0AudioPlayer, "playbackState", Audio.PlayingState);
140+ tryCompare(audioPlayer, "playbackState", Audio.PlayingState);
141+ compare(audioPlayer.uri, musicPreview.previewData.tracks.get(0).uri)
141
142
142 // Playing track 1 should make progress bar 1 visible and hide progress bar 0 again
143 // Playing track 1 should make progress bar 1 visible and hide progress bar 0 again
143 mouseClick(track1PlayButton, track1PlayButton.width / 2, track1PlayButton.height / 2);
144 mouseClick(track1PlayButton, track1PlayButton.width / 2, track1PlayButton.height / 2);
144
145
145− tryCompare(track0AudioPlayer, "playbackState", Audio.StoppedState)
146− tryCompare(track1AudioPlayer, "playbackState", Audio.PlayingState)
146+ tryCompare(audioPlayer, "playbackState", Audio.PlayingState);
147+ compare(audioPlayer.uri, musicPreview.previewData.tracks.get(1).uri)
147
148
148 tryCompare(track0ProgressBar, "visible", false);
149 tryCompare(track0ProgressBar, "visible", false);
149 tryCompare(track1ProgressBar, "visible", true);
150 tryCompare(track1ProgressBar, "visible", true);
@@ -151,9 +152,7 @@ Rectangle {
151
152
152 // Switching away from this preview should make all players shut up!
153 // Switching away from this preview should make all players shut up!
153 musicPreview.isCurrent = false
154 musicPreview.isCurrent = false
154− tryCompare(track0AudioPlayer, "playbackState", Audio.StoppedState)
155− tryCompare(track1AudioPlayer, "playbackState", Audio.StoppedState)
156− tryCompare(track2AudioPlayer, "playbackState", Audio.StoppedState)
155+ tryCompare(audioPlayer, "playbackState", Audio.StoppedState);
157 }
156 }
158 }
157 }
159}
158}