summaryrefslogtreecommitdiffstats
path: root/src/btop_draw.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/btop_draw.cpp')
-rw-r--r--src/btop_draw.cpp219
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;