18 import QtMultimedia 5.0
19 import Ubuntu.Components 0.1
37 height: childrenRect.height
39 onIsCurrentPreviewChanged:
if (!isCurrentPreview) audio.stop()
45 property real progress: audio.position / audio.duration
46 property Item playingItem
48 Component.onDestruction: {
53 onErrorStringChanged: console.warn(
"Audio player error:", errorString)
55 function lengthToString(s) {
56 if (typeof(s) !==
"number" || s <= 0)
return "";
58 var sec =
"" + s % 60;
59 if (sec.length == 1) sec =
"0" + sec;
60 var hour = Math.floor(s / 3600);
62 return Math.floor(s / 60) +
":" + sec;
64 var min =
"" + Math.floor(s / 60) % 60;
65 if (min.length == 1) min =
"0" + min;
66 return hour +
":" + min +
":" + sec;
72 anchors { left: parent.left; right: parent.right }
73 visible: trackRepeater.count > 0
77 objectName:
"trackRepeater"
78 model: root.widgetData[
"tracks"]
80 function play(item, source) {
84 audio.source = source;
85 audio.playingItem = item;
91 objectName:
"trackItem" + index
93 property bool isPlayingItem: audio.playingItem == trackItem
95 anchors { left: parent.left; right: parent.right }
101 property int column1Width: units.gu(3)
102 property int column2Width: width - (2 * spacing) - column1Width - column3Width
103 property
int column3Width: units.gu(4)
105 anchors.verticalCenter: parent.verticalCenter
110 objectName:
"playButton"
111 width: trackRow.column1Width
113 iconSource: audio.playbackState == Audio.PlayingState && trackItem.isPlayingItem ?
"image://theme/media-playback-pause" :
"image://theme/media-playback-start"
120 if (trackItem.isPlayingItem) {
121 if (audio.playbackState == Audio.PlayingState) {
123 }
else if (audio.playbackState == Audio.PausedState) {
127 trackRepeater.play(trackItem, modelData[
"source"]);
133 anchors.verticalCenter: parent.verticalCenter
134 width: parent.column2Width
135 height: trackSubtitleLabel.visible ? trackTitleLabel.height + trackSubtitleLabel.height : trackTitleLabel.height
139 objectName:
"trackTitleLabel"
140 anchors { top: parent.top; left: parent.left; right: parent.right }
142 color: scopeStyle ? scopeStyle.foreground :
"grey"
144 horizontalAlignment: Text.AlignLeft
145 text: modelData[
"title"]
146 elide: Text.ElideRight
150 id: trackSubtitleLabel
151 objectName:
"trackSubtitleLabel"
152 anchors { top: trackTitleLabel.bottom; left: parent.left; right: parent.right }
155 color: scopeStyle ? scopeStyle.foreground :
"grey"
156 font.weight: Font.Light
158 horizontalAlignment: Text.AlignLeft
159 text: modelData[
"subtitle"] ||
""
160 elide: Text.ElideRight
165 objectName:
"progressBarFill"
167 property int maxWidth: progressBarImage.width - units.dp(4)
170 left: progressBarImage.left
171 right: progressBarImage.right
172 verticalCenter: progressBarImage.verticalCenter
174 rightMargin: maxWidth - (maxWidth * audio.progress) + units.dp(2)
177 visible: progressBarImage.visible
178 color: UbuntuColors.orange
183 anchors { left: parent.left; top: parent.bottom; right: parent.right }
185 visible: audio.playbackState != Audio.StoppedState && trackItem.isPlayingItem && modelData[
"length"] > 0
186 source:
"graphics/music_progress_bg.png"
192 objectName:
"timeLabel"
193 anchors.verticalCenter: parent.verticalCenter
194 width: parent.column3Width
196 color: scopeStyle ? scopeStyle.foreground :
"grey"
198 horizontalAlignment: Text.AlignRight
199 text: audio.lengthToString(modelData[
"length"])