diff --git a/Common/SettingsData.qml b/Common/SettingsData.qml index 1bc51681..d9363891 100644 --- a/Common/SettingsData.qml +++ b/Common/SettingsData.qml @@ -44,7 +44,7 @@ Singleton { property bool showWorkspaceIndex: false property bool showWorkspacePadding: false property bool clockCompactMode: false - property bool mediaCompactMode: false + property int mediaSize: 1 property var topBarLeftWidgets: ["launcherButton", "workspaceSwitcher", "focusedWindow"] property var topBarCenterWidgets: ["music", "clock", "weather"] property var topBarRightWidgets: ["systemTray", "clipboard", "cpuUsage", "memUsage", "notificationButton", "battery", "controlCenterButton"] @@ -202,8 +202,7 @@ Singleton { !== undefined ? settings.showWorkspacePadding : false clockCompactMode = settings.clockCompactMode !== undefined ? settings.clockCompactMode : false - mediaCompactMode = settings.mediaCompactMode - !== undefined ? settings.mediaCompactMode : false + mediaSize = settings.mediaSize !== undefined ? settings.mediaSize : (settings.mediaCompactMode !== undefined ? (settings.mediaCompactMode ? 0 : 1) : 1) if (settings.topBarWidgetOrder) { topBarLeftWidgets = settings.topBarWidgetOrder.filter( w => ["launcherButton", "workspaceSwitcher", "focusedWindow"].includes( @@ -302,7 +301,7 @@ Singleton { "showWorkspaceIndex": showWorkspaceIndex, "showWorkspacePadding": showWorkspacePadding, "clockCompactMode": clockCompactMode, - "mediaCompactMode": mediaCompactMode, + "mediaSize": mediaSize, "topBarLeftWidgets": topBarLeftWidgets, "topBarCenterWidgets": topBarCenterWidgets, "topBarRightWidgets": topBarRightWidgets, @@ -341,8 +340,8 @@ Singleton { saveSettings() } - function setMediaCompactMode(enabled) { - mediaCompactMode = enabled + function setMediaSize(size) { + mediaSize = size saveSettings() } diff --git a/Modules/Settings/WidgetsTab.qml b/Modules/Settings/WidgetsTab.qml index 78457c51..efb0c8be 100644 --- a/Modules/Settings/WidgetsTab.qml +++ b/Modules/Settings/WidgetsTab.qml @@ -614,11 +614,11 @@ Item { itemId, newSize) } - onCompactModeChanged: (widgetId, enabled) => { + onCompactModeChanged: (widgetId, value) => { if (widgetId === "clock") { - SettingsData.setClockCompactMode(enabled) + SettingsData.setClockCompactMode(value) } else if (widgetId === "music") { - SettingsData.setMediaCompactMode(enabled) + SettingsData.setMediaSize(value) } } onGpuSelectionChanged: (sectionId, widgetIndex, selectedIndex) => { @@ -657,11 +657,11 @@ Item { itemId, newSize) } - onCompactModeChanged: (widgetId, enabled) => { + onCompactModeChanged: (widgetId, value) => { if (widgetId === "clock") { - SettingsData.setClockCompactMode(enabled) + SettingsData.setClockCompactMode(value) } else if (widgetId === "music") { - SettingsData.setMediaCompactMode(enabled) + SettingsData.setMediaSize(value) } } onGpuSelectionChanged: (sectionId, widgetIndex, selectedIndex) => { @@ -700,11 +700,11 @@ Item { itemId, newSize) } - onCompactModeChanged: (widgetId, enabled) => { + onCompactModeChanged: (widgetId, value) => { if (widgetId === "clock") { - SettingsData.setClockCompactMode(enabled) + SettingsData.setClockCompactMode(value) } else if (widgetId === "music") { - SettingsData.setMediaCompactMode(enabled) + SettingsData.setMediaSize(value) } } onGpuSelectionChanged: (sectionId, widgetIndex, selectedIndex) => { diff --git a/Modules/Settings/WidgetsTabSection.qml b/Modules/Settings/WidgetsTabSection.qml index eb2d797b..7375f491 100644 --- a/Modules/Settings/WidgetsTabSection.qml +++ b/Modules/Settings/WidgetsTabSection.qml @@ -18,7 +18,7 @@ Column { signal addWidget(string sectionId) signal removeWidget(string sectionId, int widgetIndex) signal spacerSizeChanged(string sectionId, string itemId, int newSize) - signal compactModeChanged(string widgetId, bool enabled) + signal compactModeChanged(string widgetId, var value) signal gpuSelectionChanged(string sectionId, int widgetIndex, int selectedIndex) width: parent.width @@ -236,32 +236,55 @@ Column { } } - Item { - width: 32 - height: 32 + Row { + spacing: Theme.spacingXS visible: modelData.id === "clock" || modelData.id === "music" - + + DankActionButton { + id: smallSizeButton + buttonSize: 28 + visible: modelData.id === "music" + iconName: "photo_size_select_small" + iconSize: 16 + iconColor: SettingsData.mediaSize === 0 ? Theme.primary : Theme.outline + onClicked: { + root.compactModeChanged("music", 0) + } + } + + DankActionButton { + id: mediumSizeButton + buttonSize: 28 + visible: modelData.id === "music" + iconName: "photo_size_select_actual" + iconSize: 16 + iconColor: SettingsData.mediaSize === 1 ? Theme.primary : Theme.outline + onClicked: { + root.compactModeChanged("music", 1) + } + } + + DankActionButton { + id: largeSizeButton + buttonSize: 28 + visible: modelData.id === "music" + iconName: "photo_size_select_large" + iconSize: 16 + iconColor: SettingsData.mediaSize === 2 ? Theme.primary : Theme.outline + onClicked: { + root.compactModeChanged("music", 2) + } + } + DankActionButton { id: compactModeButton - anchors.fill: parent - buttonSize: 32 - iconName: (modelData.id === "clock" - && SettingsData.clockCompactMode) - || (modelData.id === "music" - && SettingsData.mediaCompactMode) ? "zoom_out" : "zoom_in" - iconSize: 18 - iconColor: ((modelData.id === "clock" - && SettingsData.clockCompactMode) - || (modelData.id === "music" - && SettingsData.mediaCompactMode)) ? Theme.primary : Theme.outline + buttonSize: 28 + visible: modelData.id === "clock" + iconName: SettingsData.clockCompactMode ? "zoom_out" : "zoom_in" + iconSize: 16 + iconColor: SettingsData.clockCompactMode ? Theme.primary : Theme.outline onClicked: { - if (modelData.id === "clock") { - root.compactModeChanged("clock", - !SettingsData.clockCompactMode) - } else if (modelData.id === "music") { - root.compactModeChanged("music", - !SettingsData.mediaCompactMode) - } + root.compactModeChanged("clock", !SettingsData.clockCompactMode) } } @@ -273,8 +296,7 @@ Column { color: Theme.surfaceContainer border.color: Theme.outline border.width: 1 - visible: compactModeButton.children[1] - && compactModeButton.children[1].containsMouse + visible: false opacity: visible ? 1 : 0 x: -width - Theme.spacingS y: (parent.height - height) / 2 diff --git a/Modules/TopBar/Media.qml b/Modules/TopBar/Media.qml index 40d0aee6..c672e70f 100644 --- a/Modules/TopBar/Media.qml +++ b/Modules/TopBar/Media.qml @@ -10,9 +10,19 @@ Rectangle { readonly property MprisPlayer activePlayer: MprisController.activePlayer readonly property bool playerAvailable: activePlayer !== null property bool compactMode: false - readonly property int baseContentWidth: mediaRow.implicitWidth + Theme.spacingS * 2 - readonly property int normalContentWidth: Math.min(280, baseContentWidth) - readonly property int compactContentWidth: Math.min(120, baseContentWidth) + readonly property int textWidth: { + switch(SettingsData.mediaSize) { + case 0: return 0 // No text in small mode + case 2: return 180 // Large text area + default: return 120 // Medium text area + } + } + + readonly property int currentContentWidth: { + // AudioViz (20) + spacing + text + spacing + controls (~90) + padding + const baseWidth = 20 + Theme.spacingXS + 90 + Theme.spacingS * 2 + return baseWidth + textWidth + (textWidth > 0 ? Theme.spacingXS : 0) + } property string section: "center" property var popupTarget: null property var parentScreen: null @@ -34,7 +44,7 @@ Rectangle { PropertyChanges { target: root opacity: 1 - width: SettingsData.mediaCompactMode ? compactContentWidth : normalContentWidth + width: currentContentWidth } }, State { @@ -92,13 +102,17 @@ Rectangle { anchors.verticalCenter: parent.verticalCenter } - StyledText { - id: mediaText - + Rectangle { + id: textContainer + anchors.verticalCenter: parent.verticalCenter - width: SettingsData.mediaCompactMode ? 60 : 140 - visible: !SettingsData.mediaCompactMode - text: { + width: textWidth + height: 20 + visible: SettingsData.mediaSize > 0 + clip: true + color: "transparent" + + property string displayText: { if (!activePlayer || !activePlayer.trackTitle) return "" @@ -119,12 +133,54 @@ Rectangle { } return subtitle.length > 0 ? title + " • " + subtitle : title } - font.pixelSize: Theme.fontSizeSmall - color: Theme.surfaceText - font.weight: Font.Medium - elide: Text.ElideRight - wrapMode: Text.NoWrap - maximumLineCount: 1 + + StyledText { + id: mediaText + + anchors.verticalCenter: parent.verticalCenter + text: textContainer.displayText + font.pixelSize: Theme.fontSizeSmall + color: Theme.surfaceText + font.weight: Font.Medium + wrapMode: Text.NoWrap + + property bool needsScrolling: implicitWidth > textContainer.width + property real scrollOffset: 0 + + x: needsScrolling ? -scrollOffset : 0 + + SequentialAnimation { + id: scrollAnimation + running: mediaText.needsScrolling && textContainer.visible + loops: Animation.Infinite + + PauseAnimation { duration: 2000 } + + NumberAnimation { + target: mediaText + property: "scrollOffset" + from: 0 + to: mediaText.implicitWidth - textContainer.width + 5 + duration: 5000 + easing.type: Easing.Linear + } + + PauseAnimation { duration: 2000 } + + NumberAnimation { + target: mediaText + property: "scrollOffset" + to: 0 + duration: 5000 + easing.type: Easing.Linear + } + } + + onTextChanged: { + scrollOffset = 0 + scrollAnimation.restart() + } + } MouseArea { anchors.fill: parent