Merge lp:~justinmcp/webbrowser-app/mediaplayer into lp:webbrowser-app

Proposed by Justin McPherson
Status: Work in progress
Proposed branch: lp:~justinmcp/webbrowser-app/mediaplayer
Merge into: lp:webbrowser-app
Diff against target: 1082 lines (+991/-1)
11 files modified
src/Ubuntu/Web/Controls.qml (+285/-0)
src/Ubuntu/Web/HLine.qml (+28/-0)
src/Ubuntu/Web/IconButton.qml (+43/-0)
src/Ubuntu/Web/MediaPlayer.qml (+226/-0)
src/Ubuntu/Web/SceneFrame.qml (+79/-0)
src/Ubuntu/Web/TimeLabel.qml (+58/-0)
src/Ubuntu/Web/TimeLine.qml (+89/-0)
src/Ubuntu/Web/UbuntuWebView02.qml (+36/-0)
src/Ubuntu/Web/VLine.qml (+54/-0)
src/Ubuntu/Web/VideoSlider.qml (+89/-0)
src/app/webcontainer/webapp-container.cpp (+4/-1)
To merge this branch: bzr merge lp:~justinmcp/webbrowser-app/mediaplayer
Reviewer Review Type Date Requested Status
Ubuntu Phablet Team Pending
Review via email: mp+260911@code.launchpad.net
To post a comment you must log in.
997. By Justin McPherson <justin@phablet-dev>

WIP

998. By Justin McPherson <justin@phablet-dev>

WIP

999. By Justin McPherson <justin@phablet-dev>

WIP

1000. By Justin McPherson <justin@phablet-dev>

WIP

1001. By Justin McPherson

Merge from trunk.

Unmerged revisions

1001. By Justin McPherson

Merge from trunk.

1000. By Justin McPherson <justin@phablet-dev>

WIP

999. By Justin McPherson <justin@phablet-dev>

WIP

998. By Justin McPherson <justin@phablet-dev>

WIP

997. By Justin McPherson <justin@phablet-dev>

WIP

996. By Justin McPherson <justin@phablet-dev>

WIP

995. By Justin McPherson <justin@phablet-dev>

WIP

994. By Justin McPherson <justin@phablet-dev>

WIP

993. By Justin McPherson <justin@phablet-dev>

WIP

992. By Justin McPherson <justin@phablet-dev>

