Horizontal bar: try to get better spacing

This commit is contained in:
Ly-sec 2025-09-13 15:21:36 +02:00
parent 4f5acb7114
commit dcedae46e5
5 changed files with 218 additions and 81 deletions

View file

@ -89,7 +89,7 @@ Variants {
id: verticalBarComponent id: verticalBarComponent
Item { Item {
anchors.fill: parent anchors.fill: parent
// Top section (left widgets) // Top section (left widgets)
Column { Column {
spacing: Style.marginS * root.scaling spacing: Style.marginS * root.scaling
@ -97,7 +97,7 @@ Variants {
anchors.top: parent.top anchors.top: parent.top
anchors.topMargin: Style.marginM * root.scaling anchors.topMargin: Style.marginM * root.scaling
width: parent.width width: parent.width
Repeater { Repeater {
model: Settings.data.bar.widgets.left model: Settings.data.bar.widgets.left
delegate: NWidgetLoader { delegate: NWidgetLoader {
@ -115,14 +115,14 @@ Variants {
} }
} }
} }
// Center section (center widgets) // Center section (center widgets)
Column { Column {
spacing: Style.marginS * root.scaling spacing: Style.marginS * root.scaling
anchors.horizontalCenter: parent.horizontalCenter anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
width: parent.width width: parent.width
Repeater { Repeater {
model: Settings.data.bar.widgets.center model: Settings.data.bar.widgets.center
delegate: NWidgetLoader { delegate: NWidgetLoader {
@ -140,7 +140,7 @@ Variants {
} }
} }
} }
// Bottom section (right widgets) // Bottom section (right widgets)
Column { Column {
spacing: Style.marginS * root.scaling spacing: Style.marginS * root.scaling
@ -148,7 +148,7 @@ Variants {
anchors.bottom: parent.bottom anchors.bottom: parent.bottom
anchors.bottomMargin: Style.marginM * root.scaling anchors.bottomMargin: Style.marginM * root.scaling
width: parent.width width: parent.width
Repeater { Repeater {
model: Settings.data.bar.widgets.right model: Settings.data.bar.widgets.right
delegate: NWidgetLoader { delegate: NWidgetLoader {
@ -173,7 +173,7 @@ Variants {
id: horizontalBarComponent id: horizontalBarComponent
Row { Row {
anchors.fill: parent anchors.fill: parent
// Left Section // Left Section
Row { Row {
id: leftSection id: leftSection
@ -182,7 +182,7 @@ Variants {
anchors.left: parent.left anchors.left: parent.left
anchors.leftMargin: Style.marginS * root.scaling anchors.leftMargin: Style.marginS * root.scaling
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
spacing: Style.marginS * root.scaling spacing: 0
Repeater { Repeater {
model: Settings.data.bar.widgets.left model: Settings.data.bar.widgets.left
@ -258,7 +258,6 @@ Variants {
} }
} }
} }
} }
} }
} }

View file

@ -38,7 +38,7 @@ Item {
readonly property real maxWidth: minWidth * 2 readonly property real maxWidth: minWidth * 2
implicitHeight: (barPosition === "left" || barPosition === "right") ? calculatedVerticalHeight() : Math.round(Style.barHeight * scaling) 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() { function getTitle() {
try { try {
@ -52,20 +52,40 @@ Item {
visible: getTitle() !== "" visible: getTitle() !== ""
function calculatedVerticalHeight() { function calculatedVerticalHeight() {
// Base height for the background rectangle
let total = Math.round(Style.capsuleHeight * scaling) 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) { if (showIcon) {
total += Style.fontSizeL * scaling * 1.2 + Style.marginS * scaling total += Style.fontSizeL * scaling * 1.2 + Style.marginS * scaling
} }
return total return total
} }
function calculatedHorizontalWidth() { function calculatedHorizontalWidth() {
let total = Style.marginM * 2 * scaling // padding let total = Style.marginM * 2 * scaling // internal padding
if (showIcon) { 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() { function getAppIcon() {
@ -121,30 +141,31 @@ Item {
Rectangle { Rectangle {
id: windowTitleRect id: windowTitleRect
visible: root.visible visible: root.visible
anchors.centerIn: parent anchors.left: parent.left
width: (barPosition === "left" || barPosition === "right") ? Math.round(60 * scaling) : parent.width anchors.verticalCenter: parent.verticalCenter
height: (barPosition === "left" || barPosition === "right") ? parent.height : Math.round(Style.capsuleHeight * scaling) 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) radius: Math.round(Style.radiusM * scaling)
color: Color.mSurfaceVariant color: Color.mSurfaceVariant
Item { Item {
id: mainContainer id: mainContainer
anchors.fill: parent anchors.fill: parent
anchors.leftMargin: Style.marginS * scaling anchors.leftMargin: (barPosition === "left" || barPosition === "right") ? 0 : Style.marginS * scaling
anchors.rightMargin: Style.marginS * scaling anchors.rightMargin: (barPosition === "left" || barPosition === "right") ? 0 : Style.marginS * scaling
clip: true clip: true
// Horizontal layout for top/bottom bars // Horizontal layout for top/bottom bars
RowLayout { RowLayout {
id: horizontalLayout id: horizontalLayout
anchors.centerIn: parent anchors.centerIn: parent
spacing: Style.marginS * scaling spacing: 2 * scaling
visible: barPosition === "top" || barPosition === "bottom" visible: barPosition === "top" || barPosition === "bottom"
// Window icon // Window icon
Item { Item {
Layout.preferredWidth: Style.fontSizeL * scaling * 1.2 Layout.preferredWidth: Style.baseWidgetSize * 0.5 * scaling
Layout.preferredHeight: Style.fontSizeL * scaling * 1.2 Layout.preferredHeight: Style.baseWidgetSize * 0.5 * scaling
Layout.alignment: Qt.AlignVCenter Layout.alignment: Qt.AlignVCenter
visible: getTitle() !== "" && showIcon visible: getTitle() !== "" && showIcon
@ -172,11 +193,11 @@ Item {
if (mouseArea.containsMouse) { if (mouseArea.containsMouse) {
return Math.round(Math.min(fullTitleMetrics.contentWidth, root.maxWidth * scaling)) return Math.round(Math.min(fullTitleMetrics.contentWidth, root.maxWidth * scaling))
} else { } 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) { } catch (e) {
Logger.warn("ActiveWindow", "Error calculating width:", e) Logger.warn("ActiveWindow", "Error calculating width:", e)
return root.minWidth * scaling return 80 * scaling
} }
} }
Layout.alignment: Qt.AlignVCenter Layout.alignment: Qt.AlignVCenter
@ -208,8 +229,8 @@ Item {
// Window icon // Window icon
Item { Item {
width: Style.fontSizeL * scaling * 1.2 width: Style.baseWidgetSize * 0.5 * scaling
height: Style.fontSizeL * scaling * 1.2 height: Style.baseWidgetSize * 0.5 * scaling
anchors.centerIn: parent anchors.centerIn: parent
visible: getTitle() !== "" && showIcon visible: getTitle() !== "" && showIcon
@ -229,7 +250,6 @@ Item {
} }
} }
} }
} }
// Mouse area for hover detection // Mouse area for hover detection

View file

@ -7,7 +7,7 @@ import qs.Commons
import qs.Services import qs.Services
import qs.Widgets import qs.Widgets
RowLayout { Item {
id: root id: root
property ShellScreen screen property ShellScreen screen
@ -18,6 +18,7 @@ RowLayout {
property string section: "" property string section: ""
property int sectionWidgetIndex: -1 property int sectionWidgetIndex: -1
property int sectionWidgetsCount: 0 property int sectionWidgetsCount: 0
property string barPosition: "top"
property var widgetMetadata: BarWidgetRegistry.widgetMetadata[widgetId] property var widgetMetadata: BarWidgetRegistry.widgetMetadata[widgetId]
property var widgetSettings: { property var widgetSettings: {
@ -42,10 +43,25 @@ RowLayout {
return MediaService.trackTitle + (MediaService.trackArtist !== "" ? ` - ${MediaService.trackArtist}` : "") return MediaService.trackTitle + (MediaService.trackArtist !== "" ? ` - ${MediaService.trackArtist}` : "")
} }
Layout.alignment: Qt.AlignVCenter function calculatedVerticalHeight() {
spacing: Style.marginS * scaling 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 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 // A hidden text element to safely measure the full title width
NText { NText {
@ -57,12 +73,20 @@ RowLayout {
Rectangle { Rectangle {
id: mediaMini id: mediaMini
visible: root.visible
Layout.preferredWidth: rowLayout.implicitWidth + Style.marginM * 2 * scaling // For vertical bars, use anchors to center in parent
Layout.preferredHeight: Math.round(Style.capsuleHeight * scaling) anchors.centerIn: (barPosition === "left" || barPosition === "right") ? parent : undefined
Layout.alignment: Qt.AlignVCenter
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 color: Color.mSurfaceVariant
// Used to anchor the tooltip, so the tooltip does not move when the content expands // Used to anchor the tooltip, so the tooltip does not move when the content expands
@ -75,8 +99,8 @@ RowLayout {
Item { Item {
id: mainContainer id: mainContainer
anchors.fill: parent anchors.fill: parent
anchors.leftMargin: Style.marginS * scaling anchors.leftMargin: (barPosition === "left" || barPosition === "right") ? 0 : Style.marginS * scaling
anchors.rightMargin: Style.marginS * scaling anchors.rightMargin: (barPosition === "left" || barPosition === "right") ? 0 : Style.marginS * scaling
Loader { Loader {
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
@ -123,10 +147,12 @@ RowLayout {
} }
} }
// Horizontal layout for top/bottom bars
RowLayout { RowLayout {
id: rowLayout id: rowLayout
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
spacing: Style.marginS * scaling spacing: Style.marginS * scaling
visible: barPosition === "top" || barPosition === "bottom"
z: 1 // Above the visualizer z: 1 // Above the visualizer
NIcon { 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 // Mouse area for hover detection
MouseArea { MouseArea {
id: mouseArea id: mouseArea
@ -209,12 +262,18 @@ RowLayout {
} }
onEntered: { onEntered: {
if (tooltip.text !== "") { if (barPosition === "left" || barPosition === "right") {
tooltip.show()
} else if (tooltip.text !== "") {
tooltip.show() tooltip.show()
} }
} }
onExited: { onExited: {
tooltip.hide() if (barPosition === "left" || barPosition === "right") {
tooltip.hide()
} else {
tooltip.hide()
}
} }
} }
} }
@ -223,16 +282,23 @@ RowLayout {
NTooltip { NTooltip {
id: tooltip id: tooltip
text: { text: {
var str = "" if (barPosition === "left" || barPosition === "right") {
if (MediaService.canGoNext) { return getTitle()
str += "Right click for next.\n" } 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" positionAbove: Settings.data.bar.position === "bottom"
delay: 500
} }
} }

View file

@ -42,42 +42,96 @@ Item {
function calculatedVerticalHeight() { function calculatedVerticalHeight() {
let total = 0 let total = 0
let visibleCount = 0 let visibleCount = 0
if (showCpuUsage) visibleCount++ if (showCpuUsage)
if (showCpuTemp) visibleCount++ visibleCount++
if (showMemoryUsage) visibleCount++ if (showCpuTemp)
if (showNetworkStats) visibleCount += 2 // download + upload visibleCount++
if (showDiskUsage) visibleCount++ if (showMemoryUsage)
visibleCount++
if (showNetworkStats)
visibleCount += 2 // download + upload
if (showDiskUsage)
visibleCount++
total = visibleCount * Math.round(Style.capsuleHeight * scaling) total = visibleCount * Math.round(Style.capsuleHeight * scaling)
total += Math.max(visibleCount - 1, 0) * Style.marginS * scaling total += Math.max(visibleCount - 1, 0) * Style.marginS * scaling
total += Style.marginM * scaling * 2 // padding total += Style.marginM * scaling * 2 // padding
return total return total
} }
function calculatedHorizontalWidth() { 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 let visibleCount = 0
if (showCpuUsage)
if (showCpuUsage) visibleCount++ visibleCount++
if (showCpuTemp) visibleCount++ if (showCpuTemp)
if (showMemoryUsage) visibleCount++ visibleCount++
if (showNetworkStats) visibleCount += 2 // download + upload if (showMemoryUsage)
if (showDiskUsage) visibleCount++ visibleCount++
if (showNetworkStats)
// Estimate width per component (icon + text + spacing) visibleCount += 2
total = visibleCount * Math.round(60 * scaling) // rough estimate if (showDiskUsage)
total += Math.max(visibleCount - 1, 0) * Style.marginS * scaling visibleCount++
total += Style.marginM * scaling * 2 // padding
if (visibleCount > 1) {
return total 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 { Rectangle {
id: backgroundContainer id: backgroundContainer
anchors.centerIn: parent anchors.left: parent.left
width: (barPosition === "left" || barPosition === "right") ? Math.round(Style.capsuleHeight * scaling) : parent.width 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) height: (barPosition === "left" || barPosition === "right") ? parent.height : Math.round(Style.capsuleHeight * scaling)
radius: Math.round(Style.radiusM * scaling) radius: Math.round(Style.radiusM * scaling)
color: Color.mSurfaceVariant color: Color.mSurfaceVariant
@ -86,10 +140,8 @@ Item {
RowLayout { RowLayout {
id: horizontalLayout id: horizontalLayout
anchors.centerIn: parent anchors.centerIn: parent
width: parent.width - Style.marginM * scaling * 2 spacing: Style.marginXS * scaling
height: parent.height - Style.marginM * scaling * 2 visible: barPosition === "top" || barPosition === "bottom"
spacing: Style.marginS * scaling
visible: false // Temporarily hide horizontal layout for debugging
// CPU Usage Component // CPU Usage Component
Item { Item {
@ -101,7 +153,7 @@ Item {
RowLayout { RowLayout {
id: cpuUsageRow id: cpuUsageRow
anchors.centerIn: parent anchors.centerIn: parent
spacing: Style.marginXS * scaling spacing: 2 * scaling
NIcon { NIcon {
icon: "cpu-usage" icon: "cpu-usage"
@ -131,7 +183,7 @@ Item {
RowLayout { RowLayout {
id: cpuTempRow id: cpuTempRow
anchors.centerIn: parent anchors.centerIn: parent
spacing: Style.marginXS * scaling spacing: 2 * scaling
NIcon { NIcon {
icon: "cpu-temperature" icon: "cpu-temperature"
@ -162,7 +214,7 @@ Item {
RowLayout { RowLayout {
id: memoryUsageRow id: memoryUsageRow
anchors.centerIn: parent anchors.centerIn: parent
spacing: Style.marginXS * scaling spacing: 2 * scaling
NIcon { NIcon {
icon: "memory" icon: "memory"
@ -280,7 +332,7 @@ Item {
width: Math.round(32 * scaling) width: Math.round(32 * scaling)
height: parent.height - Style.marginM * scaling * 2 height: parent.height - Style.marginM * scaling * 2
spacing: Style.marginS * scaling spacing: Style.marginS * scaling
visible: true // Temporarily show vertical layout for debugging visible: barPosition === "left" || barPosition === "right"
// CPU Usage Component // CPU Usage Component
Item { Item {

View file

@ -189,7 +189,7 @@ Item {
width: root.width - horizontalPadding * 2 width: root.width - horizontalPadding * 2
x: horizontalPadding x: horizontalPadding
visible: barPosition === "top" || barPosition === "bottom" visible: barPosition === "top" || barPosition === "bottom"
Repeater { Repeater {
id: workspaceRepeaterHorizontal id: workspaceRepeaterHorizontal
model: localWorkspaces model: localWorkspaces
@ -334,7 +334,7 @@ Item {
height: root.height - horizontalPadding * 2 height: root.height - horizontalPadding * 2
y: horizontalPadding y: horizontalPadding
visible: barPosition === "left" || barPosition === "right" visible: barPosition === "left" || barPosition === "right"
Repeater { Repeater {
id: workspaceRepeaterVertical id: workspaceRepeaterVertical
model: localWorkspaces model: localWorkspaces