Micro menu and GUI.

Menus.

Video

Written words and still images don't convey the dynamics of the menus so I've done a video.
It is just over 2 minutes long and is 27meg in size.
File leaching is currently banned but people are welcomed to copy or mirror this video.menudemo1.mpg

March 2010,

My menu code is part of the Nokia colour LCD2 project. This aspect of the LCD code is big enough to warrant a page of it's own. I'm also hoping it can be reused for projects not using the Nokia LCD at all. It may even be used on non AVR processors.

The first version of the micro menu is coded in winarv GCC for the AVR mega328 and nokia LCD.

The code is fairly light weight but offers quite a few features.

Features.

A simple data structure in FLASH.

Full colour drop down menus.

Nested sub-menus.

Roll-over events.

Optional titles on menus and sub-menus.

Menu items can be disabled and re-enabled at runtime.

It is trackball controlled. It should be easy to adapt to other input devices.

Menu does not close when a item is selected.

Open sourced winAVR GCC.

data structure.

With only 2K of RAM available we don't want to put big data structures or tables in RAM. By default winAVR will use RAM. The menu structure is defined using the PROGMEM directive to place the structures in FLASH. This also means you can't access the data without using FLASH related functions such as strcpy_P and pgm_read_word.

typedef void (*funcpoint)(void); // a type def for a funtion pointer.
struct menuitems { // The structure used for defining menus
char menustr[17]; // a string constant, either a menu name or a title.
funcpoint executioncode; // a pointer to the code which executes when the item is activated.
short FG; short BG; // constants for foreground and background colours.
funcpoint doover; // a pointer to code which executes when the menu item is highlighted.
funcpoint exitover; // a pointer to code which executes when the menu item is de-highlighted.
char *disable; // a pointer to a RAM variable. Menu enabled if pointer null or variable == TRUE
};

Colour.

All menu strings have individual foreground and background colours. The colours are currently stored in flash and can't be changed at runtime. I could make them changeable at runtime if the need arises.

Sub-menus

There is no special field or flag to specify a sub-menu. A sub-menu item in a parent menu is no different to any other item except that it calls the sub-menu set up routine when activated.
A simple stack is used to remember details of the sub-menu's parent so the parent can be restored if the sub-menu is aborted. This also happens for sub-menus of sub-menus so they can be nested till the stack limit is reached.

Roll-overs.

Every menu item has two pointers for "over" event. One executes when the item in highlighted and another when the item is returned to normal. These are similar to mouse-overs in PC GUIs.
The pointers are call "doover" and "exitover". I didn't use "rollover" because the code may be adapted to other input devices which don't roll.
A typical use for roll-overs would be to draw a menu hint text box when an item is rolled over.

Menu Titles/headings.

Titles are optional. Not using a title allows an extra two menu items to fit on the small screen.

Enable/disable.

The "disable" field of the menu structure can point to a variable in RAM. This variable can the changed at runtime to enable or disable a menu-item.
An example of a menu item with the disable option used is below.

{"TestDisable",&enable1,WHITE,BLACK,Redon,Redoff,&TestDisable},

Several items could point to the same variable and be enabled or disabled as a group.
One could define a more complex structure to allow individual bits in a variable to be used if RAM usage became really tight.

HID.

The current code is written for a mini-trackball but should easily adapt to other human interface devices. The current features should work quite well with four switches, a switch based joystick or an analogue joystick.

No menu auto close.

There are many time when it is not appropriate to close the menu just because you have selected an action. By leaving it open and leaving it up to the application to close or re-enter the menu I have much more versatile interface. You could for example use a sub-menu to set up the parameters for a serial device without having to navigate the menu again for each item. This could remove the need to build a serial parameter set-up page.

GUI.

Other features are not strictly part of the menu system but are closely related.
When I first thought about controlling the chamber I thought about not having a menu and instead just flipping through all the setup and control pages screens till you reach the one I want.
After I finished the menu code I found I could easily reuse the routines to implement my original idea. With very little effort I now have both systems in place. The menus as demoed in the video are unchanged.

The four main status screens are now linked in a way which allows the pages to be "turned" with a sideways roll of the ball. They are link in a simple 1,2,3,4,1 sequence that can be navigated in either direction. It would also be possible to link in different ways. For example a left roll could jump to groups of pages while a right roll cycles through pages in the selected group.

I've also set up a slide-show mode where pages change automatically. Rolling down toggles the slide show on and off and a sideways roll turns slide show off.