From 931d4fbfe22c07930ba891cd052a2d24e05eb8b9 Mon Sep 17 00:00:00 2001 From: reionwong Date: Wed, 11 Aug 2021 18:41:04 +0800 Subject: [PATCH] Add media controller --- images/dark/media-playback-pause-symbolic.svg | 6 +- images/dark/media-playback-start-symbolic.svg | 2 +- .../light/media-playback-pause-symbolic.svg | 6 +- .../light/media-playback-start-symbolic.svg | 2 +- images/media-cover.svg | 4 + qml.qrc | 2 + qml/ControlCenter.qml | 5 + qml/MprisItem.qml | 193 ++++++++++++++++++ 8 files changed, 214 insertions(+), 6 deletions(-) create mode 100644 images/media-cover.svg create mode 100644 qml/MprisItem.qml diff --git a/images/dark/media-playback-pause-symbolic.svg b/images/dark/media-playback-pause-symbolic.svg index 3e90132..63c10bf 100644 --- a/images/dark/media-playback-pause-symbolic.svg +++ b/images/dark/media-playback-pause-symbolic.svg @@ -1,4 +1,6 @@ - - + + + + diff --git a/images/dark/media-playback-start-symbolic.svg b/images/dark/media-playback-start-symbolic.svg index 81730c4..d9fd388 100644 --- a/images/dark/media-playback-start-symbolic.svg +++ b/images/dark/media-playback-start-symbolic.svg @@ -1,3 +1,3 @@ - + diff --git a/images/light/media-playback-pause-symbolic.svg b/images/light/media-playback-pause-symbolic.svg index 4290326..7929a93 100644 --- a/images/light/media-playback-pause-symbolic.svg +++ b/images/light/media-playback-pause-symbolic.svg @@ -1,4 +1,6 @@ - - + + + + diff --git a/images/light/media-playback-start-symbolic.svg b/images/light/media-playback-start-symbolic.svg index 8d57c19..551081f 100644 --- a/images/light/media-playback-start-symbolic.svg +++ b/images/light/media-playback-start-symbolic.svg @@ -1,3 +1,3 @@ - + diff --git a/images/media-cover.svg b/images/media-cover.svg new file mode 100644 index 0000000..c4542b5 --- /dev/null +++ b/images/media-cover.svg @@ -0,0 +1,4 @@ + + + + diff --git a/qml.qrc b/qml.qrc index 61c8169..2a18fd1 100644 --- a/qml.qrc +++ b/qml.qrc @@ -104,5 +104,7 @@ images/dark/down.svg images/light/down.svg qml/SystemTray.qml + qml/MprisItem.qml + images/media-cover.svg diff --git a/qml/ControlCenter.qml b/qml/ControlCenter.qml index 074f831..a8321ea 100644 --- a/qml/ControlCenter.qml +++ b/qml/ControlCenter.qml @@ -243,6 +243,11 @@ ControlCenterDialog { } } + MprisItem { + height: 100 + Layout.fillWidth: true + } + Item { id: brightnessItem Layout.fillWidth: true diff --git a/qml/MprisItem.qml b/qml/MprisItem.qml new file mode 100644 index 0000000..cbf8e28 --- /dev/null +++ b/qml/MprisItem.qml @@ -0,0 +1,193 @@ +/* + * Copyright (C) 2021 CutefishOS Team. + * + * Author: Reion Wong + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +import QtQuick 2.12 +import QtQuick.Layouts 1.12 +import QtQuick.Controls 2.12 +import QtGraphicalEffects 1.0 +import FishUI 1.0 as FishUI +import Cutefish.Mpris 1.0 + +Item { + id: control + + property bool available: mprisManager.availableServices.length > 0 + property bool isPlaying: currentService && mprisManager.playbackStatus === Mpris.Playing + property alias currentService: mprisManager.currentService + property var artUrlTag: Mpris.metadataToString(Mpris.ArtUrl) + property var titleTag: Mpris.metadataToString(Mpris.Title) + property var artistTag: Mpris.metadataToString(Mpris.Artist) + + MprisManager { + id: mprisManager + + onCurrentServiceChanged: { + control.updateInfo() + } + + onMetadataChanged: { + control.updateInfo() + } + } + + Component.onCompleted: { control.updateInfo() } + + function updateInfo() { + var titleAvailable = (titleTag in mprisManager.metadata) ? mprisManager.metadata[titleTag].toString() !== "" : false + var artistAvailable = (artistTag in mprisManager.metadata) ? mprisManager.metadata[artistTag].toString() !== "" : false + + control.visible = titleAvailable || artistAvailable + _songLabel.text = titleAvailable ? mprisManager.metadata[titleTag].toString() : "" + _artistLabel.text = artistAvailable ? mprisManager.metadata[artistTag].toString() : "" + artImage.source = (artUrlTag in mprisManager.metadata) ? mprisManager.metadata[artUrlTag].toString() : "" + } + + Rectangle { + anchors.fill: parent + radius: FishUI.Theme.bigRadius + color: FishUI.Theme.darkMode ? Qt.rgba(255, 255, 255, 0.4) + : Qt.rgba(0, 0, 0, 0.1) + opacity: FishUI.Theme.darkMode ? 0.3 : 0.5 + } + + RowLayout { + id: _mainLayout + anchors.fill: parent + anchors.margins: FishUI.Units.largeSpacing + spacing: FishUI.Units.largeSpacing + + Image { + id: defaultImage + width: _mainLayout.height + height: width + source: "qrc:/images/media-cover.svg" + sourceSize: Qt.size(width, height) + visible: !artImage.visible + + layer.enabled: true + layer.effect: OpacityMask { + maskSource: Item { + width: defaultImage.width + height: defaultImage.height + + Rectangle { + anchors.fill: parent + radius: FishUI.Theme.bigRadius + } + } + } + } + + Image { + id: artImage + Layout.preferredHeight: _mainLayout.height + Layout.preferredWidth: _mainLayout.height + visible: status === Image.Ready + // sourceSize: Qt.size(width, height) + fillMode: Image.PreserveAspectFit + + layer.enabled: true + layer.effect: OpacityMask { + maskSource: Item { + width: artImage.width + height: artImage.height + + Rectangle { + anchors.fill: parent + radius: FishUI.Theme.bigRadius + } + } + } + } + + Item { + Layout.fillHeight: true + Layout.fillWidth: true + + ColumnLayout { + anchors.fill: parent + + Item { + Layout.fillHeight: true + } + + Label { + id: _songLabel + Layout.fillWidth: true + visible: _songLabel.text !== "" + elide: Text.ElideRight + } + + Label { + id: _artistLabel + Layout.fillWidth: true + visible: _artistLabel.text !== "" + elide: Text.ElideRight + } + + Item { + Layout.fillHeight: true + } + } + } + + Item { + id: _buttons + Layout.fillHeight: true + Layout.preferredWidth: _buttonsLayout.implicitWidth + + RowLayout { + id: _buttonsLayout + anchors.fill: parent + spacing: FishUI.Units.smallSpacing + + IconButton { + width: 30 + height: 30 + source: "qrc:/images/" + (FishUI.Theme.darkMode ? "dark" : "light") + "/media-skip-backward-symbolic.svg" + onLeftButtonClicked: if (mprisManager.canGoPrevious) mprisManager.previous() + visible: mprisManager.canGoPrevious + Layout.alignment: Qt.AlignRight + } + + IconButton { + width: 30 + height: 30 + source: control.isPlaying ? "qrc:/images/" + (FishUI.Theme.darkMode ? "dark" : "light") + "/media-playback-pause-symbolic.svg" + : "qrc:/images/" + (FishUI.Theme.darkMode ? "dark" : "light") + "/media-playback-start-symbolic.svg" + Layout.alignment: Qt.AlignRight + visible: mprisManager.canPause || mprisManager.canPlay + onLeftButtonClicked: + if ((control.isPlaying && mprisManager.canPause) || (!control.isPlaying && mprisManager.canPlay)) { + mprisManager.playPause() + } + } + + IconButton { + width: 30 + height: 30 + source: "qrc:/images/" + (FishUI.Theme.darkMode ? "dark" : "light") + "/media-skip-forward-symbolic.svg" + Layout.alignment: Qt.AlignRight + visible: mprisManager.canGoNext + onLeftButtonClicked: if (mprisManager.canGoNext) mprisManager.next() + } + } + } + } +}