widgets/mediacontrols: Add expanded mode to change song position

![Enregistrement_d_écran_20240725_000229](/uploads/ffd7a7edf2b079627913d033857ce3fe/Enregistrement_d_écran_20240725_000229.webm)
This commit is contained in:
Florian RICHER 2024-07-26 01:22:04 +00:00 committed by Devin Lin
parent 0b56bf8397
commit b1d75495e2
2 changed files with 84 additions and 24 deletions

View file

@ -37,4 +37,8 @@ QtObject {
function playPause() { function playPause() {
baseMpris2Model.currentPlayer.PlayPause(); baseMpris2Model.currentPlayer.PlayPause();
} }
function updatePosition(): void {
baseMpris2Model.currentPlayer.updatePosition();
}
} }

View file

@ -7,7 +7,7 @@ import QtQuick.Layouts
import QtQuick.Controls as QQC2 import QtQuick.Controls as QQC2
import org.kde.kirigami as Kirigami import org.kde.kirigami as Kirigami
import org.kde.plasma.components 3.0 as PC3
import org.kde.plasma.private.mobileshell as MobileShell import org.kde.plasma.private.mobileshell as MobileShell
import org.kde.plasma.private.mobileshell.state as MobileShellState import org.kde.plasma.private.mobileshell.state as MobileShellState
@ -19,10 +19,20 @@ import org.kde.plasma.private.mpris as Mpris
Item { Item {
id: root id: root
visible: sourceRepeater.count > 0 visible: sourceRepeater.count > 0
property bool detailledView: false
readonly property real heightMultiplier: detailledView ? 2 : 1
readonly property real padding: Kirigami.Units.gridUnit readonly property real padding: Kirigami.Units.gridUnit
readonly property real contentHeight: Kirigami.Units.gridUnit * 2 readonly property real contentHeight: Kirigami.Units.gridUnit * 2 * heightMultiplier
implicitHeight: visible ? padding * 2 + contentHeight : 0 implicitHeight: visible ? padding * 2 + contentHeight : 0
Behavior on implicitHeight {
NumberAnimation {
duration: Kirigami.Units.shortDuration
easing.type: Easing.InOutQuad
}
}
MediaControlsSource { MediaControlsSource {
id: mpris2Source id: mpris2Source
@ -82,16 +92,28 @@ Item {
return decodeURIComponent(lastUrlPart); return decodeURIComponent(lastUrlPart);
} }
function msecToString(duration: int): string {
let seconds = Math.floor(duration / 1000000)
let minutes = Math.floor(seconds / 60)
seconds -= minutes * 60
return `${minutes}:${seconds.toString().padStart(2, '0')}`
}
sourceComponent: MouseArea { sourceComponent: MouseArea {
id: mouseArea id: mouseArea
implicitHeight: playerItem.implicitHeight implicitHeight: playerItem.implicitHeight
implicitWidth: playerItem.implicitWidth implicitWidth: playerItem.implicitWidth
onClicked: { onPressAndHold: {
MobileShell.AppLaunch.launchOrActivateApp(model.desktopEntry + ".desktop"); MobileShell.AppLaunch.launchOrActivateApp(model.desktopEntry + ".desktop");
MobileShellState.ShellDBusClient.closeActionDrawer(); MobileShellState.ShellDBusClient.closeActionDrawer();
} }
onClicked: {
root.detailledView = !root.detailledView
}
MobileShell.BaseItem { MobileShell.BaseItem {
id: playerItem id: playerItem
anchors.fill: parent anchors.fill: parent
@ -105,15 +127,14 @@ Item {
imageSource: model.artUrl imageSource: model.artUrl
} }
contentItem: Item { contentItem: ColumnLayout {
Kirigami.Theme.colorSet: Kirigami.Theme.Complementary Kirigami.Theme.colorSet: Kirigami.Theme.Complementary
Kirigami.Theme.inherit: false Kirigami.Theme.inherit: false
width: playerItem.width - playerItem.leftPadding - playerItem.rightPadding width: playerItem.width - playerItem.leftPadding - playerItem.rightPadding
spacing: Kirigami.Units.largeSpacing
RowLayout { RowLayout {
id: controlsRow id: controlsRow
width: parent.width
height: parent.height
spacing: 0 spacing: 0
enabled: model.canControl enabled: model.canControl
@ -121,7 +142,7 @@ Item {
Image { Image {
id: albumArt id: albumArt
Layout.preferredWidth: height Layout.preferredWidth: height
Layout.fillHeight: true Layout.preferredHeight: controlsRow.height
asynchronous: true asynchronous: true
fillMode: Image.PreserveAspectFit fillMode: Image.PreserveAspectFit
source: model.artUrl source: model.artUrl
@ -131,6 +152,7 @@ Item {
ColumnLayout { ColumnLayout {
Layout.leftMargin: albumArt.visible ? Kirigami.Units.gridUnit : 0 Layout.leftMargin: albumArt.visible ? Kirigami.Units.gridUnit : 0
Layout.rightMargin: Kirigami.Units.largeSpacing
Layout.fillWidth: true Layout.fillWidth: true
spacing: Kirigami.Units.smallSpacing spacing: Kirigami.Units.smallSpacing
@ -160,13 +182,11 @@ Item {
} }
QQC2.ToolButton { QQC2.ToolButton {
Layout.fillHeight: true
Layout.preferredWidth: height
enabled: model.canGoPrevious enabled: model.canGoPrevious
icon.name: LayoutMirroring.enabled ? "media-skip-forward" : "media-skip-backward" icon.name: LayoutMirroring.enabled ? "media-skip-forward" : "media-skip-backward"
icon.width: Kirigami.Units.iconSizes.small icon.width: Kirigami.Units.iconSizes.smallMedium
icon.height: Kirigami.Units.iconSizes.small icon.height: Kirigami.Units.iconSizes.smallMedium
icon.color: "white"
onClicked: { onClicked: {
mpris2Source.setIndex(model.index); mpris2Source.setIndex(model.index);
mpris2Source.goPrevious(); mpris2Source.goPrevious();
@ -176,12 +196,10 @@ Item {
} }
QQC2.ToolButton { QQC2.ToolButton {
Layout.fillHeight: true
Layout.preferredWidth: height
icon.name: (model.playbackStatus === Mpris.PlaybackStatus.Playing) ? "media-playback-pause" : "media-playback-start" icon.name: (model.playbackStatus === Mpris.PlaybackStatus.Playing) ? "media-playback-pause" : "media-playback-start"
icon.width: Kirigami.Units.iconSizes.small icon.width: Kirigami.Units.iconSizes.smallMedium
icon.height: Kirigami.Units.iconSizes.small icon.height: Kirigami.Units.iconSizes.smallMedium
icon.color: "white"
onClicked: { onClicked: {
mpris2Source.setIndex(model.index); mpris2Source.setIndex(model.index);
mpris2Source.playPause(); mpris2Source.playPause();
@ -190,13 +208,11 @@ Item {
} }
QQC2.ToolButton { QQC2.ToolButton {
Layout.fillHeight: true
Layout.preferredWidth: height
enabled: model.canGoNext enabled: model.canGoNext
icon.name: LayoutMirroring.enabled ? "media-skip-backward" : "media-skip-forward" icon.name: LayoutMirroring.enabled ? "media-skip-backward" : "media-skip-forward"
icon.width: Kirigami.Units.iconSizes.small icon.width: Kirigami.Units.iconSizes.smallMedium
icon.height: Kirigami.Units.iconSizes.small icon.height: Kirigami.Units.iconSizes.smallMedium
icon.color: "white"
onClicked: { onClicked: {
mpris2Source.setIndex(model.index); mpris2Source.setIndex(model.index);
mpris2Source.goNext(); mpris2Source.goNext();
@ -205,6 +221,46 @@ Item {
Accessible.name: i18nd("plasma_lookandfeel_org.kde.lookandfeel", "Next track") Accessible.name: i18nd("plasma_lookandfeel_org.kde.lookandfeel", "Next track")
} }
} }
RowLayout {
id: timerControlsRow
spacing: Kirigami.Units.largeSpacing
visible: root.detailledView
Text {
text: msecToString(model.position)
font.pointSize: Kirigami.Theme.defaultFont.pointSize * 0.9
color: "white"
}
PC3.Slider {
Layout.fillWidth: true
from: 0
value: model.position
to: model.length
onMoved: model.position = value
Timer {
interval: 1000; running: true; repeat: true
onTriggered: {
mpris2Source.setIndex(model.index);
mpris2Source.updatePosition()
}
}
}
Text {
text: msecToString(model.length)
font.pointSize: Kirigami.Theme.defaultFont.pointSize * 0.9
color: "white"
}
}
} }
} }
} }