From 9e377f6b3527df337b659ad0ba087bb011019f7d Mon Sep 17 00:00:00 2001 From: Your Name Date: Mon, 21 Apr 2025 21:26:18 +1200 Subject: [PATCH] . --- src/servers.cpp | 2 +- src/tableprint.cpp | 139 ++++++++++++++++++++++++++++++--------------- 2 files changed, 95 insertions(+), 46 deletions(-) diff --git a/src/servers.cpp b/src/servers.cpp index 20a854c..dbd6b27 100644 --- a/src/servers.cpp +++ b/src/servers.cpp @@ -55,7 +55,7 @@ void list_servers() { auto servers = get_configured_servers(); tableprint tp("All DropShell Servers"); - tp.add_row({"Name", "Address", "Service Health", "Ports"}); + tp.add_row({"Name", "Address", "Health", "Ports"}); for (const auto& server : servers) { std::vector ports_used; std::string serviceticks = ""; diff --git a/src/tableprint.cpp b/src/tableprint.cpp index cf9b48a..83c2c58 100644 --- a/src/tableprint.cpp +++ b/src/tableprint.cpp @@ -4,6 +4,9 @@ #include #include #include +#include +#include +#include // Helper function to replace all occurrences of a substring in a regular string std::wstring replace_all(const std::string& str, const std::string& from, const std::wstring& to) { @@ -58,10 +61,11 @@ void tableprint::print() { std::vector col_widths(rows[0].size(), 0); for (const auto& row : rows) { for (size_t i = 0; i < row.size(); ++i) { - // Calculate width considering that :tick: and :cross: will be replaced with single characters std::string cell = row[i]; - size_t tick_count = std::count(cell.begin(), cell.end(), ':') / 2; // Rough estimate - col_widths[i] = std::max(col_widths[i], cell.length() - (tick_count * 5)); // 5 is length of ":tick:" minus 1 + // Count occurrences of :tick: and :cross: + size_t tick_count = std::count(cell.begin(), cell.end(), ':') / 2; + // Adjust width: original length minus 5 for each :tick: or :cross: (since they become 1 char) + col_widths[i] = std::max(col_widths[i], cell.length() - (tick_count * 5)); } } @@ -74,87 +78,132 @@ void tableprint::print() { // Print title if it exists if (!title.empty()) { - std::wcout << L"\033[90m"; // Dark grey color for borders - std::wcout << L"┌" << std::wstring(total_width, L'─') << L"┐" << std::endl; - std::wcout << L"│" << L"\033[1;37m"; // White color for title - size_t padding = (total_width - title.length()) / 2; - std::wcout << std::wstring(padding, L' ') << std::wstring(title.begin(), title.end()) - << std::wstring(total_width - title.length() - padding, L' '); - std::wcout << L"\033[90m│" << std::endl; - // Use └─┴─┘ for bottom of title box to connect with table - std::wcout << L"├"; - for (size_t i = 0; i < rows[0].size(); ++i) { - std::wcout << std::wstring(col_widths[i] + 2, L'─'); - if (i < rows[0].size() - 1) std::wcout << L"┬"; + std::cout << "\033[90m"; // Dark grey color for borders + std::cout << "┌"; + for (size_t i = 0; i < total_width; ++i) { + std::cout << "-"; } - std::wcout << L"┤" << std::endl; + std::cout << "┐" << std::endl; + + std::cout << "│" << "\033[1;37m"; // White color for title + size_t padding = (total_width - title.length()) / 2; + for (size_t i = 0; i < padding; ++i) { + std::cout << " "; + } + std::cout << title; + for (size_t i = 0; i < total_width - title.length() - padding; ++i) { + std::cout << " "; + } + std::cout << "\033[90m│" << std::endl; + + // Use └─┴─┘ for bottom of title box to connect with table + std::cout << "├"; + for (size_t i = 0; i < rows[0].size(); ++i) { + for (size_t j = 0; j < col_widths[i] + 2; ++j) { + std::cout << "-"; + } + if (i < rows[0].size() - 1) std::cout << "┬"; + } + std::cout << "┤" << std::endl; } else { // Print top border if no title - std::wcout << L"\033[90m"; // Dark grey color for borders - std::wcout << L"┌"; + std::cout << "\033[90m"; // Dark grey color for borders + std::cout << "┌"; for (size_t i = 0; i < rows[0].size(); ++i) { - std::wcout << std::wstring(col_widths[i] + 2, L'─'); - if (i < rows[0].size() - 1) std::wcout << L"┬"; + for (size_t j = 0; j < col_widths[i] + 2; ++j) { + std::cout << "-"; + } + if (i < rows[0].size() - 1) std::cout << "┬"; } - std::wcout << L"┐" << std::endl; + std::cout << "┐" << std::endl; } // Print header - std::wcout << L"│"; - std::wcout << L"\033[1;36m"; // Cyan color for header + std::cout << "│"; + std::cout << "\033[1;36m"; // Cyan color for header for (size_t i = 0; i < rows[0].size(); ++i) { - std::wcout << L" " << std::setw(col_widths[i]) << std::left << std::wstring(rows[0][i].begin(), rows[0][i].end()) << L" "; + std::cout << " " << std::setw(col_widths[i]) << std::left << rows[0][i] << " "; if (i < rows[0].size() - 1) { - std::wcout << L"\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 { - std::wcout << L"\033[90m│"; // Just border color for last column + std::cout << "\033[90m│"; // Just border color for last column } } - std::wcout << std::endl; + std::cout << std::endl; // Print header separator - std::wcout << L"├"; + std::cout << "├"; for (size_t i = 0; i < rows[0].size(); ++i) { - std::wcout << std::wstring(col_widths[i] + 2, L'─'); - if (i < rows[0].size() - 1) std::wcout << L"┼"; + for (size_t j = 0; j < col_widths[i] + 2; ++j) { + std::cout << "-"; + } + if (i < rows[0].size() - 1) std::cout << "┼"; } - std::wcout << L"┤" << std::endl; + std::cout << "┤" << std::endl; // Print rows for (size_t row_idx = 1; row_idx < rows.size(); ++row_idx) { const auto& row = rows[row_idx]; - std::wcout << L"│"; + std::cout << "│"; for (size_t i = 0; i < row.size(); ++i) { std::string cell = row[i]; // Replace :tick: and :cross: with colored symbols - std::wstring processed_cell = replace_all(cell, ":tick:", L"\033[1;32m✓\033[0m"); - processed_cell = replace_all(processed_cell, ":cross:", L"\033[1;31m✗\033[0m"); + std::string processed_cell; + size_t pos = 0; + while (pos < cell.length()) { + if (cell.compare(pos, 6, ":tick:") == 0) { + processed_cell += "\033[1;32m✓\033[0m"; + pos += 6; + } else if (cell.compare(pos, 7, ":cross:") == 0) { + processed_cell += "\033[1;31m✗\033[0m"; + pos += 7; + } else { + processed_cell += cell[pos]; + pos++; + } + } // Set the appropriate color for the row if (row_idx % 2 == 1) { - std::wcout << L" " << L"\033[38;5;142m" << processed_cell << L"\033[90m" << L" │"; + std::cout << " " << "\033[38;5;142m"; + if (cell.find(":tick:") != std::string::npos || cell.find(":cross:") != std::string::npos) { + std::cout << " " << processed_cell << " "; + } else { + std::cout << std::setw(col_widths[i]) << std::left << processed_cell; + } + std::cout << "\033[90m" << " │"; } else { - std::wcout << L" " << L"\033[38;5;250m" << processed_cell << L"\033[90m" << L" │"; + std::cout << " " << "\033[38;5;250m"; + if (cell.find(":tick:") != std::string::npos || cell.find(":cross:") != std::string::npos) { + std::cout << " " << processed_cell << " "; + } else { + std::cout << std::setw(col_widths[i]) << std::left << processed_cell; + } + std::cout << "\033[90m" << " │"; } } - std::wcout << std::endl; + std::cout << std::endl; // Print row separator if not the last row if (row_idx < rows.size() - 1) { - std::wcout << L"├"; + std::cout << "├"; for (size_t i = 0; i < rows[0].size(); ++i) { - std::wcout << std::wstring(col_widths[i] + 2, L'─'); - if (i < rows[0].size() - 1) std::wcout << L"┼"; + for (size_t j = 0; j < col_widths[i] + 2; ++j) { + std::cout << "-"; + } + if (i < rows[0].size() - 1) std::cout << "┼"; } - std::wcout << L"┤" << std::endl; + std::cout << "┤" << std::endl; } } // Print bottom border - std::wcout << L"└"; + std::cout << "└"; for (size_t i = 0; i < rows[0].size(); ++i) { - std::wcout << std::wstring(col_widths[i] + 2, L'─'); - if (i < rows[0].size() - 1) std::wcout << L"┴"; + for (size_t j = 0; j < col_widths[i] + 2; ++j) { + std::cout << "-"; + } + if (i < rows[0].size() - 1) std::cout << "┴"; } - std::wcout << L"┘" << L"\033[0m" << std::endl; // Reset color + std::cout << "┘" << "\033[0m" << std::endl; // Reset color } \ No newline at end of file