Menu Library. Simple menu management.

I’ve made a way to create menues.

This is handy for all those LCD application that needs some kind of menu system, although, this library is not resticted to LCD menus.

Example:

/*
||
|| @author Alexander Brevig
|| @version 1.0
||
|| @description
|| | This is a simple menu system, that uses input from the serial to change and use menuitems.
|| #
||
|| @license
|| | This code is subject to my AlphaLicence.txt
|| | www.alphabeta.alexanderbrevig.com/AlphaLicense.txt
|| #
||
*/

#include <SubMenuItem.h>
#include <SubMenu.h>
#include <MenuItem.h>
#include <Menu.h>
//initialize menu
Menu menu = Menu(menuUsed,menuChanged);
//initialize menuitems
MenuItem menuItem1 = MenuItem();
MenuItem menuItemWithSubmenu = MenuItem();
SubMenu subMenu = SubMenu(menuChanged);
SubMenuItem subMenuItem1 = SubMenuItem();
SubMenuItem subMenuItem2 = SubMenuItem();
SubMenuItem subMenuItem3 = SubMenuItem();
MenuItem menuItem3 = MenuItem();

void setup(){
Serial.begin(9600);

//configure menu
menu.addMenuItem(menuItem1);
menu.addMenuItem(menuItemWithSubmenu);
menuItemWithSubmenu.addSubMenu(subMenu);
subMenu.addSubMenuItem(subMenuItem1);
subMenu.addSubMenuItem(subMenuItem2);
subMenu.addSubMenuItem(subMenuItem3);
menu.addMenuItem(menuItem3);

menu.select(0);
subMenu.select(0);
}
void loop(){
if (Serial.available()){
switch (Serial.read()){
case ‘w’:
if (menu.isCurrentSubMenu()){
subMenu.down(); //set index closer to 0
}
break;
case ‘s’:
if (menu.isCurrentSubMenu()){
subMenu.up(); //set index closer to maximum
}
break;
case ‘a’:
menu.down();
break;
case ‘d’:
menu.up();
break;
case ’ ':
menu.use();
break;
case ‘0’:
menu.select(0);
break;
case ‘1’:
menu.select(1);
break;
case ‘2’:
menu.select(2);
break;
}
}
}

void menuChanged(ItemChangeEvent event){
Serial.println(“menuChanged”);
if( event == &menuItem1 ){
Serial.println("\tmenuItem1 selected"); //user feedback
}else if( event == &menuItemWithSubmenu ){
Serial.println("\tmenuItemWithSubmenu selected"); //user feedback
}else if( event == &subMenuItem1 ){
Serial.println("\tsubMenuItem1 selected"); //user feedback
}else if( event == &subMenuItem2 ){
Serial.println("\tsubMenuItem2 selected"); //user feedback
}else if( event == &subMenuItem3 ){
Serial.println("\tsubMenuItem3 selected"); //user feedback
}else if( event == &menuItem3 ){
Serial.println("\tmenuItem3 selected"); //user feedback
}
}

void menuUsed(ItemUseEvent event){
Serial.println(“menuUsed”);
if( event == &menuItem1 ){
Serial.println("\tmenuItem1 used"); //user feedback
}else if( event == &subMenuItem1 ){
Serial.println("\tsubMenuItem1 used"); //user feedback
}else if( event == &subMenuItem2 ){
Serial.println("\tsubMenuItem2 used"); //user feedback
}else if( event == &subMenuItem3 ){
Serial.println("\tsubMenuItem3 used"); //user feedback
}else if( event == &menuItem3 ){
Serial.println("\tmenuItem3 used"); //user feedback
}
}

Resulting menu ‘structure’:

[ menuItem1 ][ menuItemWithSubmenu ][ menuItem3 ]
             [    -subMenuItem1    ]
             [    -subMenuItem2    ]
             [    -subMenuItem3    ]
You control this example by [w,a,s,d,space,0,1,2]
    w = move 'up' in submenus
    a = move left in the menu
    s = move 'down' in submenus
    d = move right in the menu
    space = select/use current menu item
    0 = select menuItem1
    1 = select menuItemWithSubmenu
    2 = select MenuItem3

Result from try:

menuChanged //menu.select(0);
menuItem1 selected

menuChanged //subMenu.select(0);
subMenuItem1 selected

menuChanged // <> d [moved ‘right’ from menuItem1 to menuItemWithSubmenu->subMenuItem1
subMenuItem1 selected

menuChanged // <> s [moved down in the submenu]
subMenuItem2 selected

menuChanged // <> s [moved down in the submenu]
subMenuItem3 selected

menuUsed // <> space [used the current item]
subMenuItem3 used

menuChanged // <> d [moved right in the menu]
menuItem3 selected

menuUsed // <> space [used the current item]
menuItem3 used

menuChanged // <> a [moved left in the menu]
subMenuItem3 selected

menuChanged // <> a [moved left in the menu]
menuItem1 selected

Download Menu.zip

The playground page is under construction.

Have you finished your work on the playground regarding the "Menu" Library?

Hello!

This library is still a work in progress, much because I think no-one except me use it.

If you have any questions or problems, feel free to contact me here, PM, per mail or msn :]

See you!

