Website Summary Files Commits Branches @commit @diff @stats
path: root / src / Generic / ConsoleInterface
diff options
context:
space:
mode:
Commit6c31ce8db2f8b969f030e5d9d04c9ae511333a06 (patch)
Author
 Syndamia <kamen.d.mladenov@protonmail.com>
2022-05-08 16:12:55 +0300
Committer
 Syndamia <kamen.d.mladenov@protonmail.com>
2022-05-08 16:12:55 +0300
Filesd981ce8f9f7b827c37b8624a64c31ab611084476 /src/Generic/ConsoleInterface
FMI-OOP-P1_TicketSystem-6c31ce8db2f8b969f030e5d9d04c9ae511333a06.tar
FMI-OOP-P1_TicketSystem-6c31ce8db2f8b969f030e5d9d04c9ae511333a06.tar.gz
FMI-OOP-P1_TicketSystem-6c31ce8db2f8b969f030e5d9d04c9ae511333a06.zip
Parent517458f1cba81297f6a9472dda7b09586faba7d6 (diff)
Documented ConsoleInterface
diff --git a/src/Generic/ConsoleInterface/Command.cpp b/src/Generic/ConsoleInterface/Command.cpp
index d3d058c..c14bcc8 100644
--- a/src/Generic/ConsoleInterface/Command.cpp
+++ b/src/Generic/ConsoleInterface/Command.cpp
@@ -3,11 +3,17 @@
Command::Command() : Command("", nullptr) {}
+/*! \param nameInMenu C-style string, class stores at most 255 characters (last character is always terminating zero)
+ * \param exec Function pointer that will be executed when run() is called. Can be nullptr.
+ */
Command::Command(const char* nameInMenu, void (*exec)()) {
- strcpy(this->nameInMenu, nameInMenu);
+ strncpy(this->nameInMenu, nameInMenu, 255);
+ this->nameInMenu[255] = '\0';
this->exec = exec;
}
+/*! Executes the stored function pointer, when it's not nullptr. Otherwise does nothing.
+ */
void Command::run() const {
if (exec != nullptr)
exec();
diff --git a/src/Generic/ConsoleInterface/Command.h b/src/Generic/ConsoleInterface/Command.h
index d00b277..f1eb55b 100644
--- a/src/Generic/ConsoleInterface/Command.h
+++ b/src/Generic/ConsoleInterface/Command.h
@@ -1,13 +1,24 @@
#ifndef HEADER_CONSOLEINTERFACE_COMMAND
#define HEADER_CONSOLEINTERFACE_COMMAND
+/*! \file Command.h
+ * \brief Stores the declaration of class Command
+ */
+
+/*! \brief Stores a 256 character name and a function pointer to be executed when calling run()
+ *
+ * Menu uses this class for a more generic implementation of it's navigate function.
+ */
class Command {
char nameInMenu[256];
void (*exec)();
public:
+ //! Leaves name empty and exec function pointer to nullptr
Command();
+ //! Copies contents of nameInMenu and stores exec
Command(const char* nameInMenu, void (*exec)());
+ //! Executes the stored function pointer
void run() const;
const char* get_nameInMenu() const;
diff --git a/src/Generic/ConsoleInterface/Menu.cpp b/src/Generic/ConsoleInterface/Menu.cpp
index d672540..3ab857e 100644
--- a/src/Generic/ConsoleInterface/Menu.cpp
+++ b/src/Generic/ConsoleInterface/Menu.cpp
@@ -4,17 +4,29 @@
Menu::Menu() : Menu("Menu", false, false) {}
+/*! \param title C-style string, class stores at most 255 characters (last character is always terminating zero)
+ * \param backExistsApp Flag whether or not to list the 0-th option as "Exit", rather than "Go Back"
+ * \param isSubMenu Flag whether or not to show the title as a subTitle or not
+ */
Menu::Menu(const char* title, bool backExistsApp, bool isSubMenu) : menuOptions() {
this->backExistsApp = backExistsApp;
this->isSubMenu = isSubMenu;
- strcpy(this->title, title);
+ strncpy(this->title, title, 255);
+ this->title[255] = '\0';
}
+/*! \param title C-style string, class stores at most 255 characters (last character is always terminating zero)
+ * \param backExistsApp Flag whether or not to list the 0-th option as "Exit", rather than "Go Back"
+ * \param isSubMenu Flag whether or not to show the title as a subTitle or not
+ * \param commands Pointer to an array of Command instances
+ * \param commandCount Number of elements that "commands" points to
+ */
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);
+ strncpy(this->title, title, 255);
+ this->title[255] = '\0';
}
void Menu::addCommand(const Command& command) {
@@ -30,21 +42,54 @@ enum MessageType {
const char* msg;
MessageType msgType;
+/*! \param message C-style string, saves to pointer for later reuse when showing the message.
+ *
+ * Stores the message pointer in a global variable (in the cpp file) and
+ * sets it's type as an Error in another global variable (in the cpp file).
+ *
+ * The next time the whole Menu is shown, the message will appear below the title.
+ */
void Menu::registerError(const char* message) const {
msg = message;
msgType = Error;
}
+/*! \param message C-style string, saves to pointer for later reuse when showing the message.
+ *
+ * Stores the message pointer in a global variable (in the cpp file) and
+ * sets it's type as a Warning in another global variable (in the cpp file).
+ *
+ * The next time the whole Menu is shown, the message will appear below the title.
+ */
void Menu::registerWarning(const char* message) const {
msg = message;
msgType = Warning;
}
+/*! \param message C-style string, saves to pointer for later reuse when showing the message.
+ *
+ * Stores the message pointer in a global variable (in the cpp file) and
+ * sets it's type as Success in another global variable (in the cpp file).
+ *
+ * The next time the whole Menu is shown, the message will appear below the title.
+ */
void Menu::registerSuccess(const char* message) const {
msg = message;
msgType = Success;
}
+/*!
+ * Prints the title, then an Error/Warning/Sucess message (if set),
+ * prints all command names as an ordered list (starting from 1),
+ * waits for user input to select one of those commands (by list number)
+ * and finally executes the appropriate command's run() function.
+ *
+ * After the run() function exists, everything is reprinted.
+ * The 0 list index is always "Go Back"/"Exit" and it always stops the reprinting loop.
+ *
+ * If there are no commands, prints "Menu is empty!".
+ * If user input doesn't correspond to any command, registers an error message and reprints.
+ */
void Menu::navigate() const {
if (menuOptions.get_count() == 0) {
printLine("Menu is empty!");
diff --git a/src/Generic/ConsoleInterface/Menu.h b/src/Generic/ConsoleInterface/Menu.h
index 2501871..e0ea685 100644
--- a/src/Generic/ConsoleInterface/Menu.h
+++ b/src/Generic/ConsoleInterface/Menu.h
@@ -1,9 +1,19 @@
#ifndef HEADER_CONSOLEINTERFACE_MENU
#define HEADER_CONSOLEINTERFACE_MENU
+/*! \file Menu.h
+ * \brief Stores the declaration of class Menu
+ */
+
#include "Command.h"
#include "../List/List.hpp"
+/*! \brief Handles navigation between multiple commands
+ *
+ * Shows the title, then below it an Error/Warning/Success message if set,
+ * lists all command options as an enumerated list, takes command index
+ * and calls the chosen command's run() function.
+ */
class Menu {
char title[256];
List<Command> menuOptions;
@@ -12,15 +22,24 @@ class Menu {
bool isSubMenu;
public:
+ //! Sets name as "Menu", leaves all flags to false and creates an empty Command list
Menu();
+ //! Copies title, saves flags and creates and empty Command list
Menu(const char* title, bool backExistsApp, bool isSubMenu);
+ //! Copies title, saves flags and copies commands
Menu(const char* title, bool backExistsApp, bool isSubMenu, const Command* commands, unsigned commandCount);
+ //! Adds a command to the internal Command list
void addCommand(const Command& command);
+ //! Tell Menu to show an error message next time it prints
void registerError(const char* message) const;
+ //! Tell Menu to show a warning message next time it prints
void registerWarning(const char* message) const;
+ //! Tell Menu to show a success message next time it prints
void registerSuccess(const char* message) const;
+
+ //! Lists commands and after user input executes an appropriate command run() function
void navigate() const;
};
diff --git a/src/Generic/ConsoleInterface/Toolbox.cpp b/src/Generic/ConsoleInterface/Toolbox.cpp
index 78ca240..c46fff4 100644
--- a/src/Generic/ConsoleInterface/Toolbox.cpp
+++ b/src/Generic/ConsoleInterface/Toolbox.cpp
@@ -1,49 +1,93 @@
#include "Toolbox.hpp"
+/*!
+ * Prints an ANSI escape sequence to clear the console.
+ */
void clear() {
// Clears console on Linux
// Source: https://stackoverflow.com/a/52895729/12036073
std::cout << u8"\033[2J\033[1;1H";
}
+/*!
+ * Sub boxes are like normal boxes, but indented with 4 spaces.
+ */
void _printSubBoxSpacing() {
std::cout << " ";
}
/* Title boxes */
+/*! \param title C-style string, there are no size checks so it could wrap
+ *
+ * Prints the title, surrounded by "===".
+ */
void titleBox(const char* title) {
std::cout << std::endl << "=== " << title << " ===" << std::endl;
}
+/*! \param title C-style string, there are no size checks so it could wrap
+ *
+ * Prints the title, surrounded by "---".
+ */
void subTitleBox(const char* title) {
std::cout << std::endl << "--- " << title << " ---" << std::endl;
}
/* Status boxes */
+/*! \param message C-style string, there are no size checks so it could wrap
+ *
+ * Success boxes start with "<S>" and print the message.
+ *
+ * \remark Success/Warning/Error boxes start with "<C>" where C is an appropriate character.
+ */
void successBox(const char* message) {
std::cout << "<S> " << message << std::endl;
}
+/*!
+ * Like successBox but also prints the sub box spacing
+ * \sa successBox()
+ */
void successSubBox(const char* message) {
_printSubBoxSpacing();
successBox(message);
}
+/*! \param message C-style string, there are no size checks so it could wrap
+ *
+ * Warning boxes start with "<W>" and print the message.
+ *
+ * \remark Success/Warning/Error boxes start with "<C>" where C is an appropriate character.
+ */
void warningBox(const char* message) {
std::cout << "<W> " << message << std::endl;
}
+/*!
+ * Like warningBox but also prints the sub box spacing
+ * \sa warningBox()
+ */
void warningSubBox(const char* message) {
_printSubBoxSpacing();
warningBox(message);
}
+/*! \param message C-style string, there are no size checks so it could wrap
+ *
+ * Error boxes start with "<E>" and print the message.
+ *
+ * \remark Success/Warning/Error boxes start with "<C>" where C is an appropriate character.
+ */
void errorBox(const char* message) {
std::cout << "<E> " << message << std::endl;
}
+/*!
+ * Like errorBox but also prints the sub box spacing
+ * \sa errorBox()
+ */
void errorSubBox(const char* message) {
_printSubBoxSpacing();
errorBox(message);
@@ -51,6 +95,13 @@ void errorSubBox(const char* message) {
/* Input line boxes */
+/*! \param label C-style string, there are no size checks so it could wrap
+ *
+ * Prints "(+)" and then the given label.
+ * It doesn't create spacing after label, so it should exist in the label itself.
+ *
+ * \remark Semi-internal means the function is defined in the header out of necessity (for templated functions)
+ */
void _printInputBoxLabel(const char* label) {
std::cout << "(+) " << label;
}
@@ -61,17 +112,34 @@ void __inputLineBoxGetInput(char* output, unsigned maxWidth, bool ignore) {
std::cin.getline(output, maxWidth);
}
+/*! \param label C-style string, there are no size check so it could wrap
+ * \param output Pointer to a char array
+ * \param maxWidth Maximum count of characters to read from user input. output MUST be able to hold that many characters!
+ * \param ignore Whether or not to ignore the first new-line delimiter.
+ * true by default, should be set to false only when an inputLineBox/SubBox has been issued directly prior or when it's the very first issued box command.
+ *
+ * Prints "(+)" before the label.
+ */
void inputLineBox(const char* label, char* output, unsigned maxWidth, bool ignore) {
_printInputBoxLabel(label);
__inputLineBoxGetInput(output, maxWidth, ignore);
}
+/*!
+ * Like inputLineBox but also prints the sub box spacing
+ * \sa inputLineBox()
+ */
void inputLineSubBox(const char* label, char* output, unsigned maxWidth, bool ignore) {
_printSubBoxSpacing();
_printInputBoxLabel(label);
__inputLineBoxGetInput(output, maxWidth, ignore);
}
+/*! \param ignore Whether or not to ignore the first new-line delimiter.
+ * true by default, should be set to false only when an inputLineBox/SubBox has been issued directly prior or when it's the very first issued box command.
+ *
+ * Prints a "Press enter to continue" message and waits for the user
+ */
void pressEnterToContinue(bool ignore) {
char tmp;
inputLineBox("[Press enter to continue]", &tmp, 1, ignore);
@@ -81,10 +149,22 @@ void pressEnterToContinue(bool ignore) {
int orderedListIndex = 1;
+/*!
+ * Prints the latests ordered list index, surrounded by square brackets, and increments the ordered list index.
+ *
+ * \remark There are no size checks, so list index could overflow.
+ *
+ * \remark Semi-internal means the function is defined in the header out of necessity (for templated functions)
+ */
+
void _printOrderedListBeginning() {
std::cout << "[" << orderedListIndex++ << "] ";
}
+/*! \param starter Sets the starting number by which ordered list will enumerate
+ *
+ * \remark Although starter can be a negative number, ordered list will always increment up the number.
+ */
void resetOrderedList(int starter) {
orderedListIndex = starter;
}
@@ -113,6 +193,16 @@ void __printTableLine(unsigned columns) {
std::cout << ":" << std::endl;
}
+/*! \param startNumber The number by which column and row enumeration begins
+ * \params columns How many columns the table should have
+ * \params items C-style string, each cell is a single character from the string
+ *
+ * Prints a string as a grid/table of characters from top to bottom, left to right.
+ * The first character is on the top left, the last one is on the bottom right.
+ *
+ * Table is printed until a terminating zero is encountered.
+ * The rows are "calculated" from the columns count and the items length.
+ */
void table(unsigned startNumber, unsigned columns, const char* items) {
__printTableColumnHeader(startNumber, columns);
diff --git a/src/Generic/ConsoleInterface/Toolbox.hpp b/src/Generic/ConsoleInterface/Toolbox.hpp
index a1a310b..ea1bba1 100644
--- a/src/Generic/ConsoleInterface/Toolbox.hpp
+++ b/src/Generic/ConsoleInterface/Toolbox.hpp
@@ -3,74 +3,107 @@
#include <iostream>
+/*! \file Toolbox.hpp
+ * \brief Stores a wide range of functions for simpler/more automated printing.
+ *
+ * Adds a lot of functions for printing.
+ *
+ * \remark iostream is included by necessity (templated functions), you should only use the provided functions, if you can.
+ */
+
#define MAX_LINE_WIDTH 1024
+//! Clears the console screen (Linux-only)
void clear();
+//! Prints a title box
void titleBox(const char* title);
+//! Prints a title sub box
void subTitleBox(const char* title);
+//! Prints a success box
void successBox(const char* message);
+//! Prints a success box as a sub box
void successSubBox(const char* message);
+//! Prints a warning box
void warningBox(const char* message);
+//! Prints a warning box as a sub box
void warningSubBox(const char* message);
+//! Prints an error box
void errorBox(const char* message);
+//! Prints an error box as a sub box
void errorSubBox(const char* message);
+//! Prints label, gets a whole line of input and stores it to output
void inputLineBox(const char* label, char* output, unsigned maxWidth, bool ignore = true);
+//! Prints label as a sub box, gets a whole line of input and stores it to output
void inputLineSubBox(const char* label, char* output, unsigned maxWidth, bool ignore = true);
+//! Waits for user to press enter
void pressEnterToContinue(bool ignore = true);
+//! Resets the ordered list starting number
void resetOrderedList(int starter = 1);
+//! Prints a string as a table
void table(unsigned startNumber, unsigned columns, const char* items);
+//! Semi-internal function that prints the spacing for sub boxes
void _printSubBoxSpacing();
+//! Semi-internal function that prints the label of an input box
void _printInputBoxLabel(const char* label);
+//! Semi-internal function that prints the latest ordered list index
void _printOrderedListBeginning();
-template <class T>
+//! Reads user input and stores it
+template <typename T>
void read(T* storage) {
std::cin >> storage;
}
-template <class T>
+//! Reads user input and stores it
+template <typename T>
void read(T& storage) {
std::cin >> storage;
}
-template <class T>
+//! Prints given item
+template <typename 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>
+//! Prints given item
+template <typename T>
void print(const T& item) {
std::cout << item;
}
-template <class T>
-void printLine(const T& item) {
+//! Prints given item and an endline character
+template <typename T>
+void printLine(const T* item) {
std::cout << item << std::endl;
}
+//! Prints given item and an endline character
+template <typename T>
+void printLine(const T& item) {
+ std::cout << item << std::endl;
+}
+//! Prints the element as the latest list item
template <typename T>
void printOrderedListElem(const T& elem) {
_printOrderedListBeginning();
printLine(elem);
}
+//! Prints a label and then reads user input and stores it
template <typename T>
void inputBox(const char* label, T* output) {
_printInputBoxLabel(label);
std::cin >> *output;
}
+//! Prints a label with sub box spacing and then reads user input and stores it
template <typename T>
void inputSubBox(const char* label, T* output) {
_printSubBoxSpacing();