// // Created by robtor on 05.01.23. // #ifndef FLOATPUMP_MENU_CONTROLLER_H #define FLOATPUMP_MENU_CONTROLLER_H #include "Menu.h" namespace floatpump { namespace menu { class Menu_Controller { public: Menu_Controller(Menu *menu, LCD_I2C_Driver &driver): m_menu(menu), m_driver(driver) {}; enum Event {Increase, Decrease, Push}; void execute() { displayMenu(m_menu); } void pushEvent(Event ev) { switch(ev) { case Increase: increase(m_menu); break; case Decrease: decrease(m_menu); break; case Push: keypress(m_menu); break; } } void displayMenu(Menu *m) { int page = m_current_index / 4; int pageindex = m_current_index % 4; for (int i = 0; i < 4; i++) { m_driver.LCDSetCursor(0, i); if (pageindex == i) { m_driver.LCDSendChar(LCD_I2C_Driver::SpecialChars::RightArrow); } else { m_driver.LCDSendCString(" "); } m_driver.LCDSetCursor(1, i); int entry_index = (page * 4) + i; //Display submenus first and then entries if (entry_index < m->m_submenus.size()) { std::string dspstring = "submenu"; m_driver.LCDSendCString("submenu"); //TODO: display submenus contentname //Display entries } else if (entry_index < (m->m_entries.size() + m->m_submenus.size())) { std::string dspstring = m->m_entries[entry_index - m->m_submenus.size()].printLine(); if (dspstring.length() > 19) { m_driver.LCDSendCString("-------------------"); } else { dspstring.append((19 - dspstring.length()), ' '); m_driver.LCDSendCString(const_cast(dspstring.c_str())); } } else if (entry_index == (m->m_entries.size() + m->m_submenus.size()) && m->m_parent != nullptr) { m_driver.LCDSendCString("Go Back"); } else { //Show separator at end of menu //TODO: make this look better m_driver.LCDSendCString(" "); } } } void keypress(Menu *m) { //enter submenu if (m_current_index < m->m_submenus.size()) { m_menu = m->m_submenus[m_current_index]; //forward press to entry } else if (m_current_index < (m->m_entries.size() + m->m_submenus.size())) { m->m_entries[m_current_index - m->m_submenus.size()].action_press(); } else if (m_current_index == (m->m_submenus.size() + m->m_entries.size()) && m->m_parent != nullptr) { m_menu = m->m_parent; } } void increase(Menu *m) { //always increase if (m_current_index < m->m_submenus.size()) { m_current_index++; //increase when not in entry entered state } else if (m_current_index < (m->m_submenus.size() + m->m_entries.size())) { if (m->m_entries[m_current_index - m->m_submenus.size()].isEntered()) { m->m_entries[m_current_index - m->m_submenus.size()].action_increase(); } else if (m_current_index < (m->m_submenus.size() + m->m_entries.size()) && m->m_parent != nullptr) { m_current_index++; } else if (m_current_index < (m->m_submenus.size() + m->m_entries.size()) - 1) { m_current_index++; } } } void decrease(Menu *m) { if (m_current_index > m->m_submenus.size()) { if (m->m_entries[m_current_index - m->m_submenus.size()].isEntered()) { m->m_entries[m_current_index - m->m_submenus.size()].action_decrease(); } else { m_current_index--; } } else if (m_current_index > 0) { m_current_index--; } } private: LCD_I2C_Driver &m_driver; int m_current_index = 0; Menu *m_menu; }; } // floatpump } // menu #endif //FLOATPUMP_MENU_CONTROLLER_H