diff options
Reorganized whole architecture
6 files changed, 326 insertions, 0 deletions
| -rw-r--r-- | src/Generic/ConsoleInterface/Command.cpp | 18 | ||||
| -rw-r--r-- | src/Generic/ConsoleInterface/Command.h | 16 | ||||
| -rw-r--r-- | src/Generic/ConsoleInterface/Menu.cpp | 90 | ||||
| -rw-r--r-- | src/Generic/ConsoleInterface/Menu.h | 27 | ||||
| -rw-r--r-- | src/Generic/ConsoleInterface/Toolbox.cpp | 99 | ||||
| -rw-r--r-- | src/Generic/ConsoleInterface/Toolbox.hpp | 76 |
diff --git a/src/Generic/ConsoleInterface/Command.cpp b/src/Generic/ConsoleInterface/Command.cpp new file mode 100644 index 0000000..d3d058c --- /dev/null +++ b/src/Generic/ConsoleInterface/Command.cpp @@ -0,0 +1,18 @@ +#include "Command.h" +#include <cstring> + +Command::Command() : Command("", nullptr) {} + +Command::Command(const char* nameInMenu, void (*exec)()) { + strcpy(this->nameInMenu, nameInMenu); + this->exec = exec; +} + +void Command::run() const { + if (exec != nullptr) + exec(); +} + +const char* Command::get_nameInMenu() const { + return nameInMenu; +} diff --git a/src/Generic/ConsoleInterface/Command.h b/src/Generic/ConsoleInterface/Command.h new file mode 100644 index 0000000..d00b277 --- /dev/null +++ b/src/Generic/ConsoleInterface/Command.h @@ -0,0 +1,16 @@ +#ifndef HEADER_CONSOLEINTERFACE_COMMAND +#define HEADER_CONSOLEINTERFACE_COMMAND + +class Command { + char nameInMenu[256]; + void (*exec)(); + +public: + Command(); + Command(const char* nameInMenu, void (*exec)()); + void run() const; + + const char* get_nameInMenu() const; +}; + +#endif diff --git a/src/Generic/ConsoleInterface/Menu.cpp b/src/Generic/ConsoleInterface/Menu.cpp new file mode 100644 index 0000000..0b27d48 --- /dev/null +++ b/src/Generic/ConsoleInterface/Menu.cpp @@ -0,0 +1,90 @@ +#include "Menu.h" +#include "Toolbox.hpp" +#include <cstring> + +Menu::Menu() : Menu("Menu", false, false) {} + +Menu::Menu(const char* title, bool backExistsApp, bool isSubMenu) : menuOptions() { + this->backExistsApp = backExistsApp; + this->isSubMenu = isSubMenu; + strcpy(this->title, title); +} + +Menu::Menu(const char* title, bool backExistsApp, bool isSubMenu, const Command* commands, unsigned commandCount) { + this->backExistsApp = backExistsApp; + this->isSubMenu = isSubMenu; + menuOptions = List<Command>(commands, commandCount); + strcpy(this->title, title); +} + +void Menu::addCommand(const Command& command) { + menuOptions.add(command); +} + +enum MessageType { + NoPrint, + Success, + Warning, + Error, +}; +String msg; +MessageType msgType; + +void Menu::registerError(const char* message) const { + msg = message; + msgType = Error; +} + +void Menu::registerWarning(const char* message) const { + msg = message; + msgType = Warning; +} + +void Menu::registerSuccess(const char* message) const { + msg = message; + msgType = Success; +} + +void Menu::navigate() const { + if (menuOptions.get_count() == 0) { + printLine("Menu is empty!"); + return; + } + + unsigned buffer = 1; // We immedeately read the value of buffer, so this is fine + + while (buffer != 0) { + clear(); + if (isSubMenu) + subTitleBox(title); + else + titleBox(title); + + switch(msgType) { + case Error: errorBox(msg.get_cstr()); msgType = NoPrint; break; + case Warning: warningBox(msg.get_cstr()); msgType = NoPrint; break; + case Success: successBox(msg.get_cstr()); msgType = NoPrint; break; + case NoPrint: printLine(""); break; + } + printLine(""); + + resetOrderedList(0); + if (backExistsApp) + printOrderedListElem("Exit"); + else + printOrderedListElem("Go Back"); + + for (unsigned i = 0; i < menuOptions.get_count(); i++) + printOrderedListElem(menuOptions[i].get_nameInMenu()); + + _printInputBoxLabel("Execute No [0-"); + print(menuOptions.get_count()); + print("]: "); + read(buffer); + + if (buffer > menuOptions.get_count()) + registerError("Invalid menu option!"); + else if (buffer > 0) + menuOptions[buffer - 1].run(); + } +} diff --git a/src/Generic/ConsoleInterface/Menu.h b/src/Generic/ConsoleInterface/Menu.h new file mode 100644 index 0000000..2501871 --- /dev/null +++ b/src/Generic/ConsoleInterface/Menu.h @@ -0,0 +1,27 @@ +#ifndef HEADER_CONSOLEINTERFACE_MENU +#define HEADER_CONSOLEINTERFACE_MENU + +#include "Command.h" +#include "../List/List.hpp" + +class Menu { + char title[256]; + List<Command> menuOptions; + + bool backExistsApp; + bool isSubMenu; + +public: + Menu(); + Menu(const char* title, bool backExistsApp, bool isSubMenu); + Menu(const char* title, bool backExistsApp, bool isSubMenu, const Command* commands, unsigned commandCount); + + void addCommand(const Command& command); + + void registerError(const char* message) const; + void registerWarning(const char* message) const; + void registerSuccess(const char* message) const; + void navigate() const; +}; + +#endif diff --git a/src/Generic/ConsoleInterface/Toolbox.cpp b/src/Generic/ConsoleInterface/Toolbox.cpp new file mode 100644 index 0000000..1f2e42c --- /dev/null +++ b/src/Generic/ConsoleInterface/Toolbox.cpp @@ -0,0 +1,99 @@ +#include "Toolbox.hpp" + +void clear() { + // Clears console on Linux + // Source: https://stackoverflow.com/a/52895729/12036073 + std::cout << u8"\033[2J\033[1;1H"; +} + +int orderedListIndex = 1; + +void resetOrderedList(int starter) { + orderedListIndex = starter; +} + +void titleBox(const char* title) { + std::cout << std::endl << "=== " << title << " ===" << std::endl; +} + +void subTitleBox(const char* title) { + std::cout << std::endl << "--- " << title << " ---" << std::endl; +} + +void successBox(const char* message) { + std::cout << "<S> " << message << std::endl; +} + +void warningBox(const char* message) { + std::cout << "<W> " << message << std::endl; +} + +void errorBox(const char* message) { + std::cout << "<E> " << message << std::endl; +} + +void __printTableHeaderNumber(unsigned number) { + std::cout << ":" << ((number < 100) ? " " : "") << number << ((number < 10) ? " " : ""); +} + +void __printTableColumnHeader(unsigned start, unsigned count) { + std::cout << ": "; + for (unsigned i = 0; i < count; i++) + __printTableHeaderNumber(start++); + std::cout << ":" << std::endl; + + for (unsigned i = 0; i <= count; i++) + std::cout << "===="; + std::cout << "=" << std::endl; +} + +void __printTableLine(unsigned columns) { + std::cout << ":==="; + for (unsigned i = 0; i < columns; i++) + std::cout << "+---"; + std::cout << ":" << std::endl; +} + +void table(unsigned startNumber, unsigned columns, const char* items) { + __printTableColumnHeader(startNumber, columns); + + __printTableHeaderNumber(startNumber); + for (unsigned i = 0, colInd = 0, rowInd = 0; items[i] != '\0'; i++, (++colInd) %= columns) { + if (colInd == 0 && i != 0) { + std::cout << ":" << std::endl; + __printTableLine(columns); + __printTableHeaderNumber((++rowInd) + startNumber); + } + + std::cout << ((colInd == 0) ? "║ " : "| ") << items[rowInd * columns + colInd] << " "; + } + std::cout << ":" << std::endl; +} + +void _printOrderedListBeginning() { + std::cout << "[" << orderedListIndex++ << "] "; +} + +void _printInputBoxLabel(const char* label) { + std::cout << "(+) " << label; +} + +void _printInputSubBoxLabel(const char* label) { + std::cout << " "; + _printInputBoxLabel(label); +} + +void __inputLineBoxGetInput(char* output, unsigned maxWidth) { + std::cin.ignore(); + std::cin.getline(output, maxWidth); +} + +void inputLineBox(const char* label, char* output, unsigned maxWidth) { + _printInputBoxLabel(label); + __inputLineBoxGetInput(output, maxWidth); +} + +void inputLineSubBox(const char* label, char* output, unsigned maxWidth) { + _printInputSubBoxLabel(label); + __inputLineBoxGetInput(output, maxWidth); +} diff --git a/src/Generic/ConsoleInterface/Toolbox.hpp b/src/Generic/ConsoleInterface/Toolbox.hpp new file mode 100644 index 0000000..ed5d6ac --- /dev/null +++ b/src/Generic/ConsoleInterface/Toolbox.hpp @@ -0,0 +1,76 @@ +#ifndef HEADER_CONSOLEINTERFACE_TOOLBOX +#define HEADER_CONSOLEINTERFACE_TOOLBOX + +#include "../String/String.h" +#include <iostream> + +#define MAX_LINE_WIDTH 1024 + +void clear(); +void titleBox(const char* title); +void subTitleBox(const char* title); + +void successBox(const char* message); +void warningBox(const char* message); +void errorBox(const char* message); + +void table(unsigned startNumber, unsigned columns, const char* items); + +void inputLineBox(const char* label, char* output, unsigned maxWidth); +void inputLineSubBox(const char* label, char* output, unsigned maxWidth); +void resetOrderedList(int starter = 1); + +void _printInputBoxLabel(const char* label); +void _printInputSubBoxLabel(const char* label); +void _printOrderedListBeginning(); + +template <class T> +void read(T* storage) { + std::cin >> storage; +} + +template <class T> +void read(T& storage) { + std::cin >> storage; +} + +template <class T> +void print(const T* item) { + std::cout << item; +} + +template <class T> +void printLine(const T* item) { + std::cout << item << std::endl; +} + +template <class T> +void print(const T& item) { + std::cout << item; +} + +template <class T> +void printLine(const T& item) { + std::cout << item << std::endl; +} + + +template <typename T> +void printOrderedListElem(const T& elem) { + _printOrderedListBeginning(); + printLine(elem); +} + +template <typename T> +void inputBox(const char* label, T* output) { + _printInputBoxLabel(label); + std::cin >> *output; +} + +template <typename T> +void inputSubBox(const char* label, T* output) { + _printInputSubBoxLabel(label); + std::cin >> *output; +} + +#endif |
