// _____ _ _____ // |_ _|____ _| ||_ _|_ __ // | |/ _ \ \/ / __|| | \ \ / / // | | __/> <| |_ | | \ V / // |_|\___/_/\_\\__||_| \_/ // Author: Love Billenius // License: GPL-3 #include "Tui.hpp" #include #include #include #include #include "Command.hpp" #include "Pager.hpp" Tui::Tui(Pager pager) : m_pager(std::move(pager)) { } std::optional get_page_number(const std::string_view line) { const size_t space = line.find_first_of(' '); if (space == std::string::npos) return std::nullopt; int number = 0; const size_t size = line.size(); for (size_t i = space; i < size; i++) { const char c = line[i]; if (!std::isdigit(c)) return std::nullopt; number = number * 10 + (c - '0'); } return number; } void printHelp() { std::cout << "Available Commands:\n" << " r, refresh : Refresh the current view.\n" << " n, >, next : Move to the next item.\n" << " p, <, previous : Move to the previous item.\n" << " x, exit, q, quit : Exit the application.\n" << " seek , s : Seek to the specified number.\n" << " help, h, ? : Display this help message." << std::endl; } void Tui::run() { clear_console(); std::cout << m_pager->str_pretty() << std::endl; for (;;) { std::cout << "Enter a command: "; std::flush(std::cout); Command::Command command; try { command = Command::readCommand(); } catch (const Command::NoNumberException &e) { std::cout << e.what() << std::endl; continue; } bool should_exit = false; bool should_output = false; auto visitor = [this, &should_exit, &should_output](T0 &&arg) { using T = std::decay_t; if constexpr (std::is_same_v) { std::cout << "Invalid command!" << std::endl; } else if constexpr (std::is_same_v) { try { std::cout << "Fetching..." << std::endl; m_pager += 1; } catch (const std::runtime_error &e) { std::cout << e.what() << std::endl; return; } should_output = true; } else if constexpr (std::is_same_v) { try { std::cout << "Fetching..." << std::endl; m_pager -= 1; } catch (const std::runtime_error &e) { std::cout << e.what() << std::endl; return; } should_output = true; } else if constexpr (std::is_same_v) { m_pager.clear(); should_output = true; } else if constexpr (std::is_same_v) { should_exit = true; } else if constexpr (std::is_same_v) { printHelp(); } else if constexpr (std::is_same_v) { const Command::Seek &seek = arg; const int number = seek.number; try { std::cout << "Fetching..." << std::endl; m_pager.seek(number); } catch (const std::runtime_error &e) { std::cout << e.what() << std::endl; return; } should_output = true; } }; std::visit(visitor, command); if (should_exit) return; clear_console(); if (should_output) std::cout << m_pager->str_pretty() << std::endl; } } void Tui::clear_console() { const auto CMD = #ifdef _WIN32 || _WIN64 "cls"; #else "clear"; #endif system(CMD); }