wip

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== added file 'src/Ubuntu/Web/Controls.qml'
2--- src/Ubuntu/Web/Controls.qml 1970-01-01 00:00:00 +0000
3+++ src/Ubuntu/Web/Controls.qml 2015-08-03 07:20:39 +0000
4@@ -0,0 +1,285 @@
5+/*
6+ * Copyright (C) 2013 Canonical, Ltd.
7+ *
8+ * Authors:
9+ * Ugo Riboni <ugo.riboni@canonical.com>
10+ * MichaƂ Sawicz <michal.sawicz@canonical.com>
11+ * Renato Araujo Oliveira Filho <renato@canonical.com>
12+ *
13+ * This program is free software; you can redistribute it and/or modify
14+ * it under the terms of the GNU General Public License as published by
15+ * the Free Software Foundation; version 3.
16+ *
17+ * This program is distributed in the hope that it will be useful,
18+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
19+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20+ * GNU General Public License for more details.
21+ *
22+ * You should have received a copy of the GNU General Public License
23+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
24+ */
25+import QtQuick 2.0
26+import QtMultimedia 5.0
27+import Ubuntu.Components 1.1
28+
29+Item {
30+ id: controls
31+
32+ readonly property string orientation: controls.width >= units.gu(60) ? "LANDSCAPE" : "PORTRAIT"
33+ property variant video: null
34+ property int maximumHeight: 0
35+ property int heightOffset: 0
36+ property variant playerStatus: MediaPlayer.NoMedia
37+
38+ property alias settingsEnabled: _settingsButton.enabled
39+
40+ signal closeClicked
41+ signal playbackClicked
42+ signal settingsClicked
43+ signal shareClicked
44+ signal seekRequested(int time)
45+ signal startSeek
46+ signal endSeek
47+
48+ focus: true
49+ height: _toolbar.height
50+
51+ Rectangle {
52+ id: _bgColor
53+
54+ color: "black"
55+ opacity: 0.8
56+ anchors.fill: parent
57+ }
58+
59+ HLine {
60+ id: _divLine
61+ anchors {
62+ left: _toolbar.left
63+ right: _toolbar.right
64+ top: parent.top
65+ }
66+ }
67+
68+ Column {
69+ id: _toolbar
70+
71+ anchors {
72+ bottom: parent.bottom
73+ left: parent.left
74+ right: parent.right
75+ }
76+ height: childrenRect.height
77+
78+ Item {
79+ id: timelinePlaceHolderPortrait
80+
81+ anchors {
82+ left: parent.left
83+ right: parent.right
84+ }
85+ height: controls.orientation === "PORTRAIT" ? units.gu(5) : 0
86+ }
87+
88+ Row {
89+ id: controlsRow
90+ anchors {
91+ left: parent.left
92+ right: parent.right
93+ margins: units.gu(2)
94+ }
95+ height: units.gu(5)
96+
97+ IconButton {
98+ id: _closeButton
99+
100+ iconSource: "image://theme/close"
101+ iconSize: units.gu(3)
102+ anchors.verticalCenter: parent.verticalCenter
103+ width: units.gu(8)
104+ height: units.gu(4)
105+ onClicked: controls.closeClicked()
106+ leftAlignment: true
107+ }
108+
109+ VLine {
110+ }
111+
112+ IconButton {
113+ id: playbackButton
114+ objectName: "Controls.PlayBackButton"
115+
116+ property string icon
117+
118+ iconSource: icon ? "image://theme/media-playback-%1".arg(icon) : ""
119+ iconSize: units.gu(3)
120+ anchors.verticalCenter: parent.verticalCenter
121+ width: controls.orientation === "LANDSCAPE" ? units.gu(10) :
122+ controlsRow.width -
123+ _closeButton.width -
124+ _timeLabel.width -
125+ _shareButton.width -
126+ _settingsButton.width
127+
128+ height: units.gu(4)
129+ onClicked: {
130+ controls.playbackClicked()
131+ }
132+ }
133+
134+ VLine {
135+ }
136+
137+ Item {
138+ id: timelinePlaceHolderLandscape
139+
140+ anchors {
141+ top: parent.top
142+ bottom: parent.bottom
143+ }
144+
145+ width: controls.orientation === "LANDSCAPE" ? controlsRow.width -
146+ _closeButton.width -
147+ playbackButton.width -
148+ _timeLabel.width -
149+ _shareButton.width -
150+ _settingsButton.width -
151+ units.gu(2) : 0
152+
153+
154+ TimeLine {
155+ id: _timeline
156+
157+ property bool seeking: false
158+
159+ anchors {
160+ left: parent.left
161+ right: parent.right
162+ margins: units.gu(2)
163+ verticalCenter: parent.verticalCenter
164+ }
165+ height: units.gu(4)
166+ parent: controls.orientation === "PORTRAIT" ? timelinePlaceHolderPortrait : timelinePlaceHolderLandscape
167+ minimumValue: 0
168+ maximumValue: video ? video.duration / 1000 : 0
169+
170+ // pause the video during the seek
171+ onPressedChanged: {
172+ if (!pressed && seeking) {
173+ endSeek()
174+ seeking = false
175+ }
176+ }
177+
178+ // Live value is the real slider value. Ex: User dragging the slider
179+ onLiveValueChanged: {
180+ if (video) {
181+ var changed = Math.abs(liveValue - videoPosition)
182+ if (changed > 1) {
183+ if (!seeking) {
184+ startSeek()
185+ seeking = true
186+ }
187+ seekRequested(liveValue * 1000)
188+ }
189+ }
190+ }
191+ }
192+ }
193+
194+ VLine {
195+ visible: controls.orientation === "LANDSCAPE"
196+ }
197+
198+ TimeLabel {
199+ id: _timeLabel
200+
201+ remainingTime: _timeline.remainingTime
202+ currentTime: _timeline.currentTime
203+
204+ anchors {
205+ top: parent.top
206+ bottom: parent.bottom
207+ }
208+ width: controls.orientation === "LANDSCAPE" ? units.gu(10) : units.gu(8)
209+ }
210+
211+ VLine {
212+ visible: _shareButton.visible
213+ }
214+
215+ IconButton {
216+ id: _shareButton
217+
218+ /* Disable share button for now until we get some feedback from designers */
219+ visible: false
220+ iconSource: "artwork/icon_share.png"
221+ iconSize: units.gu(3)
222+ anchors {
223+ top: parent.top
224+ bottom: parent.bottom
225+ }
226+ width: visible ? units.gu(7) : 0
227+ onClicked: controls.shareClicked()
228+ }
229+
230+ VLine {
231+ visible: _settingsButton.visible
232+ }
233+
234+ IconButton {
235+ id: _settingsButton
236+
237+ visible: false
238+ iconSource: "artwork/icon_settings.png"
239+ iconSize: units.gu(3)
240+ anchors {
241+ top: parent.top
242+ bottom: parent.bottom
243+ }
244+ width: visible ? units.gu(7) : 0
245+ enabled: false
246+ opacity: enabled ? 1.0 : 0.2
247+ onClicked: settingsClicked()
248+ }
249+ }
250+ }
251+
252+ Connections {
253+ target: video
254+
255+ onPositionChanged: {
256+ // To get position to be smooth and accurate during seeking, do
257+ // not use the reported value for position from media-hub but instead
258+ // use the value that the user move the scrubber to. This makes seeking
259+ // silky smooth. Report correctly on normal advance, or EOS.
260+ if (!_timeline.seeking || controls.playerStatus == MediaPlayer.EndOfMedia)
261+ _timeline.videoPosition = video ? video.position / 1000 : 0
262+ }
263+ }
264+
265+ Connections {
266+ target: controls
267+ onPlayerStatusChanged: {
268+ console.debug("onPlayerStatusChanged")
269+ _timeline.playerStatus = controls.playerStatus
270+ }
271+ }
272+
273+ states: [
274+ State {
275+ name: "stopped"
276+ PropertyChanges { target: playbackButton; icon: "start" }
277+ },
278+
279+ State {
280+ name: "playing"
281+ PropertyChanges { target: playbackButton; icon: "pause" }
282+ },
283+
284+ State {
285+ name: "paused"
286+ PropertyChanges { target: playbackButton; icon: "start" }
287+ }
288+ ]
289+}
290
291=== added file 'src/Ubuntu/Web/HLine.qml'
292--- src/Ubuntu/Web/HLine.qml 1970-01-01 00:00:00 +0000
293+++ src/Ubuntu/Web/HLine.qml 2015-08-03 07:20:39 +0000
294@@ -0,0 +1,28 @@
295+/*
296+ * Copyright (C) 2013 Canonical, Ltd.
297+ *
298+ * Authors:
299+ * Renato Araujo Oliveira Filho <renato@canonical.com>
300+ *
301+ * This program is free software; you can redistribute it and/or modify
302+ * it under the terms of the GNU General Public License as published by
303+ * the Free Software Foundation; version 3.
304+ *
305+ * This program is distributed in the hope that it will be useful,
306+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
307+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
308+ * GNU General Public License for more details.
309+ *
310+ * You should have received a copy of the GNU General Public License
311+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
312+ */
313+
314+import QtQuick 2.0
315+import Ubuntu.Components 1.1
316+
317+Rectangle {
318+ height: units.dp(1)
319+ anchors.left: parent.left
320+ anchors.right: parent.right
321+ color: UbuntuColors.coolGrey
322+}
323
324=== added file 'src/Ubuntu/Web/IconButton.qml'
325--- src/Ubuntu/Web/IconButton.qml 1970-01-01 00:00:00 +0000
326+++ src/Ubuntu/Web/IconButton.qml 2015-08-03 07:20:39 +0000
327@@ -0,0 +1,43 @@
328+/*
329+ * Copyright (C) 2013 Canonical, Ltd.
330+ *
331+ * Authors:
332+ * Renato Araujo Oliveira Filho <renato@canonical.com>
333+ *
334+ * This program is free software; you can redistribute it and/or modify
335+ * it under the terms of the GNU General Public License as published by
336+ * the Free Software Foundation; version 3.
337+ *
338+ * This program is distributed in the hope that it will be useful,
339+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
340+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
341+ * GNU General Public License for more details.
342+ *
343+ * You should have received a copy of the GNU General Public License
344+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
345+ */
346+
347+import QtQuick 2.0
348+import Ubuntu.Components 1.1
349+
350+AbstractButton {
351+ id: root
352+
353+ property alias iconSource: _image.source
354+ property alias iconSize: _image.height
355+ property bool leftAlignment: false
356+
357+ focus: false
358+
359+ Image {
360+ id: _image
361+
362+ width: height
363+ smooth: true
364+ anchors {
365+ verticalCenter: parent.verticalCenter
366+ horizontalCenter: root.leftAlignment ? undefined : parent.horizontalCenter
367+ left: root.leftAlignment ? parent.left : undefined
368+ }
369+ }
370+}
371
372=== added file 'src/Ubuntu/Web/MediaPlayer.qml'
373--- src/Ubuntu/Web/MediaPlayer.qml 1970-01-01 00:00:00 +0000
374+++ src/Ubuntu/Web/MediaPlayer.qml 2015-08-03 07:20:39 +0000
375@@ -0,0 +1,226 @@
376+import QtQuick 2.0
377+import QtMultimedia 5.0
378+import "."
379+
380+Rectangle {
381+ id: mediaPlayer
382+ color: "black"
383+ state: "stopped"
384+
385+ property var content
386+
387+ property alias source: player.source
388+ property alias duration: player.duration
389+ property alias position: player.position
390+ property alias playbackState: player.playbackState
391+ property alias metaData: player.metaData
392+
393+ signal closeClicked
394+
395+ onContentChanged: {
396+ source = content.url
397+ }
398+
399+ function play() {
400+ state = "playing"
401+ }
402+
403+ function pause() {
404+ state = "paused"
405+ }
406+
407+ function stop() {
408+ state = "stopped"
409+ }
410+
411+ function playPause() {
412+ if (state == "playing") {
413+ state = "paused"
414+ } else {
415+ state = "playing"
416+ }
417+ }
418+
419+ function seek(position) {
420+ player.seek(position)
421+ }
422+
423+ MediaPlayer {
424+ id: player
425+ source: mediaPlayer.source
426+
427+ onPlaybackStateChanged: {
428+ if (playbackState == MediaPlayer.PausedState) {
429+ mediaPlayer.pause()
430+ } else if (playbackState == MediaPlayer.PlayingState) {
431+ mediaPlayer.play()
432+ }
433+ }
434+
435+ metaData.onMetaDataChanged: {
436+ mediaPlayer.metaDataChanged()
437+ }
438+ }
439+
440+ VideoOutput {
441+ id: _videoOutput
442+ source: player
443+ anchors.fill: parent
444+ opacity: 0.0
445+
446+ Behavior on opacity {
447+ NumberAnimation { duration: 300 }
448+ }
449+
450+ MouseArea {
451+ anchors {
452+ left: parent.left
453+ right: parent.right
454+ top: parent.top
455+ bottom: _controls.top
456+ }
457+
458+ onClicked: {
459+ if (_controls.state == "open") {
460+ _controls.state = "closed"
461+ } else {
462+ _controls.state = "open"
463+ }
464+ }
465+ }
466+
467+ Item {
468+ id: _controls
469+ height: _controlsContents.height
470+ anchors {
471+ left: parent.left
472+ right: parent.right
473+ }
474+
475+ state: "closed"
476+ states: [
477+ State {
478+ name: "open"
479+ PropertyChanges {
480+ target: _controls
481+ y: parent.height - height
482+ }
483+ },
484+ State {
485+ name: "closed"
486+ PropertyChanges {
487+ target: _controls
488+ y: parent.height
489+ }
490+ }
491+ ]
492+
493+ transitions: [
494+ Transition {
495+ to: "closed"
496+ PropertyAnimation {
497+ target: _controls
498+ properties: "y"
499+ duration: 175
500+ easing.type: Easing.OutQuad
501+ }
502+ },
503+ Transition {
504+ to: "open"
505+ PropertyAnimation {
506+ target: _controls
507+ properties: "y"
508+ duration: 175
509+ easing.type: Easing.OutQuad
510+ }
511+ }
512+ ]
513+
514+ Controls {
515+ id: _controlsContents
516+ property bool isPaused: false
517+
518+ settingsEnabled: false
519+
520+ objectName: "controls"
521+ state: mediaPlayer.state
522+ video: player
523+ anchors {
524+ left: parent.left
525+ right: parent.right
526+ bottom: parent.bottom
527+ }
528+
529+ maximumHeight: units.gu(27)
530+ playerStatus: player.mediaStatus
531+
532+ onPlaybackClicked: {
533+ mediaPlayer.playPause()
534+ }
535+
536+ onSeekRequested: {
537+ player.seek(time)
538+ }
539+
540+ onStartSeek: {
541+ isPaused = (state == "paused")
542+ player.pause()
543+ }
544+
545+ onEndSeek: {
546+ // Only automatically resume playing after a seek that is not to the
547+ // end of stream (i.e. position == duration)
548+ if (player.status != MediaPlayer.EndOfMedia && !isPaused) {
549+ player.play()
550+ }
551+ }
552+
553+ onCloseClicked: {
554+ _controls.state = "closed"
555+ mediaPlayer.closeClicked();
556+ }
557+ }
558+ }
559+ }
560+
561+ Timer {
562+ id: scrubbingTimer
563+ interval: 500
564+ repeat: true
565+
566+ property int step
567+
568+ onTriggered: {
569+ if (player.position + step < 0) {
570+ player.seek(0)
571+ mediaPlayer.state = "playing"
572+ } else {
573+ player.seek(mediaPlayer.position + step)
574+ }
575+ }
576+ }
577+
578+ states: [
579+ State {
580+ name: "stopped"
581+ StateChangeScript { script: player.stop() }
582+ PropertyChanges { target: scrubbingTimer; running: false }
583+ PropertyChanges { target: _videoOutput; opacity: 0.0 }
584+ },
585+
586+ State {
587+ name: "playing"
588+ PropertyChanges { target: player; playbackRate: 1.0; muted: false }
589+ StateChangeScript { script: player.play() }
590+ PropertyChanges { target: scrubbingTimer; running: false }
591+ PropertyChanges { target: _videoOutput; opacity: 1.0 }
592+ },
593+
594+ State {
595+ name: "paused"
596+ StateChangeScript { script: player.pause() }
597+ PropertyChanges { target: scrubbingTimer; running: false }
598+ PropertyChanges { target: _videoOutput; opacity: 1.0 }
599+ }
600+ ]
601+}
602
603=== added file 'src/Ubuntu/Web/SceneFrame.qml'
604--- src/Ubuntu/Web/SceneFrame.qml 1970-01-01 00:00:00 +0000
605+++ src/Ubuntu/Web/SceneFrame.qml 2015-08-03 07:20:39 +0000
606@@ -0,0 +1,79 @@
607+/*
608+ * Copyright (C) 2013 Canonical, Ltd.
609+ *
610+ * Authors:
611+ * Renato Araujo Oliveira Filho <renato@canonical.com>
612+ *
613+ * This program is free software; you can redistribute it and/or modify
614+ * it under the terms of the GNU General Public License as published by
615+ * the Free Software Foundation; version 3.
616+ *
617+ * This program is distributed in the hope that it will be useful,
618+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
619+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
620+ * GNU General Public License for more details.
621+ *
622+ * You should have received a copy of the GNU General Public License
623+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
624+ */
625+
626+import QtQuick 2.0
627+import Ubuntu.Components 1.1
628+
629+MouseArea {
630+ id: _imageFrame
631+
632+ property int start
633+ property int duration
634+ property alias source: _image.source
635+ property bool active: false
636+ readonly property bool ready: (_image.status === Image.Ready)
637+
638+ Behavior on width {
639+ NumberAnimation { duration: 150; easing.type: Easing.InOutQuart }
640+ }
641+
642+ UbuntuShape {
643+ id: _shape
644+ radius: "medium"
645+
646+ anchors {
647+ fill: parent
648+ topMargin: active ? 0 : units.gu(2)
649+ bottomMargin: active ? 0 : units.gu(2)
650+ leftMargin: units.gu(1)
651+ rightMargin: units.gu(1)
652+
653+ Behavior on topMargin {
654+ NumberAnimation { duration: 150; easing.type: Easing.InOutQuart }
655+ }
656+
657+ Behavior on bottomMargin {
658+ NumberAnimation { duration: 150; easing.type: Easing.InOutQuart }
659+ }
660+ }
661+
662+ image: Image {
663+ id: _image
664+
665+ fillMode: Image.PreserveAspectCrop
666+ smooth: true
667+ asynchronous: true
668+ sourceSize.width: _shape.width
669+ sourceSize.height: _shape.height
670+ }
671+ }
672+
673+ ActivityIndicator {
674+ id: imgLoading
675+
676+ anchors {
677+ verticalCenter: _shape.verticalCenter
678+ horizontalCenter: _shape.horizontalCenter
679+ margins: units.gu(0.5)
680+ }
681+
682+ running: _image.status != Image.Ready
683+ visible: running
684+ }
685+}
686
687=== added file 'src/Ubuntu/Web/TimeLabel.qml'
688--- src/Ubuntu/Web/TimeLabel.qml 1970-01-01 00:00:00 +0000
689+++ src/Ubuntu/Web/TimeLabel.qml 2015-08-03 07:20:39 +0000
690@@ -0,0 +1,58 @@
691+/*
692+ * Copyright (C) 2013 Canonical, Ltd.
693+ *
694+ * Authors:
695+ * Renato Araujo Oliveira Filho <renato@canonical.com>
696+ *
697+ * This program is free software; you can redistribute it and/or modify
698+ * it under the terms of the GNU General Public License as published by
699+ * the Free Software Foundation; version 3.
700+ *
701+ * This program is distributed in the hope that it will be useful,
702+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
703+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
704+ * GNU General Public License for more details.
705+ *
706+ * You should have received a copy of the GNU General Public License
707+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
708+ */
709+
710+import QtQuick 2.0
711+import Ubuntu.Components 1.1
712+//import "../sdk"
713+
714+Label {
715+ id: _TimeLabel
716+ objectName: "TimeLine.TimeLabel"
717+
718+ property string currentTime
719+ property string remainingTime
720+
721+ color: "#e8e1d0"
722+ fontSize: "small"
723+ state: "PROGRESSIVE"
724+ verticalAlignment: Text.AlignVCenter
725+ horizontalAlignment: Text.AlignRight
726+
727+ states: [
728+ State {
729+ name: "PROGRESSIVE"
730+ PropertyChanges { target: _TimeLabel; text: _TimeLabel.currentTime }
731+ },
732+ State {
733+ name: "DEGRESSIVE"
734+ PropertyChanges { target: _TimeLabel; text: "- %1".arg(_TimeLabel.remainingTime) }
735+ }
736+ ]
737+
738+ MouseArea {
739+ anchors.fill: parent
740+ onClicked: {
741+ if (_TimeLabel.state === "PROGRESSIVE") {
742+ _TimeLabel.state = "DEGRESSIVE"
743+ } else {
744+ _TimeLabel.state = "PROGRESSIVE"
745+ }
746+ }
747+ }
748+}
749
750=== added file 'src/Ubuntu/Web/TimeLine.qml'
751--- src/Ubuntu/Web/TimeLine.qml 1970-01-01 00:00:00 +0000
752+++ src/Ubuntu/Web/TimeLine.qml 2015-08-03 07:20:39 +0000
753@@ -0,0 +1,89 @@
754+/*
755+ * Copyright (C) 2013 Canonical, Ltd.
756+ *
757+ * Authors:
758+ * Renato Araujo Oliveira Filho <renato@canonical.com>
759+ *
760+ * This program is free software; you can redistribute it and/or modify
761+ * it under the terms of the GNU General Public License as published by
762+ * the Free Software Foundation; version 3.
763+ *
764+ * This program is distributed in the hope that it will be useful,
765+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
766+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
767+ * GNU General Public License for more details.
768+ *
769+ * You should have received a copy of the GNU General Public License
770+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
771+ */
772+
773+import QtQuick 2.0
774+import QtMultimedia 5.0
775+import Ubuntu.Components 1.1
776+//import "../sdk"
777+
778+Slider {
779+ id: _slider
780+ objectName: "TimeLine.Slider"
781+
782+ readonly property alias liveValue: _slider.value
783+ property real videoPosition: -1
784+ property variant playerStatus: MediaPlayer.NoMedia
785+ property string currentTime
786+ property string remainingTime
787+
788+ signal clicked(bool insideThumb)
789+
790+ function formatProgress(time) {
791+ var hour = 0
792+ var min = 0
793+ var secs = 0
794+ time = Math.floor(time)
795+
796+ secs = time % 60
797+ time = Math.floor(time / 60)
798+ min = time % 60
799+ hour = Math.floor(time / 60)
800+
801+ if (secs < 10) secs = "0%1".arg(secs)
802+ if (min < 10) min = "0%1".arg(min)
803+ if (hour < 10) hour = "0%1".arg(hour)
804+
805+ // TRANSLATORS: this refers to a duration/remaining time of the video, of which you can change the order.
806+ // %1 refers to hours, %2 refers to minutes and %3 refers to seconds.
807+ return i18n.tr("%1:%2:%3").arg(hour).arg(min).arg(secs)
808+ }
809+
810+ style: VideoSlider {property Item item: _slider}
811+ minimumValue: 0
812+ maximumValue: 1000
813+ live: true
814+ onVideoPositionChanged: {
815+ if (_slider.playerStatus == MediaPlayer.EndOfMedia)
816+ {
817+ // On EndOfMedia status, make sure the slider returns to the beginning
818+ _slider.value = 0
819+ } else {
820+ // Else, pass all new positions through to the slider UI
821+ _slider.value = _slider.videoPosition
822+ }
823+ }
824+
825+ onValueChanged: {
826+ if (value > 0) {
827+ _slider.currentTime = formatProgress(value)
828+ if (_slider.maximumValue > 0) {
829+ _slider.remainingTime = formatProgress(_slider.maximumValue - value)
830+ } else {
831+ // TRANSLATORS: this refers to an unknown duration.
832+ _slider.remainingTime = i18n.tr("unknown")
833+ }
834+ } else {
835+ _slider.currentTime = i18n.tr("0:00:00")
836+ }
837+ }
838+
839+ onTouched: {
840+ _slider.clicked(onThumb)
841+ }
842+}
843
844=== modified file 'src/Ubuntu/Web/UbuntuWebView02.qml'
845--- src/Ubuntu/Web/UbuntuWebView02.qml 2015-06-11 14:35:28 +0000
846+++ src/Ubuntu/Web/UbuntuWebView02.qml 2015-08-03 07:20:39 +0000
847@@ -285,4 +285,40 @@
848 console.error(msg)
849 }
850 }
851+
852+ Component {
853+ id: playerComponent
854+
855+ MediaPlayer {
856+ id: player
857+ anchors.fill: parent
858+ visible: false
859+
860+ function showInterface() {
861+ visible = true
862+ _webview.fullscreen = true
863+ }
864+
865+ function hideInterface() {
866+ visible = false
867+ _webview.fullscreen = false
868+ }
869+
870+ // These MUST stay, apparent signal propagation bug
871+ onPlaybackStateChanged: { }
872+ onPositionChanged: { }
873+ onDurationChanged: { }
874+
875+ onCloseClicked: {
876+ stop();
877+ source = ""
878+ }
879+ }
880+ }
881+
882+ Component.onCompleted: {
883+ if (this.hasOwnProperty("mediaPlayer")) {
884+ mediaPlayer = playerComponent.createObject(parent)
885+ }
886+ }
887 }
888
889=== added file 'src/Ubuntu/Web/VLine.qml'
890--- src/Ubuntu/Web/VLine.qml 1970-01-01 00:00:00 +0000
891+++ src/Ubuntu/Web/VLine.qml 2015-08-03 07:20:39 +0000
892@@ -0,0 +1,54 @@
893+/*
894+ * Copyright (C) 2013 Canonical, Ltd.
895+ *
896+ * Authors:
897+ * Renato Araujo Oliveira Filho <renato@canonical.com>
898+ *
899+ * This program is free software; you can redistribute it and/or modify
900+ * it under the terms of the GNU General Public License as published by
901+ * the Free Software Foundation; version 3.
902+ *
903+ * This program is distributed in the hope that it will be useful,
904+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
905+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
906+ * GNU General Public License for more details.
907+ *
908+ * You should have received a copy of the GNU General Public License
909+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
910+ */
911+
912+import QtQuick 2.0
913+import Ubuntu.Components 1.1
914+
915+Row {
916+ id: root
917+
918+ anchors {
919+ top: parent.top
920+ topMargin: units.gu(0.5)
921+ bottom: parent.bottom
922+ bottomMargin: units.gu(0.5)
923+ }
924+ width: visible ? units.dp(2) : 0
925+
926+ Rectangle {
927+ anchors {
928+ top: parent.top
929+ bottom: parent.bottom
930+ }
931+
932+ color: "white"
933+ opacity: 0.08
934+ width: root.visible ? units.dp(1) : 0
935+ }
936+ Rectangle {
937+ anchors {
938+ top: parent.top
939+ bottom: parent.bottom
940+ }
941+
942+ color: "black"
943+ opacity: 0.03
944+ width: root.visible ? units.dp(1) : 0
945+ }
946+}
947
948=== added file 'src/Ubuntu/Web/VideoSlider.qml'
949--- src/Ubuntu/Web/VideoSlider.qml 1970-01-01 00:00:00 +0000
950+++ src/Ubuntu/Web/VideoSlider.qml 2015-08-03 07:20:39 +0000
951@@ -0,0 +1,89 @@
952+/*
953+ * Copyright (C) 2013 Canonical, Ltd.
954+ *
955+ * Authors:
956+ * Renato Araujo Oliveira Filho <renato@canonical.com>
957+ *
958+ * This program is free software; you can redistribute it and/or modify
959+ * it under the terms of the GNU General Public License as published by
960+ * the Free Software Foundation; version 3.
961+ *
962+ * This program is distributed in the hope that it will be useful,
963+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
964+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
965+ * GNU General Public License for more details.
966+ *
967+ * You should have received a copy of the GNU General Public License
968+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
969+ */
970+
971+import QtQuick 2.0
972+import Ubuntu.Components 1.1
973+
974+Item {
975+ id: main
976+ anchors.fill: parent
977+
978+ // properties to be published:
979+ property Item bar: backgroundShape
980+ property Item thumb: thumbShape
981+
982+ // private properties
983+ property real thumbSpacing: units.gu(1)
984+ property real liveValue: SliderUtils.liveValue(item)
985+ property real normalizedValue: SliderUtils.normalizedValue(item)
986+
987+ property real thumbSpace: backgroundShape.width - (2.0 * thumbSpacing + thumbWidth)
988+ property real thumbWidth: item.height - thumbSpacing
989+
990+ BorderImage {
991+ id: backgroundFilledShape
992+
993+ border {
994+ left: 7
995+ top: 7
996+ right: 7
997+ bottom: 7
998+ }
999+ horizontalTileMode: BorderImage.Repeat
1000+ verticalTileMode: BorderImage.Repeat
1001+ source: "artwork/slider_shape.png"
1002+ anchors {
1003+ verticalCenter: parent.verticalCenter
1004+ left: parent.left
1005+ leftMargin: units.gu(0.2)
1006+ }
1007+ height: units.gu(1)
1008+ width: normalizedValue * thumbSpace + thumbSpacing + (thumbShape.width / 2)
1009+ }
1010+
1011+ BorderImage {
1012+ id: backgroundShape
1013+
1014+ border {
1015+ left: 7
1016+ top: 7
1017+ right: 7
1018+ bottom: 7
1019+ }
1020+ horizontalTileMode: BorderImage.Repeat
1021+ verticalTileMode: BorderImage.Repeat
1022+ source: "artwork/slider_bg.png"
1023+ anchors {
1024+ verticalCenter: parent.verticalCenter
1025+ left: parent.left
1026+ right: parent.right
1027+ }
1028+ height: units.gu(1.5)
1029+ }
1030+
1031+ Image {
1032+ id: thumbShape
1033+
1034+ x: backgroundShape.x + thumbSpacing + normalizedValue * thumbSpace
1035+ anchors.verticalCenter: backgroundShape.verticalCenter
1036+ width: thumbWidth
1037+ height: thumbWidth
1038+ source: "artwork/slider_handle.png"
1039+ }
1040+}
1041
1042=== added directory 'src/Ubuntu/Web/artwork'
1043=== added file 'src/Ubuntu/Web/artwork/close@20.png'
1044Binary files src/Ubuntu/Web/artwork/close@20.png 1970-01-01 00:00:00 +0000 and src/Ubuntu/Web/artwork/close@20.png 2015-08-03 07:20:39 +0000 differ
1045=== added file 'src/Ubuntu/Web/artwork/icon_exitfscreen@20.png'
1046Binary files src/Ubuntu/Web/artwork/icon_exitfscreen@20.png 1970-01-01 00:00:00 +0000 and src/Ubuntu/Web/artwork/icon_exitfscreen@20.png 2015-08-03 07:20:39 +0000 differ
1047=== added file 'src/Ubuntu/Web/artwork/icon_pause@20.png'
1048Binary files src/Ubuntu/Web/artwork/icon_pause@20.png 1970-01-01 00:00:00 +0000 and src/Ubuntu/Web/artwork/icon_pause@20.png 2015-08-03 07:20:39 +0000 differ
1049=== added file 'src/Ubuntu/Web/artwork/icon_play@20.png'
1050Binary files src/Ubuntu/Web/artwork/icon_play@20.png 1970-01-01 00:00:00 +0000 and src/Ubuntu/Web/artwork/icon_play@20.png 2015-08-03 07:20:39 +0000 differ
1051=== added file 'src/Ubuntu/Web/artwork/icon_settings@20.png'
1052Binary files src/Ubuntu/Web/artwork/icon_settings@20.png 1970-01-01 00:00:00 +0000 and src/Ubuntu/Web/artwork/icon_settings@20.png 2015-08-03 07:20:39 +0000 differ
1053=== added file 'src/Ubuntu/Web/artwork/icon_share@20.png'
1054Binary files src/Ubuntu/Web/artwork/icon_share@20.png 1970-01-01 00:00:00 +0000 and src/Ubuntu/Web/artwork/icon_share@20.png 2015-08-03 07:20:39 +0000 differ
1055=== added file 'src/Ubuntu/Web/artwork/slider_bg.png'
1056Binary files src/Ubuntu/Web/artwork/slider_bg.png 1970-01-01 00:00:00 +0000 and src/Ubuntu/Web/artwork/slider_bg.png 2015-08-03 07:20:39 +0000 differ
1057=== added file 'src/Ubuntu/Web/artwork/slider_handle.png'
1058Binary files src/Ubuntu/Web/artwork/slider_handle.png 1970-01-01 00:00:00 +0000 and src/Ubuntu/Web/artwork/slider_handle.png 2015-08-03 07:20:39 +0000 differ
1059=== added file 'src/Ubuntu/Web/artwork/slider_shape.png'
1060Binary files src/Ubuntu/Web/artwork/slider_shape.png 1970-01-01 00:00:00 +0000 and src/Ubuntu/Web/artwork/slider_shape.png 2015-08-03 07:20:39 +0000 differ
1061=== modified file 'src/app/webcontainer/webapp-container.cpp'
1062--- src/app/webcontainer/webapp-container.cpp 2015-06-24 13:37:05 +0000
1063+++ src/app/webcontainer/webapp-container.cpp 2015-08-03 07:20:39 +0000
1064@@ -286,6 +286,7 @@
1065 out << " --accountProvider=PROVIDER_NAME Online account provider for the application if the application is to reuse a local account." << endl;
1066 out << " --accountSwitcher enable switching between different Online Accounts identities" << endl;
1067 out << " --store-session-cookies store session cookies on disk" << endl;
1068+ out << " --enable-external-media enable use of an external media player" << endl;
1069 out << " --enable-media-hub-audio enable media-hub for audio playback" << endl;
1070 out << " --user-agent-string=USER_AGENT overrides the default User Agent with the provided one." << endl;
1071 out << "Chrome options (if none specified, no chrome is shown by default):" << endl;
1072@@ -296,7 +297,9 @@
1073 void WebappContainer::earlyEnvironment()
1074 {
1075 Q_FOREACH(const QString& argument, m_arguments) {
1076- if (argument.startsWith("--enable-media-hub-audio")) {
1077+ if (argument.startsWith("--enable-external-media")) {
1078+ qputenv("OXIDE_ENABLE_EXTERNAL_MEDIA", QString("1").toLocal8Bit().constData());
1079+ } else if (argument.startsWith("--enable-media-hub-audio")) {
1080 qputenv("OXIDE_ENABLE_MEDIA_HUB_AUDIO", QString("1").toLocal8Bit().constData());
1081 }
1082 }

Subscribers

People subscribed via source and target branches

to status/vote changes: