Pages: [1] 2 3   Go Down
Author Topic: New Arduino library: MenuSystem  (Read 9461 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 26
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I've written an Arduino library for creating a nested menu system....and I called it MenuSystem (how original!). I wanted to share it with the World. Feedback and suggestions welcome (preferably on my blog, but that's up to you).

Tutorial: http://jonblack.org/2012/05/14/arduino-library-for-creating-a-menu-system/
Source Code: https://github.com/jonblack/arduino-menusystem
« Last Edit: December 20, 2013, 07:26:30 am by jonblack » Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 24
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I was just starting to write a project that needs a menu when i saw your post... :-) , i'll give it a try.

Thanks for sharing.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 26
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Good to hear smiley If you have any questions, let me know. Good luck!
Logged

Germany
Offline Offline
Edison Member
*
Karma: 137
Posts: 1526
If you believe something is right, you won't see what's wrong (David Straker).
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi

How do i display the menu? Is it intended to show the menu tree somewhere?

Oliver
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 26
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Think of MenuSystem as a container for your menu system, holding the structure, current items, and callbacks. So, it won't display anything for you. What it does provide are three functions:

  • ms.get_current_menu_name(); // get the current menu name
  • ms.get_num_menu_items(); // get the number of menu items in the current menu
  • ms.get_cur_menu_item(); // get the current menu item number in the current menu

The first one is probably all you need. This returns the current menu name. Every time you call back(), next(), prev(), select() this will change. The other two functions return the current menu item number and total number of items in the current menu level. These are useful if you want to implement some kind of pagination.

Does that answer your question?

Hi

How do i display the menu? Is it intended to show the menu tree somewhere?

Oliver
Logged

Germany
Offline Offline
Edison Member
*
Karma: 137
Posts: 1526
If you believe something is right, you won't see what's wrong (David Straker).
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

So this means, I need to write a procedure which renders the menu on an output device. This procedure also has to take care to highlight the "current" menu item, correct?

Thanks for clarification,
Oliver


Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 26
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

So this means, I need to write a procedure which renders the menu on an output device. This procedure also has to take care to highlight the "current" menu item, correct?

Thanks for clarification,
Oliver

Yes, you need to render the menu to a device. Bear in mind that this library manages which item is current for you, and that is the only item you should display. This means that you can only show one option on your output device at a time. If you want to display all menu items and highlight the current one, this library isn't for you. I've written some pseudo-code below to explain this, I hope it makes sense:


def process_input():
  if next_button_pressed:
    menusystem.next()
  else if prev_button_pressed:
    menusystem.prev()
  else if select_button_pressed:
    menusystem.select()
  else if back_button_pressed:
    menusystem.back()

def update_menu():
  current_item_text = menusystem.get_current_menu_name()
  output_device.write(current_item_text)

def loop():
  process_input()
  update_menu()
Logged

Germany
Offline Offline
Edison Member
*
Karma: 137
Posts: 1526
If you believe something is right, you won't see what's wrong (David Straker).
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

ok, now I understand.

Thanks
Oliver
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 24
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

To manage the menu tree i added a function to Menu class:

Code:
MenuComponent* Menu::get_item( int num )
{
    return _menu_components[num];
}

And print items this way for example:

Code:
MenuComponent* selected = mm.get_selected();

for( int i=0; i<mm.get_num_menu_items(); i++ )
{
MenuComponent* item = mm.get_item( i );
gotoXY( 0, i );
if( item == selected ) LCDString( ">");
else                   LCDString( " ");
LCDString( item->get_name() );
}


By now i just have tested some basic things of the library and it is working very well.



Logged

France
Offline Offline
God Member
*****
Karma: 11
Posts: 644
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

When I developed my menu class, I faced two difficulties: displaying the menu and defining the options.

Here's there result:


