MediaCard: Player selector

This commit is contained in:
quadbyte 2025-08-13 18:26:07 -04:00
parent d4eff97566
commit 484d38a096

View file

@ -1,4 +1,5 @@
import QtQuick import QtQuick
import QtQuick.Controls
import QtQuick.Layouts import QtQuick.Layouts
import qs.Services import qs.Services
import qs.Widgets import qs.Widgets
@ -51,6 +52,90 @@ NBox {
visible: MediaPlayer.currentPlayer visible: MediaPlayer.currentPlayer
spacing: Style.marginMedium * scaling spacing: Style.marginMedium * scaling
// Player selector
ComboBox {
id: playerSelector
Layout.fillWidth: true
Layout.preferredHeight: 30 * scaling
visible: MediaPlayer.getAvailablePlayers().length > 1
model: MediaPlayer.getAvailablePlayers()
textRole: "identity"
currentIndex: MediaPlayer.selectedPlayerIndex
background: Rectangle {
// implicitWidth: 120 * scaling
// implicitHeight: 30 * scaling
color: "transparent"
border.color: playerSelector.activeFocus ? Colors.hover : Colors.outline
border.width: Math.max(1, Style.borderThin * scaling)
radius: Style.radiusMedium * scaling
}
contentItem: NText {
leftPadding: Style.marginMedium * scaling
rightPadding: playerSelector.indicator.width + playerSelector.spacing
text: playerSelector.displayText
font.pointSize: Style.fontSizeSmall * scaling
color: Colors.textPrimary
verticalAlignment: Text.AlignVCenter
elide: Text.ElideRight
}
indicator: Text {
x: playerSelector.width - width - Style.marginMedium * scaling
y: playerSelector.topPadding + (playerSelector.availableHeight - height) / 2
text: "arrow_drop_down"
font.family: "Material Symbols Outlined"
font.pointSize: Style.marginXL * scaling
color: Colors.textPrimary
}
popup: Popup {
y: playerSelector.height
width: playerSelector.width
implicitHeight: Math.min(160 * scaling, contentItem.implicitHeight + Style.marginMedium * scaling * 2)
padding: Style.marginSmall * scaling
contentItem: ListView {
clip: true
implicitHeight: contentHeight
model: playerSelector.popup.visible ? playerSelector.delegateModel : null
currentIndex: playerSelector.highlightedIndex
ScrollIndicator.vertical: ScrollIndicator {}
}
background: Rectangle {
color: Colors.backgroundSecondary
border.color: Colors.outline
border.width: Math.max(1, Style.borderThin * scaling)
radius: Style.radiusMedium * scaling
}
}
delegate: ItemDelegate {
width: playerSelector.width
contentItem: NText {
text: modelData.identity
font.pointSize: Style.fontSizeSmall * scaling
color: highlighted ? Colors.backgroundPrimary : Colors.textPrimary
verticalAlignment: Text.AlignVCenter
elide: Text.ElideRight
}
highlighted: playerSelector.highlightedIndex === index
background: Rectangle {
width: playerSelector.width - Style.marginSmall * scaling * 2
color: highlighted ? Colors.hover : "transparent"
radius: Style.radiusSmall * scaling
}
}
onActivated: {
MediaPlayer.selectedPlayerIndex = currentIndex
MediaPlayer.updateCurrentPlayer()
}
}
RowLayout { RowLayout {
spacing: Style.marginMedium * scaling spacing: Style.marginMedium * scaling
@ -229,7 +314,6 @@ NBox {
} }
} }
} // import QtQuick// import QtQuick.Controls// import QtQuick.Layouts// import QtQuick.Effects// import qs.Settings// import qs.Components// import qs.Services } // import QtQuick// import QtQuick.Controls// import QtQuick.Layouts// import QtQuick.Effects// import qs.Settings// import qs.Components// import qs.Services
// Rectangle { // Rectangle {
// id: musicCard // id: musicCard
// color: "transparent" // color: "transparent"
@ -244,7 +328,7 @@ NBox {
// Item { // Item {
// width: parent.width // width: parent.width
// height: parent.height // height: parent.height
// visible: !MusicManager.currentPlayer // visible: !MediaPlayer.currentPlayer
// ColumnLayout { // ColumnLayout {
// anchors.centerIn: parent // anchors.centerIn: parent
@ -259,7 +343,7 @@ NBox {
// } // }
// Text { // Text {
// text: MusicManager.hasPlayer ? "No controllable player selected" : "No music player detected" // text: MediaPlayer.hasPlayer ? "No controllable player selected" : "No music player detected"
// color: Qt.rgba(Theme.textPrimary.r, Theme.textPrimary.g, Theme.textPrimary.b, 0.6) // color: Qt.rgba(Theme.textPrimary.r, Theme.textPrimary.g, Theme.textPrimary.b, 0.6)
// font.family: Theme.fontFamily // font.family: Theme.fontFamily
// font.pixelSize: Theme.fontSizeSmall * scaling // font.pixelSize: Theme.fontSizeSmall * scaling
@ -273,17 +357,17 @@ NBox {
// anchors.fill: parent // anchors.fill: parent
// anchors.margins: 18 * scaling // anchors.margins: 18 * scaling
// spacing: 12 * scaling // spacing: 12 * scaling
// visible: !!MusicManager.currentPlayer // visible: !!MediaPlayer.currentPlayer
// // Player selector // // Player selector
// ComboBox { // ComboBox {
// id: playerSelector // id: playerSelector
// Layout.fillWidth: true // Layout.fillWidth: true
// Layout.preferredHeight: 40 * scaling // Layout.preferredHeight: 40 * scaling
// visible: MusicManager.getAvailablePlayers().length > 1 // visible: MediaPlayer.getAvailablePlayers().length > 1
// model: MusicManager.getAvailablePlayers() // model: MediaPlayer.getAvailablePlayers()
// textRole: "identity" // textRole: "identity"
// currentIndex: MusicManager.selectedPlayerIndex // currentIndex: MediaPlayer.selectedPlayerIndex
// background: Rectangle { // background: Rectangle {
// implicitWidth: 120 * scaling // implicitWidth: 120 * scaling
@ -353,8 +437,8 @@ NBox {
// } // }
// onActivated: { // onActivated: {
// MusicManager.selectedPlayerIndex = index; // MediaPlayer.selectedPlayerIndex = index;
// MusicManager.updateCurrentPlayer(); // MediaPlayer.updateCurrentPlayer();
// } // }
// } // }
@ -373,7 +457,7 @@ NBox {
// // Circular spectrum visualizer around album art // // Circular spectrum visualizer around album art
// CircularSpectrum { // CircularSpectrum {
// id: spectrum // id: spectrum
// values: MusicManager.cavaValues // values: MediaPlayer.cavaValues
// anchors.centerIn: parent // anchors.centerIn: parent
// innerRadius: 30 * scaling // Position just outside 60x60 album art // innerRadius: 30 * scaling // Position just outside 60x60 album art
// outerRadius: 48 * scaling // Extend bars outward from album art // outerRadius: 48 * scaling // Extend bars outward from album art
@ -405,7 +489,7 @@ NBox {
// asynchronous: true // asynchronous: true
// sourceSize.width: 60 * scaling // sourceSize.width: 60 * scaling
// sourceSize.height: 60 * scaling // sourceSize.height: 60 * scaling
// source: MusicManager.trackArtUrl // source: MediaPlayer.trackArtUrl
// visible: source.toString() !== "" // visible: source.toString() !== ""
// // Apply circular mask for rounded corners // // Apply circular mask for rounded corners
@ -452,10 +536,10 @@ NBox {
// Layout.fillWidth: true // Layout.fillWidth: true
// property real progressRatio: { // property real progressRatio: {
// if (!MusicManager.currentPlayer || !MusicManager.isPlaying || MusicManager.trackLength <= 0) { // if (!MediaPlayer.currentPlayer || !MediaPlayer.isPlaying || MediaPlayer.trackLength <= 0) {
// return 0; // return 0;
// } // }
// return Math.min(1, MusicManager.currentPosition / MusicManager.trackLength); // return Math.min(1, MediaPlayer.currentPosition / MediaPlayer.trackLength);
// } // }
// Rectangle { // Rectangle {
@ -485,7 +569,7 @@ NBox {
// x: Math.max(0, Math.min(parent.width - width, progressFill.width - width / 2)) // x: Math.max(0, Math.min(parent.width - width, progressFill.width - width / 2))
// anchors.verticalCenter: parent.verticalCenter // anchors.verticalCenter: parent.verticalCenter
// visible: MusicManager.trackLength > 0 // visible: MediaPlayer.trackLength > 0
// scale: progressMouseArea.containsMouse || progressMouseArea.pressed ? 1.2 : 1.0 // scale: progressMouseArea.containsMouse || progressMouseArea.pressed ? 1.2 : 1.0
// Behavior on scale { // Behavior on scale {
@ -501,17 +585,17 @@ NBox {
// anchors.fill: parent // anchors.fill: parent
// hoverEnabled: true // hoverEnabled: true
// cursorShape: Qt.PointingHandCursor // cursorShape: Qt.PointingHandCursor
// enabled: MusicManager.trackLength > 0 && MusicManager.canSeek // enabled: MediaPlayer.trackLength > 0 && MediaPlayer.canSeek
// onClicked: function (mouse) { // onClicked: function (mouse) {
// let ratio = mouse.x / width; // let ratio = mouse.x / width;
// MusicManager.seekByRatio(ratio); // MediaPlayer.seekByRatio(ratio);
// } // }
// onPositionChanged: function (mouse) { // onPositionChanged: function (mouse) {
// if (pressed) { // if (pressed) {
// let ratio = Math.max(0, Math.min(1, mouse.x / width)); // let ratio = Math.max(0, Math.min(1, mouse.x / width));
// MusicManager.seekByRatio(ratio); // MediaPlayer.seekByRatio(ratio);
// } // }
// } // }
// } // }
@ -537,8 +621,8 @@ NBox {
// anchors.fill: parent // anchors.fill: parent
// hoverEnabled: true // hoverEnabled: true
// cursorShape: Qt.PointingHandCursor // cursorShape: Qt.PointingHandCursor
// enabled: MusicManager.canGoPrevious // enabled: MediaPlayer.canGoPrevious
// onClicked: MusicManager.previous() // onClicked: MediaPlayer.previous()
// } // }
// Text { // Text {
@ -564,13 +648,13 @@ NBox {
// anchors.fill: parent // anchors.fill: parent
// hoverEnabled: true // hoverEnabled: true
// cursorShape: Qt.PointingHandCursor // cursorShape: Qt.PointingHandCursor
// enabled: MusicManager.canPlay || MusicManager.canPause // enabled: MediaPlayer.canPlay || MediaPlayer.canPause
// onClicked: MusicManager.playPause() // onClicked: MediaPlayer.playPause()
// } // }
// Text { // Text {
// anchors.centerIn: parent // anchors.centerIn: parent
// text: MusicManager.isPlaying ? "pause" : "play_arrow" // text: MediaPlayer.isPlaying ? "pause" : "play_arrow"
// font.family: "Material Symbols Outlined" // font.family: "Material Symbols Outlined"
// font.pixelSize: Theme.fontSizeBody * scaling // font.pixelSize: Theme.fontSizeBody * scaling
// color: playButton.enabled ? Theme.accentPrimary : Qt.rgba(Theme.textPrimary.r, Theme.textPrimary.g, Theme.textPrimary.b, 0.3) // color: playButton.enabled ? Theme.accentPrimary : Qt.rgba(Theme.textPrimary.r, Theme.textPrimary.g, Theme.textPrimary.b, 0.3)
@ -591,8 +675,8 @@ NBox {
// anchors.fill: parent // anchors.fill: parent
// hoverEnabled: true // hoverEnabled: true
// cursorShape: Qt.PointingHandCursor // cursorShape: Qt.PointingHandCursor
// enabled: MusicManager.canGoNext // enabled: MediaPlayer.canGoNext
// onClicked: MusicManager.next() // onClicked: MediaPlayer.next()
// } // }
// Text { // Text {