2023-01-26 12:22:43 +00:00
|
|
|
//
|
|
|
|
// 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;
|
|
|
|
|
2023-01-26 13:20:08 +00:00
|
|
|
auto buildString(std::string appendix) -> std::string {
|
|
|
|
int spaces = 19 - (m_name.length() + appendix.length());
|
|
|
|
std::string spacer;
|
|
|
|
if (spaces > 0)
|
|
|
|
spacer.append(spaces, ' ');
|
|
|
|
else if (spaces < 0)
|
|
|
|
return "ERROR";
|
|
|
|
|
|
|
|
return {m_name + spacer + appendix};
|
|
|
|
}
|
2023-01-26 12:22:43 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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) {}
|
|
|
|
|
2023-01-26 13:17:58 +00:00
|
|
|
enum class Error {
|
|
|
|
invalid_index
|
|
|
|
};
|
|
|
|
|
2023-01-26 12:22:43 +00:00
|
|
|
template<typename T, typename... As>
|
|
|
|
auto addEntry(As &&...args) -> void {
|
|
|
|
m_entries.push_back(std::make_unique<T>(std::forward<As>(args)...));
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2023-01-26 13:28:17 +00:00
|
|
|
auto addSubmenu(Menu &menu) -> void {
|
|
|
|
m_submenus.emplace_back(std::make_unique<Menu>(std::move(menu)))->m_parent = this;
|
2023-01-26 12:22:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
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 *;
|
|
|
|
|
2023-01-26 13:17:58 +00:00
|
|
|
auto getEntry(int index) -> IMenuEntry* ;
|
2023-01-26 12:22:43 +00:00
|
|
|
|
|
|
|
auto getParent() -> Menu * {
|
|
|
|
return m_parent;
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
std::vector<std::unique_ptr<IMenuEntry>> m_entries;
|
2023-01-26 13:28:17 +00:00
|
|
|
std::vector<std::unique_ptr<Menu>> m_submenus;
|
2023-01-26 12:22:43 +00:00
|
|
|
Menu *m_parent = nullptr;
|
|
|
|
std::string m_name;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#endif //FLOATPUMP_MENU_H
|