quickshell/modules/wallpaper/PlayerWidget.qml

219 lines
8.6 KiB
QML

pragma ComponentBehavior: Bound
import Quickshell.Services.Mpris
import Quickshell.Widgets
import QtQuick
import Qt5Compat.GraphicalEffects
import QtQuick.Layouts
import QtQuick.Controls
import qs
import qs.settings
import qs.widgets
Rectangle {
id: root
color: Colors.base00
radius: Settings.config.rounding
implicitWidth: 600
implicitHeight: 200
visible: getSpotify() != null
layer {
enabled: true
effect: DropShadow {
color: "#111111"
horizontalOffset: 7
verticalOffset: 8
radius: 12
samples: 14
}
}
MouseArea {
id: hoverDetect
hoverEnabled: true
anchors.fill: parent
onExited: title.x = 0
}
function getSpotify() {
for (var i = 0; i < Mpris.players.values.length; i++) {
if (Mpris.players.values[i].identity == "Spotify" || Mpris.players.values[i] == "spotify") {
return Mpris.players.values[i];
} else {
return null;
}
}
return null;
}
property var spotify: getSpotify() != null ? getSpotify() : null
property var title: getSpotify() != null ? getSpotify().trackTitle : ""
property var album: getSpotify() != null ? getSpotify().trackAlbum : ""
property var art: getSpotify() != null ? getSpotify().trackArtUrl : ""
property var artist: getSpotify() != null ? getSpotify().trackArtist : ""
ClippingWrapperRectangle {
id: songWrapper
radius: Settings.config.rounding / 1.5
anchors.margins: 8
margin: 0
anchors.fill: parent
color: Colors.base00
RowLayout {
id: songLayout
spacing: 10
ClippingWrapperRectangle {
id: coverRounder
Layout.fillWidth: true
Layout.fillHeight: true
Layout.maximumWidth: songCover.sourceSize.width
radius: Settings.config.rounding / 1.5
Image {
id: songCover
source: root.art
sourceSize {
width: 180
height: 180
}
}
}
WrapperRectangle {
color: Colors.base01
Layout.fillWidth: true
Layout.fillHeight: true
Layout.alignment: Qt.AlignTop
radius: Settings.config.rounding / 1.5
margin: 20
child: ColumnLayout {
id: songInfo
Layout.alignment: Qt.AlignTop
Layout.fillWidth: true
Layout.fillHeight: true
Layout.leftMargin: 20
Layout.topMargin: 2
Item {
id: titleContainer
Layout.fillWidth: true
x: 0
implicitHeight: title.implicitHeight
clip: true // Keeps the text inside this "window"
CText {
id: title
Layout.maximumWidth: 300
text: root.title
font.pixelSize: 30
SequentialAnimation on x {
id: scrollAnimation
running: hoverDetect.containsMouse && title.width > titleContainer.width
loops: Animation.Infinite
// Scroll to the end
NumberAnimation {
to: titleContainer.width - title.width
duration: Math.max(2000, (title.width - titleContainer.width) * 30)
easing.type: Easing.InOutQuad
}
// Scroll back to the start
NumberAnimation {
to: 0
duration: Math.max(2000, (title.width - titleContainer.width) * 30)
easing.type: Easing.InOutQuad
}
}
}
}
CText {
id: album
text: root.album + " - " + root.artist
opacity: 0.6
Layout.maximumWidth: 250
Layout.alignment: Qt.AlignTop
elide: Text.ElideRight
}
ProgressBar {
id: songProgress
FrameAnimation {
// only emit the signal when the position is actually changing.
running: root.spotify ? root.spotify.playbackState == MprisPlaybackState.Playing || root.visible : false
// emit the positionChanged signal every frame.
onTriggered: root.spotify.positionChanged()
}
implicitWidth: 200
implicitHeight: 10
from: 0
to: root.spotify != null ? root.spotify.length : 0
value: root.spotify != null ? root.spotify.position : 0
background: Rectangle {
implicitWidth: 200
implicitHeight: 6
color: Colors.base02
radius: Settings.config.rounding
}
contentItem: Item {
implicitWidth: 200
implicitHeight: 4
// Progress indicator for determinate state.
Rectangle {
width: songProgress.visualPosition * parent.width
height: parent.height
radius: Settings.config.rounding
color: Colors.base07
visible: !songProgress.indeterminate
}
}
}
RowLayout {
id: playerControls
Layout.maximumWidth: 200
CIcon {
id: previous
text: "\ue045"
Layout.alignment: Qt.AlignLeft
MouseArea {
id: prevHandler
anchors.fill: parent
acceptedButtons: Qt.LeftButton
cursorShape: Qt.PointingHandCursor
onClicked: {
root.spotify.previous();
title.x = 0;
}
}
}
CIcon {
id: pause
text: root.spotify ? root.spotify.isPlaying ? "\ue034" : "\ue037" : ""
Layout.alignment: Qt.AlignHCenter
MouseArea {
id: pauseHandler
anchors.fill: parent
acceptedButtons: Qt.LeftButton
cursorShape: Qt.PointingHandCursor
onClicked: {
root.spotify.togglePlaying();
title.x = 0;
}
}
}
CIcon {
id: next
Layout.alignment: Qt.AlignRight
text: "\ue044"
MouseArea {
id: nextHandler
anchors.fill: parent
acceptedButtons: Qt.LeftButton
cursorShape: Qt.PointingHandCursor
onClicked: {
root.spotify.next();
title.x = 0;
}
}
}
}
}
}
}
}
}