Warning, /plasma/plasma-mobile/components/mobileshell/qml/widgets/mediacontrols/MediaControlsWidget.qml is written in an unsupported language. File is not indexed.

0001 // SPDX-FileCopyrightText: 2021-2023 Devin Lin <devin@kde.org>
0002 // SPDX-FileCopyrightText: 2016 Kai Uwe Broulik <kde@privat.broulik.de>
0003 // SPDX-License-Identifier: LGPL-2.0-or-later
0004 
0005 import QtQuick
0006 import QtQuick.Layouts
0007 import QtQuick.Controls as QQC2
0008 
0009 import org.kde.kirigami as Kirigami
0010 
0011 import org.kde.plasma.private.mobileshell as MobileShell
0012 import org.kde.plasma.private.mobileshell.state as MobileShellState
0013 import org.kde.plasma.components 3.0 as PlasmaComponents3
0014 
0015 import org.kde.plasma.private.mpris as Mpris
0016 
0017 /**
0018  * Embeddable component that provides MPRIS control.
0019  */
0020 Item {
0021     id: root
0022     visible: sourceRepeater.count > 0
0023     
0024     readonly property real padding: Kirigami.Units.gridUnit
0025     readonly property real contentHeight: Kirigami.Units.gridUnit * 2
0026     implicitHeight: visible ? padding * 2 + contentHeight : 0
0027     
0028     MediaControlsSource {
0029         id: mpris2Source
0030     }
0031     
0032     // page indicator
0033     RowLayout {
0034         z: 1
0035         visible: view.count > 1
0036         spacing: Kirigami.Units.smallSpacing
0037         anchors.bottomMargin: Kirigami.Units.smallSpacing
0038         anchors.bottom: view.bottom
0039         anchors.horizontalCenter: parent.horizontalCenter
0040         
0041         Repeater {
0042             model: view.count
0043             delegate: Rectangle {
0044                 width: Kirigami.Units.smallSpacing
0045                 height: Kirigami.Units.smallSpacing
0046                 radius: width / 2
0047                 color: Qt.rgba(255, 255, 255, view.currentIndex == model.index ? 1 : 0.5)
0048             }
0049         }
0050     }
0051     
0052     // list of app media widgets
0053     QQC2.SwipeView {
0054         id: view
0055         clip: true
0056         
0057         anchors.fill: parent
0058         
0059         Repeater {
0060             id: sourceRepeater
0061             model: mpris2Source.mpris2Model
0062             
0063             delegate: Loader {
0064                 id: delegate
0065                 // NOTE: model is PlayerContainer from KMpris in plasma-workspace
0066 
0067                 asynchronous: true
0068                 
0069                 function getTrackName() {
0070                     console.log('track name: ' + model.title);
0071                     if (model.title) {
0072                         return model.title;
0073                     }
0074                     // if no track title is given, print out the file name
0075                     if (!model.url) {
0076                         return "";
0077                     }
0078                     const lastSlashPos = model.url.lastIndexOf('/')
0079                     if (lastSlashPos < 0) {
0080                         return ""
0081                     }
0082                     const lastUrlPart = model.url.substring(lastSlashPos + 1);
0083                     return decodeURIComponent(lastUrlPart);
0084                 }
0085 
0086                 sourceComponent: MouseArea {
0087                     id: mouseArea
0088                     implicitHeight: playerItem.implicitHeight
0089                     implicitWidth: playerItem.implicitWidth
0090                     
0091                     onClicked: {
0092                         MobileShell.AppLaunch.launchOrActivateApp(model.desktopEntry + ".desktop");
0093                         MobileShellState.ShellDBusClient.closeActionDrawer();
0094                     }
0095                     
0096                     MobileShell.BaseItem {
0097                         id: playerItem
0098                         anchors.fill: parent
0099                         
0100                         padding: root.padding
0101                         implicitHeight: root.contentHeight + root.padding * 2
0102                         implicitWidth: root.width
0103                         
0104                         background: BlurredBackground {
0105                             darken: mouseArea.pressed
0106                             imageSource: model.artUrl
0107                         }
0108                         
0109                         contentItem: Item {
0110                             Kirigami.Theme.colorSet: Kirigami.Theme.Complementary
0111                             Kirigami.Theme.inherit: false
0112                             width: playerItem.width - playerItem.leftPadding - playerItem.rightPadding
0113                             
0114                             RowLayout {
0115                                 id: controlsRow
0116                                 width: parent.width
0117                                 height: parent.height
0118                                 spacing: 0
0119 
0120                                 enabled: model.canControl
0121 
0122                                 Image {
0123                                     id: albumArt
0124                                     Layout.preferredWidth: height
0125                                     Layout.fillHeight: true
0126                                     asynchronous: true
0127                                     fillMode: Image.PreserveAspectFit
0128                                     source: model.artUrl
0129                                     sourceSize.height: height
0130                                     visible: status === Image.Loading || status === Image.Ready
0131                                 }
0132 
0133                                 ColumnLayout {
0134                                     Layout.leftMargin: albumArt.visible ? Kirigami.Units.gridUnit : 0
0135                                     Layout.fillWidth: true
0136                                     spacing: Kirigami.Units.smallSpacing
0137 
0138                                     // media track name text
0139                                     MobileShell.MarqueeLabel {
0140                                         id: trackLabel
0141                                         Layout.fillWidth: true
0142 
0143                                         inputText: model.track || i18n("No media playing");
0144                                         textFormat: Text.PlainText
0145                                         font.pointSize: Kirigami.Theme.defaultFont.pointSize
0146                                         color: "white"
0147                                     }
0148 
0149                                     // media artist name text
0150                                     MobileShell.MarqueeLabel {
0151                                         id: artistLabel
0152                                         Layout.fillWidth: true
0153 
0154                                         // if no artist is given, show player name instead
0155                                         inputText: model.artist || model.identity || ""
0156                                         textFormat: Text.PlainText
0157                                         font.pointSize: Kirigami.Theme.defaultFont.pointSize * 0.9
0158                                         opacity: 0.9
0159                                         color: "white"
0160                                     }
0161                                 }
0162 
0163                                 PlasmaComponents3.ToolButton {
0164                                     Layout.fillHeight: true
0165                                     Layout.preferredWidth: height
0166                                     
0167                                     enabled: model.canGoPrevious
0168                                     icon.name: LayoutMirroring.enabled ? "media-skip-forward" : "media-skip-backward"
0169                                     icon.width: Kirigami.Units.iconSizes.small
0170                                     icon.height: Kirigami.Units.iconSizes.small
0171                                     onClicked: {
0172                                         mpris2Source.setIndex(model.index);
0173                                         mpris2Source.goPrevious();
0174                                     }
0175                                     visible: model.canGoPrevious || model.canGoNext
0176                                     Accessible.name: i18nd("plasma_lookandfeel_org.kde.lookandfeel", "Previous track")
0177                                 }
0178 
0179                                 PlasmaComponents3.ToolButton {
0180                                     Layout.fillHeight: true
0181                                     Layout.preferredWidth: height
0182                                     
0183                                     icon.name: (model.playbackStatus === Mpris.PlaybackStatus.Playing) ? "media-playback-pause" : "media-playback-start"
0184                                     icon.width: Kirigami.Units.iconSizes.small
0185                                     icon.height: Kirigami.Units.iconSizes.small
0186                                     onClicked: {
0187                                         mpris2Source.setIndex(model.index);
0188                                         mpris2Source.playPause();
0189                                     }
0190                                     Accessible.name: i18nd("plasma_lookandfeel_org.kde.lookandfeel", "Play or Pause media")
0191                                 }
0192 
0193                                 PlasmaComponents3.ToolButton {
0194                                     Layout.fillHeight: true
0195                                     Layout.preferredWidth: height
0196                                     
0197                                     enabled: model.canGoNext
0198                                     icon.name: LayoutMirroring.enabled ? "media-skip-backward" : "media-skip-forward"
0199                                     icon.width: Kirigami.Units.iconSizes.small
0200                                     icon.height: Kirigami.Units.iconSizes.small
0201                                     onClicked: {
0202                                         mpris2Source.setIndex(model.index);
0203                                         mpris2Source.goNext();
0204                                     }
0205                                     visible: model.canGoPrevious || model.canGoNext
0206                                     Accessible.name: i18nd("plasma_lookandfeel_org.kde.lookandfeel", "Next track")
0207                                 }
0208                             }
0209                         }
0210                     }
0211                 }
0212             }
0213         }
0214     }
0215 }