Warning, /multimedia/elisa/src/qml/mobile/MobileTrackPlayer.qml is written in an unsupported language. File is not indexed.

0001 /*
0002    SPDX-FileCopyrightText: 2020 (c) Devin Lin <espidev@gmail.com>
0003 
0004    SPDX-License-Identifier: LGPL-3.0-or-later
0005  */
0006 
0007 import QtQuick 2.7
0008 import QtQuick.Layouts 1.2
0009 import QtQuick.Controls 2.3
0010 import QtQuick.Window 2.2
0011 import org.kde.kirigami 2.5 as Kirigami
0012 import org.kde.elisa 1.0
0013 import ".."
0014 import "../shared"
0015 
0016 BasePlayerControl {
0017     id: trackPlayer
0018 
0019     property alias volume: volumeButton.sliderValue
0020 
0021     property string image
0022     property string title
0023     property string artist
0024     property string albumArtist
0025     property string album
0026 
0027     property bool portrait
0028 
0029     property int imageSourceSize: 512
0030 
0031     // hardcode slider colours because theming doesn't really make sense on top of the blurred background
0032     property color sliderElapsedColor: "white"
0033     property color sliderRemainingColor: "grey"
0034     property color sliderHandleColor: "white"
0035 
0036     ColumnLayout {
0037         anchors.fill: parent
0038         spacing: Kirigami.Units.largeSpacing
0039 
0040         // hide arrow button
0041         FlatButtonWithToolTip {
0042             id: minimizePlayer
0043             Layout.alignment: Qt.AlignHCenter | Qt.AlignTop
0044             Layout.maximumHeight: parent.height
0045             Layout.preferredHeight: Kirigami.Units.gridUnit * 2
0046             Layout.maximumWidth: parent.height
0047             Layout.preferredWidth: Kirigami.Units.gridUnit * 2
0048             text: i18nc("@action:button", "Minimize Player")
0049             icon.name: "arrow-down"
0050             icon.color: "white"
0051             Kirigami.Theme.colorSet: Kirigami.Theme.Complementary
0052             Kirigami.Theme.inherit: false
0053             onClicked: toClose.restart()
0054         }
0055 
0056         // album art
0057         ImageWithFallback {
0058             property double specWidth: {
0059                 let allowedWidth = mainWindow.width - Kirigami.Units.largeSpacing * 4;
0060                 let allowedHeight = mainWindow.height - Kirigami.Units.largeSpacing * 8 - (minimizePlayer.height + bottomPlayerControls.height);
0061                 return Math.min(allowedWidth, allowedHeight);
0062             }
0063             Layout.alignment: Qt.AlignHCenter | Qt.AlignTop
0064             Layout.preferredWidth: specWidth
0065             Layout.minimumWidth: specWidth
0066             Layout.maximumWidth: specWidth
0067             Layout.preferredHeight: specWidth
0068 
0069             asynchronous: true
0070             mipmap: true
0071 
0072             source: trackPlayer.image
0073             fallback: Qt.resolvedUrl(elisaTheme.defaultAlbumImage)
0074 
0075             sourceSize {
0076                 width: imageSourceSize * Screen.devicePixelRatio
0077                 height: imageSourceSize * Screen.devicePixelRatio
0078             }
0079 
0080             fillMode: Image.PreserveAspectFit
0081         }
0082 
0083         Item { Layout.fillHeight: true }
0084 
0085         // bottom player controls
0086         ColumnLayout {
0087             id: bottomPlayerControls
0088             spacing: Kirigami.Units.smallSpacing
0089 
0090             Layout.alignment: Qt.AlignBottom
0091             Layout.fillWidth: true
0092             Layout.maximumWidth: mainWindow.width - Kirigami.Units.largeSpacing * 4
0093 
0094             LabelWithToolTip {
0095                 id: mainLabel
0096                 text: title
0097                 wrapMode: Text.Wrap
0098                 Layout.alignment: Qt.AlignLeft | Qt.AlignVCenter
0099                 Layout.fillWidth: true
0100                 elide: Text.ElideRight
0101                 maximumLineCount: 1
0102                 // Hardcoded because the footerbar blur always makes a dark-ish
0103                 // background, so we don't want to use a color scheme color that
0104                 // might also be dark
0105                 color: "white"
0106                 level: 4
0107                 font.weight: Font.Bold
0108                 font.bold: true
0109 
0110                 MouseArea {
0111                     id: titleMouseArea
0112                     hoverEnabled: true
0113                     anchors.left: parent.left
0114                     anchors.top: parent.top
0115                     anchors.bottom: parent.bottom
0116                     width: parent.implicitWidth
0117                     cursorShape: Qt.PointingHandCursor
0118                     onClicked: {
0119                         openNowPlaying()
0120                     }
0121                 }
0122             }
0123 
0124             LabelWithToolTip {
0125                 id: authorLabel
0126                 text: artist
0127                 visible: text.length > 0
0128                 wrapMode: Text.Wrap
0129                 Layout.alignment: Qt.AlignLeft | Qt.AlignVCenter
0130                 Layout.fillWidth: true
0131                 elide: Text.ElideRight
0132                 maximumLineCount: 1
0133                 // Hardcoded because the footerbar blur always makes a dark-ish
0134                 // background, so we don't want to use a color scheme color that
0135                 // might also be dark
0136                 color: "white"
0137                 level: 4
0138 
0139                 MouseArea {
0140                     id: authorMouseArea
0141                     hoverEnabled: true
0142                     anchors.left: parent.left
0143                     anchors.top: parent.top
0144                     anchors.bottom: parent.bottom
0145                     width: parent.implicitWidth
0146                     cursorShape: Qt.PointingHandCursor
0147                     onClicked: {
0148                         openArtist()
0149                     }
0150                 }
0151             }
0152 
0153             LabelWithToolTip {
0154                 id: albumLabel
0155                 text: album
0156                 visible: text.length > 0
0157                 wrapMode: Text.Wrap
0158                 Layout.alignment: Qt.AlignLeft | Qt.AlignVCenter
0159                 Layout.fillWidth: true
0160                 elide: Text.ElideRight
0161                 maximumLineCount: 1
0162                 // Hardcoded because the footerbar blur always makes a dark-ish
0163                 // background, so we don't want to use a color scheme color that
0164                 // might also be dark
0165                 color: "white"
0166                 level: 4
0167 
0168                 MouseArea {
0169                     id: albumMouseArea
0170                     hoverEnabled: true
0171                     anchors.left: parent.left
0172                     anchors.top: parent.top
0173                     anchors.bottom: parent.bottom
0174                     width: parent.implicitWidth
0175                     cursorShape: Qt.PointingHandCursor
0176                     onClicked: {
0177                         openAlbum()
0178                     }
0179                 }
0180             }
0181 
0182             // misc. player controls
0183             RowLayout {
0184                 Layout.preferredHeight: Kirigami.Units.gridUnit * 3
0185 
0186                 // ensure white icons
0187                 Kirigami.Theme.colorSet: Kirigami.Theme.Complementary
0188                 Kirigami.Theme.inherit: false
0189 
0190                 FlatButtonWithToolTip {
0191                     id: infoButton
0192                     Layout.maximumHeight: parent.height
0193                     Layout.preferredHeight: Math.floor(Kirigami.Units.gridUnit * 2.5)
0194                     Layout.maximumWidth: height
0195                     Layout.preferredWidth: height
0196                     text: i18nc("@action:button show track information", "Show Info")
0197                     icon.name: "documentinfo"
0198                     icon.color: "white"
0199                     onClicked: openNowPlaying()
0200                 }
0201 
0202                 FlatButtonWithToolTip {
0203                     id: shuffleButton
0204                     Layout.maximumHeight: parent.height
0205                     Layout.preferredHeight: Math.floor(Kirigami.Units.gridUnit * 2.5)
0206                     Layout.maximumWidth: height
0207                     Layout.preferredWidth: height
0208                     text: i18nc("@action:button", "Toggle Shuffle")
0209                     icon.name: "media-playlist-shuffle"
0210                     icon.color: "white"
0211                     checked: ElisaApplication.mediaPlayListProxyModel.shufflePlayList
0212                     onClicked: ElisaApplication.mediaPlayListProxyModel.shufflePlayList = !ElisaApplication.mediaPlayListProxyModel.shufflePlayList
0213                 }
0214 
0215                 FlatButtonWithToolTip {
0216                     id: repeatButton
0217                     Layout.maximumHeight: parent.height
0218                     Layout.preferredHeight: Math.floor(Kirigami.Units.gridUnit * 2.5)
0219                     Layout.maximumWidth: height
0220                     Layout.preferredWidth: height
0221                     text: {
0222                         const map = {
0223                             [MediaPlayListProxyModel.None]: i18nc("@info:tooltip", "Current: Don't repeat tracks"),
0224                             [MediaPlayListProxyModel.One]: i18nc("@info:tooltip", "Current: Repeat current track"),
0225                             [MediaPlayListProxyModel.Playlist]: i18nc("@info:tooltip", "Current: Repeat all tracks in playlist"),
0226                         }
0227                         return map[ElisaApplication.mediaPlayListProxyModel.repeatMode]
0228                     }
0229                     icon.name: {
0230                         const map = {
0231                             [MediaPlayListProxyModel.None]: "media-repeat-none",
0232                             [MediaPlayListProxyModel.One]: "media-repeat-single",
0233                             [MediaPlayListProxyModel.Playlist]: "media-repeat-all",
0234                         }
0235                         return map[ElisaApplication.mediaPlayListProxyModel.repeatMode]
0236                     }
0237                     icon.color: "white"
0238 
0239                     down: pressed || menu.visible
0240                     Accessible.role: Accessible.ButtonMenu
0241 
0242                     checkable: true
0243                     checked: ElisaApplication.mediaPlayListProxyModel.repeatMode !== 0
0244 
0245                     onClicked: {
0246                         ElisaApplication.mediaPlayListProxyModel.repeatMode = (ElisaApplication.mediaPlayListProxyModel.repeatMode + 1) % 3
0247                     }
0248                     onPressAndHold: {
0249                         menu.popup()
0250                     }
0251 
0252                     menu: Menu {
0253                         PlaylistModeItem {
0254                             text: i18nc("@action:inmenu", "Playlist")
0255                             mode: MediaPlayListProxyModel.Playlist
0256                         }
0257                         PlaylistModeItem {
0258                             text: i18nc("@action:inmenu", "One")
0259                             mode: MediaPlayListProxyModel.One
0260                         }
0261                         PlaylistModeItem {
0262                             text: i18nc("@action:inmenu", "None")
0263                             mode: MediaPlayListProxyModel.None
0264                         }
0265                     }
0266                 }
0267             }
0268 
0269             // duration slider
0270             DurationSlider {
0271                 Layout.fillWidth: true
0272                 Layout.maximumHeight: Math.floor(Kirigami.Units.gridUnit * 2.5)
0273                 position: trackPlayer.position
0274                 duration: trackPlayer.duration
0275                 seekable: trackPlayer.seekable
0276                 playEnabled: trackPlayer.playEnabled
0277                 onSeek: position => trackPlayer.seek(position)
0278 
0279                 // this color works well over the blurred/darkened background
0280                 labelColor: "white"
0281                 labelsInline: false
0282             }
0283 
0284             // bottom play controls
0285             RowLayout {
0286                 Layout.alignment: Qt.AlignHCenter
0287                 Layout.preferredHeight: Math.floor(Kirigami.Units.gridUnit * 2.5)
0288 
0289                 // ensure white icons
0290                 Kirigami.Theme.colorSet: Kirigami.Theme.Complementary
0291                 Kirigami.Theme.inherit: false
0292 
0293                 // volume button
0294                 MobileVolumeButton {
0295                     id: volumeButton
0296                     muted: trackPlayer.muted
0297                     Layout.maximumHeight: parent.height
0298                     Layout.preferredHeight: Math.floor(Kirigami.Units.gridUnit * 2.5)
0299                     Layout.maximumWidth: height
0300                     Layout.preferredWidth: height
0301                 }
0302 
0303                 Item { Layout.fillWidth: true }
0304 
0305                 FlatButtonWithToolTip {
0306                     id: skipBackwardButton
0307                     Layout.maximumHeight: parent.height
0308                     Layout.preferredHeight: Math.floor(Kirigami.Units.gridUnit * 2.5)
0309                     Layout.maximumWidth: height
0310                     Layout.preferredWidth: height
0311                     enabled: skipBackwardEnabled
0312                     text: i18nc("@action:button", "Skip Backward")
0313                     onClicked: trackPlayer.playPrevious()
0314                     icon.name: trackPlayer.LayoutMirroring.enabled ? "media-skip-forward" : "media-skip-backward"
0315                     icon.width: Kirigami.Units.gridUnit
0316                     icon.height: Kirigami.Units.gridUnit
0317                     icon.color: "white"
0318                 }
0319 
0320                 FlatButtonWithToolTip {
0321                     id: playPauseButton
0322                     Layout.maximumHeight: parent.height
0323                     Layout.preferredHeight: Math.floor(Kirigami.Units.gridUnit * 2.5)
0324                     Layout.maximumWidth: height
0325                     Layout.preferredWidth: height
0326                     enabled: trackPlayer.playEnabled
0327                     text: trackPlayer.isPlaying ? i18nc("@action:button Pause any media that is playing", "Pause") : i18nc("@action:button Start playing media", "Play")
0328                     onClicked: trackPlayer.isPlaying ? trackPlayer.pause() : trackPlayer.play()
0329                     icon.name: trackPlayer.isPlaying ? "media-playback-pause" : "media-playback-start"
0330                     icon.width: Kirigami.Units.gridUnit
0331                     icon.height: Kirigami.Units.gridUnit
0332                     icon.color: "white"
0333                 }
0334 
0335                 FlatButtonWithToolTip {
0336                     id: skipForwardButton
0337                     Layout.maximumHeight: parent.height
0338                     Layout.preferredHeight: Math.floor(Kirigami.Units.gridUnit * 2.5)
0339                     Layout.maximumWidth: height
0340                     Layout.preferredWidth: height
0341                     enabled: skipForwardEnabled
0342                     text: i18nc("@action:button", "Skip Forward")
0343                     onClicked: trackPlayer.playNext()
0344                     icon.name: trackPlayer.LayoutMirroring.enabled ? "media-skip-backward" : "media-skip-forward"
0345                     icon.width: Kirigami.Units.gridUnit
0346                     icon.height: Kirigami.Units.gridUnit
0347                     icon.color: "white"
0348                 }
0349 
0350                 Item { Layout.fillWidth: true }
0351 
0352                 FlatButtonWithToolTip {
0353                     id: showPlaylistButton
0354                     Layout.maximumHeight: parent.height
0355                     Layout.preferredHeight: Math.floor(Kirigami.Units.gridUnit * 2.5)
0356                     Layout.maximumWidth: height
0357                     Layout.preferredWidth: height
0358                     text: i18nc("@action:button", "Show Playlist")
0359                     onClicked: playlistDrawer.open()
0360                     icon.name: "view-media-playlist"
0361                     icon.width: Kirigami.Units.gridUnit
0362                     icon.height: Kirigami.Units.gridUnit
0363                     icon.color: "white"
0364                 }
0365             }
0366         }
0367     }
0368 }