what about something more generic
char s [90];
// -----------------------------------------------------------------------------
struct M {
const char *name;
M *next;
};
// -------------------------------------
M mammals [] = {
{ "apes", 0 },
{ "dolphons", 0 },
{ },
};
// ---------------------------
M reptiles [] = {
{ "turtles", 0 },
{ "lizards", 0 },
{ },
};
// ---------------------------
M animal [] = {
{ "birds", 0 },
{ "fish", 0 },
{ "mammals", mammals },
{ "reptiles", reptiles },
{ },
};
// -------------------------------------
M gems [] = {
{ "quarts", 0 },
{ "saphire", 0 },
{ },
};
// ---------------------------
M sedimentary [] = {
{ "limestone", 0 },
{ },
};
// ---------------------------
M rock [] = {
{ "granit", 0 },
{ },
};
// ---------------------------
M mineral [] = {
{ "aggregate", 0 },
{ "biogenic", 0 },
{ "gems", gems },
{ "sedimentary", sedimentary },
{ "rock", rock },
{ },
};
// -------------------------------------
M bush [] = {
{ "beans", 0 },
{ "peas", 0 },
{ "tomators", 0 },
{ },
};
// ---------------------------
M grains [] = {
{ "corn", 0 },
{ "wheat", 0 },
{ },
};
// ---------------------------
M tubors [] = {
{ "carrots", 0 },
{ "potatoes", 0 },
{ "turnips", 0 },
{ },
};
// ---------------------------
M vegetable [] = {
{ "bush", bush },
{ "grains", grains },
{ "tubors", tubors },
{ },
};
// -------------------------------------
M top [] = {
{ "animal", animal },
{ "mineral", mineral },
{ "vegetable", vegetable },
{ },
};
// ---------------------------------------------------------
const int Nlvl = 10;
int lvl = 0;;
M *menu [Nlvl] = { top };
M *m = top;
// -------------------------------------
void
menuAdv ()
{
m++;
if (0 == m->name)
m = menu [lvl];
Serial.println (m->name);
}
// -------------------------------------
void
menuExit ()
{
if (0 < lvl)
m = menu [--lvl];
else
Serial.println (" ^");
Serial.println (m->name);
}
// -------------------------------------
void
menuSel ()
{
#if 0
sprintf (s, "sel: name %s, next %p, next-name %s",
m->name, m->next, m->next->name);
Serial.println (s);
#endif
if (m->next && lvl < Nlvl-1) {
menu [++lvl] = m = m->next;
Serial.println (m->name);
}
else
Serial.println (" .");
}
// -----------------------------------------------------------------------------
byte pinsBut [] = { A1, A2, A3 };
#define N_BUT sizeof(pinsBut)
byte butState [N_BUT];
enum { Adv, Sel, Exit };
// -------------------------------------
int
chkButtons ()
{
for (unsigned n = 0; n < sizeof(pinsBut); n++) {
byte but = digitalRead (pinsBut [n]);
if (butState [n] != but) {
butState [n] = but;
delay (10); // debounce
if (LOW == but)
return n;
}
}
return -1;
}
// -----------------------------------------------------------------------------
void
loop ()
{
switch (chkButtons ()) {
case Adv:
menuAdv ();
break;
case Sel:
menuSel ();
break;
case Exit:
menuExit ();
break;
}
}
// -----------------------------------------------------------------------------
void
setup ()
{
Serial.begin (9600);
for (unsigned n = 0; n < sizeof(pinsBut); n++) {
pinMode (pinsBut [n], INPUT_PULLUP);
butState [n] = digitalRead (pinsBut [n]);
}
Serial.println (m->name);
}