From e13c88cea609fbf9869a9762ce2136a6bdea7621 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Tue, 18 Oct 2022 22:55:28 +0800 Subject: [PATCH] Global: support bar output for percentage value #294 --- CMakeLists.txt | 1 + completions/bash | 1 + src/common/bar.c | 48 ++++++++++++++++++++++ src/common/bar.h | 16 ++++++++ src/common/init.c | 2 + src/data/config_user.txt | 6 +++ src/data/help.txt | 1 + src/detection/battery/battery.h | 2 +- src/detection/battery/battery_apple.c | 4 +- src/detection/battery/battery_linux.c | 12 +++--- src/detection/battery/battery_windows.cpp | 4 +- src/fastfetch.c | 2 + src/fastfetch.h | 2 + src/modules/battery.c | 50 ++++++++++++++++------- src/modules/cpuUsage.c | 20 +++++++-- src/modules/disk.c | 25 ++++++++++-- src/modules/memory.c | 20 ++++++++- 17 files changed, 180 insertions(+), 36 deletions(-) create mode 100644 src/common/bar.c create mode 100644 src/common/bar.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 78bbf0d33..a595fa5d3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -221,6 +221,7 @@ set(LIBFASTFETCH_SRC src/common/settings.c src/common/library.c src/common/networking.c + src/common/bar.c src/logo/logo.c src/logo/builtin.c src/logo/image/image.c diff --git a/completions/bash b/completions/bash index 907f8c27f..fc771d5ad 100644 --- a/completions/bash +++ b/completions/bash @@ -218,6 +218,7 @@ __fastfetch_completion() "--set" "--set-keyless" "--player-name" + "--percent-type" "--public-ip-url" "--public-ip-timeout" "--weather-output-format" diff --git a/src/common/bar.c b/src/common/bar.c new file mode 100644 index 000000000..4b8ae00a3 --- /dev/null +++ b/src/common/bar.c @@ -0,0 +1,48 @@ +#include "bar.h" + +// green, yellow, red: print the color on nth (0~9) block +// set its value == 10 means the color will not be printed +void ffAppendPercentBar(FFinstance* instance, FFstrbuf* buffer, uint8_t percent, uint8_t green, uint8_t yellow, uint8_t red) +{ + assert(green <= 10 && yellow <= 10 && red <= 10); + + // [ 0%, 5%) prints 0 blocks + // [ 5%, 15%) prints 1 block; + // ... + // [85%, 95%) prints 9 blocks; + // [95%,100%] prints 10 blocks + percent = (percent + 5) / 10; + assert(percent <= 10); + + if(!instance->config.pipe) + ffStrbufAppendS(buffer, "\033[97m[ "); + else + ffStrbufAppendS(buffer, "[ "); + + for (uint8_t i = 0; i < percent; ++i) + { + if(!instance->config.pipe) + { + if (i == green) + ffStrbufAppendS(buffer, "\033[32m"); + else if (i == yellow) + ffStrbufAppendS(buffer, "\033[93m"); + else if (i == red) + ffStrbufAppendS(buffer, "\033[91m"); + } + ffStrbufAppendS(buffer, "■"); + } + + if (percent < 10) + { + if(!instance->config.pipe) + ffStrbufAppendS(buffer, "\033[97m"); + for (uint8_t i = percent; i < 10; ++i) + ffStrbufAppendS(buffer, "-"); + } + + if(!instance->config.pipe) + ffStrbufAppendS(buffer, "\033[97m ]" FASTFETCH_TEXT_MODIFIER_RESET); + else + ffStrbufAppendS(buffer, " ]"); +} diff --git a/src/common/bar.h b/src/common/bar.h new file mode 100644 index 000000000..a6c2be234 --- /dev/null +++ b/src/common/bar.h @@ -0,0 +1,16 @@ +#pragma once + +#ifndef FF_INCLUDED_common_bar +#define FF_INCLUDED_common_bar + +#include "fastfetch.h" + +enum +{ + FF_PERCENTAGE_TYPE_NUM_BIT = 1, + FF_PERCENTAGE_TYPE_BAR_BIT = 2, +}; + +void ffAppendPercentBar(FFinstance* instance, FFstrbuf* buffer, uint8_t percent, uint8_t green, uint8_t yellow, uint8_t red); + +#endif diff --git a/src/common/init.c b/src/common/init.c index af4ab7bfe..b2d69197c 100644 --- a/src/common/init.c +++ b/src/common/init.c @@ -274,6 +274,8 @@ static void defaultConfig(FFinstance* instance) ffStrbufInitA(&instance->config.osFile, 0); ffStrbufInitA(&instance->config.playerName, 0); + + instance->config.percentType = 1; } void ffInitInstance(FFinstance* instance) diff --git a/src/data/config_user.txt b/src/data/config_user.txt index 1e68fe85b..95518af0f 100644 --- a/src/data/config_user.txt +++ b/src/data/config_user.txt @@ -200,6 +200,12 @@ # Default is auto. #--gl auto +# Percentage output type option +# Applies to all modules that prints percentage values. Currently memory, swap, disk, battery and CPU usage are supported. +# Only works with default format ( without --module-format option ). +# 0: prints none; 1: prints percent number only; 2: prints bar only; 3: prints both percent number and bar +#--percent-type 1 + # Key options: # Sets the displayed key of a module # Can be any string. Some of theme take an argument like a format string. See "fastfetch --help format" for help. diff --git a/src/data/help.txt b/src/data/help.txt index 9d8c32027..ed25dcb11 100644 --- a/src/data/help.txt +++ b/src/data/help.txt @@ -107,6 +107,7 @@ Module specific options: --weather-output-format: The output weather format to be used. It must be URI encoded. --player-name: The name of the player to use --gl : Sets the opengl context creation library to use. Must be auto, egl, glx or osmesa. Default is auto + --percent-type : Sets the percentage output type. 1 for percentage number, 2 for bar, 3 for both. Default is 1 Parsing is not case sensitive. E.g. "--lib-PCI" is equal to "--Lib-Pci" If a value starts with a ?, it is optional. "true" will be used if not set. diff --git a/src/detection/battery/battery.h b/src/detection/battery/battery.h index 6269f590a..ab0021b91 100644 --- a/src/detection/battery/battery.h +++ b/src/detection/battery/battery.h @@ -12,7 +12,7 @@ typedef struct BatteryResult FFstrbuf manufacturer; FFstrbuf modelName; FFstrbuf technology; - FFstrbuf capacity; + double capacity; FFstrbuf status; double temperature; } BatteryResult; diff --git a/src/detection/battery/battery_apple.c b/src/detection/battery/battery_apple.c index 0e9667cf7..88499aaa7 100644 --- a/src/detection/battery/battery_apple.c +++ b/src/detection/battery/battery_apple.c @@ -55,7 +55,7 @@ const char* ffDetectBatteryImpl(FFinstance* instance, FFlist* results) const char* error; BatteryResult* battery = ffListAdd(results); - ffStrbufInit(&battery->capacity); + battery->capacity = 0.0/0.0; int currentCapacity, maxCapacity; if ((error = ffCfDictGetInt(properties, CFSTR("MaxCapacity"), &maxCapacity))) @@ -68,7 +68,7 @@ const char* ffDetectBatteryImpl(FFinstance* instance, FFlist* results) if(currentCapacity <= 0) return "Querying CurrentCapacity failed"; - ffStrbufAppendF(&battery->capacity, "%.0f", currentCapacity * 100.0 / maxCapacity); + battery->capacity = currentCapacity * 100.0 / maxCapacity; ffStrbufInit(&battery->manufacturer); ffStrbufInit(&battery->modelName); diff --git a/src/detection/battery/battery_linux.c b/src/detection/battery/battery_linux.c index 6a8643521..6fe799eb0 100644 --- a/src/detection/battery/battery_linux.c +++ b/src/detection/battery/battery_linux.c @@ -33,18 +33,18 @@ static void parseBattery(FFstrbuf* dir, FFlist* results) return; } - ffStrbufDestroy(&testBatteryBuffer); BatteryResult* result = ffListAdd(results); //capacity must exist and be not empty - ffStrbufInit(&result->capacity); ffStrbufAppendS(dir, "/capacity"); - ffReadFileBuffer(dir->chars, &result->capacity); + bool available = ffReadFileBuffer(dir->chars, &testBatteryBuffer); ffStrbufSubstrBefore(dir, dirLength); - - if(result->capacity.length == 0) + if(available) + result->capacity = ffStrbufToDouble(&testBatteryBuffer); + ffStrbufDestroy(&testBatteryBuffer); + if(!available) { - ffStrbufDestroy(&result->capacity); + result->capacity = 0.0/0.0; --results->length; return; } diff --git a/src/detection/battery/battery_windows.cpp b/src/detection/battery/battery_windows.cpp index a3c2accf0..9cf53ee28 100644 --- a/src/detection/battery/battery_windows.cpp +++ b/src/detection/battery/battery_windows.cpp @@ -38,9 +38,7 @@ const char* ffDetectBatteryImpl(FFinstance* instance, FFlist* results) default: ffStrbufInit(&battery->technology); break; } - uint64_t capacity; - record.getUnsigned(L"EstimatedChargeRemaining", &capacity); - ffStrbufInitF(&battery->capacity, "%d", (int)capacity); + record.getReal(L"EstimatedChargeRemaining", &battery->capacity); uint64_t batteryStatus; record.getUnsigned(L"BatteryStatus", &batteryStatus); diff --git a/src/fastfetch.c b/src/fastfetch.c index ea2818b96..b64abafb8 100644 --- a/src/fastfetch.c +++ b/src/fastfetch.c @@ -1357,6 +1357,8 @@ static void parseOption(FFinstance* instance, FFdata* data, const char* key, con NULL ); } + else if(strcasecmp(key, "--percent-type") == 0) + instance->config.percentType = optionParseUInt32(key, value); ////////////////// //Unknown option// diff --git a/src/fastfetch.h b/src/fastfetch.h index d62348e80..b4e639edf 100644 --- a/src/fastfetch.h +++ b/src/fastfetch.h @@ -189,6 +189,8 @@ typedef struct FFconfig FFstrbuf osFile; FFstrbuf playerName; + + uint32_t percentType; } FFconfig; typedef struct FFstate diff --git a/src/modules/battery.c b/src/modules/battery.c index 58773bf0a..97c603d9a 100644 --- a/src/modules/battery.c +++ b/src/modules/battery.c @@ -1,11 +1,12 @@ #include "fastfetch.h" #include "common/printing.h" +#include "common/bar.h" #include "detection/battery/battery.h" #define FF_BATTERY_MODULE_NAME "Battery" #define FF_BATTERY_NUM_FORMAT_ARGS 5 -static void printBattery(FFinstance* instance, BatteryResult* result, uint8_t index) +static void printBattery(FFinstance* instance, BatteryResult* result, uint8_t index) { if(instance->config.battery.outputFormat.length == 0) { @@ -15,27 +16,47 @@ static void printBattery(FFinstance* instance, BatteryResult* result, uint8_t i result->status.length > 0 && ffStrbufIgnCaseCompS(&result->status, "Unknown") != 0; - if(result->capacity.length > 0) - { - ffStrbufWriteTo(&result->capacity, stdout); - putchar('%'); + FFstrbuf str; + ffStrbufInit(&str); - if(showStatus) - fputs(" [", stdout); + if(result->capacity >= 0) + { + if(instance->config.percentType & FF_PERCENTAGE_TYPE_BAR_BIT) + { + if(result->capacity <= 20) + ffAppendPercentBar(instance, &str, (uint8_t)result->capacity, 10, 10, 0); + else if(result->capacity <= 50) + ffAppendPercentBar(instance, &str, (uint8_t)result->capacity, 10, 0, 10); + else + ffAppendPercentBar(instance, &str, (uint8_t)result->capacity, 0, 10, 10); + } + + if(instance->config.percentType & FF_PERCENTAGE_TYPE_NUM_BIT) + { + if(str.length > 0) + ffStrbufAppendC(&str, ' '); + ffStrbufAppendF(&str, "%.0f%%", result->capacity); + } } if(showStatus) { - ffStrbufWriteTo(&result->status, stdout); - - if(result->capacity.length > 0) - putchar(']'); + if(str.length > 0) + ffStrbufAppendF(&str, " [%s]", result->status.chars); + else + ffStrbufAppend(&str, &result->status); } if(result->temperature == result->temperature) //FF_BATTERY_TEMP_UNSET - printf(" - %.1f°C", result->temperature); + { + if(str.length > 0) + ffStrbufAppendS(&str, " - "); - putchar('\n'); + ffStrbufAppendF(&str, "%.1f°C", result->temperature); + } + + ffStrbufPutTo(&str, stdout); + ffStrbufDestroy(&str); } else { @@ -43,7 +64,7 @@ static void printBattery(FFinstance* instance, BatteryResult* result, uint8_t i {FF_FORMAT_ARG_TYPE_STRBUF, &result->manufacturer}, {FF_FORMAT_ARG_TYPE_STRBUF, &result->modelName}, {FF_FORMAT_ARG_TYPE_STRBUF, &result->technology}, - {FF_FORMAT_ARG_TYPE_STRBUF, &result->capacity}, + {FF_FORMAT_ARG_TYPE_DOUBLE, &result->capacity}, {FF_FORMAT_ARG_TYPE_STRBUF, &result->status}, {FF_FORMAT_ARG_TYPE_DOUBLE, &result->temperature}, }); @@ -71,7 +92,6 @@ void ffPrintBattery(FFinstance* instance) ffStrbufDestroy(&result->manufacturer); ffStrbufDestroy(&result->modelName); ffStrbufDestroy(&result->technology); - ffStrbufDestroy(&result->capacity); ffStrbufDestroy(&result->status); } if(results.length == 0) diff --git a/src/modules/cpuUsage.c b/src/modules/cpuUsage.c index db8ea2e5d..3e4165b90 100644 --- a/src/modules/cpuUsage.c +++ b/src/modules/cpuUsage.c @@ -1,5 +1,6 @@ #include "fastfetch.h" #include "common/printing.h" +#include "common/bar.h" #include "detection/cpuUsage/cpuUsage.h" #define FF_CPU_USAGE_MODULE_NAME "CPU Usage" @@ -7,8 +8,8 @@ void ffPrintCPUUsage(FFinstance* instance) { - double cpuPercent = 0.0/0.0; - const char* error = ffGetCpuUsageResult(&cpuPercent); + double percentage = 0.0/0.0; + const char* error = ffGetCpuUsageResult(&percentage); if(error) { @@ -20,12 +21,23 @@ void ffPrintCPUUsage(FFinstance* instance) { ffPrintLogoAndKey(instance, FF_CPU_USAGE_MODULE_NAME, 0, &instance->config.cpuUsage.key); - printf("%.2lf%%\n", cpuPercent); + FFstrbuf str; + ffStrbufInit(&str); + if(instance->config.percentType & FF_PERCENTAGE_TYPE_BAR_BIT) + ffAppendPercentBar(instance, &str, (uint8_t)percentage, 0, 5, 8); + if(instance->config.percentType & FF_PERCENTAGE_TYPE_NUM_BIT) + { + if(str.length > 0) + ffStrbufAppendC(&str, ' '); + ffStrbufAppendF(&str, "%.2lf%%", percentage); + } + ffStrbufPutTo(&str, stdout); + ffStrbufDestroy(&str); } else { ffPrintFormat(instance, FF_CPU_USAGE_MODULE_NAME, 0, &instance->config.cpuUsage, FF_CPU_USAGE_NUM_FORMAT_ARGS, (FFformatarg[]){ - {FF_FORMAT_ARG_TYPE_DOUBLE, &cpuPercent} + {FF_FORMAT_ARG_TYPE_DOUBLE, &percentage} }); } } diff --git a/src/modules/disk.c b/src/modules/disk.c index 0245d8a4a..159acb471 100644 --- a/src/modules/disk.c +++ b/src/modules/disk.c @@ -1,6 +1,7 @@ #include "fastfetch.h" #include "common/printing.h" #include "common/parsing.h" +#include "common/bar.h" #include "detection/disk/disk.h" #define FF_DISK_MODULE_NAME "Disk" @@ -35,14 +36,30 @@ static void printDisk(FFinstance* instance, const FFDisk* disk) if(instance->config.disk.outputFormat.length == 0) { ffPrintLogoAndKey(instance, key.chars, 0, NULL); + + FFstrbuf str; + ffStrbufInit(&str); + if(disk->bytesTotal > 0) - printf("%s / %s (%u%%)", usedPretty.chars, totalPretty.chars, bytesPercentage); + { + if(instance->config.percentType & FF_PERCENTAGE_TYPE_BAR_BIT) + { + ffAppendPercentBar(instance, &str, bytesPercentage, 0, 5, 8); + ffStrbufAppendC(&str, ' '); + } + ffStrbufAppendF(&str, "%s / %s", usedPretty.chars, totalPretty.chars); + + if(instance->config.percentType & FF_PERCENTAGE_TYPE_NUM_BIT) + ffStrbufAppendF(&str, " (%u%%)", bytesPercentage); + } else - fputs("unknown", stdout); + ffStrbufAppendS(&str, "Unknown"); if(disk->type == FF_DISK_TYPE_EXTERNAL) - printf(" [Removable]"); - putchar('\n'); + ffStrbufAppendS(&str, " [Removable]"); + + ffStrbufPutTo(&str, stdout); + ffStrbufDestroy(&str); } else { diff --git a/src/modules/memory.c b/src/modules/memory.c index c3681a136..5fab1b383 100644 --- a/src/modules/memory.c +++ b/src/modules/memory.c @@ -1,6 +1,7 @@ #include "fastfetch.h" #include "common/printing.h" #include "common/parsing.h" +#include "common/bar.h" #include "detection/memory/memory.h" #include "detection/swap/swap.h" @@ -41,7 +42,24 @@ static void printMemory(FFinstance* instance, const char* name, const FFModuleAr if (storage->bytesTotal == 0) puts("Disabled"); else - printf("%s / %s (%u%%)\n", usedPretty.chars, totalPretty.chars, percentage); + { + FFstrbuf str; + ffStrbufInit(&str); + + if(instance->config.percentType & FF_PERCENTAGE_TYPE_BAR_BIT) + { + ffAppendPercentBar(instance, &str, percentage, 0, 5, 8); + ffStrbufAppendC(&str, ' '); + } + + ffStrbufAppendF(&str, "%s / %s", usedPretty.chars, totalPretty.chars); + + if(instance->config.percentType & FF_PERCENTAGE_TYPE_NUM_BIT) + ffStrbufAppendF(&str, " (%u%%)", percentage); + + ffStrbufPutTo(&str, stdout); + ffStrbufDestroy(&str); + } } else {