~nick-dedekind/unity8/indicators.hint-interval

« back to all changes in this revision

Viewing changes to qml/Dash/Previews/PreviewAudioPlayback.qml

  • Committer: Nick Dedekind
  • Date: 2014-03-07 15:54:57 UTC
  • mfrom: (638.1.118 unity8)
  • Revision ID: nicholas.dedekind@gmail.com-20140307155457-f0s1zu5ll2czt3rq
merged with trunk

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (C) 2014 Canonical, Ltd.
 
3
 *
 
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.
 
7
 *
 
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.
 
12
 *
 
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/>.
 
15
 */
 
16
 
 
17
import QtQuick 2.0
 
18
import QtMultimedia 5.0
 
19
import Ubuntu.Components 0.1
 
20
 
 
21
/*! \brief Preview widget for audio tracks.
 
22
 
 
23
    This widget shows tracks contained in widgetData["tracks"], each of which should be of the form:
 
24
 
 
25
    \code{.json}
 
26
    {
 
27
      "source" "uri://to/file",
 
28
      "title": "Title",
 
29
      "subtitle": "Subtitle", // optional
 
30
      "length": 125 // in seconds
 
31
    }
 
32
    \endcode
 
33
 */
 
34
 
 
35
PreviewWidget {
 
36
    id: root
 
37
    height: childrenRect.height
 
38
 
 
39
    onIsCurrentPreviewChanged: if (!isCurrentPreview) audio.stop()
 
40
 
 
41
    Audio {
 
42
        id: audio
 
43
        objectName: "audio"
 
44
 
 
45
        property real progress: audio.position / audio.duration
 
46
        property Item playingItem
 
47
 
 
48
        Component.onDestruction: {
 
49
            // destroying the component doesn't automatically send stop to the media service, probably a bug in QtMultimedia
 
50
            audio.stop();
 
51
        }
 
52
 
 
53
        onErrorStringChanged: console.warn("Audio player error:", errorString)
 
54
 
 
55
        function lengthToString(s) {
 
56
            if (typeof(s) !== "number" || s <= 0) return "";
 
57
 
 
58
            var sec = "" + s % 60;
 
59
            if (sec.length == 1) sec = "0" + sec;
 
60
            var hour = Math.floor(s / 3600);
 
61
            if (hour < 1) {
 
62
                return Math.floor(s / 60) + ":" + sec;
 
63
            } else {
 
64
                var min = "" + Math.floor(s / 60) % 60;
 
65
                if (min.length == 1) min = "0" + min;
 
66
                return hour + ":" + min + ":" + sec;
 
67
            }
 
68
        }
 
69
    }
 
70
 
 
71
    Column {
 
72
        anchors { left: parent.left; right: parent.right }
 
73
        visible: trackRepeater.count > 0
 
74
 
 
75
        Repeater {
 
76
            id: trackRepeater
 
77
            objectName: "trackRepeater"
 
78
            model: root.widgetData["tracks"]
 
79
 
 
80
            function play(item, source) {
 
81
                audio.stop();
 
82
                // Make sure we change the source, even if two items point to the same uri location
 
83
                audio.source = "";
 
84
                audio.source = source;
 
85
                audio.playingItem = item;
 
86
                audio.play();
 
87
            }
 
88
 
 
89
            delegate: Item {
 
90
                id: trackItem
 
91
                objectName: "trackItem" + index
 
92
 
 
93
                property bool isPlayingItem: audio.playingItem == trackItem
 
94
 
 
95
                anchors { left: parent.left; right: parent.right }
 
96
                height: units.gu(5)
 
97
 
 
98
                Row {
 
99
                    id: trackRow
 
100
 
 
101
                    property int column1Width: units.gu(3)
 
102
                    property int column2Width: width - (2 * spacing) - column1Width - column3Width
 
103
                    property int column3Width: units.gu(4)
 
104
 
 
105
                    anchors.verticalCenter: parent.verticalCenter
 
106
                    width: parent.width
 
107
                    spacing: units.gu(1)
 
108
 
 
109
                    Button {
 
110
                        objectName: "playButton"
 
111
                        width: trackRow.column1Width
 
112
                        height: width
 
113
                        iconSource: audio.playbackState == Audio.PlayingState && trackItem.isPlayingItem ? "image://theme/media-playback-pause" : "image://theme/media-playback-start"
 
114
 
 
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
 
117
                        color: "#01000000"
 
118
 
 
119
                        onClicked: {
 
120
                            if (trackItem.isPlayingItem) {
 
121
                                if (audio.playbackState == Audio.PlayingState) {
 
122
                                    audio.pause();
 
123
                                } else if (audio.playbackState == Audio.PausedState) {
 
124
                                    audio.play();
 
125
                                }
 
126
                            } else {
 
127
                                trackRepeater.play(trackItem, modelData["source"]);
 
128
                            }
 
129
                        }
 
130
                    }
 
131
 
 
132
                    Item {
 
133
                        anchors.verticalCenter: parent.verticalCenter
 
134
                        width: parent.column2Width
 
135
                        height: trackSubtitleLabel.visible ? trackTitleLabel.height + trackSubtitleLabel.height : trackTitleLabel.height
 
136
 
 
137
                        Label {
 
138
                            id: trackTitleLabel
 
139
                            objectName: "trackTitleLabel"
 
140
                            anchors { top: parent.top; left: parent.left; right: parent.right }
 
141
                            opacity: 0.9
 
142
                            color: Theme.palette.selected.backgroundText
 
143
                            fontSize: "small"
 
144
                            horizontalAlignment: Text.AlignLeft
 
145
                            text: modelData["title"]
 
146
                            elide: Text.ElideRight
 
147
                        }
 
148
 
 
149
                        Label {
 
150
                            id: trackSubtitleLabel
 
151
                            objectName: "trackSubtitleLabel"
 
152
                            anchors { top: trackTitleLabel.bottom; left: parent.left; right: parent.right }
 
153
                            visible: text !== ""
 
154
                            opacity: 0.9
 
155
                            color: Theme.palette.selected.backgroundText
 
156
                            fontSize: "small"
 
157
                            horizontalAlignment: Text.AlignLeft
 
158
                            text: modelData["subtitle"] || ""
 
159
                            elide: Text.ElideRight
 
160
                        }
 
161
 
 
162
                        UbuntuShape {
 
163
                            id: progressBarFill
 
164
                            objectName: "progressBarFill"
 
165
 
 
166
                            property int maxWidth: progressBarImage.width - units.dp(4)
 
167
 
 
168
                            anchors {
 
169
                                left: progressBarImage.left
 
170
                                right: progressBarImage.right
 
171
                                verticalCenter: progressBarImage.verticalCenter
 
172
                                margins: units.dp(2)
 
173
                                rightMargin: maxWidth - (maxWidth * audio.progress) + units.dp(2)
 
174
                            }
 
175
                            height: units.dp(2)
 
176
                            visible: progressBarImage.visible
 
177
                            color: UbuntuColors.orange
 
178
                        }
 
179
 
 
180
                        Image {
 
181
                            id: progressBarImage
 
182
                            anchors { left: parent.left; top: parent.bottom; right: parent.right }
 
183
                            height: units.dp(6)
 
184
                            visible: audio.playbackState != Audio.StoppedState && trackItem.isPlayingItem && modelData["length"] > 0
 
185
                            source: "graphics/music_progress_bg.png"
 
186
                        }
 
187
                    }
 
188
 
 
189
                    Label {
 
190
                        id: timeLabel
 
191
                        objectName: "timeLabel"
 
192
                        anchors.verticalCenter: parent.verticalCenter
 
193
                        width: parent.column3Width
 
194
                        opacity: 0.9
 
195
                        color: Theme.palette.selected.backgroundText
 
196
                        fontSize: "small"
 
197
                        horizontalAlignment: Text.AlignRight
 
198
                        text: audio.lengthToString(modelData["length"])
 
199
                    }
 
200
                }
 
201
            }
 
202
        }
 
203
    }
 
204
}