From 2123b55aab2926637c999b4e8287fae763213417 Mon Sep 17 00:00:00 2001 From: Ly-sec Date: Thu, 25 Sep 2025 01:37:17 +0200 Subject: [PATCH] MediaMini: small fixes --- Assets/Translations/de.json | 8 +- Assets/Translations/en.json | 8 +- Assets/Translations/es.json | 8 +- Assets/Translations/fr.json | 8 +- Assets/Translations/pt.json | 3 +- Assets/settings-default.json | 6 +- Commons/Settings.qml | 6 +- Modules/Bar/Widgets/MediaMini.qml | 95 ++++++++----------- .../Bar/WidgetSettings/MediaMiniSettings.qml | 19 ++++ Modules/Settings/Tabs/AudioTab.qml | 21 ---- Services/BarWidgetRegistry.qml | 3 +- 11 files changed, 98 insertions(+), 87 deletions(-) diff --git a/Assets/Translations/de.json b/Assets/Translations/de.json index 8432af14..e6dade8b 100644 --- a/Assets/Translations/de.json +++ b/Assets/Translations/de.json @@ -851,7 +851,8 @@ "media-mini": { "show-album-art": "Albumcover anzeigen", "show-visualizer": "Visualizer anzeigen", - "visualizer-type": "Visualizer-Typ" + "visualizer-type": "Visualizer-Typ", + "scrolling-mode": "Scrollmodus" }, "clock": { "use-primary-color": { @@ -1068,6 +1069,11 @@ "mirrored": "Gespiegelt", "wave": "Welle" }, + "scrolling-modes": { + "always": "Immer Scrollen", + "hover": "Beim Hover Scrollen", + "never": "Nie Scrollen" + }, "screen-recording": { "sources": { diff --git a/Assets/Translations/en.json b/Assets/Translations/en.json index b2ae51d3..ef74507f 100644 --- a/Assets/Translations/en.json +++ b/Assets/Translations/en.json @@ -863,7 +863,8 @@ "media-mini": { "show-album-art": "Show album art", "show-visualizer": "Show visualizer", - "visualizer-type": "Visualizer type" + "visualizer-type": "Visualizer type", + "scrolling-mode": "Scrolling mode" }, "clock": { "use-primary-color": { @@ -1080,6 +1081,11 @@ "mirrored": "Mirrored", "wave": "Wave" }, + "scrolling-modes": { + "always": "Scroll Always", + "hover": "Scroll On Hover", + "never": "Never Scroll" + }, "screen-recording": { "sources": { diff --git a/Assets/Translations/es.json b/Assets/Translations/es.json index f9a3f742..c4815655 100644 --- a/Assets/Translations/es.json +++ b/Assets/Translations/es.json @@ -861,7 +861,8 @@ "media-mini": { "show-album-art": "Mostrar carátula del álbum", "show-visualizer": "Mostrar visualizador", - "visualizer-type": "Tipo de visualizador" + "visualizer-type": "Tipo de visualizador", + "scrolling-mode": "Modo de desplazamiento" }, "clock": { "use-primary-color": { @@ -1077,6 +1078,11 @@ "mirrored": "Espejado", "wave": "Onda" }, + "scrolling-modes": { + "always": "Desplazar Siempre", + "hover": "Desplazar al Pasar", + "never": "Nunca Desplazar" + }, "screen-recording": { "sources": { "portal": "Portal", diff --git a/Assets/Translations/fr.json b/Assets/Translations/fr.json index cdb38c08..5518b162 100644 --- a/Assets/Translations/fr.json +++ b/Assets/Translations/fr.json @@ -859,7 +859,8 @@ "media-mini": { "show-album-art": "Afficher la pochette de l'album", "show-visualizer": "Afficher le visualiseur", - "visualizer-type": "Type de visualiseur" + "visualizer-type": "Type de visualiseur", + "scrolling-mode": "Mode de défilement" }, "clock": { "use-primary-color": { @@ -1077,6 +1078,11 @@ "mirrored": "Miroir", "wave": "Vague" }, + "scrolling-modes": { + "always": "Défiler Toujours", + "hover": "Défiler au Survol", + "never": "Ne Jamais Défiler" + }, "frame-rates": { "30-fps": "30 FPS", "60-fps": "60 FPS", diff --git a/Assets/Translations/pt.json b/Assets/Translations/pt.json index 6cd104f8..4a2fe80f 100644 --- a/Assets/Translations/pt.json +++ b/Assets/Translations/pt.json @@ -861,7 +861,8 @@ "media-mini": { "show-album-art": "Mostrar arte do álbum", "show-visualizer": "Mostrar visualizador", - "visualizer-type": "Tipo de visualizador" + "visualizer-type": "Tipo de visualizador", + "scrolling-mode": "Modo de rolagem" }, "clock": { "use-primary-color": { diff --git a/Assets/settings-default.json b/Assets/settings-default.json index ab2ae437..e6f1296e 100644 --- a/Assets/settings-default.json +++ b/Assets/settings-default.json @@ -1,5 +1,5 @@ { - "settingsVersion": 5, + "settingsVersion": 6, "bar": { "position": "top", "backgroundOpacity": 1, @@ -141,7 +141,7 @@ "cavaFrameRate": 60, "visualizerType": "linear", "mprisBlacklist": [], - "preferredPlayer": "", + "preferredPlayer": "" }, "ui": { "fontDefault": "Roboto", @@ -185,4 +185,4 @@ "wallpaperChange": "", "darkModeChange": "" } -} +} \ No newline at end of file diff --git a/Commons/Settings.qml b/Commons/Settings.qml index 5f453354..e45489b0 100644 --- a/Commons/Settings.qml +++ b/Commons/Settings.qml @@ -54,7 +54,7 @@ Singleton { // Then it should be commented out again, regular users don't need to generate // default settings on every start // TODO: automate this someday! - // generateDefaultSettings() + //generateDefaultSettings() // Patch-in the local default, resolved to user's home adapter.general.avatarImage = defaultAvatar @@ -114,7 +114,7 @@ Singleton { JsonAdapter { id: adapter - property int settingsVersion: 5 + property int settingsVersion: 6 // bar property JsonObject bar: JsonObject { @@ -266,8 +266,6 @@ Singleton { property string visualizerType: "linear" property list mprisBlacklist: [] property string preferredPlayer: "" - property bool scrollingTitle: false - property int scrollingSpeed: 18 } // ui diff --git a/Modules/Bar/Widgets/MediaMini.qml b/Modules/Bar/Widgets/MediaMini.qml index 52e235e9..1ebb4b75 100644 --- a/Modules/Bar/Widgets/MediaMini.qml +++ b/Modules/Bar/Widgets/MediaMini.qml @@ -36,12 +36,10 @@ Item { readonly property bool showAlbumArt: (widgetSettings.showAlbumArt !== undefined) ? widgetSettings.showAlbumArt : widgetMetadata.showAlbumArt readonly property bool showVisualizer: (widgetSettings.showVisualizer !== undefined) ? widgetSettings.showVisualizer : widgetMetadata.showVisualizer readonly property string visualizerType: (widgetSettings.visualizerType !== undefined && widgetSettings.visualizerType !== "") ? widgetSettings.visualizerType : widgetMetadata.visualizerType - readonly property bool scrollingTitle: Settings.data.audio.scrollingTitle - readonly property int scrollingSpeed: Settings.data.audio.scrollingSpeed + readonly property string scrollingMode: (widgetSettings.scrollingMode !== undefined) ? widgetSettings.scrollingMode : widgetMetadata.scrollingMode - // 6% of total width - readonly property real minWidth: Math.max(1, screen.width * 0.06) - readonly property real maxWidth: minWidth * 2 + // Fixed width - no expansion + readonly property real widgetWidth: Math.max(1, screen.width * 0.06) function getTitle() { return MediaService.trackTitle + (MediaService.trackArtist !== "" ? ` - ${MediaService.trackArtist}` : "") @@ -51,20 +49,8 @@ Item { return Math.round(Style.baseWidgetSize * 0.8 * scaling) } - function calculatedHorizontalWidth() { - let total = Style.marginM * 2 * scaling // internal padding - if (showAlbumArt) { - total += 18 * scaling + 2 * scaling // album art + spacing - } else { - total += Style.fontSizeL * scaling + 2 * scaling // icon + spacing - } - total += Math.min(fullTitleMetrics.contentWidth, maxWidth * scaling) // title text - // Row layout handles spacing between widgets - return total - } - 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) : (rowLayout.implicitWidth + Style.marginM * 2 * scaling)) : 0 + implicitWidth: visible ? ((barPosition === "left" || barPosition === "right") ? Math.round(Style.baseWidgetSize * 0.8 * scaling) : (widgetWidth * scaling)) : 0 visible: MediaService.currentPlayer !== null && MediaService.canPlay @@ -81,7 +67,7 @@ Item { visible: root.visible anchors.left: parent.left anchors.verticalCenter: parent.verticalCenter - width: (barPosition === "left" || barPosition === "right") ? Math.round(Style.baseWidgetSize * 0.8 * scaling) : (rowLayout.implicitWidth + Style.marginM * 2 * scaling) + width: (barPosition === "left" || barPosition === "right") ? Math.round(Style.baseWidgetSize * 0.8 * scaling) : (widgetWidth * scaling) height: (barPosition === "left" || barPosition === "right") ? Math.round(Style.baseWidgetSize * 0.8 * scaling) : Math.round(Style.capsuleHeight * scaling) radius: (barPosition === "left" || barPosition === "right") ? width / 2 : Math.round(Style.radiusM * scaling) color: Settings.data.bar.showCapsule ? Color.mSurfaceVariant : Color.transparent @@ -185,52 +171,55 @@ Item { Item { id: titleContainer - Layout.preferredWidth: { - if (mouseArea.containsMouse) { - return Math.round(Math.min(fullTitleMetrics.contentWidth, root.maxWidth * scaling)) - } else { - return Math.round(Math.min(fullTitleMetrics.contentWidth, root.minWidth * scaling)) - } - } + Layout.preferredWidth: widgetWidth * scaling Layout.alignment: Qt.AlignVCenter Layout.preferredHeight: titleText.height clip: true - property bool shouldScroll: scrollingTitle && fullTitleMetrics.contentWidth > titleContainer.width property bool isScrolling: false - // Start scrolling when text is too long and not hovering + // Timer for "always" mode with delay Timer { id: scrollStartTimer interval: 2000 // Wait 2 seconds before starting scroll repeat: false onTriggered: { - if (titleContainer.shouldScroll && !mouseArea.containsMouse) { + if (scrollingMode === "always" && fullTitleMetrics.contentWidth > titleContainer.width) { titleContainer.isScrolling = true } } } - // Reset scroll position when text changes or on hover - onShouldScrollChanged: { - if (shouldScroll && !mouseArea.containsMouse) { - scrollStartTimer.restart() - } else { - scrollStartTimer.stop() + // Update scrolling state based on mode - using property instead of function + property var updateScrollingState: function () { + if (scrollingMode === "never") { isScrolling = false + } else if (scrollingMode === "always") { + if (fullTitleMetrics.contentWidth > titleContainer.width) { + if (mouseArea.containsMouse) { + isScrolling = false + } else { + scrollStartTimer.restart() + } + } else { + scrollStartTimer.stop() + isScrolling = false + } + } else if (scrollingMode === "hover") { + isScrolling = mouseArea.containsMouse && fullTitleMetrics.contentWidth > titleContainer.width } } + // React to text changes + onWidthChanged: updateScrollingState() + Component.onCompleted: updateScrollingState() + + // React to hover changes from the main mouse area Connections { target: mouseArea function onContainsMouseChanged() { - if (mouseArea.containsMouse) { - scrollStartTimer.stop() - titleContainer.isScrolling = false - } else if (titleContainer.shouldScroll) { - scrollStartTimer.restart() - } + titleContainer.updateScrollingState() } } @@ -255,7 +244,7 @@ Item { NumberAnimation { from: 0 to: -(fullTitleMetrics.contentWidth - titleContainer.width) - duration: scrollingSpeed * 1000 // Convert seconds to milliseconds + duration: Math.max(3000, getTitle().length * 100) // Compute from character count easing.type: Easing.Linear } } @@ -339,18 +328,18 @@ Item { NTooltip { id: tooltip text: { - if (barPosition === "left" || barPosition === "right") { - return getTitle() - } else { - var str = "" - if (MediaService.canGoNext) { - str += "Right click for next.\n" - } - if (MediaService.canGoPrevious) { - str += "Middle click for previous." - } - return str + var title = getTitle() + var controls = "" + if (MediaService.canGoNext) { + controls += "Right click for next.\n" } + if (MediaService.canGoPrevious) { + controls += "Middle click for previous." + } + if (controls !== "") { + return title + "\n\n" + controls + } + return title } target: (barPosition === "left" || barPosition === "right") ? verticalLayout : anchor positionLeft: barPosition === "right" diff --git a/Modules/Settings/Bar/WidgetSettings/MediaMiniSettings.qml b/Modules/Settings/Bar/WidgetSettings/MediaMiniSettings.qml index b357fa12..c5b68456 100644 --- a/Modules/Settings/Bar/WidgetSettings/MediaMiniSettings.qml +++ b/Modules/Settings/Bar/WidgetSettings/MediaMiniSettings.qml @@ -17,12 +17,14 @@ ColumnLayout { property bool valueShowAlbumArt: widgetData.showAlbumArt !== undefined ? widgetData.showAlbumArt : widgetMetadata.showAlbumArt property bool valueShowVisualizer: widgetData.showVisualizer !== undefined ? widgetData.showVisualizer : widgetMetadata.showVisualizer property string valueVisualizerType: widgetData.visualizerType || widgetMetadata.visualizerType + property string valueScrollingMode: widgetData.scrollingMode || widgetMetadata.scrollingMode function saveSettings() { var settings = Object.assign({}, widgetData || {}) settings.showAlbumArt = valueShowAlbumArt settings.showVisualizer = valueShowVisualizer settings.visualizerType = valueVisualizerType + settings.scrollingMode = valueScrollingMode return settings } @@ -55,4 +57,21 @@ ColumnLayout { onSelected: key => valueVisualizerType = key minimumWidth: 200 * scaling } + + NComboBox { + label: I18n.tr("bar.widget-settings.media-mini.scrolling-mode") + model: [{ + "key": "always", + "name": I18n.tr("options.scrolling-modes.always") + }, { + "key": "hover", + "name": I18n.tr("options.scrolling-modes.hover") + }, { + "key": "never", + "name": I18n.tr("options.scrolling-modes.never") + }] + currentKey: valueScrollingMode + onSelected: key => valueScrollingMode = key + minimumWidth: 200 * scaling + } } diff --git a/Modules/Settings/Tabs/AudioTab.qml b/Modules/Settings/Tabs/AudioTab.qml index 252fdb56..64919045 100644 --- a/Modules/Settings/Tabs/AudioTab.qml +++ b/Modules/Settings/Tabs/AudioTab.qml @@ -385,27 +385,6 @@ ColumnLayout { currentKey: Settings.data.audio.cavaFrameRate onSelected: key => Settings.data.audio.cavaFrameRate = key } - - // Scrolling Title Settings - NToggle { - label: I18n.tr("settings.audio.media.scrolling-title.label") - description: I18n.tr("settings.audio.media.scrolling-title.description") - checked: Settings.data.audio.scrollingTitle - onToggled: checked => Settings.data.audio.scrollingTitle = checked - } - - NSpinBox { - Layout.fillWidth: true - label: I18n.tr("settings.audio.media.scrolling-speed.label") - description: I18n.tr("settings.audio.media.scrolling-speed.description") - minimum: 5 - maximum: 60 - value: Settings.data.audio.scrollingSpeed - stepSize: 1 - suffix: "s" - enabled: Settings.data.audio.scrollingTitle - onValueChanged: Settings.data.audio.scrollingSpeed = value - } } NDivider { diff --git a/Services/BarWidgetRegistry.qml b/Services/BarWidgetRegistry.qml index 913286a6..08435025 100644 --- a/Services/BarWidgetRegistry.qml +++ b/Services/BarWidgetRegistry.qml @@ -98,7 +98,8 @@ Singleton { "allowUserSettings": true, "showAlbumArt": false, "showVisualizer": false, - "visualizerType": "linear" + "visualizerType": "linear", + "scrollingMode": "hover" }, "ControlCenter": { "allowUserSettings": true,