From dcedae46e5741a83e149997979ed4a052d3ef432 Mon Sep 17 00:00:00 2001 From: Ly-sec Date: Sat, 13 Sep 2025 15:21:36 +0200 Subject: [PATCH] Horizontal bar: try to get better spacing --- Modules/Bar/Bar.qml | 17 ++-- Modules/Bar/Widgets/ActiveWindow.qml | 56 +++++++++---- Modules/Bar/Widgets/MediaMini.qml | 106 ++++++++++++++++++----- Modules/Bar/Widgets/SystemMonitor.qml | 116 +++++++++++++++++++------- Modules/Bar/Widgets/Workspace.qml | 4 +- 5 files changed, 218 insertions(+), 81 deletions(-) diff --git a/Modules/Bar/Bar.qml b/Modules/Bar/Bar.qml index a42abb0..81d5241 100644 --- a/Modules/Bar/Bar.qml +++ b/Modules/Bar/Bar.qml @@ -89,7 +89,7 @@ Variants { id: verticalBarComponent Item { anchors.fill: parent - + // Top section (left widgets) Column { spacing: Style.marginS * root.scaling @@ -97,7 +97,7 @@ Variants { anchors.top: parent.top anchors.topMargin: Style.marginM * root.scaling width: parent.width - + Repeater { model: Settings.data.bar.widgets.left delegate: NWidgetLoader { @@ -115,14 +115,14 @@ Variants { } } } - + // Center section (center widgets) Column { spacing: Style.marginS * root.scaling anchors.horizontalCenter: parent.horizontalCenter anchors.verticalCenter: parent.verticalCenter width: parent.width - + Repeater { model: Settings.data.bar.widgets.center delegate: NWidgetLoader { @@ -140,7 +140,7 @@ Variants { } } } - + // Bottom section (right widgets) Column { spacing: Style.marginS * root.scaling @@ -148,7 +148,7 @@ Variants { anchors.bottom: parent.bottom anchors.bottomMargin: Style.marginM * root.scaling width: parent.width - + Repeater { model: Settings.data.bar.widgets.right delegate: NWidgetLoader { @@ -173,7 +173,7 @@ Variants { id: horizontalBarComponent Row { anchors.fill: parent - + // Left Section Row { id: leftSection @@ -182,7 +182,7 @@ Variants { anchors.left: parent.left anchors.leftMargin: Style.marginS * root.scaling anchors.verticalCenter: parent.verticalCenter - spacing: Style.marginS * root.scaling + spacing: 0 Repeater { model: Settings.data.bar.widgets.left @@ -258,7 +258,6 @@ Variants { } } } - } } } diff --git a/Modules/Bar/Widgets/ActiveWindow.qml b/Modules/Bar/Widgets/ActiveWindow.qml index eb77fa0..b956e14 100644 --- a/Modules/Bar/Widgets/ActiveWindow.qml +++ b/Modules/Bar/Widgets/ActiveWindow.qml @@ -38,7 +38,7 @@ Item { readonly property real maxWidth: minWidth * 2 implicitHeight: (barPosition === "left" || barPosition === "right") ? calculatedVerticalHeight() : Math.round(Style.barHeight * scaling) - implicitWidth: (barPosition === "left" || barPosition === "right") ? Math.round(Style.capsuleHeight * scaling) : calculatedHorizontalWidth() + implicitWidth: (barPosition === "left" || barPosition === "right") ? Math.round(Style.baseWidgetSize * 0.8 * scaling) : calculatedHorizontalWidth() function getTitle() { try { @@ -52,20 +52,40 @@ Item { visible: getTitle() !== "" function calculatedVerticalHeight() { + // Base height for the background rectangle let total = Math.round(Style.capsuleHeight * scaling) + + // Add padding for the container margins + total += Style.marginM * scaling * 2 // Top and bottom margins + + // Add space for icon if shown if (showIcon) { total += Style.fontSizeL * scaling * 1.2 + Style.marginS * scaling } + return total } function calculatedHorizontalWidth() { - let total = Style.marginM * 2 * scaling // padding + let total = Style.marginM * 2 * scaling // internal padding + if (showIcon) { - total += Style.fontSizeL * scaling * 1.2 + Style.marginS * scaling + total += Style.baseWidgetSize * 0.5 * scaling + 2 * scaling // icon + spacing } - total += Math.min(fullTitleMetrics.contentWidth, minWidth * scaling) - return total + + // Calculate actual text width more accurately + const title = getTitle() + if (title !== "") { + // Estimate text width: average character width * number of characters + const avgCharWidth = Style.fontSizeS * scaling * 0.6 // rough estimate + const titleWidth = Math.min(title.length * avgCharWidth, 80 * scaling) + total += titleWidth + } + + // Add extra margin for spacing between widgets in the bar + total += Style.marginM * scaling * 2 // widget-to-widget spacing + + return Math.max(total, Style.capsuleHeight * scaling) // Minimum width } function getAppIcon() { @@ -121,30 +141,31 @@ Item { Rectangle { id: windowTitleRect visible: root.visible - anchors.centerIn: parent - width: (barPosition === "left" || barPosition === "right") ? Math.round(60 * scaling) : parent.width - height: (barPosition === "left" || barPosition === "right") ? parent.height : Math.round(Style.capsuleHeight * scaling) + anchors.left: parent.left + anchors.verticalCenter: parent.verticalCenter + width: (barPosition === "left" || barPosition === "right") ? Math.round(Style.capsuleHeight * scaling) : (horizontalLayout.implicitWidth + Style.marginM * 2 * scaling) + height: (barPosition === "left" || barPosition === "right") ? Math.round(Style.capsuleHeight * scaling) : Math.round(Style.capsuleHeight * scaling) radius: Math.round(Style.radiusM * scaling) color: Color.mSurfaceVariant Item { id: mainContainer anchors.fill: parent - anchors.leftMargin: Style.marginS * scaling - anchors.rightMargin: Style.marginS * scaling + anchors.leftMargin: (barPosition === "left" || barPosition === "right") ? 0 : Style.marginS * scaling + anchors.rightMargin: (barPosition === "left" || barPosition === "right") ? 0 : Style.marginS * scaling clip: true // Horizontal layout for top/bottom bars RowLayout { id: horizontalLayout anchors.centerIn: parent - spacing: Style.marginS * scaling + spacing: 2 * scaling visible: barPosition === "top" || barPosition === "bottom" // Window icon Item { - Layout.preferredWidth: Style.fontSizeL * scaling * 1.2 - Layout.preferredHeight: Style.fontSizeL * scaling * 1.2 + Layout.preferredWidth: Style.baseWidgetSize * 0.5 * scaling + Layout.preferredHeight: Style.baseWidgetSize * 0.5 * scaling Layout.alignment: Qt.AlignVCenter visible: getTitle() !== "" && showIcon @@ -172,11 +193,11 @@ Item { if (mouseArea.containsMouse) { return Math.round(Math.min(fullTitleMetrics.contentWidth, root.maxWidth * scaling)) } else { - return Math.round(Math.min(fullTitleMetrics.contentWidth, root.minWidth * scaling)) + return Math.round(Math.min(fullTitleMetrics.contentWidth, 80 * scaling)) // Limited width for horizontal bars } } catch (e) { Logger.warn("ActiveWindow", "Error calculating width:", e) - return root.minWidth * scaling + return 80 * scaling } } Layout.alignment: Qt.AlignVCenter @@ -208,8 +229,8 @@ Item { // Window icon Item { - width: Style.fontSizeL * scaling * 1.2 - height: Style.fontSizeL * scaling * 1.2 + width: Style.baseWidgetSize * 0.5 * scaling + height: Style.baseWidgetSize * 0.5 * scaling anchors.centerIn: parent visible: getTitle() !== "" && showIcon @@ -229,7 +250,6 @@ Item { } } } - } // Mouse area for hover detection diff --git a/Modules/Bar/Widgets/MediaMini.qml b/Modules/Bar/Widgets/MediaMini.qml index 79f8393..c3f333a 100644 --- a/Modules/Bar/Widgets/MediaMini.qml +++ b/Modules/Bar/Widgets/MediaMini.qml @@ -7,7 +7,7 @@ import qs.Commons import qs.Services import qs.Widgets -RowLayout { +Item { id: root property ShellScreen screen @@ -18,6 +18,7 @@ RowLayout { property string section: "" property int sectionWidgetIndex: -1 property int sectionWidgetsCount: 0 + property string barPosition: "top" property var widgetMetadata: BarWidgetRegistry.widgetMetadata[widgetId] property var widgetSettings: { @@ -42,10 +43,25 @@ RowLayout { return MediaService.trackTitle + (MediaService.trackArtist !== "" ? ` - ${MediaService.trackArtist}` : "") } - Layout.alignment: Qt.AlignVCenter - spacing: Style.marginS * scaling + function calculatedVerticalHeight() { + return Math.round(Style.baseWidgetSize * 0.8 * scaling) + } + + function calculatedHorizontalWidth() { + let total = Style.marginM * 2 * scaling // padding + if (showAlbumArt) { + total += 18 * scaling + Style.marginS * scaling // album art + spacing + } else { + total += Style.fontSizeL * scaling + Style.marginS * scaling // icon + spacing + } + total += Math.min(fullTitleMetrics.contentWidth, maxWidth * scaling) // title text + return total + } + + implicitHeight: (barPosition === "left" || barPosition === "right") ? calculatedVerticalHeight() : Math.round(Style.barHeight * scaling) + implicitWidth: (barPosition === "left" || barPosition === "right") ? Math.round(Style.baseWidgetSize * 0.8 * scaling) : calculatedHorizontalWidth() + visible: MediaService.currentPlayer !== null && MediaService.canPlay - Layout.preferredWidth: MediaService.currentPlayer !== null && MediaService.canPlay ? implicitWidth : 0 // A hidden text element to safely measure the full title width NText { @@ -57,12 +73,20 @@ RowLayout { Rectangle { id: mediaMini + visible: root.visible - Layout.preferredWidth: rowLayout.implicitWidth + Style.marginM * 2 * scaling - Layout.preferredHeight: Math.round(Style.capsuleHeight * scaling) - Layout.alignment: Qt.AlignVCenter + // For vertical bars, use anchors to center in parent + anchors.centerIn: (barPosition === "left" || barPosition === "right") ? parent : undefined - radius: Math.round(Style.radiusM * scaling) + // For horizontal bars, use Layout properties + Layout.preferredWidth: (barPosition === "left" || barPosition === "right") ? Math.round(Style.baseWidgetSize * 0.8 * scaling) : (rowLayout.implicitWidth + Style.marginM * 2 * scaling) + Layout.preferredHeight: (barPosition === "left" || barPosition === "right") ? Math.round(Style.baseWidgetSize * 0.8 * scaling) : Math.round(Style.capsuleHeight * scaling) + Layout.alignment: (barPosition === "left" || barPosition === "right") ? undefined : Qt.AlignVCenter + + width: (barPosition === "left" || barPosition === "right") ? Math.round(Style.baseWidgetSize * 0.8 * scaling) : undefined + height: (barPosition === "left" || barPosition === "right") ? Math.round(Style.baseWidgetSize * 0.8 * scaling) : undefined + + radius: (barPosition === "left" || barPosition === "right") ? width / 2 : Math.round(Style.radiusM * scaling) color: Color.mSurfaceVariant // Used to anchor the tooltip, so the tooltip does not move when the content expands @@ -75,8 +99,8 @@ RowLayout { Item { id: mainContainer anchors.fill: parent - anchors.leftMargin: Style.marginS * scaling - anchors.rightMargin: Style.marginS * scaling + anchors.leftMargin: (barPosition === "left" || barPosition === "right") ? 0 : Style.marginS * scaling + anchors.rightMargin: (barPosition === "left" || barPosition === "right") ? 0 : Style.marginS * scaling Loader { anchors.verticalCenter: parent.verticalCenter @@ -123,10 +147,12 @@ RowLayout { } } + // Horizontal layout for top/bottom bars RowLayout { id: rowLayout anchors.verticalCenter: parent.verticalCenter spacing: Style.marginS * scaling + visible: barPosition === "top" || barPosition === "bottom" z: 1 // Above the visualizer NIcon { @@ -187,6 +213,33 @@ RowLayout { } } + // Vertical layout for left/right bars - icon only + Item { + id: verticalLayout + anchors.centerIn: parent + width: parent.width - Style.marginM * scaling * 2 + height: parent.height - Style.marginM * scaling * 2 + visible: barPosition === "left" || barPosition === "right" + z: 1 // Above the visualizer + + // Media icon + 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" + font.pointSize: Style.fontSizeL * scaling + verticalAlignment: Text.AlignVCenter + horizontalAlignment: Text.AlignHCenter + } + } + } + // Mouse area for hover detection MouseArea { id: mouseArea @@ -209,12 +262,18 @@ RowLayout { } onEntered: { - if (tooltip.text !== "") { + if (barPosition === "left" || barPosition === "right") { + tooltip.show() + } else if (tooltip.text !== "") { tooltip.show() } } onExited: { - tooltip.hide() + if (barPosition === "left" || barPosition === "right") { + tooltip.hide() + } else { + tooltip.hide() + } } } } @@ -223,16 +282,23 @@ RowLayout { NTooltip { id: tooltip text: { - var str = "" - if (MediaService.canGoNext) { - str += "Right click for next.\n" + 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 } - if (MediaService.canGoPrevious) { - str += "Middle click for previous." - } - return str } - target: anchor + target: (barPosition === "left" || barPosition === "right") ? verticalLayout : anchor + positionLeft: barPosition === "right" + positionRight: barPosition === "left" positionAbove: Settings.data.bar.position === "bottom" + delay: 500 } } diff --git a/Modules/Bar/Widgets/SystemMonitor.qml b/Modules/Bar/Widgets/SystemMonitor.qml index ef28e30..45a576c 100644 --- a/Modules/Bar/Widgets/SystemMonitor.qml +++ b/Modules/Bar/Widgets/SystemMonitor.qml @@ -42,42 +42,96 @@ Item { function calculatedVerticalHeight() { let total = 0 let visibleCount = 0 - - if (showCpuUsage) visibleCount++ - if (showCpuTemp) visibleCount++ - if (showMemoryUsage) visibleCount++ - if (showNetworkStats) visibleCount += 2 // download + upload - if (showDiskUsage) visibleCount++ - + + if (showCpuUsage) + visibleCount++ + if (showCpuTemp) + visibleCount++ + if (showMemoryUsage) + visibleCount++ + if (showNetworkStats) + visibleCount += 2 // download + upload + if (showDiskUsage) + visibleCount++ + total = visibleCount * Math.round(Style.capsuleHeight * scaling) total += Math.max(visibleCount - 1, 0) * Style.marginS * scaling total += Style.marginM * scaling * 2 // padding - + return total } function calculatedHorizontalWidth() { - let total = 0 + let total = Style.marginM * scaling * 2 // base padding + + if (showCpuUsage) { + // Icon + "99%" text + total += Style.fontSizeM * scaling * 1.2 + // icon + Style.fontSizeXS * scaling * 2.5 + // text (~3 chars) + 2 * scaling // spacing + } + + if (showCpuTemp) { + // Icon + "85°C" text + total += Style.fontSizeS * scaling * 1.2 + // smaller fire icon + Style.fontSizeXS * scaling * 3.5 + // text (~4 chars) + 2 * scaling // spacing + } + + if (showMemoryUsage) { + // Icon + "16G" or "85%" text + total += Style.fontSizeM * scaling * 1.2 + // icon + Style.fontSizeXS * scaling * 3 + // text (~3-4 chars) + 2 * scaling // spacing + } + + if (showNetworkStats) { + // Download: icon + "1.2M" text + total += Style.fontSizeM * scaling * 1.2 + // icon + Style.fontSizeXS * scaling * 3.5 + // text + Style.marginXS * scaling + 2 * scaling // spacing + + // Upload: icon + "256K" text + total += Style.fontSizeM * scaling * 1.2 + // icon + Style.fontSizeXS * scaling * 3.5 + // text + Style.marginXS * scaling + 2 * scaling // spacing + } + + if (showDiskUsage) { + // Icon + "75%" text + total += Style.fontSizeM * scaling * 1.2 + // icon + Style.fontSizeXS * scaling * 3 + // text (~3 chars) + Style.marginXS * scaling + 2 * scaling // spacing + } + + // Add spacing between visible components let visibleCount = 0 - - if (showCpuUsage) visibleCount++ - if (showCpuTemp) visibleCount++ - if (showMemoryUsage) visibleCount++ - if (showNetworkStats) visibleCount += 2 // download + upload - if (showDiskUsage) visibleCount++ - - // Estimate width per component (icon + text + spacing) - total = visibleCount * Math.round(60 * scaling) // rough estimate - total += Math.max(visibleCount - 1, 0) * Style.marginS * scaling - total += Style.marginM * scaling * 2 // padding - - return total + if (showCpuUsage) + visibleCount++ + if (showCpuTemp) + visibleCount++ + if (showMemoryUsage) + visibleCount++ + if (showNetworkStats) + visibleCount += 2 + if (showDiskUsage) + visibleCount++ + + if (visibleCount > 1) { + total += (visibleCount - 1) * Style.marginXS * scaling + } + + // Add extra margin for spacing between widgets in the bar + total += Style.marginM * scaling * 2 // widget-to-widget spacing + + return Math.max(total, Style.capsuleHeight * scaling) } Rectangle { id: backgroundContainer - anchors.centerIn: parent - width: (barPosition === "left" || barPosition === "right") ? Math.round(Style.capsuleHeight * scaling) : parent.width + anchors.left: parent.left + anchors.verticalCenter: parent.verticalCenter + width: (barPosition === "left" || barPosition === "right") ? Math.round(Style.capsuleHeight * scaling) : calculatedHorizontalWidth() height: (barPosition === "left" || barPosition === "right") ? parent.height : Math.round(Style.capsuleHeight * scaling) radius: Math.round(Style.radiusM * scaling) color: Color.mSurfaceVariant @@ -86,10 +140,8 @@ Item { RowLayout { id: horizontalLayout anchors.centerIn: parent - width: parent.width - Style.marginM * scaling * 2 - height: parent.height - Style.marginM * scaling * 2 - spacing: Style.marginS * scaling - visible: false // Temporarily hide horizontal layout for debugging + spacing: Style.marginXS * scaling + visible: barPosition === "top" || barPosition === "bottom" // CPU Usage Component Item { @@ -101,7 +153,7 @@ Item { RowLayout { id: cpuUsageRow anchors.centerIn: parent - spacing: Style.marginXS * scaling + spacing: 2 * scaling NIcon { icon: "cpu-usage" @@ -131,7 +183,7 @@ Item { RowLayout { id: cpuTempRow anchors.centerIn: parent - spacing: Style.marginXS * scaling + spacing: 2 * scaling NIcon { icon: "cpu-temperature" @@ -162,7 +214,7 @@ Item { RowLayout { id: memoryUsageRow anchors.centerIn: parent - spacing: Style.marginXS * scaling + spacing: 2 * scaling NIcon { icon: "memory" @@ -280,7 +332,7 @@ Item { width: Math.round(32 * scaling) height: parent.height - Style.marginM * scaling * 2 spacing: Style.marginS * scaling - visible: true // Temporarily show vertical layout for debugging + visible: barPosition === "left" || barPosition === "right" // CPU Usage Component Item { diff --git a/Modules/Bar/Widgets/Workspace.qml b/Modules/Bar/Widgets/Workspace.qml index 63f6c9c..34dce9b 100644 --- a/Modules/Bar/Widgets/Workspace.qml +++ b/Modules/Bar/Widgets/Workspace.qml @@ -189,7 +189,7 @@ Item { width: root.width - horizontalPadding * 2 x: horizontalPadding visible: barPosition === "top" || barPosition === "bottom" - + Repeater { id: workspaceRepeaterHorizontal model: localWorkspaces @@ -334,7 +334,7 @@ Item { height: root.height - horizontalPadding * 2 y: horizontalPadding visible: barPosition === "left" || barPosition === "right" - + Repeater { id: workspaceRepeaterVertical model: localWorkspaces