.
This commit is contained in:
parent
635a7c79ec
commit
caf1e87718
@ -11,15 +11,194 @@
|
|||||||
#include <term.h>
|
#include <term.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "interactive.hpp"
|
#include "interactive.hpp"
|
||||||
|
#include <map>
|
||||||
|
|
||||||
namespace interactive {
|
namespace interactive {
|
||||||
|
|
||||||
|
// Forward declarations
|
||||||
|
void process_line(WINDOW* win, const std::string& text, const std::map<std::string, int>& color_pair_map);
|
||||||
|
|
||||||
|
// Function to convert ANSI escape codes to ncurses attributes and print text
|
||||||
|
void ansi_print(WINDOW* win, const std::string& text) {
|
||||||
|
// Ensure we're using a UTF-8 compatible locale
|
||||||
|
static bool locale_initialized = false;
|
||||||
|
if (!locale_initialized) {
|
||||||
|
setlocale(LC_ALL, "");
|
||||||
|
locale_initialized = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int color_pairs_initialized = 0;
|
||||||
|
static std::map<std::string, int> color_pair_map;
|
||||||
|
|
||||||
|
// Initialize color pairs if not done yet
|
||||||
|
if (!color_pairs_initialized) {
|
||||||
|
// Check if terminal supports colors
|
||||||
|
if (has_colors()) {
|
||||||
|
// Define color pairs for common ANSI colors
|
||||||
|
init_pair(1, COLOR_RED, -1);
|
||||||
|
init_pair(2, COLOR_GREEN, -1);
|
||||||
|
init_pair(3, COLOR_YELLOW, -1);
|
||||||
|
init_pair(4, COLOR_BLUE, -1);
|
||||||
|
init_pair(5, COLOR_MAGENTA, -1);
|
||||||
|
init_pair(6, COLOR_CYAN, -1);
|
||||||
|
init_pair(7, COLOR_WHITE, -1);
|
||||||
|
|
||||||
|
// Try to define extended colors if possible
|
||||||
|
if (COLORS >= 256) {
|
||||||
|
init_pair(8, 8, -1); // Dark grey
|
||||||
|
init_pair(9, 142, -1); // Dark yellow (approximation)
|
||||||
|
init_pair(10, 250, -1); // Light grey (approximation)
|
||||||
|
} else {
|
||||||
|
// Fallback for terminals with fewer colors
|
||||||
|
init_pair(8, COLOR_BLACK, -1); // Dark grey fallback
|
||||||
|
init_pair(9, COLOR_YELLOW, -1); // Dark yellow fallback
|
||||||
|
init_pair(10, COLOR_WHITE, -1); // Light grey fallback
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Map ANSI codes to color pairs
|
||||||
|
color_pair_map["\033[1;31m"] = 1; // Red
|
||||||
|
color_pair_map["\033[1;32m"] = 2; // Green
|
||||||
|
color_pair_map["\033[1;33m"] = 3; // Yellow
|
||||||
|
color_pair_map["\033[1;34m"] = 4; // Blue
|
||||||
|
color_pair_map["\033[1;35m"] = 5; // Magenta
|
||||||
|
color_pair_map["\033[1;36m"] = 6; // Cyan
|
||||||
|
color_pair_map["\033[1;37m"] = 7; // White
|
||||||
|
color_pair_map["\033[90m"] = 8; // Dark Grey
|
||||||
|
color_pair_map["\033[38;5;142m"] = 9; // Dark Yellow
|
||||||
|
color_pair_map["\033[38;5;250m"] = 10; // Light Grey
|
||||||
|
|
||||||
|
// Also map the non-bold versions
|
||||||
|
color_pair_map["\033[31m"] = 1; // Red
|
||||||
|
color_pair_map["\033[32m"] = 2; // Green
|
||||||
|
color_pair_map["\033[33m"] = 3; // Yellow
|
||||||
|
color_pair_map["\033[34m"] = 4; // Blue
|
||||||
|
color_pair_map["\033[35m"] = 5; // Magenta
|
||||||
|
color_pair_map["\033[36m"] = 6; // Cyan
|
||||||
|
color_pair_map["\033[37m"] = 7; // White
|
||||||
|
|
||||||
|
color_pairs_initialized = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle newlines in the text
|
||||||
|
size_t start = 0;
|
||||||
|
size_t end = text.find('\n');
|
||||||
|
|
||||||
|
// If no newlines, process the whole text at once
|
||||||
|
if (end == std::string::npos) {
|
||||||
|
process_line(win, text, color_pair_map);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Process each line separately
|
||||||
|
while (end != std::string::npos) {
|
||||||
|
// Process this line
|
||||||
|
std::string line = text.substr(start, end - start);
|
||||||
|
process_line(win, line, color_pair_map);
|
||||||
|
|
||||||
|
// Move to next line
|
||||||
|
waddch(win, '\n');
|
||||||
|
|
||||||
|
// Find next line
|
||||||
|
start = end + 1;
|
||||||
|
end = text.find('\n', start);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Process any remaining text after the last newline
|
||||||
|
if (start < text.length()) {
|
||||||
|
process_line(win, text.substr(start), color_pair_map);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Helper function to process a single line of text
|
||||||
|
void process_line(WINDOW* win, const std::string& text, const std::map<std::string, int>& color_pair_map) {
|
||||||
|
size_t pos = 0;
|
||||||
|
int current_attrs = 0;
|
||||||
|
int current_color_pair = 0;
|
||||||
|
|
||||||
|
while (pos < text.length()) {
|
||||||
|
// Check for ANSI escape sequence
|
||||||
|
if (text[pos] == '\033' && pos + 1 < text.length() && text[pos + 1] == '[') {
|
||||||
|
// Find the end of the escape sequence (marked by 'm')
|
||||||
|
size_t end_pos = text.find('m', pos);
|
||||||
|
if (end_pos != std::string::npos) {
|
||||||
|
std::string esc_seq = text.substr(pos, end_pos - pos + 1);
|
||||||
|
|
||||||
|
// Reset attributes if the sequence is a reset code
|
||||||
|
if (esc_seq == "\033[0m") {
|
||||||
|
wattrset(win, A_NORMAL);
|
||||||
|
current_attrs = 0;
|
||||||
|
current_color_pair = 0;
|
||||||
|
}
|
||||||
|
// Handle bold attribute
|
||||||
|
else if (esc_seq == "\033[1m") {
|
||||||
|
current_attrs |= A_BOLD;
|
||||||
|
wattrset(win, COLOR_PAIR(current_color_pair) | current_attrs);
|
||||||
|
}
|
||||||
|
// Apply color pair if known
|
||||||
|
else if (color_pair_map.find(esc_seq) != color_pair_map.end()) {
|
||||||
|
current_color_pair = color_pair_map.at(esc_seq);
|
||||||
|
// Check if this is a bold sequence (contains "1;")
|
||||||
|
if (esc_seq.find("1;") != std::string::npos) {
|
||||||
|
current_attrs |= A_BOLD;
|
||||||
|
}
|
||||||
|
wattrset(win, COLOR_PAIR(current_color_pair) | current_attrs);
|
||||||
|
}
|
||||||
|
// Handle more complex color sequences (38;5;XXXm)
|
||||||
|
else if (esc_seq.find("38;5;") != std::string::npos) {
|
||||||
|
// Extract the color number
|
||||||
|
std::string color_num_str = esc_seq.substr(esc_seq.find("38;5;") + 5);
|
||||||
|
color_num_str = color_num_str.substr(0, color_num_str.length() - 1); // Remove 'm'
|
||||||
|
|
||||||
|
try {
|
||||||
|
int color_num = std::stoi(color_num_str);
|
||||||
|
// Create a new color pair for this color if needed
|
||||||
|
int pair_num = 11 + color_num; // Start after our predefined pairs
|
||||||
|
|
||||||
|
// Only initialize if in valid range and we haven't seen this color before
|
||||||
|
if (color_num < COLORS && color_pair_map.find(esc_seq) == color_pair_map.end()) {
|
||||||
|
// Try to initialize, but catch errors in case color is invalid
|
||||||
|
try {
|
||||||
|
init_pair(pair_num, color_num, -1);
|
||||||
|
const_cast<std::map<std::string, int>&>(color_pair_map)[esc_seq] = pair_num;
|
||||||
|
} catch (...) {
|
||||||
|
// If we can't initialize this color, use a default
|
||||||
|
const_cast<std::map<std::string, int>&>(color_pair_map)[esc_seq] = 7; // White
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (color_pair_map.find(esc_seq) != color_pair_map.end()) {
|
||||||
|
current_color_pair = color_pair_map.at(esc_seq);
|
||||||
|
wattrset(win, COLOR_PAIR(current_color_pair) | current_attrs);
|
||||||
|
}
|
||||||
|
} catch (...) {
|
||||||
|
// If we can't parse the color, just ignore it
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pos = end_pos + 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Print the character as-is
|
||||||
|
waddch(win, text[pos]);
|
||||||
|
pos++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int fullscreen_window::ncurses_streambuf::overflow(int c) {
|
int fullscreen_window::ncurses_streambuf::overflow(int c) {
|
||||||
if (c != EOF) {
|
if (c != EOF) {
|
||||||
buffer += static_cast<char>(c);
|
buffer += static_cast<char>(c);
|
||||||
if (c == '\n') {
|
if (c == '\n') {
|
||||||
// Process buffer with proper escape sequence handling
|
// Process buffer with proper escape sequence handling
|
||||||
wprintw(win, "%s", buffer.c_str());
|
ansi_print(win, buffer);
|
||||||
|
wrefresh(win);
|
||||||
|
buffer.clear();
|
||||||
|
} else if (buffer.length() > 1024) {
|
||||||
|
// If buffer is getting too large without a newline,
|
||||||
|
// process it anyway to prevent memory issues
|
||||||
|
ansi_print(win, buffer);
|
||||||
wrefresh(win);
|
wrefresh(win);
|
||||||
buffer.clear();
|
buffer.clear();
|
||||||
}
|
}
|
||||||
@ -31,8 +210,8 @@ fullscreen_window::fullscreen_window(std::string title) {
|
|||||||
// Set locale for wide character support
|
// Set locale for wide character support
|
||||||
std::setlocale(LC_ALL, "");
|
std::setlocale(LC_ALL, "");
|
||||||
|
|
||||||
// Initialize ncurses with proper terminal capabilities
|
// Initialize ncurses with basic terminal capabilities
|
||||||
putenv(const_cast<char*>("TERM=xterm-256color"));
|
// Don't force a specific TERM type which could cause compatibility issues
|
||||||
|
|
||||||
initscr();
|
initscr();
|
||||||
raw(); // Use raw mode for better control
|
raw(); // Use raw mode for better control
|
||||||
@ -41,9 +220,11 @@ fullscreen_window::fullscreen_window(std::string title) {
|
|||||||
curs_set(0); // Hide cursor
|
curs_set(0); // Hide cursor
|
||||||
set_escdelay(25); // Set ESC delay to 25ms
|
set_escdelay(25); // Set ESC delay to 25ms
|
||||||
|
|
||||||
// Enable color support
|
// Enable color support if available
|
||||||
start_color();
|
if (has_colors()) {
|
||||||
use_default_colors();
|
start_color();
|
||||||
|
use_default_colors();
|
||||||
|
}
|
||||||
|
|
||||||
refresh();
|
refresh();
|
||||||
|
|
||||||
@ -102,6 +283,12 @@ fullscreen_window::~fullscreen_window() {
|
|||||||
close();
|
close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void fullscreen_window::clear_display()
|
||||||
|
{
|
||||||
|
werase(display_win);
|
||||||
|
wrefresh(display_win);
|
||||||
|
}
|
||||||
|
|
||||||
void fullscreen_window::set_input_text_display(std::string text) {
|
void fullscreen_window::set_input_text_display(std::string text) {
|
||||||
werase(input_win);
|
werase(input_win);
|
||||||
box(input_win, 0, 0);
|
box(input_win, 0, 0);
|
||||||
@ -152,7 +339,7 @@ std::string fullscreen_window::set_input_text_entry(std::string prompt) {
|
|||||||
return input;
|
return input;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string fullscreen_window::set_input_multiple_choice(std::string prompt, std::vector<std::string> choices) {
|
std::string fullscreen_window::set_input_multiple_choice(std::string prompt, std::vector<std::string> choices, std::string default_choice) {
|
||||||
werase(input_win);
|
werase(input_win);
|
||||||
box(input_win, 0, 0);
|
box(input_win, 0, 0);
|
||||||
|
|
||||||
@ -160,6 +347,14 @@ std::string fullscreen_window::set_input_multiple_choice(std::string prompt, std
|
|||||||
mvwprintw(input_win, 1, 2, "%s", prompt.c_str());
|
mvwprintw(input_win, 1, 2, "%s", prompt.c_str());
|
||||||
|
|
||||||
int selected = 0;
|
int selected = 0;
|
||||||
|
if (!default_choice.empty()) {
|
||||||
|
for (size_t i = 0; i < choices.size(); ++i) {
|
||||||
|
if (choices[i] == default_choice) {
|
||||||
|
selected = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
std::string filter = "";
|
std::string filter = "";
|
||||||
std::string last_filter = "";
|
std::string last_filter = "";
|
||||||
auto last_key_time = std::chrono::steady_clock::now();
|
auto last_key_time = std::chrono::steady_clock::now();
|
||||||
|
@ -9,6 +9,9 @@
|
|||||||
|
|
||||||
namespace interactive {
|
namespace interactive {
|
||||||
|
|
||||||
|
// Function to convert ANSI escape codes to ncurses attributes and print text
|
||||||
|
void ansi_print(WINDOW* win, const std::string& text);
|
||||||
|
|
||||||
class fullscreen_window {
|
class fullscreen_window {
|
||||||
private:
|
private:
|
||||||
WINDOW* display_win;
|
WINDOW* display_win;
|
||||||
@ -48,19 +51,20 @@ class fullscreen_window {
|
|||||||
// Destructor to restore original streambufs
|
// Destructor to restore original streambufs
|
||||||
~fullscreen_window();
|
~fullscreen_window();
|
||||||
|
|
||||||
|
// clears the display window and refreshes it
|
||||||
|
void clear_display();
|
||||||
|
|
||||||
// just display centered text in the input window. returns immediately.
|
// just display centered text in the input window. returns immediately.
|
||||||
void set_input_text_display(std::string text);
|
void set_input_text_display(std::string text);
|
||||||
|
|
||||||
|
|
||||||
// displays the prompt and a text entry box.
|
// displays the prompt and a text entry box.
|
||||||
// only returns after the user has entered text and pressed enter. pressing escape returns an empty string.
|
// only returns after the user has entered text and pressed enter. pressing escape returns an empty string.
|
||||||
std::string set_input_text_entry(std::string prompt);
|
std::string set_input_text_entry(std::string prompt);
|
||||||
|
|
||||||
|
|
||||||
// displays the prompt and then a list of choices.
|
// displays the prompt and then a list of choices.
|
||||||
// returns when user selects a choice using arrow keys and presses enter. pressing escape returns an empty string.
|
// returns when user selects a choice using arrow keys and presses enter. pressing escape returns an empty string.
|
||||||
// letter keys filter by choices to those that start with that letter, and if multiple letters are typed with a delay it will filter by that string of letters.
|
// letter keys filter by choices to those that start with that letter, and if multiple letters are typed with a delay it will filter by that string of letters.
|
||||||
std::string set_input_multiple_choice(std::string prompt, std::vector<std::string> choices);
|
std::string set_input_multiple_choice(std::string prompt, std::vector<std::string> choices, std::string default_choice = "");
|
||||||
|
|
||||||
// displays a yes/no confirmation prompt, with arrow keys to select yes or no. returns true if yes, false if no.
|
// displays a yes/no confirmation prompt, with arrow keys to select yes or no. returns true if yes, false if no.
|
||||||
// allows y as shortcut for yes and n as shortcut for no.
|
// allows y as shortcut for yes and n as shortcut for no.
|
||||||
|
@ -65,15 +65,22 @@ void interactive_mode() {
|
|||||||
|
|
||||||
list_servers();
|
list_servers();
|
||||||
|
|
||||||
std::string server_name = iw.set_input_multiple_choice("Select a server", server_names);
|
while (true) {
|
||||||
if (server_name.empty()) {
|
std::string server_name = iw.set_input_multiple_choice("Select a server", server_names);
|
||||||
return;
|
if (server_name.empty())
|
||||||
|
{
|
||||||
|
iw.close();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (!server_name.empty()) {
|
||||||
|
iw.clear_display();
|
||||||
|
show_server_details(server_name);
|
||||||
|
server_name = iw.set_input_multiple_choice("Select a server", server_names, server_name);
|
||||||
|
}
|
||||||
|
iw.clear_display();
|
||||||
|
list_servers();
|
||||||
}
|
}
|
||||||
|
|
||||||
iw.close();
|
|
||||||
|
|
||||||
show_server_details(server_name);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void list_servers() {
|
void list_servers() {
|
||||||
@ -151,6 +158,7 @@ void show_server_details(const std::string& server_name) {
|
|||||||
std::cout << "Status: Offline" << std::endl;
|
std::cout << "Status: Offline" << std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
std::cout << std::endl;
|
||||||
|
|
||||||
//---------------------
|
//---------------------
|
||||||
{
|
{
|
||||||
|
@ -29,12 +29,12 @@ struct coloredText {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const std::map<std::string, coloredText> kReplacements = {
|
const std::map<std::string, coloredText> kReplacements = {
|
||||||
{":tick:", {"✓", kTextColor_Green}},
|
{":tick:", {"+", kTextColor_Green}},
|
||||||
{":cross:", {"✗", kTextColor_Red}},
|
{":cross:", {"x", kTextColor_Red}},
|
||||||
{":warning:", {"⚠️", kTextColor_Yellow}},
|
{":warning:", {"!", kTextColor_Yellow}},
|
||||||
{":info:", {"ℹ️", kTextColor_Blue}},
|
{":info:", {"i", kTextColor_Blue}},
|
||||||
{":check:", {"✅", kTextColor_Green}},
|
{":check:", {"+", kTextColor_Green}},
|
||||||
{":x:", {"❌", kTextColor_Red}}
|
{":x:", {"x", kTextColor_Red}}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Helper function to get ANSI color code
|
// Helper function to get ANSI color code
|
||||||
@ -192,14 +192,14 @@ void tableprint::print() {
|
|||||||
// Print title if it exists
|
// Print title if it exists
|
||||||
if (!title.empty()) {
|
if (!title.empty()) {
|
||||||
std::cout << "\033[90m"; // Dark grey color for borders
|
std::cout << "\033[90m"; // Dark grey color for borders
|
||||||
std::cout << "┌";
|
std::cout << "+";
|
||||||
for (size_t i = 0; i < rows[0].size(); ++i) {
|
for (size_t i = 0; i < rows[0].size(); ++i) {
|
||||||
std::cout << std::string(col_widths[i] + 2, '-');
|
std::cout << std::string(col_widths[i] + 2, '-');
|
||||||
if (i < rows[0].size() - 1) std::cout << "┬";
|
if (i < rows[0].size() - 1) std::cout << "+";
|
||||||
}
|
}
|
||||||
std::cout << "┐" << std::endl;
|
std::cout << "+" << std::endl;
|
||||||
|
|
||||||
std::cout << "│"; // White color for title
|
std::cout << "|"; // White color for title
|
||||||
size_t title_width = 0;
|
size_t title_width = 0;
|
||||||
for (size_t width : col_widths) {
|
for (size_t width : col_widths) {
|
||||||
title_width += width + 2; // +2 for padding
|
title_width += width + 2; // +2 for padding
|
||||||
@ -207,82 +207,82 @@ void tableprint::print() {
|
|||||||
title_width += col_widths.size() - 1; // Add space for vertical borders
|
title_width += col_widths.size() - 1; // Add space for vertical borders
|
||||||
|
|
||||||
std::cout << width_print_centered(title,title_width,"\033[1;37m");
|
std::cout << width_print_centered(title,title_width,"\033[1;37m");
|
||||||
std::cout << "\033[90m│" << std::endl;
|
std::cout << "\033[90m|" << std::endl;
|
||||||
|
|
||||||
// Use └─┴─┘ for bottom of title box to connect with table
|
// Use └─┴─┘ for bottom of title box to connect with table
|
||||||
std::cout << "├";
|
std::cout << "+";
|
||||||
for (size_t i = 0; i < rows[0].size(); ++i) {
|
for (size_t i = 0; i < rows[0].size(); ++i) {
|
||||||
std::cout << std::string(col_widths[i] + 2, '-');
|
std::cout << std::string(col_widths[i] + 2, '-');
|
||||||
if (i < rows[0].size() - 1) std::cout << "┼";
|
if (i < rows[0].size() - 1) std::cout << "-";
|
||||||
}
|
}
|
||||||
std::cout << "┤" << std::endl;
|
std::cout << "+" << std::endl;
|
||||||
} else {
|
} else {
|
||||||
// Print top border if no title
|
// Print top border if no title
|
||||||
std::cout << "\033[90m"; // Dark grey color for borders
|
std::cout << "\033[90m"; // Dark grey color for borders
|
||||||
std::cout << "┌";
|
std::cout << "┌";
|
||||||
for (size_t i = 0; i < rows[0].size(); ++i) {
|
for (size_t i = 0; i < rows[0].size(); ++i) {
|
||||||
std::cout << std::string(col_widths[i] + 2, '-');
|
std::cout << std::string(col_widths[i] + 2, '-');
|
||||||
if (i < rows[0].size() - 1) std::cout << "┬";
|
if (i < rows[0].size() - 1) std::cout << "+";
|
||||||
}
|
}
|
||||||
std::cout << "┐" << std::endl;
|
std::cout << "+" << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Print header
|
// Print header
|
||||||
std::cout << "│";
|
std::cout << "|";
|
||||||
for (size_t i = 0; i < rows[0].size(); ++i) {
|
for (size_t i = 0; i < rows[0].size(); ++i) {
|
||||||
std::cout << width_print_centered(rows[0][i],col_widths[i]+2,"\033[1;36m");
|
std::cout << width_print_centered(rows[0][i],col_widths[i]+2,"\033[1;36m");
|
||||||
if (i < rows[0].size() - 1) {
|
if (i < rows[0].size() - 1) {
|
||||||
std::cout << "\033[90m│\033[1;36m"; // Border color then back to cyan
|
std::cout << "\033[90m|\033[1;36m"; // Border color then back to cyan
|
||||||
} else {
|
} else {
|
||||||
std::cout << "\033[90m│"; // Just border color for last column
|
std::cout << "\033[90m|"; // Just border color for last column
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
std::cout << std::endl;
|
std::cout << std::endl;
|
||||||
|
|
||||||
// Print header separator
|
// Print header separator
|
||||||
if (!mCompact) {
|
if (!mCompact) {
|
||||||
std::cout << "├";
|
std::cout << "+";
|
||||||
for (size_t i = 0; i < rows[0].size(); ++i) {
|
for (size_t i = 0; i < rows[0].size(); ++i) {
|
||||||
for (size_t j = 0; j < col_widths[i] + 2; ++j) {
|
for (size_t j = 0; j < col_widths[i] + 2; ++j) {
|
||||||
std::cout << "-";
|
std::cout << "-";
|
||||||
}
|
}
|
||||||
if (i < rows[0].size() - 1) std::cout << "┼";
|
if (i < rows[0].size() - 1) std::cout << "+";
|
||||||
}
|
}
|
||||||
std::cout << "┤" << std::endl;
|
std::cout << "+" << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Print rows
|
// Print rows
|
||||||
for (size_t row_idx = 1; row_idx < rows.size(); ++row_idx) {
|
for (size_t row_idx = 1; row_idx < rows.size(); ++row_idx) {
|
||||||
const auto& row = rows[row_idx];
|
const auto& row = rows[row_idx];
|
||||||
std::cout << "│";
|
std::cout << "|";
|
||||||
for (size_t i = 0; i < row.size(); ++i) {
|
for (size_t i = 0; i < row.size(); ++i) {
|
||||||
// Set the appropriate color for the row
|
// Set the appropriate color for the row
|
||||||
std::string rowcolor = (row_idx % 2 == 1) ? "\033[38;5;142m" : "\033[38;5;250m";
|
std::string rowcolor = (row_idx % 2 == 1) ? "\033[38;5;142m" : "\033[38;5;250m";
|
||||||
std::cout << width_print_left(row[i],col_widths[i]+2,rowcolor);
|
std::cout << width_print_left(row[i],col_widths[i]+2,rowcolor);
|
||||||
std::cout << "\033[90m" << "│";
|
std::cout << "\033[90m" << "|";
|
||||||
}
|
}
|
||||||
std::cout << std::endl;
|
std::cout << std::endl;
|
||||||
|
|
||||||
// Print row separator if not the last row
|
// Print row separator if not the last row
|
||||||
if (row_idx < rows.size() - 1 && !mCompact) {
|
if (row_idx < rows.size() - 1 && !mCompact) {
|
||||||
std::cout << "├";
|
std::cout << "+";
|
||||||
for (size_t i = 0; i < rows[0].size(); ++i) {
|
for (size_t i = 0; i < rows[0].size(); ++i) {
|
||||||
for (size_t j = 0; j < col_widths[i] + 2; ++j) {
|
for (size_t j = 0; j < col_widths[i] + 2; ++j) {
|
||||||
std::cout << "-";
|
std::cout << "-";
|
||||||
}
|
}
|
||||||
if (i < rows[0].size() - 1) std::cout << "┼";
|
if (i < rows[0].size() - 1) std::cout << "+";
|
||||||
}
|
}
|
||||||
std::cout << "┤" << std::endl;
|
std::cout << "+" << std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Print bottom border
|
// Print bottom border
|
||||||
std::cout << "└";
|
std::cout << "+";
|
||||||
for (size_t i = 0; i < rows[0].size(); ++i) {
|
for (size_t i = 0; i < rows[0].size(); ++i) {
|
||||||
for (size_t j = 0; j < col_widths[i] + 2; ++j) {
|
for (size_t j = 0; j < col_widths[i] + 2; ++j) {
|
||||||
std::cout << "-";
|
std::cout << "-";
|
||||||
}
|
}
|
||||||
if (i < rows[0].size() - 1) std::cout << "┴";
|
if (i < rows[0].size() - 1) std::cout << "+";
|
||||||
}
|
}
|
||||||
std::cout << "┘" << "\033[0m" << std::endl; // Reset color
|
std::cout << "+" << "\033[0m" << std::endl; // Reset color
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user