14 Commits
Author SHA1 Message Date
kleiax 35b1478666 doxygen fix 2023-10-12 19:53:03 +02:00
kleiax 9b8bf22795 doxygen comments 2023-10-12 19:50:26 +02:00
kleiax f05ab56833 call prepareReenter in SpecialMenus 2023-09-27 15:27:44 +02:00
kleiax 52c1fe25c8 add function for prepare rentering a menu 2023-09-27 15:19:32 +02:00
kleiax 230fa1ba62 remove const for runCommand 2023-09-27 13:39:28 +02:00
kleiax cbfbad26ae move the bool for skip from private to protected 2023-09-23 22:13:24 +02:00
kleiax 79b4cd4018 possibility to skip no and do left 2023-09-23 22:03:14 +02:00
kleiax 341add1deb remove multiple definition of function declarition 2023-08-18 16:30:31 +02:00
kleiax 155fd73c81 fix syntax 2023-08-18 16:28:16 +02:00
kleiax 67315f18b3 menuinformation site - add second action
inherit lcd Wrapper
2023-08-18 15:59:00 +02:00
kleiax 7de343d08a Update MenuInfornationSites printDefault() 2023-05-11 12:59:11 +02:00
kleiax 6b57b3fdb4 fix wrong variable name 2023-04-26 08:11:45 +02:00
kleiax 0ab6c829d5 removed old update functions 2023-04-26 07:57:00 +02:00
kleiax db3c25da42 mnoved update delay to base class and make
it setAble
2023-04-26 07:54:57 +02:00
12 changed files with 1345 additions and 987 deletions
+45 -22
View File
@@ -1,22 +1,45 @@
/** /**
* @file displayWrapper.h * @file displayWrapper.h
* @author Alexander Klein (alex@kleiax.de) * @author Alexander Klein (alex@kleiax.de)
* @brief * @brief Contains a interface to presents a display
* @version 0.1 * @version 0.1
* @date 2023-01-08 * @date 2023-01-08
* *
* @copyright Copyright (c) 2023 * @copyright Copyright (c) 2023
* *
*/ */
#ifndef DISPLAY_WRAPPER_H #ifndef DISPLAY_WRAPPER_H
#define DISPLAY_WRAPPER_H #define DISPLAY_WRAPPER_H
class DisplayWrapper { /**
public: * @brief This interface abstracted a display
virtual void clear() = 0; *
virtual void setCursor(uint8_t row, uint8_t line) = 0; * With this inteface a display which works with columns
virtual void print(const char *str) = 0; * and lines can be wrapped to be accepted by menus.
}; */
class DisplayWrapper
#endif // DISPLAY_WRAPPER_H {
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
+75 -55
View File
@@ -1,55 +1,75 @@
/** /**
* @file menu.h * @file menu.h
* @author Alexander Klein (alex@kleiax.de) * @author Alexander Klein (alex@kleiax.de)
* @brief Contains the Menu class * @brief Contains the Menu class
* @version 0.1 * @version 0.1
* @date 2022-01-12 * @date 2022-01-12
* *
* @copyright Copyright (c) 2022 * @copyright Copyright (c) 2022
* *
*/ */
#ifndef MENU_H #ifndef MENU_H
#define MENU_H #define MENU_H
#include <list> #include <list>
#include "menuAction.h" #include "menuAction.h"
#include "menuControl.h" #include "menuControl.h"
class MenuAction; class MenuAction;
/** /**
* @brief A class to build menu structers * @brief A class to build menu structures
*/ */
class Menu : public MenuControl { class Menu : public MenuControl
public: {
Menu(); public:
~Menu() override; Menu();
~Menu() override;
/**
* @brief Add a menu action to the menu /**
* * @brief Add a MenuAction to the menu
* @param entry *
*/ * Every MenuAction is an Entry in the Menu
void addEntry(MenuAction* entry); *
bool isInSubmenu(); * @param entry
*/
void printMenu() override; void addEntry(MenuAction *entry);
void update() override;
/**
void down() override; * @brief get information about the active menu
void up() override; *
void right() override; * If this is not the active menu, will be passed to
void left() override; * active menu.
void yes() override; *
void no() override; * @return true an other menu is active
* @return false this menu is active
private: */
bool inSubmenu = false; bool isInSubmenu();
std::list<MenuAction*> entrys; /**
std::list<MenuAction*>::iterator selectedEntry; * @brief Print the actual screen
*/
}; void printMenu() override;
#endif // MENU_H /**
* @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<MenuAction *> entries;
std::list<MenuAction *>::iterator selectedEntry;
};
#endif // MENU_H
+113 -103
View File
@@ -1,103 +1,113 @@
/** /**
* @file menuAction.h * @file menuAction.h
* @author Alexander Klein (alex@kleiax.de) * @author Alexander Klein (alex@kleiax.de)
* @brief Contains the MenuAction class * @brief Contains the MenuAction class
* @version 0.1 * @version 0.1
* @date 2022-01-12 * @date 2022-01-12
* *
* @copyright Copyright (c) 2022 * @copyright Copyright (c) 2022
* *
*/ */
#ifndef MENU_ENTRY_H #ifndef MENU_ENTRY_H
#define MENU_ENTRY_H #define MENU_ENTRY_H
#include "menu.h" #include "menu.h"
class MenuControl; class MenuControl;
class MenuActionWrapper { /**
public: * @brief An Interface to execute actions
virtual ~MenuActionWrapper() {} *
virtual void action() = 0; * This interface can be inherited to wrap actions
}; * in it for a MenuAction.
*/
/** class MenuActionWrapper
* @brief This class forms the transition between menus. {
* public:
* In the Menu these are the entries. virtual ~MenuActionWrapper() {}
* This class can be call an submenu or a function. /**
*/ * @brief Function to be called by the MenuAction
class MenuAction { */
public: virtual void action() = 0;
};
/**
* @brief Construct a new Menu Action object /**
* * @brief This class forms the transition between menus.
* @param name shown in the Menu *
* @param function to call when activate the entry * In the Menu these are the entries.
* @param callback to call when leave the entry * This class can be call an submenu or a function.
*/ */
MenuAction(const char* name, void (*function) (), void (*callback) () = nullptr); class MenuAction
{
/** public:
* @brief Construct a new Menu Action object /**
* * @brief Construct a new Menu Action object
* @param name shown in the Menu *
* @param action to call when activate the entry * @param name shown in the Menu
*/ * @param function to call when activate the entry
MenuAction(const char* name, MenuActionWrapper* action); * @param callback to call when leave the entry
*/
/** MenuAction(const char *name, void (*function)(), void (*callback)() = nullptr);
* @brief Construct a new Menu Action object
* /**
* This constructer is used for submenus. * @brief Construct a new Menu Action object
* *
* @param name shown in the Menu * @param name shown in the Menu
* @param menu to call when activate the entry * @param action to call when activate the entry
*/ */
MenuAction(const char* name, MenuControl* menu); MenuAction(const char *name, MenuActionWrapper *action);
~MenuAction(); /**
* @brief Construct a new Menu Action object
/** *
* @brief activates the entry * This constructor is used for submenus.
*/ *
void runAction(); * @param name shown in the Menu
* @param menu to call when activate the entry
/** */
* @brief Get the Name string MenuAction(const char *name, MenuControl *menu);
*
* @return const char* ~MenuAction();
*/
const char* getName(); /**
* @brief activates the entry
/** */
* @brief Get the Is Menu object void runAction();
*
* @return true runAction calls a submenu /**
* @return false runAction call a function * @brief Get the Name string
*/ *
bool getIsMenu(); * @return const char*
*/
/** const char *getName();
* @brief Get the Menu object
* /**
* Before call this function it may be useful * @brief Get the Is Menu object
* to check if is it a submenu with getIsMenu. *
* * @return true runAction calls a submenu
* @return MenuControl* * @return false runAction call a function
*/ */
MenuControl* getMenu(); bool getIsMenu();
private: /**
const char* name; * @brief Get the Menu object
*
void (*function) () = nullptr; * Before call this function it may be useful
void (*callback) () = nullptr; * to check if is it a submenu with getIsMenu.
*
bool isMenu = false; * @return MenuControl*
MenuControl* menu = nullptr; */
MenuActionWrapper* action = nullptr; MenuControl *getMenu();
};
private:
#endif // MENU_ENTRY_H const char *name;
void (*function)() = nullptr;
void (*callback)() = nullptr;
bool isMenu = false;
MenuControl *menu = nullptr;
MenuActionWrapper *action = nullptr;
};
#endif // MENU_ENTRY_H
+118 -78
View File
@@ -1,78 +1,118 @@
/** /**
* @file menuControl.h * @file menuControl.h
* @author Alexander Klein (alex@kleiax.de) * @author Alexander Klein (alex@kleiax.de)
* @brief Contains a abstract class for Menu * @brief Contains a abstract class for Menu
* @version 0.1 * @version 0.1
* @date 2022-01-19 * @date 2022-01-19
* *
* @copyright Copyright (c) 2022 * @copyright Copyright (c) 2022
* *
*/ */
#ifndef MENU_CONTROLL_H #ifndef MENU_CONTROLL_H
#define MENU_CONTROLL_H #define MENU_CONTROLL_H
#include <Arduino.h> #include <Arduino.h>
#include <iostream> #include <iostream>
#include "displayWrapper.h" #include "displayWrapper.h"
/** /**
* @brief Baseclass to build Menus * @brief Baseclass to build Menus
* *
* This class have to be inherited by other classes which want to be * This class have to be inherited by other classes which want to be
* act as a menu, because the menu structure uses polymorphism. * act as a menu, because the menu structure uses polymorphism.
* *
*/ */
class MenuControl { class MenuControl
public: {
virtual ~MenuControl() {}; public:
virtual ~MenuControl(){};
/** @name UserInputs
* @brief This functions should be called be user actions. /** @name UserInputs
* * @brief This functions should be called be user actions.
* This functions have to be implement in every other menu *
* class. * This functions have to be implement in every other menu
*/ * class.
///@{ */
virtual void down() {}; ///@{
virtual void up() {}; virtual void down(){};
virtual void right() {}; virtual void up(){};
virtual void left() {}; virtual void right(){};
virtual void yes() {}; virtual void left(){};
virtual void no() {}; virtual void yes(){};
///@} virtual void no(){};
///@}
/**
* @brief can be called to update shown data /**
*/ * @brief can be called to update shown data
virtual void update() {} *
* The data will be only updated if a updateDelay is set
virtual void printMenu() = 0; * and delay is reached.
*/
/** virtual void update();
* @brief Set the Parent Menu
* /**
* If the parentMenu is set it will be called automaticaly * @brief Prepare reenter the this menu
* when the user left the child menu. *
* * This function must be called separately
* @param menu */
*/ virtual void prepareReenterMenu() {}
void setParentMenu(MenuControl* menu) { this->parentMenu = menu; }
// MenuControl* getParentMenu() { return this->parentMenu; } /**
* @brief Function to print the Menu
/** *
* @brief Set the Lcd object * Have to be overwritten to implement the representation
* * of the menu.
* If this is set the menu will be print on the display too. * This function have to call the print() function to access
* * the display.
* @param lcd */
*/ virtual void printMenu() = 0;
void setLcd(DisplayWrapper* lcd) { this->lcd = lcd; }
/**
protected: * @brief Set the Parent Menu
void print(String lineOne, String lineTwo) const; *
* If the parentMenu is set it will be called automaticaly
MenuControl* parentMenu = nullptr; * when the user left the child menu.
DisplayWrapper* lcd = nullptr; * If the parentMenu has set a LCD it will be copied to the
}; * actual instance.
#endif // MENU_CONTROLL_H *
* @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
+153 -92
View File
@@ -1,92 +1,153 @@
/** /**
* @file menuInformationSites.h * @file menuInformationSites.h
* @author Alexander Klein (alex@kleiax.de) * @author Alexander Klein (alex@kleiax.de)
* @brief Contains a class to print informations over more pages * @brief Contains a class to print informations over more pages
* @version 0.1 * @version 0.1
* @date 2022-12-27 * @date 2022-12-27
* *
* @copyright Copyright (c) 2022 * @copyright Copyright (c) 2022
* *
*/ */
#ifndef MENU_INFORMATION_SITES_H #ifndef MENU_INFORMATION_SITES_H
#define MENU_INFORMATION_SITES_H #define MENU_INFORMATION_SITES_H
#include "menuControl.h" #include "menuControl.h"
class MenuInformationSites : public MenuControl { /**
public: * @brief A Menu interface to show informations
/** *
* @brief Construct a new Menu Information Sites object * The informations a organized by multiple pages
* */
* @param amount of pages class MenuInformationSites : public MenuControl
*/ {
MenuInformationSites(uint8_t pages = 1); public:
/**
/** * @brief Construct a new Menu Information Sites object
* @brief Next page *
*/ * @param pages amount of the available pages
void down() override; */
MenuInformationSites(uint8_t pages = 1);
/**
* @brief Previous page /**
*/ * @brief Next page
void up() override; */
void down() override;
/**
* @brief Update information /**
*/ * @brief Previous page
void right() override; */
void up() override;
/**
* @brief Go to the parent menu /**
*/ * @brief Update information
void left() override; */
void right() override;
/**
* @brief Go to the parent menu /**
*/ * @brief Go to the parent menu
void no() override; */
void left() override;
/**
* @brief Update information /**
*/ * @brief Calls runCommandNo()
void yes() override; */
void no() override;
/**
* @brief Prints the Information to display and console /**
* * @brief Calls runCommand()
* Prints the selected page. */
* The informations are only printed to the display if it void yes() override;
* set.
*/ /**
void printMenu() override; * @brief Prints the Information to display and console
*
/** * Prints the selected page.
* @brief can be called to update shown data */
*/ void printMenu() override;
void update() override;
protected:
protected: /**
bool setCountPages(uint8_t pages); * @brief Change the amount of available pages
uint8_t getCountPages() const; *
uint8_t getCurrentPage() const; * @param pages
* @return true successful
virtual void printPage() const = 0; * @return false
virtual void runCommand() const {} */
virtual void init() {} bool setCountPages(uint8_t pages);
void printDefault() const; /**
* @brief Get the amount of available pages
uint8_t lastPageNumber = 0; *
bool leaved = true; * @return uint8_t
*/
private: uint8_t getCountPages() const;
uint8_t countPages;
uint8_t currentPage; /**
* @brief Get the selected page number
*
const uint16_t delay = 5000; * @return uint8_t
uint32_t lastMillis = 0; */
}; uint8_t getCurrentPage() const;
#endif // MENU_INFORMATION_SITES_H /**
* @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
+202 -103
View File
@@ -1,103 +1,202 @@
/** /**
* @file menuIntInput.h * @file menuIntInput.h
* @author Alexander Klein (alex@kleiax.de) * @author Alexander Klein (alex@kleiax.de)
* @brief * @brief Contains a class to get integer inputs from the user
* @version 0.1 * @version 0.1
* @date 2022-09-12 * @date 2022-09-12
* *
* @copyright Copyright (c) 2022 * @copyright Copyright (c) 2022
* *
*/ */
#ifndef MENU_INT_INPUT_H #ifndef MENU_INT_INPUT_H
#define MENU_INT_INPUT_H #define MENU_INT_INPUT_H
#include "menuControl.h" #include "menuControl.h"
#include <stdint.h> #include <stdint.h>
#define MAX_NAME_LENGTH 12 #define MAX_NAME_LENGTH 12
class MenuIntInputWrapper { /**
public: * @brief Interface to transfer the integer data
virtual ~MenuIntInputWrapper() {} */
virtual void action(int16_t* values, uint8_t length) = 0; class MenuIntInputWrapper
}; {
public:
class MenuIntInput : public MenuControl { virtual ~MenuIntInputWrapper() {}
public:
MenuIntInput(int16_t values[], char *names, uint8_t length, MenuIntInputWrapper* wrapper); /**
MenuIntInput(uint8_t length, MenuIntInputWrapper *wrapper); * @brief Transfer function
~MenuIntInput(); *
* This function will be called by MenuIntInput, if the input
void setEntry(uint8_t valueNumber, const char* name, int16_t startValue = 0); * are confirmed.
*
void setMin(uint8_t valueNumber, int16_t min); * @param values
void setMin(int16_t min); * @param length amount of integer
void setMax(uint8_t valueNumber, int16_t max); */
void setMax(int16_t max); virtual void action(int16_t *values, uint8_t length) = 0;
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); * @brief A Menu class to make integer inputs
void setPrintParentMenu(bool b) { this->printParentMenu = b; } */
class MenuIntInput : public MenuControl
void setStepsPerInput(uint8_t valueNumber, uint8_t steps); {
void setStepsPerInput(uint8_t steps); public:
/**
/** * @brief Construct a new Menu Int Input object
* @brief Decrement selected value *
*/ * @param values the integer values
void down() override; * @param names names of the values
* @param length amount of values
/** * @param wrapper MenuIntInputWrapper
* @brief Increment selected value */
*/ MenuIntInput(int16_t values[], char *names, uint8_t length, MenuIntInputWrapper *wrapper);
void up() override; MenuIntInput(uint8_t length, MenuIntInputWrapper *wrapper);
~MenuIntInput();
/**
* @brief Select next value /**
*/ * @brief Set a specific entry
void right() override; *
* @param valueNumber the entry
/** * @param name name of entry
* @brief Select previous value * @param startValue default value
*/ */
void left() override; void setEntry(uint8_t valueNumber, const char *name, int16_t startValue = 0);
/** /**
* @brief Leave menu without saving * @brief Set the minium for a specific value
*/ *
void no() override; * @param valueNumber the entry
* @param min
/** */
* @brief Leave menu with saving void setMin(uint8_t valueNumber, int16_t min);
*/
void yes() override; /**
* @brief Set the minimum for all entries
/** *
* @brief Prints the Information to display and console * @param min
* */
* The informations are only printed to the display if it void setMin(int16_t min);
* set.
*/ /**
void printMenu() override; * @brief Set the maximum for a specific value
*
void update() override {}; * @param valueNumber the entry
* @param max
private: */
MenuIntInputWrapper* wrapper; void setMax(uint8_t valueNumber, int16_t max);
bool printParentMenu = true; /**
* @brief Set the maximum for all entries
uint8_t currentPosition = 0; *
uint8_t length; * @param max
uint8_t *stepsPerInput; */
uint8_t countSameActions = 0; void setMax(int16_t max);
int16_t *values;
int16_t *originalValues; /**
int16_t *min; * @brief Set the minium and the maximum for a specific value
int16_t *max; *
char *names; * @param valueNumber the entry
* @param min
}; * @param max
*/
#endif // MENU_INT_INPUT_H void setMinMax(uint8_t valueNumber, int16_t min, int16_t max);
/**
* @brief Set the minium and the maximum for all entries
*
* @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 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
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "Menu", "name": "Menu",
"version": "1.0.1", "version": "1.1.2",
"description": "Build page based menus on uCs", "description": "Build page based menus on uCs",
"keywords": "menu, page, input", "keywords": "menu, page, input",
"repository": "repository":
+152 -128
View File
@@ -1,128 +1,152 @@
/** /**
* @file menu.cpp * @file menu.cpp
* @author Alexander Klein (alex@kleiax.de) * @author Alexander Klein (alex@kleiax.de)
* @brief Implementation of the class Menu * @brief Implementation of the class Menu
* @version 0.1 * @version 0.1
* @date 2022-01-12 * @date 2022-01-12
* *
* @copyright Copyright (c) 2022 * @copyright Copyright (c) 2022
* *
*/ */
#include "menu.h" #include "menu.h"
Menu::Menu() { Menu::Menu()
this->selectedEntry = this->entrys.begin(); {
} this->selectedEntry = this->entries.begin();
}
Menu::~Menu() {
for (std::list<MenuAction*>::iterator iter = this->entrys.begin(); iter != this->entrys.end(); iter++) Menu::~Menu()
delete *iter; {
} for (std::list<MenuAction *>::iterator iter = this->entries.begin(); iter != this->entries.end(); iter++)
delete *iter;
void Menu::addEntry(MenuAction* entry) { }
this->entrys.push_back(entry);
void Menu::addEntry(MenuAction *entry)
if (this->entrys.size() == 2) {
this->selectedEntry = this->entrys.begin(); this->entries.push_back(entry);
}
if (this->entries.size() == 2)
bool Menu::isInSubmenu() { this->selectedEntry = this->entries.begin();
return this->inSubmenu; }
}
bool Menu::isInSubmenu()
void Menu::printMenu() { {
std::list<MenuAction*>::iterator iter = this->selectedEntry; return this->inSubmenu;
}
String lineOne = "-> ";
String lineTwo = ""; void Menu::printMenu()
{
lineOne.concat((**iter).getName()); std::list<MenuAction *>::iterator iter = this->selectedEntry;
iter++;
if (iter != this->entrys.end()) { String lineOne = "-> ";
lineTwo.concat((**iter).getName()); String lineTwo = "";
} else
lineTwo.concat((*this->entrys.begin())->getName()); lineOne.concat((**iter).getName());
iter++;
this->inSubmenu = false; if (iter != this->entries.end())
this->print(lineOne, lineTwo); {
} lineTwo.concat((**iter).getName());
}
void Menu::update() { else
if (this->inSubmenu) { lineTwo.concat((*this->entries.begin())->getName());
(**this->selectedEntry).getMenu()->update();
return; this->inSubmenu = false;
} this->print(lineOne, lineTwo);
} }
void Menu::down() { void Menu::update()
if (this->inSubmenu) { {
(**this->selectedEntry).getMenu()->down(); if (this->inSubmenu)
return; {
} (**this->selectedEntry).getMenu()->update();
return;
// TODO: Why I need the fucking next two lines? here and in the next function }
std::list<MenuAction*>::iterator iter = this->selectedEntry; }
iter++;
if (iter != this->entrys.end()) void Menu::down()
this->selectedEntry++; {
else if (this->inSubmenu)
this->selectedEntry = this->entrys.begin(); {
this->printMenu(); (**this->selectedEntry).getMenu()->down();
} return;
}
void Menu::up() {
if (this->inSubmenu) { // TODO: Why I need the fucking next two lines? here and in the next function
(**this->selectedEntry).getMenu()->up(); std::list<MenuAction *>::iterator iter = this->selectedEntry;
return; iter++;
} if (iter != this->entries.end())
std::list<MenuAction*>::iterator iter = this->entrys.end(); this->selectedEntry++;
iter--; else
if (this->selectedEntry != this->entrys.begin()) { this->selectedEntry = this->entries.begin();
this->selectedEntry--; this->printMenu();
} }
else {
this->selectedEntry = iter; void Menu::up()
} {
this->printMenu(); if (this->inSubmenu)
} {
(**this->selectedEntry).getMenu()->up();
void Menu::right() { return;
if (this->inSubmenu) { }
(**this->selectedEntry).getMenu()->right(); std::list<MenuAction *>::iterator iter = this->entries.end();
return; iter--;
} if (this->selectedEntry != this->entries.begin())
{
if ((**this->selectedEntry).getIsMenu()) { this->selectedEntry--;
this->inSubmenu = true; }
(**this->selectedEntry).getMenu()->setParentMenu(this); else
} {
(**this->selectedEntry).runAction(); this->selectedEntry = iter;
} }
this->printMenu();
void Menu::left() { }
if (this->inSubmenu) {
(**this->selectedEntry).getMenu()->left(); void Menu::right()
return; {
} if (this->inSubmenu)
{
if (parentMenu) (**this->selectedEntry).getMenu()->right();
this->parentMenu->printMenu(); return;
} }
void Menu::yes() { if ((**this->selectedEntry).getIsMenu())
if (this->inSubmenu) { {
(**this->selectedEntry).getMenu()->yes(); this->inSubmenu = true;
return; (**this->selectedEntry).getMenu()->setParentMenu(this);
} }
(**this->selectedEntry).runAction();
this->right(); }
}
void Menu::left()
void Menu::no() { {
if (this->inSubmenu) { if (this->inSubmenu)
(**this->selectedEntry).getMenu()->no(); {
return; (**this->selectedEntry).getMenu()->left();
} return;
}
this->left();
} 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();
}
+76 -67
View File
@@ -1,67 +1,76 @@
/** /**
* @file menuAction.cpp * @file menuAction.cpp
* @author Alexander Klein (alex@kleiax.de) * @author Alexander Klein (alex@kleiax.de)
* @brief Implentation of the class MenuAction * @brief Implentation of the class MenuAction
* @version 0.1 * @version 0.1
* @date 2022-01-12 * @date 2022-01-12
* *
* @copyright Copyright (c) 2022 * @copyright Copyright (c) 2022
* *
*/ */
#include "menuAction.h" #include "menuAction.h"
MenuAction::MenuAction(const char* name, void (*function) (), void (*callback) ()) { MenuAction::MenuAction(const char *name, void (*function)(), void (*callback)())
this->name = name; {
this->function = function; this->name = name;
this->callback = callback; this->function = function;
} this->callback = callback;
}
MenuAction::MenuAction(const char* name, MenuControl* menu) {
this->name = name; MenuAction::MenuAction(const char *name, MenuControl *menu)
this->menu = menu; {
this->isMenu = true; this->name = name;
} this->menu = menu;
this->isMenu = true;
MenuAction::MenuAction(const char* name, MenuActionWrapper* action) { }
this->name = name;
this->action = action; MenuAction::MenuAction(const char *name, MenuActionWrapper *action)
} {
this->name = name;
MenuAction::~MenuAction() { this->action = action;
if (this->menu) }
delete this->menu;
MenuAction::~MenuAction()
if (this->action) {
delete this->action; if (this->menu)
} delete this->menu;
void MenuAction::runAction() { if (this->action)
if (isMenu) delete this->action;
this->menu->printMenu(); }
else {
if (this->function) void MenuAction::runAction()
this->function(); {
else if (this->action) if (isMenu)
this->action->action(); this->menu->printMenu();
else else
std::cout << "Error in MenuAction::runAction" << std::endl; {
} if (this->function)
this->function();
if (this->callback) else if (this->action)
this->callback(); this->action->action();
} else
std::cout << "Error in MenuAction::runAction" << std::endl;
const char* MenuAction::getName() { }
return this->name;
} if (this->callback)
this->callback();
bool MenuAction::getIsMenu() { }
return this->isMenu;
} const char *MenuAction::getName()
{
MenuControl* MenuAction::getMenu() { return this->name;
if (isMenu) }
return this->menu;
else bool MenuAction::getIsMenu()
return nullptr; {
} return this->isMenu;
}
MenuControl *MenuAction::getMenu()
{
if (isMenu)
return this->menu;
else
return nullptr;
}
+45 -22
View File
@@ -1,22 +1,45 @@
/** /**
* @file menuControl.cpp * @file menuControl.cpp
* @author Alexander Klein (alex@kleiax.de) * @author Alexander Klein (alex@kleiax.de)
* @brief * @brief
* @version 0.1 * @version 0.1
* @date 2022-12-28 * @date 2022-12-28
* *
* @copyright Copyright (c) 2022 * @copyright Copyright (c) 2022
* *
*/ */
#include "menuControl.h" #include "menuControl.h"
void MenuControl::update()
void MenuControl::print(String lineOne, String lineTwo) const { {
if (this->lcd) { if (this->updateDelay == 0)
lcd->clear(); return;
lcd->setCursor(0, 0);
lcd->print(lineOne.c_str()); if (millis() - this->lastUpdateMillis < this->updateDelay)
lcd->setCursor(0, 1); {
lcd->print(lineTwo.c_str()); 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;
}
+112 -98
View File
@@ -1,98 +1,112 @@
/** /**
* @file menuInformationSites.cpp * @file menuInformationSites.cpp
* @author Alexander Klein (alex@kleiax.de) * @author Alexander Klein (alex@kleiax.de)
* @brief Contains an implementation of the class MenuInformationSites * @brief Contains an implementation of the class MenuInformationSites
* @version 0.1 * @version 0.1
* @date 2022-12-27 * @date 2022-12-27
* *
* @copyright Copyright (c) 2022 * @copyright Copyright (c) 2022
* *
*/ */
#include "menuInformationSites.h" #include "menuInformationSites.h"
MenuInformationSites::MenuInformationSites(uint8_t pages) { MenuInformationSites::MenuInformationSites(uint8_t pages)
this->countPages = pages; {
this->currentPage = 0; this->countPages = pages;
this->lastMillis = millis(); this->currentPage = 0;
} this->lastMillis = millis();
}
void MenuInformationSites::up() {
if (this->currentPage == 0) void MenuInformationSites::up()
this->currentPage = this->countPages - 1; {
else if (this->currentPage == 0)
this->currentPage--; this->currentPage = this->countPages - 1;
this->printMenu(); else
} this->currentPage--;
this->printMenu();
void MenuInformationSites::down() { }
if (this->currentPage == this->countPages - 1)
this->currentPage = 0; void MenuInformationSites::down()
else {
this->currentPage++; if (this->currentPage == this->countPages - 1)
this->printMenu(); this->currentPage = 0;
} else
this->currentPage++;
void MenuInformationSites::right() { this->printMenu();
this->yes(); }
}
void MenuInformationSites::right()
void MenuInformationSites::left() { {
if (this->parentMenu) { this->printMenu();
this->parentMenu->printMenu(); }
this->leaved = true;
} void MenuInformationSites::left()
} {
if (this->parentMenu)
void MenuInformationSites::no() { {
this->left(); this->parentMenu->prepareReenterMenu();
} this->parentMenu->printMenu();
this->leaved = true;
void MenuInformationSites::yes() { }
this->runCommand(); }
this->printMenu();
} void MenuInformationSites::no()
{
void MenuInformationSites::printMenu() { if (this->noEqualLeft)
if (this->leaved) { {
this->leaved = false; this->left();
this->lastPageNumber++; return;
this->init(); }
} this->runCommandNo();
this->printMenu();
this->printPage(); }
this->lastPageNumber = this->currentPage;
} void MenuInformationSites::yes()
{
void MenuInformationSites::update() { this->runCommand();
if (millis() - this->lastMillis < this->delay) { this->printMenu();
return; }
}
this->printMenu(); void MenuInformationSites::printMenu()
this->lastMillis = millis(); {
} if (this->leaved)
{
bool MenuInformationSites::setCountPages(uint8_t pages) { this->leaved = false;
this->countPages = pages; this->lastPageNumber++;
this->currentPage = 0; this->init();
if (this->countPages == 0) { }
this->countPages = 1;
return false; this->printPage();
} this->lastPageNumber = this->currentPage;
return true; }
}
bool MenuInformationSites::setCountPages(uint8_t pages)
uint8_t MenuInformationSites::getCountPages() const { {
return this->countPages; this->countPages = pages;
} this->currentPage = 0;
if (this->countPages == 0)
uint8_t MenuInformationSites::getCurrentPage() const { {
return this->currentPage; this->countPages = 1;
} return false;
}
void MenuInformationSites::printDefault() const { return true;
String lineOne = String("Page: ") + (this->currentPage + 1); }
String lineTwo = String("of ") + this->countPages;
uint8_t MenuInformationSites::getCountPages() const
this->print(lineOne, lineTwo); {
} 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);
}
+253 -218
View File
@@ -1,218 +1,253 @@
/** /**
* @file menuIntInput.cpp * @file menuIntInput.cpp
* @author Alexander Klein (alex@kleiax.de) * @author Alexander Klein (alex@kleiax.de)
* @brief * @brief
* @version 0.1 * @version 0.1
* @date 2022-09-12 * @date 2022-09-12
* *
* @copyright Copyright (c) 2022 * @copyright Copyright (c) 2022
* *
*/ */
#include "menuIntInput.h" #include "menuIntInput.h"
MenuIntInput::MenuIntInput(int16_t values[], char *names, uint8_t length, MenuIntInputWrapper* wrapper) { MenuIntInput::MenuIntInput(int16_t values[], char *names, uint8_t length, MenuIntInputWrapper *wrapper)
this->values = values; {
this->names = names; this->values = values;
this->length = length; this->names = names;
this->wrapper = wrapper; this->length = length;
this->wrapper = wrapper;
this->min = new int16_t[this->length];
this->max = new int16_t[this->length]; this->min = new int16_t[this->length];
this->originalValues = new int16_t[this->length]; this->max = new int16_t[this->length];
this->stepsPerInput = new uint8_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; for (uint8_t i = 0; i < this->length; i++)
this->max[i] = INT16_MAX; {
this->originalValues[i] = this->values[i]; this->min[i] = INT16_MIN;
this->stepsPerInput[i] = 1; 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; MenuIntInput::MenuIntInput(uint8_t length, MenuIntInputWrapper *wrapper)
{
this->values = new int16_t[this->length]; this->length = length;
this->names = (char*) new char[this->length][MAX_NAME_LENGTH]; this->wrapper = wrapper;
this->min = new int16_t[this->length];
this->max = new int16_t[this->length]; this->values = new int16_t[this->length];
this->originalValues = new int16_t[this->length]; this->names = (char *)new char[this->length][MAX_NAME_LENGTH];
this->stepsPerInput = new uint8_t[this->length]; this->min = new int16_t[this->length];
this->max = new int16_t[this->length];
for (uint8_t i = 0; i < this->length; i++) { this->originalValues = new int16_t[this->length];
this->min[i] = INT16_MIN; this->stepsPerInput = new uint8_t[this->length];
this->max[i] = INT16_MAX;
this->values[i] = 0; for (uint8_t i = 0; i < this->length; i++)
this->originalValues[i] = 0; {
this->stepsPerInput[i] = 1; this->min[i] = INT16_MIN;
strcpy(this->names + MAX_NAME_LENGTH * i, "Default"); this->max[i] = INT16_MAX;
} this->values[i] = 0;
} this->originalValues[i] = 0;
this->stepsPerInput[i] = 1;
MenuIntInput::~MenuIntInput() { strcpy(this->names + MAX_NAME_LENGTH * i, "Default");
delete this->min; }
delete this->max; }
delete this->originalValues;
delete this->stepsPerInput; MenuIntInput::~MenuIntInput()
delete this->values; {
delete this->names; delete this->min;
delete this->wrapper; delete this->max;
} delete this->originalValues;
delete this->stepsPerInput;
void MenuIntInput::setEntry(uint8_t valueNumber, const char* name, int16_t startValue) { delete this->values;
if (this->length < valueNumber) delete this->names;
return; delete this->wrapper;
}
if (strlen(name) > MAX_NAME_LENGTH)
return; void MenuIntInput::setEntry(uint8_t valueNumber, const char *name, int16_t startValue)
{
if (this->length < valueNumber)
strcpy(this->names + MAX_NAME_LENGTH * valueNumber, name); return;
this->values[valueNumber] = startValue;
this->originalValues[valueNumber] = startValue; if (strlen(name) > MAX_NAME_LENGTH)
} return;
void MenuIntInput::setMin(uint8_t valueNumber, int16_t min) { strcpy(this->names + MAX_NAME_LENGTH * valueNumber, name);
if (this->length < valueNumber) this->values[valueNumber] = startValue;
return; this->originalValues[valueNumber] = startValue;
}
this->min[valueNumber] = min;
} void MenuIntInput::setMin(uint8_t valueNumber, int16_t min)
{
void MenuIntInput::setMax(uint8_t valueNumber, int16_t max) { if (this->length < valueNumber)
if (this->length < valueNumber) return;
return;
this->min[valueNumber] = min;
this->max[valueNumber] = max; }
}
void MenuIntInput::setMax(uint8_t valueNumber, int16_t max)
void MenuIntInput::setMinMax(uint8_t valueNumber, int16_t min, int16_t max) { {
this->setMin(valueNumber, min); if (this->length < valueNumber)
this->setMax(valueNumber, max); return;
}
this->max[valueNumber] = max;
void MenuIntInput::setMin(int16_t min) { }
for (uint8_t i = 0; i < this->length; i++)
this->min[i] = min; void MenuIntInput::setMinMax(uint8_t valueNumber, int16_t min, int16_t max)
} {
this->setMin(valueNumber, min);
void MenuIntInput::setMax(int16_t max) { this->setMax(valueNumber, max);
for (uint8_t i = 0; i < this->length; i++) }
this->max[i] = max;
} void MenuIntInput::setMin(int16_t min)
{
void MenuIntInput::setMinMax(int16_t min, int16_t max) { for (uint8_t i = 0; i < this->length; i++)
this->setMin(min); this->min[i] = min;
this->setMax(max); }
}
void MenuIntInput::setMax(int16_t max)
void MenuIntInput::setMinMaxSteps(uint8_t valueNumber, int16_t min, int16_t max, uint8_t steps) { {
this->setMin(valueNumber, min); for (uint8_t i = 0; i < this->length; i++)
this->setMax(valueNumber, max); this->max[i] = max;
this->setStepsPerInput(valueNumber, steps); }
}
void MenuIntInput::setMinMax(int16_t min, int16_t max)
void MenuIntInput::setMinMaxSteps(int16_t min, int16_t max, uint8_t steps) { {
this->setMin(min); this->setMin(min);
this->setMax(max); this->setMax(max);
this->setStepsPerInput(steps); }
}
void MenuIntInput::setMinMaxSteps(uint8_t valueNumber, int16_t min, int16_t max, uint8_t steps)
void MenuIntInput::setStepsPerInput(uint8_t valueNumber, uint8_t steps) { {
if (this->length < valueNumber) this->setMin(valueNumber, min);
return; this->setMax(valueNumber, max);
this->setStepsPerInput(valueNumber, steps);
this->stepsPerInput[valueNumber] = steps; }
}
void MenuIntInput::setMinMaxSteps(int16_t min, int16_t max, uint8_t steps)
void MenuIntInput::setStepsPerInput(uint8_t steps) { {
for (uint8_t i = 0; i < this->length; i++) this->setMin(min);
this->stepsPerInput[i] = steps; this->setMax(max);
} this->setStepsPerInput(steps);
}
void MenuIntInput::down() {
if (this->values[this->currentPosition] void MenuIntInput::setStepsPerInput(uint8_t valueNumber, uint8_t steps)
- this->stepsPerInput[this->currentPosition] {
>= this->min[currentPosition]) if (this->length < valueNumber)
{ return;
this->values[this->currentPosition] -= this->stepsPerInput[this->currentPosition];
} else { this->stepsPerInput[valueNumber] = steps;
this->values[this->currentPosition] = this->max[this->currentPosition]; }
}
void MenuIntInput::setStepsPerInput(uint8_t steps)
this->printMenu(); {
} for (uint8_t i = 0; i < this->length; i++)
this->stepsPerInput[i] = steps;
void MenuIntInput::up() { }
if (this->values[this->currentPosition]
+ this->stepsPerInput[this->currentPosition] void MenuIntInput::down()
<= this->max[this->currentPosition]) {
{ 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->stepsPerInput[this->currentPosition];
this->values[this->currentPosition] = this->min[this->currentPosition]; }
} else
{
this->printMenu(); this->values[this->currentPosition] = this->max[this->currentPosition];
} }
void MenuIntInput::right() { this->printMenu();
if (currentPosition < this->length - 1) }
currentPosition++;
else void MenuIntInput::up()
currentPosition = 0; {
if (this->values[this->currentPosition] + this->stepsPerInput[this->currentPosition] <= this->max[this->currentPosition])
this->printMenu(); {
} this->values[this->currentPosition] += this->stepsPerInput[this->currentPosition];
}
void MenuIntInput::left() { else
if (currentPosition > 0) {
currentPosition--; this->values[this->currentPosition] = this->min[this->currentPosition];
else }
currentPosition = this->length - 1;
this->printMenu();
this->printMenu(); }
}
void MenuIntInput::right()
void MenuIntInput::no() { {
for (uint8_t i = 0; i < this->length; i++) if (currentPosition < this->length - 1)
this->values[i] = this->originalValues[i]; currentPosition++;
this->currentPosition = 0; else
currentPosition = 0;
if (this->parentMenu)
this->parentMenu->printMenu(); this->printMenu();
} }
void MenuIntInput::yes() { void MenuIntInput::left()
this->wrapper->action(this->values, this->length); {
if (this->parentMenu && printParentMenu) if (currentPosition > 0)
this->parentMenu->printMenu(); currentPosition--;
} else
currentPosition = this->length - 1;
void MenuIntInput::printMenu() {
char bufferName[17]; this->printMenu();
}
if (this->currentPosition == 0 && this->length == 1) {
// No arrow void MenuIntInput::no()
sprintf(bufferName, " %s ", this->names + MAX_NAME_LENGTH * this->currentPosition); {
} else if (this->currentPosition > 0 && this->length - 1 == this->currentPosition) { for (uint8_t i = 0; i < this->length; i++)
// Left arrow only this->values[i] = this->originalValues[i];
sprintf(bufferName, "< %s ", this->names + MAX_NAME_LENGTH * this->currentPosition); this->currentPosition = 0;
} else if (this->currentPosition == 0 && this->length > 1) {
// Right arrow only if (this->parentMenu)
sprintf(bufferName, " %s >", this->names + MAX_NAME_LENGTH * this->currentPosition); {
} else { this->parentMenu->prepareReenterMenu();
// Both arrow this->parentMenu->printMenu();
sprintf(bufferName, "< %s >", this->names + MAX_NAME_LENGTH * this->currentPosition); }
} }
char bufferValue[17]; void MenuIntInput::yes()
if (this->values[this->currentPosition]) {
sprintf(bufferValue, " -> %5.d", this->values[this->currentPosition]); this->wrapper->action(this->values, this->length);
else if (this->parentMenu && printParentMenu)
sprintf(bufferValue, " -> 0"); {
this->parentMenu->prepareReenterMenu();
this->print(bufferName, bufferValue); 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);
}