From a0f6d1433435d2050d52593f31e974c5217c6146 Mon Sep 17 00:00:00 2001 From: Ly-sec Date: Tue, 30 Sep 2025 18:37:45 +0200 Subject: [PATCH] MediaMini: add no active player placeholder --- Assets/Translations/de.json | 3 +- Assets/Translations/en.json | 3 +- Assets/Translations/es.json | 3 +- Assets/Translations/fr.json | 3 +- Assets/Translations/pt.json | 3 +- Assets/Translations/zh-CN.json | 3 +- Modules/Bar/Widgets/MediaMini.qml | 47 ++++++++++++++++++------------- 7 files changed, 40 insertions(+), 25 deletions(-) diff --git a/Assets/Translations/de.json b/Assets/Translations/de.json index 0205cfe8..c81f4eb8 100644 --- a/Assets/Translations/de.json +++ b/Assets/Translations/de.json @@ -987,7 +987,8 @@ "scrolling-mode": { "label": "Scrollmodus", "description": "Steuern, wann Textscrolling für lange Track-Titel aktiviert ist." - } + }, + "no-active-player": "Kein aktiver Player" }, "clock": { "use-primary-color": { diff --git a/Assets/Translations/en.json b/Assets/Translations/en.json index 8d688282..4d307af2 100644 --- a/Assets/Translations/en.json +++ b/Assets/Translations/en.json @@ -979,7 +979,8 @@ "scrolling-mode": { "label": "Scrolling mode", "description": "Control when text scrolling is enabled for long track titles." - } + }, + "no-active-player": "No active player" }, "clock": { "use-primary-color": { diff --git a/Assets/Translations/es.json b/Assets/Translations/es.json index 485879f3..22e39288 100644 --- a/Assets/Translations/es.json +++ b/Assets/Translations/es.json @@ -968,7 +968,8 @@ "scrolling-mode": { "label": "Modo de desplazamiento", "description": "Controlar cuándo está habilitado el desplazamiento de texto para títulos de pista largos." - } + }, + "no-active-player": "Sin reproductor activo" }, "clock": { "use-primary-color": { diff --git a/Assets/Translations/fr.json b/Assets/Translations/fr.json index 32644792..3e7bbcfb 100644 --- a/Assets/Translations/fr.json +++ b/Assets/Translations/fr.json @@ -968,7 +968,8 @@ "auto-hide": { "label": "Masquer automatiquement", "description": "Masquer automatiquement le widget quand aucun média n'est en cours de lecture." - } + }, + "no-active-player": "Aucun lecteur actif" }, "clock": { "use-primary-color": { diff --git a/Assets/Translations/pt.json b/Assets/Translations/pt.json index 7f41cb46..068f5d04 100644 --- a/Assets/Translations/pt.json +++ b/Assets/Translations/pt.json @@ -968,7 +968,8 @@ "scrolling-mode": { "label": "Modo de rolagem", "description": "Controlar quando a rolagem de texto está habilitada para títulos de faixa longos." - } + }, + "no-active-player": "Nenhum player ativo" }, "clock": { "use-primary-color": { diff --git a/Assets/Translations/zh-CN.json b/Assets/Translations/zh-CN.json index 9c854954..562e4cda 100644 --- a/Assets/Translations/zh-CN.json +++ b/Assets/Translations/zh-CN.json @@ -977,7 +977,8 @@ "scrolling-mode": { "label": "滚动模式", "description": "控制何时为长曲目标题启用文本滚动。" - } + }, + "no-active-player": "无活动播放器" }, "clock": { "use-primary-color": { diff --git a/Modules/Bar/Widgets/MediaMini.qml b/Modules/Bar/Widgets/MediaMini.qml index f1a32669..a65e99d1 100644 --- a/Modules/Bar/Widgets/MediaMini.qml +++ b/Modules/Bar/Widgets/MediaMini.qml @@ -42,6 +42,9 @@ Item { // Fixed width - no expansion readonly property real widgetWidth: Math.max(1, screen.width * 0.06) + readonly property bool hasActivePlayer: MediaService.currentPlayer !== null && getTitle() !== "" + readonly property string placeholderText: I18n.tr("bar.widget-settings.media-mini.no-active-player") + readonly property string tooltipText: { var title = getTitle() var controls = "" @@ -60,7 +63,7 @@ Item { implicitHeight: visible ? ((barPosition === "left" || barPosition === "right") ? calculatedVerticalHeight() : Math.round(Style.barHeight * scaling)) : 0 implicitWidth: visible ? ((barPosition === "left" || barPosition === "right") ? Math.round(Style.baseWidgetSize * 0.8 * scaling) : (widgetWidth * scaling)) : 0 - opacity: !autoHide || getTitle() !== "" ? 1.0 : 0 + opacity: !autoHide || hasActivePlayer || (!hasActivePlayer && !autoHide) ? 1.0 : 0 Behavior on opacity { NumberAnimation { duration: Style.animationNormal @@ -151,21 +154,21 @@ Item { anchors.verticalCenter: parent.verticalCenter spacing: Style.marginS * scaling - visible: (barPosition === "top" || barPosition === "bottom") && getTitle() !== "" + visible: (barPosition === "top" || barPosition === "bottom") z: 1 // Above the visualizer NIcon { id: windowIcon - icon: MediaService.isPlaying ? "media-pause" : "media-play" + icon: hasActivePlayer ? (MediaService.isPlaying ? "media-pause" : "media-play") : "music-off" pointSize: Style.fontSizeL * scaling verticalAlignment: Text.AlignVCenter Layout.alignment: Qt.AlignVCenter - visible: !showAlbumArt && getTitle() !== "" && !trackArt.visible + visible: !showAlbumArt && !trackArt.visible } ColumnLayout { Layout.alignment: Qt.AlignVCenter - visible: showAlbumArt + visible: showAlbumArt && hasActivePlayer spacing: 0 Item { @@ -187,6 +190,10 @@ Item { Item { id: titleContainer Layout.preferredWidth: { + if (!hasActivePlayer) { + // When no active player, take full width to center the placeholder + return mainContainer.width - Style.marginXXS * scaling * 2 + } // Calculate available width based on other elements in the row var iconWidth = (windowIcon.visible ? (Style.fontSizeL * scaling + Style.marginS * scaling) : 0) var albumArtWidth = (showAlbumArt ? (18 * scaling + Style.marginS * scaling) : 0) @@ -195,7 +202,7 @@ Item { return Math.max(20 * scaling, availableWidth) } Layout.maximumWidth: Layout.preferredWidth - Layout.alignment: Qt.AlignVCenter + Layout.alignment: hasActivePlayer ? Qt.AlignVCenter : Qt.AlignCenter Layout.preferredHeight: titleText.height clip: true @@ -264,29 +271,31 @@ Item { Item { id: scrollContainer height: parent.height - width: childrenRect.width + width: hasActivePlayer ? childrenRect.width : parent.width property real scrollX: 0 - x: scrollX + x: hasActivePlayer ? scrollX : 0 RowLayout { spacing: 50 * scaling // Gap between text copies NText { id: titleText - text: getTitle() + text: hasActivePlayer ? getTitle() : placeholderText pointSize: Style.fontSizeS * scaling font.weight: Style.fontWeightMedium verticalAlignment: Text.AlignVCenter - color: Color.mOnSurface + horizontalAlignment: hasActivePlayer ? Text.AlignLeft : Text.AlignHCenter + color: hasActivePlayer ? Color.mOnSurface : Color.mOnSurfaceVariant } NText { - text: getTitle() + text: hasActivePlayer ? getTitle() : placeholderText font: titleText.font verticalAlignment: Text.AlignVCenter - color: Color.mOnSurface - visible: titleContainer.needsScrolling && titleContainer.isScrolling + horizontalAlignment: hasActivePlayer ? Text.AlignLeft : Text.AlignHCenter + color: hasActivePlayer ? Color.mOnSurface : Color.mOnSurfaceVariant + visible: hasActivePlayer && titleContainer.needsScrolling && titleContainer.isScrolling } } @@ -336,12 +345,11 @@ Item { width: Style.baseWidgetSize * 0.5 * scaling height: Style.baseWidgetSize * 0.5 * scaling anchors.centerIn: parent - visible: getTitle() !== "" NIcon { id: mediaIconVertical anchors.fill: parent - icon: MediaService.isPlaying ? "media-pause" : "media-play" + icon: hasActivePlayer ? (MediaService.isPlaying ? "media-pause" : "media-play") : "music-off" pointSize: Style.fontSizeL * scaling verticalAlignment: Text.AlignVCenter horizontalAlignment: Text.AlignHCenter @@ -354,10 +362,10 @@ Item { id: mouseArea anchors.fill: parent hoverEnabled: true - cursorShape: Qt.PointingHandCursor + cursorShape: hasActivePlayer ? Qt.PointingHandCursor : Qt.ArrowCursor acceptedButtons: Qt.LeftButton | Qt.RightButton | Qt.MiddleButton onClicked: mouse => { - if (!MediaService.currentPlayer || !MediaService.canPlay) { + if (!hasActivePlayer || !MediaService.currentPlayer || !MediaService.canPlay) { return } @@ -375,8 +383,9 @@ Item { } onEntered: { - if ((tooltipText !== "") && (barPosition === "left" || barPosition === "right") || (scrollingMode === "never")) { - TooltipService.show(root, tooltipText, BarService.getTooltipDirection()) + var textToShow = hasActivePlayer ? tooltipText : placeholderText + if ((textToShow !== "") && (barPosition === "left" || barPosition === "right") || (scrollingMode === "never")) { + TooltipService.show(root, textToShow, BarService.getTooltipDirection()) } } onExited: {