1/* 2 SPDX-FileCopyrightText: 2016 Kai Uwe Broulik <kde@privat.broulik.de> 3 4 SPDX-License-Identifier: GPL-2.0-or-later 5*/ 6 7import QtQuick 2.5 8import QtQuick.Layouts 1.1 9 10import org.kde.plasma.core 2.0 as PlasmaCore 11import org.kde.plasma.components 3.0 as PlasmaComponents3 12import org.kde.plasma.extras 2.0 as PlasmaExtras 13 14Item { 15 visible: mpris2Source.hasPlayer 16 implicitHeight: PlasmaCore.Units.gridUnit * 3 17 implicitWidth: PlasmaCore.Units.gridUnit * 16 18 19 RowLayout { 20 id: controlsRow 21 anchors.fill: parent 22 spacing: 0 23 24 enabled: mpris2Source.canControl 25 26 PlasmaCore.DataSource { 27 id: mpris2Source 28 29 readonly property string source: "@multiplex" 30 readonly property var playerData: data[source] 31 32 readonly property bool hasPlayer: sources.length > 1 && !!playerData 33 readonly property string identity: hasPlayer ? playerData.Identity : "" 34 readonly property bool playing: hasPlayer && playerData.PlaybackStatus === "Playing" 35 readonly property bool canControl: hasPlayer && playerData.CanControl 36 readonly property bool canGoBack: hasPlayer && playerData.CanGoPrevious 37 readonly property bool canGoNext: hasPlayer && playerData.CanGoNext 38 39 readonly property var currentMetadata: hasPlayer ? playerData.Metadata : ({}) 40 41 readonly property string track: { 42 var xesamTitle = currentMetadata["xesam:title"] 43 if (xesamTitle) { 44 return xesamTitle 45 } 46 // if no track title is given, print out the file name 47 var xesamUrl = currentMetadata["xesam:url"] ? currentMetadata["xesam:url"].toString() : "" 48 if (!xesamUrl) { 49 return "" 50 } 51 var lastSlashPos = xesamUrl.lastIndexOf('/') 52 if (lastSlashPos < 0) { 53 return "" 54 } 55 var lastUrlPart = xesamUrl.substring(lastSlashPos + 1) 56 return decodeURIComponent(lastUrlPart) 57 } 58 readonly property string artist: currentMetadata["xesam:artist"] || "" 59 readonly property string albumArt: currentMetadata["mpris:artUrl"] || "" 60 61 engine: "mpris2" 62 connectedSources: [source] 63 64 function startOperation(op) { 65 var service = serviceForSource(source) 66 var operation = service.operationDescription(op) 67 return service.startOperationCall(operation) 68 } 69 70 function goPrevious() { 71 startOperation("Previous"); 72 } 73 function goNext() { 74 startOperation("Next"); 75 } 76 function playPause(source) { 77 startOperation("PlayPause"); 78 } 79 } 80 81 Image { 82 id: albumArt 83 Layout.preferredWidth: height 84 Layout.fillHeight: true 85 asynchronous: true 86 fillMode: Image.PreserveAspectFit 87 source: mpris2Source.albumArt 88 sourceSize.height: height 89 visible: status === Image.Loading || status === Image.Ready 90 } 91 92 Item { // spacer 93 width: PlasmaCore.Units.smallSpacing 94 height: 1 95 } 96 97 ColumnLayout { 98 Layout.fillWidth: true 99 spacing: 0 100 101 PlasmaComponents3.Label { 102 Layout.fillWidth: true 103 wrapMode: Text.NoWrap 104 elide: Text.ElideRight 105 text: mpris2Source.track || i18nd("plasma_lookandfeel_org.kde.lookandfeel", "No media playing") 106 textFormat: Text.PlainText 107 font.pointSize: PlasmaCore.Theme.defaultFont.pointSize + 1 108 maximumLineCount: 1 109 } 110 111 PlasmaExtras.DescriptiveLabel { 112 Layout.fillWidth: true 113 wrapMode: Text.NoWrap 114 elide: Text.ElideRight 115 // if no artist is given, show player name instead 116 text: mpris2Source.artist || mpris2Source.identity || "" 117 textFormat: Text.PlainText 118 font.pointSize: PlasmaCore.Theme.smallestFont.pointSize + 1 119 maximumLineCount: 1 120 } 121 } 122 123 PlasmaComponents3.ToolButton { 124 focusPolicy: Qt.TabFocus 125 enabled: mpris2Source.canGoBack 126 Layout.preferredHeight: PlasmaCore.Units.gridUnit*2 127 Layout.preferredWidth: Layout.preferredHeight 128 icon.name: LayoutMirroring.enabled ? "media-skip-forward" : "media-skip-backward" 129 onClicked: { 130 fadeoutTimer.running = false 131 mpris2Source.goPrevious() 132 } 133 visible: mpris2Source.canGoBack || mpris2Source.canGoNext 134 Accessible.name: i18nd("plasma_lookandfeel_org.kde.lookandfeel", "Previous track") 135 } 136 137 PlasmaComponents3.ToolButton { 138 focusPolicy: Qt.TabFocus 139 Layout.fillHeight: true 140 Layout.preferredWidth: height // make this button bigger 141 icon.name: mpris2Source.playing ? "media-playback-pause" : "media-playback-start" 142 onClicked: { 143 fadeoutTimer.running = false 144 mpris2Source.playPause() 145 } 146 Accessible.name: i18nd("plasma_lookandfeel_org.kde.lookandfeel", "Play or Pause media") 147 } 148 149 PlasmaComponents3.ToolButton { 150 focusPolicy: Qt.TabFocus 151 enabled: mpris2Source.canGoNext 152 Layout.preferredHeight: PlasmaCore.Units.gridUnit*2 153 Layout.preferredWidth: Layout.preferredHeight 154 icon.name: LayoutMirroring.enabled ? "media-skip-backward" : "media-skip-forward" 155 onClicked: { 156 fadeoutTimer.running = false 157 mpris2Source.goNext() 158 } 159 visible: mpris2Source.canGoBack || mpris2Source.canGoNext 160 Accessible.name: i18nd("plasma_lookandfeel_org.kde.lookandfeel", "Next track") 161 } 162 } 163} 164