diff options
Diffstat (limited to 'src/btop_draw.cpp')
-rw-r--r-- | src/btop_draw.cpp | 219 |
1 files changed, 117 insertions, 102 deletions
diff --git a/src/btop_draw.cpp b/src/btop_draw.cpp index 989c052..5aa5b28 100644 --- a/src/btop_draw.cpp +++ b/src/btop_draw.cpp @@ -20,17 +20,18 @@ tab-size = 4 #include <algorithm> #include <cmath> #include <ranges> - -#include <btop_draw.hpp> -#include <btop_config.hpp> -#include <btop_theme.hpp> -#include <btop_shared.hpp> -#include <btop_tools.hpp> -#include <btop_input.hpp> -#include <btop_menu.hpp> #include <stdexcept> #include <string> +#include "btop_draw.hpp" +#include "btop_config.hpp" +#include "btop_theme.hpp" +#include "btop_shared.hpp" +#include "btop_tools.hpp" +#include "btop_input.hpp" +#include "btop_menu.hpp" + + using std::array; using std::clamp; using std::cmp_equal; @@ -108,8 +109,8 @@ namespace Draw { if (redraw) banner.clear(); if (banner.empty()) { string b_color, bg, fg, oc, letter; - auto lowcolor = Config::getB("lowcolor"); - auto tty_mode = Config::getB("tty_mode"); + auto lowcolor = Config::getB("lowcolor"); + auto tty_mode = Config::getB("tty_mode"); for (size_t z = 0; const auto& line : Global::Banner_src) { if (const auto w = ulen(line[1]); w > width) width = w; if (tty_mode) { @@ -158,10 +159,10 @@ namespace Draw { upos++; pos = uresize(text, upos).size(); } - else if (key == "home" and pos > 0) { + else if (key == "home" and not text.empty() and pos > 0) { pos = upos = 0; } - else if (key == "end" and pos < text.size()) { + else if (key == "end" and not text.empty() and pos < text.size()) { pos = text.size(); upos = ulen(text); } @@ -204,6 +205,10 @@ namespace Draw { } string TextEdit::operator()(const size_t limit) { + string out; + size_t c_upos = upos; + if (text.empty()) + return Fx::ul + " " + Fx::uul; if (limit > 0 and ulen(text) + 1 > limit) { try { const size_t half = (size_t)round((double)limit / 2); @@ -216,29 +221,39 @@ namespace Draw { else first = luresize(text.substr(0, pos), half); - return first + Fx::bl + "█" + Fx::ubl + uresize(text.substr(pos), limit - ulen(first)); + out = first + uresize(text.substr(pos), limit - ulen(first)); + c_upos = ulen(first); } catch (const std::exception& e) { - Logger::error("In TextEdit::operator() : " + string{e.what()}); + Logger::error("In TextEdit::operator() : " + string{e.what()}); + return ""; } } - return text.substr(0, pos) + Fx::bl + "█" + Fx::ubl + text.substr(pos); + else + out = text; + + if (c_upos == 0) + return Fx::ul + uresize(out, 1) + Fx::uul + luresize(out, ulen(out) - 1); + else if (c_upos == ulen(out)) + return out + Fx::ul + " " + Fx::uul; + else + return uresize(out, c_upos) + Fx::ul + luresize(uresize(out, c_upos + 1), 1) + Fx::uul + luresize(out, ulen(out) - c_upos - 1); } void TextEdit::clear() { this->text.clear(); } - string createBox(const int x, const int y, const int width, - const int height, string line_color, bool fill, - const string title, const string title2, const int num) { + string createBox(const int x, const int y, const int width, + const int height, string line_color, bool fill, + const string title, const string title2, const int num) { string out; - if (line_color.empty()) - line_color = Theme::c("div_line"); + if (line_color.empty()) + line_color = Theme::c("div_line"); - auto tty_mode = Config::getB("tty_mode"); - auto rounded = Config::getB("rounded_corners"); + auto tty_mode = Config::getB("tty_mode"); + auto rounded = Config::getB("rounded_corners"); const string numbering = (num == 0) ? "" : Theme::c("hi_fg") + (tty_mode ? std::to_string(num) : Symbols::superscript.at(clamp(num, 0, 9))); const auto& right_up = (tty_mode or not rounded ? Symbols::right_up : Symbols::round_right_up); const auto& left_up = (tty_mode or not rounded ? Symbols::left_up : Symbols::round_left_up); @@ -248,12 +263,12 @@ namespace Draw { out = Fx::reset + line_color; //? Draw horizontal lines - for (const int& hpos : {y, y + height - 1}) { + for (const int& hpos : {y, y + height - 1}) { out += Mv::to(hpos, x) + Symbols::h_line * (width - 1); } //? Draw vertical lines and fill if enabled - for (const int& hpos : iota(y + 1, y + height - 1)) { + for (const int& hpos : iota(y + 1, y + height - 1)) { out += Mv::to(hpos, x) + Symbols::v_line + ((fill) ? string(width - 2, ' ') : Mv::r(width - 2)) + Symbols::v_line; @@ -291,11 +306,11 @@ namespace Draw { {"/uptime", ""} }; - static time_t c_time{}; // defaults to 0 - static size_t clock_len{}; // defaults to 0 + static time_t c_time{}; // defaults to 0 + static size_t clock_len{}; // defaults to 0 static string clock_str; - if (auto n_time = time(NULL); not force and n_time == c_time) + if (auto n_time = time(nullptr); not force and n_time == c_time) return false; else { c_time = n_time; @@ -305,7 +320,7 @@ namespace Draw { } auto& out = Global::clock; - auto cpu_bottom = Config::getB("cpu_bottom"); + auto cpu_bottom = Config::getB("cpu_bottom"); const auto& x = Cpu::x; const auto y = (cpu_bottom ? Cpu::y + Cpu::height - 1 : Cpu::y); const auto& width = Cpu::width; @@ -345,8 +360,8 @@ namespace Draw { //* Meter class ------------------------------------------------------------------------------------------------------------> Meter::Meter() {} - Meter::Meter(const int width, const string& color_gradient, bool invert) - : width(width), color_gradient(color_gradient), invert(invert) {} + Meter::Meter(const int width, const string& color_gradient, bool invert) + : width(width), color_gradient(color_gradient), invert(invert) {} string Meter::operator()(int value) { if (width < 1) return ""; @@ -368,7 +383,7 @@ namespace Draw { //* Graph class ------------------------------------------------------------------------------------------------------------> void Graph::_create(const deque<long long>& data, int data_offset) { - bool mult = (data.size() - data_offset > 1); + bool mult = (data.size() - data_offset > 1); const auto& graph_symbol = Symbols::graph_symbols.at(symbol + '_' + (invert ? "down" : "up")); array<int, 2> result; const float mod = (height == 1) ? 0.3 : 0.1; @@ -438,11 +453,11 @@ namespace Draw { Graph::Graph() {} - Graph::Graph(int width, int height, const string& color_gradient, - const deque<long long>& data, const string& symbol, - bool invert, bool no_zero, long long max_value, long long offset) - : width(width), height(height), color_gradient(color_gradient), - invert(invert), no_zero(no_zero), offset(offset) { + Graph::Graph(int width, int height, const string& color_gradient, + const deque<long long>& data, const string& symbol, + bool invert, bool no_zero, long long max_value, long long offset) + : width(width), height(height), color_gradient(color_gradient), + invert(invert), no_zero(no_zero), offset(offset) { if (Config::getB("tty_mode") or symbol == "tty") this->symbol = "tty"; else if (symbol != "default") this->symbol = symbol; else this->symbol = Config::getS("graph_symbol"); @@ -466,7 +481,7 @@ namespace Draw { this->_create(data, data_offset); } - string& Graph::operator()(const deque<long long>& data, bool data_same) { + string& Graph::operator()(const deque<long long>& data, bool data_same) { if (data_same) return out; //? Make room for new characters on graph @@ -514,23 +529,23 @@ namespace Cpu { string draw(const cpu_info& cpu, const vector<Gpu::gpu_info>& gpus, bool force_redraw, bool data_same) { if (Runner::stopping) return ""; if (force_redraw) redraw = true; - bool show_temps = (Config::getB("check_temp") and got_sensors); - auto single_graph = Config::getB("cpu_single_graph"); - bool hide_cores = show_temps and (cpu_temp_only or not Config::getB("show_coretemp")); + bool show_temps = (Config::getB("check_temp") and got_sensors); + auto single_graph = Config::getB("cpu_single_graph"); + bool hide_cores = show_temps and (cpu_temp_only or not Config::getB("show_coretemp")); const int extra_width = (hide_cores ? max(6, 6 * b_column_size) : 0); auto& graph_up_field = Config::getS("cpu_graph_upper"); auto& graph_lo_field = Config::getS("cpu_graph_lower"); - auto tty_mode = Config::getB("tty_mode"); + auto tty_mode = Config::getB("tty_mode"); auto& graph_symbol = (tty_mode ? "tty" : Config::getS("graph_symbol_cpu")); auto& graph_bg = Symbols::graph_symbols.at((graph_symbol == "default" ? Config::getS("graph_symbol") + "_up" : graph_symbol + "_up")).at(6); auto& temp_scale = Config::getS("temp_scale"); - auto cpu_bottom = Config::getB("cpu_bottom"); + auto cpu_bottom = Config::getB("cpu_bottom"); const string& title_left = Theme::c("cpu_box") + (cpu_bottom ? Symbols::title_left_down : Symbols::title_left); const string& title_right = Theme::c("cpu_box") + (cpu_bottom ? Symbols::title_right_down : Symbols::title_right); static int bat_pos = 0, bat_len = 0; - if (cpu.cpu_percent.at("total").empty() - or cpu.core_percent.at(0).empty() - or (show_temps and cpu.temp.at(0).empty())) return ""; + if (cpu.cpu_percent.at("total").empty() + or cpu.core_percent.at(0).empty() + or (show_temps and cpu.temp.at(0).empty())) return ""; string out; out.reserve(width * height); @@ -664,8 +679,8 @@ namespace Cpu { //? Draw battery if enabled and present if (Config::getB("show_battery") and has_battery) { - static int old_percent{}; // defaults to = 0 - static long old_seconds{}; // defaults to = 0 + static int old_percent{}; // defaults to = 0 + static long old_seconds{}; // defaults to = 0 static string old_status; static Draw::Meter bat_meter {10, "cpu", true}; static const unordered_flat_map<string, string> bat_symbols = { @@ -758,7 +773,7 @@ namespace Cpu { } out += Theme::c("div_line") + Symbols::v_line; - } catch (const std::exception& e) { throw std::runtime_error("graphs, clock, meter : " + string{e.what()}); } + } catch (const std::exception& e) { throw std::runtime_error("graphs, clock, meter : " + string{e.what()}); } //? Core text and graphs int cx = 0, cy = 1, cc = 0, core_width = (b_column_size == 0 ? 2 : 3); @@ -1048,17 +1063,17 @@ namespace Mem { unordered_flat_map<string, Draw::Meter> disk_meters_free; unordered_flat_map<string, Draw::Graph> io_graphs; - string draw(const mem_info& mem, bool force_redraw, bool data_same) { + string draw(const mem_info& mem, bool force_redraw, bool data_same) { if (Runner::stopping) return ""; if (force_redraw) redraw = true; - auto show_swap = Config::getB("show_swap"); - auto swap_disk = Config::getB("swap_disk"); - auto show_disks = Config::getB("show_disks"); - auto show_io_stat = Config::getB("show_io_stat"); - auto io_mode = Config::getB("io_mode"); - auto io_graph_combined = Config::getB("io_graph_combined"); - auto use_graphs = Config::getB("mem_graphs"); - auto tty_mode = Config::getB("tty_mode"); + auto show_swap = Config::getB("show_swap"); + auto swap_disk = Config::getB("swap_disk"); + auto show_disks = Config::getB("show_disks"); + auto show_io_stat = Config::getB("show_io_stat"); + auto io_mode = Config::getB("io_mode"); + auto io_graph_combined = Config::getB("io_graph_combined"); + auto use_graphs = Config::getB("mem_graphs"); + auto tty_mode = Config::getB("tty_mode"); auto& graph_symbol = (tty_mode ? "tty" : Config::getS("graph_symbol_mem")); auto& graph_bg = Symbols::graph_symbols.at((graph_symbol == "default" ? Config::getS("graph_symbol") + "_up" : graph_symbol + "_up")).at(6); auto totalMem = Mem::get_totalMem(); @@ -1124,20 +1139,20 @@ namespace Mem { if (io_graph_combined) { deque<long long> combined(disk.io_read.size(), 0); rng::transform(disk.io_read, disk.io_write, combined.begin(), std::plus<long long>()); - io_graphs[name] = Draw::Graph{ - disks_width - (io_mode ? 0 : 6), - disks_io_h, "available", combined, - graph_symbol, false, true, speed}; + io_graphs[name] = Draw::Graph{ + disks_width - (io_mode ? 0 : 6), + disks_io_h, "available", combined, + graph_symbol, false, true, speed}; } else { - io_graphs[name + "_read"] = Draw::Graph{ - disks_width, half_height, "free", - disk.io_read, graph_symbol, false, - true, speed}; - io_graphs[name + "_write"] = Draw::Graph{ - disks_width, disks_io_h - half_height, - "used", disk.io_write, graph_symbol, - true, true, speed}; + io_graphs[name + "_read"] = Draw::Graph{ + disks_width, half_height, "free", + disk.io_read, graph_symbol, false, + true, speed}; + io_graphs[name + "_write"] = Draw::Graph{ + disks_width, disks_io_h - half_height, + "used", disk.io_write, graph_symbol, + true, true, speed}; } } } @@ -1207,7 +1222,7 @@ namespace Mem { if (show_disks) { const auto& disks = mem.disks; cx = mem_width; cy = 0; - bool big_disk = disks_width >= 25; + bool big_disk = disks_width >= 25; divider = Mv::l(1) + Theme::c("div_line") + Symbols::div_left + Symbols::h_line * disks_width + Theme::c("mem_box") + Fx::ub + Symbols::div_right + Mv::l(disks_width); const string hu_div = Theme::c("div_line") + Symbols::h_line + Theme::c("main_fg"); if (io_mode) { @@ -1302,12 +1317,12 @@ namespace Net { unordered_flat_map<string, Draw::Graph> graphs; string box; - string draw(const net_info& net, bool force_redraw, bool data_same) { + string draw(const net_info& net, bool force_redraw, bool data_same) { if (Runner::stopping) return ""; if (force_redraw) redraw = true; - auto net_sync = Config::getB("net_sync"); - auto net_auto = Config::getB("net_auto"); - auto tty_mode = Config::getB("tty_mode"); + auto net_sync = Config::getB("net_sync"); + auto net_auto = Config::getB("net_auto"); + auto tty_mode = Config::getB("tty_mode"); auto& graph_symbol = (tty_mode ? "tty" : Config::getS("graph_symbol_net")); string ip_addr = (net.ipv4.empty() ? net.ipv6 : net.ipv4); if (old_ip != ip_addr) { @@ -1329,13 +1344,13 @@ namespace Net { graphs.clear(); if (net.bandwidth.at("download").empty() or net.bandwidth.at("upload").empty()) return out + Fx::reset; - graphs["download"] = Draw::Graph{ - width - b_width - 2, u_graph_height, "download", - net.bandwidth.at("download"), graph_symbol, - false, true, down_max}; - graphs["upload"] = Draw::Graph{ - width - b_width - 2, d_graph_height, "upload", - net.bandwidth.at("upload"), graph_symbol, true, true, up_max}; + graphs["download"] = Draw::Graph{ + width - b_width - 2, u_graph_height, "download", + net.bandwidth.at("download"), graph_symbol, + false, true, down_max}; + graphs["upload"] = Draw::Graph{ + width - b_width - 2, d_graph_height, "upload", + net.bandwidth.at("upload"), graph_symbol, true, true, up_max}; //? Interface selector and buttons @@ -1416,7 +1431,7 @@ namespace Proc { auto selected = Config::getI("proc_selected"); auto last_selected = Config::getI("proc_last_selected"); const int select_max = (Config::getB("show_detailed") ? Proc::select_max - 8 : Proc::select_max); - auto vim_keys = Config::getB("vim_keys"); + auto vim_keys = Config::getB("vim_keys"); int numpids = Proc::numpids; if ((cmd_key == "up" or (vim_keys and cmd_key == "k")) and selected > 0) { @@ -1471,18 +1486,18 @@ namespace Proc { return (not changed ? -1 : selected); } - string draw(const vector<proc_info>& plist, bool force_redraw, bool data_same) { + string draw(const vector<proc_info>& plist, bool force_redraw, bool data_same) { if (Runner::stopping) return ""; - auto proc_tree = Config::getB("proc_tree"); - bool show_detailed = (Config::getB("show_detailed") and cmp_equal(Proc::detailed.last_pid, Config::getI("detailed_pid"))); - bool proc_gradient = (Config::getB("proc_gradient") and not Config::getB("lowcolor") and Theme::gradients.contains("proc")); - auto proc_colors = Config::getB("proc_colors"); - auto tty_mode = Config::getB("tty_mode"); + auto proc_tree = Config::getB("proc_tree"); + bool show_detailed = (Config::getB("show_detailed") and cmp_equal(Proc::detailed.last_pid, Config::getI("detailed_pid"))); + bool proc_gradient = (Config::getB("proc_gradient") and not Config::getB("lowcolor") and Theme::gradients.contains("proc")); + auto proc_colors = Config::getB("proc_colors"); + auto tty_mode = Config::getB("tty_mode"); auto& graph_symbol = (tty_mode ? "tty" : Config::getS("graph_symbol_proc")); auto& graph_bg = Symbols::graph_symbols.at((graph_symbol == "default" ? Config::getS("graph_symbol") + "_up" : graph_symbol + "_up")).at(6); - auto mem_bytes = Config::getB("proc_mem_bytes"); - auto vim_keys = Config::getB("vim_keys"); - auto show_graphs = Config::getB("proc_cpu_graphs"); + auto mem_bytes = Config::getB("proc_mem_bytes"); + auto vim_keys = Config::getB("vim_keys"); + auto show_graphs = Config::getB("proc_cpu_graphs"); start = Config::getI("proc_start"); selected = Config::getI("proc_selected"); const int y = show_detailed ? Proc::y + 8 : Proc::y; @@ -1517,7 +1532,7 @@ namespace Proc { //? Detailed box if (show_detailed) { - bool alive = detailed.status != "Dead"; + bool alive = detailed.status != "Dead"; dgraph_x = x; dgraph_width = max(width / 3, width - 121); d_width = width - dgraph_width - 1; @@ -1589,7 +1604,7 @@ namespace Proc { } //? Filter - auto filtering = Config::getB("proc_filtering"); // ? filter(20) : Config::getS("proc_filter")) + auto filtering = Config::getB("proc_filtering"); // ? filter(20) : Config::getS("proc_filter")) const auto filter_text = (filtering) ? filter(max(6, width - 58)) : uresize(Config::getS("proc_filter"), max(6, width - 58)); out += Mv::to(y, x+9) + title_left + (not filter_text.empty() ? Fx::b : "") + Theme::c("hi_fg") + 'f' + Theme::c("title") + (not filter_text.empty() ? ' ' + filter_text : "ilter") @@ -1670,7 +1685,7 @@ namespace Proc { //? Draw details box if shown if (show_detailed) { - bool alive = detailed.status != "Dead"; + bool alive = detailed.status != "Dead"; const int item_fit = floor((double)(d_width - 2) / 10); const int item_width = floor((double)(d_width - 2) / min(item_fit, 8)); @@ -1729,7 +1744,7 @@ namespace Proc { } //? Update graphs for processes with above 0.0% cpu usage, delete if below 0.1% 10x times - bool has_graph = show_graphs ? p_counters.contains(p.pid) : false; + bool has_graph = show_graphs ? p_counters.contains(p.pid) : false; if (show_graphs and ((p.cpu_p > 0 and not has_graph) or (not data_same and has_graph))) { if (not has_graph) { p_graphs[p.pid] = Draw::Graph{5, 1, "", {}, graph_symbol}; @@ -1886,10 +1901,10 @@ namespace Draw { void calcSizes() { atomic_wait(Runner::active); Config::unlock(); - auto boxes = Config::getS("shown_boxes"); - auto cpu_bottom = Config::getB("cpu_bottom"); - auto mem_below_net = Config::getB("mem_below_net"); - auto proc_left = Config::getB("proc_left"); + auto boxes = Config::getS("shown_boxes"); + auto cpu_bottom = Config::getB("cpu_bottom"); + auto mem_below_net = Config::getB("mem_below_net"); + auto proc_left = Config::getB("proc_left"); Cpu::box.clear(); Gpu::box.clear(); @@ -2030,9 +2045,9 @@ namespace Draw { //* Calculate and draw mem box outlines if (Mem::shown) { using namespace Mem; - auto show_disks = Config::getB("show_disks"); - auto swap_disk = Config::getB("swap_disk"); - auto mem_graphs = Config::getB("mem_graphs"); + auto show_disks = Config::getB("show_disks"); + auto swap_disk = Config::getB("swap_disk"); + auto mem_graphs = Config::getB("mem_graphs"); width = round((double)Term::width * (Proc::shown ? width_p : 100) / 100); height = ceil((double)Term::height * (100 - Net::height_p * Net::shown*4 / ((Gpu::shown != 0 and Cpu::shown) + 4)) / 100) - Cpu::height - Gpu::height*Gpu::shown; |