A menu is declared this way:
Code:
// menu declaration and size
item myMenuItems[] = {
  {     0x0000, "Menu 0"        }  ,   
  {     0x1000, "Item 1"        }  ,
  {     0x1100, "Item 11"       }  ,
  {     0x1200, "Item 12"       }  ,
  {     0x2000, "Item 2"        }  ,
  {     0x2100, "Item 21"       }  ,
  {     0x2110, "Item 211"      }  ,
  {     0x2120, "Item 212"      }  ,
  {     0x2121, "Item 2121"     }  ,
  {     0x2122, "Item 2122"     }  ,
  {     0x2200, "Item 22"       }  ,
  {     0x2300, "Item 23"       }  ,
  {     0x3000, "Item 3"        }
};

Learn more about the menu and the Serial_LCD library suite  smiley
Logged


Offline Offline
Newbie
*
Karma: 0
Posts: 24
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Not sure if this is possible without doing changes, but i needed another function in MesuSystem class:

Code:
Menu* MenuSystem::get_current_menu()
{
    return _p_curr_menu;
}

And i print the current menu at it's items this way:
Code:
void updateMenu()
{
LCDClear();

Menu* currentMenu = menu_system.get_current_menu();

MenuComponent* selected = currentMenu->get_selected();

LCDString( currentMenu->get_name() ); // Displays current menu

for( int i=0; i<currentMenu->get_num_menu_items(); i++ )
{
MenuComponent* item = currentMenu->get_item( i );

gotoXY(  5, i+1 );

if( item == selected ) LCDString( ">"); // Displays an arrow in current item
else                   LCDString( " ");

LCDString( item->get_name() ); // Displays items in current menu
}
}

I see more ineresting have getter: MenuSystem::get_current_menu() intead of MenuSystem::get_current_menu_name(), with the first i can access to anything i need in the current menu, not only name.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 26
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Not entirely sure how this is relevant to the MenuSystem I've created. Looks to me like a shameless plug!

When I developed my menu class, I faced two difficulties: displaying the menu and defining the options.

A menu is declared this way:
Code:
// menu declaration and size
item myMenuItems[] = {
  {     0x0000, "Menu 0"        }  ,   
  {     0x1000, "Item 1"        }  ,
  {     0x1100, "Item 11"       }  ,
  {     0x1200, "Item 12"       }  ,
  {     0x2000, "Item 2"        }  ,
  {     0x2100, "Item 21"       }  ,
  {     0x2110, "Item 211"      }  ,
  {     0x2120, "Item 212"      }  ,
  {     0x2121, "Item 2121"     }  ,
  {     0x2122, "Item 2122"     }  ,
  {     0x2200, "Item 22"       }  ,
  {     0x2300, "Item 23"       }  ,
  {     0x3000, "Item 3"        }
};

Learn more about the menu and the Serial_LCD library suite  smiley
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 26
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Looks interesting. I'll test it and see if it fits well with the original design. It's nice that you can display multiple items and show the highlighted one, what I don't like is having to iterate over the menu components outside of the library - those should stay internal.

Perhaps a function in the menu system like so would be better:

char** MenuSystem::get_current_menu_options();

This will return an array of the menu options for the current menu. What do you think?

Not sure if this is possible without doing changes, but i needed another function in MesuSystem class:

....

I see more ineresting have getter: MenuSystem::get_current_menu() intead of MenuSystem::get_current_menu_name(), with the first i can access to anything i need in the current menu, not only name.

Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 24
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Perhaps a function in the menu system like so would be better:

char** MenuSystem::get_current_menu_options();

This will return an array of the menu options for the current menu. What do you think?
Ok, this is a safer and easier (for the user) way to do it.

The only little disadvantage i see if i understand correctly is that MenuSystem has to iterate through items to create the array, and then the user has to iterate again through array to print names, what is little slower, but... all have a price.

Another cuestion: Why do you pass a pointer to MenuItem in the callback funtion?

Thinking about this library.. it could be used for anything that needs a tree structure, noy only a menu system.

Logged

France
Offline Offline
God Member
*****
Karma: 11
Posts: 644
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Not entirely sure how this is relevant to the MenuSystem I've created. Looks to me like a shameless plug!

When I developed my menu class, I faced two difficulties: displaying the menu and defining the options.


Sorry for my contribution on menu indexing being considered as a shameless plug.
Logged


Pages: [1] 2 3   Go Up
Jump to: