From e7393524ad2945e6a180ef607e64426ec57f022a Mon Sep 17 00:00:00 2001 From: PM Date: Tue, 21 Oct 2025 01:23:05 +0530 Subject: [PATCH 1/5] Implement different display types for bar meters Allow bar meters to enable "sub-pixel" rendering. Bar meter styles can be changed in setup (F2) under Display Options. Co-Authored-By: Benny Baumann --- DisplayOptionsPanel.c | 6 ++++++ Meter.c | 40 ++++++++++++++++++++++++++++++++++++++-- MeterMode.h | 1 + Settings.c | 16 ++++++++++++++++ Settings.h | 3 +++ 5 files changed, 64 insertions(+), 2 deletions(-) diff --git a/DisplayOptionsPanel.c b/DisplayOptionsPanel.c index 234df4b68..28a7e3dc4 100644 --- a/DisplayOptionsPanel.c +++ b/DisplayOptionsPanel.c @@ -203,6 +203,12 @@ DisplayOptionsPanel* DisplayOptionsPanel_new(Settings* settings, ScreenManager* Panel_add(super, (Object*) CheckItem_newByRef("Highlight new and old processes", &(settings->highlightChanges))); Panel_add(super, (Object*) NumberItem_newByRef("- Highlight time (in seconds)", &(settings->highlightDelaySecs), 0, 1, 24 * 60 * 60)); Panel_add(super, (Object*) NumberItem_newByRef("Hide main function bar (0 - off, 1 - on ESC until next input, 2 - permanently)", &(settings->hideFunctionBar), 0, 0, 2)); + + #ifdef HAVE_LIBNCURSESW + if(CRT_utf8) + Panel_add(super, (Object*) NumberItem_newByRef("Bar Type (0 - default)", (int*)&(settings->barType), 0, 0, BAR_METER_NUM_STYLES-1)); + #endif + #ifdef HAVE_LIBHWLOC Panel_add(super, (Object*) CheckItem_newByRef("Show topology when selecting affinity by default", &(settings->topologyAffinity))); #endif diff --git a/Meter.c b/Meter.c index 4f8f76673..0efff8f93 100644 --- a/Meter.c +++ b/Meter.c @@ -86,6 +86,18 @@ static void TextMeterMode_draw(Meter* this, int x, int y, int w) { static const char BarMeterMode_characters[] = "|#*@$%&."; +#ifdef HAVE_LIBNCURSESW +const wchar_t* bars[BAR_METER_NUM_STYLES] = { + L"|", + L"#", + L"⣿⡀⡄⡆⡇⣇⣧⣷", + L"█░░▒▒▓▓█", + L"█▏▎▍▌▋▊▉", + L"█▁▂▃▄▅▆▇", + L"█▌▌▌▌███" +}; +#endif + static void BarMeterMode_draw(Meter* this, int x, int y, int w) { assert(x >= 0); assert(w <= INT_MAX - x); @@ -149,6 +161,14 @@ static void BarMeterMode_draw(Meter* this, int x, int y, int w) { assert(startPos + w <= RichString_sizeVal(bar)); int blockSizes[10]; +#ifdef HAVE_LIBNCURSESW + Settings* settings = this->host->settings; + assert(settings->barType < ( sizeof(bars) / sizeof(wchar_t*) )); + assert(settings->barType >= 0); + const wchar_t* currBar = bars[settings->barType]; + int barLen = (int)wcslen(currBar); + int extraWidth = 0; +#endif // First draw in the bar[] buffer... int offset = 0; @@ -158,19 +178,35 @@ static void BarMeterMode_draw(Meter* this, int x, int y, int w) { value = MINIMUM(value, this->total); blockSizes[i] = ceil((value / this->total) * w); blockSizes[i] = MINIMUM(blockSizes[i], w - offset); + +#ifdef HAVE_LIBNCURSESW + extraWidth = (int)ceil((value / this->total) * w * barLen) % barLen; +#endif } else { blockSizes[i] = 0; } int nextOffset = offset + blockSizes[i]; - for (int j = offset; j < nextOffset; j++) + for (int j = offset; j < nextOffset; j++) { if (RichString_getCharVal(bar, startPos + j) == ' ') { if (CRT_colorScheme == COLORSCHEME_MONOCHROME) { assert(i < strlen(BarMeterMode_characters)); RichString_setChar(&bar, startPos + j, BarMeterMode_characters[i]); - } else { + } +#ifdef HAVE_LIBNCURSESW + else if(CRT_utf8 && settings->barType) { + if(j==nextOffset-1){ + RichString_setChar(&bar, startPos+nextOffset-1, currBar[extraWidth]); + } else { + RichString_setChar(&bar, startPos + j, currBar[0]); + } + } +#endif + else { RichString_setChar(&bar, startPos + j, '|'); } } + } + offset = nextOffset; } diff --git a/MeterMode.h b/MeterMode.h index 8a4355417..603c3d974 100644 --- a/MeterMode.h +++ b/MeterMode.h @@ -26,4 +26,5 @@ typedef unsigned int MeterModeId; (1 << LED_METERMODE) | \ 0) // Avoids edits when updating +#define BAR_METER_NUM_STYLES 7 #endif diff --git a/Settings.c b/Settings.c index be0019788..d30e16c9d 100644 --- a/Settings.c +++ b/Settings.c @@ -5,6 +5,7 @@ Released under the GNU GPLv2+, see the COPYING file in the source distribution for its full text. */ +#include "MeterMode.h" #include "config.h" // IWYU pragma: keep #include "Settings.h" @@ -516,6 +517,13 @@ static bool Settings_read(Settings* this, const char* fileName, const Machine* h didReadMeters = true; } else if (String_eq(option[0], "hide_function_bar")) { this->hideFunctionBar = atoi(option[1]); + #ifdef HAVE_LIBNCURSESW + } else if (String_eq(option[0], "bar_type")) { + long value = strtol(option[1], NULL, 10); + if (value < 0 || value > BAR_METER_NUM_STYLES) + value = 0; + this->barType = (unsigned int)value; + #endif #ifdef HAVE_LIBHWLOC } else if (String_eq(option[0], "topology_affinity")) { this->topologyAffinity = !!atoi(option[1]); @@ -714,6 +722,9 @@ int Settings_write(const Settings* this, bool onCrash) { #endif printSettingInteger("delay", (int) this->delay); printSettingInteger("hide_function_bar", (int) this->hideFunctionBar); + #ifdef HAVE_LIBNCURSESW + printSettingInteger("bar_type", (int) this->barType); + #endif #ifdef HAVE_LIBHWLOC printSettingInteger("topology_affinity", this->topologyAffinity); #endif @@ -821,6 +832,11 @@ Settings* Settings_new(const Machine* host, Hashtable* dynamicMeters, Hashtable* this->showMergedCommand = false; this->hideFunctionBar = 0; this->headerMargin = true; + + #ifdef HAVE_LIBNCURSESW + this->barType = 0; + #endif + #ifdef HAVE_LIBHWLOC this->topologyAffinity = false; #endif diff --git a/Settings.h b/Settings.h index 01e808e86..72287f281 100644 --- a/Settings.h +++ b/Settings.h @@ -106,6 +106,9 @@ typedef struct Settings_ { bool enableMouse; #endif int hideFunctionBar; // 0 - off, 1 - on ESC until next input, 2 - permanently + #ifdef HAVE_LIBNCURSESW + unsigned int barType; + #endif #ifdef HAVE_LIBHWLOC bool topologyAffinity; #endif From 87f75bb3d2bbadf142ad88a04760834c15403f34 Mon Sep 17 00:00:00 2001 From: rustedusted Date: Sun, 26 Oct 2025 21:44:29 +0530 Subject: [PATCH 2/5] Update DisplayOptionsPanel.c Co-authored-by: BenBE --- DisplayOptionsPanel.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DisplayOptionsPanel.c b/DisplayOptionsPanel.c index 28a7e3dc4..093685260 100644 --- a/DisplayOptionsPanel.c +++ b/DisplayOptionsPanel.c @@ -205,7 +205,7 @@ DisplayOptionsPanel* DisplayOptionsPanel_new(Settings* settings, ScreenManager* Panel_add(super, (Object*) NumberItem_newByRef("Hide main function bar (0 - off, 1 - on ESC until next input, 2 - permanently)", &(settings->hideFunctionBar), 0, 0, 2)); #ifdef HAVE_LIBNCURSESW - if(CRT_utf8) + if (CRT_utf8) Panel_add(super, (Object*) NumberItem_newByRef("Bar Type (0 - default)", (int*)&(settings->barType), 0, 0, BAR_METER_NUM_STYLES-1)); #endif From 3bd039b9d94b31bee5ded8ff1e2f5508927bdd4a Mon Sep 17 00:00:00 2001 From: rustedusted Date: Sun, 26 Oct 2025 21:46:00 +0530 Subject: [PATCH 3/5] Update Meter.c Co-authored-by: BenBE --- Meter.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Meter.c b/Meter.c index 0efff8f93..347f0cbc9 100644 --- a/Meter.c +++ b/Meter.c @@ -193,7 +193,7 @@ static void BarMeterMode_draw(Meter* this, int x, int y, int w) { RichString_setChar(&bar, startPos + j, BarMeterMode_characters[i]); } #ifdef HAVE_LIBNCURSESW - else if(CRT_utf8 && settings->barType) { + else if (CRT_utf8 && settings->barType) { if(j==nextOffset-1){ RichString_setChar(&bar, startPos+nextOffset-1, currBar[extraWidth]); } else { From f64d0c1ba9d8428c3291184267c9f0200d8647a1 Mon Sep 17 00:00:00 2001 From: rustedusted Date: Sun, 26 Oct 2025 21:46:14 +0530 Subject: [PATCH 4/5] Update Meter.c Co-authored-by: BenBE --- Meter.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Meter.c b/Meter.c index 347f0cbc9..7241608a7 100644 --- a/Meter.c +++ b/Meter.c @@ -194,7 +194,7 @@ static void BarMeterMode_draw(Meter* this, int x, int y, int w) { } #ifdef HAVE_LIBNCURSESW else if (CRT_utf8 && settings->barType) { - if(j==nextOffset-1){ + if (j == nextOffset - 1) { RichString_setChar(&bar, startPos+nextOffset-1, currBar[extraWidth]); } else { RichString_setChar(&bar, startPos + j, currBar[0]); From 1d95f2134123468571fa9693c248d0720b00c839 Mon Sep 17 00:00:00 2001 From: rustedusted Date: Sun, 26 Oct 2025 21:46:26 +0530 Subject: [PATCH 5/5] Update Meter.c Co-authored-by: BenBE --- Meter.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Meter.c b/Meter.c index 7241608a7..d1ae4d4c1 100644 --- a/Meter.c +++ b/Meter.c @@ -195,7 +195,7 @@ static void BarMeterMode_draw(Meter* this, int x, int y, int w) { #ifdef HAVE_LIBNCURSESW else if (CRT_utf8 && settings->barType) { if (j == nextOffset - 1) { - RichString_setChar(&bar, startPos+nextOffset-1, currBar[extraWidth]); + RichString_setChar(&bar, startPos + nextOffset - 1, currBar[extraWidth]); } else { RichString_setChar(&bar, startPos + j, currBar[0]); }