feat(ALabel): allow custom percentage thresholds in format-icons
Previously, format-icons with N icons would divide the 0-100 range
into N equal parts. This made it impossible to define custom ranges
like 0%, 1-69%, 70-100%.
This adds support for an alternative object syntax in format-icons:
"format-icons": [
{ "icon": "▁", "max": 0},
{ "icon": "▅", "max": 69 },
{ "icon": "▇", "max": 100 }
]
The array is iterated in order and the first icon whose max value
is >= the current percentage is returned. If no threshold matches,
the last icon is used as fallback. The existing string array syntax
remains fully supported and unchanged.
Applies to both getIcon overloads, affecting all modules that use
format-icons (battery, pulseaudio, network, backlight, etc.).
Closes #5150
This commit is contained in:
+40
-2
@@ -150,7 +150,26 @@ std::string ALabel::getIcon(uint16_t percentage, const std::string& alt, uint16_
|
||||
}
|
||||
if (format_icons.isArray()) {
|
||||
auto size = format_icons.size();
|
||||
if (size != 0U) {
|
||||
if (size != 0U && format_icons[0].isObject()) {
|
||||
std::string last_icon;
|
||||
for (const auto& threshold : format_icons) {
|
||||
if (!threshold.isObject() || !threshold["icon"].isString() || !threshold["max"].isUInt()) {
|
||||
static bool warned = false;
|
||||
if (!warned) {
|
||||
spdlog::warn("format-icons: skipping invalid threshold object, expected {\"icon\": \"...\", \"max\": N}");
|
||||
warned = true;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
last_icon = threshold["icon"].asString();
|
||||
if (percentage <= threshold["max"].asUInt()) {
|
||||
return last_icon;
|
||||
}
|
||||
}
|
||||
if (!last_icon.empty()) {
|
||||
return last_icon;
|
||||
}
|
||||
} else if (size != 0U) {
|
||||
auto divisor = std::max(1U, (max == 0 ? 100U : static_cast<unsigned>(max)) / size);
|
||||
auto idx = std::clamp(percentage / divisor, 0U, size - 1);
|
||||
format_icons = format_icons[idx];
|
||||
@@ -177,7 +196,26 @@ std::string ALabel::getIcon(uint16_t percentage, const std::vector<std::string>&
|
||||
}
|
||||
if (format_icons.isArray()) {
|
||||
auto size = format_icons.size();
|
||||
if (size != 0U) {
|
||||
if (size != 0U && format_icons[0].isObject()) {
|
||||
std::string last_icon;
|
||||
for (const auto& threshold : format_icons) {
|
||||
if (!threshold.isObject() || !threshold["icon"].isString() || !threshold["max"].isUInt()) {
|
||||
static bool warned = false;
|
||||
if (!warned) {
|
||||
spdlog::warn("format-icons: skipping invalid threshold object, expected {\"icon\": \"...\", \"max\": N}");
|
||||
warned = true;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
last_icon = threshold["icon"].asString();
|
||||
if (percentage <= threshold["max"].asUInt()) {
|
||||
return last_icon;
|
||||
}
|
||||
}
|
||||
if (!last_icon.empty()) {
|
||||
return last_icon;
|
||||
}
|
||||
} else if (size != 0U) {
|
||||
auto divisor = std::max(1U, (max == 0 ? 100U : static_cast<unsigned>(max)) / size);
|
||||
auto idx = std::clamp(percentage / divisor, 0U, size - 1);
|
||||
format_icons = format_icons[idx];
|
||||
|
||||
Reference in New Issue
Block a user