Warning, /plasma/plasma-workspace/applets/mediacontroller/package/contents/ui/CompactRepresentation.qml is written in an unsupported language. File is not indexed.

0001 /*
0002     SPDX-FileCopyrightText: 2022 Fushan Wen <qydwhotmail@gmail.com>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 import QtQuick
0008 import QtQuick.Layouts
0009 
0010 import org.kde.plasma.core as PlasmaCore
0011 import org.kde.plasma.components 3.0 as PC3
0012 import org.kde.plasma.plasmoid 2.0
0013 import org.kde.kirigami 2 as Kirigami
0014 
0015 /**
0016  * [Album Art][Now Playing]
0017  */
0018 MouseArea {
0019     id: compactRepresentation
0020 
0021     Layout.preferredWidth: {
0022         switch (compactRepresentation.layoutForm) {
0023         case CompactRepresentation.LayoutType.VerticalPanel:
0024         case CompactRepresentation.LayoutType.VerticalDesktop:
0025             return compactRepresentation.parent.width;
0026         case CompactRepresentation.LayoutType.HorizontalPanel:
0027         case CompactRepresentation.LayoutType.HorizontalDesktop:
0028             return iconLoader.active ? iconLoader.item.implicitWidth : playerRow.width;
0029         case CompactRepresentation.LayoutType.IconOnly:
0030         default:
0031             return -1;
0032         }
0033     }
0034     Layout.preferredHeight: {
0035         switch (compactRepresentation.layoutForm) {
0036         case CompactRepresentation.LayoutType.VerticalPanel:
0037             return iconLoader.active ? compactRepresentation.parent.width : playerRow.height;
0038         default:
0039             return -1;
0040         }
0041     }
0042     Layout.maximumHeight: Layout.preferredHeight
0043 
0044     enum LayoutType {
0045         Tray,
0046         HorizontalPanel,
0047         VerticalPanel,
0048         HorizontalDesktop,
0049         VerticalDesktop,
0050         IconOnly
0051     }
0052 
0053     property int layoutForm: CompactRepresentation.LayoutType.IconOnly
0054 
0055     Binding on layoutForm {
0056         when: playerRow.active
0057         delayed: true
0058         restoreMode: Binding.RestoreBindingOrValue
0059         value: {
0060             if (compactRepresentation.inTray) {
0061                 return CompactRepresentation.LayoutType.Tray;
0062             } else if (compactRepresentation.inPanel) {
0063                 return compactRepresentation.isVertical ? CompactRepresentation.LayoutType.VerticalPanel : CompactRepresentation.LayoutType.HorizontalPanel;
0064             } else if (compactRepresentation.parent.width > compactRepresentation.parent.height + playerRow.item.columnSpacing) {
0065                 return CompactRepresentation.LayoutType.HorizontalDesktop;
0066             } else if (compactRepresentation.parent.height - compactRepresentation.parent.width >= playerRow.item.labelHeight + playerRow.item.rowSpacing) {
0067                 return CompactRepresentation.LayoutType.VerticalDesktop;
0068             }
0069             return CompactRepresentation.LayoutType.IconOnly;
0070         }
0071     }
0072 
0073     readonly property bool isVertical: Plasmoid.formFactor === PlasmaCore.Types.Vertical
0074     readonly property bool inPanel: [PlasmaCore.Types.TopEdge, PlasmaCore.Types.RightEdge, PlasmaCore.Types.BottomEdge, PlasmaCore.Types.LeftEdge].includes(Plasmoid.location)
0075     readonly property bool inTray: parent.objectName === "org.kde.desktop-CompactApplet"
0076 
0077     acceptedButtons: Qt.LeftButton | Qt.MiddleButton | Qt.BackButton | Qt.ForwardButton
0078     hoverEnabled: true
0079 
0080     property int wheelDelta: 0
0081 
0082     onWheel: wheel => {
0083         wheelDelta += (wheel.inverted ? -1 : 1) * (wheel.angleDelta.y ? wheel.angleDelta.y : -wheel.angleDelta.x)
0084         while (wheelDelta >= 120) {
0085             wheelDelta -= 120;
0086             mpris2Model.currentPlayer?.changeVolume(volumePercentStep / 100, true);
0087         }
0088         while (wheelDelta <= -120) {
0089             wheelDelta += 120;
0090             mpris2Model.currentPlayer?.changeVolume(-volumePercentStep / 100, true);
0091         }
0092     }
0093 
0094     onClicked: mouse => {
0095         switch (mouse.button) {
0096         case Qt.MiddleButton:
0097             root.togglePlaying()
0098             break
0099         case Qt.BackButton:
0100             if (root.canGoPrevious) {
0101                 root.previous();
0102             }
0103             break
0104         case Qt.ForwardButton:
0105             if (root.canGoNext) {
0106                 root.next();
0107             }
0108             break
0109         default:
0110             root.expanded = !root.expanded
0111         }
0112     }
0113 
0114     Loader {
0115         id: iconLoader
0116         anchors.fill: parent
0117         visible: active
0118 
0119         active: inTray || root.track.length === 0
0120         sourceComponent: Kirigami.Icon {
0121             active: compactRepresentation.containsMouse
0122             source: Plasmoid.icon
0123         }
0124     }
0125 
0126     Loader {
0127         id: playerRow
0128 
0129         width: {
0130             if (!active) {
0131                 return 0;
0132             }
0133             switch (compactRepresentation.layoutForm) {
0134             case CompactRepresentation.LayoutType.VerticalPanel:
0135             case CompactRepresentation.LayoutType.VerticalDesktop:
0136                 return compactRepresentation.parent.width;
0137             case CompactRepresentation.LayoutType.HorizontalPanel:
0138                 return item.implicitWidth;
0139             case CompactRepresentation.LayoutType.HorizontalDesktop:
0140                 return Math.min(item.implicitWidth, compactRepresentation.parent.width);
0141             case CompactRepresentation.LayoutType.IconOnly:
0142             default:
0143                 return Math.min(compactRepresentation.parent.width, compactRepresentation.parent.height);
0144             }
0145         }
0146 
0147         height: {
0148             if (!active) {
0149                 return 0;
0150             }
0151             switch (compactRepresentation.layoutForm) {
0152             case CompactRepresentation.LayoutType.VerticalPanel:
0153                 return item.implicitHeight;
0154             case CompactRepresentation.LayoutType.VerticalDesktop:
0155             case CompactRepresentation.LayoutType.HorizontalPanel:
0156             case CompactRepresentation.LayoutType.HorizontalDesktop:
0157                 return compactRepresentation.parent.height;
0158             case CompactRepresentation.LayoutType.IconOnly:
0159             default:
0160                 return Math.min(compactRepresentation.parent.width, compactRepresentation.parent.height);
0161             }
0162         }
0163 
0164         visible: active
0165 
0166         active: !iconLoader.active
0167         sourceComponent: GridLayout {
0168             id: grid
0169             readonly property real labelHeight: songTitle.contentHeight
0170 
0171             rowSpacing: Kirigami.Units.smallSpacing
0172             columnSpacing: rowSpacing
0173             flow: {
0174                 switch (compactRepresentation.layoutForm) {
0175                 case CompactRepresentation.LayoutType.VerticalPanel:
0176                 case CompactRepresentation.LayoutType.VerticalDesktop:
0177                     return GridLayout.TopToBottom;
0178                 default:
0179                     return GridLayout.LeftToRight;
0180                 }
0181             }
0182 
0183             Item {
0184                 id: spacerItem
0185                 visible: compactRepresentation.layoutForm === CompactRepresentation.LayoutType.VerticalDesktop
0186                 Layout.fillHeight: true
0187             }
0188 
0189             AlbumArtStackView {
0190                 id: albumArt
0191 
0192                 Layout.alignment: Qt.AlignVCenter
0193                 Layout.preferredWidth: Math.min(compactRepresentation.parent.width, compactRepresentation.parent.height)
0194                 Layout.preferredHeight: Layout.preferredWidth
0195 
0196                 inCompactRepresentation: true
0197 
0198                 Connections {
0199                     target: root
0200 
0201                     function onAlbumArtChanged() {
0202                         albumArt.loadAlbumArt();
0203                     }
0204                 }
0205 
0206                 Component.onCompleted: albumArt.loadAlbumArt()
0207             }
0208 
0209             ColumnLayout {
0210                 Layout.alignment: Qt.AlignVCenter
0211                 visible: (compactRepresentation.layoutForm !== CompactRepresentation.LayoutType.VerticalPanel
0212                     && compactRepresentation.layoutForm !== CompactRepresentation.LayoutType.IconOnly)
0213                     || (compactRepresentation.layoutForm === CompactRepresentation.LayoutType.VerticalPanel
0214                     && compactRepresentation.parent.width >= Kirigami.Units.gridUnit * 5)
0215 
0216                 spacing: 0
0217 
0218                 // Song Title
0219                 PC3.Label {
0220                     id: songTitle
0221 
0222                     Layout.fillWidth: true
0223                     Layout.maximumWidth: compactRepresentation.layoutForm === CompactRepresentation.LayoutType.HorizontalPanel ? Kirigami.Units.gridUnit * 10 : -1
0224 
0225                     elide: Text.ElideRight
0226                     horizontalAlignment: grid.flow === GridLayout.TopToBottom ? Text.AlignHCenter : Text.AlignJustify
0227                     maximumLineCount: 1
0228 
0229                     opacity: root.isPlaying ? 1 : 0.6
0230                     Behavior on opacity {
0231                         NumberAnimation {
0232                             duration: Kirigami.Units.longDuration
0233                             easing.type: Easing.InOutQuad
0234                         }
0235                     }
0236 
0237                     text: root.track
0238                     textFormat: Text.PlainText
0239                     wrapMode: Text.Wrap
0240                 }
0241 
0242                 // Song Artist
0243                 PC3.Label {
0244                     id: songArtist
0245 
0246                     Layout.fillWidth: true
0247                     Layout.maximumWidth: songTitle.Layout.maximumWidth
0248                     visible: root.artist.length > 0 && playerRow.height >= songTitle.contentHeight + contentHeight * 0.8 /* For CJK */ + (compactRepresentation.layoutForm === CompactRepresentation.LayoutType.VerticalDesktop ? albumArt.Layout.preferredHeight + grid.rowSpacing : 0)
0249 
0250                     elide: Text.ElideRight
0251                     font.pointSize: Kirigami.Theme.smallFont.pointSize
0252                     horizontalAlignment: songTitle.horizontalAlignment
0253                     maximumLineCount: 1
0254                     opacity: 0.6
0255                     text: root.artist
0256                     textFormat: Text.PlainText
0257                     wrapMode: Text.Wrap
0258                 }
0259             }
0260 
0261             Item {
0262                 visible: spacerItem.visible
0263                 Layout.fillHeight: true
0264             }
0265         }
0266     }
0267 }