Warning, /system/mycroft-gui/import/qml/VideoPlayer.qml is written in an unsupported language. File is not indexed.
0001 /* 0002 * Copyright 2019 by Aditya Mehra <aix.m@outlook.com> 0003 * Copyright 2019 by Marco Martin <mart@kde.org> 0004 * 0005 * Licensed under the Apache License, Version 2.0 (the "License"); 0006 * you may not use this file except in compliance with the License. 0007 * You may obtain a copy of the License at 0008 * 0009 * http://www.apache.org/licenses/LICENSE-2.0 0010 * 0011 * Unless required by applicable law or agreed to in writing, software 0012 * distributed under the License is distributed on an "AS IS" BASIS, 0013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 0014 * See the License for the specific language governing permissions and 0015 * limitations under the License. 0016 * 0017 */ 0018 0019 import QtQuick 2.15 0020 import QtQuick.Controls 2.15 as Controls 0021 import QtQuick.Templates 2.15 as Templates 0022 import QtQuick.Layouts 1.15 0023 import org.kde.kirigami 2.19 as Kirigami 0024 import Mycroft 1.0 as Mycroft 0025 import QtMultimedia 0026 0027 Item { 0028 id: root 0029 0030 property alias source: video.source 0031 property string status: "stop" 0032 property bool progressBar: true 0033 property bool hasNextAction: true 0034 property bool hasPreviousAction: true 0035 property bool controlBarOpened: false 0036 property var nextAction 0037 property var previousAction 0038 property alias currentState: video.status 0039 0040 onEnabledChanged: syncStatusTimer.restart() 0041 onSourceChanged: syncStatusTimer.restart() 0042 Component.onCompleted: syncStatusTimer.restart() 0043 0044 function formatTime(timeInMs) { 0045 if (!timeInMs || timeInMs <= 0) return "0:00" 0046 var seconds = timeInMs / 1000; 0047 var minutes = Math.floor(seconds / 60) 0048 seconds = Math.floor(seconds % 60) 0049 if (seconds < 10) seconds = "0" + seconds; 0050 return minutes + ":" + seconds 0051 } 0052 0053 Timer { 0054 id: hideTimer 0055 interval: 5000 0056 onTriggered: root.controlBarOpened = false; 0057 } 0058 0059 // Sometimes can't be restarted reliably immediately, put it in a timer 0060 Timer { 0061 id: syncStatusTimer 0062 interval: 0 0063 onTriggered: { 0064 if (enabled && status == "play") { 0065 video.play(); 0066 } else if (status == "stop") { 0067 video.stop(); 0068 } else { 0069 video.pause(); 0070 } 0071 } 0072 } 0073 0074 Video { 0075 id: video 0076 anchors.fill: parent 0077 focus: true 0078 autoLoad: true 0079 autoPlay: false 0080 readonly property string currentStatus: root.enabled ? root.status : "pause" 0081 Keys.onSpacePressed: video.playbackState == MediaPlayer.PlayingState ? video.pause() : video.play() 0082 Keys.onLeftPressed: video.seek(video.position - 5000) 0083 Keys.onRightPressed: video.seek(video.position + 5000) 0084 0085 onSourceChanged: { 0086 console.log(source) 0087 } 0088 0089 onCurrentStatusChanged: { 0090 switch(currentStatus){ 0091 case "stop": 0092 video.stop(); 0093 break; 0094 case "pause": 0095 video.pause() 0096 break; 0097 case "play": 0098 video.play() 0099 break; 0100 } 0101 } 0102 0103 MouseArea { 0104 anchors.fill: parent 0105 onClicked: controlBarOpened = !controlBarOpened 0106 } 0107 } 0108 0109 0110 Rectangle { 0111 anchors.left: parent.left 0112 anchors.right: parent.right 0113 anchors.bottom: parent.bottom 0114 clip: true 0115 implicitHeight: controlLayout.implicitHeight + Kirigami.Units.largeSpacing * 2 0116 color: Qt.rgba(Kirigami.Theme.backgroundColor.r, Kirigami.Theme.backgroundColor.g, Kirigami.Theme.backgroundColor.b, 0.6) 0117 opacity: controlBarOpened 0118 0119 Behavior on opacity { 0120 OpacityAnimator { 0121 duration: Kirigami.Units.longDuration 0122 easing.type: Easing.InOutCubic 0123 } 0124 } 0125 0126 onOpacityChanged: { 0127 if (controlBarOpened) { 0128 hideTimer.restart(); 0129 } 0130 } 0131 0132 RowLayout { 0133 id: controlLayout 0134 anchors.fill: parent 0135 anchors.margins: Kirigami.Units.largeSpacing 0136 0137 Controls.RoundButton { 0138 id: backButton 0139 Layout.minimumWidth: Kirigami.Units.iconSizes.smallMedium 0140 Layout.minimumHeight: width 0141 Layout.fillWidth: true 0142 Layout.fillHeight: true 0143 Layout.maximumWidth: Kirigami.Units.gridUnit * 3 0144 Layout.maximumHeight: width 0145 icon.name: "go-previous-symbolic" 0146 z: 1000 0147 onClicked: { 0148 Mycroft.MycroftController.sendRequest("mycroft.gui.screen.close", {}); 0149 video.stop(); 0150 } 0151 } 0152 0153 Controls.RoundButton { 0154 id: previousButton 0155 Layout.minimumWidth: Kirigami.Units.iconSizes.smallMedium 0156 Layout.minimumHeight: width 0157 Layout.fillWidth: true 0158 Layout.fillHeight: true 0159 Layout.maximumWidth: Kirigami.Units.gridUnit * 3 0160 Layout.maximumHeight: width 0161 focus: false 0162 icon.name: "media-seek-backward" 0163 visible: hasNextAction 0164 onClicked: { 0165 triggerGuiEvent(previousAction, {}) 0166 previousButton.focus = false 0167 } 0168 } 0169 0170 Controls.RoundButton { 0171 id: playButton 0172 Layout.minimumWidth: Kirigami.Units.iconSizes.medium 0173 Layout.minimumHeight: width 0174 Layout.fillWidth: true 0175 Layout.fillHeight: true 0176 Layout.maximumWidth: Kirigami.Units.gridUnit * 4 0177 Layout.maximumHeight: width 0178 focus: false 0179 icon.name: video.playbackState === MediaPlayer.PlayingState ? "media-playback-pause" : "media-playback-start" 0180 onClicked: { 0181 video.playbackState === MediaPlayer.PlayingState ? video.pause() : video.play() 0182 playButton.focus = false 0183 } 0184 } 0185 0186 Controls.RoundButton { 0187 id: nextButton 0188 Layout.minimumWidth: Kirigami.Units.iconSizes.smallMedium 0189 Layout.minimumHeight: width 0190 Layout.fillWidth: true 0191 Layout.fillHeight: true 0192 Layout.maximumWidth: Kirigami.Units.gridUnit * 3 0193 Layout.maximumHeight: width 0194 focus: false 0195 icon.name: "media-seek-forward" 0196 visible: hasPreviousAction 0197 onClicked: { 0198 triggerGuiEvent(nextAction, {}) 0199 nextButton.focus = false 0200 } 0201 } 0202 0203 Templates.Slider { 0204 id: slider 0205 Layout.fillWidth: true 0206 Layout.alignment: Qt.AlignVCenter 0207 implicitHeight: Kirigami.Units.gridUnit 0208 value: video.position 0209 from: 0 0210 to: video.duration 0211 z: 1000 0212 onMoved: { 0213 video.seek(value); 0214 hideTimer.restart(); 0215 } 0216 handle: Rectangle { 0217 x: slider.position * (parent.width - width) 0218 implicitWidth: Kirigami.Units.gridUnit 0219 implicitHeight: implicitWidth 0220 radius: width 0221 } 0222 background: Item { 0223 Rectangle { 0224 id: groove 0225 anchors { 0226 verticalCenter: parent.verticalCenter 0227 left: parent.left 0228 right: parent.right 0229 } 0230 radius: height 0231 height: Math.round(Kirigami.Units.gridUnit/3) 0232 color: Qt.rgba(Kirigami.Theme.textColor.r, Kirigami.Theme.textColor.g, Kirigami.Theme.textColor.b, 0.3) 0233 Rectangle { 0234 anchors { 0235 left: parent.left 0236 top: parent.top 0237 bottom: parent.bottom 0238 } 0239 radius: height 0240 color: Kirigami.Theme.highlightColor 0241 width: slider.position * (parent.width - slider.handle.width/2) + slider.handle.width/2 0242 } 0243 } 0244 0245 Controls.Label { 0246 anchors { 0247 left: parent.left 0248 top: groove.bottom 0249 topMargin: Kirigami.Units.smallSpacing 0250 } 0251 horizontalAlignment: Text.AlignLeft 0252 verticalAlignment: Text.AlignVCenter 0253 text: formatTime(playPosition) 0254 color: "white" 0255 } 0256 0257 Controls.Label { 0258 anchors { 0259 right: parent.right 0260 top: groove.bottom 0261 topMargin: Kirigami.Units.smallSpacing 0262 } 0263 horizontalAlignment: Text.AlignRight 0264 verticalAlignment: Text.AlignVCenter 0265 text: formatTime(duration) 0266 } 0267 } 0268 } 0269 } 0270 } 0271 } 0272