creating a simple gui in C for a microcontroller-based project

Hello Experts,

First, some background...
I am working on C project that will run on a micro controller.  There are 4 buttons (+, -, enter, and cancel)  
and a 2x16 character LCD that will be used for the user interface.  I've got a handle using the LCD and input  
buttons so far.  Although this project is micro controller-based, my questions are not specific to the micro.  


where I'm stuck...
I am looking for help (example code would be great as I'm pretty new to this) on creating the best data  
structure for the menu and mechanism for navigating through it.  I want to maintain the ability to add and delete menus in my code (not at runtime) and still be able to use the code that navigates through the menus without doing a lot of recoding.  I did some experimentation, and was able to do this without a hitch with a simple array, but I'm thinking I will need to use a more flexible data type, so I can keep menu text and the  
associated parameters (which may vary in type) for the menu text together.


I came up with the following nested structure design.  I don't even know if I'm on the right track or if the  
code below is possible, but I thought it might be helpful to see what I've been working with.


struct menu
{
   struct mainMenu
   {
       char mainMenuText[15];  //this is just some kind of title screen
   } MAINMENU;
   
   struct menu_1
   {
       char menu_1_item_1_Text[15];  // for each setting in the gui, there is display text
       int  menu_1_item_1_Value;     //  ...and a corresponding value.
       char menu_1_item_2_Text[15];
       int  menu_1_item_2_Value;
       char menu_1_item_3_Text[15];
       int  menu_1_item_3_Value;

   } MENU_1;

   struct menu_2
   {
       char menu_2_item_1_Text[15];
       int  menu_2_item_1_Value;
       char menu_2_item_2_Text[15];
       int  menu_2_item_2_Value;
   } MENU_2;
} MAINMENU;
   


I intend for it to end up looking something like as follows:

Main Menu
Menu 1
 Menu 1 item 1 = (some number)
 Menu 1 item 2 = (some number)
 Menu 1 item 3 = (some number)
Menu 2
 Menu 2 item 1 = (some number)
 Menu 2 item 2 = (some number)


I want to be able to "scroll" through the choices with my + and - buttons, so if I hit the "-" button when  
the main menu loads, I would be at the last top level menu choice (Menu 2, in this case).  If I hit the "+"  
button, when the Main Menu loads, I would be on Menu 1.  The cancel button will go back a level and the enter  
button will confirm a choice.


Thanks in advance!

SINEtistAsked:
Who is Participating?
 
Jaime OlivaresConnect With a Mentor Software ArchitectCommented:
I think linked list is exactly what you need, but you will need a more complex structure to go back and forth:
struct menu
   {
       char text[15];  // for each setting in the gui, there is display text
       int  value;     //  ...and a corresponding value.
       struct rmenu *next_sibling;  // poinjter to next menu option at same level
       struct rmenu *prev_sibling;  // poinjter to previous menu option at same level
       struct rmenu *first_child;     // pointer to next menu option at deeper level
       struct rmenu *parent;     // pointer to parent menu option
   } MENU;

notice this is the unique structure type you will need.
you can create options with a single funtion like:

struct MENU *CreateMenuOption(struct MENU *parent, char *text, int value);

so you can use as:
MENU *main = CreateMenuOption(NULL, "Main menu", 0);
MENU *menu1 = CreateMenuOption(main, "Option 1", 1);
MENU *menu2 = CreateMenuOption(main, "Option 2", 2);
CreateMenuOption(menu1, "Option 1.1", 11);
CreateMenuOption(menu1, "Option 1.2", 12);
CreateMenuOption(menu2, "Option 2.1", 21);

0
 
Jaime OlivaresSoftware ArchitectCommented:
Array won't be the best option for nested menus, better you use some kind of linked list structure, have you heard about it?
0
 
Jaime OlivaresSoftware ArchitectCommented:
Your structure for any kind of menu would be:

struct menu
   {
       char menu_1_item_1_Text[15];  // for each setting in the gui, there is display text
       int  menu_1_item_1_Value;     //  ...and a corresponding value.
       struct rmenu *next_sibling;  // poinjter to next menu option at same level
       struct rmenu *first_child;     // pointer to next menu option at deeper level
   } MENU;

0
 
Jaime OlivaresSoftware ArchitectCommented:
Sorry, variable names are unnecessarily complex:

struct menu
   {
       char text[15];  // for each setting in the gui, there is display text
       int  value;     //  ...and a corresponding value.
       struct rmenu *next_sibling;  // poinjter to next menu option at same level
       struct rmenu *first_child;     // pointer to next menu option at deeper level
   } MENU;

if you are using pure C you will need malloc function to dinamically create menu options at runtime, if you are using C++ you can work easier with the new operator, please specify.

0
 
SINEtistAuthor Commented:
Hi there,

Wow that was fast!

I am using C, as the micro does not support C++.  I was hoping to avoid malloc and free, because...well, frankly I guess I'm just  lazy and that's another new concept to learn.  ; )

I was considering linked lists, but I was under the impression that since each menu would have a different number of options, that a linked list was not appropriate.     Perhaps I'm just wrong about that.

Could you expand on how using the + and  - buttons will cycle through the dynamic data structure example you provided (with a few different menus to get me started).  Once I have that, I think I will be good to go... Go read up on malloc and free, that is.

Thank you!





0
All Courses

From novice to tech pro — start learning today.