Merge pull request #664 from lonerOrz/fix/vertical-bar-text

fix(custom button): Adjust the custom button text display when the bar is vertical
This commit is contained in:
Lemmy
2025-11-10 08:34:54 -05:00
committed by GitHub
13 changed files with 106 additions and 32 deletions
+2
View File
@@ -17,6 +17,7 @@ Item {
property bool forceClose: false
property bool oppositeDirection: false
property bool hovered: false
property bool rotateText: false
readonly property string barPosition: Settings.data.bar.position
readonly property bool isVerticalBar: barPosition === "left" || barPosition === "right"
@@ -52,6 +53,7 @@ Item {
oppositeDirection: root.oppositeDirection
hovered: root.hovered
density: root.density
rotateText: root.rotateText
onShown: root.shown()
onHidden: root.hidden()
onEntered: root.entered()
+13 -11
View File
@@ -18,6 +18,7 @@ Item {
property bool forceClose: false
property bool oppositeDirection: false
property bool hovered: false
property bool rotateText: false
// Bar position detection for pill direction
readonly property string barPosition: Settings.data.bar.position
@@ -48,8 +49,8 @@ Item {
readonly property int pillHeight: buttonSize
readonly property int pillPaddingVertical: 3 * 2 // Very precise adjustment don't replace by Style.margin
readonly property int pillOverlap: Math.round(buttonSize * 0.5)
readonly property int maxPillWidth: buttonSize
readonly property int maxPillHeight: Math.max(1, Math.round(textItem.implicitHeight + pillPaddingVertical * 4))
readonly property int maxPillWidth: rotateText ? Math.max(buttonSize, Math.round(textItem.implicitHeight + pillPaddingVertical * 2)) : buttonSize
readonly property int maxPillHeight: rotateText ? Math.max(1, Math.round(textItem.implicitWidth + pillPaddingVertical * 2 + Math.round(iconCircle.height / 4))) : Math.max(1, Math.round(textItem.implicitHeight + pillPaddingVertical * 4))
readonly property real iconSize: {
switch (root.density) {
@@ -109,14 +110,8 @@ Item {
id: textItem
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
anchors.verticalCenterOffset: {
var offset = openDownward ? Math.round(pillPaddingVertical * 0.75) : -Math.round(pillPaddingVertical * 0.75)
if (forceOpen) {
// If its force open, the icon disc background is the same color as the bg pill move text slightly
offset += oppositeDirection ? -Style.marginXXS : Style.marginXXS
}
return offset
}
anchors.verticalCenterOffset: rotateText ? Math.round(iconCircle.height / 4) : getVerticalCenterOffset()
rotation: rotateText ? -90 : 0
text: root.text + root.suffix
family: Settings.data.ui.fontFixed
pointSize: textSize
@@ -126,8 +121,15 @@ Item {
verticalAlignment: Text.AlignVCenter
color: forceOpen ? Color.mOnSurface : Color.mPrimary
visible: revealed
}
function getVerticalCenterOffset() {
var offset = openDownward ? Math.round(pillPaddingVertical * 0.75) : -Math.round(pillPaddingVertical * 0.75)
if (forceOpen) {
offset += oppositeDirection ? -Style.marginXXS : Style.marginXXS
}
return offset
}
}
Behavior on width {
enabled: showAnim.running || hideAnim.running
NumberAnimation {
+48 -20
View File
@@ -30,7 +30,8 @@ Item {
return {}
}
// Use settings or defaults from BarWidgetRegistry
readonly property bool isVerticalBar: Settings.data.bar.position === "left" || Settings.data.bar.position === "right"
readonly property string customIcon: widgetSettings.icon || widgetMetadata.icon
readonly property string leftClickExec: widgetSettings.leftClickExec || widgetMetadata.leftClickExec
readonly property string rightClickExec: widgetSettings.rightClickExec || widgetMetadata.rightClickExec
@@ -40,8 +41,11 @@ Item {
readonly property int textIntervalMs: widgetSettings.textIntervalMs !== undefined ? widgetSettings.textIntervalMs : (widgetMetadata.textIntervalMs || 3000)
readonly property string textCollapse: widgetSettings.textCollapse !== undefined ? widgetSettings.textCollapse : (widgetMetadata.textCollapse || "")
readonly property bool parseJson: widgetSettings.parseJson !== undefined ? widgetSettings.parseJson : (widgetMetadata.parseJson || false)
readonly property bool hideTextInVerticalBar: widgetSettings.hideTextInVerticalBar !== undefined ? widgetSettings.hideTextInVerticalBar : (widgetMetadata.hideTextInVerticalBar || false)
readonly property bool hasExec: (leftClickExec || rightClickExec || middleClickExec)
readonly property bool shouldShowText: !isVerticalBar || !hideTextInVerticalBar
implicitWidth: pill.width
implicitHeight: pill.height
@@ -50,25 +54,37 @@ Item {
oppositeDirection: BarService.getPillDirection(root)
icon: _dynamicIcon !== "" ? _dynamicIcon : customIcon
text: _dynamicText
text: shouldShowText ? _dynamicText : ""
density: Settings.data.bar.density
rotateText: isVerticalBar && !hideTextInVerticalBar
autoHide: false
forceOpen: _dynamicText !== ""
tooltipText: {
if (!hasExec) {
return "Custom button, configure in settings."
} else {
var lines = []
var tooltipLines = []
if (hasExec) {
if (leftClickExec !== "") {
lines.push(`Left click: ${leftClickExec}.`)
tooltipLines.push(`Left click: ${leftClickExec}.`)
}
if (rightClickExec !== "") {
lines.push(`Right click: ${rightClickExec}.`)
tooltipLines.push(`Right click: ${rightClickExec}.`)
}
if (middleClickExec !== "") {
lines.push(`Middle click: ${middleClickExec}.`)
tooltipLines.push(`Middle click: ${middleClickExec}.`)
}
return lines.join("\n")
}
if (_dynamicTooltip !== "") {
if (tooltipLines.length > 0) {
tooltipLines.push("")
}
tooltipLines.push(_dynamicTooltip)
}
if (tooltipLines.length === 0) {
return "Custom button, configure in settings."
} else {
return tooltipLines.join("\n")
}
}
@@ -80,13 +96,14 @@ Item {
// Internal state for dynamic text
property string _dynamicText: ""
property string _dynamicIcon: ""
property string _dynamicTooltip: ""
// Periodically run the text command (if set)
Timer {
id: refreshTimer
interval: Math.max(250, textIntervalMs)
repeat: true
running: !textStream && textCommand && textCommand.length > 0
running: shouldShowText && !textStream && textCommand && textCommand.length > 0
triggeredOnStart: true
onTriggered: root.runTextCommand()
}
@@ -95,7 +112,7 @@ Item {
Timer {
id: restartTimer
interval: 1000
running: textStream && !textProc.running
running: shouldShowText && textStream && !textProc.running
onTriggered: root.runTextCommand()
}
@@ -123,38 +140,49 @@ Item {
function parseDynamicContent(content) {
var contentStr = String(content || "").trim()
if (contentStr.indexOf("\n") !== -1) {
contentStr = contentStr.split("\n")[0]
}
if (parseJson) {
var lineToParse = contentStr
if (!textStream && contentStr.includes('\n')) {
const lines = contentStr.split('\n').filter(line => line.trim() !== '')
if (lines.length > 0) {
lineToParse = lines[lines.length - 1]
}
}
try {
var parsed = JSON.parse(contentStr)
var text = parsed.text || ""
const parsed = JSON.parse(lineToParse)
const text = parsed.text || ""
const icon = parsed.icon || ""
const tooltip = parsed.tooltip || ""
if (checkCollapse(text)) {
_dynamicText = ""
_dynamicIcon = ""
_dynamicTooltip = ""
return
}
_dynamicText = text
_dynamicIcon = parsed.icon || ""
_dynamicIcon = icon
_dynamicTooltip = tooltip
return
} catch (e) {
// Not a valid JSON, treat as plain text
Logger.w("CustomButton", `Failed to parse JSON. Content: "${lineToParse}"`)
}
}
if (checkCollapse(contentStr)) {
_dynamicText = ""
_dynamicIcon = ""
_dynamicTooltip = ""
return
}
_dynamicText = contentStr
_dynamicIcon = ""
_dynamicTooltip = ""
}
function checkCollapse(text) {
@@ -15,6 +15,7 @@ ColumnLayout {
property string valueIcon: widgetData.icon !== undefined ? widgetData.icon : widgetMetadata.icon
property bool valueTextStream: widgetData.textStream !== undefined ? widgetData.textStream : widgetMetadata.textStream
property bool valueParseJson: widgetData.parseJson !== undefined ? widgetData.parseJson : widgetMetadata.parseJson
property bool valueHideTextInVerticalBar: widgetData.hideTextInVerticalBar !== undefined ? widgetData.hideTextInVerticalBar : widgetMetadata.hideTextInVerticalBar
function saveSettings() {
var settings = Object.assign({}, widgetData || {})
@@ -26,6 +27,7 @@ ColumnLayout {
settings.textCollapse = textCollapseInput.text
settings.textStream = valueTextStream
settings.parseJson = valueParseJson
settings.hideTextInVerticalBar = valueHideTextInVerticalBar
settings.textIntervalMs = parseInt(textIntervalInput.text || textIntervalInput.placeholderText, 10)
return settings
}
@@ -94,6 +96,13 @@ ColumnLayout {
label: I18n.tr("bar.widget-settings.custom-button.dynamic-text")
}
NToggle {
label: I18n.tr("bar.widget-settings.custom-button.hide-vertical.label", "Hide text in vertical bar")
description: I18n.tr("bar.widget-settings.custom-button.hide-vertical.description", "If enabled, the text from the command output will not be shown when the bar is in a vertical layout (left or right).")
checked: valueHideTextInVerticalBar
onToggled: checked => valueHideTextInVerticalBar = checked
}
NToggle {
id: textStreamInput
label: I18n.tr("bar.widget-settings.custom-button.text-stream.label")