From fedecd82a60062e1ba5115bc5c1e51990da0f224 Mon Sep 17 00:00:00 2001 From: JFpro160 Date: Sat, 13 Jul 2024 19:31:38 -0500 Subject: [PATCH 01/15] Interfaz 1.1 --- src/app/Movie/Movie.cpp | 20 --- src/app/Movie/Movie.h | 19 --- src/app/Movie/Review.cpp | 5 - src/app/Movie/Review.h | 29 ---- src/app/Movie/SearchEngine/SearchEngine.cpp | 5 - src/app/Movie/SearchEngine/SearchEngine.h | 13 -- src/app/SearchEngine/SearchEngine.cpp | 5 - src/app/SearchEngine/SearchEngine.h | 13 -- src/app/SearchEngine/SearchEngineBuilder.cpp | 30 ---- src/app/SearchEngine/SearchEngineBuilder.h | 16 --- src/app/TriePrefix/TrieNode.cpp | 86 ------------ src/app/TriePrefix/TrieNode.h | 28 ---- src/beta_modules/BST_beta.cpp | 102 -------------- src/main.cpp | 19 +-- src/tools/BTS.cpp | 138 ------------------- 15 files changed, 4 insertions(+), 524 deletions(-) delete mode 100644 src/app/Movie/Movie.cpp delete mode 100644 src/app/Movie/Movie.h delete mode 100644 src/app/Movie/Review.cpp delete mode 100644 src/app/Movie/Review.h delete mode 100644 src/app/Movie/SearchEngine/SearchEngine.cpp delete mode 100644 src/app/Movie/SearchEngine/SearchEngine.h delete mode 100644 src/app/SearchEngine/SearchEngine.cpp delete mode 100644 src/app/SearchEngine/SearchEngine.h delete mode 100644 src/app/SearchEngine/SearchEngineBuilder.cpp delete mode 100644 src/app/SearchEngine/SearchEngineBuilder.h delete mode 100644 src/app/TriePrefix/TrieNode.cpp delete mode 100644 src/app/TriePrefix/TrieNode.h delete mode 100644 src/beta_modules/BST_beta.cpp delete mode 100644 src/tools/BTS.cpp diff --git a/src/app/Movie/Movie.cpp b/src/app/Movie/Movie.cpp deleted file mode 100644 index bd998c5..0000000 --- a/src/app/Movie/Movie.cpp +++ /dev/null @@ -1,20 +0,0 @@ - -#include "Movie.h" - - -const std::string &Movie::getSynopsis() const { - return synopsis; -} - -const std::unordered_set &Movie::getTags() const { - return tags; -} - -const std::string &Movie::getTitle() const { - return title; -} - -Movie::Movie(const std::string &title, const std::string &synopsis, const std::string &tags){ - this->title = title; - this->title = synopsis; -} diff --git a/src/app/Movie/Movie.h b/src/app/Movie/Movie.h deleted file mode 100644 index f759948..0000000 --- a/src/app/Movie/Movie.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef PROGRA3_MOVIE_H -#define PROGRA3_MOVIE_H -#include -#include - -class Movie { - std::string title; - std::string synopsis; - std::unordered_set tags; -public: - const std::string &getTitle() const; - const std::string &getSynopsis() const; - const std::unordered_set &getTags() const; - Movie(const std::string &title, const std::string &synopsis, const std::string &tags); - -}; - - -#endif //PROGRA3_MOVIE_H diff --git a/src/app/Movie/Review.cpp b/src/app/Movie/Review.cpp deleted file mode 100644 index 99945bc..0000000 --- a/src/app/Movie/Review.cpp +++ /dev/null @@ -1,5 +0,0 @@ -// -// Created by Badi on 7/13/2024. -// - -#include "Review.h" diff --git a/src/app/Movie/Review.h b/src/app/Movie/Review.h deleted file mode 100644 index a5eeff5..0000000 --- a/src/app/Movie/Review.h +++ /dev/null @@ -1,29 +0,0 @@ -// -// Created by Badi on 7/13/2024. -// - -#ifndef PROGRA3FINALPROJECT_REVIEW_H -#define PROGRA3FINALPROJECT_REVIEW_H - -#include -#include - -class Review { - -private: - std::string username; - std::vector comment; - float score; - int review_id; -public: - Review() = default; - Review(std::string, std::vector, float); - void getInfoBlock(); - std::string getUsername() {return username;}; - std::vector getComment() {return comment;}; - float getScore() {return score;}; - int getReviewId() {return review_id;}; -}; - - -#endif //PROGRA3FINALPROJECT_REVIEW_H diff --git a/src/app/Movie/SearchEngine/SearchEngine.cpp b/src/app/Movie/SearchEngine/SearchEngine.cpp deleted file mode 100644 index 672c169..0000000 --- a/src/app/Movie/SearchEngine/SearchEngine.cpp +++ /dev/null @@ -1,5 +0,0 @@ -// -// Created by flauta on 13/07/2024. -// - -#include "SearchEngine.h" diff --git a/src/app/Movie/SearchEngine/SearchEngine.h b/src/app/Movie/SearchEngine/SearchEngine.h deleted file mode 100644 index f91f313..0000000 --- a/src/app/Movie/SearchEngine/SearchEngine.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef PROGRA3_SEARCHENGINE_H -#define PROGRA3_SEARCHENGINE_H -#include -#include - -//Builder aplicar aca -class SearchEngine { - std::string query; - std::unordered_set tags; -}; - - -#endif //PROGRA3_SEARCHENGINE_H diff --git a/src/app/SearchEngine/SearchEngine.cpp b/src/app/SearchEngine/SearchEngine.cpp deleted file mode 100644 index 672c169..0000000 --- a/src/app/SearchEngine/SearchEngine.cpp +++ /dev/null @@ -1,5 +0,0 @@ -// -// Created by flauta on 13/07/2024. -// - -#include "SearchEngine.h" diff --git a/src/app/SearchEngine/SearchEngine.h b/src/app/SearchEngine/SearchEngine.h deleted file mode 100644 index f91f313..0000000 --- a/src/app/SearchEngine/SearchEngine.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef PROGRA3_SEARCHENGINE_H -#define PROGRA3_SEARCHENGINE_H -#include -#include - -//Builder aplicar aca -class SearchEngine { - std::string query; - std::unordered_set tags; -}; - - -#endif //PROGRA3_SEARCHENGINE_H diff --git a/src/app/SearchEngine/SearchEngineBuilder.cpp b/src/app/SearchEngine/SearchEngineBuilder.cpp deleted file mode 100644 index 66f3d8a..0000000 --- a/src/app/SearchEngine/SearchEngineBuilder.cpp +++ /dev/null @@ -1,30 +0,0 @@ - -#include "SearchEngineBuilder.h" -#include -#include - - - -SearchEngineBuilder &SearchEngineBuilder::Query(const std::string &query) { - searchEngine_->query = query; - return *this; -} - -SearchEngineBuilder &SearchEngineBuilder::Tags(const std::string &tags) { - std::stringstream ss(tags); - std::string t; - char delimiter = ','; - while (getline(ss, t, delimiter)) { - searchEngine_->tags.insert(t); - } - return *this; -} - -SearchEngine *SearchEngineBuilder::build() { - if(searchEngine_->query.empty() and searchEngine_->tags.empty()){ - throw std::runtime_error("Query is empty"); - } - return searchEngine_; -} - - diff --git a/src/app/SearchEngine/SearchEngineBuilder.h b/src/app/SearchEngine/SearchEngineBuilder.h deleted file mode 100644 index 4494945..0000000 --- a/src/app/SearchEngine/SearchEngineBuilder.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef PROGRA3_SEARCHENGINEBUILDER_H -#define PROGRA3_SEARCHENGINEBUILDER_H -#include "SearchEngine.h" - -class SearchEngineBuilder { -private: - SearchEngine* searchEngine_ = new SearchEngine(); -public: - SearchEngineBuilder& Query(const std::string& query); - SearchEngineBuilder& Tags(const std::string& tags); - SearchEngine* build(); - -}; - - -#endif //PROGRA3_SEARCHENGINEBUILDER_H diff --git a/src/app/TriePrefix/TrieNode.cpp b/src/app/TriePrefix/TrieNode.cpp deleted file mode 100644 index c860f0a..0000000 --- a/src/app/TriePrefix/TrieNode.cpp +++ /dev/null @@ -1,86 +0,0 @@ -// -// Created by jorughen on 7/13/24. -// - -#include "TrieNode.h" - -TrieNode::TrieNode() { - // constructor - // initialize the wordEnd variable with false - // initialize every index of childNode array with - // NULL - wordEnd = false; - - for (int i = 0; i < 26; i++) { - childNode[i] = nullptr; - } -} - -void insert_key(TrieNode* root, string& key) -{ - // Initialize the currentNode pointer - // with the root node - TrieNode* currentNode = root; - - // Iterate across the length of the string - for (int i = 0; i < key.length(); i++){ - char c = key[i]; - // Check if the node exist for the current - // character in the Trie. - if (isdigit(c)){ - c -= '0'+27; - } - else{ - c -= 'a'; - } - - if (currentNode->childNode[c] == nullptr) { - - // If node for current character does not exist - // then make a new node - TrieNode* newNode = new TrieNode(); - - // Keep the reference for the newly created - // node. - currentNode->childNode[c] = newNode; - } - - // Now, move the current node pointer to the newly - // created node. - currentNode = currentNode->childNode[c]; - } - - // Increment the wordEndCount for the last currentNode - // pointer this implies that there is a string ending at - // currentNode. - currentNode->wordEnd = true; - - - -} - -bool search_key(TrieNode* root, string& key) -{ - // Initialize the currentNode pointer - // with the root node - TrieNode* currentNode = root; - - // Iterate across the length of the string - for (auto c : key) { - - // Check if the node exist for the current - // character in the Trie. - if (currentNode->childNode[c - 'a'] == nullptr) { - - // Given word does not exist in Trie - return false; - } - - // Move the currentNode pointer to the already - // existing node for current character. - currentNode = currentNode->childNode[c - 'a']; - } - - return currentNode->wordEnd; -} - diff --git a/src/app/TriePrefix/TrieNode.h b/src/app/TriePrefix/TrieNode.h deleted file mode 100644 index 03af957..0000000 --- a/src/app/TriePrefix/TrieNode.h +++ /dev/null @@ -1,28 +0,0 @@ -// -// Created by jorughen on 7/13/24. -// - -#ifndef PROGRA3_TRIENODE_H -#define PROGRA3_TRIENODE_H - -#include -using namespace std; - -struct TrieNode { - - // pointer array for child nodes of each node - TrieNode* childNode[36]; - - // Used for indicating ending of string - bool wordEnd; - - TrieNode(); - -}; - - - -void insert_key(TrieNode* root, string& key); -bool search_key(TrieNode* root, string& key); - -#endif //PROGRA3_TRIENODE_H diff --git a/src/beta_modules/BST_beta.cpp b/src/beta_modules/BST_beta.cpp deleted file mode 100644 index ad170c6..0000000 --- a/src/beta_modules/BST_beta.cpp +++ /dev/null @@ -1,102 +0,0 @@ -// -// Created by Badi on 7/13/2024. -// - -#include -#include -#include -#include -#include -#include - -// Define a structure for the BST node -struct BSTNode { - std::string key; // Change this to the appropriate data type for your key - std::vector data; // Store the rest of the CSV data in a vector - BSTNode* left; - BSTNode* right; - - BSTNode(std::string k, const std::vector& d) : key(std::move(k)), data(d), left(nullptr), right(nullptr) {} -}; - -// Function to insert a new node into the BST -BSTNode* insert(BSTNode* root, const std::string& key, const std::vector& data) { - if (root == nullptr) { - return new BSTNode(key, data); - } - if (key < root->key) { - root->left = insert(root->left, key, data); - } else { - root->right = insert(root->right, key, data); - } - return root; -} - -// Function to search for a key in the BST -BSTNode* search(BSTNode* root, const std::string& key) { - if (root == nullptr || root->key == key) { - return root; - } - if (key < root->key) { - return search(root->left, key); - } - return search(root->right, key); -} - -// Function to read the CSV file and populate the BST -BSTNode* readCSVAndPopulateBST(const std::string& filename) { - std::ifstream file(filename); - std::string line; - BSTNode* root = nullptr; - - if (file.is_open()) { - // Read the header line - std::getline(file, line); - - // Read the rest of the lines - while (std::getline(file, line)) { - std::stringstream ss(line); - std::string item; - std::vector data; - - while (std::getline(ss, item, ',')) { - data.push_back(item); - } - - // Assuming the key is the first column in the CSV - std::string key = data[0]; - root = insert(root, key, data); - } - file.close(); - } else { - std::cerr << "Unable to open file"; - } - - return root; -} - -int main() { - // Path to the CSV file - std::string filename = "mpst_full_data.csv"; - - // Populate the BST - BSTNode* root = readCSVAndPopulateBST(filename); - - // Search for a specific key (example) - std::string searchKey = "example_key"; // Replace with an actual key from your CSV - BSTNode* result = search(root, searchKey); - - if (result != nullptr) { - std::cout << "Found key: " << result->key << std::endl; - // Print the associated data - for (const auto& item : result->data) { - std::cout << item << " "; - } - std::cout << std::endl; - } else { - std::cout << "Key not found" << std::endl; - } - - return 0; -} - diff --git a/src/main.cpp b/src/main.cpp index db5f254..a9baa04 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,17 +1,6 @@ -#include -#include "app/Movie/Movie.h" -#include "app/TriePrefix/TrieNode.h" - -using namespace std; - -int main(){ - Movie a = Movie("title", "synopsis", {"Horror", "Action"}); - Movie b = Movie("title", "synopsis", {"Horror", "Suspense"}); - - TrieNode* root = new TrieNode(); - - - - +#include "interface/Menu/Menu.h" +int main() { + Menu::getInstance().run(); + return 0; } diff --git a/src/tools/BTS.cpp b/src/tools/BTS.cpp deleted file mode 100644 index 967942c..0000000 --- a/src/tools/BTS.cpp +++ /dev/null @@ -1,138 +0,0 @@ -// -// Created by Badi on 7/13/2024. -// - -#include - -using namespace std; - -struct Nodo { - int dato; - Nodo* left; - Nodo* right; - - // Constructor - Nodo(int dato) { - this->dato = dato; - left = nullptr; - right = nullptr; - } -}; - -class BST { -private: - Nodo* raiz=nullptr; - Nodo* insertarNodoAux(Nodo* nodo, int dato); - Nodo* buscarNodoAux(Nodo* nodo, int dato); - int heightAux(Nodo* nodo); - Nodo* minimoAux(Nodo* nodo_raiz); - bool esArbolAVLAux(Nodo* nodo); -public: - void insertarNodo(int dato); - Nodo* buscarNodo(int dato); - int height(); - int minimo(); - int maximo(); - Nodo* Sucesor(int dato); - bool esArbolAVL(); -}; - -void BST::insertarNodo(int dato) { - raiz = insertarNodoAux(raiz, dato); -} - -// Función auxiliar para insertar un nodo en el árbol -Nodo* BST::insertarNodoAux(Nodo* nodo, int dato) { - if (nodo == nullptr) - return new Nodo(dato); - - if (dato < nodo->dato) - nodo->left = insertarNodoAux(nodo->left, dato); - else - nodo->right = insertarNodoAux(nodo->right, dato); - return nodo; -} - -Nodo* BST::buscarNodo(int dato) { - return buscarNodoAux(raiz, dato); -} - -// Función auxiliar para buscar un nodo en el árbol -Nodo* BST::buscarNodoAux(Nodo* nodo, int dato) { - if (nodo == nullptr || nodo->dato == dato) - return nodo; - - if (dato < nodo->dato) - return buscarNodoAux(nodo->left, dato); - else - return buscarNodoAux(nodo->right, dato); -} - -int BST::height() { - return heightAux(raiz); -} - -int BST::heightAux(Nodo* nodo) { - if (nodo == nullptr) { - return -1; - } - return 1 + max(heightAux(nodo->left), heightAux(nodo->right)); -} - -Nodo* BST::minimoAux(Nodo* nodo_raiz){ - Nodo* nodo = nodo_raiz; - while(nodo->left != nullptr){ - nodo = nodo->left; - } - return nodo; -} - -int BST::minimo(){ - Nodo* nodo = raiz; - while(nodo->left != nullptr){ - nodo = nodo->left; - } - return nodo->dato; -} - -int BST::maximo(){ - Nodo* nodo = raiz; - while(nodo->right != nullptr){ - nodo = nodo->right; - } - return nodo->dato; -} -Nodo* BST::Sucesor(int dato){ - Nodo* nodo = buscarNodo(dato); - if(nodo == nullptr) // El dato no se encuentra en el arbol - return nullptr; - if(nodo->right != nullptr) - return minimoAux(nodo->right); - - Nodo* sucesor = nullptr; - Nodo* ancestro = raiz; - - while (ancestro != nodo){ - if(dato < ancestro->dato){ - sucesor = ancestro; - ancestro = ancestro->left; - } - else - ancestro = ancestro->right; - } - return sucesor; -} - -bool BST::esArbolAVL(){ - return esArbolAVLAux(raiz); -} -bool BST::esArbolAVLAux(Nodo* nodo){ - if (nodo == nullptr) - return true; - - int h1 = heightAux(nodo->left); - int h2 = heightAux(nodo->right); - if (abs(h1 - h2) > 1) - return false; - return esArbolAVLAux(nodo->left) and esArbolAVLAux(nodo->right); -} \ No newline at end of file From 2ad88bedb81c781c44439a9f356f7da5988ebfd7 Mon Sep 17 00:00:00 2001 From: JFpro160 Date: Sat, 13 Jul 2024 19:33:40 -0500 Subject: [PATCH 02/15] Interfaz 1.2 --- src/interface/Command/Command.cpp | 20 ++++++++++++++ src/interface/Command/Command.h | 25 ++++++++++++++++++ src/interface/Menu/Menu.cpp | 44 +++++++++++++++++++++++++++++++ src/interface/Menu/Menu.h | 43 ++++++++++++++++++++++++++++++ 4 files changed, 132 insertions(+) create mode 100644 src/interface/Command/Command.cpp create mode 100644 src/interface/Command/Command.h create mode 100644 src/interface/Menu/Menu.cpp create mode 100644 src/interface/Menu/Menu.h diff --git a/src/interface/Command/Command.cpp b/src/interface/Command/Command.cpp new file mode 100644 index 0000000..f283b2a --- /dev/null +++ b/src/interface/Command/Command.cpp @@ -0,0 +1,20 @@ +// +// Created by jfpro on 13/07/24. +// + +#include "Command.h" +#include + +void Option1Command::execute() { + clear(); + mvprintw(0, 0, "Opcion 1 seleccionada"); + refresh(); + getch(); +} + +void Option2Command::execute() { + clear(); + mvprintw(0, 0, "Opcion 2 seleccionada"); + refresh(); + getch(); +} diff --git a/src/interface/Command/Command.h b/src/interface/Command/Command.h new file mode 100644 index 0000000..f74197b --- /dev/null +++ b/src/interface/Command/Command.h @@ -0,0 +1,25 @@ +// +// Created by jfpro on 13/07/24. +// + +#ifndef COMMAND_H +#define COMMAND_H + +class Command { +public: + virtual void execute() = 0; + virtual ~Command() = default; +}; + +class Option1Command : public Command { +public: + void execute() override; +}; + +class Option2Command : public Command { +public: + void execute() override; +}; + +#endif // COMMAND_H + diff --git a/src/interface/Menu/Menu.cpp b/src/interface/Menu/Menu.cpp new file mode 100644 index 0000000..628adc7 --- /dev/null +++ b/src/interface/Menu/Menu.cpp @@ -0,0 +1,44 @@ +// +// Created by jfpro on 13/07/24. +// + +#include "Menu.h" + +void Menu::run() { + commands.push_back(std::make_unique()); + commands.push_back(std::make_unique()); + + int choice; + while (true) { + drawMenu(); + choice = getch(); + processInput(choice); + } +} + +void Menu::drawMenu() { + clear(); + mvprintw(0, 0, "Menu Principal:"); + mvprintw(1, 0, "1. Opcion 1"); + mvprintw(2, 0, "2. Opcion 2"); + mvprintw(3, 0, "3. Salir"); + refresh(); +} + +void Menu::processInput(int ch) { + switch (ch) { + case '1': + commands[0]->execute(); + break; + case '2': + commands[1]->execute(); + break; + case '3': + exit(0); + default: + mvprintw(4, 0, "Opcion no valida"); + refresh(); + getch(); + break; + } +} diff --git a/src/interface/Menu/Menu.h b/src/interface/Menu/Menu.h new file mode 100644 index 0000000..533a5dd --- /dev/null +++ b/src/interface/Menu/Menu.h @@ -0,0 +1,43 @@ +// +// Created by jfpro on 13/07/24. +// + +#ifndef MENU_H +#define MENU_H + +#include +#include +#include +#include "../Command/Command.h" + +class Menu { +public: + static Menu& getInstance() { + static Menu instance; + return instance; + } + + void run(); + +private: + Menu() { + initscr(); + noecho(); + cbreak(); + keypad(stdscr, TRUE); + } + + ~Menu() { + endwin(); + } + + Menu(const Menu&) = delete; + Menu& operator=(const Menu&) = delete; + + void drawMenu(); + void processInput(int ch); + + std::vector> commands; +}; + +#endif // MENU_H From d593edfd5040820d2a79c68bf34d3c89ff4084bc Mon Sep 17 00:00:00 2001 From: JFpro160 Date: Sat, 13 Jul 2024 19:49:11 -0500 Subject: [PATCH 03/15] Interfaz 1.3 clean --- src/interface/Command/Command.h | 4 ++-- src/interface/Menu/Menu.cpp | 7 +++---- src/interface/Menu/Menu.h | 13 +++++++------ src/main.cpp | 1 - 4 files changed, 12 insertions(+), 13 deletions(-) diff --git a/src/interface/Command/Command.h b/src/interface/Command/Command.h index f74197b..6f26851 100644 --- a/src/interface/Command/Command.h +++ b/src/interface/Command/Command.h @@ -11,12 +11,12 @@ class Command { virtual ~Command() = default; }; -class Option1Command : public Command { +class Option1Command final : public Command { public: void execute() override; }; -class Option2Command : public Command { +class Option2Command final : public Command { public: void execute() override; }; diff --git a/src/interface/Menu/Menu.cpp b/src/interface/Menu/Menu.cpp index 628adc7..245efe4 100644 --- a/src/interface/Menu/Menu.cpp +++ b/src/interface/Menu/Menu.cpp @@ -4,14 +4,13 @@ #include "Menu.h" -void Menu::run() { +[[noreturn]] void Menu::run() { commands.push_back(std::make_unique()); commands.push_back(std::make_unique()); - int choice; while (true) { drawMenu(); - choice = getch(); + const int choice = getch(); processInput(choice); } } @@ -25,7 +24,7 @@ void Menu::drawMenu() { refresh(); } -void Menu::processInput(int ch) { +void Menu::processInput(const int ch) const { switch (ch) { case '1': commands[0]->execute(); diff --git a/src/interface/Menu/Menu.h b/src/interface/Menu/Menu.h index 533a5dd..24fd276 100644 --- a/src/interface/Menu/Menu.h +++ b/src/interface/Menu/Menu.h @@ -17,7 +17,10 @@ class Menu { return instance; } - void run(); + [[noreturn]] void run(); + + Menu(const Menu&) = delete; + Menu& operator=(const Menu&) = delete; private: Menu() { @@ -31,13 +34,11 @@ class Menu { endwin(); } - Menu(const Menu&) = delete; - Menu& operator=(const Menu&) = delete; - void drawMenu(); - void processInput(int ch); + static void drawMenu(); + void processInput(int ch) const; - std::vector> commands; + std::vector> commands{}; }; #endif // MENU_H diff --git a/src/main.cpp b/src/main.cpp index a9baa04..5e5086c 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -2,5 +2,4 @@ int main() { Menu::getInstance().run(); - return 0; } From 242d9d9a2f69263a4e1a427ef5bcf2f4ea8aa8b0 Mon Sep 17 00:00:00 2001 From: JFpro160 Date: Sat, 13 Jul 2024 19:57:45 -0500 Subject: [PATCH 04/15] Ignorar .idea --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index ecbbe4b..8cc4ac4 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,5 @@ /cmake-build-debug/ +/.idea/ CMakeLists.txt mpst_full_data.csv - From bd4cde07392d6c54250957becc5c27ae3c2b891c Mon Sep 17 00:00:00 2001 From: JFpro160 Date: Sat, 13 Jul 2024 21:58:14 -0500 Subject: [PATCH 05/15] Menu clean --- src/interface/Menu/Menu.cpp | 41 +++++++++++++++++++++++++++---------- src/interface/Menu/Menu.h | 37 ++++++++++++--------------------- 2 files changed, 43 insertions(+), 35 deletions(-) diff --git a/src/interface/Menu/Menu.cpp b/src/interface/Menu/Menu.cpp index 245efe4..8f32521 100644 --- a/src/interface/Menu/Menu.cpp +++ b/src/interface/Menu/Menu.cpp @@ -3,16 +3,26 @@ // #include "Menu.h" +#include -[[noreturn]] void Menu::run() { - commands.push_back(std::make_unique()); - commands.push_back(std::make_unique()); +Menu Menu::instance; - while (true) { - drawMenu(); - const int choice = getch(); - processInput(choice); - } +Menu::Menu() { + initscr(); + noecho(); + cbreak(); + keypad(stdscr, TRUE); + + commands.push_back(make_unique()); + commands.push_back(make_unique()); +} + +Menu::~Menu() { + endwin(); +} + +Menu& Menu::getInstance() { + return instance; } void Menu::drawMenu() { @@ -24,8 +34,8 @@ void Menu::drawMenu() { refresh(); } -void Menu::processInput(const int ch) const { - switch (ch) { +void Menu::processInput(const int choice) const { + switch (choice) { case '1': commands[0]->execute(); break; @@ -33,7 +43,8 @@ void Menu::processInput(const int ch) const { commands[1]->execute(); break; case '3': - exit(0); + endwin(); + exit(0); default: mvprintw(4, 0, "Opcion no valida"); refresh(); @@ -41,3 +52,11 @@ void Menu::processInput(const int ch) const { break; } } + +[[noreturn]] void Menu::run() const { + while (true) { + drawMenu(); + const int choice = getch(); + processInput(choice); + } +} \ No newline at end of file diff --git a/src/interface/Menu/Menu.h b/src/interface/Menu/Menu.h index 24fd276..bbd9cf3 100644 --- a/src/interface/Menu/Menu.h +++ b/src/interface/Menu/Menu.h @@ -5,40 +5,29 @@ #ifndef MENU_H #define MENU_H -#include #include #include -#include "../Command/Command.h" +#include "Command.h" -class Menu { -public: - static Menu& getInstance() { - static Menu instance; - return instance; - } - - [[noreturn]] void run(); - - Menu(const Menu&) = delete; - Menu& operator=(const Menu&) = delete; +using std::unique_ptr, std::make_unique; +class Menu { private: - Menu() { - initscr(); - noecho(); - cbreak(); - keypad(stdscr, TRUE); - } + static Menu instance; + + std::vector> commands; - ~Menu() { - endwin(); - } + Menu(); + ~Menu(); +public: + static Menu& getInstance(); static void drawMenu(); - void processInput(int ch) const; - std::vector> commands{}; + void processInput(int choice) const; + + [[noreturn]] void run() const; }; #endif // MENU_H From 700369f24ed71aa02e38e062165ed4f7a0fbfea1 Mon Sep 17 00:00:00 2001 From: JFpro160 Date: Sat, 13 Jul 2024 22:11:25 -0500 Subject: [PATCH 06/15] Clean --- src/interface/Command/Command.cpp | 4 ++-- src/interface/Command/Command.h | 4 ++-- src/interface/Menu/Menu.cpp | 6 +++--- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/interface/Command/Command.cpp b/src/interface/Command/Command.cpp index f283b2a..c68f902 100644 --- a/src/interface/Command/Command.cpp +++ b/src/interface/Command/Command.cpp @@ -5,14 +5,14 @@ #include "Command.h" #include -void Option1Command::execute() { +void Option1::execute() { clear(); mvprintw(0, 0, "Opcion 1 seleccionada"); refresh(); getch(); } -void Option2Command::execute() { +void Option2::execute() { clear(); mvprintw(0, 0, "Opcion 2 seleccionada"); refresh(); diff --git a/src/interface/Command/Command.h b/src/interface/Command/Command.h index 6f26851..18fbd20 100644 --- a/src/interface/Command/Command.h +++ b/src/interface/Command/Command.h @@ -11,12 +11,12 @@ class Command { virtual ~Command() = default; }; -class Option1Command final : public Command { +class Option1 final : public Command { public: void execute() override; }; -class Option2Command final : public Command { +class Option2 final : public Command { public: void execute() override; }; diff --git a/src/interface/Menu/Menu.cpp b/src/interface/Menu/Menu.cpp index 8f32521..994a810 100644 --- a/src/interface/Menu/Menu.cpp +++ b/src/interface/Menu/Menu.cpp @@ -13,8 +13,8 @@ Menu::Menu() { cbreak(); keypad(stdscr, TRUE); - commands.push_back(make_unique()); - commands.push_back(make_unique()); + commands.push_back(make_unique()); + commands.push_back(make_unique()); } Menu::~Menu() { @@ -27,7 +27,7 @@ Menu& Menu::getInstance() { void Menu::drawMenu() { clear(); - mvprintw(0, 0, "Menu Principal:"); + mvprintw(0, 0, "ChavezNet:"); mvprintw(1, 0, "1. Opcion 1"); mvprintw(2, 0, "2. Opcion 2"); mvprintw(3, 0, "3. Salir"); From dcbbcf7ab3102ce0e745879ac55aab4f9d0399de Mon Sep 17 00:00:00 2001 From: JFpro160 Date: Sun, 14 Jul 2024 06:57:53 -0500 Subject: [PATCH 07/15] Interfaz 2.0 Terminada al Fin A Dormir --- src/interface/Menu/Menu.cpp | 264 ++++++++++++++++++++++++++++++++---- src/interface/Menu/Menu.h | 18 ++- 2 files changed, 250 insertions(+), 32 deletions(-) diff --git a/src/interface/Menu/Menu.cpp b/src/interface/Menu/Menu.cpp index 994a810..09eafaf 100644 --- a/src/interface/Menu/Menu.cpp +++ b/src/interface/Menu/Menu.cpp @@ -1,17 +1,55 @@ -// -// Created by jfpro on 13/07/24. -// - #include "Menu.h" #include +#include +#include +#include Menu Menu::instance; +bool Menu::firstTime = true; + +const char* ascii_art[] = { + " _____ _ _ _ _ ", + " / ____| | | \\ | | | | ", + " | | | |___ __ ___ _____ ___| \\| | ___| |_ ", + R"( | | | __ \ / _` \ \ / / _ \_ / . ` |/ _ \ __|)", + " | |____| | | | (_| |\\ V / __// /| |\\ | __/ |_ ", + R"( \_____|_| |_|\__,_| \_/ \___/___|_| \_|\___|\__|)", + " ", + " " +}; + +constexpr int n_lines = std::size(ascii_art); +const char* options[] = { + "1. Opcion 1", + "2. Opcion 2", + "3. Salir" +}; + +constexpr int n_options = std::size(options); Menu::Menu() { initscr(); + start_color(); // Inicializa el uso de colores + + init_pair(1, COLOR_WHITE, COLOR_BLACK); // Fondo negro, texto blanco + init_pair(2, COLOR_CYAN, COLOR_BLACK); // Texto cian brillante + init_pair(3, COLOR_MAGENTA, COLOR_BLACK); // Texto magenta brillante + init_pair(4, COLOR_GREEN, COLOR_BLACK); // Texto verde brillante para opciones + init_pair(5, COLOR_BLACK, COLOR_WHITE); // Fondo blanco, texto negro para selección + init_pair(6, COLOR_MAGENTA, COLOR_BLACK); // Texto magenta para el borde + noecho(); cbreak(); keypad(stdscr, TRUE); + bkgd(COLOR_PAIR(1)); // Establecer fondo negro + + // Configurar la señal de redimensionamiento + signal(SIGWINCH, [](int) { + endwin(); + refresh(); + clear(); + drawMenu(0); // Ajustar aquí para llamar a la instancia correcta + }); commands.push_back(make_unique()); commands.push_back(make_unique()); @@ -25,38 +63,208 @@ Menu& Menu::getInstance() { return instance; } -void Menu::drawMenu() { - clear(); - mvprintw(0, 0, "ChavezNet:"); - mvprintw(1, 0, "1. Opcion 1"); - mvprintw(2, 0, "2. Opcion 2"); - mvprintw(3, 0, "3. Salir"); +void Menu::drawOptionBox(int y, int x, const char* text, bool highlight) { + if (highlight) { + attron(COLOR_PAIR(5)); + } else { + attron(COLOR_PAIR(4) | A_BOLD); + } + + mvprintw(y, x, "+---------------+"); + mvprintw(y + 1, x, "| %-13s |", text); + mvprintw(y + 2, x, "+---------------+"); + + if (highlight) { + attroff(COLOR_PAIR(5)); + } else { + attroff(COLOR_PAIR(4) | A_BOLD); + } +} + +void Menu::drawAsciiArt() { + attron(COLOR_PAIR(2) | A_BOLD); + for (int i = 0; i < n_lines; ++i) { + mvprintw(i + 1, (COLS - 52) / 2, ascii_art[i]); + refresh(); + std::this_thread::sleep_for(std::chrono::milliseconds(100)); // Pausa de 100ms para animación + } + attroff(COLOR_PAIR(2) | A_BOLD); +} + +void Menu::drawBorderSnail() { + attron(COLOR_PAIR(6)); // Usar color magenta para el borde + + int x_start = 0; + int y_start = 0; + int x_end = COLS - 1; + int y_end = LINES - 1; + + mvprintw(y_start, x_start, "+"); // Esquina superior izquierda refresh(); + + while (x_start <= x_end && y_start <= y_end) { + for (int i = x_start + 1; i <= x_end; ++i) { + mvprintw(y_start, i, "-"); + move(y_start, i); // Mover el cursor durante la animación + refresh(); + std::this_thread::sleep_for(std::chrono::milliseconds(10)); + } + mvprintw(y_start, x_end, "+"); // Esquina superior derecha + refresh(); + y_start++; + + for (int i = y_start; i <= y_end; ++i) { + mvprintw(i, x_end, "|"); + move(i, x_end); // Mover el cursor durante la animación + refresh(); + std::this_thread::sleep_for(std::chrono::milliseconds(10)); + } + mvprintw(y_end, x_end, "+"); // Esquina inferior derecha + refresh(); + x_end--; + + if (y_start <= y_end) { + for (int i = x_end; i >= x_start; --i) { + mvprintw(y_end, i, "-"); + move(y_end, i); // Mover el cursor durante la animación + refresh(); + std::this_thread::sleep_for(std::chrono::milliseconds(10)); + } + mvprintw(y_end, x_start, "+"); // Esquina inferior izquierda + refresh(); + y_end--; + } + + if (x_start <= x_end) { + for (int i = y_end; i >= y_start; --i) { + mvprintw(i, x_start, "|"); + move(i, x_start); // Mover el cursor durante la animación + refresh(); + std::this_thread::sleep_for(std::chrono::milliseconds(10)); + } + if (y_start == 1) break; // Detener la animación al regresar a la esquina superior izquierda + mvprintw(y_start, x_start, "+"); // Esquina superior izquierda + refresh(); + x_start++; + } + } + attroff(COLOR_PAIR(6)); } -void Menu::processInput(const int choice) const { - switch (choice) { - case '1': - commands[0]->execute(); - break; - case '2': - commands[1]->execute(); - break; - case '3': - endwin(); - exit(0); - default: - mvprintw(4, 0, "Opcion no valida"); +void Menu::animateBackground() { + clear(); + refresh(); + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + + // Asegurarse de que el borde sea consistente + drawBorderSnail(); + + // Mostrar el ASCII art línea por línea + drawAsciiArt(); + + int y = (LINES - (n_options * 4)) / 2 - 2; // Ajuste de posición vertical + + for (int i = 0; i < n_options; ++i) { + drawOptionBox(y + i * 4, (COLS - 16) / 2, options[i], false); refresh(); - getch(); - break; + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + } + + move(LINES - 1, COLS - 1); // Mover el cursor al lado derecho durante la animación + refresh(); +} + +void Menu::drawMenu(const int highlight) { + clear(); + bkgd(COLOR_PAIR(1)); + + attron(COLOR_PAIR(6)); // Usar color magenta para el borde + + int x_start = 0; + int y_start = 0; + int x_end = COLS - 1; + int y_end = LINES - 1; + + mvprintw(y_start, x_start, "+"); // Esquina superior izquierda + mvprintw(y_start, x_end, "+"); // Esquina superior derecha + mvprintw(y_end, x_start, "+"); // Esquina inferior izquierda + mvprintw(y_end, x_end, "+"); // Esquina inferior derecha + + for (int i = x_start + 1; i <= x_end - 1; ++i) { + mvprintw(y_start, i, "-"); + mvprintw(y_end, i, "-"); + } + + for (int i = y_start + 1; i <= y_end - 1; ++i) { + mvprintw(i, x_start, "|"); + mvprintw(i, x_end, "|"); + } + attroff(COLOR_PAIR(6)); + + attron(COLOR_PAIR(2) | A_BOLD); + for (int i = 0; i < n_lines; ++i) { + mvprintw(i + 1, (COLS - 52) / 2, ascii_art[i]); + } + attroff(COLOR_PAIR(2) | A_BOLD); + + int y = (LINES - (n_options * 4)) / 2 - 2; // Ajuste de posición vertical + + for (int i = 0; i < n_options; ++i) { + drawOptionBox(y + i * 4, (COLS - 16) / 2, options[i], i == highlight); + } + + refresh(); +} + +void Menu::processInput(int& choice) const { + move((LINES - (n_options * 4)) / 2 - 1 + choice * 4, (COLS - 16) / 2 + 2); + switch (getch()) { + case KEY_UP: + case KEY_LEFT: + if (choice == 0) { + choice = n_options - 1; + } else { + choice--; + } + break; + case KEY_DOWN: + case KEY_RIGHT: + if (choice == n_options - 1) { + choice = 0; + } else { + choice++; + } + break; + case 10: // Enter key + switch (choice) { + case 0: + commands[0]->execute(); + break; + case 1: + commands[1]->execute(); + break; + case 2: + endwin(); + exit(0); + default: break; + } + firstTime = true; // Permite la animación al regresar al menú + break; + + default:; // No hacer nada } } [[noreturn]] void Menu::run() const { + int choice = 0; + + if (firstTime) { + animateBackground(); + firstTime = false; + } + while (true) { - drawMenu(); - const int choice = getch(); + drawMenu(choice); processInput(choice); } -} \ No newline at end of file +} diff --git a/src/interface/Menu/Menu.h b/src/interface/Menu/Menu.h index bbd9cf3..907c287 100644 --- a/src/interface/Menu/Menu.h +++ b/src/interface/Menu/Menu.h @@ -15,17 +15,27 @@ class Menu { private: static Menu instance; + static bool firstTime; // Declarar como estática + std::vector> commands; Menu(); ~Menu(); -public: - static Menu& getInstance(); + static void drawOptionBox(int y, int x, const char* text, bool highlight); + + static void drawAsciiArt(); + + static void drawBorderSnail(); - static void drawMenu(); + static void animateBackground(); - void processInput(int choice) const; + static void drawMenu(int highlight); + + void processInput(int &choice) const; + +public: + static Menu& getInstance(); [[noreturn]] void run() const; }; From 901c1e9b1baf0d8ca372f5b609675e3b3e550d3a Mon Sep 17 00:00:00 2001 From: JFpro160 Date: Sun, 14 Jul 2024 20:06:43 -0500 Subject: [PATCH 08/15] ChavezNet 1.0 --- src/interface/Command/Command.cpp | 83 +++++++-- src/interface/Command/Command.h | 90 +++++++++- src/interface/Menu/Menu.cpp | 268 +++++++++--------------------- src/interface/Menu/Menu.h | 51 +++--- src/main.cpp | 2 +- 5 files changed, 255 insertions(+), 239 deletions(-) diff --git a/src/interface/Command/Command.cpp b/src/interface/Command/Command.cpp index c68f902..cf19388 100644 --- a/src/interface/Command/Command.cpp +++ b/src/interface/Command/Command.cpp @@ -1,20 +1,77 @@ -// -// Created by jfpro on 13/07/24. -// - #include "Command.h" -#include +#include "Menu.h" +// Implementaciones de Option1 void Option1::execute() { - clear(); - mvprintw(0, 0, "Opcion 1 seleccionada"); - refresh(); - getch(); + std::vector> commands; + commands.push_back(std::make_unique()); + commands.push_back(std::make_unique()); + commands.push_back(std::make_unique()); + commands.push_back(std::make_unique()); + Menu::getInstance().setCommands(std::move(commands)); } +// Implementaciones de Option2 void Option2::execute() { - clear(); - mvprintw(0, 0, "Opcion 2 seleccionada"); - refresh(); - getch(); + std::vector> commands; + commands.push_back(std::make_unique()); + commands.push_back(std::make_unique()); + commands.push_back(std::make_unique()); + Menu::getInstance().setCommands(std::move(commands)); +} + +// Implementaciones de ExitOption +void ExitOption::execute() { + endwin(); + exit(0); +} + +// Implementaciones de SubOption1 +void SubOption1::execute() { + std::vector> commands; + commands.push_back(std::make_unique()); + commands.push_back(std::make_unique()); + commands.push_back(std::make_unique()); + commands.push_back(std::make_unique()); + Menu::getInstance().setCommands(std::move(commands)); +} + +// Implementaciones de SubOption2 +void SubOption2::execute() { + // Define actions for SubOption2 +} + +// Implementaciones de SubOption3 +void SubOption3::execute() { + // Define actions for SubOption3 +} + +// Implementaciones de SubOption4 +void SubOption4::execute() { + // Define actions for SubOption4 +} + +// Implementaciones de SubOption5 +void SubOption5::execute() { + // Define actions for SubOption5 +} + +// Implementaciones de SubSubOption1 +void SubSubOption1::execute() { + // Define actions for SubSubOption1 +} + +// Implementaciones de SubSubOption2 +void SubSubOption2::execute() { + // Define actions for SubSubOption2 +} + +// Implementaciones de SubSubOption5 +void SubSubOption5::execute() { + // Define actions for SubSubOption5 +} + +// Implementaciones de ReturnOption +void ReturnOption::execute() { + Menu::getInstance().restoreState(); } diff --git a/src/interface/Command/Command.h b/src/interface/Command/Command.h index 18fbd20..ac163cf 100644 --- a/src/interface/Command/Command.h +++ b/src/interface/Command/Command.h @@ -1,25 +1,99 @@ -// -// Created by jfpro on 13/07/24. -// - #ifndef COMMAND_H #define COMMAND_H +#include +#include + class Command { public: - virtual void execute() = 0; virtual ~Command() = default; + virtual void execute() = 0; + virtual std::string getText() const = 0; + virtual std::unique_ptr clone() const = 0; }; -class Option1 final : public Command { +class Option1 : public Command { public: void execute() override; + std::string getText() const override { return "Option 1"; } + std::unique_ptr clone() const override { return std::make_unique(*this); } }; -class Option2 final : public Command { +class Option2 : public Command { public: void execute() override; + std::string getText() const override { return "Option 2"; } + std::unique_ptr clone() const override { return std::make_unique(*this); } }; -#endif // COMMAND_H +class ExitOption : public Command { +public: + void execute() override; + std::string getText() const override { return "Exit"; } + std::unique_ptr clone() const override { return std::make_unique(*this); } +}; + +class SubOption1 : public Command { +public: + void execute() override; + std::string getText() const override { return "SubOption 1"; } + std::unique_ptr clone() const override { return std::make_unique(*this); } +}; +class SubOption2 : public Command { +public: + void execute() override; + std::string getText() const override { return "SubOption 2"; } + std::unique_ptr clone() const override { return std::make_unique(*this); } +}; + +class SubOption3 : public Command { +public: + void execute() override; + std::string getText() const override { return "SubOption 3"; } + std::unique_ptr clone() const override { return std::make_unique(*this); } +}; + +class SubOption4 : public Command { +public: + void execute() override; + std::string getText() const override { return "SubOption 4"; } + std::unique_ptr clone() const override { return std::make_unique(*this); } +}; + +class SubOption5 : public Command { +public: + void execute() override; + std::string getText() const override { return "SubOption 5"; } + std::unique_ptr clone() const override { return std::make_unique(*this); } +}; + +class SubSubOption1 : public Command { +public: + void execute() override; + std::string getText() const override { return "SubSubOption 1"; } + std::unique_ptr clone() const override { return std::make_unique(*this); } +}; + +class SubSubOption2 : public Command { +public: + void execute() override; + std::string getText() const override { return "SubSubOption 2"; } + std::unique_ptr clone() const override { return std::make_unique(*this); } +}; + +class SubSubOption5 : public Command { +public: + void execute() override; + std::string getText() const override { return "SubSubOption 5"; } + std::unique_ptr clone() const override { return std::make_unique(*this); } +}; + +class ReturnOption : public Command { +public: + void execute() override; + std::string getText() const override { return "Return"; } + std::unique_ptr clone() const override { return std::make_unique(*this); } +}; + +#endif // COMMAND_H diff --git a/src/interface/Menu/Menu.cpp b/src/interface/Menu/Menu.cpp index 09eafaf..2bec47a 100644 --- a/src/interface/Menu/Menu.cpp +++ b/src/interface/Menu/Menu.cpp @@ -1,42 +1,25 @@ #include "Menu.h" +#include "Animation.h" #include #include -#include -#include +#include +#include +#include +#include Menu Menu::instance; bool Menu::firstTime = true; -const char* ascii_art[] = { - " _____ _ _ _ _ ", - " / ____| | | \\ | | | | ", - " | | | |___ __ ___ _____ ___| \\| | ___| |_ ", - R"( | | | __ \ / _` \ \ / / _ \_ / . ` |/ _ \ __|)", - " | |____| | | | (_| |\\ V / __// /| |\\ | __/ |_ ", - R"( \_____|_| |_|\__,_| \_/ \___/___|_| \_|\___|\__|)", - " ", - " " -}; - -constexpr int n_lines = std::size(ascii_art); -const char* options[] = { - "1. Opcion 1", - "2. Opcion 2", - "3. Salir" -}; - -constexpr int n_options = std::size(options); - -Menu::Menu() { +Menu::Menu() : highlight(0) { initscr(); start_color(); // Inicializa el uso de colores init_pair(1, COLOR_WHITE, COLOR_BLACK); // Fondo negro, texto blanco - init_pair(2, COLOR_CYAN, COLOR_BLACK); // Texto cian brillante - init_pair(3, COLOR_MAGENTA, COLOR_BLACK); // Texto magenta brillante + init_pair(2, COLOR_MAGENTA, COLOR_BLACK); // Texto morado para la animacion + init_pair(3, COLOR_CYAN, COLOR_BLACK); // Texto celeste despues de la animacion init_pair(4, COLOR_GREEN, COLOR_BLACK); // Texto verde brillante para opciones - init_pair(5, COLOR_BLACK, COLOR_WHITE); // Fondo blanco, texto negro para selección - init_pair(6, COLOR_MAGENTA, COLOR_BLACK); // Texto magenta para el borde + init_pair(5, COLOR_BLACK, COLOR_WHITE); // Fondo blanco, texto negro para seleccion + init_pair(6, COLOR_MAGENTA, COLOR_BLACK); // Texto morado para el borde noecho(); cbreak(); @@ -48,11 +31,8 @@ Menu::Menu() { endwin(); refresh(); clear(); - drawMenu(0); // Ajustar aquí para llamar a la instancia correcta + Menu::getInstance().drawMenu(0); }); - - commands.push_back(make_unique()); - commands.push_back(make_unique()); } Menu::~Menu() { @@ -63,208 +43,116 @@ Menu& Menu::getInstance() { return instance; } -void Menu::drawOptionBox(int y, int x, const char* text, bool highlight) { - if (highlight) { - attron(COLOR_PAIR(5)); - } else { - attron(COLOR_PAIR(4) | A_BOLD); +[[noreturn]] void Menu::run() { + + if (firstTime) { + Animation::drawBorderSnail(); + Animation::drawAsciiArt(); + firstTime = false; } - mvprintw(y, x, "+---------------+"); - mvprintw(y + 1, x, "| %-13s |", text); - mvprintw(y + 2, x, "+---------------+"); + std::vector> mainCommands; + mainCommands.push_back(std::make_unique()); + mainCommands.push_back(std::make_unique()); + mainCommands.push_back(std::make_unique()); - if (highlight) { - attroff(COLOR_PAIR(5)); - } else { - attroff(COLOR_PAIR(4) | A_BOLD); - } -} + setCommands(std::move(mainCommands)); + highlight = 0; // Resaltar la última opción al iniciar -void Menu::drawAsciiArt() { - attron(COLOR_PAIR(2) | A_BOLD); - for (int i = 0; i < n_lines; ++i) { - mvprintw(i + 1, (COLS - 52) / 2, ascii_art[i]); - refresh(); - std::this_thread::sleep_for(std::chrono::milliseconds(100)); // Pausa de 100ms para animación + while (true) { + drawMenu(highlight); + processInput(highlight); } - attroff(COLOR_PAIR(2) | A_BOLD); } -void Menu::drawBorderSnail() { - attron(COLOR_PAIR(6)); // Usar color magenta para el borde - - int x_start = 0; - int y_start = 0; - int x_end = COLS - 1; - int y_end = LINES - 1; - - mvprintw(y_start, x_start, "+"); // Esquina superior izquierda - refresh(); - - while (x_start <= x_end && y_start <= y_end) { - for (int i = x_start + 1; i <= x_end; ++i) { - mvprintw(y_start, i, "-"); - move(y_start, i); // Mover el cursor durante la animación - refresh(); - std::this_thread::sleep_for(std::chrono::milliseconds(10)); - } - mvprintw(y_start, x_end, "+"); // Esquina superior derecha - refresh(); - y_start++; - - for (int i = y_start; i <= y_end; ++i) { - mvprintw(i, x_end, "|"); - move(i, x_end); // Mover el cursor durante la animación - refresh(); - std::this_thread::sleep_for(std::chrono::milliseconds(10)); - } - mvprintw(y_end, x_end, "+"); // Esquina inferior derecha - refresh(); - x_end--; - - if (y_start <= y_end) { - for (int i = x_end; i >= x_start; --i) { - mvprintw(y_end, i, "-"); - move(y_end, i); // Mover el cursor durante la animación - refresh(); - std::this_thread::sleep_for(std::chrono::milliseconds(10)); - } - mvprintw(y_end, x_start, "+"); // Esquina inferior izquierda - refresh(); - y_end--; - } +void Menu::setCommands(std::vector> newCommands) { + saveState(); + commands = std::move(newCommands); + highlight = 0; // Reset highlight to first option +} - if (x_start <= x_end) { - for (int i = y_end; i >= y_start; --i) { - mvprintw(i, x_start, "|"); - move(i, x_start); // Mover el cursor durante la animación - refresh(); - std::this_thread::sleep_for(std::chrono::milliseconds(10)); - } - if (y_start == 1) break; // Detener la animación al regresar a la esquina superior izquierda - mvprintw(y_start, x_start, "+"); // Esquina superior izquierda - refresh(); - x_start++; - } +void Menu::saveState() { + std::vector> stateCopy; + for (auto& command : commands) { + stateCopy.push_back(command->clone()); } - attroff(COLOR_PAIR(6)); + history.push(Memento(std::move(stateCopy))); } -void Menu::animateBackground() { - clear(); - refresh(); - std::this_thread::sleep_for(std::chrono::milliseconds(100)); - - // Asegurarse de que el borde sea consistente - drawBorderSnail(); - - // Mostrar el ASCII art línea por línea - drawAsciiArt(); - - int y = (LINES - (n_options * 4)) / 2 - 2; // Ajuste de posición vertical - - for (int i = 0; i < n_options; ++i) { - drawOptionBox(y + i * 4, (COLS - 16) / 2, options[i], false); - refresh(); - std::this_thread::sleep_for(std::chrono::milliseconds(100)); +void Menu::restoreState() { + if (!history.empty()) { + commands = history.top().getState(); + history.pop(); } - - move(LINES - 1, COLS - 1); // Mover el cursor al lado derecho durante la animación - refresh(); + highlight = static_cast(commands.size()) - 1; // Seleccionar la última opción por defecto } -void Menu::drawMenu(const int highlight) { +void Menu::drawMenu(int highlight) const { clear(); bkgd(COLOR_PAIR(1)); - attron(COLOR_PAIR(6)); // Usar color magenta para el borde + Animation::drawStaticBorder(); + if (firstTime) { + Animation::drawAsciiArt(); + } else { + Animation::drawStaticAsciiArt(); + } - int x_start = 0; - int y_start = 0; - int x_end = COLS - 1; - int y_end = LINES - 1; + int maxWidth = 0; + for (const auto& command : commands) { + maxWidth = std::max(maxWidth, static_cast(command->getText().size())); + } + maxWidth += 4; // Espacio para los bordes - mvprintw(y_start, x_start, "+"); // Esquina superior izquierda - mvprintw(y_start, x_end, "+"); // Esquina superior derecha - mvprintw(y_end, x_start, "+"); // Esquina inferior izquierda - mvprintw(y_end, x_end, "+"); // Esquina inferior derecha + int menuHeight = static_cast(commands.size()) * 4; + int y = (LINES - menuHeight) / 2; // Centrar el menú verticalmente - for (int i = x_start + 1; i <= x_end - 1; ++i) { - mvprintw(y_start, i, "-"); - mvprintw(y_end, i, "-"); + for (size_t i = 0; i < commands.size(); ++i) { + drawOptionBox(y + static_cast(i) * 4, (COLS - maxWidth) / 2, commands[i]->getText(), static_cast(i) == highlight, maxWidth); } - for (int i = y_start + 1; i <= y_end - 1; ++i) { - mvprintw(i, x_start, "|"); - mvprintw(i, x_end, "|"); - } - attroff(COLOR_PAIR(6)); + // Mover el cursor a la última letra de la opción resaltada, desplazado una posición hacia la derecha + int padding = (maxWidth - static_cast(commands[highlight]->getText().size()) - 2) / 2; + move(y + highlight * 4 + 1, (COLS - maxWidth) / 2 + padding + static_cast(commands[highlight]->getText().size()) - 1 + 1); - attron(COLOR_PAIR(2) | A_BOLD); - for (int i = 0; i < n_lines; ++i) { - mvprintw(i + 1, (COLS - 52) / 2, ascii_art[i]); - } - attroff(COLOR_PAIR(2) | A_BOLD); + refresh(); +} - int y = (LINES - (n_options * 4)) / 2 - 2; // Ajuste de posición vertical +void Menu::drawOptionBox(int y, int x, const std::string& text, bool highlight, int width) const { + int pair = highlight ? 5 : 4; - for (int i = 0; i < n_options; ++i) { - drawOptionBox(y + i * 4, (COLS - 16) / 2, options[i], i == highlight); - } + int padding = (width - static_cast(text.size()) - 2) / 2; - refresh(); + attron(COLOR_PAIR(pair)); // Usar color adecuado para la opción (resaltada o no) + mvprintw(y, x, "+%s+", std::string(width - 2, '-').c_str()); + mvprintw(y + 1, x, "|%s%s%s|", std::string(padding, ' ').c_str(), text.c_str(), std::string(width - text.size() - padding - 2, ' ').c_str()); + mvprintw(y + 2, x, "+%s+", std::string(width - 2, '-').c_str()); + attroff(COLOR_PAIR(pair)); } -void Menu::processInput(int& choice) const { - move((LINES - (n_options * 4)) / 2 - 1 + choice * 4, (COLS - 16) / 2 + 2); - switch (getch()) { +void Menu::processInput(int& choice) { + int ch = getch(); + switch (ch) { case KEY_UP: case KEY_LEFT: if (choice == 0) { - choice = n_options - 1; + choice = static_cast(commands.size()) - 1; } else { choice--; } break; case KEY_DOWN: case KEY_RIGHT: - if (choice == n_options - 1) { + if (choice == static_cast(commands.size()) - 1) { choice = 0; } else { choice++; } break; case 10: // Enter key - switch (choice) { - case 0: - commands[0]->execute(); - break; - case 1: - commands[1]->execute(); - break; - case 2: - endwin(); - exit(0); - default: break; - } - firstTime = true; // Permite la animación al regresar al menú + commands[choice]->execute(); + break; + default: break; - - default:; // No hacer nada - } -} - -[[noreturn]] void Menu::run() const { - int choice = 0; - - if (firstTime) { - animateBackground(); - firstTime = false; - } - - while (true) { - drawMenu(choice); - processInput(choice); } } diff --git a/src/interface/Menu/Menu.h b/src/interface/Menu/Menu.h index 907c287..c1c19e1 100644 --- a/src/interface/Menu/Menu.h +++ b/src/interface/Menu/Menu.h @@ -1,43 +1,40 @@ -// -// Created by jfpro on 13/07/24. -// - #ifndef MENU_H #define MENU_H -#include #include +#include +#include #include "Command.h" - -using std::unique_ptr, std::make_unique; +#include "Memento.h" +#include "Animation.h" +#include +#include class Menu { -private: - static Menu instance; - - static bool firstTime; // Declarar como estática - - std::vector> commands; +public: + static Menu& getInstance(); + [[noreturn]] void run(); + void setCommands(std::vector> commands); +private: Menu(); ~Menu(); + Menu(const Menu&) = delete; + Menu& operator=(const Menu&) = delete; - static void drawOptionBox(int y, int x, const char* text, bool highlight); - - static void drawAsciiArt(); - - static void drawBorderSnail(); - - static void animateBackground(); - - static void drawMenu(int highlight); + void saveState(); + void restoreState(); + void drawMenu(int highlight) const; + void drawOptionBox(int y, int x, const std::string& text, bool highlight, int width) const; + void processInput(int& choice); - void processInput(int &choice) const; - -public: - static Menu& getInstance(); + static Menu instance; + static bool firstTime; + std::vector> commands; + std::stack history; + int highlight; - [[noreturn]] void run() const; + friend ReturnOption; }; #endif // MENU_H diff --git a/src/main.cpp b/src/main.cpp index 5e5086c..b60abf5 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,4 +1,4 @@ -#include "interface/Menu/Menu.h" +#include "Menu.h" int main() { Menu::getInstance().run(); From 76a0c03e4c6597138654323fceba73c3b9c06f35 Mon Sep 17 00:00:00 2001 From: JFpro160 Date: Sun, 14 Jul 2024 20:19:03 -0500 Subject: [PATCH 09/15] ChavezNet 1.1 --- src/interface/Animation/Animation.cpp | 131 ++++++++++++++++++++++++++ src/interface/Animation/Animation.h | 13 +++ src/interface/Menu/Memento.h | 21 +++++ 3 files changed, 165 insertions(+) create mode 100644 src/interface/Animation/Animation.cpp create mode 100644 src/interface/Animation/Animation.h create mode 100644 src/interface/Menu/Memento.h diff --git a/src/interface/Animation/Animation.cpp b/src/interface/Animation/Animation.cpp new file mode 100644 index 0000000..8a60bc6 --- /dev/null +++ b/src/interface/Animation/Animation.cpp @@ -0,0 +1,131 @@ +#include "Animation.h" +#include +#include +#include +#include + +const char* ascii_art[] = { + " _____ _ _ _ _ ", + " / ____| | | \\ | | | | ", + " | | | |___ __ ___ _____ ___| \\| | ___| |_ ", + " | | | __ \\ / _` \\ \\ / / _ \\_ / . ` |/ _ \\ __|", + " | |____| | | | (_| |\\ V / __// /| |\\ | __/ |_ ", + " \\_____|_| |_|\\__,_| \\_/ \\___/___|_| \\_|\\___|\\__|", + " ", + " " +}; + +constexpr int n_lines = std::size(ascii_art); + +void Animation::drawBorderSnail() { + // Desactivar la señal de redimensionamiento + auto old_handler = signal(SIGWINCH, SIG_IGN); + + attron(COLOR_PAIR(6)); // Usar color morado para el borde + + int x_start = 0; + int y_start = 0; + int x_end = COLS - 1; + int y_end = LINES - 1; + + mvprintw(y_start, x_start, "+"); // Esquina superior izquierda + refresh(); + + while (x_start <= x_end && y_start <= y_end) { + for (int i = x_start + 1; i <= x_end; ++i) { + mvprintw(y_start, i, "-"); + move(y_start, i); // Mover el cursor durante la animación + refresh(); + std::this_thread::sleep_for(std::chrono::milliseconds(10)); + } + mvprintw(y_start, x_end, "+"); // Esquina superior derecha + refresh(); + y_start++; + + for (int i = y_start; i <= y_end; ++i) { + mvprintw(i, x_end, "|"); + move(i, x_end); // Mover el cursor durante la animación + refresh(); + std::this_thread::sleep_for(std::chrono::milliseconds(10)); + } + mvprintw(y_end, x_end, "+"); // Esquina inferior derecha + refresh(); + x_end--; + + if (y_start <= y_end) { + for (int i = x_end; i >= x_start; --i) { + mvprintw(y_end, i, "-"); + move(y_end, i); // Mover el cursor durante la animación + refresh(); + std::this_thread::sleep_for(std::chrono::milliseconds(10)); + } + mvprintw(y_end, x_start, "+"); // Esquina inferior izquierda + refresh(); + y_end--; + } + + if (x_start <= x_end) { + for (int i = y_end; i >= y_start; --i) { + mvprintw(i, x_start, "|"); + move(i, x_start); // Mover el cursor durante la animación + refresh(); + std::this_thread::sleep_for(std::chrono::milliseconds(10)); + } + if (y_start == 1) break; // Detener la animación al regresar a la esquina superior izquierda + mvprintw(y_start, x_start, "+"); // Esquina superior izquierda + refresh(); + x_start++; + } + } + attroff(COLOR_PAIR(6)); + + // Restaurar la señal de redimensionamiento + signal(SIGWINCH, old_handler); +} + +void Animation::drawAsciiArt() { + attron(COLOR_PAIR(2) | A_BOLD); // Color morado durante la animación + for (int i = 0; i < n_lines; ++i) { + mvprintw(i + 1, (COLS - 52) / 2, ascii_art[i]); + refresh(); + std::this_thread::sleep_for(std::chrono::milliseconds(100)); // Pausa de 100ms para animación + } + attroff(COLOR_PAIR(2) | A_BOLD); +} + +void Animation::drawStaticAsciiArt() { + attron(COLOR_PAIR(3) | A_BOLD); // Color celeste después de la animación + for (int i = 0; i < n_lines; ++i) { + mvprintw(i + 1, (COLS - 52) / 2, ascii_art[i]); + } + attroff(COLOR_PAIR(3) | A_BOLD); +} + +void Animation::drawStaticBorder() { + attron(COLOR_PAIR(6)); + int x_start = 0; + int y_start = 0; + int x_end = COLS - 1; + int y_end = LINES - 1; + + // Superior + mvhline(y_start, x_start + 1, '-', x_end - 1); + + // Inferior + mvhline(y_end, x_start + 1, '-', x_end - 1); + + // Izquierda + mvvline(y_start + 1, x_start, '|', y_end - 1); + + // Derecha + mvvline(y_start + 1, x_end, '|', y_end - 1); + + // Esquinas + mvprintw(y_start, x_start, "+"); + mvprintw(y_start, x_end, "+"); + mvprintw(y_end, x_start, "+"); + mvprintw(y_end, x_end, "+"); + + attroff(COLOR_PAIR(6)); + refresh(); +} diff --git a/src/interface/Animation/Animation.h b/src/interface/Animation/Animation.h new file mode 100644 index 0000000..3a7da68 --- /dev/null +++ b/src/interface/Animation/Animation.h @@ -0,0 +1,13 @@ +#ifndef ANIMATION_H +#define ANIMATION_H + +class Animation { +public: + static void drawAsciiArt(); + static void drawStaticAsciiArt(); + static void drawBorderSnail(); + static void drawStaticBorder(); + static constexpr int n_lines = 8; // Altura del logo en ASCII +}; + +#endif // ANIMATION_H diff --git a/src/interface/Menu/Memento.h b/src/interface/Menu/Memento.h new file mode 100644 index 0000000..466990d --- /dev/null +++ b/src/interface/Menu/Memento.h @@ -0,0 +1,21 @@ +#ifndef MEMENTO_H +#define MEMENTO_H + +#include +#include +#include "../Command/Command.h" + +class Memento { + friend class Menu; // Agregar la clase Menu como amiga +public: + Memento(std::vector> state) : state_(std::move(state)) {} + +private: + std::vector> getState() { + return std::move(state_); + } + + std::vector> state_; +}; + +#endif // MEMENTO_H From 08c7db7e23bf8291e7fea0b22d793e5edcd36d44 Mon Sep 17 00:00:00 2001 From: JFpro160 Date: Sun, 14 Jul 2024 20:30:16 -0500 Subject: [PATCH 10/15] ChavezNet 1.2.0 --- src/interface/Animation/Animation.cpp | 13 +++++++++++++ src/interface/Menu/Menu.cpp | 5 +++-- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/interface/Animation/Animation.cpp b/src/interface/Animation/Animation.cpp index 8a60bc6..c07be21 100644 --- a/src/interface/Animation/Animation.cpp +++ b/src/interface/Animation/Animation.cpp @@ -1,3 +1,4 @@ +// Animation.cpp #include "Animation.h" #include #include @@ -84,6 +85,9 @@ void Animation::drawBorderSnail() { } void Animation::drawAsciiArt() { + // Desactivar la señal de redimensionamiento + auto old_handler = signal(SIGWINCH, SIG_IGN); + attron(COLOR_PAIR(2) | A_BOLD); // Color morado durante la animación for (int i = 0; i < n_lines; ++i) { mvprintw(i + 1, (COLS - 52) / 2, ascii_art[i]); @@ -91,14 +95,23 @@ void Animation::drawAsciiArt() { std::this_thread::sleep_for(std::chrono::milliseconds(100)); // Pausa de 100ms para animación } attroff(COLOR_PAIR(2) | A_BOLD); + + // Restaurar la señal de redimensionamiento + signal(SIGWINCH, old_handler); } void Animation::drawStaticAsciiArt() { + // Desactivar la señal de redimensionamiento + auto old_handler = signal(SIGWINCH, SIG_IGN); + attron(COLOR_PAIR(3) | A_BOLD); // Color celeste después de la animación for (int i = 0; i < n_lines; ++i) { mvprintw(i + 1, (COLS - 52) / 2, ascii_art[i]); } attroff(COLOR_PAIR(3) | A_BOLD); + + // Restaurar la señal de redimensionamiento + signal(SIGWINCH, old_handler); } void Animation::drawStaticBorder() { diff --git a/src/interface/Menu/Menu.cpp b/src/interface/Menu/Menu.cpp index 2bec47a..ec63eee 100644 --- a/src/interface/Menu/Menu.cpp +++ b/src/interface/Menu/Menu.cpp @@ -44,6 +44,7 @@ Menu& Menu::getInstance() { } [[noreturn]] void Menu::run() { + int choice = 0; if (firstTime) { Animation::drawBorderSnail(); @@ -57,7 +58,7 @@ Menu& Menu::getInstance() { mainCommands.push_back(std::make_unique()); setCommands(std::move(mainCommands)); - highlight = 0; // Resaltar la última opción al iniciar + highlight = static_cast(commands.size()) - 1; // Resaltar la última opción al iniciar while (true) { drawMenu(highlight); @@ -105,7 +106,7 @@ void Menu::drawMenu(int highlight) const { maxWidth += 4; // Espacio para los bordes int menuHeight = static_cast(commands.size()) * 4; - int y = (LINES - menuHeight) / 2; // Centrar el menú verticalmente + int y = (LINES - (menuHeight + Animation::n_lines)) / 2 + Animation::n_lines; // Centrar el menú verticalmente teniendo en cuenta el alto del logo for (size_t i = 0; i < commands.size(); ++i) { drawOptionBox(y + static_cast(i) * 4, (COLS - maxWidth) / 2, commands[i]->getText(), static_cast(i) == highlight, maxWidth); From 21ded8e4a2fb5904420b06aeff62c380c15e1d88 Mon Sep 17 00:00:00 2001 From: JFpro160 Date: Sun, 14 Jul 2024 21:42:12 -0500 Subject: [PATCH 11/15] ChavezNet 1.2.1 --- src/interface/Menu/Menu.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/interface/Menu/Menu.cpp b/src/interface/Menu/Menu.cpp index ec63eee..23fc10e 100644 --- a/src/interface/Menu/Menu.cpp +++ b/src/interface/Menu/Menu.cpp @@ -31,7 +31,7 @@ Menu::Menu() : highlight(0) { endwin(); refresh(); clear(); - Menu::getInstance().drawMenu(0); + getInstance().drawMenu(0); }); } @@ -44,7 +44,6 @@ Menu& Menu::getInstance() { } [[noreturn]] void Menu::run() { - int choice = 0; if (firstTime) { Animation::drawBorderSnail(); @@ -61,6 +60,9 @@ Menu& Menu::getInstance() { highlight = static_cast(commands.size()) - 1; // Resaltar la última opción al iniciar while (true) { + endwin(); + refresh(); + clear(); drawMenu(highlight); processInput(highlight); } From 2ba462cff359d1a561c6b849b4f05b94b8464c72 Mon Sep 17 00:00:00 2001 From: JFpro160 Date: Sun, 14 Jul 2024 22:08:05 -0500 Subject: [PATCH 12/15] ChavezNet 2.0 --- src/interface/Animation/Animation.cpp | 167 ++++++++++++++------------ src/interface/Animation/Animation.h | 8 ++ 2 files changed, 99 insertions(+), 76 deletions(-) diff --git a/src/interface/Animation/Animation.cpp b/src/interface/Animation/Animation.cpp index c07be21..f400a6d 100644 --- a/src/interface/Animation/Animation.cpp +++ b/src/interface/Animation/Animation.cpp @@ -1,9 +1,4 @@ -// Animation.cpp #include "Animation.h" -#include -#include -#include -#include const char* ascii_art[] = { " _____ _ _ _ _ ", @@ -18,100 +13,120 @@ const char* ascii_art[] = { constexpr int n_lines = std::size(ascii_art); -void Animation::drawBorderSnail() { - // Desactivar la señal de redimensionamiento - auto old_handler = signal(SIGWINCH, SIG_IGN); +volatile sig_atomic_t Animation::resized = 0; +std::function current_animation_func; - attron(COLOR_PAIR(6)); // Usar color morado para el borde +void resizeHandler(int) { + Animation::resized = 1; + endwin(); + refresh(); + clear(); + if (current_animation_func) { + current_animation_func(); + } +} - int x_start = 0; - int y_start = 0; - int x_end = COLS - 1; - int y_end = LINES - 1; +void Animation::handleResizeDuringAnimation(const std::function& animationFunc) { + current_animation_func = animationFunc; + auto old_handler = signal(SIGWINCH, resizeHandler); - mvprintw(y_start, x_start, "+"); // Esquina superior izquierda - refresh(); + while (true) { + Animation::resized = 0; + animationFunc(); + if (!Animation::resized) break; // Salir del bucle si no ha habido redimensión + } - while (x_start <= x_end && y_start <= y_end) { - for (int i = x_start + 1; i <= x_end; ++i) { - mvprintw(y_start, i, "-"); - move(y_start, i); // Mover el cursor durante la animación - refresh(); - std::this_thread::sleep_for(std::chrono::milliseconds(10)); - } - mvprintw(y_start, x_end, "+"); // Esquina superior derecha - refresh(); - y_start++; + signal(SIGWINCH, old_handler); +} - for (int i = y_start; i <= y_end; ++i) { - mvprintw(i, x_end, "|"); - move(i, x_end); // Mover el cursor durante la animación - refresh(); - std::this_thread::sleep_for(std::chrono::milliseconds(10)); - } - mvprintw(y_end, x_end, "+"); // Esquina inferior derecha +void Animation::drawBorderSnail() { + handleResizeDuringAnimation([]() { + attron(COLOR_PAIR(6)); // Usar color morado para el borde + + int x_start = 0; + int y_start = 0; + int x_end = COLS - 1; + int y_end = LINES - 1; + + mvprintw(y_start, x_start, "+"); // Esquina superior izquierda refresh(); - x_end--; - if (y_start <= y_end) { - for (int i = x_end; i >= x_start; --i) { - mvprintw(y_end, i, "-"); - move(y_end, i); // Mover el cursor durante la animación + while (x_start <= x_end && y_start <= y_end) { + for (int i = x_start + 1; i <= x_end; ++i) { + if (Animation::resized) return; + mvprintw(y_start, i, "-"); + move(y_start, i); // Mover el cursor durante la animación refresh(); std::this_thread::sleep_for(std::chrono::milliseconds(10)); } - mvprintw(y_end, x_start, "+"); // Esquina inferior izquierda + mvprintw(y_start, x_end, "+"); // Esquina superior derecha refresh(); - y_end--; - } + y_start++; - if (x_start <= x_end) { - for (int i = y_end; i >= y_start; --i) { - mvprintw(i, x_start, "|"); - move(i, x_start); // Mover el cursor durante la animación + for (int i = y_start; i <= y_end; ++i) { + if (Animation::resized) return; + mvprintw(i, x_end, "|"); + move(i, x_end); // Mover el cursor durante la animación refresh(); std::this_thread::sleep_for(std::chrono::milliseconds(10)); } - if (y_start == 1) break; // Detener la animación al regresar a la esquina superior izquierda - mvprintw(y_start, x_start, "+"); // Esquina superior izquierda + mvprintw(y_end, x_end, "+"); // Esquina inferior derecha refresh(); - x_start++; - } - } - attroff(COLOR_PAIR(6)); + x_end--; + + if (y_start <= y_end) { + for (int i = x_end; i >= x_start; --i) { + if (Animation::resized) return; + mvprintw(y_end, i, "-"); + move(y_end, i); // Mover el cursor durante la animación + refresh(); + std::this_thread::sleep_for(std::chrono::milliseconds(10)); + } + mvprintw(y_end, x_start, "+"); // Esquina inferior izquierda + refresh(); + y_end--; + } - // Restaurar la señal de redimensionamiento - signal(SIGWINCH, old_handler); + if (x_start <= x_end) { + for (int i = y_end; i >= y_start; --i) { + if (Animation::resized) return; + mvprintw(i, x_start, "|"); + move(i, x_start); // Mover el cursor durante la animación + refresh(); + std::this_thread::sleep_for(std::chrono::milliseconds(10)); + } + if (y_start == 1) break; // Detener la animación al regresar a la esquina superior izquierda + mvprintw(y_start, x_start, "+"); // Esquina superior izquierda + refresh(); + x_start++; + } + } + attroff(COLOR_PAIR(6)); + }); } void Animation::drawAsciiArt() { - // Desactivar la señal de redimensionamiento - auto old_handler = signal(SIGWINCH, SIG_IGN); - - attron(COLOR_PAIR(2) | A_BOLD); // Color morado durante la animación - for (int i = 0; i < n_lines; ++i) { - mvprintw(i + 1, (COLS - 52) / 2, ascii_art[i]); - refresh(); - std::this_thread::sleep_for(std::chrono::milliseconds(100)); // Pausa de 100ms para animación - } - attroff(COLOR_PAIR(2) | A_BOLD); - - // Restaurar la señal de redimensionamiento - signal(SIGWINCH, old_handler); + handleResizeDuringAnimation([]() { + attron(COLOR_PAIR(2) | A_BOLD); // Color morado durante la animación + for (int i = 0; i < n_lines; ++i) { + if (Animation::resized) return; + mvprintw(i + 1, (COLS - 52) / 2, ascii_art[i]); + refresh(); + std::this_thread::sleep_for(std::chrono::milliseconds(100)); // Pausa de 100ms para animación + } + attroff(COLOR_PAIR(2) | A_BOLD); + }); } void Animation::drawStaticAsciiArt() { - // Desactivar la señal de redimensionamiento - auto old_handler = signal(SIGWINCH, SIG_IGN); - - attron(COLOR_PAIR(3) | A_BOLD); // Color celeste después de la animación - for (int i = 0; i < n_lines; ++i) { - mvprintw(i + 1, (COLS - 52) / 2, ascii_art[i]); - } - attroff(COLOR_PAIR(3) | A_BOLD); - - // Restaurar la señal de redimensionamiento - signal(SIGWINCH, old_handler); + handleResizeDuringAnimation([]() { + attron(COLOR_PAIR(3) | A_BOLD); // Color celeste después de la animación + for (int i = 0; i < n_lines; ++i) { + if (Animation::resized) return; + mvprintw(i + 1, (COLS - 52) / 2, ascii_art[i]); + } + attroff(COLOR_PAIR(3) | A_BOLD); + }); } void Animation::drawStaticBorder() { diff --git a/src/interface/Animation/Animation.h b/src/interface/Animation/Animation.h index 3a7da68..2811371 100644 --- a/src/interface/Animation/Animation.h +++ b/src/interface/Animation/Animation.h @@ -1,13 +1,21 @@ #ifndef ANIMATION_H #define ANIMATION_H +#include +#include +#include +#include +#include + class Animation { public: static void drawAsciiArt(); static void drawStaticAsciiArt(); static void drawBorderSnail(); static void drawStaticBorder(); + static void handleResizeDuringAnimation(const std::function& animationFunc); static constexpr int n_lines = 8; // Altura del logo en ASCII + static volatile sig_atomic_t resized; // Bandera de redimensión }; #endif // ANIMATION_H From 4742cd7f084c273e05144098b6b8a4f2f90dad4a Mon Sep 17 00:00:00 2001 From: JFpro160 Date: Mon, 15 Jul 2024 08:23:28 -0500 Subject: [PATCH 13/15] ChavezNet 3.0 SuperMegaHiperFINO --- src/interface/Animation/Animation.h | 21 -- .../{Animation.cpp => AnimationManager.cpp} | 206 ++++++++++++------ src/interface/Animation/AnimationManager.h | 42 ++++ src/interface/Drawer/MenuDrawer.cpp | 166 ++++++++++++++ src/interface/Drawer/MenuDrawer.h | 26 +++ src/interface/Menu/Memento.h | 18 +- src/interface/Menu/Menu.cpp | 64 +----- src/interface/Menu/Menu.h | 10 +- 8 files changed, 400 insertions(+), 153 deletions(-) delete mode 100644 src/interface/Animation/Animation.h rename src/interface/Animation/{Animation.cpp => AnimationManager.cpp} (51%) create mode 100644 src/interface/Animation/AnimationManager.h create mode 100644 src/interface/Drawer/MenuDrawer.cpp create mode 100644 src/interface/Drawer/MenuDrawer.h diff --git a/src/interface/Animation/Animation.h b/src/interface/Animation/Animation.h deleted file mode 100644 index 2811371..0000000 --- a/src/interface/Animation/Animation.h +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef ANIMATION_H -#define ANIMATION_H - -#include -#include -#include -#include -#include - -class Animation { -public: - static void drawAsciiArt(); - static void drawStaticAsciiArt(); - static void drawBorderSnail(); - static void drawStaticBorder(); - static void handleResizeDuringAnimation(const std::function& animationFunc); - static constexpr int n_lines = 8; // Altura del logo en ASCII - static volatile sig_atomic_t resized; // Bandera de redimensión -}; - -#endif // ANIMATION_H diff --git a/src/interface/Animation/Animation.cpp b/src/interface/Animation/AnimationManager.cpp similarity index 51% rename from src/interface/Animation/Animation.cpp rename to src/interface/Animation/AnimationManager.cpp index f400a6d..b2d02bd 100644 --- a/src/interface/Animation/Animation.cpp +++ b/src/interface/Animation/AnimationManager.cpp @@ -1,6 +1,9 @@ -#include "Animation.h" +#include "AnimationManager.h" -const char* ascii_art[] = { +volatile sig_atomic_t AnimationManager::resized = 0; +std::function AnimationManager::current_animation_func; + +const std::vector AnimationManager::ascii_art_large = { " _____ _ _ _ _ ", " / ____| | | \\ | | | | ", " | | | |___ __ ___ _____ ___| \\| | ___| |_ ", @@ -11,35 +14,151 @@ const char* ascii_art[] = { " " }; -constexpr int n_lines = std::size(ascii_art); +const std::vector AnimationManager::ascii_art_medium = { + " _____ _ _ _ _ ", + " / ____| | | | | | | |", + "| | | |__ __ _ ___| | __| |_| |", + "| | | '_ \\ / _` |/ __| |/ / __| __|", + "| |____| | | | (_| | (__| <| |_| |_ ", + " \\_____|_| |_|\\__,_|\\___|_|\\_\\\\__|\\__|", + " ", + " " +}; + +const std::vector AnimationManager::ascii_art_small = { + " _____ _", + " / __ \\ | |", + "| / \\/ ___| |_", + "| | / _ \\ __|", + "| \\__/\\ __/ |_", + " \\____/\\___|\\__|", + " ", + " " +}; + +const std::string AnimationManager::ascii_art_text = "ChavezNet"; + +AnimationManager& AnimationManager::getInstance() { + static AnimationManager instance; + return instance; +} + +int AnimationManager::getAsciiArtHeight(const std::vector& asciiArt) const { + return static_cast(asciiArt.size()); +} + +const std::vector& AnimationManager::getAsciiArtLarge() const { + return ascii_art_large; +} -volatile sig_atomic_t Animation::resized = 0; -std::function current_animation_func; +const std::vector& AnimationManager::getAsciiArtMedium() const { + return ascii_art_medium; +} + +const std::vector& AnimationManager::getAsciiArtSmall() const { + return ascii_art_small; +} + +const std::string& AnimationManager::getAsciiArtText() const { + return ascii_art_text; +} void resizeHandler(int) { - Animation::resized = 1; + AnimationManager::resized = 1; endwin(); refresh(); clear(); - if (current_animation_func) { - current_animation_func(); + if (AnimationManager::current_animation_func) { + AnimationManager::current_animation_func(); } } -void Animation::handleResizeDuringAnimation(const std::function& animationFunc) { +void AnimationManager::handleResizeDuringAnimation(const std::function& animationFunc) const { current_animation_func = animationFunc; auto old_handler = signal(SIGWINCH, resizeHandler); while (true) { - Animation::resized = 0; + AnimationManager::resized = 0; animationFunc(); - if (!Animation::resized) break; // Salir del bucle si no ha habido redimensión + if (!AnimationManager::resized) break; // Salir del bucle si no ha habido redimensión } signal(SIGWINCH, old_handler); } -void Animation::drawBorderSnail() { +void AnimationManager::drawStaticAsciiArt() const { + const std::vector* ascii_art; + if (LINES < 12 || COLS < 60) { + ascii_art = &ascii_art_small; + } else if (LINES < 16 || COLS < 80) { + ascii_art = &ascii_art_medium; + } else { + ascii_art = &ascii_art_large; + } + + attron(COLOR_PAIR(3) | A_BOLD); // Color celeste después de la animación + for (int i = 0; i < static_cast(ascii_art->size()); ++i) { + mvprintw(i + 1, (COLS - static_cast(ascii_art->at(0).size())) / 2, ascii_art->at(i).c_str()); + } + attroff(COLOR_PAIR(3) | A_BOLD); + refresh(); +} + +void AnimationManager::drawAdaptiveAsciiArt() const { + handleResizeDuringAnimation([]() { + attron(COLOR_PAIR(2) | A_BOLD); // Color morado durante la animación + + const std::vector* ascii_art; + if (LINES < 12 || COLS < 60) { + ascii_art = &AnimationManager::getInstance().ascii_art_small; + } else if (LINES < 16 || COLS < 80) { + ascii_art = &AnimationManager::getInstance().ascii_art_medium; + } else { + ascii_art = &AnimationManager::getInstance().ascii_art_large; + } + + for (int i = 0; i < static_cast(ascii_art->size()); ++i) { + if (AnimationManager::resized) return; + mvprintw(i + 1, (COLS - static_cast(ascii_art->at(0).size())) / 2, ascii_art->at(i).c_str()); + refresh(); + std::this_thread::sleep_for(std::chrono::milliseconds(100)); // Pausa de 100ms para animación + } + + attroff(COLOR_PAIR(2) | A_BOLD); + AnimationManager::getInstance().drawStaticAsciiArt(); + }); +} + +void AnimationManager::drawStaticBorder() const { + attron(COLOR_PAIR(6)); + int x_start = 0; + int y_start = 0; + int x_end = COLS - 1; + int y_end = LINES - 1; + + // Superior + mvhline(y_start, x_start + 1, '-', x_end - 1); + + // Inferior + mvhline(y_end, x_start + 1, '-', x_end - 1); + + // Izquierda + mvvline(y_start + 1, x_start, '|', y_end - 1); + + // Derecha + mvvline(y_start + 1, x_end, '|', y_end - 1); + + // Esquinas + mvprintw(y_start, x_start, "+"); + mvprintw(y_start, x_end, "+"); + mvprintw(y_end, x_start, "+"); + mvprintw(y_end, x_end, "+"); + + attroff(COLOR_PAIR(6)); + refresh(); +} + +void AnimationManager::drawBorderSnail() const { handleResizeDuringAnimation([]() { attron(COLOR_PAIR(6)); // Usar color morado para el borde @@ -53,7 +172,7 @@ void Animation::drawBorderSnail() { while (x_start <= x_end && y_start <= y_end) { for (int i = x_start + 1; i <= x_end; ++i) { - if (Animation::resized) return; + if (AnimationManager::resized) return; mvprintw(y_start, i, "-"); move(y_start, i); // Mover el cursor durante la animación refresh(); @@ -64,7 +183,7 @@ void Animation::drawBorderSnail() { y_start++; for (int i = y_start; i <= y_end; ++i) { - if (Animation::resized) return; + if (AnimationManager::resized) return; mvprintw(i, x_end, "|"); move(i, x_end); // Mover el cursor durante la animación refresh(); @@ -76,7 +195,7 @@ void Animation::drawBorderSnail() { if (y_start <= y_end) { for (int i = x_end; i >= x_start; --i) { - if (Animation::resized) return; + if (AnimationManager::resized) return; mvprintw(y_end, i, "-"); move(y_end, i); // Mover el cursor durante la animación refresh(); @@ -88,8 +207,8 @@ void Animation::drawBorderSnail() { } if (x_start <= x_end) { - for (int i = y_end; i >= y_start; --i) { - if (Animation::resized) return; + for (int i = y_end; i >= y_start; -- i) { + if (AnimationManager::resized) return; mvprintw(i, x_start, "|"); move(i, x_start); // Mover el cursor durante la animación refresh(); @@ -104,56 +223,3 @@ void Animation::drawBorderSnail() { attroff(COLOR_PAIR(6)); }); } - -void Animation::drawAsciiArt() { - handleResizeDuringAnimation([]() { - attron(COLOR_PAIR(2) | A_BOLD); // Color morado durante la animación - for (int i = 0; i < n_lines; ++i) { - if (Animation::resized) return; - mvprintw(i + 1, (COLS - 52) / 2, ascii_art[i]); - refresh(); - std::this_thread::sleep_for(std::chrono::milliseconds(100)); // Pausa de 100ms para animación - } - attroff(COLOR_PAIR(2) | A_BOLD); - }); -} - -void Animation::drawStaticAsciiArt() { - handleResizeDuringAnimation([]() { - attron(COLOR_PAIR(3) | A_BOLD); // Color celeste después de la animación - for (int i = 0; i < n_lines; ++i) { - if (Animation::resized) return; - mvprintw(i + 1, (COLS - 52) / 2, ascii_art[i]); - } - attroff(COLOR_PAIR(3) | A_BOLD); - }); -} - -void Animation::drawStaticBorder() { - attron(COLOR_PAIR(6)); - int x_start = 0; - int y_start = 0; - int x_end = COLS - 1; - int y_end = LINES - 1; - - // Superior - mvhline(y_start, x_start + 1, '-', x_end - 1); - - // Inferior - mvhline(y_end, x_start + 1, '-', x_end - 1); - - // Izquierda - mvvline(y_start + 1, x_start, '|', y_end - 1); - - // Derecha - mvvline(y_start + 1, x_end, '|', y_end - 1); - - // Esquinas - mvprintw(y_start, x_start, "+"); - mvprintw(y_start, x_end, "+"); - mvprintw(y_end, x_start, "+"); - mvprintw(y_end, x_end, "+"); - - attroff(COLOR_PAIR(6)); - refresh(); -} diff --git a/src/interface/Animation/AnimationManager.h b/src/interface/Animation/AnimationManager.h new file mode 100644 index 0000000..8a154df --- /dev/null +++ b/src/interface/Animation/AnimationManager.h @@ -0,0 +1,42 @@ +#ifndef ANIMATIONMANAGER_H +#define ANIMATIONMANAGER_H + +#include +#include +#include +#include +#include +#include +#include + +class AnimationManager { +public: + static AnimationManager& getInstance(); + void drawStaticBorder() const; + void drawStaticAsciiArt() const; + void drawAdaptiveAsciiArt() const; + void drawBorderSnail() const; + void drawAsciiArt() const; + + const std::vector& getAsciiArtLarge() const; + const std::vector& getAsciiArtMedium() const; + const std::vector& getAsciiArtSmall() const; + const std::string& getAsciiArtText() const; + int getAsciiArtHeight(const std::vector& asciiArt) const; + + friend void resizeHandler(int); + +private: + AnimationManager() = default; + void handleResizeDuringAnimation(const std::function& animationFunc) const; + + static const std::vector ascii_art_large; + static const std::vector ascii_art_medium; + static const std::vector ascii_art_small; + static const std::string ascii_art_text; + + static volatile sig_atomic_t resized; + static std::function current_animation_func; +}; + +#endif // ANIMATIONMANAGER_H diff --git a/src/interface/Drawer/MenuDrawer.cpp b/src/interface/Drawer/MenuDrawer.cpp new file mode 100644 index 0000000..30b776d --- /dev/null +++ b/src/interface/Drawer/MenuDrawer.cpp @@ -0,0 +1,166 @@ +#include "MenuDrawer.h" +#include "ncurses.h" +#include "AnimationManager.h" + +void MenuDrawer::drawMenu(const std::vector>& commands, int highlight) const { + clear(); + bkgd(COLOR_PAIR(1)); + + AnimationManager::getInstance().drawStaticBorder(); + AnimationManager::getInstance().drawStaticAsciiArt(); + + int maxWidth = 0; + for (const auto& command : commands) { + int commandWidth = static_cast(command->getText().size()); + maxWidth = std::max(maxWidth, commandWidth); + } + maxWidth += 6; // Espacio para los bordes y el espacio entre opciones + + int totalHeight = AnimationManager::getInstance().getAsciiArtHeight(AnimationManager::getInstance().getAsciiArtLarge()) + static_cast(commands.size()) * 5; + + int spaceBetween = (COLS - maxWidth * static_cast(commands.size())) / (static_cast(commands.size()) + 1); + int totalCommandsWidth = maxWidth * static_cast(commands.size()) + spaceBetween * (static_cast(commands.size()) - 1); + + // Si no hay suficiente espacio horizontal para el menú vertical, usa el menú de texto vertical + if (COLS < totalCommandsWidth) { + drawVerticalTextMenu(commands, highlight); + } else if (LINES < totalHeight) { + // Si no hay suficiente espacio vertical para el menú vertical, usa el menú horizontal + if (LINES < AnimationManager::getInstance().getAsciiArtHeight(AnimationManager::getInstance().getAsciiArtLarge()) + 10) { + drawHorizontalTextMenu(commands, highlight); + } else { + drawHorizontalMenu(commands, highlight); + } + } else { + drawVerticalMenu(commands, highlight); + } +} + +void MenuDrawer::drawVerticalTextMenu(const std::vector>& commands, int highlight) const { + clear(); + bkgd(COLOR_PAIR(1)); + AnimationManager::getInstance().drawStaticBorder(); + + mvprintw(0, (COLS - static_cast(AnimationManager::getInstance().getAsciiArtText().size())) / 2, AnimationManager::getInstance().getAsciiArtText().c_str()); + int y = 2; + for (size_t i = 0; i < commands.size(); ++i) { + if (static_cast(i) == highlight) { + attron(COLOR_PAIR(5)); + } else { + attron(COLOR_PAIR(4)); + } + mvprintw(y++, (COLS - static_cast(commands[i]->getText().size())) / 2, commands[i]->getText().c_str()); + if (static_cast(i) == highlight) { + attroff(COLOR_PAIR(5)); + } else { + attroff(COLOR_PAIR(4)); + } + } + // Mover el cursor a la última letra de la opción resaltada + move(y - 1, (COLS + static_cast(commands[highlight]->getText().size())) / 2 - 1); + refresh(); +} + +void MenuDrawer::drawHorizontalTextMenu(const std::vector>& commands, int highlight) const { + clear(); + bkgd(COLOR_PAIR(1)); + AnimationManager::getInstance().drawStaticBorder(); + + mvprintw(0, (COLS - static_cast(AnimationManager::getInstance().getAsciiArtText().size())) / 2, AnimationManager::getInstance().getAsciiArtText().c_str()); + int y = 2; + int totalWidth = 0; + int maxWidth = 0; + for (const auto& command : commands) { + int commandWidth = static_cast(command->getText().size()); + maxWidth = std::max(maxWidth, commandWidth); + } + maxWidth += 6; // Espacio para los bordes y el espacio entre opciones + totalWidth = maxWidth * static_cast(commands.size()); + + int x = (COLS - totalWidth) / 2; + for (size_t i = 0; i < commands.size(); ++i) { + if (static_cast(i) == highlight) { + attron(COLOR_PAIR(5)); + } else { + attron(COLOR_PAIR(4)); + } + mvprintw(y, x, commands[i]->getText().c_str()); + x += maxWidth; + if (static_cast(i) == highlight) { + attroff(COLOR_PAIR(5)); + } else { + attroff(COLOR_PAIR(4)); + } + } + // Mover el cursor a la última letra de la opción resaltada + move(y, x - 5); + refresh(); +} + +void MenuDrawer::drawVerticalMenu(const std::vector>& commands, int highlight) const { + AnimationManager::getInstance().drawStaticAsciiArt(); + int maxWidth = 0; + for (const auto& command : commands) { + maxWidth = std::max(maxWidth, static_cast(command->getText().size())); + } + maxWidth += 6; // Espacio para los bordes y el espacio entre opciones + + int menuHeight = static_cast(commands.size()) * 5; + int y_offset = AnimationManager::getInstance().getAsciiArtHeight(AnimationManager::getInstance().getAsciiArtLarge()) + 1; + int y = (LINES - (menuHeight + y_offset)) / 2 + y_offset; + int spaceBetween = std::max(0, (LINES - y - menuHeight) / (static_cast(commands.size()) - 1)); + + // Ajustar y para que el menú comience una distancia spaceBetween más arriba + y -= spaceBetween; + + for (size_t i = 0; i < commands.size(); ++i) { + drawOptionBox(y + static_cast(i) * (5 + spaceBetween), (COLS - maxWidth) / 2, commands[i]->getText(), static_cast(i) == highlight, maxWidth); + } + + int padding = (maxWidth - static_cast(commands[highlight]->getText().size()) - 2) / 2; + move(y + highlight * (5 + spaceBetween) + 1, (COLS - maxWidth) / 2 + padding + static_cast(commands[highlight]->getText().size()) - 1 + 1); + + refresh(); +} + +void MenuDrawer::drawHorizontalMenu(const std::vector>& commands, int highlight) const { + AnimationManager::getInstance().drawStaticAsciiArt(); + int maxWidth = 0; + for (const auto& command : commands) { + maxWidth = std::max(maxWidth, static_cast(command->getText().size())); + } + maxWidth += 6; // Espacio para los bordes y el espacio entre opciones + + int spaceBetween = (COLS - maxWidth * static_cast(commands.size())) / (static_cast(commands.size()) + 1); + int totalCommandsWidth = maxWidth * static_cast(commands.size()) + spaceBetween * (static_cast(commands.size()) - 1); + + int y_offset = AnimationManager::getInstance().getAsciiArtHeight(AnimationManager::getInstance().getAsciiArtLarge()) + 1; // Asegurarse de no superponer el logo + int y = y_offset + (LINES - y_offset - 5) / 2; + int totalCommandsHeight = 5; + + // Calcular la posición inicial x + int x = (COLS - totalCommandsWidth) / 2; + + for (size_t i = 0; i < commands.size(); ++i) { + drawOptionBox(y, x + static_cast(i) * (maxWidth + spaceBetween), commands[i]->getText(), static_cast(i) == highlight, maxWidth); + } + + int padding = (maxWidth - static_cast(commands[highlight]->getText().size()) - 2) / 2; + move(y + 1, x + highlight * (maxWidth + spaceBetween) + padding + static_cast(commands[highlight]->getText().size()) - 1 + 1); + + refresh(); +} + +void MenuDrawer::drawOptionBox(int y, int x, const std::string& text, bool highlight, int width) const { + int pair = highlight ? 5 : 4; + + int padding = (width - static_cast(text.size()) - 2) / 2; + + attron(COLOR_PAIR(pair)); // Usar color adecuado para la opción (resaltada o no) + mvprintw(y, x, "+%s+", std::string(width - 2, '-').c_str()); + mvprintw(y + 1, x, "|%s%s%s|", std::string(padding, ' ').c_str(), text.c_str(), std::string(width - padding - static_cast(text.size()) - 2, ' ').c_str()); + mvprintw(y + 2, x, "+%s+", std::string(width - 2, '-').c_str()); + attroff(COLOR_PAIR(pair)); + + refresh(); +} diff --git a/src/interface/Drawer/MenuDrawer.h b/src/interface/Drawer/MenuDrawer.h new file mode 100644 index 0000000..2285116 --- /dev/null +++ b/src/interface/Drawer/MenuDrawer.h @@ -0,0 +1,26 @@ +#ifndef MENUDRAWER_H +#define MENUDRAWER_H + +#include +#include +#include "../Command/Command.h" +#include "../Animation/AnimationManager.h" + +class Menu; // Declaración adelantada de la clase Menu + +class MenuDrawer { +public: + MenuDrawer(const Menu& menu) : menu(menu) {} + void drawMenu(const std::vector>& commands, int highlight) const; + +private: + const Menu& menu; + + void drawVerticalTextMenu(const std::vector>& commands, int highlight) const; + void drawHorizontalTextMenu(const std::vector>& commands, int highlight) const; + void drawVerticalMenu(const std::vector>& commands, int highlight) const; + void drawHorizontalMenu(const std::vector>& commands, int highlight) const; + void drawOptionBox(int y, int x, const std::string& text, bool highlight, int width) const; +}; + +#endif // MENUDRAWER_H diff --git a/src/interface/Menu/Memento.h b/src/interface/Menu/Memento.h index 466990d..93a74d1 100644 --- a/src/interface/Menu/Memento.h +++ b/src/interface/Menu/Memento.h @@ -8,14 +8,24 @@ class Memento { friend class Menu; // Agregar la clase Menu como amiga public: - Memento(std::vector> state) : state_(std::move(state)) {} + Memento(int highlight, std::vector>&& commands) + : highlight_(highlight), commands_(std::move(commands)) {} private: - std::vector> getState() { - return std::move(state_); + int getHighlight() const { + return highlight_; } - std::vector> state_; + const std::vector>& getCommands() const { + return commands_; + } + + std::vector> releaseCommands() { + return std::move(commands_); + } + + int highlight_; + std::vector> commands_; }; #endif // MEMENTO_H diff --git a/src/interface/Menu/Menu.cpp b/src/interface/Menu/Menu.cpp index 23fc10e..7ec734d 100644 --- a/src/interface/Menu/Menu.cpp +++ b/src/interface/Menu/Menu.cpp @@ -1,22 +1,18 @@ #include "Menu.h" -#include "Animation.h" +#include "AnimationManager.h" #include -#include -#include -#include -#include #include Menu Menu::instance; bool Menu::firstTime = true; -Menu::Menu() : highlight(0) { +Menu::Menu() : highlight(0), isVertical(false), menuDrawer(*this) { initscr(); start_color(); // Inicializa el uso de colores init_pair(1, COLOR_WHITE, COLOR_BLACK); // Fondo negro, texto blanco init_pair(2, COLOR_MAGENTA, COLOR_BLACK); // Texto morado para la animacion - init_pair(3, COLOR_CYAN, COLOR_BLACK); // Texto celeste despues de la animacion + init_pair(3, COLOR_CYAN, COLOR_BLACK); // Texto celeste después de la animacion init_pair(4, COLOR_GREEN, COLOR_BLACK); // Texto verde brillante para opciones init_pair(5, COLOR_BLACK, COLOR_WHITE); // Fondo blanco, texto negro para seleccion init_pair(6, COLOR_MAGENTA, COLOR_BLACK); // Texto morado para el borde @@ -44,10 +40,9 @@ Menu& Menu::getInstance() { } [[noreturn]] void Menu::run() { - if (firstTime) { - Animation::drawBorderSnail(); - Animation::drawAsciiArt(); + AnimationManager::getInstance().drawBorderSnail(); + AnimationManager::getInstance().drawAdaptiveAsciiArt(); firstTime = false; } @@ -57,7 +52,7 @@ Menu& Menu::getInstance() { mainCommands.push_back(std::make_unique()); setCommands(std::move(mainCommands)); - highlight = static_cast(commands.size()) - 1; // Resaltar la última opción al iniciar + highlight = 0; while (true) { endwin(); @@ -79,58 +74,19 @@ void Menu::saveState() { for (auto& command : commands) { stateCopy.push_back(command->clone()); } - history.push(Memento(std::move(stateCopy))); + history.push(Memento(highlight, std::move(stateCopy))); } void Menu::restoreState() { if (!history.empty()) { - commands = history.top().getState(); + commands = history.top().releaseCommands(); + highlight = history.top().getHighlight(); history.pop(); } - highlight = static_cast(commands.size()) - 1; // Seleccionar la última opción por defecto } void Menu::drawMenu(int highlight) const { - clear(); - bkgd(COLOR_PAIR(1)); - - Animation::drawStaticBorder(); - if (firstTime) { - Animation::drawAsciiArt(); - } else { - Animation::drawStaticAsciiArt(); - } - - int maxWidth = 0; - for (const auto& command : commands) { - maxWidth = std::max(maxWidth, static_cast(command->getText().size())); - } - maxWidth += 4; // Espacio para los bordes - - int menuHeight = static_cast(commands.size()) * 4; - int y = (LINES - (menuHeight + Animation::n_lines)) / 2 + Animation::n_lines; // Centrar el menú verticalmente teniendo en cuenta el alto del logo - - for (size_t i = 0; i < commands.size(); ++i) { - drawOptionBox(y + static_cast(i) * 4, (COLS - maxWidth) / 2, commands[i]->getText(), static_cast(i) == highlight, maxWidth); - } - - // Mover el cursor a la última letra de la opción resaltada, desplazado una posición hacia la derecha - int padding = (maxWidth - static_cast(commands[highlight]->getText().size()) - 2) / 2; - move(y + highlight * 4 + 1, (COLS - maxWidth) / 2 + padding + static_cast(commands[highlight]->getText().size()) - 1 + 1); - - refresh(); -} - -void Menu::drawOptionBox(int y, int x, const std::string& text, bool highlight, int width) const { - int pair = highlight ? 5 : 4; - - int padding = (width - static_cast(text.size()) - 2) / 2; - - attron(COLOR_PAIR(pair)); // Usar color adecuado para la opción (resaltada o no) - mvprintw(y, x, "+%s+", std::string(width - 2, '-').c_str()); - mvprintw(y + 1, x, "|%s%s%s|", std::string(padding, ' ').c_str(), text.c_str(), std::string(width - text.size() - padding - 2, ' ').c_str()); - mvprintw(y + 2, x, "+%s+", std::string(width - 2, '-').c_str()); - attroff(COLOR_PAIR(pair)); + menuDrawer.drawMenu(commands, highlight); // Utiliza la clase MenuDrawer para dibujar el menú } void Menu::processInput(int& choice) { diff --git a/src/interface/Menu/Menu.h b/src/interface/Menu/Menu.h index c1c19e1..dc32db4 100644 --- a/src/interface/Menu/Menu.h +++ b/src/interface/Menu/Menu.h @@ -6,8 +6,8 @@ #include #include "Command.h" #include "Memento.h" -#include "Animation.h" -#include +#include "AnimationManager.h" +#include "../Drawer/MenuDrawer.h" #include class Menu { @@ -25,7 +25,6 @@ class Menu { void saveState(); void restoreState(); void drawMenu(int highlight) const; - void drawOptionBox(int y, int x, const std::string& text, bool highlight, int width) const; void processInput(int& choice); static Menu instance; @@ -33,8 +32,11 @@ class Menu { std::vector> commands; std::stack history; int highlight; + mutable bool isVertical; // Variable para almacenar la disposición del menú - friend ReturnOption; + MenuDrawer menuDrawer; // Instancia de MenuDrawer + + friend class ReturnOption; // Asegúrate de que ReturnOption pueda acceder a los métodos privados de Menu }; #endif // MENU_H From 349b48f2685b516c0f66425343326dab805c5d31 Mon Sep 17 00:00:00 2001 From: JFpro160 Date: Mon, 15 Jul 2024 13:56:52 -0500 Subject: [PATCH 14/15] ChavezNet 4.0 FINALLY GOD JIJIJIJA POMNI DOOM --- src/interface/Animation/AnimationManager.cpp | 88 +++++++--- src/interface/Animation/AnimationManager.h | 12 +- src/interface/Command/Command.cpp | 173 ++++++++++++++----- src/interface/Command/Command.h | 90 ++++++---- src/interface/Drawer/MenuDrawer.cpp | 102 +++++++---- src/interface/Menu/Menu.cpp | 7 +- 6 files changed, 338 insertions(+), 134 deletions(-) diff --git a/src/interface/Animation/AnimationManager.cpp b/src/interface/Animation/AnimationManager.cpp index b2d02bd..fe90930 100644 --- a/src/interface/Animation/AnimationManager.cpp +++ b/src/interface/Animation/AnimationManager.cpp @@ -36,7 +36,9 @@ const std::vector AnimationManager::ascii_art_small = { " " }; -const std::string AnimationManager::ascii_art_text = "ChavezNet"; +const std::vector AnimationManager::ascii_art_text = { + "ChavezNet" +}; AnimationManager& AnimationManager::getInstance() { static AnimationManager instance; @@ -47,6 +49,11 @@ int AnimationManager::getAsciiArtHeight(const std::vector& asciiArt return static_cast(asciiArt.size()); } +int AnimationManager::getAsciiArtWidth(const std::vector& asciiArt) const { + if (asciiArt.empty()) return 0; + return static_cast(asciiArt[0].size()); +} + const std::vector& AnimationManager::getAsciiArtLarge() const { return ascii_art_large; } @@ -59,7 +66,7 @@ const std::vector& AnimationManager::getAsciiArtSmall() const { return ascii_art_small; } -const std::string& AnimationManager::getAsciiArtText() const { +const std::vector& AnimationManager::getAsciiArtText() const { return ascii_art_text; } @@ -86,46 +93,85 @@ void AnimationManager::handleResizeDuringAnimation(const std::function& signal(SIGWINCH, old_handler); } -void AnimationManager::drawStaticAsciiArt() const { - const std::vector* ascii_art; - if (LINES < 12 || COLS < 60) { - ascii_art = &ascii_art_small; - } else if (LINES < 16 || COLS < 80) { - ascii_art = &ascii_art_medium; - } else { - ascii_art = &ascii_art_large; +void AnimationManager::drawStaticAsciiArtLarge() const { + const std::vector& ascii_art = ascii_art_large; + attron(COLOR_PAIR(3) | A_BOLD); // Color celeste después de la animación + for (int i = 0; i < static_cast(ascii_art.size()); ++i) { + mvprintw(i + 1, (COLS - static_cast(ascii_art.at(0).size())) / 2, ascii_art.at(i).c_str()); + } + attroff(COLOR_PAIR(3) | A_BOLD); + refresh(); +} + +void AnimationManager::drawStaticAsciiArtMedium() const { + const std::vector& ascii_art = ascii_art_medium; + attron(COLOR_PAIR(3) | A_BOLD); // Color celeste después de la animación + for (int i = 0; i < static_cast(ascii_art.size()); ++i) { + mvprintw(i + 1, (COLS - static_cast(ascii_art.at(0).size())) / 2, ascii_art.at(i).c_str()); + } + attroff(COLOR_PAIR(3) | A_BOLD); + refresh(); +} + +void AnimationManager::drawStaticAsciiArtSmall() const { + const std::vector& ascii_art = ascii_art_small; + attron(COLOR_PAIR(3) | A_BOLD); // Color celeste después de la animación + for (int i = 0; i < static_cast(ascii_art.size()); ++i) { + mvprintw(i + 1, (COLS - static_cast(ascii_art.at(0).size())) / 2, ascii_art.at(i).c_str()); } + attroff(COLOR_PAIR(3) | A_BOLD); + refresh(); +} +void AnimationManager::drawStaticAsciiArtText() const { + const std::vector& ascii_art = ascii_art_text; attron(COLOR_PAIR(3) | A_BOLD); // Color celeste después de la animación - for (int i = 0; i < static_cast(ascii_art->size()); ++i) { - mvprintw(i + 1, (COLS - static_cast(ascii_art->at(0).size())) / 2, ascii_art->at(i).c_str()); + for (int i = 0; i < static_cast(ascii_art.size()); ++ i) { + mvprintw(i + 1, (COLS - static_cast(ascii_art.at(0).size())) / 2, ascii_art.at(i).c_str()); } attroff(COLOR_PAIR(3) | A_BOLD); refresh(); } -void AnimationManager::drawAdaptiveAsciiArt() const { +void AnimationManager::drawStaticAsciiArt() const { + if (LINES <= getAsciiArtHeight(ascii_art_small) || COLS <= getAsciiArtWidth(ascii_art_small)) { + drawStaticAsciiArtText(); + } else if (LINES <= getAsciiArtHeight(ascii_art_medium) || COLS <= getAsciiArtWidth(ascii_art_medium)) { + drawStaticAsciiArtSmall(); + } else if (LINES <= getAsciiArtHeight(ascii_art_large) || COLS <= getAsciiArtWidth(ascii_art_large)) { + drawStaticAsciiArtMedium(); + } else { + drawStaticAsciiArtLarge(); + } +} + +void AnimationManager::drawAdaptiveAsciiArtAnimation() const { handleResizeDuringAnimation([]() { attron(COLOR_PAIR(2) | A_BOLD); // Color morado durante la animación const std::vector* ascii_art; - if (LINES < 12 || COLS < 60) { - ascii_art = &AnimationManager::getInstance().ascii_art_small; - } else if (LINES < 16 || COLS < 80) { - ascii_art = &AnimationManager::getInstance().ascii_art_medium; + if (LINES <= getInstance().getAsciiArtHeight(ascii_art_small) || + COLS <= getInstance().getAsciiArtWidth(ascii_art_small)) { + ascii_art = &ascii_art_text; + } else if (LINES <= getInstance().getAsciiArtHeight(ascii_art_medium) || + COLS <= getInstance().getAsciiArtWidth(ascii_art_medium)) { + ascii_art = &ascii_art_small; + } else if (LINES <= getInstance().getAsciiArtHeight(ascii_art_large) || + COLS <= getInstance().getAsciiArtWidth(ascii_art_large)) { + ascii_art = &ascii_art_medium; } else { - ascii_art = &AnimationManager::getInstance().ascii_art_large; + ascii_art = &ascii_art_large; } for (int i = 0; i < static_cast(ascii_art->size()); ++i) { - if (AnimationManager::resized) return; + if (resized) return; mvprintw(i + 1, (COLS - static_cast(ascii_art->at(0).size())) / 2, ascii_art->at(i).c_str()); refresh(); std::this_thread::sleep_for(std::chrono::milliseconds(100)); // Pausa de 100ms para animación } attroff(COLOR_PAIR(2) | A_BOLD); - AnimationManager::getInstance().drawStaticAsciiArt(); + getInstance().drawStaticAsciiArt(); }); } @@ -207,7 +253,7 @@ void AnimationManager::drawBorderSnail() const { } if (x_start <= x_end) { - for (int i = y_end; i >= y_start; -- i) { + for (int i = y_end; i >= y_start; --i) { if (AnimationManager::resized) return; mvprintw(i, x_start, "|"); move(i, x_start); // Mover el cursor durante la animación diff --git a/src/interface/Animation/AnimationManager.h b/src/interface/Animation/AnimationManager.h index 8a154df..be939c3 100644 --- a/src/interface/Animation/AnimationManager.h +++ b/src/interface/Animation/AnimationManager.h @@ -14,14 +14,18 @@ class AnimationManager { static AnimationManager& getInstance(); void drawStaticBorder() const; void drawStaticAsciiArt() const; - void drawAdaptiveAsciiArt() const; + void drawStaticAsciiArtLarge() const; + void drawStaticAsciiArtMedium() const; + void drawStaticAsciiArtSmall() const; + void drawStaticAsciiArtText() const; + void drawAdaptiveAsciiArtAnimation() const; void drawBorderSnail() const; - void drawAsciiArt() const; const std::vector& getAsciiArtLarge() const; const std::vector& getAsciiArtMedium() const; const std::vector& getAsciiArtSmall() const; - const std::string& getAsciiArtText() const; + const std::vector& getAsciiArtText() const; + int getAsciiArtWidth(const std::vector& asciiArt) const; int getAsciiArtHeight(const std::vector& asciiArt) const; friend void resizeHandler(int); @@ -33,7 +37,7 @@ class AnimationManager { static const std::vector ascii_art_large; static const std::vector ascii_art_medium; static const std::vector ascii_art_small; - static const std::string ascii_art_text; + static const std::vector ascii_art_text; static volatile sig_atomic_t resized; static std::function current_animation_func; diff --git a/src/interface/Command/Command.cpp b/src/interface/Command/Command.cpp index cf19388..0a1f0a1 100644 --- a/src/interface/Command/Command.cpp +++ b/src/interface/Command/Command.cpp @@ -1,77 +1,168 @@ #include "Command.h" #include "Menu.h" +#include +#include +//#include linux +//#include -// Implementaciones de Option1 -void Option1::execute() { +// Implementaciones de SearchOption +void SearchOption::execute() { std::vector> commands; - commands.push_back(std::make_unique()); - commands.push_back(std::make_unique()); - commands.push_back(std::make_unique()); + commands.push_back(std::make_unique()); + commands.push_back(std::make_unique()); + commands.push_back(std::make_unique()); commands.push_back(std::make_unique()); Menu::getInstance().setCommands(std::move(commands)); } -// Implementaciones de Option2 -void Option2::execute() { +// Implementaciones de CheckBookmarksOption +void CheckBookmarksOption::execute() { std::vector> commands; - commands.push_back(std::make_unique()); - commands.push_back(std::make_unique()); + commands.push_back(std::make_unique()); + commands.push_back(std::make_unique()); commands.push_back(std::make_unique()); Menu::getInstance().setCommands(std::move(commands)); } -// Implementaciones de ExitOption -void ExitOption::execute() { - endwin(); - exit(0); -} - -// Implementaciones de SubOption1 -void SubOption1::execute() { +// Implementaciones de SeeMoreOption +void SeeMoreOption::execute() { std::vector> commands; - commands.push_back(std::make_unique()); - commands.push_back(std::make_unique()); - commands.push_back(std::make_unique()); + commands.push_back(std::make_unique()); + commands.push_back(std::make_unique()); commands.push_back(std::make_unique()); Menu::getInstance().setCommands(std::move(commands)); } -// Implementaciones de SubOption2 -void SubOption2::execute() { - // Define actions for SubOption2 +// Implementaciones de ExitOption +void ExitOption::execute() { + std::cout << "Exiting application..." << std::endl; + exit(0); } -// Implementaciones de SubOption3 -void SubOption3::execute() { - // Define actions for SubOption3 +// Implementaciones de SearchByTagsSubOption +void SearchByTagsSubOption::execute() { + std::cout << "Executing Search by Tags" << std::endl; } -// Implementaciones de SubOption4 -void SubOption4::execute() { - // Define actions for SubOption4 +// Implementaciones de SearchByNameSubOption +void SearchByNameSubOption::execute() { + std::cout << "Executing Search by Name" << std::endl; } -// Implementaciones de SubOption5 -void SubOption5::execute() { - // Define actions for SubOption5 +// Implementaciones de SearchBySynopsisSubOption +void SearchBySynopsisSubOption::execute() { + std::cout << "Executing Search by Synopsis" << std::endl; } -// Implementaciones de SubSubOption1 -void SubSubOption1::execute() { - // Define actions for SubSubOption1 +// Implementaciones de WatchLaterOption +void WatchLaterOption::execute() { + std::cout << "Executing Watch Later Option" << std::endl; } -// Implementaciones de SubSubOption2 -void SubSubOption2::execute() { - // Define actions for SubSubOption2 +// Implementaciones de FavoritesOption +void FavoritesOption::execute() { + std::cout << "Executing Favorites Option" << std::endl; } -// Implementaciones de SubSubOption5 -void SubSubOption5::execute() { - // Define actions for SubSubOption5 +// Implementaciones de WhatIsChavezNetOption +void WhatIsChavezNetOption::execute() { + std::cout << "Executing What is ChavezNet Option" << std::endl; } // Implementaciones de ReturnOption void ReturnOption::execute() { Menu::getInstance().restoreState(); } + +// Implementaciones de ConfirmOption +void ConfirmOption::execute() { + std::cout << "Confirming selection." << std::endl; +} + +// Implementaciones de DevModeOption +void DevModeOption::execute() { + std::cout << "Attempting to engage DevMode" << std::endl; + if (authenticate()) { + std::cout << "Authentication successful!" << std::endl; + displayDebugInfo(); + showResourceUsage(); + + std::vector> commands; + commands.push_back(std::make_unique()); + commands.push_back(std::make_unique()); + Menu::getInstance().setCommands(std::move(commands)); + } else { + std::cout << "Authentication failed!" << std::endl; + } +} + +bool DevModeOption::authenticate() { + std::string password; + std::cout << "Enter password to access DevMode: "; + std::cin >> password; + return password == "devpass"; // Replace "devpass" with your secure password +} + +void DevModeOption::displayDebugInfo() { + std::cout << "\n--- Debugging Information ---" << std::endl; + std::cout << "Application Version: 1.0.0" << std::endl; + std::cout << "Build Time: " << __DATE__ << " " << __TIME__ << std::endl; + std::cout << "Running on: " << std::this_thread::get_id() << std::endl; + std::cout << "Engine F.O.R.C.E. by DynamicProjects." << std::endl; + // Add more debugging information as needed +} + +void DevModeOption::showResourceUsage() { + std::cout << "\n--- Resource Usage ---" << std::endl; +// std::cout << "CPU Usage: " << getCPUUsage() << "%" << std::endl; +// std::cout << "Memory Usage: " << getMemoryUsage() << "%" << std::endl; + std::cout << "Disk I/O: 1.2MB/s" << std::endl; // Dummy data for disk I/O + // Add real resource usage metrics if available +} + +// long CompareFileTime(FILETIME time1, FILETIME time2) { +// ULARGE_INTEGER a, b; +// a.LowPart = time1.dwLowDateTime; +// a.HighPart = time1.dwHighDateTime; + +// b.LowPart = time2.dwLowDateTime; +// b.HighPart = time2.dwHighDateTime; + +// return b.QuadPart - a.QuadPart; +//} + +float getCPUUsage() { +// static FILETIME prevSysIdle, prevSysKernel, prevSysUser; +// FILETIME sysIdle, sysKernel, sysUser; + +// if (!GetSystemTimes(&sysIdle, &sysKernel, &sysUser)) { + return -1.0f; // Error + } + +// if (prevSysIdle.dwLowDateTime != 0 && prevSysKernel.dwLowDateTime != 0 && prevSysUser.dwLowDateTime != 0) { +// auto diffSysIdle = CompareFileTime(prevSysIdle, sysIdle); +// auto diffSysKernel = CompareFileTime(prevSysKernel, sysKernel); +// auto diffSysUser = CompareFileTime(prevSysUser, sysUser); + +// auto totalSys = diffSysKernel + diffSysUser; +// return (totalSys - diffSysIdle) * 100.0f / totalSys; +// } + +// prevSysIdle = sysIdle; +// prevSysKernel = sysKernel; +// prevSysUser = sysUser; + +// return -1.0f; // First call +//} + +float getMemoryUsage() { +// MEMORYSTATUSEX memInfo; +// memInfo.dwLength = sizeof(MEMORYSTATUSEX); +// GlobalMemoryStatusEx(&memInfo); + +// DWORDLONG totalPhysMem = memInfo.ullTotalPhys; +// DWORDLONG physMemUsed = memInfo.ullTotalPhys - memInfo.ullAvailPhys; + +// return physMemUsed / (float)totalPhysMem * 100.0f; + return 0.0f; // Dummy data +} diff --git a/src/interface/Command/Command.h b/src/interface/Command/Command.h index ac163cf..443ba40 100644 --- a/src/interface/Command/Command.h +++ b/src/interface/Command/Command.h @@ -3,6 +3,8 @@ #include #include +#include +#include // For sleep class Command { public: @@ -12,88 +14,106 @@ class Command { virtual std::unique_ptr clone() const = 0; }; -class Option1 : public Command { +// Primary options +class SearchOption : public Command { public: void execute() override; - std::string getText() const override { return "Option 1"; } - std::unique_ptr clone() const override { return std::make_unique(*this); } + [[nodiscard]] std::string getText() const override { return "Search"; } + [[nodiscard]] std::unique_ptr clone() const override { return std::make_unique(*this); } }; -class Option2 : public Command { +class CheckBookmarksOption : public Command { public: void execute() override; - std::string getText() const override { return "Option 2"; } - std::unique_ptr clone() const override { return std::make_unique(*this); } + [[nodiscard]] std::string getText() const override { return "Check bookmarks"; } + [[nodiscard]] std::unique_ptr clone() const override { return std::make_unique(*this); } +}; + +class SeeMoreOption : public Command { +public: + void execute() override; + [[nodiscard]] std::string getText() const override { return "See more..."; } + [[nodiscard]] std::unique_ptr clone() const override { return std::make_unique(*this); } }; class ExitOption : public Command { public: void execute() override; - std::string getText() const override { return "Exit"; } - std::unique_ptr clone() const override { return std::make_unique(*this); } + [[nodiscard]] std::string getText() const override { return "Exit"; } + [[nodiscard]] std::unique_ptr clone() const override { return std::make_unique(*this); } }; -class SubOption1 : public Command { +// SubOptions for SearchOption +class SearchByTagsSubOption : public Command { public: void execute() override; - std::string getText() const override { return "SubOption 1"; } - std::unique_ptr clone() const override { return std::make_unique(*this); } + [[nodiscard]] std::string getText() const override { return "Search by Tags"; } + [[nodiscard]] std::unique_ptr clone() const override { return std::make_unique(*this); } }; -class SubOption2 : public Command { +class SearchByNameSubOption : public Command { public: void execute() override; - std::string getText() const override { return "SubOption 2"; } - std::unique_ptr clone() const override { return std::make_unique(*this); } + [[nodiscard]] std::string getText() const override { return "Search by Name"; } + [[nodiscard]] std::unique_ptr clone() const override { return std::make_unique(*this); } }; -class SubOption3 : public Command { +class SearchBySynopsisSubOption : public Command { public: void execute() override; - std::string getText() const override { return "SubOption 3"; } - std::unique_ptr clone() const override { return std::make_unique(*this); } + [[nodiscard]] std::string getText() const override { return "Search by Synopsis"; } + [[nodiscard]] std::unique_ptr clone() const override { return std::make_unique(*this); } }; -class SubOption4 : public Command { +// SubOptions for CheckBookmarksOption +class WatchLaterOption : public Command { public: void execute() override; - std::string getText() const override { return "SubOption 4"; } - std::unique_ptr clone() const override { return std::make_unique(*this); } + [[nodiscard]] std::string getText() const override { return "Watch Later list"; } + [[nodiscard]] std::unique_ptr clone() const override { return std::make_unique(*this); } }; -class SubOption5 : public Command { +class FavoritesOption : public Command { public: void execute() override; - std::string getText() const override { return "SubOption 5"; } - std::unique_ptr clone() const override { return std::make_unique(*this); } + [[nodiscard]] std::string getText() const override { return "Favorites list"; } + [[nodiscard]] std::unique_ptr clone() const override { return std::make_unique(*this); } }; -class SubSubOption1 : public Command { +class WhatIsChavezNetOption : public Command { public: void execute() override; - std::string getText() const override { return "SubSubOption 1"; } - std::unique_ptr clone() const override { return std::make_unique(*this); } + [[nodiscard]] std::string getText() const override { return "What is ChavezNet?"; } + [[nodiscard]] std::unique_ptr clone() const override { return std::make_unique(*this); } }; -class SubSubOption2 : public Command { +// Return options for submenus +class ReturnOption : public Command { public: void execute() override; - std::string getText() const override { return "SubSubOption 2"; } - std::unique_ptr clone() const override { return std::make_unique(*this); } + [[nodiscard]] std::string getText() const override { return "Return"; } + [[nodiscard]] std::unique_ptr clone() const override { return std::make_unique(*this); } }; -class SubSubOption5 : public Command { +// Confirm option for general usage +class ConfirmOption : public Command { public: void execute() override; - std::string getText() const override { return "SubSubOption 5"; } - std::unique_ptr clone() const override { return std::make_unique(*this); } + [[nodiscard]] std::string getText() const override { return "Confirm"; } + [[nodiscard]] std::unique_ptr clone() const override { return std::make_unique(*this); } }; -class ReturnOption : public Command { +// Option for the DevMode engage +class DevModeOption : public Command { public: void execute() override; - std::string getText() const override { return "Return"; } - std::unique_ptr clone() const override { return std::make_unique(*this); } + [[nodiscard]] std::string getText() const override { return "Engage DevMode"; } + [[nodiscard]] std::unique_ptr clone() const override { return std::make_unique(*this); } + +private: + static bool authenticate(); + void displayDebugInfo(); + void showResourceUsage(); }; #endif // COMMAND_H diff --git a/src/interface/Drawer/MenuDrawer.cpp b/src/interface/Drawer/MenuDrawer.cpp index 30b776d..8823101 100644 --- a/src/interface/Drawer/MenuDrawer.cpp +++ b/src/interface/Drawer/MenuDrawer.cpp @@ -2,34 +2,47 @@ #include "ncurses.h" #include "AnimationManager.h" +const int BORDER_PADDING = 2; // Un borde a cada lado +const int ADDITIONAL_PADDING = 4; // Espacio adicional para presentación + void MenuDrawer::drawMenu(const std::vector>& commands, int highlight) const { clear(); bkgd(COLOR_PAIR(1)); AnimationManager::getInstance().drawStaticBorder(); - AnimationManager::getInstance().drawStaticAsciiArt(); int maxWidth = 0; for (const auto& command : commands) { int commandWidth = static_cast(command->getText().size()); maxWidth = std::max(maxWidth, commandWidth); } - maxWidth += 6; // Espacio para los bordes y el espacio entre opciones + maxWidth += BORDER_PADDING + ADDITIONAL_PADDING; - int totalHeight = AnimationManager::getInstance().getAsciiArtHeight(AnimationManager::getInstance().getAsciiArtLarge()) + static_cast(commands.size()) * 5; + int logoWidthSmall = AnimationManager::getInstance().getAsciiArtWidth(AnimationManager::getInstance().getAsciiArtSmall()); + int logoHeightSmall = AnimationManager::getInstance().getAsciiArtHeight(AnimationManager::getInstance().getAsciiArtSmall()); - int spaceBetween = (COLS - maxWidth * static_cast(commands.size())) / (static_cast(commands.size()) + 1); - int totalCommandsWidth = maxWidth * static_cast(commands.size()) + spaceBetween * (static_cast(commands.size()) - 1); + int commandWidthWithPadding = maxWidth; + int totalHeightVertical = logoHeightSmall + static_cast(commands.size()) * 5; + + int verticalCommandWidth = maxWidth; + int verticalCommandHeight = logoHeightSmall + static_cast(commands.size()) * 3; - // Si no hay suficiente espacio horizontal para el menú vertical, usa el menú de texto vertical - if (COLS < totalCommandsWidth) { + int horizontalCommandWidth = maxWidth; + int spaceBetweenHorizontal = (COLS - horizontalCommandWidth * static_cast(commands.size())) / (static_cast(commands.size()) + 1); + int totalCommandsWidthHorizontal = horizontalCommandWidth * static_cast(commands.size()) + spaceBetweenHorizontal * (static_cast(commands.size()) - 1); + int totalHeightHorizontal = logoHeightSmall + 5; + + if (COLS <= verticalCommandWidth) { drawVerticalTextMenu(commands, highlight); - } else if (LINES < totalHeight) { - // Si no hay suficiente espacio vertical para el menú vertical, usa el menú horizontal - if (LINES < AnimationManager::getInstance().getAsciiArtHeight(AnimationManager::getInstance().getAsciiArtLarge()) + 10) { + } else if (LINES <= totalHeightVertical) { + if (LINES <= totalHeightHorizontal) { drawHorizontalTextMenu(commands, highlight); } else { - drawHorizontalMenu(commands, highlight); + if (COLS <= totalCommandsWidthHorizontal) { + drawVerticalTextMenu(commands, highlight); + } else { + drawHorizontalMenu(commands, highlight); + } } } else { drawVerticalMenu(commands, highlight); @@ -41,23 +54,36 @@ void MenuDrawer::drawVerticalTextMenu(const std::vector bkgd(COLOR_PAIR(1)); AnimationManager::getInstance().drawStaticBorder(); - mvprintw(0, (COLS - static_cast(AnimationManager::getInstance().getAsciiArtText().size())) / 2, AnimationManager::getInstance().getAsciiArtText().c_str()); - int y = 2; + int maxWidth = 0; + for (const auto& command : commands) { + int commandWidth = static_cast(command->getText().size()); + maxWidth = std::max(maxWidth, commandWidth); + } + maxWidth += BORDER_PADDING + ADDITIONAL_PADDING; + + const std::vector& asciiArtText = AnimationManager::getInstance().getAsciiArtText(); + int asciiArtTextWidth = static_cast(asciiArtText[0].size()); + for (int i = 0; i < static_cast(asciiArtText.size()); ++i) { + mvprintw(i, (COLS - asciiArtTextWidth) / 2, asciiArtText[i].c_str()); + } + + int y = static_cast(asciiArtText.size()) + 2; for (size_t i = 0; i < commands.size(); ++i) { + int x = (COLS - static_cast(commands[i]->getText().size())) / 2; if (static_cast(i) == highlight) { attron(COLOR_PAIR(5)); } else { attron(COLOR_PAIR(4)); } - mvprintw(y++, (COLS - static_cast(commands[i]->getText().size())) / 2, commands[i]->getText().c_str()); + mvprintw(y++, x, "%s", commands[i]->getText().c_str()); + if (static_cast(i) == highlight) { attroff(COLOR_PAIR(5)); } else { attroff(COLOR_PAIR(4)); } } - // Mover el cursor a la última letra de la opción resaltada - move(y - 1, (COLS + static_cast(commands[highlight]->getText().size())) / 2 - 1); + move(y - static_cast(commands.size()) + highlight, (COLS - static_cast(commands[highlight]->getText().size())) / 2 + static_cast(commands[highlight]->getText().size()) - 1); refresh(); } @@ -66,25 +92,37 @@ void MenuDrawer::drawHorizontalTextMenu(const std::vector(AnimationManager::getInstance().getAsciiArtText().size())) / 2, AnimationManager::getInstance().getAsciiArtText().c_str()); - int y = 2; + const std::vector& asciiArtText = AnimationManager::getInstance().getAsciiArtText(); + int asciiArtTextWidth = static_cast(asciiArtText[0].size()); + for (int i = 0; i < static_cast(asciiArtText.size()); ++i) { + mvprintw(i, (COLS - asciiArtTextWidth) / 2, asciiArtText[i].c_str()); + } + + int y = static_cast(asciiArtText.size()) + 2; int totalWidth = 0; int maxWidth = 0; + for (const auto& command : commands) { int commandWidth = static_cast(command->getText().size()); maxWidth = std::max(maxWidth, commandWidth); } - maxWidth += 6; // Espacio para los bordes y el espacio entre opciones + maxWidth += BORDER_PADDING + ADDITIONAL_PADDING; totalWidth = maxWidth * static_cast(commands.size()); + if (COLS <= totalWidth) { + drawVerticalTextMenu(commands, highlight); + return; + } + int x = (COLS - totalWidth) / 2; for (size_t i = 0; i < commands.size(); ++i) { + int xCentered = x + (maxWidth - static_cast(commands[i]->getText().size())) / 2; if (static_cast(i) == highlight) { attron(COLOR_PAIR(5)); } else { attron(COLOR_PAIR(4)); } - mvprintw(y, x, commands[i]->getText().c_str()); + mvprintw(y, xCentered, "%s", commands[i]->getText().c_str()); x += maxWidth; if (static_cast(i) == highlight) { attroff(COLOR_PAIR(5)); @@ -92,25 +130,24 @@ void MenuDrawer::drawHorizontalTextMenu(const std::vector(commands.size())) / 2 + highlight * maxWidth + (maxWidth - static_cast(commands[highlight]->getText().size())) / 2 + static_cast(commands[highlight]->getText().size()) - 1); refresh(); } void MenuDrawer::drawVerticalMenu(const std::vector>& commands, int highlight) const { AnimationManager::getInstance().drawStaticAsciiArt(); int maxWidth = 0; + for (const auto& command : commands) { maxWidth = std::max(maxWidth, static_cast(command->getText().size())); } - maxWidth += 6; // Espacio para los bordes y el espacio entre opciones + maxWidth += BORDER_PADDING + ADDITIONAL_PADDING; int menuHeight = static_cast(commands.size()) * 5; int y_offset = AnimationManager::getInstance().getAsciiArtHeight(AnimationManager::getInstance().getAsciiArtLarge()) + 1; int y = (LINES - (menuHeight + y_offset)) / 2 + y_offset; int spaceBetween = std::max(0, (LINES - y - menuHeight) / (static_cast(commands.size()) - 1)); - // Ajustar y para que el menú comience una distancia spaceBetween más arriba y -= spaceBetween; for (size_t i = 0; i < commands.size(); ++i) { @@ -126,20 +163,25 @@ void MenuDrawer::drawVerticalMenu(const std::vector>& c void MenuDrawer::drawHorizontalMenu(const std::vector>& commands, int highlight) const { AnimationManager::getInstance().drawStaticAsciiArt(); int maxWidth = 0; + for (const auto& command : commands) { maxWidth = std::max(maxWidth, static_cast(command->getText().size())); } - maxWidth += 6; // Espacio para los bordes y el espacio entre opciones + maxWidth += BORDER_PADDING + ADDITIONAL_PADDING; int spaceBetween = (COLS - maxWidth * static_cast(commands.size())) / (static_cast(commands.size()) + 1); - int totalCommandsWidth = maxWidth * static_cast(commands.size()) + spaceBetween * (static_cast(commands.size()) - 1); + int totalCommandsWidthHorizontal = maxWidth * static_cast(commands.size()) + spaceBetween * (static_cast(commands.size()) - 1); + + if (COLS <= totalCommandsWidthHorizontal) { + drawVerticalTextMenu(commands, highlight); + return; + } - int y_offset = AnimationManager::getInstance().getAsciiArtHeight(AnimationManager::getInstance().getAsciiArtLarge()) + 1; // Asegurarse de no superponer el logo + int y_offset = AnimationManager::getInstance().getAsciiArtHeight(AnimationManager::getInstance().getAsciiArtLarge()) + 1; int y = y_offset + (LINES - y_offset - 5) / 2; int totalCommandsHeight = 5; - // Calcular la posición inicial x - int x = (COLS - totalCommandsWidth) / 2; + int x = (COLS - totalCommandsWidthHorizontal) / 2; for (size_t i = 0; i < commands.size(); ++i) { drawOptionBox(y, x + static_cast(i) * (maxWidth + spaceBetween), commands[i]->getText(), static_cast(i) == highlight, maxWidth); @@ -156,7 +198,7 @@ void MenuDrawer::drawOptionBox(int y, int x, const std::string& text, bool highl int padding = (width - static_cast(text.size()) - 2) / 2; - attron(COLOR_PAIR(pair)); // Usar color adecuado para la opción (resaltada o no) + attron(COLOR_PAIR(pair)); mvprintw(y, x, "+%s+", std::string(width - 2, '-').c_str()); mvprintw(y + 1, x, "|%s%s%s|", std::string(padding, ' ').c_str(), text.c_str(), std::string(width - padding - static_cast(text.size()) - 2, ' ').c_str()); mvprintw(y + 2, x, "+%s+", std::string(width - 2, '-').c_str()); diff --git a/src/interface/Menu/Menu.cpp b/src/interface/Menu/Menu.cpp index 7ec734d..f91f7f9 100644 --- a/src/interface/Menu/Menu.cpp +++ b/src/interface/Menu/Menu.cpp @@ -42,13 +42,14 @@ Menu& Menu::getInstance() { [[noreturn]] void Menu::run() { if (firstTime) { AnimationManager::getInstance().drawBorderSnail(); - AnimationManager::getInstance().drawAdaptiveAsciiArt(); + AnimationManager::getInstance().drawAdaptiveAsciiArtAnimation(); firstTime = false; } std::vector> mainCommands; - mainCommands.push_back(std::make_unique()); - mainCommands.push_back(std::make_unique()); + mainCommands.push_back(std::make_unique()); + mainCommands.push_back(std::make_unique()); + mainCommands.push_back(std::make_unique()); mainCommands.push_back(std::make_unique()); setCommands(std::move(mainCommands)); From c634fbcf550898ea143e04f7d4b3e02ded291793 Mon Sep 17 00:00:00 2001 From: JFpro160 Date: Mon, 15 Jul 2024 16:08:37 -0500 Subject: [PATCH 15/15] Loading Bar --- src/interface/Animation/AnimationManager.cpp | 36 ++++++++++++++++++++ src/interface/Animation/AnimationManager.h | 3 ++ src/main.cpp | 1 + 3 files changed, 40 insertions(+) diff --git a/src/interface/Animation/AnimationManager.cpp b/src/interface/Animation/AnimationManager.cpp index fe90930..49c419a 100644 --- a/src/interface/Animation/AnimationManager.cpp +++ b/src/interface/Animation/AnimationManager.cpp @@ -2,6 +2,8 @@ volatile sig_atomic_t AnimationManager::resized = 0; std::function AnimationManager::current_animation_func; +float AnimationManager::loading_progress = 0.0f; +int AnimationManager::loading_duration = 0; const std::vector AnimationManager::ascii_art_large = { " _____ _ _ _ _ ", @@ -269,3 +271,37 @@ void AnimationManager::drawBorderSnail() const { attroff(COLOR_PAIR(6)); }); } + +void AnimationManager::drawLoadingBar(int duration) const { + loading_duration = duration; + handleResizeDuringAnimation([]() { + int bar_width = COLS - 4; + int bar_start_x = 2; + int bar_y = LINES / 2; + int steps = 100; + int sleep_duration = (loading_duration * 1000) / steps; + + attron(COLOR_PAIR(3) | A_BOLD); + for (int i = 0; i <= static_cast(loading_progress * steps); ++i) { + if (resized) return; + clear(); + mvprintw(bar_y - 2, (COLS - 10) / 2, "Loading..."); + mvhline(bar_y, bar_start_x, ' ', bar_width); + mvhline(bar_y, bar_start_x, '=', static_cast(loading_progress * bar_width)); + mvprintw(bar_y + 2, (COLS - 20) / 2, "%3d%% Complete", static_cast(loading_progress * 100)); + refresh(); + } + for (int i = static_cast(loading_progress * steps); i <= steps; ++i) { + if (resized) return; + clear(); + mvprintw(bar_y - 2, (COLS - 10) / 2, "Loading..."); + mvhline(bar_y, bar_start_x, ' ', bar_width); + mvhline(bar_y, bar_start_x, '=', static_cast(loading_progress * bar_width)); + mvprintw(bar_y + 2, (COLS - 20) / 2, "%3d%% Complete", static_cast(loading_progress * 100)); + refresh(); + loading_progress = static_cast(i) / steps; + std::this_thread::sleep_for(std::chrono::milliseconds(sleep_duration)); + } + attroff(COLOR_PAIR(3) | A_BOLD); + }); +} \ No newline at end of file diff --git a/src/interface/Animation/AnimationManager.h b/src/interface/Animation/AnimationManager.h index be939c3..ae49f0c 100644 --- a/src/interface/Animation/AnimationManager.h +++ b/src/interface/Animation/AnimationManager.h @@ -20,6 +20,7 @@ class AnimationManager { void drawStaticAsciiArtText() const; void drawAdaptiveAsciiArtAnimation() const; void drawBorderSnail() const; + void drawLoadingBar(int duration) const; // Nueva función para la barra de carga const std::vector& getAsciiArtLarge() const; const std::vector& getAsciiArtMedium() const; @@ -41,6 +42,8 @@ class AnimationManager { static volatile sig_atomic_t resized; static std::function current_animation_func; + static float loading_progress; // Progreso de la barra de carga + static int loading_duration; // Duración de la barra de carga }; #endif // ANIMATIONMANAGER_H diff --git a/src/main.cpp b/src/main.cpp index b60abf5..e976f4c 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,5 +1,6 @@ #include "Menu.h" int main() { + AnimationManager::getInstance().drawLoadingBar(20); Menu::getInstance().run(); }