commit 7a3fa50503abea8b947d4cb1ea0fe1af8249134f Author: somebody_master Date: Tue Oct 20 14:16:46 2020 +0200 Init commit diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..1a15379 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,42 @@ +cmake_minimum_required(VERSION "3.18.4") + +set(CMAKE_BUILD_TYPE Debug) +set(CMAKE_CXX_STANDARD 17) +#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}") + +project("Basic" + LANGUAGES CXX + VERSION 0.1 + ) + +add_library( + ui + STATIC + include/ui.hpp + src/ui.cpp + ) + +add_library( + configFile + STATIC + include/configFile.hpp + src/configFile.cpp + ) + +add_library( + config + STATIC + include/config.hpp + src/config.cpp + ) + +add_executable("${PROJECT_NAME}" src/main.cpp) + +target_include_directories(ui PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include") +target_include_directories(configFile PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include") +target_include_directories(config PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include") + +target_link_libraries("${PROJECT_NAME}" PRIVATE ui) +target_link_libraries("${PROJECT_NAME}" PRIVATE configFile) +target_link_libraries("${PROJECT_NAME}" PRIVATE ncurses) +target_link_libraries("${PROJECT_NAME}" PRIVATE config) diff --git a/include/config.hpp b/include/config.hpp new file mode 100644 index 0000000..98e8cb1 --- /dev/null +++ b/include/config.hpp @@ -0,0 +1,17 @@ +#include +#ifndef __CONFIG_HPP_ +#define __CONFIG_HPP_ +class Config { +private: + int8_t *numHilos; + std::string *tiempo; + +public: + Config(int8_t nh, std::string t); + ~Config(); + int8_t getNumHilos(); + std::string getTiempo(); + void setNumHilos(int8_t nh); + void setTiempo(std::string t); +}; +#endif // __CONFIG_HPP_ diff --git a/include/configFile.hpp b/include/configFile.hpp new file mode 100644 index 0000000..181ae27 --- /dev/null +++ b/include/configFile.hpp @@ -0,0 +1,14 @@ +#include "config.hpp" +#include +#include +#ifndef __CONFIG_FILE_HPP_ +#define __CONFIG_FILE_HPP_ +namespace cf { +const std::string g_cofigFile = "~/.config/stressUI.cfg"; +Config *openConfig(); +void closeConfig(Config *config); +std::string getLine(std::ifstream *file); +void saveConfig(); +void createConfig(); +} // namespace cf +#endif // __CONFIG_FILE_HPP_ diff --git a/include/ui.hpp b/include/ui.hpp new file mode 100644 index 0000000..87be778 --- /dev/null +++ b/include/ui.hpp @@ -0,0 +1,32 @@ +#include +#include +#include +#ifndef __UI_HPP_ +#define __UI_HPP_ + +namespace ui { + +extern int g_maxLines, g_maxCols, g_begCol, g_begLine, g_menuWith; +extern bool g_mensaje; + +int8_t initUI(const int8_t *menu_principal, const int8_t *menu_error); +void closeUI(); +// void userInterface(int8_t *menu); +// void userInterface(int8_t *menu, std::vector *mensaje); +/*void userInterface(std::string *num_menu); + int8_t inputToInt(std::string *input);*/ +// void showMenu(std::vector *menu_elems, int8_t *num_menu); +// void showMenu(std::vector *menu_elems, int8_t *num_menu, +// std::vector *mensaje); + +void showCentralInputBox(std::vector *textos, + const int8_t *num_box, + std::vector *elems); +void showCentralInputBox(std::vector *textos, + const int8_t *num_box, std::vector *elems, + long title_size); +void showCenterMensaje(std::vector *mensaje, + const int8_t *menu_color); +void showTopTitle(const std::vector *titulo); +} // namespace ui +#endif // __UI_HPP_ diff --git a/src/config.cpp b/src/config.cpp new file mode 100644 index 0000000..f326b50 --- /dev/null +++ b/src/config.cpp @@ -0,0 +1,19 @@ +#include "config.hpp" + +Config::Config(int8_t nh, std::string t) { + Config::numHilos = &nh; + Config::tiempo = &t; +} + +Config::~Config() { + delete Config::numHilos; + delete Config::tiempo; +} + +int8_t Config::getNumHilos() { return *Config::numHilos; } + +void Config::setNumHilos(int8_t nh) { Config::numHilos = &nh; } + +std::string Config::getTiempo() { return *Config::tiempo; } + +void Config::setTiempo(std::string t) { Config::tiempo = &t; } diff --git a/src/configFile.cpp b/src/configFile.cpp new file mode 100644 index 0000000..140b4ce --- /dev/null +++ b/src/configFile.cpp @@ -0,0 +1,39 @@ +#include "configFile.hpp" +#include + +Config *cf::openConfig() { + std::ifstream file(g_cofigFile); + if (file.is_open()) { + std::string line; + line = cf::getLine(&file); + int8_t nh = std::stoi(line); + std::string t = cf::getLine(&file); + Config config = Config(nh, t); + file.close(); + Config *ptr = &config; + return ptr; + } else { + // file.close(); + // cf::createConfig(); + // return cf::openConfig(); + return nullptr; + } +} + +void cf::closeConfig(Config *config) { delete config; } + +std::string cf::getLine(std::ifstream *file) { + std::string line; + std::getline(*file, line); + + if (line[0] == '#' || line == "") { + return cf::getLine(file); + } + + line = line.substr(line.find("= ") + 1, line.length()); + return line; +} + +void cf::createConfig() {} + +void cf::saveConfig() {} diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..429ddb9 --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,252 @@ +#include "configFile.hpp" +#include "ui.hpp" +#include + +using namespace std; + +const int8_t MENU_PRINCIPAL = 0; +const int8_t MENU_INICIAR_STRESS = 1; +const int8_t MENU_CONFIGURACION = 2; +const int8_t SALIR = 3; + +const int8_t CONFIGURAR_TODO = 4; +const int8_t CONFIGURAR_HILOS = 5; +const int8_t CONFIGURAR_TIEMPO = 6; +const int8_t CONFIGURAR_MENU_PRINCIPAL = 7; + +const int8_t MENU_ERROR = 8; +const int8_t MENU_TITULO = 9; + +const int8_t PRIMER_INICIO = 10; + +const vector TITULO_PRINCIPAL = { + "____ ___ __ __ _____ ____ ___ ______ __ ____ _____ ______ " + " _______ ____ ", + "/ ___| / _ \\| \\/ | ____| __ ) / _ \\| _ \\ \\ / / / ___|| ____| " + "_ \\ \\ / / ____| _ \\ ", + "\\___ \\| | | | |\\/| | _| | _ \\| | | | | | \\ V / \\___ \\| _| " + "| |_) \\ \\ / /| _| | |_) |", + " ___) | |_| | | | | |___| |_) | |_| | |_| || | ___) | |___| _ < " + "\\ V / | |___| _ < ", + "|____/ \\___/|_| |_|_____|____/ \\___/|____/ |_| |____/|_____|_| " + "\\_\\ \\_/ |_____|_| \\_\\", + "", + "_______________________________________________________________________", +}; + +void userInterface(const int8_t *menu); +void userInterface(const int8_t *menu, vector *mensaje); +void showMenu(vector *menu_elems, const int8_t *num_menu, + vector *mensaje); +void showMenu(vector *menu_elems, const int8_t *num_menu); + +int main(int argc, char *argv[]) { + if (ui::initUI(&MENU_PRINCIPAL, &MENU_ERROR) != 0) { + return -1; + } + // menu = 12; + + Config *config = cf::openConfig(); + + if (config == nullptr) { + userInterface(&PRIMER_INICIO); + } else { + + userInterface(&MENU_PRINCIPAL); + } + ui::closeUI(); + return 0; +} + +void userInterface(const int8_t *menu) { + /*int8_t menu_num = inputToInt(menu);*/ + vector dummy = {""}; + userInterface(menu, &dummy); +} + +void userInterface(const int8_t *num_menu, vector *mensaje) { + switch (*num_menu) { + + case CONFIGURAR_MENU_PRINCIPAL: + case MENU_PRINCIPAL: { + vector elem_menu = {"- Iniciar Stress Test", "- Configurar", + "- Salir"}; + showMenu(&elem_menu, &MENU_PRINCIPAL, mensaje); + break; + } + + case MENU_INICIAR_STRESS: { + /*TODO*/ + break; + } + + case MENU_CONFIGURACION: { + vector elem_menu = {"- Configurar todo", "- Número de hilos", + "- Tiempo", "- Menú principal"}; + + showMenu(&elem_menu, num_menu, mensaje); + break; + } + + case CONFIGURAR_TODO: + case PRIMER_INICIO: { + + vector textos_init = { + "Toda la configuración se escribirá en " + cf::g_cofigFile, "", ""}; + vector elemens = {"- Número de hilos\t> ", "- Tiempo\t\t> "}; + + ui::showCentralInputBox(&textos_init, &CONFIGURAR_TODO, &elemens, + TITULO_PRINCIPAL.size()); + + userInterface(&MENU_CONFIGURACION, mensaje); + break; + } + + case CONFIGURAR_HILOS: { + break; + } + + case CONFIGURAR_TIEMPO: { + break; + } + + case MENU_TITULO: { + break; + } + + case SALIR: { + break; + } + + default: { + ui::g_mensaje = true; + *mensaje = {"¿Como has llegado aquí?", + "Por si acaso vamos al menú principal"}; + + userInterface(&MENU_PRINCIPAL, mensaje); + break; + } + } +} + +void showMenu(vector *menu_elems, const int8_t *num_menu, + vector *mensaje) { + clear(); + if (ui::g_mensaje) { + ui::showCenterMensaje(mensaje, &MENU_ERROR); + } + + showMenu(menu_elems, num_menu); +} + +void showMenu(vector *menu_elems, const int8_t *num_menu) { + size_t height = menu_elems->size(); + + attron(COLOR_PAIR(MENU_PRINCIPAL)); + WINDOW *menuwin = + // newwin(height + 2, g_maxCols - 4, g_maxLines - height - 3, 2); + newwin(height + 2, ui::g_menuWith, TITULO_PRINCIPAL.size() + 4, 2); + + box(menuwin, 0, 0); + refresh(); + + ui::showTopTitle(&TITULO_PRINCIPAL); + wrefresh(menuwin); + + keypad(menuwin, true); + + int choice = 0; + int8_t highlight = 0; + switch (*num_menu) { + + case MENU_PRINCIPAL: { + mvwprintw(menuwin, 0, 1, "Menú Principal"); + break; + } + + case MENU_CONFIGURACION: { + mvwprintw(menuwin, 0, 1, "Configuración"); + break; + } + } + while (true) { + + for (int i = 0; i < height; i++) { + if (i == highlight) { + wattron(menuwin, A_REVERSE); + } + + if (menu_elems->at(i).length() < (ui::g_menuWith - 4)) { + string spaces = ""; + for (int j = menu_elems->at(i).length(); j < (ui::g_menuWith - 4); + j++) { + spaces.append(" "); + } + + // Por algún motivo los acentos y tildes cuentan como un caracter + // aparte por lo que hay que añadir un espacio extra. + if (menu_elems->at(i).find("á") != std::string::npos | + menu_elems->at(i).find("é") != std::string::npos | + menu_elems->at(i).find("í") != std::string::npos | + menu_elems->at(i).find("ó") != std::string::npos | + menu_elems->at(i).find("ú") != std::string::npos | + menu_elems->at(i).find("Á") != std::string::npos | + menu_elems->at(i).find("É") != std::string::npos | + menu_elems->at(i).find("Í") != std::string::npos | + menu_elems->at(i).find("Ó") != std::string::npos | + menu_elems->at(i).find("Ú") != std::string::npos | + menu_elems->at(i).find("ñ") != std::string::npos | + menu_elems->at(i).find("Ñ") != std::string::npos) { + spaces.append(" "); + } + menu_elems->at(i).append(spaces); + } + + mvwprintw(menuwin, i + 1, 2, menu_elems->at(i).c_str()); + + wattroff(menuwin, A_REVERSE); + } + + choice = wgetch(menuwin); + + switch (choice) { + + case KEY_UP: { + if (highlight > 0) { + highlight--; + } + break; + } + + case KEY_DOWN: { + if ((highlight + 1) < height) { + highlight++; + } + break; + } + + default: { + break; + } + } + + if (choice == 10) { + break; + } + } + + switch (*num_menu) { + case MENU_PRINCIPAL: { + highlight++; + break; + } + + case MENU_CONFIGURACION: { + highlight = highlight + 4; + break; + } + } + + attroff(COLOR_PAIR(MENU_PRINCIPAL)); + userInterface(&highlight); +} diff --git a/src/ui.cpp b/src/ui.cpp new file mode 100644 index 0000000..f49d47b --- /dev/null +++ b/src/ui.cpp @@ -0,0 +1,109 @@ +#include "ui.hpp" +#include "configFile.hpp" +#include + +using namespace std; + +int ui::g_maxLines = 0; +int ui::g_maxCols = 0; +int ui::g_begLine = 0; +int ui::g_begCol = 0; +int ui::g_menuWith = 30; +bool ui::g_mensaje = false; + +int8_t ui::initUI(const int8_t *menu_principal, const int8_t *menu_error) { + /*TODO hacer que la interfaz lea la localización*/ + locale::global(locale("es_ES.utf8")); + initscr(); + noecho(); + cbreak(); + if (!has_colors()) { + printw("El terminal no soporta colores"); + getch(); + return -1; + } + start_color(); + init_pair(*menu_principal, COLOR_WHITE, COLOR_BLACK); + init_pair(*menu_error, COLOR_RED, COLOR_BLACK); + curs_set(0); + getbegyx(stdscr, ui::g_begLine, ui::g_begCol); + getmaxyx(stdscr, ui::g_maxLines, ui::g_maxCols); + return 0; +} + +void ui::closeUI() { + echo(); + nocbreak(); + curs_set(1); + endwin(); +} + +void ui::showCenterMensaje(vector *mensaje, const int8_t *menu_color) { + int startLine = (g_maxLines - mensaje->size()) / 2; + + attron(COLOR_PAIR(*menu_color)); + for (int i = 0; i < mensaje->size(); i++) { + move(startLine + i, (g_maxCols - mensaje->at(i).length()) / 2); + printw(mensaje->at(i).c_str()); + refresh(); + } + + attroff(COLOR_PAIR(*menu_color)); + g_mensaje = false; +} + +void ui::showCentralInputBox(std::vector *textos, + const int8_t *num_box, + std::vector *elems) { + ui::showCentralInputBox(textos, num_box, elems, 0); +} + +void ui::showCentralInputBox(vector *textos, const int8_t *num_box, + vector *elems, long title_size) { + int start_ver_window = 1; + if (title_size != 0) { + start_ver_window = title_size + 4; + } + + int height = ui::g_maxLines - (title_size + 4) - 1; + WINDOW *centralBOX = newwin(height, ui::g_maxCols - ui::g_menuWith - 4, + start_ver_window, ui::g_menuWith + 2); + box(centralBOX, 0, 0); + + for (int i = 0; i < textos->size(); i++) { + mvwprintw(centralBOX, i + 1, 1, textos->at(i).c_str()); + } + + wrefresh(centralBOX); + echo(); + nocbreak(); + curs_set(1); + for (int i = 0; i < elems->size(); i++) { + mvwprintw(centralBOX, i + 1 + textos->size(), 1, elems->at(i).c_str()); + wrefresh(centralBOX); + char input[10]; + wgetnstr(centralBOX, input, 10); + } + curs_set(0); + noecho(); + cbreak(); + + // std::chrono::milliseconds timespan(10000); // or whatever + + // std::this_thread::sleep_for(timespan); +} + +void ui::showTopTitle(const vector *titulo) { + size_t height = titulo->size(); + WINDOW *topTitleWin = newwin(height + 3, g_maxCols - 4, 1, 2); + attron(A_BOLD); + box(topTitleWin, 0, 0); + // wrefresh(topTitleWin); + for (int i = 0; i < height; i++) { + mvwprintw(topTitleWin, i + 1, (g_maxCols - 4 - titulo->at(i).length()) / 2, + titulo->at(i).c_str()); + // wattroff(topTitleWin, A_REVERSE); + } + attroff(A_BOLD); + wrefresh(topTitleWin); +}