From 9b8bf2279565a9b55fa49e4cfedd794e2f2f81ec Mon Sep 17 00:00:00 2001 From: Alexander Klein Date: Thu, 12 Oct 2023 19:50:26 +0200 Subject: [PATCH] doxygen comments --- include/displayWrapper.h | 67 +++-- include/menu.h | 130 +++++---- include/menuAction.h | 216 ++++++++------- include/menuControl.h | 221 ++++++++------- include/menuInformationSites.h | 241 +++++++++++------ include/menuIntInput.h | 305 ++++++++++++++------- src/menu.cpp | 280 ++++++++++--------- src/menuAction.cpp | 143 +++++----- src/menuControl.cpp | 74 +++-- src/menuInformationSites.cpp | 208 ++++++++------- src/menuIntInput.cpp | 475 ++++++++++++++++++--------------- 11 files changed, 1346 insertions(+), 1014 deletions(-) diff --git a/include/displayWrapper.h b/include/displayWrapper.h index 866bc3e..816139f 100644 --- a/include/displayWrapper.h +++ b/include/displayWrapper.h @@ -1,22 +1,45 @@ -/** - * @file displayWrapper.h - * @author Alexander Klein (alex@kleiax.de) - * @brief - * @version 0.1 - * @date 2023-01-08 - * - * @copyright Copyright (c) 2023 - * - */ - -#ifndef DISPLAY_WRAPPER_H -#define DISPLAY_WRAPPER_H - -class DisplayWrapper { - public: - virtual void clear() = 0; - virtual void setCursor(uint8_t row, uint8_t line) = 0; - virtual void print(const char *str) = 0; -}; - -#endif // DISPLAY_WRAPPER_H +/** + * @file displayWrapper.h + * @author Alexander Klein (alex@kleiax.de) + * @brief Contains a interface to presents a display + * @version 0.1 + * @date 2023-01-08 + * + * @copyright Copyright (c) 2023 + * + */ + +#ifndef DISPLAY_WRAPPER_H +#define DISPLAY_WRAPPER_H + +/** + * @brief This interface abstracted a display + * + * With this inteface a display which works with columns + * and lines can be wrapped to be accepted by menus. + */ +class DisplayWrapper +{ +public: + /** + * @brief Remove everything from the display + */ + virtual void clear() = 0; + + /** + * @brief Set the cursor to specific line and column + * + * @param row + * @param line + */ + virtual void setCursor(uint8_t row, uint8_t line) = 0; + + /** + * @brief Print to the position set by setCursor() + * + * @param str + */ + virtual void print(const char *str) = 0; +}; + +#endif // DISPLAY_WRAPPER_H diff --git a/include/menu.h b/include/menu.h index 832b055..562a90b 100644 --- a/include/menu.h +++ b/include/menu.h @@ -1,55 +1,75 @@ -/** - * @file menu.h - * @author Alexander Klein (alex@kleiax.de) - * @brief Contains the Menu class - * @version 0.1 - * @date 2022-01-12 - * - * @copyright Copyright (c) 2022 - * - */ -#ifndef MENU_H -#define MENU_H - -#include - -#include "menuAction.h" -#include "menuControl.h" - -class MenuAction; - -/** - * @brief A class to build menu structers - */ -class Menu : public MenuControl { - public: - Menu(); - ~Menu() override; - - /** - * @brief Add a menu action to the menu - * - * @param entry - */ - void addEntry(MenuAction* entry); - bool isInSubmenu(); - - void printMenu() override; - void update() override; - - void down() override; - void up() override; - void right() override; - void left() override; - void yes() override; - void no() override; - - private: - bool inSubmenu = false; - - std::list entrys; - std::list::iterator selectedEntry; - -}; - -#endif // MENU_H +/** + * @file menu.h + * @author Alexander Klein (alex@kleiax.de) + * @brief Contains the Menu class + * @version 0.1 + * @date 2022-01-12 + * + * @copyright Copyright (c) 2022 + * + */ +#ifndef MENU_H +#define MENU_H + +#include + +#include "menuAction.h" +#include "menuControl.h" + +class MenuAction; + +/** + * @brief A class to build menu structures + */ +class Menu : public MenuControl +{ +public: + Menu(); + ~Menu() override; + + /** + * @brief Add a MenuAction to the menu + * + * Every MenuAction is an Entry in the Menu + * + * @param entry + */ + void addEntry(MenuAction *entry); + + /** + * @brief get information about the active menu + * + * If this is not the active menu, will be passed to + * active menu. + * + * @return true an other menu is active + * @return false this menu is active + */ + bool isInSubmenu(); + + /** + * @brief Print the actual screen + */ + void printMenu() override; + + /** + * @brief Print the screen from the active menu + */ + void update() override; + + // User Inputs + void down() override; + void up() override; + void right() override; + void left() override; + void yes() override; + void no() override; + +private: + bool inSubmenu = false; + + std::list entries; + std::list::iterator selectedEntry; +}; + +#endif // MENU_H diff --git a/include/menuAction.h b/include/menuAction.h index f4bf046..abe5457 100644 --- a/include/menuAction.h +++ b/include/menuAction.h @@ -1,103 +1,113 @@ -/** - * @file menuAction.h - * @author Alexander Klein (alex@kleiax.de) - * @brief Contains the MenuAction class - * @version 0.1 - * @date 2022-01-12 - * - * @copyright Copyright (c) 2022 - * - */ -#ifndef MENU_ENTRY_H -#define MENU_ENTRY_H - -#include "menu.h" - -class MenuControl; - -class MenuActionWrapper { - public: - virtual ~MenuActionWrapper() {} - virtual void action() = 0; -}; - -/** - * @brief This class forms the transition between menus. - * - * In the Menu these are the entries. - * This class can be call an submenu or a function. - */ -class MenuAction { - public: - - /** - * @brief Construct a new Menu Action object - * - * @param name shown in the Menu - * @param function to call when activate the entry - * @param callback to call when leave the entry - */ - MenuAction(const char* name, void (*function) (), void (*callback) () = nullptr); - - /** - * @brief Construct a new Menu Action object - * - * @param name shown in the Menu - * @param action to call when activate the entry - */ - MenuAction(const char* name, MenuActionWrapper* action); - - /** - * @brief Construct a new Menu Action object - * - * This constructer is used for submenus. - * - * @param name shown in the Menu - * @param menu to call when activate the entry - */ - MenuAction(const char* name, MenuControl* menu); - - ~MenuAction(); - - /** - * @brief activates the entry - */ - void runAction(); - - /** - * @brief Get the Name string - * - * @return const char* - */ - const char* getName(); - - /** - * @brief Get the Is Menu object - * - * @return true runAction calls a submenu - * @return false runAction call a function - */ - bool getIsMenu(); - - /** - * @brief Get the Menu object - * - * Before call this function it may be useful - * to check if is it a submenu with getIsMenu. - * - * @return MenuControl* - */ - MenuControl* getMenu(); - - private: - const char* name; - - void (*function) () = nullptr; - void (*callback) () = nullptr; - - bool isMenu = false; - MenuControl* menu = nullptr; - MenuActionWrapper* action = nullptr; -}; - -#endif // MENU_ENTRY_H +/** + * @file menuAction.h + * @author Alexander Klein (alex@kleiax.de) + * @brief Contains the MenuAction class + * @version 0.1 + * @date 2022-01-12 + * + * @copyright Copyright (c) 2022 + * + */ +#ifndef MENU_ENTRY_H +#define MENU_ENTRY_H + +#include "menu.h" + +class MenuControl; + +/** + * @brief An Interface to execute actions + * + * This interface can be inherited to wrap actions + * in it for a MenuAction. + */ +class MenuActionWrapper +{ +public: + virtual ~MenuActionWrapper() {} + /** + * @brief Function to be called by the MenuAction + */ + virtual void action() = 0; +}; + +/** + * @brief This class forms the transition between menus. + * + * In the Menu these are the entries. + * This class can be call an submenu or a function. + */ +class MenuAction +{ +public: + /** + * @brief Construct a new Menu Action object + * + * @param name shown in the Menu + * @param function to call when activate the entry + * @param callback to call when leave the entry + */ + MenuAction(const char *name, void (*function)(), void (*callback)() = nullptr); + + /** + * @brief Construct a new Menu Action object + * + * @param name shown in the Menu + * @param action to call when activate the entry + */ + MenuAction(const char *name, MenuActionWrapper *action); + + /** + * @brief Construct a new Menu Action object + * + * This constructor is used for submenus. + * + * @param name shown in the Menu + * @param menu to call when activate the entry + */ + MenuAction(const char *name, MenuControl *menu); + + ~MenuAction(); + + /** + * @brief activates the entry + */ + void runAction(); + + /** + * @brief Get the Name string + * + * @return const char* + */ + const char *getName(); + + /** + * @brief Get the Is Menu object + * + * @return true runAction calls a submenu + * @return false runAction call a function + */ + bool getIsMenu(); + + /** + * @brief Get the Menu object + * + * Before call this function it may be useful + * to check if is it a submenu with getIsMenu. + * + * @return MenuControl* + */ + MenuControl *getMenu(); + +private: + const char *name; + + void (*function)() = nullptr; + void (*callback)() = nullptr; + + bool isMenu = false; + MenuControl *menu = nullptr; + MenuActionWrapper *action = nullptr; +}; + +#endif // MENU_ENTRY_H diff --git a/include/menuControl.h b/include/menuControl.h index 5b70632..cf66d54 100644 --- a/include/menuControl.h +++ b/include/menuControl.h @@ -1,103 +1,118 @@ -/** - * @file menuControl.h - * @author Alexander Klein (alex@kleiax.de) - * @brief Contains a abstract class for Menu - * @version 0.1 - * @date 2022-01-19 - * - * @copyright Copyright (c) 2022 - * - */ - -#ifndef MENU_CONTROLL_H -#define MENU_CONTROLL_H - -#include -#include -#include "displayWrapper.h" - -/** - * @brief Baseclass to build Menus - * - * This class have to be inherited by other classes which want to be - * act as a menu, because the menu structure uses polymorphism. - * - */ -class MenuControl { - public: - virtual ~MenuControl() {}; - - /** @name UserInputs - * @brief This functions should be called be user actions. - * - * This functions have to be implement in every other menu - * class. - */ - ///@{ - virtual void down() {}; - virtual void up() {}; - virtual void right() {}; - virtual void left() {}; - virtual void yes() {}; - virtual void no() {}; - ///@} - - /** - * @brief can be called to update shown data - */ - virtual void update() { - if (this->updateDelay == 0) - return; - - if (millis() - this->lastUpdateMillis < this->updateDelay) { - return; - } - - this->printMenu(); - this->lastUpdateMillis = millis(); - } - - virtual void prepareReenterMenu() {} - virtual void printMenu() = 0; - - /** - * @brief Set the Parent Menu - * - * If the parentMenu is set it will be called automaticaly - * when the user left the child menu. - * - * @param menu - */ - void setParentMenu(MenuControl* menu); - // MenuControl* getParentMenu() { return this->parentMenu; } - - /** - * @brief Set the Lcd object - * - * If this is set the menu will be print on the display too. - * - * @param lcd - */ - void setLcd(DisplayWrapper* lcd) { this->lcd = lcd; } - - /** - * @brief Set the time between each new print to the display - * - * If the delay is zero, no updates will be made. - * The delay is by default zero. - * - * @param delay time in milliseconds - */ - void setUpdateDelay(uint16_t delay = 0) { this->updateDelay = delay; } - - protected: - void print(String lineOne, String lineTwo) const; - DisplayWrapper* getLcd() const { return this->lcd; } - - MenuControl* parentMenu = nullptr; - DisplayWrapper* lcd = nullptr; - - uint16_t updateDelay = 0; - uint32_t lastUpdateMillis = 0; -}; -#endif // MENU_CONTROLL_H +/** + * @file menuControl.h + * @author Alexander Klein (alex@kleiax.de) + * @brief Contains a abstract class for Menu + * @version 0.1 + * @date 2022-01-19 + * + * @copyright Copyright (c) 2022 + * + */ + +#ifndef MENU_CONTROLL_H +#define MENU_CONTROLL_H + +#include +#include +#include "displayWrapper.h" + +/** + * @brief Baseclass to build Menus + * + * This class have to be inherited by other classes which want to be + * act as a menu, because the menu structure uses polymorphism. + * + */ +class MenuControl +{ +public: + virtual ~MenuControl(){}; + + /** @name UserInputs + * @brief This functions should be called be user actions. + * + * This functions have to be implement in every other menu + * class. + */ + ///@{ + virtual void down(){}; + virtual void up(){}; + virtual void right(){}; + virtual void left(){}; + virtual void yes(){}; + virtual void no(){}; + ///@} + + /** + * @brief can be called to update shown data + * + * The data will be only updated if a updateDelay is set + * and delay is reached. + */ + virtual void update(); + + /** + * @brief Prepare reenter the this menu + * + * This function must be called separately + */ + virtual void prepareReenterMenu() {} + + /** + * @brief Function to print the Menu + * + * Have to be overwritten to implement the representation + * of the menu. + * This function have to call the print() function to access + * the display. + */ + virtual void printMenu() = 0; + + /** + * @brief Set the Parent Menu + * + * If the parentMenu is set it will be called automaticaly + * when the user left the child menu. + * If the parentMenu has set a LCD it will be copied to the + * actual instance. + * + * @param menu + */ + void setParentMenu(MenuControl *menu); + + /** + * @brief Set the Lcd object + * + * If this is set the menu will be print on the display too. + * + * @param lcd + */ + void setLcd(DisplayWrapper *lcd) { this->lcd = lcd; } + + /** + * @brief Set the time between each new print to the display + * + * If the delay is zero, no updates will be made. + * The delay is by default zero. + * + * @param delay time in milliseconds + */ + void setUpdateDelay(uint16_t delay = 0) { this->updateDelay = delay; } + +protected: + /** + * @brief + * + * @param lineOne + * @param lineTwo + */ + void print(String lineOne, String lineTwo) const; + DisplayWrapper *getLcd() const { return this->lcd; } + + MenuControl *parentMenu = nullptr; + DisplayWrapper *lcd = nullptr; + + uint16_t updateDelay = 0; + uint32_t lastUpdateMillis = 0; +}; +#endif // MENU_CONTROLL_H diff --git a/include/menuInformationSites.h b/include/menuInformationSites.h index 54a4bd5..07bbc68 100644 --- a/include/menuInformationSites.h +++ b/include/menuInformationSites.h @@ -1,88 +1,153 @@ -/** - * @file menuInformationSites.h - * @author Alexander Klein (alex@kleiax.de) - * @brief Contains a class to print informations over more pages - * @version 0.1 - * @date 2022-12-27 - * - * @copyright Copyright (c) 2022 - * - */ -#ifndef MENU_INFORMATION_SITES_H -#define MENU_INFORMATION_SITES_H - -#include "menuControl.h" - -class MenuInformationSites : public MenuControl { - public: - /** - * @brief Construct a new Menu Information Sites object - * - * @param amount of pages - */ - MenuInformationSites(uint8_t pages = 1); - - /** - * @brief Next page - */ - void down() override; - - /** - * @brief Previous page - */ - void up() override; - - /** - * @brief Update information - */ - void right() override; - - /** - * @brief Go to the parent menu - */ - void left() override; - - /** - * @brief Go to the parent menu - */ - void no() override; - - /** - * @brief Update information - */ - void yes() override; - - /** - * @brief Prints the Information to display and console - * - * Prints the selected page. - * The informations are only printed to the display if it - * set. - */ - void printMenu() override; - - protected: - bool setCountPages(uint8_t pages); - uint8_t getCountPages() const; - uint8_t getCurrentPage() const; - - virtual void printPage() const = 0; - virtual void runCommandNo() {} - virtual void runCommand() {} - virtual void init() {} - - void printDefault() const; - - uint8_t lastPageNumber = 0; - bool leaved = true; - bool noEqualLeft = false; - - private: - uint8_t countPages; - uint8_t currentPage; - - const uint16_t delay = 5000; - uint32_t lastMillis = 0; -}; - -#endif // MENU_INFORMATION_SITES_H +/** + * @file menuInformationSites.h + * @author Alexander Klein (alex@kleiax.de) + * @brief Contains a class to print informations over more pages + * @version 0.1 + * @date 2022-12-27 + * + * @copyright Copyright (c) 2022 + * + */ +#ifndef MENU_INFORMATION_SITES_H +#define MENU_INFORMATION_SITES_H + +#include "menuControl.h" + +/** + * @brief A Menu interface to show informations + * + * The informations a organized by multiple pages + */ +class MenuInformationSites : public MenuControl +{ +public: + /** + * @brief Construct a new Menu Information Sites object + * + * @param pages amount of the available pages + */ + MenuInformationSites(uint8_t pages = 1); + + /** + * @brief Next page + */ + void down() override; + + /** + * @brief Previous page + */ + void up() override; + + /** + * @brief Update information + */ + void right() override; + + /** + * @brief Go to the parent menu + */ + void left() override; + + /** + * @brief Calls runCommandNo() + */ + void no() override; + + /** + * @brief Calls runCommand() + */ + void yes() override; + + /** + * @brief Prints the Information to display and console + * + * Prints the selected page. + */ + void printMenu() override; + +protected: + /** + * @brief Change the amount of available pages + * + * @param pages + * @return true successful + * @return false + */ + bool setCountPages(uint8_t pages); + + /** + * @brief Get the amount of available pages + * + * @return uint8_t + */ + uint8_t getCountPages() const; + + /** + * @brief Get the selected page number + * + * @return uint8_t + */ + uint8_t getCurrentPage() const; + + /** + * @brief Print a page with informations + * + * This function have to be overwritten. + * The function have to use the print() function to access the display. + * The printed informations should be depends from the current page, + * which can determine by call getCurrentPage(). + */ + virtual void printPage() const = 0; + + /** + * @brief Function to adds actions + * + * If this function is overwritten, the menu can be extended + * with extra functionality. The executed action should be depends on + * the current page, which can determine by call getCurrentPage(). + * + * This function is called if no() is called. + */ + virtual void runCommandNo() {} + + /** + * @brief Function to adds actions + * + * If this function is overwritten, the menu can be extended + * with extra functionality. The executed action should be depends on + * the current page, which can determine by call getCurrentPage(). + * + * This function is called if yes() is called. + */ + virtual void runCommand() {} + + /** + * @brief Function to prepare dependencies + * + * This function is called when the menu is entered. + */ + virtual void init() {} + + /** + * @brief Prints default informations + * + * The default informations are the current page number + * and the amount of available pages. + * + * Can be used by printPage() if the current page is not available. + */ + void printDefault() const; + + uint8_t lastPageNumber = 0; + bool leaved = true; + bool noEqualLeft = false; + +private: + uint8_t countPages; + uint8_t currentPage; + + const uint16_t delay = 5000; + uint32_t lastMillis = 0; +}; + +#endif // MENU_INFORMATION_SITES_H diff --git a/include/menuIntInput.h b/include/menuIntInput.h index db0cb7a..58c665c 100644 --- a/include/menuIntInput.h +++ b/include/menuIntInput.h @@ -1,101 +1,204 @@ -/** - * @file menuIntInput.h - * @author Alexander Klein (alex@kleiax.de) - * @brief - * @version 0.1 - * @date 2022-09-12 - * - * @copyright Copyright (c) 2022 - * - */ -#ifndef MENU_INT_INPUT_H -#define MENU_INT_INPUT_H - -#include "menuControl.h" -#include - -#define MAX_NAME_LENGTH 12 - -class MenuIntInputWrapper { - public: - virtual ~MenuIntInputWrapper() {} - virtual void action(int16_t* values, uint8_t length) = 0; -}; - -class MenuIntInput : public MenuControl { - public: - MenuIntInput(int16_t values[], char *names, uint8_t length, MenuIntInputWrapper* wrapper); - MenuIntInput(uint8_t length, MenuIntInputWrapper *wrapper); - ~MenuIntInput(); - - void setEntry(uint8_t valueNumber, const char* name, int16_t startValue = 0); - - void setMin(uint8_t valueNumber, int16_t min); - void setMin(int16_t min); - void setMax(uint8_t valueNumber, int16_t max); - void setMax(int16_t max); - void setMinMax(uint8_t valueNumber, int16_t min, int16_t max); - void setMinMax(int16_t min, int16_t max); - void setMinMaxSteps(uint8_t valueNumber, int16_t min, int16_t max, uint8_t steps); - void setMinMaxSteps(int16_t min, int16_t max, uint8_t steps); - void setPrintParentMenu(bool b) { this->printParentMenu = b; } - - void setStepsPerInput(uint8_t valueNumber, uint8_t steps); - void setStepsPerInput(uint8_t steps); - - /** - * @brief Decrement selected value - */ - void down() override; - - /** - * @brief Increment selected value - */ - void up() override; - - /** - * @brief Select next value - */ - void right() override; - - /** - * @brief Select previous value - */ - void left() override; - - /** - * @brief Leave menu without saving - */ - void no() override; - - /** - * @brief Leave menu with saving - */ - void yes() override; - - /** - * @brief Prints the Information to display and console - * - * The informations are only printed to the display if it - * set. - */ - void printMenu() override; - - private: - MenuIntInputWrapper* wrapper; - - bool printParentMenu = true; - - uint8_t currentPosition = 0; - uint8_t length; - uint8_t *stepsPerInput; - uint8_t countSameActions = 0; - int16_t *values; - int16_t *originalValues; - int16_t *min; - int16_t *max; - char *names; - -}; - -#endif // MENU_INT_INPUT_H +/** + * @file menuIntInput.h + * @author Alexander Klein (alex@kleiax.de) + * @brief Contains a class to get integer inputs from the user + * @version 0.1 + * @date 2022-09-12 + * + * @copyright Copyright (c) 2022 + * + */ +#ifndef MENU_INT_INPUT_H +#define MENU_INT_INPUT_H + +#include "menuControl.h" +#include + +#define MAX_NAME_LENGTH 12 + +/** + * @brief Interface to transfer the integer data + */ +class MenuIntInputWrapper +{ +public: + virtual ~MenuIntInputWrapper() {} + + /** + * @brief Transfer function + * + * This function will be called by MenuIntInput, if the input + * are confirmed. + * + * @param values + * @param length amount of integer + */ + virtual void action(int16_t *values, uint8_t length) = 0; +}; + +/** + * @brief A Menu class to make integer inputs + */ +class MenuIntInput : public MenuControl +{ +public: + /** + * @brief Construct a new Menu Int Input object + * + * @param values the integer values + * @param names names of the values + * @param length amount of values + * @param wrapper MenuIntInputWrapper + */ + MenuIntInput(int16_t values[], char *names, uint8_t length, MenuIntInputWrapper *wrapper); + MenuIntInput(uint8_t length, MenuIntInputWrapper *wrapper); + ~MenuIntInput(); + + /** + * @brief Set a specific entry + * + * @param valueNumber the entry + * @param name name of entry + * @param startValue default value + */ + void setEntry(uint8_t valueNumber, const char *name, int16_t startValue = 0); + + /** + * @brief Set the minium for a specific value + * + * @param valueNumber the entry + * @param min + */ + void setMin(uint8_t valueNumber, int16_t min); + + /** + * @brief Set the minimum for all entries + * + * @param min + */ + void setMin(int16_t min); + + /** + * @brief Set the maximum for a specific value + * + * @param valueNumber the entry + * @param max + */ + void setMax(uint8_t valueNumber, int16_t max); + + /** + * @brief Set the maximum for all entries + * + * @param max + */ + void setMax(int16_t max); + + /** + * @brief Set the minium and the maximum for a specific value + * + * @param valueNumber the entry + * @param min + * @param max + */ + void setMinMax(uint8_t valueNumber, int16_t min, int16_t max); + + /** + * @brief Set the minium and the maximum for all entries + * + * @param valueNumber the entry + * @param min + * @param max + */ + void setMinMax(int16_t min, int16_t max); + + /** + * @brief Set the minium, the maximum and the steps for a specific value + * + * @param valueNumber the entry + * @param min + * @param max + * @param steps for increment and decrement + */ + void setMinMaxSteps(uint8_t valueNumber, int16_t min, int16_t max, uint8_t steps); + + /** + * @brief Set the minium, the maximum and the steps for all entries + * + * @param valueNumber the entry + * @param min + * @param max + * @param steps for increment and decrement + */ + void setMinMaxSteps(int16_t min, int16_t max, uint8_t steps); + + void setPrintParentMenu(bool b) { this->printParentMenu = b; } + /** + * @brief Set the steps for a specific value + * + * @param valueNumber the entry + * @param steps + */ + void setStepsPerInput(uint8_t valueNumber, uint8_t steps); + + /** + * @brief Set the steps for all entries + * + * @param steps + */ + void setStepsPerInput(uint8_t steps); + + /** + * @brief Decrement selected value + */ + void down() override; + + /** + * @brief Increment selected value + */ + void up() override; + + /** + * @brief Select next value + */ + void right() override; + + /** + * @brief Select previous value + */ + void left() override; + + /** + * @brief Leave menu without saving + */ + void no() override; + + /** + * @brief Leave menu with saving + */ + void yes() override; + + /** + * @brief Prints the Information to display and console + * + * The informations are only printed to the display if it + * set. + */ + void printMenu() override; + +private: + MenuIntInputWrapper *wrapper; + + bool printParentMenu = true; + + uint8_t currentPosition = 0; + uint8_t length; + uint8_t *stepsPerInput; + uint8_t countSameActions = 0; + int16_t *values; + int16_t *originalValues; + int16_t *min; + int16_t *max; + char *names; +}; + +#endif // MENU_INT_INPUT_H diff --git a/src/menu.cpp b/src/menu.cpp index 33c30e0..808b2d7 100644 --- a/src/menu.cpp +++ b/src/menu.cpp @@ -1,128 +1,152 @@ -/** - * @file menu.cpp - * @author Alexander Klein (alex@kleiax.de) - * @brief Implementation of the class Menu - * @version 0.1 - * @date 2022-01-12 - * - * @copyright Copyright (c) 2022 - * - */ -#include "menu.h" - -Menu::Menu() { - this->selectedEntry = this->entrys.begin(); -} - -Menu::~Menu() { - for (std::list::iterator iter = this->entrys.begin(); iter != this->entrys.end(); iter++) - delete *iter; -} - -void Menu::addEntry(MenuAction* entry) { - this->entrys.push_back(entry); - - if (this->entrys.size() == 2) - this->selectedEntry = this->entrys.begin(); -} - -bool Menu::isInSubmenu() { - return this->inSubmenu; -} - -void Menu::printMenu() { - std::list::iterator iter = this->selectedEntry; - - String lineOne = "-> "; - String lineTwo = ""; - - lineOne.concat((**iter).getName()); - iter++; - if (iter != this->entrys.end()) { - lineTwo.concat((**iter).getName()); - } else - lineTwo.concat((*this->entrys.begin())->getName()); - - this->inSubmenu = false; - this->print(lineOne, lineTwo); -} - -void Menu::update() { - if (this->inSubmenu) { - (**this->selectedEntry).getMenu()->update(); - return; - } -} - -void Menu::down() { - if (this->inSubmenu) { - (**this->selectedEntry).getMenu()->down(); - return; - } - - // TODO: Why I need the fucking next two lines? here and in the next function - std::list::iterator iter = this->selectedEntry; - iter++; - if (iter != this->entrys.end()) - this->selectedEntry++; - else - this->selectedEntry = this->entrys.begin(); - this->printMenu(); -} - -void Menu::up() { - if (this->inSubmenu) { - (**this->selectedEntry).getMenu()->up(); - return; - } - std::list::iterator iter = this->entrys.end(); - iter--; - if (this->selectedEntry != this->entrys.begin()) { - this->selectedEntry--; - } - else { - this->selectedEntry = iter; - } - this->printMenu(); -} - -void Menu::right() { - if (this->inSubmenu) { - (**this->selectedEntry).getMenu()->right(); - return; - } - - if ((**this->selectedEntry).getIsMenu()) { - this->inSubmenu = true; - (**this->selectedEntry).getMenu()->setParentMenu(this); - } - (**this->selectedEntry).runAction(); -} - -void Menu::left() { - if (this->inSubmenu) { - (**this->selectedEntry).getMenu()->left(); - return; - } - - if (parentMenu) - this->parentMenu->printMenu(); -} - -void Menu::yes() { - if (this->inSubmenu) { - (**this->selectedEntry).getMenu()->yes(); - return; - } - - this->right(); -} - -void Menu::no() { - if (this->inSubmenu) { - (**this->selectedEntry).getMenu()->no(); - return; - } - - this->left(); -} +/** + * @file menu.cpp + * @author Alexander Klein (alex@kleiax.de) + * @brief Implementation of the class Menu + * @version 0.1 + * @date 2022-01-12 + * + * @copyright Copyright (c) 2022 + * + */ +#include "menu.h" + +Menu::Menu() +{ + this->selectedEntry = this->entries.begin(); +} + +Menu::~Menu() +{ + for (std::list::iterator iter = this->entries.begin(); iter != this->entries.end(); iter++) + delete *iter; +} + +void Menu::addEntry(MenuAction *entry) +{ + this->entries.push_back(entry); + + if (this->entries.size() == 2) + this->selectedEntry = this->entries.begin(); +} + +bool Menu::isInSubmenu() +{ + return this->inSubmenu; +} + +void Menu::printMenu() +{ + std::list::iterator iter = this->selectedEntry; + + String lineOne = "-> "; + String lineTwo = ""; + + lineOne.concat((**iter).getName()); + iter++; + if (iter != this->entries.end()) + { + lineTwo.concat((**iter).getName()); + } + else + lineTwo.concat((*this->entries.begin())->getName()); + + this->inSubmenu = false; + this->print(lineOne, lineTwo); +} + +void Menu::update() +{ + if (this->inSubmenu) + { + (**this->selectedEntry).getMenu()->update(); + return; + } +} + +void Menu::down() +{ + if (this->inSubmenu) + { + (**this->selectedEntry).getMenu()->down(); + return; + } + + // TODO: Why I need the fucking next two lines? here and in the next function + std::list::iterator iter = this->selectedEntry; + iter++; + if (iter != this->entries.end()) + this->selectedEntry++; + else + this->selectedEntry = this->entries.begin(); + this->printMenu(); +} + +void Menu::up() +{ + if (this->inSubmenu) + { + (**this->selectedEntry).getMenu()->up(); + return; + } + std::list::iterator iter = this->entries.end(); + iter--; + if (this->selectedEntry != this->entries.begin()) + { + this->selectedEntry--; + } + else + { + this->selectedEntry = iter; + } + this->printMenu(); +} + +void Menu::right() +{ + if (this->inSubmenu) + { + (**this->selectedEntry).getMenu()->right(); + return; + } + + if ((**this->selectedEntry).getIsMenu()) + { + this->inSubmenu = true; + (**this->selectedEntry).getMenu()->setParentMenu(this); + } + (**this->selectedEntry).runAction(); +} + +void Menu::left() +{ + if (this->inSubmenu) + { + (**this->selectedEntry).getMenu()->left(); + return; + } + + if (parentMenu) + this->parentMenu->printMenu(); +} + +void Menu::yes() +{ + if (this->inSubmenu) + { + (**this->selectedEntry).getMenu()->yes(); + return; + } + + this->right(); +} + +void Menu::no() +{ + if (this->inSubmenu) + { + (**this->selectedEntry).getMenu()->no(); + return; + } + + this->left(); +} diff --git a/src/menuAction.cpp b/src/menuAction.cpp index f4bda6a..53fe8cb 100644 --- a/src/menuAction.cpp +++ b/src/menuAction.cpp @@ -1,67 +1,76 @@ -/** - * @file menuAction.cpp - * @author Alexander Klein (alex@kleiax.de) - * @brief Implentation of the class MenuAction - * @version 0.1 - * @date 2022-01-12 - * - * @copyright Copyright (c) 2022 - * - */ -#include "menuAction.h" - -MenuAction::MenuAction(const char* name, void (*function) (), void (*callback) ()) { - this->name = name; - this->function = function; - this->callback = callback; -} - -MenuAction::MenuAction(const char* name, MenuControl* menu) { - this->name = name; - this->menu = menu; - this->isMenu = true; -} - -MenuAction::MenuAction(const char* name, MenuActionWrapper* action) { - this->name = name; - this->action = action; -} - -MenuAction::~MenuAction() { - if (this->menu) - delete this->menu; - - if (this->action) - delete this->action; -} - -void MenuAction::runAction() { - if (isMenu) - this->menu->printMenu(); - else { - if (this->function) - this->function(); - else if (this->action) - this->action->action(); - else - std::cout << "Error in MenuAction::runAction" << std::endl; - } - - if (this->callback) - this->callback(); -} - -const char* MenuAction::getName() { - return this->name; -} - -bool MenuAction::getIsMenu() { - return this->isMenu; -} - -MenuControl* MenuAction::getMenu() { - if (isMenu) - return this->menu; - else - return nullptr; -} +/** + * @file menuAction.cpp + * @author Alexander Klein (alex@kleiax.de) + * @brief Implentation of the class MenuAction + * @version 0.1 + * @date 2022-01-12 + * + * @copyright Copyright (c) 2022 + * + */ +#include "menuAction.h" + +MenuAction::MenuAction(const char *name, void (*function)(), void (*callback)()) +{ + this->name = name; + this->function = function; + this->callback = callback; +} + +MenuAction::MenuAction(const char *name, MenuControl *menu) +{ + this->name = name; + this->menu = menu; + this->isMenu = true; +} + +MenuAction::MenuAction(const char *name, MenuActionWrapper *action) +{ + this->name = name; + this->action = action; +} + +MenuAction::~MenuAction() +{ + if (this->menu) + delete this->menu; + + if (this->action) + delete this->action; +} + +void MenuAction::runAction() +{ + if (isMenu) + this->menu->printMenu(); + else + { + if (this->function) + this->function(); + else if (this->action) + this->action->action(); + else + std::cout << "Error in MenuAction::runAction" << std::endl; + } + + if (this->callback) + this->callback(); +} + +const char *MenuAction::getName() +{ + return this->name; +} + +bool MenuAction::getIsMenu() +{ + return this->isMenu; +} + +MenuControl *MenuAction::getMenu() +{ + if (isMenu) + return this->menu; + else + return nullptr; +} diff --git a/src/menuControl.cpp b/src/menuControl.cpp index 3a5f520..2134507 100644 --- a/src/menuControl.cpp +++ b/src/menuControl.cpp @@ -1,29 +1,45 @@ -/** - * @file menuControl.cpp - * @author Alexander Klein (alex@kleiax.de) - * @brief - * @version 0.1 - * @date 2022-12-28 - * - * @copyright Copyright (c) 2022 - * - */ - -#include "menuControl.h" - -void MenuControl::print(String lineOne, String lineTwo) const { - if (this->lcd) { - lcd->clear(); - lcd->setCursor(0, 0); - lcd->print(lineOne.c_str()); - lcd->setCursor(0, 1); - lcd->print(lineTwo.c_str()); - } -} - -void MenuControl::setParentMenu(MenuControl* menu) { - this->parentMenu = menu; - DisplayWrapper* lcd = this->parentMenu->getLcd(); - if (lcd) - this->lcd = lcd; -} +/** + * @file menuControl.cpp + * @author Alexander Klein (alex@kleiax.de) + * @brief + * @version 0.1 + * @date 2022-12-28 + * + * @copyright Copyright (c) 2022 + * + */ + +#include "menuControl.h" +void MenuControl::update() +{ + if (this->updateDelay == 0) + return; + + if (millis() - this->lastUpdateMillis < this->updateDelay) + { + return; + } + + this->printMenu(); + this->lastUpdateMillis = millis(); +} + +void MenuControl::print(String lineOne, String lineTwo) const +{ + if (this->lcd) + { + lcd->clear(); + lcd->setCursor(0, 0); + lcd->print(lineOne.c_str()); + lcd->setCursor(0, 1); + lcd->print(lineTwo.c_str()); + } +} + +void MenuControl::setParentMenu(MenuControl *menu) +{ + this->parentMenu = menu; + DisplayWrapper *lcd = this->parentMenu->getLcd(); + if (lcd) + this->lcd = lcd; +} diff --git a/src/menuInformationSites.cpp b/src/menuInformationSites.cpp index 0c53788..280345a 100644 --- a/src/menuInformationSites.cpp +++ b/src/menuInformationSites.cpp @@ -1,96 +1,112 @@ -/** - * @file menuInformationSites.cpp - * @author Alexander Klein (alex@kleiax.de) - * @brief Contains an implementation of the class MenuInformationSites - * @version 0.1 - * @date 2022-12-27 - * - * @copyright Copyright (c) 2022 - * - */ - -#include "menuInformationSites.h" - -MenuInformationSites::MenuInformationSites(uint8_t pages) { - this->countPages = pages; - this->currentPage = 0; - this->lastMillis = millis(); -} - -void MenuInformationSites::up() { - if (this->currentPage == 0) - this->currentPage = this->countPages - 1; - else - this->currentPage--; - this->printMenu(); -} - -void MenuInformationSites::down() { - if (this->currentPage == this->countPages - 1) - this->currentPage = 0; - else - this->currentPage++; - this->printMenu(); -} - -void MenuInformationSites::right() { - this->yes(); -} - -void MenuInformationSites::left() { - if (this->parentMenu) { - this->parentMenu->prepareReenterMenu(); - this->parentMenu->printMenu(); - this->leaved = true; - } -} - -void MenuInformationSites::no() { - if (this->noEqualLeft) { - this->left(); - return; - } - this->runCommandNo(); - this->printMenu(); -} - -void MenuInformationSites::yes() { - this->runCommand(); - this->printMenu(); -} - -void MenuInformationSites::printMenu() { - if (this->leaved) { - this->leaved = false; - this->lastPageNumber++; - this->init(); - } - - this->printPage(); - this->lastPageNumber = this->currentPage; -} - -bool MenuInformationSites::setCountPages(uint8_t pages) { - this->countPages = pages; - this->currentPage = 0; - if (this->countPages == 0) { - this->countPages = 1; - return false; - } - return true; -} - -uint8_t MenuInformationSites::getCountPages() const { - return this->countPages; -} - -uint8_t MenuInformationSites::getCurrentPage() const { - return this->currentPage; -} - -void MenuInformationSites::printDefault() const { - String lineOne = String("Pagenumber: ") + (this->currentPage + 1); - String lineTwo = String("Pagecount : ") + this->countPages; - - this->print(lineOne, lineTwo); -} +/** + * @file menuInformationSites.cpp + * @author Alexander Klein (alex@kleiax.de) + * @brief Contains an implementation of the class MenuInformationSites + * @version 0.1 + * @date 2022-12-27 + * + * @copyright Copyright (c) 2022 + * + */ + +#include "menuInformationSites.h" + +MenuInformationSites::MenuInformationSites(uint8_t pages) +{ + this->countPages = pages; + this->currentPage = 0; + this->lastMillis = millis(); +} + +void MenuInformationSites::up() +{ + if (this->currentPage == 0) + this->currentPage = this->countPages - 1; + else + this->currentPage--; + this->printMenu(); +} + +void MenuInformationSites::down() +{ + if (this->currentPage == this->countPages - 1) + this->currentPage = 0; + else + this->currentPage++; + this->printMenu(); +} + +void MenuInformationSites::right() +{ + this->printMenu(); +} + +void MenuInformationSites::left() +{ + if (this->parentMenu) + { + this->parentMenu->prepareReenterMenu(); + this->parentMenu->printMenu(); + this->leaved = true; + } +} + +void MenuInformationSites::no() +{ + if (this->noEqualLeft) + { + this->left(); + return; + } + this->runCommandNo(); + this->printMenu(); +} + +void MenuInformationSites::yes() +{ + this->runCommand(); + this->printMenu(); +} + +void MenuInformationSites::printMenu() +{ + if (this->leaved) + { + this->leaved = false; + this->lastPageNumber++; + this->init(); + } + + this->printPage(); + this->lastPageNumber = this->currentPage; +} + +bool MenuInformationSites::setCountPages(uint8_t pages) +{ + this->countPages = pages; + this->currentPage = 0; + if (this->countPages == 0) + { + this->countPages = 1; + return false; + } + return true; +} + +uint8_t MenuInformationSites::getCountPages() const +{ + return this->countPages; +} + +uint8_t MenuInformationSites::getCurrentPage() const +{ + return this->currentPage; +} + +void MenuInformationSites::printDefault() const +{ + String lineOne = String("Pagenumber: ") + (this->currentPage + 1); + String lineTwo = String("Pagecount : ") + this->countPages; + + this->print(lineOne, lineTwo); +} diff --git a/src/menuIntInput.cpp b/src/menuIntInput.cpp index ff99925..33435be 100644 --- a/src/menuIntInput.cpp +++ b/src/menuIntInput.cpp @@ -1,222 +1,253 @@ -/** - * @file menuIntInput.cpp - * @author Alexander Klein (alex@kleiax.de) - * @brief - * @version 0.1 - * @date 2022-09-12 - * - * @copyright Copyright (c) 2022 - * - */ - -#include "menuIntInput.h" - -MenuIntInput::MenuIntInput(int16_t values[], char *names, uint8_t length, MenuIntInputWrapper* wrapper) { - this->values = values; - this->names = names; - this->length = length; - this->wrapper = wrapper; - - this->min = new int16_t[this->length]; - this->max = new int16_t[this->length]; - this->originalValues = new int16_t[this->length]; - this->stepsPerInput = new uint8_t[this->length]; - - for (uint8_t i = 0; i < this->length; i++) { - this->min[i] = INT16_MIN; - this->max[i] = INT16_MAX; - this->originalValues[i] = this->values[i]; - this->stepsPerInput[i] = 1; - } -} - -MenuIntInput::MenuIntInput(uint8_t length, MenuIntInputWrapper *wrapper) { - this->length = length; - this->wrapper = wrapper; - - this->values = new int16_t[this->length]; - this->names = (char*) new char[this->length][MAX_NAME_LENGTH]; - this->min = new int16_t[this->length]; - this->max = new int16_t[this->length]; - this->originalValues = new int16_t[this->length]; - this->stepsPerInput = new uint8_t[this->length]; - - for (uint8_t i = 0; i < this->length; i++) { - this->min[i] = INT16_MIN; - this->max[i] = INT16_MAX; - this->values[i] = 0; - this->originalValues[i] = 0; - this->stepsPerInput[i] = 1; - strcpy(this->names + MAX_NAME_LENGTH * i, "Default"); - } -} - -MenuIntInput::~MenuIntInput() { - delete this->min; - delete this->max; - delete this->originalValues; - delete this->stepsPerInput; - delete this->values; - delete this->names; - delete this->wrapper; -} - -void MenuIntInput::setEntry(uint8_t valueNumber, const char* name, int16_t startValue) { - if (this->length < valueNumber) - return; - - if (strlen(name) > MAX_NAME_LENGTH) - return; - - - strcpy(this->names + MAX_NAME_LENGTH * valueNumber, name); - this->values[valueNumber] = startValue; - this->originalValues[valueNumber] = startValue; -} - -void MenuIntInput::setMin(uint8_t valueNumber, int16_t min) { - if (this->length < valueNumber) - return; - - this->min[valueNumber] = min; -} - -void MenuIntInput::setMax(uint8_t valueNumber, int16_t max) { - if (this->length < valueNumber) - return; - - this->max[valueNumber] = max; -} - -void MenuIntInput::setMinMax(uint8_t valueNumber, int16_t min, int16_t max) { - this->setMin(valueNumber, min); - this->setMax(valueNumber, max); -} - -void MenuIntInput::setMin(int16_t min) { - for (uint8_t i = 0; i < this->length; i++) - this->min[i] = min; -} - -void MenuIntInput::setMax(int16_t max) { - for (uint8_t i = 0; i < this->length; i++) - this->max[i] = max; -} - -void MenuIntInput::setMinMax(int16_t min, int16_t max) { - this->setMin(min); - this->setMax(max); -} - -void MenuIntInput::setMinMaxSteps(uint8_t valueNumber, int16_t min, int16_t max, uint8_t steps) { - this->setMin(valueNumber, min); - this->setMax(valueNumber, max); - this->setStepsPerInput(valueNumber, steps); -} - -void MenuIntInput::setMinMaxSteps(int16_t min, int16_t max, uint8_t steps) { - this->setMin(min); - this->setMax(max); - this->setStepsPerInput(steps); -} - -void MenuIntInput::setStepsPerInput(uint8_t valueNumber, uint8_t steps) { - if (this->length < valueNumber) - return; - - this->stepsPerInput[valueNumber] = steps; -} - -void MenuIntInput::setStepsPerInput(uint8_t steps) { - for (uint8_t i = 0; i < this->length; i++) - this->stepsPerInput[i] = steps; -} - -void MenuIntInput::down() { - if (this->values[this->currentPosition] - - this->stepsPerInput[this->currentPosition] - >= this->min[currentPosition]) - { - this->values[this->currentPosition] -= this->stepsPerInput[this->currentPosition]; - } else { - this->values[this->currentPosition] = this->max[this->currentPosition]; - } - - this->printMenu(); -} - -void MenuIntInput::up() { - if (this->values[this->currentPosition] - + this->stepsPerInput[this->currentPosition] - <= this->max[this->currentPosition]) - { - this->values[this->currentPosition] += this->stepsPerInput[this->currentPosition]; - } else { - this->values[this->currentPosition] = this->min[this->currentPosition]; - } - - this->printMenu(); -} - -void MenuIntInput::right() { - if (currentPosition < this->length - 1) - currentPosition++; - else - currentPosition = 0; - - this->printMenu(); -} - -void MenuIntInput::left() { - if (currentPosition > 0) - currentPosition--; - else - currentPosition = this->length - 1; - - this->printMenu(); -} - -void MenuIntInput::no() { - for (uint8_t i = 0; i < this->length; i++) - this->values[i] = this->originalValues[i]; - this->currentPosition = 0; - - if (this->parentMenu) { - this->parentMenu->prepareReenterMenu(); - this->parentMenu->printMenu(); - } -} - -void MenuIntInput::yes() { - this->wrapper->action(this->values, this->length); - if (this->parentMenu && printParentMenu){ - this->parentMenu->prepareReenterMenu(); - this->parentMenu->printMenu(); - } -} - -void MenuIntInput::printMenu() { - char bufferName[17]; - - if (this->currentPosition == 0 && this->length == 1) { - // No arrow - sprintf(bufferName, " %s ", this->names + MAX_NAME_LENGTH * this->currentPosition); - } else if (this->currentPosition > 0 && this->length - 1 == this->currentPosition) { - // Left arrow only - sprintf(bufferName, "< %s ", this->names + MAX_NAME_LENGTH * this->currentPosition); - } else if (this->currentPosition == 0 && this->length > 1) { - // Right arrow only - sprintf(bufferName, " %s >", this->names + MAX_NAME_LENGTH * this->currentPosition); - } else { - // Both arrow - sprintf(bufferName, "< %s >", this->names + MAX_NAME_LENGTH * this->currentPosition); - } - - char bufferValue[17]; - if (this->values[this->currentPosition]) - sprintf(bufferValue, " -> %5.d", this->values[this->currentPosition]); - else - sprintf(bufferValue, " -> 0"); - - this->print(bufferName, bufferValue); -} +/** + * @file menuIntInput.cpp + * @author Alexander Klein (alex@kleiax.de) + * @brief + * @version 0.1 + * @date 2022-09-12 + * + * @copyright Copyright (c) 2022 + * + */ + +#include "menuIntInput.h" + +MenuIntInput::MenuIntInput(int16_t values[], char *names, uint8_t length, MenuIntInputWrapper *wrapper) +{ + this->values = values; + this->names = names; + this->length = length; + this->wrapper = wrapper; + + this->min = new int16_t[this->length]; + this->max = new int16_t[this->length]; + this->originalValues = new int16_t[this->length]; + this->stepsPerInput = new uint8_t[this->length]; + + for (uint8_t i = 0; i < this->length; i++) + { + this->min[i] = INT16_MIN; + this->max[i] = INT16_MAX; + this->originalValues[i] = this->values[i]; + this->stepsPerInput[i] = 1; + } +} + +MenuIntInput::MenuIntInput(uint8_t length, MenuIntInputWrapper *wrapper) +{ + this->length = length; + this->wrapper = wrapper; + + this->values = new int16_t[this->length]; + this->names = (char *)new char[this->length][MAX_NAME_LENGTH]; + this->min = new int16_t[this->length]; + this->max = new int16_t[this->length]; + this->originalValues = new int16_t[this->length]; + this->stepsPerInput = new uint8_t[this->length]; + + for (uint8_t i = 0; i < this->length; i++) + { + this->min[i] = INT16_MIN; + this->max[i] = INT16_MAX; + this->values[i] = 0; + this->originalValues[i] = 0; + this->stepsPerInput[i] = 1; + strcpy(this->names + MAX_NAME_LENGTH * i, "Default"); + } +} + +MenuIntInput::~MenuIntInput() +{ + delete this->min; + delete this->max; + delete this->originalValues; + delete this->stepsPerInput; + delete this->values; + delete this->names; + delete this->wrapper; +} + +void MenuIntInput::setEntry(uint8_t valueNumber, const char *name, int16_t startValue) +{ + if (this->length < valueNumber) + return; + + if (strlen(name) > MAX_NAME_LENGTH) + return; + + strcpy(this->names + MAX_NAME_LENGTH * valueNumber, name); + this->values[valueNumber] = startValue; + this->originalValues[valueNumber] = startValue; +} + +void MenuIntInput::setMin(uint8_t valueNumber, int16_t min) +{ + if (this->length < valueNumber) + return; + + this->min[valueNumber] = min; +} + +void MenuIntInput::setMax(uint8_t valueNumber, int16_t max) +{ + if (this->length < valueNumber) + return; + + this->max[valueNumber] = max; +} + +void MenuIntInput::setMinMax(uint8_t valueNumber, int16_t min, int16_t max) +{ + this->setMin(valueNumber, min); + this->setMax(valueNumber, max); +} + +void MenuIntInput::setMin(int16_t min) +{ + for (uint8_t i = 0; i < this->length; i++) + this->min[i] = min; +} + +void MenuIntInput::setMax(int16_t max) +{ + for (uint8_t i = 0; i < this->length; i++) + this->max[i] = max; +} + +void MenuIntInput::setMinMax(int16_t min, int16_t max) +{ + this->setMin(min); + this->setMax(max); +} + +void MenuIntInput::setMinMaxSteps(uint8_t valueNumber, int16_t min, int16_t max, uint8_t steps) +{ + this->setMin(valueNumber, min); + this->setMax(valueNumber, max); + this->setStepsPerInput(valueNumber, steps); +} + +void MenuIntInput::setMinMaxSteps(int16_t min, int16_t max, uint8_t steps) +{ + this->setMin(min); + this->setMax(max); + this->setStepsPerInput(steps); +} + +void MenuIntInput::setStepsPerInput(uint8_t valueNumber, uint8_t steps) +{ + if (this->length < valueNumber) + return; + + this->stepsPerInput[valueNumber] = steps; +} + +void MenuIntInput::setStepsPerInput(uint8_t steps) +{ + for (uint8_t i = 0; i < this->length; i++) + this->stepsPerInput[i] = steps; +} + +void MenuIntInput::down() +{ + if (this->values[this->currentPosition] - this->stepsPerInput[this->currentPosition] >= this->min[currentPosition]) + { + this->values[this->currentPosition] -= this->stepsPerInput[this->currentPosition]; + } + else + { + this->values[this->currentPosition] = this->max[this->currentPosition]; + } + + this->printMenu(); +} + +void MenuIntInput::up() +{ + if (this->values[this->currentPosition] + this->stepsPerInput[this->currentPosition] <= this->max[this->currentPosition]) + { + this->values[this->currentPosition] += this->stepsPerInput[this->currentPosition]; + } + else + { + this->values[this->currentPosition] = this->min[this->currentPosition]; + } + + this->printMenu(); +} + +void MenuIntInput::right() +{ + if (currentPosition < this->length - 1) + currentPosition++; + else + currentPosition = 0; + + this->printMenu(); +} + +void MenuIntInput::left() +{ + if (currentPosition > 0) + currentPosition--; + else + currentPosition = this->length - 1; + + this->printMenu(); +} + +void MenuIntInput::no() +{ + for (uint8_t i = 0; i < this->length; i++) + this->values[i] = this->originalValues[i]; + this->currentPosition = 0; + + if (this->parentMenu) + { + this->parentMenu->prepareReenterMenu(); + this->parentMenu->printMenu(); + } +} + +void MenuIntInput::yes() +{ + this->wrapper->action(this->values, this->length); + if (this->parentMenu && printParentMenu) + { + this->parentMenu->prepareReenterMenu(); + this->parentMenu->printMenu(); + } +} + +void MenuIntInput::printMenu() +{ + char bufferName[17]; + + if (this->currentPosition == 0 && this->length == 1) + { + // No arrow + sprintf(bufferName, " %s ", this->names + MAX_NAME_LENGTH * this->currentPosition); + } + else if (this->currentPosition > 0 && this->length - 1 == this->currentPosition) + { + // Left arrow only + sprintf(bufferName, "< %s ", this->names + MAX_NAME_LENGTH * this->currentPosition); + } + else if (this->currentPosition == 0 && this->length > 1) + { + // Right arrow only + sprintf(bufferName, " %s >", this->names + MAX_NAME_LENGTH * this->currentPosition); + } + else + { + // Both arrow + sprintf(bufferName, "< %s >", this->names + MAX_NAME_LENGTH * this->currentPosition); + } + + char bufferValue[17]; + if (this->values[this->currentPosition]) + sprintf(bufferValue, " -> %5.d", this->values[this->currentPosition]); + else + sprintf(bufferValue, " -> 0"); + + this->print(bufferName, bufferValue); +}