Merge lp:~unity-team/unity8/unity8.previews_textSummary into lp:unity8

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
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+}

Subscribers

People subscribed via source and target branches