Small changes

This commit is contained in:
aristocratos 2021-05-29 02:32:36 +02:00
parent ecd4ef9985
commit f424feb24d
8 changed files with 208 additions and 180 deletions

195
btop.cpp
View File

@ -28,6 +28,7 @@ tab-size = 4
#include <ranges>
#include <filesystem>
#include <unistd.h>
#include <robin_hood.h>
namespace Global {
const std::vector<std::array<std::string, 2>> Banner_src = {
@ -69,7 +70,7 @@ namespace Global {
#error Platform not supported!
#endif
using std::string, std::vector, std::array, std::map, std::atomic, std::endl, std::cout, std::views::iota, std::list, std::accumulate;
using std::string, std::vector, std::array, robin_hood::unordered_flat_map, std::atomic, std::endl, std::cout, std::views::iota, std::list, std::accumulate;
using std::flush, std::endl, std::future, std::string_literals::operator""s, std::future_status;
namespace fs = std::filesystem;
using namespace Tools;
@ -79,10 +80,14 @@ namespace Global {
string banner;
const uint banner_width = 49;
fs::path conf_dir;
fs::path conf_file;
fs::path theme_folder;
fs::path user_theme_folder;
fs::path self_path;
bool debuginit = false;
bool debug = false;
uint64_t start_time;
bool quitting = false;
}
@ -94,10 +99,13 @@ void argumentParser(int argc, char **argv){
if (argument == "-v" || argument == "--version") {
cout << "btop version: " << Global::Version << endl;
exit(0);
} else if (argument == "-h" || argument == "--help") {
}
else if (argument == "-h" || argument == "--help") {
cout << "help here" << endl;
exit(0);
} else {
}
else if (argument == "--debug") Global::debug = true;
else {
cout << " Unknown argument: " << argument << "\n" <<
" Use -h or --help for help." << endl;
exit(1);
@ -134,6 +142,18 @@ string createBanner(){
return out;
}
void clean_quit(int signal){
if (Global::quitting) return;
if (Term::initialized) {
Term::restore();
if (!Global::debuginit) cout << Term::normal_screen << Term::show_cursor << flush;
}
if (Global::debug) Logger::debug("Quitting! Runtime: " + sec_to_dhms(time_s() - Global::start_time));
Global::quitting = true;
if (signal != -1) exit(signal);
}
void _exit_handler() { clean_quit(-1); }
//* Threading test function
string my_worker(int x){
@ -150,62 +170,83 @@ int main(int argc, char **argv){
//? Init
Global::start_time = time_s();
cout.setf(std::ios::boolalpha);
if (argc > 1) argumentParser(argc, argv);
std::atexit(_exit_handler);
#if defined(LINUX)
//? Linux init
//? Linux paths init
Global::proc_path = (fs::is_directory(fs::path("/proc")) && access("/proc", R_OK) != -1) ? "/proc" : "";
if (Global::proc_path.empty()) {
cout << "ERROR: Proc filesystem not found or no permission to read from it!" << endl;
exit(1);
}
{
std::error_code ec;
Global::self_path = fs::read_symlink("/proc/self/exe", ec).remove_filename();
}
#endif
//? Setup paths for config, log and themes
for (auto env : {"XDG_CONFIG_HOME", "HOME"}) {
if (getenv(env) != NULL && access(getenv(env), W_OK) != -1) {
Global::conf_dir = fs::path(getenv(env)) / (((string)env == "HOME") ? ".config/btop" : "btop");
Config::conf_dir = fs::path(getenv(env)) / (((string)env == "HOME") ? ".config/btop" : "btop");
break;
}
}
if (!Global::conf_dir.empty()) {
if (!fs::is_directory(Global::conf_dir) && !fs::create_directories(Global::conf_dir)) {
if (!Config::conf_dir.empty()) {
std::error_code ec;
if (!fs::is_directory(Config::conf_dir) && !fs::create_directories(Config::conf_dir, ec)) {
cout << "WARNING: Could not create or access btop config directory. Logging and config saving disabled." << endl;
cout << "Make sure your $HOME environment variable is correctly set to fix this." << endl;
}
else {
Global::conf_file = Global::conf_dir / "btop.conf";
Logger::logfile = Global::conf_dir / "btop.log";
Global::user_theme_folder = Global::conf_dir / "themes";
if (!fs::exists(Global::user_theme_folder) && !fs::create_directory(Global::user_theme_folder)) Global::user_theme_folder.clear();
std::error_code ec;
Config::conf_file = Config::conf_dir / "btop.conf";
Logger::logfile = Config::conf_dir / "btop.log";
Theme::user_theme_dir = Config::conf_dir / "themes";
if (!fs::exists(Theme::user_theme_dir) && !fs::create_directory(Theme::user_theme_dir, ec)) Theme::user_theme_dir.clear();
}
}
for (auto theme_path : {"/usr/local/share/btop/themes", "/usr/share/btop/themes"}) {
if (access(theme_path, R_OK) != -1) {
Global::theme_folder = theme_path;
break;
if (!Global::self_path.empty()) {
std::error_code ec;
Theme::theme_dir = fs::canonical(Global::self_path / "../share/btop/themes", ec);
if (ec || access(Theme::theme_dir.c_str(), R_OK) == -1) Theme::theme_dir.clear();
}
if (Theme::theme_dir.empty()) {
for (auto theme_path : {"/usr/local/share/btop/themes", "/usr/share/btop/themes"}) {
if (fs::exists(fs::path(theme_path)) && access(theme_path, R_OK) != -1) {
Theme::theme_dir = fs::path(theme_path);
break;
}
}
}
string err_msg;
Global::debug = true;
if (Global::debug) { Logger::loglevel = 4; Logger::debug("Starting in debug mode");}
if (!string(getenv("LANG")).ends_with("UTF-8") && !string(getenv("LANG")).ends_with("utf-8")) {
err_msg = "No UTF-8 locale was detected! Symbols might not look as intended.";
string err_msg = "No UTF-8 locale was detected! Symbols might not look as intended.";
Logger::warning(err_msg);
cout << "WARNING: " << err_msg << endl;
}
//? Initialize terminal and set options
if (!Term::init()) {
err_msg = "No tty detected!";
string err_msg = "No tty detected!";
Logger::error(err_msg + " Quitting.");
cout << "ERROR: " << err_msg << endl;
cout << "btop++ needs an interactive shell to run." << endl;
exit(1);
clean_quit(1);
}
//? Read config file if present
Config::load("____");
Config::setB("truecolor", false);
auto thts = time_ms();
@ -218,16 +259,13 @@ int main(int argc, char **argv){
//* ------------------------------------------------ TESTING ------------------------------------------------------
int debug = 1;
int tests = 0;
bool debuginit = false;
if (debug > 0) { Logger::loglevel = 4; Logger::debug("Running in debug mode!");}
Global::debuginit = false;
// cout << Theme("main_bg") << Term::clear << flush;
bool thread_test = false;
if (!debuginit) cout << Term::alt_screen << Term::hide_cursor << flush;
if (!Global::debuginit) cout << Term::alt_screen << Term::hide_cursor << flush;
cout << Theme::c("main_fg") << Theme::c("main_bg") << Term::clear << endl;
@ -273,8 +311,7 @@ int main(int argc, char **argv){
exit(0);
}
if (true) {
if (false) {
Draw::Meter kmeter;
kmeter(Term::width - 2, "cpu", false);
cout << kmeter(25) << endl;
@ -285,11 +322,25 @@ int main(int argc, char **argv){
exit(0);
}
if (false) {
cout << fs::absolute(fs::current_path() / "..") << endl;
cout << Global::self_path << endl;
cout << Theme::theme_dir << endl;
cout << Config::conf_dir << endl;
exit(0);
}
if (false) {
string a = "⣿ ⣿\n⣿⣿⣿⣿ ⣿\n⣿⣿⣿⣿ ⣿\n⣿⣿⣿⣿ ⣿\n⣿⣿⣿";
cout << a << endl;
exit(0);
}
if (thread_test){
map<int, future<string>> runners;
map<int, string> outputs;
unordered_flat_map<int, future<string>> runners;
unordered_flat_map<int, string> outputs;
for (int i : iota(0, 10)){
runners[i] = async(my_worker, i);
@ -325,7 +376,7 @@ int main(int argc, char **argv){
uint lc;
string ostring;
uint64_t tsl, timestamp2, rcount = 0;
list<uint64_t> avgtimes;
list<uint64_t> avgtimes = {0};
uint timer = 1000;
bool filtering = false;
bool reversing = false;
@ -369,8 +420,8 @@ int main(int argc, char **argv){
avgtimes.push_front(timestamp);
if (avgtimes.size() > 100) avgtimes.pop_back();
if (rcount > 0) avgtimes.push_front(timestamp);
if (avgtimes.size() > 10) avgtimes.pop_back();
cout << pbox << ostring << Fx::reset << "\n" << endl;
cout << Mv::to(Term::height - 4, 1) << "Processes call took: " << rjust(to_string(timestamp), 5) << " μs. Average: " <<
rjust(to_string(accumulate(avgtimes.begin(), avgtimes.end(), 0) / avgtimes.size()), 5) << " μs of " << avgtimes.size() <<
@ -403,79 +454,5 @@ int main(int argc, char **argv){
//*-----<<<<<
//cout << pw->pw_name << "/" << gr->gr_name << endl;
if (tests>4){
string trim_test1 = "-*vad ";
string trim_test2 = " vad*-";
string trim_test3 = trim_test1 + trim_test2;
cout << "\"" << ltrim(trim_test1, "-*") << "\" \"" << rtrim(trim_test2, "*-") << "\" \"" << trim(trim_test3, "-") << "\"" << endl;
string testie = "Does this work as intended? Or?";
auto t_vec = ssplit(testie);
for(auto& tp : t_vec){
cout << "\"" << tp << "\" " << flush;
}
}
//if (tests>5){
//}
// map<string, string> dict = {
// {"Korv", "14"},
// {"Vad", "13"}
// };
// cout << dict["Korv"] << ", " << dict["Vad"] << endl;
// vector<map<string, int>> test = {
// {{"first", 1}, {"second", 2}},
// {{"first", 11}, {"second", 22}}
// };
//cout << test[0]["first"] << " " << test[1]["second"] << endl;
// for (auto& m : test) {
// cout << endl;
// for (auto& item : m) {
// cout << item.first << " " << item.second << endl;
// }
// }
if (debug == 3){
cout << Theme::c("main_fg");
cout << Mv::to(Term::height - 1, 0) << "Press q to exit! Timeout" << flush;
string full, key;
int wt = 90;
bool qp = false;
while (!qp && wt >= 0){
int wtm = wt / 60;
int wts = wt - wtm * 60;
wt--;
cout << Mv::to(Term::height - 1, 26) << "(" << wtm << ":" << wts << ") " << flush;
//chr = Key(1000);
if (Input::poll(1000)) {
key = Input::get();
cout << Mv::to(Term::height - 2, 1) << "Last key: LEN=" << key.size() << " ULEN=" << ulen(key) << " KEY=\"" << key << "\" CODE=" << (int)key.at(0) << " " << flush;
full += key;
cout << Mv::to(Term::height - 5, 1) << full << flush;
if (key == "q") qp = true;
key = "";
wt++;
}
}
}
Term::restore();
if (!debuginit) cout << Term::normal_screen << Term::show_cursor << flush;
return 0;
}

View File

@ -21,11 +21,13 @@ tab-size = 4
#include <string>
#include <vector>
#include <unordered_map>
#include <robin_hood.h>
#include <filesystem>
#include <btop_tools.h>
using std::string, std::vector, std::unordered_map;
using std::string, std::vector, robin_hood::unordered_flat_map;
namespace fs = std::filesystem;
using namespace Tools;
@ -33,9 +35,12 @@ using namespace Tools;
namespace Config {
namespace {
fs::path conf_dir;
fs::path conf_file;
bool changed = false;
unordered_map<string, string> strings = {
unordered_flat_map<string, string> strings = {
{"color_theme", "Default"},
{"shown_boxes", "cpu mem net proc"},
{"proc_sorting", "cpu lazy"},
@ -52,7 +57,7 @@ namespace Config {
{"net_iface", ""},
{"log_level", "WARNING"}
};
unordered_map<string, bool> bools = {
unordered_flat_map<string, bool> bools = {
{"theme_background", true},
{"truecolor", true},
{"proc_reversed", false},
@ -84,7 +89,7 @@ namespace Config {
{"show_battery", true},
{"show_init", false}
};
unordered_map<string, int> ints = {
unordered_flat_map<string, int> ints = {
{"update_ms", 2000},
{"proc_update_mult", 2},
{"tree_depth", 3}

View File

@ -20,7 +20,7 @@ tab-size = 4
#include <string>
#include <vector>
#include <map>
#include <robin_hood.h>
#include <ranges>
#include <algorithm>
#include <cmath>
@ -31,7 +31,42 @@ tab-size = 4
#ifndef _btop_draw_included_
#define _btop_draw_included_ 1
using std::string, std::vector, std::map, std::round, std::views::iota, std::string_literals::operator""s;
using std::string, std::vector, robin_hood::unordered_flat_map, std::round, std::views::iota, std::string_literals::operator""s, std::clamp;
namespace Symbols {
const string h_line = "";
const string v_line = "";
const string left_up = "";
const string right_up = "";
const string left_down = "";
const string right_down = "";
const string title_left = "";
const string title_right = "";
const string div_up = "";
const string div_down = "";
const string meter = "";
const array<string, 10> superscript = { "", "¹", "²", "³", "", "", "", "", "", "" };
const unordered_flat_map<bool, string> graph_00 = { {true, Mv::r(1)}, {false, ""} };
unordered_flat_map<float, string> graph_up = {
{0.0, ""}, {0.1, ""}, {0.2, ""}, {0.3, ""}, {0.4, ""},
{1.0, ""}, {1.1, ""}, {1.2, ""}, {1.3, ""}, {1.4, ""},
{2.0, ""}, {2.1, ""}, {2.2, ""}, {2.3, ""}, {2.4, ""},
{3.0, ""}, {3.1, ""}, {3.2, ""}, {3.3, ""}, {3.4, ""},
{4.0, ""}, {4.1, ""}, {4.2, ""}, {4.3, ""}, {4.4, ""}
};
unordered_flat_map<float, string> graph_down = {
{0.0, ""}, {0.1, ""}, {0.2, ""}, {0.3, ""}, {0.4, ""},
{1.0, ""}, {1.1, ""}, {1.2, ""}, {1.3, ""}, {1.4, ""},
{2.0, ""}, {2.1, ""}, {2.2, ""}, {2.3, ""}, {2.4, ""},
{3.0, ""}, {3.1, ""}, {3.2, ""}, {3.3, ""}, {3.4, ""},
{4.0, ""}, {4.1, ""}, {4.2, ""}, {4.3, ""}, {4.4, ""}
};
}
namespace Draw {
@ -43,6 +78,7 @@ namespace Draw {
uint num=0;
};
//* Create a box using values from a BoxConf struct and return as a string
string createBox(BoxConf c){
string out;
string lcolor = (c.line_color.empty()) ? Theme::c("div_line") : c.line_color;
@ -81,24 +117,27 @@ namespace Draw {
return out + Fx::reset + Mv::to(c.y + 1, c.x + 2);
}
//* Class holding a percentage meter
class Meter {
string out, color_gradient;
int width = 10;
bool invert = false;
vector<string> cache;
public:
//* Set meter options
void operator()(int width, string color_gradient, bool invert = false) {
if (width < 0) width = 1;
this->width = width;
this->color_gradient = color_gradient;
this->invert = invert;
out.clear();
cache.clear();
cache.insert(cache.begin(), 101, "");
}
//* Return a string representation of the meter with given value
string operator()(int value) {
if (value > 100) value = 100;
else if (value < 0) value = 0;
if (width < 1) return out;
value = clamp(value, 0, 100);
if (!cache.at(value).empty()) return out = cache.at(value);
out.clear();
int y;

View File

@ -23,9 +23,9 @@ tab-size = 4
#include <vector>
#include <array>
#include <atomic>
#include <unordered_map>
#include <robin_hood.h>
using std::string, std::vector, std::unordered_map, std::array, std::atomic;
using std::string, std::vector, std::unordered_map, std::array, std::atomic, robin_hood::unordered_flat_map;
namespace Global {
@ -33,7 +33,7 @@ namespace Global {
const unordered_map<string, unordered_map<string, vector<string>>> Menus = {
const unordered_flat_map<string, unordered_map<string, vector<string>>> Menus = {
{ "options", {
{ "normal", {
"┌─┐┌─┐┌┬┐┬┌─┐┌┐┌┌─┐",

View File

@ -20,12 +20,12 @@ tab-size = 4
#define _btop_input_included_ 1
#include <string>
#include <unordered_map>
#include <robin_hood.h>
#include <iostream>
#include <btop_tools.h>
using std::string, std::unordered_map, std::cin;
using std::string, robin_hood::unordered_flat_map, std::cin;
using namespace Tools;
/* The input functions relies on the following std::cin options being set:
@ -38,7 +38,7 @@ using namespace Tools;
namespace Input {
namespace {
//* Map for translating key codes to readable values
const unordered_map<string, string> Key_escapes = {
const unordered_flat_map<string, string> Key_escapes = {
{"\033", "escape"},
{"\n", "enter"},
{" ", "space"},

View File

@ -31,16 +31,17 @@ tab-size = 4
#include <filesystem>
#include <ranges>
#include <list>
#include <robin_hood.h>
#include <unistd.h>
#include <btop_config.h>
#include <btop_globs.h>
#include <btop_tools.h>
#include <robin_hood.h>
using std::string, std::vector, std::array, std::ifstream, std::atomic, std::numeric_limits, std::streamsize, robin_hood::unordered_flat_map;
using std::string, std::vector, std::array, std::ifstream, std::atomic, std::numeric_limits, std::streamsize;
using std::cout, std::flush, std::endl;
namespace fs = std::filesystem;
using namespace Tools;

View File

@ -22,20 +22,24 @@ tab-size = 4
#include <string>
#include <cmath>
#include <vector>
#include <map>
#include <unordered_map>
#include <robin_hood.h>
#include <ranges>
#include <algorithm>
#include <btop_globs.h>
#include <btop_tools.h>
#include <btop_config.h>
using std::string, std::round, std::vector, std::map, std::stoi, std::views::iota, std::array, std::unordered_map;
using std::string, std::round, std::vector, robin_hood::unordered_flat_map, std::stoi, std::views::iota, std::array, std::clamp, std::max, std::min;
using namespace Tools;
namespace Theme {
const unordered_map<string, string> Default_theme = {
fs::path theme_dir;
fs::path user_theme_dir;
const unordered_flat_map<string, string> Default_theme = {
{ "main_bg", "#00" },
{ "main_fg", "#cc" },
{ "title", "#ee" },
@ -83,10 +87,10 @@ namespace Theme {
namespace {
//* Convert 24-bit colors to 256 colors using 6x6x6 color cube
int truecolor_to_256(uint r, uint g, uint b){
if (r / 11 == g / 11 && g / 11 == b / 11) {
return 232 + r / 11;
if (round((double)r / 11) == round((double)g / 11) && round((double)g / 11) == round((double)b / 11)) {
return 232 + round((double)r / 11);
} else {
return round((float)(r / 51)) * 36 + round((float)(g / 51)) * 6 + round((float)(b / 51)) + 16;
return round((double)r / 51) * 36 + round((double)g / 51) * 6 + round((double)b / 51) + 16;
}
}
}
@ -98,7 +102,10 @@ namespace Theme {
string hex_to_color(string hexa, bool t_to_256=false, string depth="fg"){
if (hexa.size() > 1){
hexa.erase(0, 1);
for (auto& c : hexa) if (!isxdigit(c)) return "";
for (auto& c : hexa) if (!isxdigit(c)) {
Logger::error("Invalid hex value: " + hexa);
return "";
}
depth = (depth == "fg") ? "38" : "48";
string pre = Fx::e + depth + ";";
pre += (t_to_256) ? "5;" : "2;";
@ -125,7 +132,9 @@ namespace Theme {
to_string(stoi(hexa.substr(4, 2), 0, 16)) + "m";
}
}
else Logger::error("Invalid size of hex value: " + hexa);
}
else Logger::error("Hex value missing." + hexa);
return "";
}
@ -137,9 +146,9 @@ namespace Theme {
depth = (depth == "fg") ? "38" : "48";
string pre = Fx::e + depth + ";";
pre += (t_to_256) ? "5;" : "2;";
r = (r > 255) ? 255 : r;
g = (g > 255) ? 255 : g;
b = (b > 255) ? 255 : b;
r = min(r, 255u);
g = min(g, 255u);
b = min(b, 255u);
if (t_to_256) return pre + to_string(truecolor_to_256(r, g, b)) + "m";
else return pre + to_string(r) + ";" + to_string(g) + ";" + to_string(b) + "m";
}
@ -161,9 +170,9 @@ namespace Theme {
namespace {
unordered_map<string, string> colors;
unordered_map<string, array<int, 3>> rgbs;
unordered_map<string, array<string, 101>> gradients;
unordered_flat_map<string, string> colors;
unordered_flat_map<string, array<int, 3>> rgbs;
unordered_flat_map<string, array<string, 101>> gradients;
//* Convert hex color to a array of decimals
array<int, 3> hex_to_dec(string hexa){
@ -187,40 +196,46 @@ namespace Theme {
}
//* Generate colors and rgb decimal vectors for the theme
void generateColors(unordered_map<string, string>& source){
void generateColors(unordered_flat_map<string, string>& source){
vector<string> t_rgb;
string depth;
bool t_to_256 = !Config::getB("truecolor");
colors.clear(); rgbs.clear();
for (auto& [name, color] : Default_theme) {
depth = (name.ends_with("bg") && name != "meter_bg") ? "bg" : "fg";
if (source.contains(name)) {
if (source.at(name)[0] == '#') {
colors[name] = hex_to_color(source.at(name), !Config::getB("truecolor"), depth);
colors[name] = hex_to_color(source.at(name), t_to_256, depth);
rgbs[name] = hex_to_dec(source.at(name));
}
else {
t_rgb = ssplit(source.at(name), " ");
colors[name] = dec_to_color(stoi(t_rgb[0]), stoi(t_rgb[1]), stoi(t_rgb[2]), !Config::getB("truecolor"), depth);
rgbs[name] = array<int, 3>{stoi(t_rgb[0]), stoi(t_rgb[1]), stoi(t_rgb[2])};
if (t_rgb.size() != 3)
Logger::error("Invalid RGB decimal value: \"" + source.at(name) + "\"");
else {
colors[name] = dec_to_color(stoi(t_rgb[0]), stoi(t_rgb[1]), stoi(t_rgb[2]), t_to_256, depth);
rgbs[name] = array<int, 3>{stoi(t_rgb[0]), stoi(t_rgb[1]), stoi(t_rgb[2])};
}
}
}
else colors[name] = "";
if (colors[name].empty()) {
colors[name] = hex_to_color(color, !Config::getB("truecolor"), depth);
Logger::info("Missing color value for \"" + name + "\". Using value from default.");
colors[name] = hex_to_color(color, t_to_256, depth);
rgbs[name] = array<int, 3>{-1, -1, -1};
}
}
}
//* Generate color gradients from one, two or three colors, 101 values indexed 0-100
//* Generate color gradients from two or three colors, 101 values indexed 0-100
void generateGradients(){
gradients.clear();
array<string, 101> c_gradient;
string wname;
bool t_to_256 = !Config::getB("truecolor");
array<array<int, 3>, 3> rgb_arr;
array<array<int, 3>, 101> dec_arr;
int f, s, r, o, y;
for (auto& [name, source_arr] : rgbs){
int arr1, arr2, rng, offset, y;
for (auto& [name, source_arr] : rgbs) {
if (!name.ends_with("_start")) continue;
dec_arr[0][0] = -1;
wname = rtrim(name, "_start");
@ -230,21 +245,22 @@ namespace Theme {
if (rgb_arr[2][0] >= 0) {
//? Split iteration in two passes of 50 + 51 instead of 101 if gradient has _start, _mid and _end values defined
r = (rgb_arr[1][0] >= 0) ? 50 : 100;
for (int i : iota(0, 3)){
f = 0; s = (r == 50) ? 1 : 2; o = 0;
for (int c : iota(0, 101)){
dec_arr[c][i] = rgb_arr[f][i] + (c - o) * (rgb_arr[s][i] - rgb_arr[f][i]) / r;
rng = (rgb_arr[1][0] >= 0) ? 50 : 100;
for (int rgb : iota(0, 3)){
arr1 = 0; arr2 = (rng == 50) ? 1 : 2; offset = 0;
for (int i : iota(0, 101)) {
dec_arr[i][rgb] = rgb_arr[arr1][rgb] + (i - offset) * (rgb_arr[arr2][rgb] - rgb_arr[arr1][rgb]) / rng;
//? Switch source arrays from _start/_mid to _mid/_end at 50 passes if _mid is defined
if (c == r) { ++f; ++s; o = 50;}
if (i == rng) { ++arr1; ++arr2; offset = 50;}
}
}
}
y = 0;
if (dec_arr[0][0] != -1) {
for (auto& vec : dec_arr) c_gradient[y++] = dec_to_color(vec[0], vec[1], vec[2], !Config::getB("truecolor"));
} else {
for (auto& arr : dec_arr) c_gradient[y++] = dec_to_color(arr[0], arr[1], arr[2], t_to_256);
}
else {
//? If only _start was defined fill array with _start color
c_gradient.fill(colors[name]);
}
@ -255,7 +271,7 @@ namespace Theme {
//* Set current theme using <source> map
void set(unordered_map<string, string> source){
void set(unordered_flat_map<string, string> source){
generateColors(source);
generateGradients();
Term::fg = colors.at("main_fg");
@ -264,17 +280,17 @@ namespace Theme {
}
//* Return escape code for color <name>
auto c(string name){
auto& c(string name){
return colors.at(name);
}
//* Return array of escape codes for color gradient <name>
auto g(string name){
auto& g(string name){
return gradients.at(name);
}
//* Return array of red, green and blue in decimal for color <name>
auto dec(string name){
auto& dec(string name){
return rgbs.at(name);
}

View File

@ -32,6 +32,7 @@ tab-size = 4
#include <utility>
#include <atomic>
#include <filesystem>
#include <robin_hood.h>
#include <unistd.h>
#include <termios.h>
@ -39,28 +40,11 @@ tab-size = 4
#include <btop_globs.h>
using std::string, std::vector, std::regex, std::max, std::to_string, std::cin, std::atomic;
using std::string, std::vector, std::regex, std::max, std::to_string, std::cin, std::atomic, robin_hood::unordered_flat_map;
namespace fs = std::filesystem;
//? ------------------------------------------------- NAMESPACES ------------------------------------------------------
namespace Symbols {
const string h_line = "";
const string v_line = "";
const string left_up = "";
const string right_up = "";
const string left_down = "";
const string right_down = "";
const string title_left = "";
const string title_right = "";
const string div_up = "";
const string div_down = "";
const string meter = "";
const array<string, 10> superscript = { "", "¹", "²", "³", "", "", "", "", "", "" };
}
//* Collection of escape codes for text style and formatting
namespace Fx {
//* Escape sequence start
@ -251,6 +235,11 @@ namespace Tools {
[](char c) { return (static_cast<unsigned char>(c) & 0xC0) != 0x80; } );
}
//* Return current time since epoch in seconds
inline uint64_t time_s(){
return std::chrono::duration_cast<std::chrono::seconds>(std::chrono::system_clock::now().time_since_epoch()).count();
}
//* Return current time since epoch in milliseconds
inline uint64_t time_ms(){
return std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count();
@ -459,6 +448,7 @@ namespace Tools {
}
//* Simple logging implementation
namespace Logger {
namespace {
std::atomic<bool> busy (false);
@ -466,7 +456,7 @@ namespace Logger {
uint loglevel = 2;
bool first = true;
string tdf = "%Y/%m/%d (%T) | ";
unordered_map<uint, string> log_levels = {
unordered_flat_map<uint, string> log_levels = {
{ 0, "DISABLED" },
{ 1, "ERROR" },
{ 2, "WARNING" },