FEATURE: simple navigable menu

This commit is contained in:
Robin Dietzel 2023-01-04 13:22:45 +01:00
parent 68b05424a0
commit 029f2745d1
7 changed files with 166 additions and 65 deletions

View File

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

View File

@ -6,6 +6,8 @@
#include "LCD_I2C_Driver.h"
#include "InitSequence.h"
#include "button_input.h"
#include "Menu.h"
#include "Menu_Entry_Type_Checkable.h"
#define SLAVE_ADDRESS_LCD 0x4e
@ -69,47 +71,49 @@ int main(void) {
// display.LCDSetCursor(18, 3);
//Disable Interrupt for Debouncing timer during display initalisation (exact timings are necessary)
HAL_NVIC_DisableIRQ(TIM1_CC_IRQn);
HAL_NVIC_DisableIRQ(TIM2_IRQn);
floatpump::LCD_I2C_Driver &display = floatpump::LCD_I2C_Driver::getInstance(hi2c1, SLAVE_ADDRESS_LCD);
HAL_NVIC_EnableIRQ(TIM1_CC_IRQn);
HAL_NVIC_EnableIRQ(TIM2_IRQn);
floatpump::InitSequence initializer(display);
initializer.runInitSequence();
while (1) {
display.LCDSetCursor(0, 0);
char stri[20];
sprintf(stri, "DT: %03d", rot_counter);
display.LCDSendCString(stri);
using namespace floatpump::menu;
if (rot_button && rot_counter == 1) {
HAL_GPIO_TogglePin(OCHAN0_GPIO_Port, OCHAN0_Pin);
rot_button = false;
} else if (rot_button && rot_counter == 2) {
HAL_GPIO_TogglePin(OCHAN1_GPIO_Port, OCHAN1_Pin);
Menu mainmenu(display);
Menu_Entry entry(new Menu_Entry_Type_Checkable(), "test");
Menu_Entry entry2(new Menu_Entry_Type_Checkable(), "test2bl");
mainmenu.addEntry(entry);
mainmenu.addEntry(entry2);
mainmenu.addEntry(entry);
mainmenu.addEntry(entry2);
Menu_Entry entry3(new Menu_Entry_Type_Checkable(), "Page2");
mainmenu.addEntry(entry3);
mainmenu.addEntry(entry3);
mainmenu.addEntry(entry3);
static int old_pos = 0;
while (1) {
mainmenu.displayMenu();
if(rot_button) {
rot_button = false;
mainmenu.keypress();
}
if(old_pos < rot_counter) {
mainmenu.increase();
old_pos = rot_counter;
} else if (old_pos > rot_counter) {
mainmenu.decrease();
old_pos = rot_counter;
}
HAL_Delay(100);
// HAL_GPIO_TogglePin(OCHAN0_GPIO_Port, OCHAN0_Pin);
// HAL_Delay(2000);
// HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_0);
// HAL_Delay(1000);
// HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_1);
// HAL_Delay(1000);
// HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_2);
// HAL_Delay(1000);
//
// HAL_GPIO_TogglePin(LED3_GPIO_Port, LED3_Pin);
// HAL_Delay(1000);
// HAL_GPIO_TogglePin(LED4_GPIO_Port, LED4_Pin);
// HAL_Delay(1000);
// HAL_GPIO_TogglePin(LED5_GPIO_Port, LED5_Pin);
// HAL_Delay(1000);
}
}

View File

@ -5,11 +5,71 @@
#ifndef FLOATPUMP_MENU_H
#define FLOATPUMP_MENU_H
#include <vector>
#include "Menu_Entry.h"
#include "LCD_I2C_Driver.h"
namespace floatpump {
namespace menu {
class Menu {
public:
Menu(LCD_I2C_Driver &driver) : m_driver(driver) {
}
void addEntry(Menu_Entry entry) {
m_entries.push_back(entry);
}
void displayMenu() {
int page = m_first_index / 4;
int pageindex = m_first_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;
if( m_entries.size() > entry_index) {
std::string dspstring = m_entries[entry_index].printLine();
dspstring.append((19 - dspstring.length()), ' ');
m_driver.LCDSendCString(const_cast<char *>(dspstring.c_str()));
} else {
m_driver.LCDSendCString("-------------------");
}
}
}
void keypress() {
if(m_first_index < m_entries.size()) {
m_entries[m_first_index].action_press();
}
}
void increase() {
if(m_first_index < m_entries.size() - 1)
m_first_index++;
}
void decrease() {
if(m_first_index > 0)
m_first_index--;
}
private:
LCD_I2C_Driver &m_driver;
std::vector<Menu_Entry> m_entries;
int m_first_index = 0;
};
} // floatpump

View File

@ -0,0 +1,10 @@
//
// Created by robtor on 04.01.23.
//
#include "Menu_Entry.h"
namespace floatpump {
namespace menu {
} // floatpump
} // menu

View File

@ -0,0 +1,43 @@
//
// Created by robtor on 04.01.23.
//
#ifndef FLOATPUMP_MENU_ENTRY_H
#define FLOATPUMP_MENU_ENTRY_H
#include <Menu_Entry_Type_Delegate.h>
namespace floatpump {
namespace menu {
class Menu_Entry {
public:
Menu_Entry_Type_Delegate *m_type;
Menu_Entry(Menu_Entry_Type_Delegate *type, std::string name) : m_type(type), m_name(name) {};
std::string printLine() {
return m_name + ": " + m_type->toString();
}
void action_press() {
m_type->u_press();
}
void action_increase() {
m_type->u_increase(1);
}
void action_decrease() {
m_type->u_decrease(1);
}
private:
std::string m_name;
};
} // floatpump
} // menu
#endif //FLOATPUMP_MENU_ENTRY_H

View File

@ -10,43 +10,29 @@
namespace floatpump {
namespace menu {
class Menu_Entry_Type_Checkable : public Menu_Entry_Type_Delegate<bool> {
class Menu_Entry_Type_Checkable : public Menu_Entry_Type_Delegate {
public:
std::string toString() override {
return std::string("E: " + m_name);
return std::string((m_state) ? "True" : "false");
}
void u_press() override {
Menu_Entry_Type_Delegate::u_press();
m_state = !m_state;
}
void u_increase(uint16_t steps) override {
Menu_Entry_Type_Delegate::u_increase(steps);
}
void u_decrease(uint16_t steps) override {
Menu_Entry_Type_Delegate::u_decrease(steps);
}
bool s_entered() override {
return Menu_Entry_Type_Delegate::s_entered();
}
bool u_leave() override {
return Menu_Entry_Type_Delegate::u_leave();
}
bool getValue() override {
return Menu_Entry_Type_Delegate::getValue();
}
void p_setName(std::string name) override {
m_name = name;
}
bool enterable = false;
private:
std::string m_name;
bool m_checked;
bool m_state = false;
};
} // floatpump

View File

@ -2,8 +2,8 @@
// Created by robtor on 09.12.22.
//
#ifndef FLOATPUMP_MENU_ENTRY_H
#define FLOATPUMP_MENU_ENTRY_H
#ifndef FLOATPUMP_MENU_ENTRY_DELEGATE_H
#define FLOATPUMP_MENU_ENTRY_DELEGATE_H
#include <string>
@ -11,19 +11,17 @@ namespace floatpump {
namespace menu {
template<class t> class Menu_Entry_Type_Delegate {
class Menu_Entry_Type_Delegate {
public:
virtual std::string toString();
virtual void u_press();
virtual void u_increase(uint16_t steps = 1);
virtual void u_decrease(uint16_t steps = 1);
virtual bool s_entered();
virtual bool u_leave();
virtual t getValue();
virtual void p_setName(std::string name);
virtual std::string toString() = 0;
virtual void u_press() = 0;
virtual void u_increase(uint16_t steps = 1) = 0;
virtual void u_decrease(uint16_t steps = 1) = 0;
bool enterable = true;
};
} // floatpump
} // menu
#endif //FLOATPUMP_MENU_ENTRY_H
#endif //FLOATPUMP_MENU_ENTRY_DELEGATE_H