Indeed, nice buttons.
So, assuming you want to give a try to M2tklib, here is some example.
Let's start with the first menu:
menu 1
lights on/off
submenu 1
light timer
First, i rename it from "menu 1" to "light"-menu, and i remove the submenu 1.
Then we have:
light menu
lights on/off
light timer
The basic M2tklib building block is a dialog window. The active dialog window is visible and data can be entered into it by the user. The light control dialog window for your first menu may look like this:
Light On: <toggle button>
Timer: <numeric input>
< ok button >
This is the layout. Of course this is only my personal suggestion how to design this.
This layout has to be translated into m2tklib language. More specific, each layout component has to be translated into an m2tklib element. Elements are listed here:
http://code.google.com/p/m2tklib/wiki/elrefThe translation will have the following result:
<M2_LABEL> <M2_TOGGLE>
<M2_LABEL> <M2_U8NUM>
<M2_BUTTON>
Before I start to turn this into real code: M2tklib dialog windows interact with the remaing program by variables. This means we have to define variables, which will be filled by M2tklib with the data given by the user:
// the following variables contain the input values from the user
uint8_t light_timer = 0;
uint8_t light_on = 0;
Let us convert the first label into real code. The label text will be "Light On: "
The code is:
M2_LABEL(el_light_on_label, NULL, "Light On: ");
The first argument to the element is an element name ("el_light_on_label"). All elements in M2tklib start with their element name.
The second argument to the element is the format string. Also in M2tklib all elements have such a format string. I try to avoid the use of format strings as far as possible in this example, but in principle, a format string provides additional information for the element.
The third argument is the label text itself.
M2_LABEL is also discussed here:
http://code.google.com/p/m2tklib/wiki/elref#LABELNow I do not discuss all remaining elements, but just give the element translated code here:
M2_LABEL(el_light_on_label, NULL, "Light On: ");
M2_TOGGLE(el_light_on_toggle, NULL, &light_on);
M2_LABEL(el_light_timer_label, NULL, "Timer: ");
M2_U8NUM(el_light_timer_u8, "c2", 0, 99, &light_timer);
void light_dialog_ok(m2_el_fnarg_p fnarg) {
/* do something with the values */
/* ... */
/* go back to main menu */
m2.setRoot(&el_top_controller_menu);
}
M2_BUTTON(el_light_ok, "f4", " ok ", light_dialog_ok);
Some notes:
- M2_U8NUM expects a range (here from 0 to 99 as an example)
- M2_U8NUM has a format option which limits the number of visible digits to 2
- M2_BUTTON expects a callback function. This means, a procedure (light_dialog_ok) is called when the button is pressed.
- Within a callback procedure you can change the complete dialog window by assigning a new dialog (root) elemet. This is el_top_controller_menu in our case.
- M2_BUTTON option "f4" selects the so called highlighted font 0. This is done by placing a box around the text (see below).
- Variables are provided as arguments to the related element, with a "&" in front of it
- The format argument NULL means: No options, use default values.
How does M2tklib know the arrangement of elements? Well, we need to define it. For this reason we have so called container elements. One usefull container is the grid element. M2_GRID expects a list of elements and arranges them in a matrix style:
M2_LIST(list_light_dialog) = {
&el_light_on_label, &el_light_on_toggle,
&el_light_timer_label, &el_light_timer_u8,
&el_light_ok
};
M2_GRIDLIST(el_light_grid, "c2", list_light_dialog);
Notes:
- M2_LIST ist NOT an element. It is a list
- Elements are always refered by adding a "&" in front of it
- Lists are always refered without a "&" in front of it
- Format option "c2" defines two columns for the matrix
At last, we want to center the whole dialog window. This is done by M2_ALIGN. Unfortunately it requires a more complex format option, so this is given here without further explaination:
M2_ALIGN(el_top_light, "-1|1W64H64", &el_light_grid);
At the end, it will (more or less) look like this:

The actual style will depend on the underlaying graphics engine. Is it a character or graphics LCD? Which font is in use? Which cursor style has been selected? What is the shape of the toggle button?
One good thing on M2tklib is, that your code is portable. You can use the same code with a character display.
Finally let me discuss the main menu: Design could be this:
<Jump to Light Menu>
<Jump to Power Menu>
I already had introduced M2_BUTTON, but if you only want to switch to another dialog window, then M2_ROOT is more easier to use (it avoids the callback procedure):
M2_ROOT(list_controller_light, NULL, "Light", &el_top_light);
M2_ROOT(list_controller_power, NULL, "Power", &el_top_power);
// all menu lines are grouped by a vlist element
M2_LIST(list_controller_menu) = { &list_controller_light, &list_controller_power};
M2_VLIST(el_controller_menu_vlist, NULL, list_controller_menu);
// center the menu on the display
M2_ALIGN(el_top_controller_menu, "-1|1W64H64", &el_controller_menu_vlist);
Notes:
- Very similar to the previous dialog window...
- Instead of M2_GRID, there is M2_VLIST which is a little bit simpler than M2_GRID: It arranges the buttons in a vertical list
I skip the power menu. I am sure you can design it by yourself.
I hope that this introduction was not too complicated and confusing, so if there are more questions, please let me know.
Oliver