2 * Copyright (C) 2014,2015 Canonical, Ltd.
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; version 3.
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 import QtMultimedia 5.0
19 import Ubuntu.Components 1.3
21 /*! \brief Preview widget for audio tracks.
23 This widget shows tracks contained in widgetData["tracks"], each of which should be of the form:
27 "source" "uri://to/file",
29 "subtitle": "Subtitle", // optional
30 "length": 125 // in seconds
37 implicitHeight: childrenRect.height
39 onIsCurrentPreviewChanged: if (!isCurrentPreview) audio.stop()
45 property real progress: audio.position / audio.duration
46 property Item playingItem
48 Component.onDestruction: {
49 // destroying the component doesn't automatically send stop to the media service, probably a bug in QtMultimedia
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) {
82 // Make sure we change the source, even if two items point to the same uri location
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"
115 // Can't be "transparent" or "#00xxxxxx" as the button optimizes away the surrounding shape
116 // FIXME when this is resolved: https://bugs.launchpad.net/ubuntu-ui-toolkit/+bug/1251685
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 : theme.palette.normal.baseText
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 : theme.palette.normal.baseText
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 backgroundColor: 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 : theme.palette.normal.baseText
198 horizontalAlignment: Text.AlignRight
199 text: audio.lengthToString(modelData["length"])