diff options
-rw-r--r-- | src/btop.cpp | 13 | ||||
-rw-r--r-- | src/btop_config.cpp | 184 | ||||
-rw-r--r-- | src/btop_config.hpp | 16 | ||||
-rw-r--r-- | src/btop_draw.hpp | 1 | ||||
-rw-r--r-- | src/btop_linux.cpp | 49 | ||||
-rw-r--r-- | src/btop_shared.hpp | 3 | ||||
-rw-r--r-- | src/btop_theme.cpp | 96 | ||||
-rw-r--r-- | src/btop_theme.hpp | 7 | ||||
-rw-r--r-- | src/btop_tools.hpp | 2 | ||||
-rw-r--r-- | themes/adapta.theme | 89 | ||||
-rw-r--r-- | themes/default.theme-sample | 100 | ||||
-rw-r--r-- | themes/dracula.theme | 89 | ||||
-rw-r--r-- | themes/dusklight.theme | 95 | ||||
-rw-r--r-- | themes/flat-remix-light.theme | 89 | ||||
-rw-r--r-- | themes/flat-remix.theme | 89 | ||||
-rw-r--r-- | themes/greyscale.theme | 89 | ||||
-rw-r--r-- | themes/gruvbox_dark.theme | 92 | ||||
-rw-r--r-- | themes/kyli0x.theme | 92 | ||||
-rw-r--r-- | themes/matcha-dark-sea.theme | 92 | ||||
-rw-r--r-- | themes/monokai.theme | 92 | ||||
-rw-r--r-- | themes/nord.theme | 89 | ||||
-rw-r--r-- | themes/solarized_dark.theme | 89 | ||||
-rw-r--r-- | themes/whiteout.theme | 89 |
23 files changed, 1525 insertions, 121 deletions
diff --git a/src/btop.cpp b/src/btop.cpp index 0cf42b6..75eb4b3 100644 --- a/src/btop.cpp +++ b/src/btop.cpp @@ -67,7 +67,7 @@ namespace Global { {"#801414", "██████╔╝ ██║ ╚██████╔╝██║ ╚═╝ ╚═╝"}, {"#000000", "╚═════╝ ╚═╝ ╚═════╝ ╚═╝"}, }; - std::string Version = "0.0.21"; + const std::string Version = "0.0.21"; int coreCount; } @@ -178,7 +178,7 @@ void _signal_handler(int sig) { void banner_gen() { size_t z = 0; string b_color, bg, fg, oc, letter; - bool truecolor = Config::getB("truecolor"); + auto& truecolor = Config::getB("truecolor"); int bg_i; Global::banner.clear(); Global::banner_width = 0; @@ -186,7 +186,7 @@ void banner_gen() { for (auto line: Global::Banner_src) { if (auto w = ulen(line[1]); w > Global::banner_width) Global::banner_width = w; fg = Theme::hex_to_color(line[0], !truecolor); - bg_i = 120-z*12; + bg_i = 120 - z * 12; bg = Theme::dec_to_color(bg_i, bg_i, bg_i, !truecolor); for (size_t i = 0; i < line[1].size(); i += 3) { if (line[1][i] == ' ') { @@ -238,7 +238,6 @@ int main(int argc, char **argv){ #if defined(LINUX) Global::coreCount = sysconf(_SC_NPROCESSORS_ONLN); if (Global::coreCount < 1) Global::coreCount = 1; - { std::error_code ec; Global::self_path = fs::read_symlink("/proc/self/exe", ec).remove_filename(); @@ -327,7 +326,7 @@ int main(int argc, char **argv){ auto thts = time_ms(); //? Generate the theme - Theme::set(Theme::Default_theme); + Theme::set("Default"); //? Create the btop++ banner banner_gen(); @@ -407,7 +406,7 @@ int main(int argc, char **argv){ exit(0); } - if (false) { + if (true) { vector<long long> mydata; for (long long i = 0; i <= 100; i++) mydata.push_back(i); @@ -589,7 +588,7 @@ int main(int argc, char **argv){ cmd_cond = p.cmd.substr(0, std::min(p.cmd.find(' '), p.cmd.size())); cmd_cond = cmd_cond.substr(std::min(cmd_cond.find_last_of('/') + 1, cmd_cond.size())); } - ostring += Mv::r(1) + greyscale[lc] + ljust(p.prefix + to_string(p.pid) + " " + p.name + " " + (!cmd_cond.empty() && cmd_cond != p.name ? "(" + cmd_cond + ")" : ""), Term::width - 40, true) + " " + ostring += Mv::r(1) + (Config::getB("tty_mode") ? " " : greyscale[lc]) + ljust(p.prefix + to_string(p.pid) + " " + p.name + " " + (!cmd_cond.empty() && cmd_cond != p.name ? "(" + cmd_cond + ")" : ""), Term::width - 40, true) + " " + rjust(to_string(p.threads), 5) + " " + ljust(p.user, 10) + " " + rjust(floating_humanizer(p.mem, true), 5) + string(11, ' ') + (p.cpu_p < 10 || p.cpu_p >= 100 ? rjust(to_string(p.cpu_p), 3) + " " : rjust(to_string(p.cpu_p), 4)) + "\n"; diff --git a/src/btop_config.cpp b/src/btop_config.cpp index 89c7046..f2b90ea 100644 --- a/src/btop_config.cpp +++ b/src/btop_config.cpp @@ -39,69 +39,120 @@ namespace Config { bool write_new; vector<array<string, 2>> descriptions = { - {"color_theme", "#* Color theme, looks for a .theme file in \"/usr/[local/]share/bpytop/themes\" and \"~/.config/bpytop/themes\", \"Default\" for builtin default theme.\n" - "#* Prefix name by a plus sign (+) for a theme located in user themes folder, i.e. color_theme=\"+monokai\"." }, - {"theme_background", "#* If the theme set background should be shown, set to False if you want terminal background transparency."}, - {"truecolor", "#* Sets if 24-bit truecolor should be used, will convert 24-bit colors to 256 color (6x6x6 color cube) if false."}, - {"graph_symbol", "#* Default symbols to use for graph creation, \"braille\", \"block\" or \"tty\".\n" - "#* \"braille\" offers the highest resolution but might not be included in all fonts.\n" - "#* \"block\" has half the resolution of braille but uses more common characters.\n" - "#* \"tty\" uses only 3 different symbols but will work with most fonts and should work in a real TTY.\n" - "#* Note that \"tty\" only has half the horizontal resolution of the other two, so will show a shorter historical view."}, - {"graph_symbol_cpu", "# Graph symbol to use for graphs in cpu box, \"default\", \"braille\", \"block\" or \"tty\"."}, - {"graph_symbol_mem", "# Graph symbol to use for graphs in cpu box, \"default\", \"braille\", \"block\" or \"tty\"."}, - {"graph_symbol_net", "# Graph symbol to use for graphs in cpu box, \"default\", \"braille\", \"block\" or \"tty\"."}, - {"graph_symbol_proc", "# Graph symbol to use for graphs in cpu box, \"default\", \"braille\", \"block\" or \"tty\"."}, - {"force_tty", "#* Set to true to true to force tty mode regardless if a real tty has been detected or not."}, - {"shown_boxes", "#* Manually set which boxes to show. Available values are \"cpu mem net proc\", separate values with whitespace."}, - {"update_ms", "#* Update time in milliseconds, increases automatically if set below internal loops processing time, recommended 2000 ms or above for better sample times for graphs."}, + {"color_theme", "#* Color theme, looks for a .theme file in \"/usr/[local/]share/bpytop/themes\" and \"~/.config/bpytop/themes\", \"Default\" for builtin default theme.\n" + "#* Prefix name by a plus sign (+) for a theme located in user themes folder, i.e. color_theme=\"+monokai\"." }, + + {"theme_background", "#* If the theme set background should be shown, set to False if you want terminal background transparency."}, + + {"truecolor", "#* Sets if 24-bit truecolor should be used, will convert 24-bit colors to 256 color (6x6x6 color cube) if false."}, + + {"force_tty", "#* Set to true to force tty mode regardless if a real tty has been detected or not.\n" + "#* Will force 16-color mode, set all graph symbols to \"tty\" and swap out other non tty friendly symbols."}, + + {"graph_symbol", "#* Default symbols to use for graph creation, \"braille\", \"block\" or \"tty\".\n" + "#* \"braille\" offers the highest resolution but might not be included in all fonts.\n" + "#* \"block\" has half the resolution of braille but uses more common characters.\n" + "#* \"tty\" uses only 3 different symbols but will work with most fonts and should work in a real TTY.\n" + "#* Note that \"tty\" only has half the horizontal resolution of the other two, so will show a shorter historical view."}, + + {"graph_symbol_cpu", "# Graph symbol to use for graphs in cpu box, \"default\", \"braille\", \"block\" or \"tty\"."}, + + {"graph_symbol_mem", "# Graph symbol to use for graphs in cpu box, \"default\", \"braille\", \"block\" or \"tty\"."}, + + {"graph_symbol_net", "# Graph symbol to use for graphs in cpu box, \"default\", \"braille\", \"block\" or \"tty\"."}, + + {"graph_symbol_proc", "# Graph symbol to use for graphs in cpu box, \"default\", \"braille\", \"block\" or \"tty\"."}, + + {"shown_boxes", "#* Manually set which boxes to show. Available values are \"cpu mem net proc\", separate values with whitespace."}, + + {"update_ms", "#* Update time in milliseconds, increases automatically if set below internal loops processing time, recommended 2000 ms or above for better sample times for graphs."}, + {"proc_update_mult", "#* Processes update multiplier, sets how often the process list is updated as a multiplier of \"update_ms\".\n" "#* Set to 2 or higher to greatly decrease bpytop cpu usage. (Only integers)."}, - {"proc_sorting", "#* Processes sorting, \"pid\" \"program\" \"arguments\" \"threads\" \"user\" \"memory\" \"cpu lazy\" \"cpu responsive\",\n" - "#* \"cpu lazy\" updates top process over time, \"cpu responsive\" updates top process directly."}, - {"proc_reversed", "#* Reverse sorting order, True or False."}, - {"proc_tree", "#* Show processes as a tree."}, - {"proc_colors", "#* Use the cpu graph colors in the process list."}, - {"proc_gradient", "#* Use a darkening gradient in the process list."}, - {"proc_per_core", "#* If process cpu usage should be of the core it's running on or usage of the total available cpu power."}, - {"proc_mem_bytes", "#* Show process memory as bytes instead of percent."}, - {"cpu_graph_upper", "#* Sets the CPU stat shown in upper half of the CPU graph, \"total\" is always available.\n" - "#* Select from a list of detected attributes from the options menu."}, - {"cpu_graph_lower", "#* Sets the CPU stat shown in lower half of the CPU graph, \"total\" is always available.\n" - "#* Select from a list of detected attributes from the options menu."}, - {"cpu_invert_lower", "#* Toggles if the lower CPU graph should be inverted."}, - {"cpu_single_graph", "#* Set to True to completely disable the lower CPU graph."}, - {"show_uptime", "#* Shows the system uptime in the CPU box."}, - {"check_temp", "#* Show cpu temperature."}, - {"cpu_sensor", "#* Which sensor to use for cpu temperature, use options menu to select from list of available sensors."}, - {"show_coretemp", "#* Show temperatures for cpu cores also if check_temp is True and sensors has been found."}, - {"temp_scale", "#* Which temperature scale to use, available values: \"celsius\", \"fahrenheit\", \"kelvin\" and \"rankine\"."}, - {"show_cpu_freq", "#* Show CPU frequency."}, - {"draw_clock", "#* Draw a clock at top of screen, formatting according to strftime, empty string to disable."}, - {"background_update", "#* Update main ui in background when menus are showing, set this to false if the menus is flickering too much for comfort."}, - {"custom_cpu_name", "#* Custom cpu model name, empty string to disable."}, - {"disks_filter", "#* Optional filter for shown disks, should be full path of a mountpoint, separate multiple values with a comma \",\".\n" - "#* Begin line with \"exclude=\" to change to exclude filter, otherwise defaults to \"most include\" filter. Example: disks_filter=\"exclude=/boot, /home/user\"."}, - {"mem_graphs", "#* Show graphs instead of meters for memory values."}, - {"show_swap", "#* If swap memory should be shown in memory box."}, - {"swap_disk", "#* Show swap as a disk, ignores show_swap value above, inserts itself after first disk."}, - {"show_disks", "#* If mem box should be split to also show disks info."}, - {"only_physical", "#* Filter out non physical disks. Set this to False to include network disks, RAM disks and similar."}, - {"use_fstab", "#* Read disks list from /etc/fstab. This also disables only_physical."}, - {"show_io_stat", "#* Toggles if io stats should be shown in regular disk usage view."}, - {"io_mode", "#* Toggles io mode for disks, showing only big graphs for disk read/write speeds."}, - {"io_graph_combined", "#* Set to True to show combined read/write io graphs in io mode."}, - {"io_graph_speeds", "#* Set the top speed for the io graphs in MiB/s (10 by default), use format \"device:speed\" separate disks with a comma \",\".\n" - "#* Example: \"/dev/sda:100, /dev/sdb:20\"."}, - {"net_download", "#* Set fixed values for network graphs, default \"10M\" = 10 Mibibytes, possible units \"K\", \"M\", \"G\", append with \"bit\" for bits instead of bytes, i.e \"100mbit\"."}, + + {"proc_sorting", "#* Processes sorting, \"pid\" \"program\" \"arguments\" \"threads\" \"user\" \"memory\" \"cpu lazy\" \"cpu responsive\",\n" + "#* \"cpu lazy\" updates top process over time, \"cpu responsive\" updates top process directly."}, + + {"proc_reversed", "#* Reverse sorting order, True or False."}, + + {"proc_tree", "#* Show processes as a tree."}, + + {"proc_colors", "#* Use the cpu graph colors in the process list."}, + + {"proc_gradient", "#* Use a darkening gradient in the process list."}, + + {"proc_per_core", "#* If process cpu usage should be of the core it's running on or usage of the total available cpu power."}, + + {"proc_mem_bytes", "#* Show process memory as bytes instead of percent."}, + + {"cpu_graph_upper", "#* Sets the CPU stat shown in upper half of the CPU graph, \"total\" is always available.\n" + "#* Select from a list of detected attributes from the options menu."}, + + {"cpu_graph_lower", "#* Sets the CPU stat shown in lower half of the CPU graph, \"total\" is always available.\n" + "#* Select from a list of detected attributes from the options menu."}, + + {"cpu_invert_lower", "#* Toggles if the lower CPU graph should be inverted."}, + + {"cpu_single_graph", "#* Set to True to completely disable the lower CPU graph."}, + + {"show_uptime", "#* Shows the system uptime in the CPU box."}, + + {"check_temp", "#* Show cpu temperature."}, + + {"cpu_sensor", "#* Which sensor to use for cpu temperature, use options menu to select from list of available sensors."}, + + {"show_coretemp", "#* Show temperatures for cpu cores also if check_temp is True and sensors has been found."}, + + {"temp_scale", "#* Which temperature scale to use, available values: \"celsius\", \"fahrenheit\", \"kelvin\" and \"rankine\"."}, + + {"show_cpu_freq", "#* Show CPU frequency."}, + + {"draw_clock", "#* Draw a clock at top of screen, formatting according to strftime, empty string to disable."}, + + {"background_update", "#* Update main ui in background when menus are showing, set this to false if the menus is flickering too much for comfort."}, + + {"custom_cpu_name", "#* Custom cpu model name, empty string to disable."}, + + {"disks_filter", "#* Optional filter for shown disks, should be full path of a mountpoint, separate multiple values with a comma \",\".\n" + "#* Begin line with \"exclude=\" to change to exclude filter, otherwise defaults to \"most include\" filter. Example: disks_filter=\"exclude=/boot, /home/user\"."}, + + {"mem_graphs", "#* Show graphs instead of meters for memory values."}, + + {"show_swap", "#* If swap memory should be shown in memory box."}, + + {"swap_disk", "#* Show swap as a disk, ignores show_swap value above, inserts itself after first disk."}, + + {"show_disks", "#* If mem box should be split to also show disks info."}, + + {"only_physical", "#* Filter out non physical disks. Set this to False to include network disks, RAM disks and similar."}, + + {"use_fstab", "#* Read disks list from /etc/fstab. This also disables only_physical."}, + + {"show_io_stat", "#* Toggles if io stats should be shown in regular disk usage view."}, + + {"io_mode", "#* Toggles io mode for disks, showing only big graphs for disk read/write speeds."}, + + {"io_graph_combined", "#* Set to True to show combined read/write io graphs in io mode."}, + + {"io_graph_speeds", "#* Set the top speed for the io graphs in MiB/s (10 by default), use format \"device:speed\" separate disks with a comma \",\".\n" + "#* Example: \"/dev/sda:100, /dev/sdb:20\"."}, + + {"net_download", "#* Set fixed values for network graphs, default \"10M\" = 10 Mibibytes, possible units \"K\", \"M\", \"G\", append with \"bit\" for bits instead of bytes, i.e \"100mbit\"."}, + {"net_upload", ""}, - {"net_auto", "#* Start in network graphs auto rescaling mode, ignores any values set above and rescales down to 10 Kibibytes at the lowest."}, - {"net_sync", "#* Sync the scaling for download and upload to whichever currently has the highest scale."}, - {"net_color_fixed", "#* If the network graphs color gradient should scale to bandwidth usage or auto scale, bandwidth usage is based on \"net_download\" and \"net_upload\" values."}, - {"net_iface", "#* Starts with the Network Interface specified here."}, - {"show_battery", "#* Show battery stats in top right if battery is present."}, - {"log_level", "#* Set loglevel for \"~/.config/bpytop/error.log\" levels are: \"ERROR\" \"WARNING\" \"INFO\" \"DEBUG\".\n" - "#* The level set includes all lower levels, i.e. \"DEBUG\" will show all logging info."} + + {"net_auto", "#* Start in network graphs auto rescaling mode, ignores any values set above and rescales down to 10 Kibibytes at the lowest."}, + + {"net_sync", "#* Sync the scaling for download and upload to whichever currently has the highest scale."}, + + {"net_color_fixed", "#* If the network graphs color gradient should scale to bandwidth usage or auto scale, bandwidth usage is based on \"net_download\" and \"net_upload\" values."}, + + {"net_iface", "#* Starts with the Network Interface specified here."}, + + {"show_battery", "#* Show battery stats in top right if battery is present."}, + + {"log_level", "#* Set loglevel for \"~/.config/bpytop/error.log\" levels are: \"ERROR\" \"WARNING\" \"INFO\" \"DEBUG\".\n" + "#* The level set includes all lower levels, i.e. \"DEBUG\" will show all logging info."} }; unordered_flat_map<string, string> strings = { @@ -180,42 +231,35 @@ namespace Config { fs::path conf_dir; fs::path conf_file; - vector<string> valid_graph_symbols = { "braille", "block", "tty" }; + const vector<string> valid_graph_symbols = { "braille", "block", "tty" }; - //* Return bool config value <name> const bool& getB(string name){ return bools.at(name); } - //* Return integer config value <name> const int& getI(string name){ return ints.at(name); } - //* Return string config value <name> const string& getS(string name){ return strings.at(name); } - //* Set config value <name> to bool <value> void set(string name, bool value){ if (_locked(name)) boolsTmp.insert_or_assign(name, value); else bools.at(name) = value; } - //* Set config value <name> to int <value> void set(string name, int value){ if (_locked(name)) intsTmp.insert_or_assign(name, value); ints.at(name) = value; } - //* Set config value <name> to string <value> void set(string name, string value){ if (_locked(name)) stringsTmp.insert_or_assign(name, value); else strings.at(name) = value; } - //* Flip config bool <name> void flip(string name){ if (_locked(name)) { if (boolsTmp.contains(name)) boolsTmp.at(name) = !boolsTmp.at(name); @@ -224,12 +268,10 @@ namespace Config { else bools.at(name) = !bools.at(name); } - //* Wait if locked then lock config and cache changes until unlock void lock(){ atomic_wait_set(locked); } - //* Unlock config and write any cached values to config void unlock(){ atomic_wait_set(writelock); @@ -252,7 +294,6 @@ namespace Config { writelock = false; } - //* Load the config file from disk void load(fs::path conf_file, vector<string>& load_errors){ if (conf_file.empty()) return; @@ -319,7 +360,6 @@ namespace Config { } } - //* Write the config file to disk void write(){ if (conf_file.empty() || !write_new) return; Logger::debug("Writing new config file"); diff --git a/src/btop_config.hpp b/src/btop_config.hpp index 98e239c..31b4e28 100644 --- a/src/btop_config.hpp +++ b/src/btop_config.hpp @@ -30,27 +30,27 @@ namespace Config { extern std::filesystem::path conf_dir; extern std::filesystem::path conf_file; - extern vector<string> valid_graph_symbols; + extern const vector<string> valid_graph_symbols; - //* Return bool config value <name> + //* Return bool for config key <name> const bool& getB(string name); - //* Return integer config value <name> + //* Return integer for config key <name> const int& getI(string name); - //* Return string config value <name> + //* Return string for config key <name> const string& getS(string name); - //* Set config value <name> to bool <value> + //* Set config key <name> to bool <value> void set(string name, bool value); - //* Set config value <name> to int <value> + //* Set config key <name> to int <value> void set(string name, int value); - //* Set config value <name> to string <value> + //* Set config key <name> to string <value> void set(string name, string value); - //* Flip config bool <name> + //* Flip config key bool <name> void flip(string name); //* Wait if locked then lock config and cache changes until unlock diff --git a/src/btop_draw.hpp b/src/btop_draw.hpp index de3d8db..afcd1bb 100644 --- a/src/btop_draw.hpp +++ b/src/btop_draw.hpp @@ -45,6 +45,7 @@ namespace Draw { string line_color = "", title = "", title2 = ""; bool fill = true; uint num=0; + uint w_percent=0, h_percent=0; }; //* Create a box using values from a BoxConf struct and return as a string diff --git a/src/btop_linux.cpp b/src/btop_linux.cpp index 7d84e28..12e6c31 100644 --- a/src/btop_linux.cpp +++ b/src/btop_linux.cpp @@ -92,35 +92,29 @@ namespace Proc { }; //* Generate process tree list - void _tree_gen(proc_info& cur_proc, vector<proc_info>& in_procs, vector<proc_info>& out_procs, int cur_depth=0, bool collapsed=false){ + void _tree_gen(proc_info& cur_proc, vector<proc_info>& in_procs, vector<proc_info>& out_procs, int cur_depth, bool collapsed, string& prefix){ auto cur_pos = out_procs.size(); if (!collapsed) out_procs.push_back(cur_proc); + int children = 0; - for (auto& p : in_procs) { - if (p.ppid == cur_proc.pid) { - children++; - if (collapsed) { - out_procs.back().cpu_p += p.cpu_p; - out_procs.back().mem += p.mem; - out_procs.back().threads += p.threads; - _tree_gen(p, in_procs, out_procs, cur_depth + 1, collapsed); - } - else _tree_gen(p, in_procs, out_procs, cur_depth + 1, cache.at(cur_proc.pid).collapsed); + for (auto& p : rng::equal_range(in_procs, cur_proc.pid, rng::less{}, &proc_info::ppid)) { + children++; + if (collapsed) { + out_procs.back().cpu_p += p.cpu_p; + out_procs.back().mem += p.mem; + out_procs.back().threads += p.threads; } + _tree_gen(p, in_procs, out_procs, cur_depth + 1, (collapsed ? true : cache.at(cur_proc.pid).collapsed), prefix); } if (collapsed) return; if (out_procs.size() > cur_pos + 1 && !out_procs.back().prefix.ends_with("] ")) { - std::string_view n_prefix = out_procs.back().prefix; - n_prefix.remove_suffix(8); - out_procs.back().prefix = (string)n_prefix + " └─ "; + out_procs.back().prefix.resize(out_procs.back().prefix.size() - 8); + out_procs.back().prefix += " └─ "; } - string prefix = " ├─ "; - if (children > 0) prefix = (cache.at(cur_proc.pid).collapsed) ? "[+] " : "[-] "; - - out_procs.at(cur_pos).prefix = " │ "s * cur_depth + prefix; + out_procs.at(cur_pos).prefix = " │ "s * cur_depth + (children > 0 ? (cache.at(cur_proc.pid).collapsed ? "[+] " : "[-] ") : prefix); } vector<proc_info> current_procs; @@ -323,13 +317,13 @@ namespace Proc { new_proc.mem *= page_size; } - //* Push process to vector + //? Push process to vector procs.push_back(new_proc); } } //* Sort processes - auto cmp = [&reverse](auto &a, auto &b) { return (reverse ? a < b : a > b); }; + auto cmp = [&reverse](const auto &a, const auto &b) { return (reverse ? a < b : a > b); }; switch (v_index(sort_vector, sorting)) { case 0: { rng::sort(procs, cmp, &proc_info::pid); break; } case 1: { rng::sort(procs, cmp, &proc_info::name); break; } @@ -359,9 +353,13 @@ namespace Proc { //* Generate tree view if enabled if (tree) { vector<proc_info> tree_procs; - auto min_pid = rng::min(procs, rng::less{}, &proc_info::ppid).ppid; - for (auto& p : procs) { - if (p.ppid == min_pid) _tree_gen(p, procs, tree_procs); + + //? Stable sort to retain selected sorting among processes with the same parent + rng::stable_sort(procs, rng::less{}, &proc_info::ppid); + + string prefix = " ├─ "; + for (auto& p : rng::equal_range(procs, procs.at(0).ppid, rng::less{}, &proc_info::ppid)) { + _tree_gen(p, procs, tree_procs, 0, cache.at(p.pid).collapsed, prefix); } procs.swap(tree_procs); } @@ -372,11 +370,10 @@ namespace Proc { counter = 0; unordered_flat_map<uint, p_cache> r_cache; r_cache.reserve(pid_list.size()); - for (auto& p : pid_list) { - if (cache.contains(p)) r_cache[p] = cache.at(p); - } + rng::for_each(pid_list, [&r_cache](const auto &p){ if (cache.contains(p)) r_cache[p] = cache.at(p); }); cache.swap(r_cache); } + old_cputimes = cputimes; current_procs.swap(procs); numpids = npids; diff --git a/src/btop_shared.hpp b/src/btop_shared.hpp index 3419b81..b39bc38 100644 --- a/src/btop_shared.hpp +++ b/src/btop_shared.hpp @@ -26,8 +26,9 @@ tab-size = 4 using std::string, std::vector; namespace Global { - extern string Version; + extern const string Version; extern int coreCount; + extern string banner; } namespace Tools { diff --git a/src/btop_theme.cpp b/src/btop_theme.cpp index 59ff663..5fe8b1c 100644 --- a/src/btop_theme.cpp +++ b/src/btop_theme.cpp @@ -37,6 +37,7 @@ namespace Theme { fs::path theme_dir; fs::path user_theme_dir; + vector<string> themes; const unordered_flat_map<string, string> Default_theme = { { "main_bg", "#00" }, @@ -83,6 +84,51 @@ namespace Theme { { "process_end", "#d45454" } }; + const unordered_flat_map<string, string> TTY_theme = { + { "main_bg", "\x1b[40m" }, + { "main_fg", "\x1b[37m" }, + { "title", "\x1b[97m" }, + { "hi_fg", "\x1b[31m" }, + { "selected_bg", "\x1b[41m" }, + { "selected_fg", "\x1b[97m" }, + { "inactive_fg", "\x1b[90m" }, + { "graph_text", "\x1b[37m" }, + { "meter_bg", "\x1b[90m" }, + { "proc_misc", "\x1b[92m" }, + { "cpu_box", "\x1b[32m" }, + { "mem_box", "\x1b[33m" }, + { "net_box", "\x1b[35m" }, + { "proc_box", "\x1b[31m" }, + { "div_line", "\x1b[90m" }, + { "temp_start", "\x1b[94m" }, + { "temp_mid", "\x1b[96m" }, + { "temp_end", "\x1b[95m" }, + { "cpu_start", "\x1b[92m" }, + { "cpu_mid", "\x1b[93m" }, + { "cpu_end", "\x1b[91m" }, + { "free_start", "\x1b[32m" }, + { "free_mid", "" }, + { "free_end", "\x1b[92m" }, + { "cached_start", "\x1b[36m" }, + { "cached_mid", "" }, + { "cached_end", "\x1b[96m" }, + { "available_start", "\x1b[33m" }, + { "available_mid", "" }, + { "available_end", "\x1b[93m" }, + { "used_start", "\x1b[31m" }, + { "used_mid", "" }, + { "used_end", "\x1b[91m" }, + { "download_start", "\x1b[34m" }, + { "download_mid", "" }, + { "download_end", "\x1b[94m" }, + { "upload_start", "\x1b[35m" }, + { "upload_mid", "" }, + { "upload_end", "\x1b[95m" }, + { "process_start", "\x1b[32m" }, + { "process_mid", "\x1b[33m" }, + { "process_end", "\x1b[31m" } + }; + namespace { //* Convert 24-bit colors to 256 colors using 6x6x6 color cube int truecolor_to_256(int r, int g, int b){ @@ -182,7 +228,7 @@ namespace Theme { } //* Generate colors and rgb decimal vectors for the theme - void generateColors(unordered_flat_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"); @@ -251,13 +297,55 @@ namespace Theme { gradients[wname].swap(c_gradient); } } + + void generateTTYColors(){ + + rgbs.clear(); + colors = TTY_theme; + + gradients.clear(); + + for (auto& c : colors) { + if (!c.first.ends_with("_start")) continue; + string base_name = rtrim(c.first, "_start"); + string section = "_start"; + int split = colors.at(base_name + "_mid").empty() ? 50 : 33; + for (int i : iota(0, 101)) { + gradients[base_name][i] = colors.at(base_name + section); + if (i == split) { + if (split == 50 || split == 66) + section = "_end"; + else { + section = "_mid"; + split *= 2; + } + } + } + + } + + } + + auto loadFile(string filename){ + unordered_flat_map<string, string> out; + + return out; + } + } + + void updateThemes(){ + } //* Set current theme using <source> map - void set(unordered_flat_map<string, string> source){ - generateColors(source); - generateGradients(); + void set(string theme){ + if (theme == "TTY" || Config::getB("tty_mode")) + generateTTYColors(); + else { + generateColors((theme == "Default" ? Default_theme : loadFile(theme))); + generateGradients(); + } Term::fg = colors.at("main_fg"); Term::bg = colors.at("main_bg"); Fx::reset = Fx::reset_base + Term::fg + Term::bg; diff --git a/src/btop_theme.hpp b/src/btop_theme.hpp index 699d416..45f48a1 100644 --- a/src/btop_theme.hpp +++ b/src/btop_theme.hpp @@ -28,7 +28,7 @@ namespace Theme { extern std::filesystem::path theme_dir; extern std::filesystem::path user_theme_dir; - extern const robin_hood::unordered_flat_map<string, string> Default_theme; + extern vector<string> themes; //* Generate escape sequence for 24-bit or 256 color and return as a string //* Args hexa: ["#000000"-"#ffffff"] for color, ["#00"-"#ff"] for greyscale @@ -45,8 +45,11 @@ namespace Theme { //* Return an array of red, green and blue, 0-255 values for a 24-bit color escape string std::array<int, 3> esc_to_rgb(string c_string); + //* Update list of available themes + void updateThemes(); + //* Set current theme using <source> map - void set(robin_hood::unordered_flat_map<string, string> source); + void set(string theme); //* Return escape code for color <name> const string& c(string name); diff --git a/src/btop_tools.hpp b/src/btop_tools.hpp index 6ab63a5..b7d1cc0 100644 --- a/src/btop_tools.hpp +++ b/src/btop_tools.hpp @@ -151,7 +151,7 @@ namespace Tools { //* Check if vector <vec> contains value <find_val> template <typename T> - bool v_contains(vector<T>& vec, T find_val) { + bool v_contains(const vector<T>& vec, const T find_val) { return std::ranges::find(vec, find_val) != vec.end(); } diff --git a/themes/adapta.theme b/themes/adapta.theme new file mode 100644 index 0000000..e3e2128 --- /dev/null +++ b/themes/adapta.theme @@ -0,0 +1,89 @@ +#Bashtop Adapta theme +#by olokelo + +# Colors should be in 6 or 2 character hexadecimal or single spaced rgb decimal: "#RRGGBB", "#BW" or "0-255 0-255 0-255" +# example for white: "#ffffff", "#ff" or "255 255 255". + +# All graphs and meters can be gradients +# For single color graphs leave "mid" and "end" variable empty. +# Use "start" and "end" variables for two color gradient +# Use "start", "mid" and "end" for three color gradient + +# Main background, empty for terminal default, need to be empty if you want transparent background +theme[main_bg]="" + +# Main text color +theme[main_fg]="#cfd8dc" + +# Title color for boxes +theme[title]="#ff" + +# Higlight color for keyboard shortcuts +theme[hi_fg]="#90" + +# Background color of selected item in processes box +theme[selected_bg]="#bb0040" + +# Foreground color of selected item in processes box +theme[selected_fg]="#ff" + +# Color of inactive/disabled text +theme[inactive_fg]="#40" + +# Misc colors for processes box including mini cpu graphs, details memory graph and details status text +theme[proc_misc]="#55bcea" + +# Cpu box outline color +theme[cpu_box]="#00bcd4" + +# Memory/disks box outline color +theme[mem_box]="#00bcd4" + +# Net up/down box outline color +theme[net_box]="#00bcd4" + +# Processes box outline color +theme[proc_box]="#00bcd4" + +# Box divider line and small boxes line color +theme[div_line]="#50" + +# Temperature graph colors +theme[temp_start]="#00bcd4" +theme[temp_mid]="#d4d400" +theme[temp_end]="#ff0040" + +# CPU graph colors +theme[cpu_start]="#00bcd4" +theme[cpu_mid]="#d4d400" +theme[cpu_end]="#ff0040" + +# Mem/Disk free meter +theme[free_start]="#00bcd4" +theme[free_mid]="#1090a0" +theme[free_end]="#206f79" + +# Mem/Disk cached meter +theme[cached_start]="#991199" +theme[cached_mid]="#770a55" +theme[cached_end]="#550055" + +# Mem/Disk available meter +theme[available_start]="#00b0ff" +theme[available_mid]="#1099cc" +theme[available_end]="#2070aa" + +# Mem/Disk used meter +theme[used_start]="#ff0040" +theme[used_mid]="#ff2060" +theme[used_end]="#ff4080" + +# Download graph colors +theme[download_start]="#00bcd4" +theme[download_mid]="#991199" +theme[download_end]="#ff0040" + +# Upload graph colors +theme[upload_start]="#00bcd4" +theme[upload_mid]="#991199" +theme[upload_end]="#ff0040" diff --git a/themes/default.theme-sample b/themes/default.theme-sample new file mode 100644 index 0000000..ff47168 --- /dev/null +++ b/themes/default.theme-sample @@ -0,0 +1,100 @@ +#Bashtop theme with default colors and black background +#by aristocratos + +# Colors should be in 6 or 2 character hexadecimal or single spaced rgb decimal: "#RRGGBB", "#BW" or "0-255 0-255 0-255" +# example for white: "#FFFFFF", "#ff" or "255 255 255". + +# All graphs and meters can be gradients +# For single color graphs leave "mid" and "end" variable empty. +# Use "start" and "end" variables for two color gradient +# Use "start", "mid" and "end" for three color gradient + +# Main background, empty for terminal default, need to be empty if you want transparent background +theme[main_bg]="#00" + +# Main text color +theme[main_fg]="#cc" + +# Title color for boxes +theme[title]="#ee" + +# Highlight co |