WIP: Submenu support and handling

This commit is contained in:
Robin Dietzel 2023-01-05 17:42:39 +01:00
parent 1441fc49b4
commit 053d35087d
4 changed files with 151 additions and 81 deletions

View File

@ -7,6 +7,6 @@
// Auto generated header file containing the last git revision
#define GIT_HASH "d25705d"
#define GIT_HASH "b92adab"
#endif //FLOATPUMP_GIT_REVISION_TEMPLATE_H

View File

@ -12,6 +12,7 @@
#include "Menu_Entry_Type_Percent.h"
#include "Menu_Entry_Type_Time.h"
#include "Config_Store.h"
#include "Menu_Controller.h"
#define SLAVE_ADDRESS_LCD 0x4e
@ -107,23 +108,31 @@ int main(void) {
mainmenu.addEntry(entry2);
mainmenu.addEntry(entry3);
Menu submenu(display);
Menu_Entry_Type_Checkable entrysub(true);
Menu_Entry sube(&entrysub, "yay dies sub!");
submenu.addEntry(sube);
mainmenu.addSubmenu(&submenu);
Menu_Controller controller(&mainmenu, display);
static int old_pos = 0;
while (1) {
mainmenu.updateMenu();
controller.execute();
if(rot_button) {
rot_button = false;
mainmenu.keypress();
controller.pushEvent(Menu_Controller::Event::Push);
}
if(old_pos < rot_counter) {
mainmenu.increase();
controller.pushEvent(Menu_Controller::Event::Increase);
old_pos = rot_counter;
} else if (old_pos > rot_counter) {
mainmenu.decrease();
controller.pushEvent(Menu_Controller::Event::Decrease);
old_pos = rot_counter;
}
HAL_Delay(100);

View File

@ -17,97 +17,57 @@ namespace floatpump {
public:
Menu(LCD_I2C_Driver &driver) : m_driver(driver) {
}
void addEntry(Menu_Entry entry) {
m_entries.push_back(entry);
}
void updateMenu() {
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_submenus.size()) {
std::string dspstring = "submenu";
m_driver.LCDSendCString("submenu");
//TODO: display submenu contentsnames
//Display entries
} else if (entry_index < (m_entries.size() + m_submenus.size())) {
std::string dspstring = m_entries[entry_index - m_submenus.size()].printLine();
if (dspstring.length() > 19) {
m_driver.LCDSendCString("-------------------");
} else {
dspstring.append((19 - dspstring.length()), ' ');
m_driver.LCDSendCString(const_cast<char *>(dspstring.c_str()));
}
} else { //Show separator at end of menu
//TODO: make this look better
m_driver.LCDSendCString("-");
}
}
}
void keypress() {
//enter submenu
if (m_current_index < m_submenus.size()) {
//forward press to entry
} else if (m_current_index < (m_entries.size() + m_submenus.size())) {
m_entries[m_current_index - m_submenus.size()].action_press();
}
}
void increase() {
//always increase
if (m_current_index < m_submenus.size()) {
m_current_index++;
//increase when not in entry entered state
} else if (m_current_index < (m_submenus.size() + m_entries.size())) {
if (m_entries[m_current_index - m_submenus.size()].isEntered()) {
m_entries[m_current_index - m_submenus.size()].action_increase();
} else if (m_current_index < (m_submenus.size() + m_entries.size() - 1)) {
m_current_index++;
}
}
}
void decrease() {
if (m_current_index > m_submenus.size()) {
if (m_entries[m_current_index - m_submenus.size()].isEntered()) {
m_entries[m_current_index - m_submenus.size()].action_decrease();
} else {
m_current_index--;
}
} else if (m_current_index > 0) {
m_current_index--;
}
}
void addSubmenu(Menu *submenu) {
submenu->m_parent = this;
m_submenus.push_back(submenu);
}
private:
/*
bool isSubmenu(int index) {
if(index > 0 && index < m_submenus.size()) {
return true;
}
return false;
}
bool isEntry(int index) {
if(index >= m_submenus.size() && index < (m_entries.size() + m_submenus.size())) {
return true;
}
return false;
}
Menu_Entry *getEntry(int index) {
if(isEntry(index)) {
return &m_entries[index - m_submenus.size()];
} else {
return nullptr;
}
}
Menu *getSubmenu(int index) {
if(isSubmenu(index)) {
return m_submenus[index];
} else {
return nullptr;
}
}
*/
LCD_I2C_Driver &m_driver;
std::vector<Menu_Entry> m_entries;
std::vector<Menu *> m_submenus;
Menu *m_parent = nullptr;
int m_current_index = 0;
private:
};
} // floatpump

View File

@ -11,10 +11,111 @@ 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<char *>(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