Merge lp:~unity-team/unity8/unity8.previews_textSummary into lp:unity8
- unity8.previews_textSummary
- Merge into trunk
Proposed by
Andrea Cimitan
Status: | Superseded |
---|---|
Proposed branch: | lp:~unity-team/unity8/unity8.previews_textSummary |
Merge into: | lp:unity8 |
Diff against target: |
417 lines (+390/-0) 4 files modified
qml/Dash/Previews/AudioPlayer.qml (+200/-0) qml/Dash/Previews/TextSummary.qml (+27/-0) tests/qmltests/CMakeLists.txt (+1/-0) tests/qmltests/Dash/Previews/tst_AudioPlayer.qml (+162/-0) |
To merge this branch: | bzr merge lp:~unity-team/unity8/unity8.previews_textSummary |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Unity Team | Pending | ||
Review via email: mp+204176@code.launchpad.net |
This proposal has been superseded by a proposal from 2014-01-31.
Commit message
Adding textSummary previews component
Description of the change
It's a label basically with some style
To post a comment you must log in.
- 661. By Andrea Cimitan
-
Merged preview widget branch
- 662. By Andrea Cimitan
-
Merged
- 663. By Andrea Cimitan
-
continue work
- 664. By Andrea Cimitan
-
More work
- 665. By Andrea Cimitan
-
Merged audioplayer
- 666. By Andrea Cimitan
-
Added tests
- 667. By Andrea Cimitan
-
More robust test
- 668. By Andrea Cimitan
-
moved code
- 669. By Andrea Cimitan
-
Added another test and comments
- 670. By Andrea Cimitan
-
Added dot at end of comment
- 671. By Andrea Cimitan
-
Moved end of comment to new line
- 672. By Andrea Cimitan
-
Renamings
- 673. By Andrea Cimitan
-
Merged audioplayer branch
- 674. By Andrea Cimitan
-
More renamings
- 675. By Andrea Cimitan
-
Removed unused dep
- 676. By Andrea Cimitan
-
Modified unity8 pot file
- 677. By Andrea Cimitan
-
Added comments to seemore and moved variable
- 678. By Andrea Cimitan
-
Changes according to review
- 679. By Andrea Cimitan
-
Moar fixes
- 680. By Andrea Cimitan
-
review stuff
Unmerged revisions
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === added file 'qml/Dash/Previews/AudioPlayer.qml' |
2 | --- qml/Dash/Previews/AudioPlayer.qml 1970-01-01 00:00:00 +0000 |
3 | +++ qml/Dash/Previews/AudioPlayer.qml 2014-01-31 09:36:27 +0000 |
4 | @@ -0,0 +1,200 @@ |
5 | +/* |
6 | + * Copyright (C) 2014 Canonical, Ltd. |
7 | + * |
8 | + * This program is free software; you can redistribute it and/or modify |
9 | + * it under the terms of the GNU General Public License as published by |
10 | + * the Free Software Foundation; version 3. |
11 | + * |
12 | + * This program is distributed in the hope that it will be useful, |
13 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
14 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
15 | + * GNU General Public License for more details. |
16 | + * |
17 | + * You should have received a copy of the GNU General Public License |
18 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
19 | + */ |
20 | + |
21 | +import QtQuick 2.0 |
22 | +import QtMultimedia 5.0 |
23 | +import Ubuntu.Components 0.1 |
24 | +import Ubuntu.Components.ListItems 0.1 |
25 | + |
26 | +Item { |
27 | + id: root |
28 | + |
29 | + property alias model: trackRepeater.model |
30 | + |
31 | + implicitHeight: childrenRect.height |
32 | + |
33 | + function stop() { |
34 | + audio.stop() |
35 | + } |
36 | + |
37 | + Audio { |
38 | + id: audio |
39 | + objectName: "audio" |
40 | + |
41 | + property real progress: audio.position / audio.duration |
42 | + property Item playingItem |
43 | + |
44 | + Component.onDestruction: { |
45 | + audio.stop(); |
46 | + } |
47 | + |
48 | + onErrorStringChanged: console.warn("Audio player error:", errorString) |
49 | + } |
50 | + |
51 | + Column { |
52 | + anchors { left: parent.left; right: parent.right } |
53 | + visible: trackRepeater.count > 0 |
54 | + |
55 | + Repeater { |
56 | + id: trackRepeater |
57 | + objectName: "trackRepeater" |
58 | + |
59 | + delegate: Item { |
60 | + id: trackItem |
61 | + objectName: "trackItem" + index |
62 | + |
63 | + property bool isPlayingItem: audio.playingItem == trackItem |
64 | + |
65 | + anchors { left: parent.left; right: parent.right } |
66 | + height: units.gu(5) |
67 | + |
68 | + function play() { |
69 | + audio.stop(); |
70 | + // Make sure we change the source, even if two items point to the same uri location |
71 | + audio.source = ""; |
72 | + audio.source = modelData["source"]; |
73 | + audio.playingItem = trackItem; |
74 | + audio.play(); |
75 | + } |
76 | + |
77 | + Row { |
78 | + id: trackRow |
79 | + |
80 | + property int column1Width: units.gu(3) |
81 | + property int column2Width: width - (2 * spacing) - column1Width - column3Width |
82 | + property int column3Width: units.gu(4) |
83 | + |
84 | + anchors.verticalCenter: parent.verticalCenter |
85 | + width: parent.width |
86 | + spacing: units.gu(1) |
87 | + |
88 | + Button { |
89 | + objectName: "playButton" |
90 | + width: trackRow.column1Width |
91 | + height: width |
92 | + iconSource: audio.playbackState == Audio.PlayingState && trackItem.isPlayingItem ? "image://theme/media-playback-pause" : "image://theme/media-playback-start" |
93 | + |
94 | + // Can't be "transparent" or "#00xxxxxx" as the button optimizes away the surrounding shape |
95 | + // FIXME when this is resolved: https://bugs.launchpad.net/ubuntu-ui-toolkit/+bug/1251685 |
96 | + color: "#01000000" |
97 | + |
98 | + onClicked: { |
99 | + if (trackItem.isPlayingItem) { |
100 | + if (audio.playbackState == Audio.PlayingState) { |
101 | + audio.pause(); |
102 | + } else if (audio.playbackState == Audio.PausedState){ |
103 | + audio.play(); |
104 | + } |
105 | + } else { |
106 | + trackItem.play(); |
107 | + } |
108 | + } |
109 | + } |
110 | + |
111 | + Item { |
112 | + anchors.verticalCenter: parent.verticalCenter |
113 | + width: parent.column2Width |
114 | + height: trackSubtitleLabel.visible ? trackTitleLabel.height + trackSubtitleLabel.height : trackTitleLabel.height |
115 | + |
116 | + Label { |
117 | + id: trackTitleLabel |
118 | + objectName: "trackTitleLabel" |
119 | + anchors { top: parent.top; left: parent.left; right: parent.right } |
120 | + opacity: 0.9 |
121 | + color: "white" |
122 | + fontSize: "small" |
123 | + horizontalAlignment: Text.AlignLeft |
124 | + text: modelData["title"] |
125 | + style: Text.Raised |
126 | + styleColor: "black" |
127 | + elide: Text.ElideRight |
128 | + } |
129 | + |
130 | + Label { |
131 | + id: trackSubtitleLabel |
132 | + objectName: "trackSubtitleLabel" |
133 | + anchors { top: trackTitleLabel.bottom; left: parent.left; right: parent.right } |
134 | + visible: text != "" |
135 | + opacity: 0.9 |
136 | + color: "white" |
137 | + fontSize: "small" |
138 | + horizontalAlignment: Text.AlignLeft |
139 | + text: modelData["subtitle"] !== undefined ? modelData["subtitle"] : "" |
140 | + style: Text.Raised |
141 | + styleColor: "black" |
142 | + elide: Text.ElideRight |
143 | + } |
144 | + |
145 | + UbuntuShape { |
146 | + id: progressBarFill |
147 | + objectName: "progressBarFill" |
148 | + |
149 | + property int maxWidth: progressBarImage.width - units.dp(4) |
150 | + |
151 | + anchors { |
152 | + left: progressBarImage.left |
153 | + right: progressBarImage.right |
154 | + verticalCenter: progressBarImage.verticalCenter |
155 | + margins: units.dp(2) |
156 | + rightMargin: maxWidth - (maxWidth * audio.progress) + units.dp(2) |
157 | + } |
158 | + height: units.dp(2) |
159 | + visible: progressBarImage.visible |
160 | + color: UbuntuColors.orange |
161 | + } |
162 | + |
163 | + Image { |
164 | + id: progressBarImage |
165 | + anchors { left: parent.left; top: parent.bottom; right: parent.right } |
166 | + height: units.dp(6) |
167 | + visible: audio.playbackState != Audio.StoppedState && trackItem.isPlayingItem && modelData["length"] > 0 |
168 | + source: "graphics/music_progress_bg.png" |
169 | + } |
170 | + } |
171 | + |
172 | + Label { |
173 | + id: timeLabel |
174 | + objectName: "timeLabel" |
175 | + anchors.verticalCenter: parent.verticalCenter |
176 | + width: parent.column3Width |
177 | + opacity: 0.9 |
178 | + color: "white" |
179 | + fontSize: "small" |
180 | + horizontalAlignment: Text.AlignRight |
181 | + text: lengthToString(modelData["length"]) |
182 | + style: Text.Raised |
183 | + styleColor: "black" |
184 | + |
185 | + function lengthToString(s) { |
186 | + if (s <= 0 || s === undefined) return "" |
187 | + |
188 | + var sec = "" + s % 60 |
189 | + if (sec.length == 1) sec = "0" + sec |
190 | + var hour = Math.floor(s / 3600) |
191 | + if (hour < 1) { |
192 | + return Math.floor(s / 60) + ":" + sec |
193 | + } else { |
194 | + var min = "" + Math.floor(s / 60) % 60 |
195 | + if (min.length == 1) min = "0" + min |
196 | + return hour + ":" + min + ":" + sec |
197 | + } |
198 | + } |
199 | + } |
200 | + } |
201 | + } |
202 | + } |
203 | + } |
204 | +} |
205 | |
206 | === added file 'qml/Dash/Previews/TextSummary.qml' |
207 | --- qml/Dash/Previews/TextSummary.qml 1970-01-01 00:00:00 +0000 |
208 | +++ qml/Dash/Previews/TextSummary.qml 2014-01-31 09:36:27 +0000 |
209 | @@ -0,0 +1,27 @@ |
210 | +/* |
211 | + * Copyright (C) 2014 Canonical, Ltd. |
212 | + * |
213 | + * This program is free software; you can redistribute it and/or modify |
214 | + * it under the terms of the GNU General Public License as published by |
215 | + * the Free Software Foundation; version 3. |
216 | + * |
217 | + * This program is distributed in the hope that it will be useful, |
218 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
219 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
220 | + * GNU General Public License for more details. |
221 | + * |
222 | + * You should have received a copy of the GNU General Public License |
223 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
224 | + */ |
225 | + |
226 | +import QtQuick 2.0 |
227 | +import Ubuntu.Components 0.1 |
228 | + |
229 | +Label { |
230 | + fontSize: "medium" |
231 | + color: Theme.palette.selected.backgroundText |
232 | + opacity: .6 |
233 | + wrapMode: Text.WordWrap |
234 | + style: Text.Raised |
235 | + styleColor: "black" |
236 | +} |
237 | |
238 | === renamed directory 'qml/Dash/Music/graphics' => 'qml/Dash/Previews/graphics' |
239 | === modified file 'tests/qmltests/CMakeLists.txt' |
240 | --- tests/qmltests/CMakeLists.txt 2014-01-13 14:15:17 +0000 |
241 | +++ tests/qmltests/CMakeLists.txt 2014-01-31 09:36:27 +0000 |
242 | @@ -53,6 +53,7 @@ |
243 | add_qml_test(Dash/Apps AppPreview IMPORT_PATHS ${qmltest_DEFAULT_IMPORT_PATHS} ${CMAKE_BINARY_DIR}/tests/mocks) |
244 | add_qml_test(Dash/Movie MoviePreview IMPORT_PATHS ${qmltest_DEFAULT_IMPORT_PATHS} ${CMAKE_BINARY_DIR}/tests/mocks) |
245 | add_qml_test(Dash/Music MusicPreview IMPORT_PATHS ${qmltest_DEFAULT_IMPORT_PATHS} ${CMAKE_BINARY_DIR}/tests/mocks) |
246 | +add_qml_test(Dash/Previews AudioPlayer IMPORT_PATHS ${qmltest_DEFAULT_IMPORT_PATHS} ${CMAKE_BINARY_DIR}/tests/mocks) |
247 | add_qml_test(Greeter Lockscreen IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins ${qmltest_DEFAULT_IMPORT_PATHS} |
248 | PROPERTIES ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/tests/mocks/libusermetrics:${CMAKE_BINARY_DIR}/tests/mocks/LightDM/full") |
249 | add_qml_test(Greeter Tablet IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins ${qmltest_DEFAULT_IMPORT_PATHS} |
250 | |
251 | === added directory 'tests/qmltests/Dash/Previews' |
252 | === added file 'tests/qmltests/Dash/Previews/tst_AudioPlayer.qml' |
253 | --- tests/qmltests/Dash/Previews/tst_AudioPlayer.qml 1970-01-01 00:00:00 +0000 |
254 | +++ tests/qmltests/Dash/Previews/tst_AudioPlayer.qml 2014-01-31 09:36:27 +0000 |
255 | @@ -0,0 +1,162 @@ |
256 | +/* |
257 | + * Copyright 2014 Canonical Ltd. |
258 | + * |
259 | + * This program is free software; you can redistribute it and/or modify |
260 | + * it under the terms of the GNU General Public License as published by |
261 | + * the Free Software Foundation; version 3. |
262 | + * |
263 | + * This program is distributed in the hope that it will be useful, |
264 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
265 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
266 | + * GNU General Public License for more details. |
267 | + * |
268 | + * You should have received a copy of the GNU General Public License |
269 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
270 | + */ |
271 | + |
272 | +import QtQuick 2.0 |
273 | +import QtTest 1.0 |
274 | +import Ubuntu.Components 0.1 |
275 | +import "../../../../qml/Dash/Previews" |
276 | +import Unity.Test 0.1 as UT |
277 | +import QtMultimedia 5.0 |
278 | + |
279 | +Rectangle { |
280 | + id: root |
281 | + width: units.gu(60) |
282 | + height: units.gu(80) |
283 | + color: "grey" |
284 | + |
285 | + property var tracksModel0: [ |
286 | + ] |
287 | + |
288 | + property var tracksModel1: [ |
289 | + { title: "Some track name", length: "30", source: "../../tests/qmltests/Dash/Music/data/testsound1.ogg" } |
290 | + ] |
291 | + |
292 | + property var tracksModel2: [ |
293 | + { title: "Some track name", length: "30", source: "../../tests/qmltests/Dash/Music/data/testsound1.ogg" }, |
294 | + { title: "Some other track name", subtitle: "Subtitle", length: "83", source: "../../tests/qmltests/Dash/Music/data/testsound2.ogg" }, |
295 | + { title: "And another one", length: "7425", source: "../../tests/qmltests/Dash/Music/data/testsound3.ogg" } |
296 | + ] |
297 | + |
298 | + AudioPlayer { |
299 | + id: audioPlayer |
300 | + anchors.fill: parent |
301 | + model: tracksModel2 |
302 | + } |
303 | + |
304 | + UT.UnityTestCase { |
305 | + name: "AudioPlayerTest" |
306 | + when: windowShown |
307 | + |
308 | + function init() { |
309 | + waitForRendering(audioPlayer); |
310 | + } |
311 | + |
312 | + function test_tracks_data() { |
313 | + return [ |
314 | + {tag: "0 tracks", tracksModel: tracksModel0}, |
315 | + {tag: "1 track", tracksModel: tracksModel1}, |
316 | + {tag: "3 tracks", tracksModel: tracksModel2} |
317 | + ]; |
318 | + } |
319 | + |
320 | + function test_tracks(data) { |
321 | + audioPlayer.model = data.tracksModel; |
322 | + waitForRendering(audioPlayer); |
323 | + |
324 | + var trackRepeater = findChild(audioPlayer, "trackRepeater"); |
325 | + compare(trackRepeater.count, data.tracksModel.length) |
326 | + |
327 | + for (var i = 0; i < data.tracksModel.length; ++i) { |
328 | + var trackItem = findChild(audioPlayer, "trackItem" + i); |
329 | + var titleLabel = findChild(trackItem, "trackTitleLabel"); |
330 | + compare(titleLabel.text, data.tracksModel[i]["title"]) |
331 | + var subtitleLabel = findChild(trackItem, "trackSubtitleLabel"); |
332 | + if (data.tracksModel[i]["subtitle"] !== undefined) { |
333 | + compare(subtitleLabel.text, data.tracksModel[i]["subtitle"]) |
334 | + } else { |
335 | + compare(subtitleLabel.visible, false) |
336 | + } |
337 | + // not checking time label because it's formatted, the model only contains seconds |
338 | + } |
339 | + } |
340 | + |
341 | + function checkPlayerSource(index) { |
342 | + var modelFilename = audioPlayer.model[index]["source"].replace(/^.*[\\\/]/, ''); |
343 | + var playerFilename = findInvisibleChild(audioPlayer, "audio").source.toString().replace(/^.*[\\\/]/, ''); |
344 | + |
345 | + compare(modelFilename, playerFilename, "Player source is not set correctly."); |
346 | + } |
347 | + |
348 | + function test_playback() { |
349 | + audioPlayer.model = tracksModel2; |
350 | + waitForRendering(audioPlayer); |
351 | + |
352 | + var track0Item = findChild(audioPlayer, "trackItem0"); |
353 | + var track1Item = findChild(audioPlayer, "trackItem1"); |
354 | + var track2Item = findChild(audioPlayer, "trackItem2"); |
355 | + |
356 | + var track0ProgressBar = findChild(track0Item, "progressBarFill"); |
357 | + var track1ProgressBar = findChild(track1Item, "progressBarFill"); |
358 | + var track2ProgressBar = findChild(track2Item, "progressBarFill"); |
359 | + |
360 | + var track0PlayButton = findChild(track0Item, "playButton"); |
361 | + var track1PlayButton = findChild(track1Item, "playButton"); |
362 | + var track2PlayButton = findChild(track2Item, "playButton"); |
363 | + |
364 | + var audio = findInvisibleChild(audioPlayer, "audio"); |
365 | + |
366 | + // All progress bars must be hidden in the beginning |
367 | + compare(track0ProgressBar.visible, false); |
368 | + compare(track1ProgressBar.visible, false); |
369 | + compare(track2ProgressBar.visible, false); |
370 | + |
371 | + // Playing track 0 should make progress bar 0 visible |
372 | + mouseClick(track0PlayButton, track0PlayButton.width / 2, track0PlayButton.height / 2); |
373 | + |
374 | + tryCompare(audio, "playbackState", Audio.PlayingState); |
375 | + checkPlayerSource(0); |
376 | + |
377 | + tryCompare(track0ProgressBar, "visible", true); |
378 | + tryCompare(track1ProgressBar, "visible", false); |
379 | + tryCompare(track2ProgressBar, "visible", false); |
380 | + |
381 | + // Clicking the button again should pause it. The progress bar should stay visible |
382 | + mouseClick(track0PlayButton, track0PlayButton.width / 2, track0PlayButton.height / 2); |
383 | + tryCompare(audio, "playbackState", Audio.PausedState); |
384 | + checkPlayerSource(0); |
385 | + tryCompare(track0ProgressBar, "visible", true); |
386 | + |
387 | + // Continue playback |
388 | + mouseClick(track0PlayButton, track0PlayButton.width / 2, track0PlayButton.height / 2); |
389 | + tryCompare(audio, "playbackState", Audio.PlayingState); |
390 | + checkPlayerSource(0); |
391 | + |
392 | + // Playing track 1 should make progress bar 1 visible and hide progress bar 0 again |
393 | + mouseClick(track1PlayButton, track1PlayButton.width / 2, track1PlayButton.height / 2); |
394 | + |
395 | + tryCompare(audio, "playbackState", Audio.PlayingState); |
396 | + checkPlayerSource(1); |
397 | + |
398 | + tryCompare(track0ProgressBar, "visible", false); |
399 | + tryCompare(track1ProgressBar, "visible", true); |
400 | + tryCompare(track2ProgressBar, "visible", false); |
401 | + |
402 | + // Playing track 2 should make progress bar 1 visible and hide progress bar 0 again |
403 | + mouseClick(track2PlayButton, track2PlayButton.width / 2, track2PlayButton.height / 2); |
404 | + |
405 | + tryCompare(audio, "playbackState", Audio.PlayingState); |
406 | + checkPlayerSource(2); |
407 | + |
408 | + tryCompare(track0ProgressBar, "visible", false); |
409 | + tryCompare(track1ProgressBar, "visible", false); |
410 | + tryCompare(track2ProgressBar, "visible", true); |
411 | + |
412 | + // Calling stop() should make all players shut up! |
413 | + audioPlayer.stop() |
414 | + tryCompare(audio, "playbackState", Audio.StoppedState); |
415 | + } |
416 | + } |
417 | +} |