Warning, /system/mycroft-gui/import/qml/AudioPlayer.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.Layouts 1.15 0022 import org.kde.kirigami 2.19 as Kirigami 0023 import Mycroft 1.0 as Mycroft 0024 import QtMultimedia 0025 0026 Item { 0027 id: root 0028 0029 property alias source: player.source 0030 property string status: "stop" 0031 property int switchWidth: Kirigami.Units.gridUnit * 22 0032 property alias thumbnail: albumimg.source 0033 property alias title: songtitle.text 0034 property bool progressBar: true 0035 property bool thumbnailVisible: true 0036 property bool titleVisible: true 0037 property var nextAction 0038 property var previousAction 0039 property alias currentState: player.status 0040 readonly property bool horizontal: width > switchWidth 0041 0042 onEnabledChanged: syncStatusTimer.restart() 0043 onSourceChanged: syncStatusTimer.restart() 0044 Component.onCompleted: syncStatusTimer.restart() 0045 0046 // Sometimes can't be restarted reliably immediately, put it in a timer 0047 onActiveFocusChanged: { 0048 if(activeFocus){ 0049 playButton.forceActiveFocus(); 0050 } 0051 } 0052 0053 function msToTime(duration) { 0054 var seconds = parseInt((duration/1000)%60); 0055 var minutes = parseInt((duration/(1000*60))%60); 0056 0057 minutes = (minutes < 10) ? "0" + minutes : minutes; 0058 seconds = (seconds < 10) ? "0" + seconds : seconds; 0059 0060 return minutes + ":" + seconds; 0061 } 0062 0063 Timer { 0064 id: syncStatusTimer 0065 interval: 0 0066 onTriggered: { 0067 if (enabled && status == "play") { 0068 player.play(); 0069 } else if (status == "stop") { 0070 player.stop(); 0071 } else { 0072 player.pause(); 0073 } 0074 } 0075 } 0076 MediaPlayer { 0077 id: player 0078 autoPlay: false 0079 readonly property string currentStatus: root.enabled ? root.status : "pause" 0080 0081 onCurrentStatusChanged: { 0082 switch(currentStatus){ 0083 case "stop": 0084 player.stop(); 0085 break; 0086 case "pause": 0087 player.pause() 0088 break; 0089 case "play": 0090 player.play() 0091 break; 0092 } 0093 } 0094 } 0095 0096 0097 GridLayout { 0098 anchors { 0099 top: root.horizontal ? undefined : parent.top 0100 left: parent.left 0101 right: parent.right 0102 bottom: parent.bottom 0103 } 0104 columns: root.horizontal ? 2 : 1 0105 height: implicitHeight 0106 0107 Image { 0108 id: albumimg 0109 fillMode: Image.PreserveAspectCrop 0110 visible: root.thumbnailVisible ? 1 : 0 0111 enabled: root.thumbnailVisible ? 1 : 0 0112 Layout.preferredWidth: root.horizontal ? Kirigami.Units.gridUnit * 10 : Kirigami.Units.gridUnit * 5 0113 Layout.preferredHeight: root.horizontal ? Kirigami.Units.gridUnit * 10 : Kirigami.Units.gridUnit * 5 0114 Layout.alignment: Qt.AlignHCenter 0115 } 0116 0117 ColumnLayout { 0118 Layout.fillWidth: true 0119 Layout.fillHeight: true 0120 spacing: Kirigami.Units.largeSpacing 0121 0122 Kirigami.Heading { 0123 id: songtitle 0124 text: title 0125 level: root.horizontal ? 1 : 3 0126 Layout.fillWidth: true 0127 elide: Text.ElideRight 0128 font.capitalization: Font.Capitalize 0129 visible: root.titleVisible ? 1 : 0 0130 enabled: root.titleVisible ? 1 : 0 0131 } 0132 0133 RowLayout { 0134 Layout.fillWidth: true 0135 Layout.fillHeight: true 0136 Layout.alignment: root.horizontal ? Qt.AlignLeft : Qt.AlignHCenter 0137 spacing: Kirigami.Units.largeSpacing 0138 0139 Controls.RoundButton { 0140 id: previousButton 0141 Layout.minimumWidth: Kirigami.Units.iconSizes.smallMedium 0142 Layout.minimumHeight: width 0143 Layout.fillWidth: true 0144 Layout.fillHeight: true 0145 Layout.maximumWidth: Kirigami.Units.gridUnit * 3 0146 Layout.maximumHeight: width 0147 focus: false 0148 icon.name: "media-seek-backward" 0149 KeyNavigation.right: playButton 0150 KeyNavigation.down: seekableslider 0151 onClicked: { 0152 triggerGuiEvent(previousAction, {}) 0153 } 0154 0155 background: Rectangle { 0156 Kirigami.Theme.colorSet: Kirigami.Theme.Button 0157 radius: width 0158 color: previousButton.activeFocus ? Kirigami.Theme.highlightColor : Kirigami.Theme.backgroundColor 0159 } 0160 0161 Keys.onReturnPressed: { 0162 clicked() 0163 } 0164 } 0165 0166 Controls.RoundButton { 0167 id: playButton 0168 Layout.minimumWidth: Kirigami.Units.iconSizes.medium 0169 Layout.minimumHeight: width 0170 Layout.fillWidth: true 0171 Layout.fillHeight: true 0172 Layout.maximumWidth: Kirigami.Units.gridUnit * 4 0173 Layout.maximumHeight: width 0174 focus: false 0175 icon.name: player.playbackState === MediaPlayer.PlayingState ? "media-playback-pause" : "media-playback-start" 0176 KeyNavigation.left: previousButton 0177 KeyNavigation.right: nextButton 0178 KeyNavigation.down: seekableslider 0179 onClicked: { 0180 player.playbackState === MediaPlayer.PlayingState ? player.pause() : player.play() 0181 } 0182 0183 background: Rectangle { 0184 Kirigami.Theme.colorSet: Kirigami.Theme.Button 0185 radius: width 0186 color: playButton.activeFocus ? Kirigami.Theme.highlightColor : Kirigami.Theme.backgroundColor 0187 } 0188 0189 Keys.onReturnPressed: { 0190 clicked() 0191 } 0192 } 0193 0194 Controls.RoundButton { 0195 id: nextButton 0196 Layout.minimumWidth: Kirigami.Units.iconSizes.smallMedium 0197 Layout.minimumHeight: width 0198 Layout.fillWidth: true 0199 Layout.fillHeight: true 0200 Layout.maximumWidth: Kirigami.Units.gridUnit * 3 0201 Layout.maximumHeight: width 0202 focus: false 0203 icon.name: "media-seek-forward" 0204 KeyNavigation.left: playButton 0205 KeyNavigation.down: seekableslider 0206 onClicked: { 0207 triggerGuiEvent(nextAction, {}) 0208 } 0209 0210 background: Rectangle { 0211 Kirigami.Theme.colorSet: Kirigami.Theme.Button 0212 radius: width 0213 color: nextButton.activeFocus ? Kirigami.Theme.highlightColor : Kirigami.Theme.backgroundColor 0214 } 0215 0216 Keys.onReturnPressed: { 0217 clicked() 0218 } 0219 } 0220 } 0221 0222 RowLayout { 0223 spacing: Kirigami.Units.smallSpacing 0224 Layout.fillWidth: true 0225 visible: root.progressBar ? 1 : 0 0226 enabled: root.progressBar ? 1 : 0 0227 0228 Controls.Slider { 0229 id: seekableslider 0230 to: player.duration 0231 Layout.fillWidth: true 0232 property bool sync: false 0233 0234 onValueChanged: { 0235 if (!sync) 0236 player.seek(value) 0237 } 0238 0239 Connections { 0240 target: player 0241 onPositionChanged: { 0242 seekableslider.sync = true 0243 seekableslider.value = player.position 0244 seekableslider.sync = false 0245 } 0246 } 0247 0248 Keys.onLeftPressed: { 0249 var l = 0 0250 l = seekableslider.position - 0.05 0251 seekableslider.value = seekableslider.valueAt(l); 0252 } 0253 0254 Keys.onRightPressed: { 0255 var l = 0 0256 l = seekableslider.position + 0.05 0257 seekableslider.value = seekableslider.valueAt(l); 0258 } 0259 } 0260 0261 Controls.Label { 0262 id: positionLabel 0263 text: msToTime(player.position) + " / " + msToTime(player.duration) 0264 } 0265 } 0266 } 0267 } 0268 } 0269