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
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 {
}
}
}
}
}
}

View file

@ -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

View file

@ -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
}
}

View file

@ -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 {

View file

@ -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