feat(ui): add separate icon and text colorization for CustomButton

- Add colorizeSystemText setting for text color (icon only was already supported)
- JSON parse supports iconColor and textColor fields separately
- Legacy "color" field still works for both icon and text
- Enable colorization no longer depends on show icon setting
- Refactor resolveColor helper to eliminate duplicate code
This commit is contained in:
loner
2026-04-06 08:18:28 +08:00
parent 55c7f344b3
commit f21e8fb82a
4 changed files with 61 additions and 12 deletions
+3
View File
@@ -105,6 +105,8 @@
"collapse-condition-description": "If the output text matches this value, the button will collapse.",
"collapse-condition-label": "Collapse condition",
"color-selection-description": "Apply theme colors to icon and text.",
"icon-color-selection-description": "Apply theme colors to icons.",
"text-color-selection-description": "Apply theme colors to text.",
"default-tooltip": "Custom button, configure in settings",
"display-command-output-description": "Enter a command to run at a regular interval. The first line of its output will be displayed as text.",
"display-command-output-label": "Display command output",
@@ -523,6 +525,7 @@
"select-color": "Select color",
"select-color-description": "Apply theme colors for emphasis.",
"select-icon-color": "Select icon color",
"select-text-color": "Select text color",
"settings": "Settings",
"shortcuts": "Shortcuts",
"shutdown": "Shutdown",
+39 -9
View File
@@ -146,8 +146,13 @@ Item {
return widgetSettings.colorizeSystemIcon;
return widgetMetadata.colorizeSystemIcon !== undefined ? widgetMetadata.colorizeSystemIcon : "none";
}
readonly property string colorizeSystemText: {
if (widgetSettings.colorizeSystemText !== undefined)
return widgetSettings.colorizeSystemText;
return widgetMetadata.colorizeSystemText !== undefined ? widgetMetadata.colorizeSystemText : "none";
}
readonly property bool isColorizing: enableColorization && colorizeSystemIcon !== "none"
readonly property bool isColorizing: enableColorization && (colorizeSystemIcon !== "none" || colorizeSystemText !== "none")
// Get color value from color name (returns null for invalid names)
function _getColorValue(colorName, forHover) {
@@ -188,8 +193,10 @@ Item {
return isHover ? Color.mOnHover : Color.mOnSurface;
}
readonly property color iconColor: _resolveIconColor(_dynamicColor, colorizeSystemIcon, false)
readonly property color iconHoverColor: _resolveIconColor(_dynamicColor, colorizeSystemIcon, true)
readonly property color iconColor: _resolveIconColor(_dynamicIconColor || _dynamicColor, colorizeSystemIcon, false)
readonly property color iconHoverColor: _resolveIconColor(_dynamicIconColor || _dynamicColor, colorizeSystemIcon, true)
readonly property color textColor: _resolveIconColor(_dynamicTextColor || _dynamicColor, colorizeSystemText, false)
readonly property color textHoverColor: _resolveIconColor(_dynamicTextColor || _dynamicColor, colorizeSystemText, true)
implicitWidth: pill.width
implicitHeight: pill.height
@@ -208,7 +215,8 @@ Item {
autoHide: false
forceOpen: _pillForceOpen
forceClose: !_pillForceOpen
customTextIconColor: iconColor
customIconColor: iconColor
customTextColor: textColor
// Helper function to build tooltip content
function _buildTooltipContent() {
@@ -287,6 +295,8 @@ Item {
property string _dynamicIcon: ""
property string _dynamicTooltip: ""
property string _dynamicColor: ""
property string _dynamicIconColor: ""
property string _dynamicTextColor: ""
// Maximum length for text display before scrolling (different values for horizontal and vertical)
readonly property var maxTextLength: {
@@ -415,11 +425,23 @@ Item {
const text = parsed.text || "";
const icon = parsed.icon || "";
let tooltip = parsed.tooltip || "";
const color = parsed.color || "";
// Validate color value
// Support both "color" (legacy) and "iconColor"/"textColor" (new)
const legacyColor = parsed.color || "";
const iconColorKey = parsed.iconColor || "";
const textColorKey = parsed.textColor || "";
const validColors = ["primary", "secondary", "tertiary", "error", "none"];
const validColor = (color && validColors.includes(color)) ? color : "";
// Helper to resolve color: legacy > specific > none
function resolveColor(legacy, specific) {
if (legacy && validColors.includes(legacy)) return legacy;
if (specific && validColors.includes(specific)) return specific;
return "";
}
const resolvedIconColor = resolveColor(legacyColor, iconColorKey);
const resolvedTextColor = resolveColor(legacyColor, textColorKey);
if (checkCollapse(text)) {
_scrollState.originalText = "";
@@ -427,6 +449,8 @@ Item {
_dynamicIcon = "";
_dynamicTooltip = "";
_dynamicColor = "";
_dynamicIconColor = "";
_dynamicTextColor = "";
_scrollState.needsScrolling = false;
_scrollState.phase = 0;
_scrollState.phaseCounter = 0;
@@ -446,7 +470,9 @@ Item {
scrollTimer.stop();
}
_dynamicIcon = icon;
_dynamicColor = validColor;
_dynamicColor = legacyColor; // Keep legacy color for fallback
_dynamicIconColor = resolvedIconColor;
_dynamicTextColor = resolvedTextColor;
_dynamicTooltip = toHtml(tooltip);
_scrollState.offset = 0;
@@ -462,6 +488,8 @@ Item {
_dynamicIcon = "";
_dynamicTooltip = "";
_dynamicColor = "";
_dynamicIconColor = "";
_dynamicTextColor = "";
_scrollState.needsScrolling = false;
_scrollState.phase = 0;
_scrollState.phaseCounter = 0;
@@ -482,6 +510,8 @@ Item {
}
_dynamicIcon = "";
_dynamicColor = "";
_dynamicIconColor = "";
_dynamicTextColor = "";
_dynamicTooltip = toHtml(contentStr);
_scrollState.offset = 0;
}
@@ -32,6 +32,7 @@ ColumnLayout {
property bool valueShowTextTooltip: widgetData.showTextTooltip !== undefined ? widgetData.showTextTooltip : widgetMetadata.showTextTooltip
property bool valueEnableColorization: widgetData.enableColorization !== undefined ? widgetData.enableColorization : widgetMetadata.enableColorization
property string valueColorizeSystemIcon: widgetData.colorizeSystemIcon !== undefined ? widgetData.colorizeSystemIcon : widgetMetadata.colorizeSystemIcon
property string valueColorizeSystemText: widgetData.colorizeSystemText !== undefined ? widgetData.colorizeSystemText : widgetMetadata.colorizeSystemText
property string valueIpcIdentifier: widgetData.ipcIdentifier !== undefined ? widgetData.ipcIdentifier : widgetMetadata.ipcIdentifier
property string valueGeneralTooltipText: widgetData.generalTooltipText !== undefined ? widgetData.generalTooltipText : widgetMetadata.generalTooltipText
@@ -67,6 +68,7 @@ ColumnLayout {
settings.textIntervalMs = parseInt(textIntervalInput.text || textIntervalInput.placeholderText, 10);
settings.enableColorization = valueEnableColorization;
settings.colorizeSystemIcon = valueColorizeSystemIcon;
settings.colorizeSystemText = valueColorizeSystemText;
settings.ipcIdentifier = valueIpcIdentifier;
settings.generalTooltipText = valueGeneralTooltipText;
settingsChanged(settings);
@@ -156,14 +158,13 @@ ColumnLayout {
valueEnableColorization = checked;
saveSettings();
}
visible: valueShowIcon
defaultValue: widgetMetadata.enableColorization
}
NColorChoice {
visible: valueShowIcon && valueEnableColorization
visible: valueEnableColorization
label: I18n.tr("common.select-icon-color")
description: I18n.tr("bar.custom-button.color-selection-description")
description: I18n.tr("bar.custom-button.icon-color-selection-description")
currentKey: valueColorizeSystemIcon
onSelected: key => {
valueColorizeSystemIcon = key;
@@ -172,6 +173,18 @@ ColumnLayout {
defaultValue: widgetMetadata.colorizeSystemIcon
}
NColorChoice {
visible: valueEnableColorization
label: I18n.tr("common.select-text-color")
description: I18n.tr("bar.custom-button.text-color-selection-description")
currentKey: valueColorizeSystemText
onSelected: key => {
valueColorizeSystemText = key;
saveSettings();
}
defaultValue: widgetMetadata.colorizeSystemText
}
NTextInput {
Layout.fillWidth: true
label: I18n.tr("bar.custom-button.general-tooltip-text-label")
+3
View File
@@ -126,6 +126,7 @@ Singleton {
"customIconPath": "",
"colorizeDistroLogo": false,
"colorizeSystemIcon": "none",
"colorizeSystemText": "none",
"enableColorization": false
},
"CustomButton": {
@@ -160,6 +161,7 @@ Singleton {
},
"enableColorization": false,
"colorizeSystemIcon": "none",
"colorizeSystemText": "none",
"ipcIdentifier": ""
},
"DarkMode": {
@@ -189,6 +191,7 @@ Singleton {
"icon": "rocket",
"customIconPath": "",
"colorizeSystemIcon": "none",
"colorizeSystemText": "none",
"enableColorization": false,
"iconColor": "none"
},