floatpump-firmware/Middlewares/floatpump/Inc/Menu.h

173 lines
4.5 KiB
C++

//
// Created by robtor on 26.01.23.
//
#ifndef FLOATPUMP_MENU_H
#define FLOATPUMP_MENU_H
#include <cstdint>
#include <string>
#include <vector>
#include <memory>
namespace floatpump {
namespace menu {
struct IMenuEntry {
virtual ~IMenuEntry() = default;
virtual auto u_press() -> void = 0;
virtual auto u_increase(uint16_t steps = 1) -> void = 0;
virtual auto u_decrease(uint16_t steps = 1) -> void = 0;
virtual auto is_entered() -> bool = 0;
virtual auto toString() -> std::string = 0;
};
template<typename T>
class MenuEntry : public IMenuEntry {
public:
MenuEntry(T *linked_config, std::string name) : m_name(name) {
m_storage = linked_config;
};
auto getValue() -> T & {
return (*m_storage);
}
auto setValue(T &value) -> void {
*m_storage = value;
}
auto relinkConfig(T *linked_config) -> void {
m_storage = linked_config;
}
protected:
T *m_storage;
std::string m_name;
bool m_entered = false;
auto buildString(std::string appendix) -> std::string;
};
class MenuEntryCheckable : public MenuEntry<bool> {
public:
MenuEntryCheckable(bool *linked_config, const std::string &name) : MenuEntry(linked_config, name) {}
auto toString() -> std::string override;
auto u_press() -> void override;
auto u_increase(uint16_t steps) -> void override {}
auto u_decrease(uint16_t steps) -> void override {}
auto is_entered() -> bool override {
return false;
}
};
class MenuEntryExecute : public MenuEntry<bool> {
public:
MenuEntryExecute(bool *linked_config, const std::string &name) : MenuEntry(linked_config, name) {}
auto u_press() -> void override;
auto u_increase(uint16_t steps) -> void override {}
auto u_decrease(uint16_t steps) -> void override {}
auto is_entered() -> bool override {
return false;
}
auto toString() -> std::string override;
};
class MenuEntryNumeric : public MenuEntry<uint16_t> {
public:
MenuEntryNumeric(uint16_t *linked_config, const std::string &name) : MenuEntry(linked_config, name) {}
auto u_press() -> void override;
auto u_increase(uint16_t steps) -> void override;
auto u_decrease(uint16_t steps) -> void override;
auto is_entered() -> bool override;
auto toString() -> std::string override;
};
class MenuEntryPercent : public MenuEntry<uint8_t> {
public:
MenuEntryPercent(uint8_t *linked_config, const std::string &name) : MenuEntry(linked_config, name) {}
auto u_press() -> void override;
auto u_increase(uint16_t steps) -> void override;
auto u_decrease(uint16_t steps) -> void override;
auto is_entered() -> bool override;
auto toString() -> std::string override;
};
class Menu {
public:
explicit Menu(const std::string &m_name) : m_name(m_name) {}
enum class Error {
invalid_index
};
template<typename T, typename... As>
auto addEntry(As &&...args) -> void {
m_entries.push_back(std::make_unique<T>(std::forward<As>(args)...));
}
auto addSubmenu(Menu *submenu) -> void {
submenu->m_parent = this;
m_submenus.push_back(submenu);
}
auto printLine() -> const std::string {
return m_name;
}
auto getDisplayList() -> std::vector<std::string>;
auto getAllEntriesNum() -> unsigned const int {
return (m_entries.size() + m_submenus.size()) + ((m_parent != nullptr) ? 1 : 0);
}
auto getSubmenu(int index) -> Menu *;
auto getEntry(int index) -> IMenuEntry* ;
auto getParent() -> Menu * {
return m_parent;
}
private:
std::vector<std::unique_ptr<IMenuEntry>> m_entries;
std::vector<Menu *> m_submenus;
Menu *m_parent = nullptr;
std::string m_name;
};
}
}
#endif //FLOATPUMP_MENU_H