131 lines
4.0 KiB
C++
131 lines
4.0 KiB
C++
// _____ _ _____
|
|
// |_ _|____ _| ||_ _|_ __
|
|
// | |/ _ \ \/ / __|| | \ \ / /
|
|
// | | __/> <| |_ | | \ V /
|
|
// |_|\___/_/\_\\__||_| \_/
|
|
// Author: Love Billenius <lovebillenius@disroot.org>
|
|
// License: GPL-3
|
|
|
|
#include "Tui.hpp"
|
|
|
|
#include <iostream>
|
|
#include <optional>
|
|
#include <ostream>
|
|
#include <utility>
|
|
|
|
#include "Command.hpp"
|
|
#include "Pager.hpp"
|
|
|
|
Tui::Tui(Pager pager) : m_pager(std::move(pager)) {
|
|
}
|
|
|
|
std::optional<int> 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 <number>, s <number> : 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]<typename T0>(T0 &&arg) {
|
|
using T = std::decay_t<T0>;
|
|
|
|
if constexpr (std::is_same_v<T, Command::None>) {
|
|
std::cout << "Invalid command!" << std::endl;
|
|
} else if constexpr (std::is_same_v<T, Command::Next>) {
|
|
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<T, Command::Previous>) {
|
|
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<T, Command::Refresh>) {
|
|
m_pager.clear();
|
|
should_output = true;
|
|
} else if constexpr (std::is_same_v<T, Command::Exit>) {
|
|
should_exit = true;
|
|
} else if constexpr (std::is_same_v<T, Command::Help>) {
|
|
printHelp();
|
|
} else if constexpr (std::is_same_v<T, Command::Seek>) {
|
|
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);
|
|
}
|