Menu system

Im trying to build a menu system for my Panda tinkerer kit and Im wondering if any of you have some input on how to program it?

The menu system will be used to change settings in the system and Im not looking for more than two, max three levels.

I have three buttons: Up, Down and Select (toggle ON/OFF)

So, how is the best way to build a menu system? An endless mess of if (or switch) statements or is there a better way?

What display are you using?

Just a 16x2 LCD

You can write it so it is independent from the display where you write to memory the flush memory. This will work nut then it maybe slow. A better way is to write to display directly and optimize the menue just for the display

Look at our drivers fir 128x64 displays. There is the core driver that can print text right to the display and there is the graphics drivers. Writing right to the display is much faster but then you are stuck with 8pixel alignment plus you end up with limited font size, 8pixels high. For a menu? I would go with direct and limited apeoach ti make things faster

Just saw your last post, my post only applies to displays with graphics

Menu on a 2x16 character display? Won’t be very exciting

After reading your question one more time I think it is more generic and doesn’t really mater what display you are using.

There are multiple options. You can have a menu state machine. You can have a hash table that will map current state to a handler delegate.

I must admit that I have absolutely no idea of how this works;

Do you have an example or a link to further reading?

I will put an example, later tonight. ;D

Thats great Architect.
Looking forward to have a look at it. You have my full respect!
I’m off for bed so take you time :slight_smile:

Geir,

Menu Manager class:


    public delegate void MenuItemHandler(int menuId);

    public class MenuManager
    {
        /// <summary>
        /// Hashtable to keep all menu items and corresponding handlers
        /// </summary>
        Hashtable  _menuItems = null;
        
        /// <summary>
        /// Constructor
        /// </summary>
        public MenuManager()
        {
          _menuItems = new Hashtable();
        }

        /// <summary>
        /// Add new menu entry
        /// </summary>
        /// <param name="id">menu id</param>
        /// <param name="handler">handler</param>
        public void AddMenuItem(int id, MenuItemHandler handler)
        {
            _menuItems.Add(id, handler);
        }

        /// <summary>
        /// Call the menu handler for the given menu id
        /// </summary>
        /// <param name="menuId"></param>
        public void Execute(int menuId)
        {
            if (_menuItems.Contains(menuId))
            {
                MenuItemHandler handler = _menuItems[menuId] as MenuItemHandler;

                if (handler != null)
                {
                    handler(menuId);
                }
            }
        }
    }

Menu ids:


        internal sealed class MenuIds
        {
            //File menu
            internal const int File = 10;
            internal const int Save = 11;
            internal const int Open = 12;
            internal const int Exit = 13;

            //Help menu
            internal const int Help = 20;
            internal const int About = 21;
        }

Initialize menu manager and setup handlers for each menu item:


        private MenuManager _menuManager = new MenuManager();

        private void InitializeMenu()
        {
            _menuManager.AddMenuItem(MenuIds.File, new MenuItemHandler(OnMenu));
            _menuManager.AddMenuItem(MenuIds.Save, new MenuItemHandler(OnSave));
            //_menuManager.AddMenuItem(MenuIds.Open, new MenuItemHandler(OnOpen));
            //_menuManager.AddMenuItem(MenuIds.Exit, new MenuItemHandler(OnExit));

            _menuManager.AddMenuItem(MenuIds.Help, new MenuItemHandler(OnMenu));
            //_menuManager.AddMenuItem(MenuIds.About, new MenuItemHandler(OnAbout));
        
        }


Somewhere in your button handling code:


_menuManager.Execute(menuId);

I hope this will give you an idea on how to implement it.
I also recommend to take a look at Design Patterns if you have not used them before. There is a lot of information on that topic.

Thank you very much Architect. This looks promising.
I will test it later as some in my household finds it more important to clean the house for new year party than playing with FEZ :o

Yep, I know what you mean ;).