Хабр Курсы для всех
РЕКЛАМА
Практикум, Хекслет, SkyPro, авторские курсы — собрали всех и попросили скидки. Осталось выбрать!
typedef byte ( * tCallback)(byte, byte, char * );
//prototypes NEED FOR CALLBACK
byte callback_StartTimer(byte id, byte parent, char * name);
//struct define typical menu item
struct menuItem {
byte id;
char * name;
byte parent; //id parent
tCallback callback; //callback function
bool haveChilds;//using for optimizations
};
vector<menuItem> items;//vector of menu items
int freeRam () { //display free ram memory
extern int __heap_start, * __brkval;
int v;
return (int) & v - (__brkval == 0 ? (int) & __heap_start : (int) __brkval);
}
void setup() {
menuItem root;
{
root.id = 10;
root.name = "Set octave";
root.parent = CONST_ROOT_ITEM;
root.callback = & callback_SetOcave;
items.push_back(root);
root.id = 12;
root.name = "Setup";
root.parent = CONST_ROOT_ITEM;
root.callback = NULL;
items.push_back(root);
{
root.id = 24;
root.name = "Time";
root.parent = 12;
root.callback = & callback_resetAllKeys;
items.push_back(root);
}
}
Serial.println("Free ram: " + String(freeRam()));
}
//call callback of menu item
items[i].callback(id, parent, name);
byte callback_StartTimer(byte id, byte parent, char * name) { //return true if need reprint menu
//Serial.println("Callbacked function callback_StartTimer by " + String(name));
return false;
}
//print menu recursively. return need for checking empty menu
bool printMenuRecurcive(vector<menuItem> & items, byte parent, byte level) {
if (level > CONST_MAX_LEVEL) return false;
bool haveChilds = false;//flag reports if have items
for (byte i = 0; i < items.size(); i++) {
if (parent == items[i].parent) {
haveChilds = true;//yay! his have items
String indent = "";
for (int j = 0; j < level; j++) {
indent += " ";
}
if (items[i].haveChilds) {
Serial.println(indent + String(items[i].name) + ">");
} else {
Serial.println(indent + String(items[i].name));
}
printMenuRecurcive(items, items[i].id, level + 1); //print next level
}//end if parent
}//end for
return haveChilds;
}//end func
struct menu_item {
struct menu_item* parent; // указатель на родителя
struct menu_item* child; // указатель на потомка
struct menu_item* prev; // предыдущий в списке
struct menu_item* next; // следующий в списке
const char* name; // имя
void* data; // данные пункта
int (*do_left)(void*); // действие для кнопок
int (*do_right)(void*);
int (*do_up)(void*);
int (*do_down)(void*);
}
Многоуровневое меню для Arduino и не только