It seems a nice idea, but I don't find a way to embed it inside a microcontroller. I would like to use it on an small application (just a 4x7-segment display), 2 or 3 push-buttons and a serial port.

Best Regards,

/me

This library is still a work in progress, much because I think no-one except me use it.

I would hardly argue that it is for lack of others using it. It has the potential for a lot of use. Anytime you want an LCD with a list of options this library would be extremely useful.

Right now though, and it may just be my misinterpretation, it seems that you can only make it but one level deep. Is this correct? Why not change it to where you just have two item types? Menu and MenuItem. Then you just make it where the addSubMenu() function accepts a Menu instead of a different SubMenu type. This way you could theoretically make it so that you could have a menu that goes n levels deep and does not have to be a complete n level tree either.

To give you an idea of what I'm doing, I'm using this to create a menu system for a setup that I'm designing to control and monitor my aquarium. Just for the sake of how many items I want to have in the menu, it is always nice to be able to group some of the items a little.

Have a look at this: http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1273349195/0#0

The old Menu was written with simple screens in mind (I wrote it for ASCII LCDs). The new one provides a much more versatile way to manage menus.

It supports: *2d menus (navigation in four directions) *Mnemonic cymbols (see the example, and the use('V') triggers the Verify item) *Backnavigation (the menu 'remembers' your traversal through the menu) :)

Please do continue work on the Playground page--I'm very interested. I posted this last week: http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1280801433/4.

I need a very simple five-item menu for 16x2 LCD. The device is for education, so we want to keep code as simple as possible so students can hack it.

I was wondering if work is till going on with this menu library. I really like the start of it, but I'm trying to get it to work with a 2-button setup and an LCD. I am quite new to programing and the ardiuno in general, otherwise i'd try and do these changes myself.

In my project, I was looking to use 1 or 2 buttons to scroll (up/down or just down, and loop to the first item when reaching the end) and a button to select.

My thought was to have a top menu, with sub-menus similar to what you have here, but a slight difference:

Currently, as you scroll through the list, you get:

menuItem1 -> subMenuItem1-3 -> menuItem3

Then you have other keys to select the subMenuItem number.

I was wondering if it would be possible to change the code in such a way so that scrolling goes:

menuItem1 -> menuItem2withSubMenu -> menuItem3

Then pressing a 'selection key' on menuItem2withSubMenu reveals the next list:

subMenuItem1 -> subMenuItem2 -> subMenuItem3

Doing this with 2 buttons, the lists would loop, with the subMenuItem3 being an "exit" function to bring the user back to menuItem2withSubMenu.

I've seen this done on many industrial interfaces and think it's a really neat way to simplify the user interface.

UPDATE: After reviewing the sample program a bit closer, it appears that you have an menuChanged event handler for menuItemWithSubMenu, but it just never gets displayed. I will keep investigating. Solving this would make a really nice library for a simple, powerful LCD menu. I just wish I knew more about what I was looking at.

I'll have to admit that the development have come to a halt, but that's because I've forgotten about it.

If you would not mind, please send me a mail and a diagram/sketch of the layout of your menu and I'll get back to you with a possible solution :)

alexanderbrevig [ATSIGN] gmail [DOTHERE] com

Please do continue work on the Playground page--I'm very interested.

+1 ;)

Please do work on a library. Here's an attempt I made, not very good I fear, for a flow controller that is now in production. Video and such here:

http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1287629597/8#8

Steve

I’ve managed to fiddle with it enough to be able to create an infinitely looping menu. That will pave the way for 2-button menu navigation if I decide to stick with that route.

Old Code from Menu.cpp:

void Menu::up(){
  select(currentIndex+1);
}

void Menu::down(){
  select(currentIndex-1);
}

New Code:

// Added check for looping of menu items
void Menu::up(){
      if ((currentIndex+1)<numberOfMenuItems) {
            select(currentIndex+1);
      }
      else {
            select(0);
      }
}

//Added check for looping of menu items
void Menu::down(){
      if ((currentIndex-1)>=0) {
            select(currentIndex-1);
      }
      else {
            select(numberOfMenuItems-1);
      }            
}

Basically, I just added a check for the selection index to loop back around. I tried just adding this check to the “bool Menu::select(byte select)” but for some reason, it would only go one direction. menu.up() would work correctly, looping the menu, but menu.down() would continuously stop at the first menu item, and wouldn’t loop. I’m pretty sure this has something to do with the functions up top setting the selection to 0, but at this point, I’m just happy I got it working.

I’ve currently got it wired for three buttons, so scrolling up to far brings you to the end of the menu, and visa-versa.

Next I am going to take a look at menu headings and see if I can’t get menus with subMenus to display correctly, i.e., it only shows the menu heading first, then shows the first subMenu heading when physically selected.

Also, i’m going to be posting some of these code changes, but I’m not a programmer, so if there is easier commands i could be using, or a better way to do this, please feel free to help a brother out.

EDIT: One more thing - It looks like menu.cpp and subMenu.cpp are fairly similar, so I’m thinking that making the same changes to the subMenu.cpp will result in similar functionality. I’ll have to try it out when i can properly scroll through it.

This library will be deprecated in favor of this:

http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1273349195/30#41

IF you have any wishes or ideas please do not hesitate to let me know :slight_smile: