Merge lp:~renatofilho/mediaplayer-app/use-cotent-hub into lp:mediaplayer-app
- use-cotent-hub
- Merge into trunk
Proposed by
Renato Araujo Oliveira Filho
Status: | Merged |
---|---|
Approved by: | Bill Filler |
Approved revision: | 454 |
Merged at revision: | 441 |
Proposed branch: | lp:~renatofilho/mediaplayer-app/use-cotent-hub |
Merge into: | lp:mediaplayer-app |
Diff against target: |
655 lines (+280/-119) 9 files modified
data/mediaplayer-app.desktop.in.in (+0/-1) src/mediaplayer.cpp (+1/-46) src/mediaplayer.h (+0/-4) src/qml/VideoImport.qml (+40/-0) src/qml/VideoImportDialog.qml (+98/-0) src/qml/player.qml (+30/-18) src/qml/player/Controls.qml (+27/-16) src/qml/player/VideoPlayer.qml (+66/-33) tests/unittest/tst_video_player.qml (+18/-1) |
To merge this branch: | bzr merge lp:~renatofilho/mediaplayer-app/use-cotent-hub |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
system-apps-ci-bot | continuous-integration | Approve | |
Ubuntu Phablet Team | Pending | ||
Review via email: mp+320366@code.launchpad.net |
Commit message
Open content peer selection in case of the app start without a video url.
Description of the change
To post a comment you must log in.
Revision history for this message
system-apps-ci-bot (system-apps-ci-bot) wrote : | # |
review:
Approve
(continuous-integration)
- 444. By Renato Araujo Oliveira Filho
-
Added missing files.
- 445. By Renato Araujo Oliveira Filho
-
Fixed vide import using content-hub.
- 446. By Renato Araujo Oliveira Filho
-
add a option to switch to full screen.
- 447. By Renato Araujo Oliveira Filho
-
Fixed check for desktop mode on unity7.
- 448. By Renato Araujo Oliveira Filho
-
Ask to pick a video file if player is empty while clicking on "play" button.
- 449. By Renato Araujo Oliveira Filho
-
Added a open-file button.
- 450. By Renato Araujo Oliveira Filho
-
Always show quit an fullscreen button.
Does not pause video if the app loses focus. - 451. By Renato Araujo Oliveira Filho
-
Show a empty state if the app was started without a URL.
- 452. By Renato Araujo Oliveira Filho
-
Fixed empty state on player startup.
- 453. By Renato Araujo Oliveira Filho
-
Use a different icon for open a new file.
- 454. By Renato Araujo Oliveira Filho
-
Pause video player if it is playing while picking a new file.
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'data/mediaplayer-app.desktop.in.in' |
2 | --- data/mediaplayer-app.desktop.in.in 2016-11-23 22:58:39 +0000 |
3 | +++ data/mediaplayer-app.desktop.in.in 2017-03-21 19:39:57 +0000 |
4 | @@ -12,4 +12,3 @@ |
5 | X-Ubuntu-Gettext-Domain=mediaplayer-app |
6 | X-Ubuntu-Single-Instance=true |
7 | X-Ubuntu-Default-Department-ID=sound-video |
8 | -OnlyShowIn=Old |
9 | |
10 | === modified file 'src/mediaplayer.cpp' |
11 | --- src/mediaplayer.cpp 2017-01-12 13:17:45 +0000 |
12 | +++ src/mediaplayer.cpp 2017-03-21 19:39:57 +0000 |
13 | @@ -47,7 +47,7 @@ |
14 | } |
15 | |
16 | MediaPlayer::MediaPlayer(int &argc, char **argv) |
17 | - : QApplication(argc, argv), m_view(0), m_fileChooser(0) |
18 | + : QApplication(argc, argv), m_view(0) |
19 | { |
20 | } |
21 | |
22 | @@ -57,9 +57,6 @@ |
23 | bool windowed = args.removeAll("-w") + args.removeAll("--windowed") > 0; |
24 | bool testability = args.removeAll("-testability") > 0; |
25 | |
26 | - // use windowed in desktop as default |
27 | - windowed = windowed || isDesktopMode(); |
28 | - |
29 | // The testability driver is only loaded by QApplication but not by |
30 | // QGuiApplication. |
31 | // However, QApplication depends on QWidget which would add some |
32 | @@ -155,10 +152,6 @@ |
33 | if (m_view) { |
34 | delete m_view; |
35 | } |
36 | - if (m_fileChooser) { |
37 | - delete m_fileChooser; |
38 | - m_fileChooser = 0; |
39 | - } |
40 | } |
41 | |
42 | void |
43 | @@ -189,44 +182,6 @@ |
44 | m_view->rootContext()->setContextProperty("screenHeight", height); |
45 | } |
46 | |
47 | -bool MediaPlayer::isDesktopMode() const |
48 | -{ |
49 | - // WORKAROUND: check unity profile |
50 | - if (qgetenv("UNITY_INDICATOR_PROFILE") == "desktop") |
51 | - return true; |
52 | - |
53 | - // Assume that platformName (QtUbuntu) with ubuntu |
54 | - // in name means it's running on device |
55 | - // TODO: replace this check with SDK call for formfactor |
56 | - QString platform = QGuiApplication::platformName(); |
57 | - return !((platform == "ubuntu") || (platform == "ubuntumirclient")); |
58 | -} |
59 | - |
60 | -QUrl MediaPlayer::chooseFile() |
61 | -{ |
62 | - QUrl fileName; |
63 | - if (!m_fileChooser) { |
64 | - m_fileChooser = new QFileDialog(0, |
65 | - tr("Open Video"), |
66 | - QStandardPaths::writableLocation(QStandardPaths::MoviesLocation), |
67 | - tr("Video files (*.avi *.mov *.mp4 *.divx *.ogg *.ogv *.mpeg);;All files (*)")); |
68 | - m_fileChooser->setModal(true); |
69 | - int result = m_fileChooser->exec(); |
70 | - if (result == QDialog::Accepted) { |
71 | - QStringList selectedFiles = m_fileChooser->selectedFiles(); |
72 | - if (selectedFiles.count() > 0) { |
73 | - fileName = selectedFiles[0]; |
74 | - } |
75 | - } |
76 | - delete m_fileChooser; |
77 | - m_fileChooser = 0; |
78 | - } else { |
79 | - m_fileChooser->raise(); |
80 | - } |
81 | - |
82 | - return fileName; |
83 | -} |
84 | - |
85 | QList<QUrl> MediaPlayer::copyFiles(const QList<QUrl> &urls) |
86 | { |
87 | static QString moviesDir = QStandardPaths::writableLocation(QStandardPaths::MoviesLocation); |
88 | |
89 | === modified file 'src/mediaplayer.h' |
90 | --- src/mediaplayer.h 2016-01-20 15:44:22 +0000 |
91 | +++ src/mediaplayer.h 2017-03-21 19:39:57 +0000 |
92 | @@ -25,7 +25,6 @@ |
93 | class MediaPlayer : public QApplication |
94 | { |
95 | Q_OBJECT |
96 | - Q_PROPERTY(bool desktopMode READ isDesktopMode CONSTANT) |
97 | |
98 | public: |
99 | MediaPlayer(int &argc, char **argv); |
100 | @@ -38,13 +37,10 @@ |
101 | void leaveFullScreen(); |
102 | void onWidthChanged(int); |
103 | void onHeightChanged(int); |
104 | - bool isDesktopMode() const; |
105 | - QUrl chooseFile(); |
106 | QList<QUrl> copyFiles(const QList<QUrl> &urls); |
107 | |
108 | private: |
109 | QQuickView *m_view; |
110 | - QFileDialog *m_fileChooser; |
111 | }; |
112 | |
113 | #endif // MEDIAPLAYER_H |
114 | |
115 | === added file 'src/qml/VideoImport.qml' |
116 | --- src/qml/VideoImport.qml 1970-01-01 00:00:00 +0000 |
117 | +++ src/qml/VideoImport.qml 2017-03-21 19:39:57 +0000 |
118 | @@ -0,0 +1,40 @@ |
119 | +/* |
120 | + * Copyright (C) 2012-2016 Canonical, Ltd. |
121 | + * |
122 | + * This program is free software; you can redistribute it and/or modify |
123 | + * it under the terms of the GNU General Public License as published by |
124 | + * the Free Software Foundation; version 3. |
125 | + * |
126 | + * This program is distributed in the hope that it will be useful, |
127 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
128 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
129 | + * GNU General Public License for more details. |
130 | + * |
131 | + * You should have received a copy of the GNU General Public License |
132 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
133 | + */ |
134 | + |
135 | +import QtQuick 2.4 |
136 | + |
137 | +import Ubuntu.Components 1.3 |
138 | +import Ubuntu.Components.Popups 1.3 |
139 | + |
140 | +Item { |
141 | + id: root |
142 | + |
143 | + property var importDialog: null |
144 | + |
145 | + signal videoReceived(string videoUrl) |
146 | + |
147 | + function requestVideo() |
148 | + { |
149 | + if (!root.importDialog) { |
150 | + root.importDialog = PopupUtils.open(Qt.resolvedUrl("VideoImportDialog.qml"), null) |
151 | + root.importDialog.videoReceived.connect(root.videoReceived) |
152 | + root.importDialog.destruction.connect(function () {root.importDialog = null}) |
153 | + |
154 | + } else { |
155 | + console.warn("Import dialog already running") |
156 | + } |
157 | + } |
158 | +} |
159 | |
160 | === added file 'src/qml/VideoImportDialog.qml' |
161 | --- src/qml/VideoImportDialog.qml 1970-01-01 00:00:00 +0000 |
162 | +++ src/qml/VideoImportDialog.qml 2017-03-21 19:39:57 +0000 |
163 | @@ -0,0 +1,98 @@ |
164 | +/* |
165 | + * Copyright (C) 2016 Canonical, Ltd. |
166 | + * |
167 | + * This program is free software; you can redistribute it and/or modify |
168 | + * it under the terms of the GNU General Public License as published by |
169 | + * the Free Software Foundation; version 3. |
170 | + * |
171 | + * This program is distributed in the hope that it will be useful, |
172 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
173 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
174 | + * GNU General Public License for more details. |
175 | + * |
176 | + * You should have received a copy of the GNU General Public License |
177 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
178 | + */ |
179 | + |
180 | +import QtQuick 2.4 |
181 | + |
182 | +import Ubuntu.Components 1.3 |
183 | +import Ubuntu.Components.Popups 1.3 |
184 | +import Ubuntu.Content 1.3 |
185 | + |
186 | +PopupBase { |
187 | + id: dialogue |
188 | + |
189 | + property alias activeTransfer: signalConnections.target |
190 | + signal videoReceived(string videoUrl) |
191 | + signal destruction() |
192 | + |
193 | + parent: QuickUtils.rootItem(this) |
194 | + focus: true |
195 | + |
196 | + Rectangle { |
197 | + anchors.fill: parent |
198 | + |
199 | + ContentTransferHint { |
200 | + anchors.fill: parent |
201 | + activeTransfer: dialogue.activeTransfer |
202 | + } |
203 | + |
204 | + ContentPeerPicker { |
205 | + id: peerPicker |
206 | + |
207 | + anchors.fill: parent |
208 | + contentType: ContentType.Videos |
209 | + handler: ContentHandler.Source |
210 | + |
211 | + onPeerSelected: { |
212 | + peer.selectionType = ContentTransfer.Single |
213 | + dialogue.activeTransfer = peer.request() |
214 | + } |
215 | + |
216 | + onCancelPressed: { |
217 | + PopupUtils.close(dialogue) |
218 | + } |
219 | + } |
220 | + } |
221 | + |
222 | + Connections { |
223 | + id: signalConnections |
224 | + |
225 | + onStateChanged: { |
226 | + var done = ((dialogue.activeTransfer.state === ContentTransfer.Charged) || |
227 | + (dialogue.activeTransfer.state === ContentTransfer.Aborted)) |
228 | + |
229 | + if (dialogue.activeTransfer.state === ContentTransfer.Charged) { |
230 | + if (dialogue.activeTransfer.items.length > 0) { |
231 | + dialogue.videoReceived(dialogue.activeTransfer.items[0].url) |
232 | + } |
233 | + } |
234 | + |
235 | + if (done) { |
236 | + acceptTimer.restart() |
237 | + } |
238 | + } |
239 | + } |
240 | + |
241 | + // WORKAROUND: Work around for application becoming insensitive to touch events |
242 | + // if the dialog is dismissed while the application is inactive. |
243 | + // Just listening for changes to Qt.application.active doesn't appear |
244 | + // to be enough to resolve this, so it seems that something else needs |
245 | + // to be happening first. As such there's a potential for a race |
246 | + // condition here, although as yet no problem has been encountered. |
247 | + Timer { |
248 | + id: acceptTimer |
249 | + |
250 | + interval: 100 |
251 | + repeat: true |
252 | + running: false |
253 | + onTriggered: { |
254 | + if(Qt.application.state === Qt.ApplicationActive) { |
255 | + PopupUtils.close(dialogue) |
256 | + } |
257 | + } |
258 | + } |
259 | + |
260 | + Component.onDestruction: dialogue.destruction() |
261 | +} |
262 | |
263 | === modified file 'src/qml/player.qml' |
264 | --- src/qml/player.qml 2016-01-26 14:48:04 +0000 |
265 | +++ src/qml/player.qml 2017-03-21 19:39:57 +0000 |
266 | @@ -25,7 +25,7 @@ |
267 | import Ubuntu.Unity.Action 1.1 as UnityActions |
268 | import Ubuntu.Components 1.3 |
269 | import Ubuntu.Components.Popups 1.0 as Popups |
270 | -import Ubuntu.Content 0.1 as ContentHub |
271 | +import Ubuntu.Content 1.3 |
272 | |
273 | Item { |
274 | id: mediaPlayer |
275 | @@ -38,15 +38,25 @@ |
276 | property bool appActive: Qt.application.active |
277 | property variant nativeOrientation: Screen.primaryOrientation |
278 | |
279 | - onAppActiveChanged: { |
280 | - if (!appActive && |
281 | - !mpApplication.desktopMode && |
282 | - playerLoader.item && |
283 | - playerLoader.item.playing) { |
284 | + function pickAFile() |
285 | + { |
286 | + if (playerLoader.item.playing) |
287 | playerLoader.item.pause() |
288 | - } |
289 | + videoImport.requestVideo() |
290 | } |
291 | |
292 | +// FIXME: For now keep the video playing even if the app is not active |
293 | +// Wait for a better app life cycle to inform if the app will be suspended or not |
294 | +// |
295 | +// onAppActiveChanged: { |
296 | +// if (!appActive && |
297 | +// !mpApplication.desktopMode && |
298 | +// playerLoader.item && |
299 | +// playerLoader.item.playing) { |
300 | +// playerLoader.item.pause() |
301 | +// } |
302 | +// } |
303 | + |
304 | Screen.onOrientationChanged: { |
305 | // Rotate the UI when the device orientation changes |
306 | mediaPlayer.orientation = Screen.angleBetween(Screen.primaryOrientation, Screen.orientation) |
307 | @@ -170,6 +180,7 @@ |
308 | playerLoader.item.controlsActive = true |
309 | } |
310 | } |
311 | + onPlayEmptyFile: mediaPlayer.pickAFile() |
312 | } |
313 | |
314 | UnityActions.ActionManager { |
315 | @@ -225,10 +236,10 @@ |
316 | } |
317 | |
318 | Connections { |
319 | - target: ContentHub.ContentHub |
320 | + target: ContentHub |
321 | onImportRequested: { |
322 | lateUrlCheck.stop() |
323 | - if (transfer.state === ContentHub.ContentTransfer.Charged) { |
324 | + if (transfer.state === ContentTransfer.Charged) { |
325 | var urls = [] |
326 | for(var i=0; i < transfer.items.length; i++) { |
327 | urls.push(transfer.items[i].url) |
328 | @@ -241,6 +252,14 @@ |
329 | } |
330 | } |
331 | |
332 | + VideoImport { |
333 | + id: videoImport |
334 | + |
335 | + onVideoReceived: { |
336 | + playerLoader.item.playUri(videoUrl) |
337 | + } |
338 | + } |
339 | + |
340 | Timer { |
341 | id: lateUrlCheck |
342 | |
343 | @@ -248,15 +267,8 @@ |
344 | repeat: false |
345 | running: true |
346 | onTriggered: { |
347 | - if ((playUri == "") && !ContentHub.ContentHub.hasPending) { |
348 | - if (mpApplication.desktopMode) { |
349 | - var videoFile = mpApplication.chooseFile() |
350 | - if (videoFile != "") { |
351 | - playerLoader.item.playUri(videoFile) |
352 | - } |
353 | - } else { |
354 | - PopupUtils.open(dialogNoUrl, null) |
355 | - } |
356 | + if (playerLoader.item && (playerLoader.item.source == "") && !ContentHub.hasPending) { |
357 | + mediaPlayer.pickAFile() |
358 | } |
359 | } |
360 | } |
361 | |
362 | === modified file 'src/qml/player/Controls.qml' |
363 | --- src/qml/player/Controls.qml 2016-11-22 20:22:15 +0000 |
364 | +++ src/qml/player/Controls.qml 2017-03-21 19:39:57 +0000 |
365 | @@ -35,11 +35,12 @@ |
366 | property variant playerStatus: MediaPlayer.NoMedia |
367 | |
368 | property alias finalSeekPosition: _timeline.finalSeekPosition |
369 | - property alias settingsEnabled: _settingsButton.enabled |
370 | + property alias openFileEnabled: _openFileButton.enabled |
371 | |
372 | signal fullscreenClicked |
373 | signal playbackClicked |
374 | signal settingsClicked |
375 | + signal openFileClicked |
376 | signal shareClicked |
377 | signal seekRequested(int time) |
378 | signal startSeek |
379 | @@ -153,12 +154,7 @@ |
380 | IconButton { |
381 | id: _fullScreenButton |
382 | |
383 | - //TODO: use the correct icon based on window state |
384 | -// visible: (mpApplication.desktopMode || (Window.visibility === Window.FullScreen)) |
385 | -// iconSource: mpApplication.desktopMode ? |
386 | -// Window.visibility === Window.FullScreen ? "image://theme/view-restore" : "image://theme/view-fullscreen" : |
387 | -// "image://theme/close" |
388 | - iconSource: mpApplication.desktopMode ? "image://theme/view-fullscreen" : "image://theme/close" |
389 | + iconSource: Window.visibility === Window.FullScreen ? "image://theme/view-restore" : "image://theme/view-fullscreen" |
390 | iconSize: units.gu(3) |
391 | anchors.verticalCenter: parent.verticalCenter |
392 | width: visible ? units.gu(8) : 0 |
393 | @@ -184,7 +180,8 @@ |
394 | _fullScreenButton.width - |
395 | _timeLabel.width - |
396 | _shareButton.width - |
397 | - _settingsButton.width |
398 | + _openFileButton.width - |
399 | + _quitButton.width |
400 | |
401 | height: units.gu(4) |
402 | onClicked: controls.playbackClicked() |
403 | @@ -206,9 +203,8 @@ |
404 | playbackButton.width - |
405 | _timeLabel.width - |
406 | _shareButton.width - |
407 | - _settingsButton.width - |
408 | - units.gu(2) : 0 |
409 | - |
410 | + _openFileButton.width - |
411 | + _quitButton.width : 0 |
412 | |
413 | TimeLine { |
414 | id: _timeline |
415 | @@ -297,14 +293,14 @@ |
416 | } |
417 | |
418 | VLine { |
419 | - visible: _settingsButton.visible |
420 | + visible: _openFileButton.visible |
421 | } |
422 | |
423 | IconButton { |
424 | - id: _settingsButton |
425 | + id: _openFileButton |
426 | |
427 | - visible: false |
428 | - iconSource: "artwork/icon_settings.png" |
429 | + visible: enabled |
430 | + iconSource: "image://theme/document-open" |
431 | iconSize: units.gu(3) |
432 | anchors { |
433 | top: parent.top |
434 | @@ -313,7 +309,22 @@ |
435 | width: visible ? units.gu(7) : 0 |
436 | enabled: false |
437 | opacity: enabled ? 1.0 : 0.2 |
438 | - onClicked: settingsClicked() |
439 | + onClicked: openFileClicked() |
440 | + } |
441 | + |
442 | + VLine {} |
443 | + |
444 | + IconButton { |
445 | + id: _quitButton |
446 | + |
447 | + iconSource: "image://theme/close" |
448 | + iconSize: units.gu(3) |
449 | + anchors { |
450 | + top: parent.top |
451 | + bottom: parent.bottom |
452 | + } |
453 | + width: units.gu(7) |
454 | + onClicked: Qt.quit() |
455 | } |
456 | } |
457 | } |
458 | |
459 | === modified file 'src/qml/player/VideoPlayer.qml' |
460 | --- src/qml/player/VideoPlayer.qml 2016-02-19 11:14:53 +0000 |
461 | +++ src/qml/player/VideoPlayer.qml 2017-03-21 19:39:57 +0000 |
462 | @@ -28,20 +28,21 @@ |
463 | AbstractPlayer { |
464 | id: player |
465 | |
466 | - property variant nfo |
467 | + property variant info |
468 | property int pressCount: 0 |
469 | property bool wasPlaying: false |
470 | - property string uri |
471 | property bool rotating: false |
472 | property alias controlsActive: _controls.active |
473 | property bool componentLoaded: false |
474 | readonly property int seekStep: 1000 |
475 | + readonly property bool isEmpty: source == "" |
476 | property var errorDialog: null |
477 | |
478 | signal timeClicked |
479 | + signal playEmptyFile |
480 | |
481 | objectName: "player" |
482 | - nfo: VideoInfo { |
483 | + info: VideoInfo { |
484 | uri: source |
485 | } |
486 | |
487 | @@ -134,8 +135,7 @@ |
488 | player.video.seek(time) |
489 | } |
490 | |
491 | - settingsEnabled: mpApplication.desktopMode |
492 | - |
493 | + openFileEnabled: true |
494 | objectName: "controls" |
495 | state: player.state |
496 | video: player.video |
497 | @@ -149,46 +149,79 @@ |
498 | sceneSelectorHeight: units.gu(18) |
499 | playerStatus: player.status |
500 | |
501 | - onPlaybackClicked: player.playPause() |
502 | - |
503 | - onFullscreenClicked: { |
504 | - if (mpApplication.desktopMode) { |
505 | - mpApplication.toggleFullscreen() |
506 | + onPlaybackClicked: { |
507 | + if (player.source == "") { |
508 | + player.playEmptyFile() |
509 | } else { |
510 | - Qt.quit() |
511 | + player.playPause() |
512 | } |
513 | } |
514 | |
515 | + onFullscreenClicked: mpApplication.toggleFullscreen() |
516 | + onOpenFileClicked: player.playEmptyFile() |
517 | onStartSeek: aboutToSeek() |
518 | onEndSeek: seekDone() |
519 | onSeekRequested: seek(time) |
520 | - |
521 | - onSettingsClicked: { |
522 | - if (mpApplication.desktopMode) { |
523 | - var videoFile = mpApplication.chooseFile() |
524 | - if (videoFile != "") { |
525 | - player.stop() |
526 | - item.playUri(videoFile) |
527 | - } |
528 | - } |
529 | - } |
530 | } |
531 | } |
532 | |
533 | MouseArea { |
534 | - id: _mouseArea |
535 | - |
536 | - objectName: "videoMouseArea" |
537 | + id: _mouseArea |
538 | + |
539 | + objectName: "videoMouseArea" |
540 | + anchors { |
541 | + left: parent.left |
542 | + right: parent.right |
543 | + top: parent.top |
544 | + bottom: _controls.top |
545 | + } |
546 | + onClicked: _controls.active = !_controls.active |
547 | + } |
548 | + |
549 | + Item { |
550 | + id: emptyState |
551 | + |
552 | + anchors.fill: parent |
553 | + visible: false |
554 | + Icon { |
555 | + id: emptyStateIcon |
556 | + |
557 | + source: "image://theme/document-open" |
558 | + color: "white" |
559 | + anchors.centerIn: parent |
560 | + width: units.gu(4) |
561 | + } |
562 | + Label { |
563 | + text: i18n.tr("Please choose a file to open") |
564 | + color: "white" |
565 | + textSize: Label.Large |
566 | anchors { |
567 | - left: parent.left |
568 | - right: parent.right |
569 | - top: parent.top |
570 | - bottom: _controls.top |
571 | - } |
572 | - |
573 | - onClicked: _controls.active = !_controls.active |
574 | - } |
575 | - |
576 | + horizontalCenter: parent.horizontalCenter |
577 | + top: emptyStateIcon.bottom |
578 | + topMargin: units.gu(2) |
579 | + } |
580 | + } |
581 | + } |
582 | + |
583 | + state: player.isEmpty ? "empty" : "" |
584 | + states: [ |
585 | + State { |
586 | + name: "empty" |
587 | + PropertyChanges { |
588 | + target: _controls |
589 | + active: true |
590 | + } |
591 | + PropertyChanges { |
592 | + target: emptyState |
593 | + visible: true |
594 | + } |
595 | + PropertyChanges { |
596 | + target: _mouseArea |
597 | + enabled: false |
598 | + } |
599 | + } |
600 | + |
601 | + ] |
602 | |
603 | Keys.onReleased: |
604 | { |
605 | |
606 | === modified file 'tests/unittest/tst_video_player.qml' |
607 | --- tests/unittest/tst_video_player.qml 2016-09-26 23:12:42 +0000 |
608 | +++ tests/unittest/tst_video_player.qml 2017-03-21 19:39:57 +0000 |
609 | @@ -75,6 +75,21 @@ |
610 | tryCompare(player, 'paused', false) |
611 | tryCompare(player, 'playing', false) |
612 | tryCompare(player, 'wasPlaying', false) |
613 | + tryCompare(player, 'isEmpty', true) |
614 | + } |
615 | + |
616 | + function test_empty_state() |
617 | + { |
618 | + tryCompare(player, 'isEmpty', true) |
619 | + tryCompare(player, 'controlsActive', true) |
620 | + |
621 | + // test if controls stay active after click on empty state |
622 | + mouseClick(player) |
623 | + tryCompare(player, 'controlsActive', true) |
624 | + |
625 | + // play any uri should leave empty state |
626 | + player.playUri(videUri) |
627 | + tryCompare(player, 'isEmpty', false) |
628 | } |
629 | |
630 | function test_open_video() |
631 | @@ -87,6 +102,8 @@ |
632 | function test_play_pause_video() |
633 | { |
634 | player.playUri(videUri) |
635 | + |
636 | + tryCompare(player, 'isEmpty', false) |
637 | tryCompare(player, 'playing', true) |
638 | player.playPause() |
639 | tryCompare(player, 'paused', true) |
640 | @@ -98,6 +115,7 @@ |
641 | { |
642 | player.playUri(videUri) |
643 | tryCompare(player, 'playing', true) |
644 | + tryCompare(player, 'controlsActive', false) |
645 | |
646 | mouseClick(player) |
647 | tryCompare(player, 'controlsActive', true) |
648 | @@ -126,7 +144,6 @@ |
649 | tryCompare(player, 'paused', true) |
650 | } |
651 | |
652 | - |
653 | function test_play_after_pause() |
654 | { |
655 | // play video |
PASSED: Continuous integration, rev:443 /jenkins. canonical. com/system- apps/job/ lp-mediaplayer- app-ci/ 3/ /jenkins. canonical. com/system- apps/job/ build/2328 /jenkins. canonical. com/system- apps/job/ build-0- fetch/2327 /jenkins. canonical. com/system- apps/job/ build-2- binpkg/ arch=amd64, release= xenial+ overlay/ 2149 /jenkins. canonical. com/system- apps/job/ build-2- binpkg/ arch=amd64, release= xenial+ overlay/ 2149/artifact/ output/ *zip*/output. zip /jenkins. canonical. com/system- apps/job/ build-2- binpkg/ arch=amd64, release= zesty/2149 /jenkins. canonical. com/system- apps/job/ build-2- binpkg/ arch=amd64, release= zesty/2149/ artifact/ output/ *zip*/output. zip /jenkins. canonical. com/system- apps/job/ build-2- binpkg/ arch=armhf, release= xenial+ overlay/ 2149 /jenkins. canonical. com/system- apps/job/ build-2- binpkg/ arch=armhf, release= xenial+ overlay/ 2149/artifact/ output/ *zip*/output. zip /jenkins. canonical. com/system- apps/job/ build-2- binpkg/ arch=armhf, release= zesty/2149 /jenkins. canonical. com/system- apps/job/ build-2- binpkg/ arch=armhf, release= zesty/2149/ artifact/ output/ *zip*/output. zip /jenkins. canonical. com/system- apps/job/ build-2- binpkg/ arch=i386, release= xenial+ overlay/ 2149 /jenkins. canonical. com/system- apps/job/ build-2- binpkg/ arch=i386, release= xenial+ overlay/ 2149/artifact/ output/ *zip*/output. zip /jenkins. canonical. com/system- apps/job/ build-2- binpkg/ arch=i386, release= zesty/2149 /jenkins. canonical. com/system- apps/job/ build-2- binpkg/ arch=i386, release= zesty/2149/ artifact/ output/ *zip*/output. zip
https:/
Executed test runs:
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
Click here to trigger a rebuild: /jenkins. canonical. com/system- apps/job/ lp-mediaplayer- app-ci/ 3/rebuild
https:/