diff --git a/src/commands/b_manage.cpp b/src/commands/b_manage.cpp index c3efaca..6d75e6e 100644 --- a/src/commands/b_manage.cpp +++ b/src/commands/b_manage.cpp @@ -4,8 +4,11 @@ #include #include #include "manage/ManageScreen.h" +#include #include "config.h" +platform::ManageScreen* manager = nullptr; + void manageArguments(argparse::ArgumentParser& program, int argc, char** argv) { program.add_argument("-m", "--model").default_value("any").help("Filter results of the selected model)"); @@ -42,6 +45,11 @@ std::pair numRowsCols() return { ts.ws_row, ts.ws_col }; #endif /* TIOCGSIZE */ } +void handleResize(int sig) +{ + auto [rows, cols] = numRowsCols(); + manager->updateSize(rows, cols); +} int main(int argc, char** argv) { @@ -50,13 +58,15 @@ int main(int argc, char** argv) std::string model = program.get("model"); std::string score = program.get("score"); std::string platform = program.get("platform"); - auto complete = program.get("complete"); - auto partial = program.get("partial"); - auto compare = program.get("compare"); - auto [rows, cols] = numRowsCols(); + bool complete = program.get("complete"); + bool partial = program.get("partial"); + bool compare = program.get("compare"); if (complete) partial = false; - auto manager = platform::ManageScreen(rows, cols, model, score, platform, complete, partial, compare); - manager.doMenu(); + signal(SIGWINCH, handleResize); + auto [rows, cols] = numRowsCols(); + manager = new platform::ManageScreen(rows, cols, model, score, platform, complete, partial, compare); + manager->doMenu(); + delete manager; return 0; } diff --git a/src/manage/ManageScreen.cpp b/src/manage/ManageScreen.cpp index 2c03b6d..5063efb 100644 --- a/src/manage/ManageScreen.cpp +++ b/src/manage/ManageScreen.cpp @@ -24,21 +24,16 @@ namespace platform { results.load(); openExcel = false; workbook = NULL; - this->rows = std::max(0, rows - 6); // 6 is the number of lines used by the menu & header + this->rows = std::max(6, rows - 6); // 6 is the number of lines used by the menu & header maxModel = results.maxModelSize(); maxTitle = results.maxTitleSize(); header_lengths = { 3, 10, maxModel, 11, 10, 12, 2, 3, 7, maxTitle }; header_labels = { " #", "Date", "Model", "Score Name", "Score", "Platform", "SD", "C/P", "Time", "Title" }; sort_fields = { "Date", "Model", "Score", "Time" }; - int minTitle = 10; - // set 10 chars as minimum for Title - int columns = std::accumulate(header_lengths.begin(), header_lengths.end(), 0) + header_lengths.size() - maxTitle + minTitle; - if (columns > cols) { - throw std::runtime_error("Make screen bigger to fit the results! " + std::to_string(columns - cols) + " columns needed! "); + computeSizes(); + if (min_columns > cols) { + throw std::runtime_error("Make screen bigger to fit the results! " + std::to_string(min_columns - cols) + " columns needed! "); } - maxTitle = minTitle + cols - columns; - header_lengths[header_lengths.size() - 1] = maxTitle; - cols = std::min(cols, columns + maxTitle); // Initializes the paginator for each output type (experiments, datasets, result) for (int i = 0; i < static_cast(OutputType::Count); i++) { paginator.push_back(Paginator(this->rows, results.size())); @@ -49,6 +44,27 @@ namespace platform { subIndex = -1; output_type = OutputType::EXPERIMENTS; } + void ManageScreen::computeSizes() + { + int minTitle = 10; + // set 10 chars as minimum for Title + auto header_title = header_lengths[header_lengths.size() - 1]; + min_columns = std::accumulate(header_lengths.begin(), header_lengths.end(), 0) + header_lengths.size() - header_title + minTitle; + maxTitle = minTitle + cols - min_columns; + header_lengths[header_lengths.size() - 1] = maxTitle; + cols = std::min(cols, min_columns + maxTitle); + for (auto& paginator_ : paginator) { + paginator_.setPageSize(rows); + } + resize = false; + } + void ManageScreen::updateSize(int rows_, int cols_) + { + rows = std::max(6, rows_ - 6); // 6 is the number of lines used by the menu & header + cols = cols_; + resize = true; + computeSizes(); + } void ManageScreen::doMenu() { if (results.empty()) { @@ -212,7 +228,6 @@ namespace platform { std::cout << Colors::RESET(); std::string arrow_dn = Symbols::down_arrow + " "; std::string arrow_up = Symbols::up_arrow + " "; - for (int i = 0; i < header_labels.size(); i++) { std::string suffix = "", color = Colors::GREEN(); int diff = 0; @@ -358,14 +373,19 @@ namespace platform { {"Page+", '+', false}, {"Page-", '-', false} }; - auto main_menu = OptionsMenu(mainOptions, Colors::IGREEN(), Colors::YELLOW(), cols); - auto list_menu = OptionsMenu(listOptions, Colors::IBLUE(), Colors::YELLOW(), cols); + while (!finished) { + auto main_menu = OptionsMenu(mainOptions, Colors::IGREEN(), Colors::YELLOW(), cols); + auto list_menu = OptionsMenu(listOptions, Colors::IBLUE(), Colors::YELLOW(), cols); OptionsMenu& menu = output_type == OutputType::EXPERIMENTS ? main_menu : list_menu; bool parserError = true; // force the first iteration while (parserError) { + if (min_columns > cols) { + throw std::runtime_error("Make screen bigger to fit the results! " + std::to_string(min_columns - cols) + " columns needed! "); + } auto [min_index, max_index] = paginator[static_cast(output_type)].getOffset(); std::tie(option, index, parserError) = menu.parse('r', min_index, max_index); + menu.updateColumns(cols); if (parserError) { list(menu.getErrorMessage(), Colors::RED()); } diff --git a/src/manage/ManageScreen.h b/src/manage/ManageScreen.h index e1e368f..78900e4 100644 --- a/src/manage/ManageScreen.h +++ b/src/manage/ManageScreen.h @@ -18,6 +18,7 @@ namespace platform { ManageScreen(int rows, int cols, const std::string& model, const std::string& score, const std::string& platform, bool complete, bool partial, bool compare); ~ManageScreen() = default; void doMenu(); + void updateSize(int rows, int cols); private: void list(const std::string& status, const std::string& color); void list_experiments(const std::string& status, const std::string& color); @@ -29,12 +30,14 @@ namespace platform { std::string report_compared(); std::pair sortList(); std::string getVersions(); + void computeSizes(); void menu(); void header(); void footer(const std::string& status, const std::string& color); OutputType output_type; int rows; int cols; + int min_columns; int index; int subIndex; int index_A, index_B; // used for comparison of experiments @@ -44,6 +47,7 @@ namespace platform { bool complete; bool partial; bool compare; + bool resize = false; int maxModel, maxTitle; std::vector header_labels; std::vector header_lengths; diff --git a/src/manage/OptionsMenu.cpp b/src/manage/OptionsMenu.cpp index 1f10fd5..b8acd43 100644 --- a/src/manage/OptionsMenu.cpp +++ b/src/manage/OptionsMenu.cpp @@ -8,8 +8,8 @@ namespace platform { std::string OptionsMenu::to_string() { bool first = true; - size_t size = 0; std::string result = color_normal + "Options: ("; + size_t size = 10; // Size of "Options: (" for (auto& option : options) { if (!first) { result += ", "; diff --git a/src/manage/OptionsMenu.h b/src/manage/OptionsMenu.h index c750a25..0ad4c9d 100644 --- a/src/manage/OptionsMenu.h +++ b/src/manage/OptionsMenu.h @@ -13,6 +13,7 @@ namespace platform { char getCommand() const { return command; }; int getIndex() const { return index; }; std::string getErrorMessage() const { return errorMessage; }; + void updateColumns(int cols) { this->cols = cols; } private: std::vector>& options; std::string color_normal, color_bold; diff --git a/src/manage/Paginator.hpp b/src/manage/Paginator.hpp index cd2f2bb..9e3a8c1 100644 --- a/src/manage/Paginator.hpp +++ b/src/manage/Paginator.hpp @@ -54,4 +54,6 @@ private: int page; int numPages; }; +//Options: (quit, list, Delete, datasets, hide, sort, report, excel, title, set A, set B, compare A~B, page, Page+, Page- +//123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456798012345678901234567890(120) #endif \ No newline at end of file