Yeah, I have seen that. I wasn't too fond of the submenu type idea, I sort of wanted everything to just be one type.
Hijacking is totally fine, as long as it's somewhat related. Always good to look around at other code.
Brian, thanks for the input. I've changed it to a linked list and it has made it much more flexible, in addition to more than cutting in half an instance of the object!
I can't seem to get the typedef boolean MYCALL(menu&) to work
error: typedef 'MYCALL' is initialized (use __typeof__ instead) In constructor 'menu::menu(char*, int)':
At global scope:
I'm still having a little trouble though..
I changed my code such that in your main code, you should have a menu pointer, and everything will just return menu pointers that you can put into that. Makes it very flexible I think. I'm having trouble then referencing the menu that is currently pointed to, so I think I may be doing something wrong.
#include <LiquidCrystal.h>
LiquidCrystal lcd(2,-1,3,4,5,6,7);
typedef boolean (*MYCALL)(void);
class menu
{
private:
menu * parent; Â Â //Pointer to parent menu
menu * child; Â Â Â //Pointer to first child
menu * sibling; Â Â //Pointer to next sibling
MYCALL callback; Â //Function associated with menu item
        Â
void setparent(menu &p)
{
parent=&p;
}
void addsibling(menu &s,menu &p)
{
if (sibling)
{
sibling->addsibling(s,p);
}
else
{
sibling=&s;
sibling->setparent(p);
}
}
menu * getsibling(int which)
{
if (which==0)
{
return this;
}
else if (sibling)
{
return sibling->getsibling(which-1);
}
else //Asking for a nonexistent sibling
{
serror("Sibling does not exist");
return NULL;
}
}
public:
char *name;
menu(char *n,MYCALL c)
{
name=n;
callback=c;
}
void addchild(menu &c)
{
if (child)
{
child->addsibling(c,*this);
}
else
{
child=&c;
child->setparent(*this);
}
}
menu * getchild(int which)
{
if (child)
{
return child->getsibling(which);
}
else //This menu item has no children
{
serror("Has no children");
return NULL;
}
}
menu * goup()
{
return parent;
}
};
void serror(char *error)
{
Serial.print(error);
/*
lcd.clear();
lcd.print("ERROR");
lcd.setCursor(0,1);
lcd.print(error);
*/
}
boolean none()
{
Serial.println("none");
return 0;
}
boolean some()
{
Serial.println("some");
return 1;
}
menu * Menu;
menu Root("Root",some);
menu Item1("Something",some);
menu Item11("Stuff",none);
menu Item12("More",some);
menu Item121("Deeper",none);
menu Item2("Other",none);
menu Item3("Etc",some);
menu Item31("So On",none);
void menuinit()
{
Root.addchild(Item1);
Root.addchild(Item2);
Root.addchild(Item3);
Item1.addchild(Item11);
Item1.addchild(Item12);
Item12.addchild(Item121);
Item3.addchild(Item31);
Menu=&Root;
}
//UP,DOWN,LEFT,RIGHT,ENTER
int but[5]={8,9,10,11,12};
//Previous States of buttons
boolean pbut[5]={0,0,0,0,0};
int curloc;
boolean dread(int pin)
{
return digitalRead(pin);
}
void buttoncheck()
{
for (int i=0;i<5;i++)
{
if (dread(but[i]))
 {
 if (pbut[i]==0)
 {
 button(i);
 pbut[i]=1;
 }
 }
else
 {
 pbut[i]=0;
 }
}
}
void button(int which)
{
switch (which)
{
case 0://UP
 curloc-=2;
break;
case 1://DOWN
 curloc+=2;
break;
case 2://LEFT
 curloc--;
break;
case 3://RIGHT
 curloc++;
break;
case 4://ENTER
Menu=Menu->getchild(curloc);
break;
}
if (curloc<0){curloc+=8;}
curloc%=8;
}
void setup()
{
Serial.begin(9600);
Serial.println(sizeof(menu));
lcd.clear();
menuinit();
lcd.command(0x0F);
}
void loop()
{
lcd.setCursor((curloc%2)*10,curloc/2);
buttoncheck();
}
I would like a function (external to the class) display()
This function would I think be something like this:
void display()
{
void display()
{
menu * tmp;
int i=0;
lcd.clear();
while (tmp=Menu->getchild(i))
{
lcd.setCursor(((i%2)*10)+1,i/2);
lcd.print(tmp->name);
i++;
}
}
This works fine for the first Root menu, but once you enter a menu the lcd displays garbage, so I think I'm having pointer trouble...