feat(bar): add explicit iconPosition control for CustomButton widget

Replace auto-calculated icon position (based on widget bar section) with
user-controlled iconPosition setting ("left" or "right", default "left").
This commit is contained in:
loner
2026-04-06 06:20:41 +08:00
parent 6205749472
commit 9cc8b36804
8 changed files with 50 additions and 11 deletions
+3
View File
@@ -10,6 +10,7 @@ Item {
required property ShellScreen screen
property string icon: ""
property string iconPosition: ""
property string text: ""
property string suffix: ""
property var tooltipText
@@ -55,6 +56,7 @@ Item {
BarPillVertical {
screen: root.screen
icon: root.icon
iconPosition: root.iconPosition
text: root.text
suffix: root.suffix
tooltipText: root.tooltipText
@@ -84,6 +86,7 @@ Item {
BarPillHorizontal {
screen: root.screen
icon: root.icon
iconPosition: root.iconPosition
text: root.text
suffix: root.suffix
tooltipText: root.tooltipText
+11 -8
View File
@@ -18,6 +18,7 @@ Item {
property bool forceOpen: false
property bool forceClose: false
property bool oppositeDirection: false
property string iconPosition: "left"
property bool hovered: false
property color customBackgroundColor: "transparent"
property color customTextIconColor: "transparent"
@@ -111,16 +112,18 @@ Item {
x: {
if (!hasIcon)
return 0;
return oppositeDirection ? (iconCircle.x + iconCircle.width / 2) : (iconCircle.x + iconCircle.width / 2) - width;
return iconPosition === "right"
? (iconCircle.x + iconCircle.width / 2) - width
: (iconCircle.x + iconCircle.width / 2);
}
opacity: revealed ? Style.opacityFull : Style.opacityNone
color: "transparent" // Make pill background transparent to avoid double opacity
topLeftRadius: oppositeDirection ? 0 : Style.radiusM
bottomLeftRadius: oppositeDirection ? 0 : Style.radiusM
topRightRadius: oppositeDirection ? Style.radiusM : 0
bottomRightRadius: oppositeDirection ? Style.radiusM : 0
topLeftRadius: iconPosition === "right" ? Style.radiusM : 0
bottomLeftRadius: iconPosition === "right" ? Style.radiusM : 0
topRightRadius: iconPosition === "right" ? 0 : Style.radiusM
bottomRightRadius: iconPosition === "right" ? 0 : Style.radiusM
anchors.verticalCenter: parent.verticalCenter
NText {
@@ -132,10 +135,10 @@ Item {
// Better text horizontal centering
var centerX = (parent.width - width) / 2;
var offset = oppositeDirection ? Style.marginXS : -Style.marginXS;
var offset = iconPosition === "right" ? -Style.marginXS : Style.marginXS;
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;
offset += iconPosition === "right" ? Style.marginXXS : -Style.marginXXS;
}
return centerX + offset;
}
@@ -171,7 +174,7 @@ Item {
color: "transparent" // Make icon background transparent to avoid double opacity
anchors.verticalCenter: parent.verticalCenter
x: oppositeDirection ? 0 : (parent.width - width)
x: iconPosition === "right" ? (parent.width - width) : 0
NIcon {
icon: root.icon
+4 -3
View File
@@ -18,6 +18,7 @@ Item {
property bool forceOpen: false
property bool forceClose: false
property bool oppositeDirection: false
property string iconPosition: "left"
property bool hovered: false
property bool rotateText: false
property color customBackgroundColor: "transparent"
@@ -48,9 +49,9 @@ Item {
readonly property int maxPillWidth: rotateText ? Math.max(buttonSize, Math.round(textItem.implicitHeight + Style.margin2M)) : buttonSize
readonly property int maxPillHeight: rotateText ? Math.max(1, Math.round(textItem.implicitWidth + Style.margin2M + Math.round(iconCircle.height / 4))) : Math.max(1, Math.round(textItem.implicitHeight + Style.margin2M))
// Determine pill direction based on section position
readonly property bool openDownward: oppositeDirection
readonly property bool openUpward: !oppositeDirection
// Determine pill direction based on icon position
readonly property bool openDownward: iconPosition === "right"
readonly property bool openUpward: iconPosition === "left"
// Effective shown state (true if animated open or forced, but not if force closed)
readonly property bool revealed: !forceClose && (forceOpen || showPill)
+2
View File
@@ -37,6 +37,7 @@ Item {
readonly property bool isVerticalBar: barPosition === "left" || barPosition === "right"
readonly property string customIcon: widgetSettings.icon || widgetMetadata.icon
readonly property string iconPosition: widgetSettings.iconPosition || widgetMetadata.iconPosition
readonly property string leftClickExec: widgetSettings.leftClickExec || widgetMetadata.leftClickExec
readonly property bool leftClickUpdateText: widgetSettings.leftClickUpdateText ?? widgetMetadata.leftClickUpdateText
readonly property string rightClickExec: widgetSettings.rightClickExec || widgetMetadata.rightClickExec
@@ -200,6 +201,7 @@ Item {
opacity: _pillOpacity
screen: root.screen
oppositeDirection: BarService.getPillDirection(root)
iconPosition: root.iconPosition
icon: _pillIcon
text: _pillText
rotateText: isVerticalBar && currentMaxTextLength > 0
@@ -18,6 +18,7 @@ ColumnLayout {
signal settingsChanged(var settings)
property string valueIcon: widgetData.icon !== undefined ? widgetData.icon : widgetMetadata.icon
property string valueIconPosition: widgetData.iconPosition !== undefined ? widgetData.iconPosition : widgetMetadata.iconPosition
property bool valueTextStream: widgetData.textStream !== undefined ? widgetData.textStream : widgetMetadata.textStream
property bool valueParseJson: widgetData.parseJson !== undefined ? widgetData.parseJson : widgetMetadata.parseJson
property int valueMaxTextLengthHorizontal: widgetData?.maxTextLength?.horizontal ?? widgetMetadata?.maxTextLength?.horizontal
@@ -34,6 +35,7 @@ ColumnLayout {
function saveSettings() {
var settings = Object.assign({}, widgetData || {});
settings.icon = valueIcon;
settings.iconPosition = valueIconPosition;
settings.leftClickExec = leftClickExecInput.text;
settings.leftClickUpdateText = leftClickUpdateText.checked;
settings.rightClickExec = rightClickExecInput.text;
@@ -97,6 +99,28 @@ ColumnLayout {
}
}
NComboBox {
id: iconPositionComboBox
label: I18n.tr("bar.custom-button.icon-position-label")
description: I18n.tr("bar.custom-button.icon-position-description")
model: [
{
name: I18n.tr("bar.custom-button.icon-position-left"),
key: "left"
},
{
name: I18n.tr("bar.custom-button.icon-position-right"),
key: "right"
}
]
currentKey: valueIconPosition
onSelected: key => {
valueIconPosition = key;
saveSettings();
}
defaultValue: widgetMetadata.iconPosition
}
NToggle {
id: showIconToggle
label: I18n.tr("bar.custom-button.show-icon-label")