Go Down

Topic: menubackend library submenus (Read 4 times) previous topic - next topic

a.mlw.walker

#5
Jul 16, 2012, 08:55 pm Last Edit: Jul 16, 2012, 10:40 pm by a.mlw.walker Reason: 1
Hi Oliver,
I wonder if you could pull a slightly more basic example together, Ive been studying the code from the example, but it seems like setting pwm pins is hard coded into the class?
Is there any chance you could make a simple example possibly using the girl/boy example where it calls a second menu for the hair colour. Also is there any chance you could do it using serial.println() to display the menu so it is very bare bone as it were?
i know im asking quite a lot but it would be extremely handy if you could find the time
Thanks
A

olikraus

ok, let me start with your last question:
Within the pwm example:
In line 67 replace
M2tk m2(&top_el_pin_list, m2_es_arduino, m2_eh_4bs, m2_gh_lc);
with
M2tk m2(&top_el_pin_list, m2_es_arduino_serial, m2_eh_4bs, m2_gh_arduino_serial);

This will use serial.print and you can see the menu on the serial monitor.
(hey, thats a really cool feature, isn't it...  8) )

I will answer the remaining questions in another post.

Oliver

olikraus

ok, then, here is my boy, girl,... example. Very simplified and reduced to one screen.

Code: [Select]

#include <LiquidCrystal.h>
#include "M2tk.h"
#include "m2ghlc.h"

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

uint8_t uiKeySelectPin = 10;
uint8_t uiKeyNextPin = 9;

uint8_t girl_color = 0;
uint8_t boy_color = 0;
uint8_t man_color = 0;

void fn_ok(m2_el_fnarg_p fnarg) {
  /* do something */
}

const char *fn_idx_to_color(uint8_t idx)
{
  switch(idx)
  {
    case 0: return "brown";
    case 1: return "blonde";
    case 2: return "red";
  }
  return "";
}


M2_LABEL(el_label1, NULL, "Boy:");
M2_COMBO(el_combo1, NULL, &boy_color, 3, fn_idx_to_color);

M2_LABEL(el_label2, NULL, "Girl: ");
M2_COMBO(el_combo2, NULL, &girl_color, 3, fn_idx_to_color);

M2_LABEL(el_label3, NULL, "Man: ");
M2_COMBO(el_combo3, NULL, &man_color, 3, fn_idx_to_color);

M2_BUTTON(el_ok, NULL, " ok ", fn_ok);

M2_LIST(list) = {
    &el_label1, &el_combo1,
    &el_label2, &el_combo2, 
    &el_label3, &el_combo3, 
    &el_ok
};

M2_GRIDLIST(list_element, "c2",list);
M2tk m2(&list_element, m2_es_arduino, m2_eh_4bs, m2_gh_lc);

void setup() {
  m2_SetLiquidCrystal(&lcd, 16, 4);
  m2.setPin(M2_KEY_SELECT, uiKeySelectPin);
  m2.setPin(M2_KEY_NEXT, uiKeyNextPin);
}

void loop() {
  m2.checkKey();
  if ( m2.handleKey() )
    m2.draw();
  m2.checkKey();
}


The result will be stored in the three variables:
Code: [Select]

uint8_t girl_color = 0;
uint8_t boy_color = 0;
uint8_t man_color = 0;


I am not sure if i should repeat what is written in the reference manual. Maybe you should have a look at M2_GRIDLIST, which arranges the element into a matrix and M2_COMBO which does most of the work here.
So please let me know if there is something i can explain into more detail.

Remember: You can still use the serial monitor by replacing the event handler (eh) and the graphics handler (eh) as described in my last post.

Oliver

olikraus

so, finally, here is the example with submenu:
Code: [Select]


#include <LiquidCrystal.h>
#include "M2tk.h"
#include "m2ghlc.h"

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

uint8_t uiKeySelectPin = 10;
uint8_t uiKeyNextPin = 9;

uint8_t girl_color = 0;
uint8_t boy_color = 0;
uint8_t man_color = 0;

M2_EXTERN_GRIDLIST(el_main_menu);
M2tk m2(&el_main_menu, m2_es_arduino, m2_eh_4bs, m2_gh_lc);

void fn_ok(m2_el_fnarg_p fnarg) {
  /* color changed, do something */
 
  /* then jump back to the main menu */
  m2.setRoot(&el_main_menu);
}

const char *fn_idx_to_color(uint8_t idx)
{
  switch(idx)
  {
    case 0: return "brown";
    case 1: return "blonde";
    case 2: return "red";
  }
  return "";
}

/* boy submenu */
M2_LABEL(el_label1, NULL, "Boy:");
M2_COMBO(el_combo1, NULL, &boy_color, 3, fn_idx_to_color);
M2_BUTTON(el_ok1, NULL, " ok ", fn_ok);
M2_LIST(list1) = {
    &el_label1, &el_combo1,
    &el_ok1
};
M2_GRIDLIST(el_grid1, "c2",list1);

/* girl submenu */
M2_LABEL(el_label2, NULL, "Girl:");
M2_COMBO(el_combo2, NULL, &girl_color, 3, fn_idx_to_color);
M2_BUTTON(el_ok2, NULL, " ok ", fn_ok);
M2_LIST(list2) = {
    &el_label2, &el_combo2,
    &el_ok2
};
M2_GRIDLIST(el_grid2, "c2",list2);

/* man submenu */
M2_LABEL(el_label3, NULL, "Man:");
M2_COMBO(el_combo3, NULL, &man_color, 3, fn_idx_to_color);
M2_BUTTON(el_ok3, NULL, " ok ", fn_ok);
M2_LIST(list3) = {
    &el_label3, &el_combo3,
    &el_ok3
};
M2_GRIDLIST(el_grid3, "c2",list3);

/* main menu */
M2_ROOT(el_boy_button, NULL, "Boy", &el_grid1);
M2_ROOT(el_girl_button, NULL, "Girl", &el_grid2);
M2_ROOT(el_man_button, NULL, "Man", &el_grid3);
M2_LIST(list_main_menu) = {
    &el_boy_button, 
    &el_girl_button,   
    &el_man_button, 
};
M2_GRIDLIST(el_main_menu, "c1",list_main_menu);

void setup() {
  m2_SetLiquidCrystal(&lcd, 16, 4);
  m2.setPin(M2_KEY_SELECT, uiKeySelectPin);
  m2.setPin(M2_KEY_NEXT, uiKeyNextPin);
}

void loop() {
  m2.checkKey();
  if ( m2.handleKey() )
    m2.draw();
  m2.checkKey();
}


This example defines four different menus (or dialog boxes). You can switch between these dialog boxes by using the M2_ROOT button or the m2.setRoot procedure. Calling a sub menu is nothing else than assigning a new dialog box with M2_ROOT. For the jump back to the main menu, the callback procedure of the ok button uses "m2.setRoot()".

hope this helps... again, let me know if you need more examples.

Oliver

a.mlw.walker

Great Oliver, thanks I'll give that a go.
So I can change easily to serial from you lcd, however what if I want to use a different lcd to the one in your library.
I declare my lcd here:

Code: [Select]

Adafruit_PCD8544 display = Adafruit_PCD8544(52, 51, 50, 48, 49);


So I need to replace:
Code: [Select]

m2_gh_lc

but Im not sure with what... it isnt declared anywhere else in your code, and I assume
Code: [Select]

m2_es_arduino

can stay the same if I change the lcd?
And lastly:
Code: [Select]

m2_SetLiquidCrystal(&lcd, 16, 4);
[code]
?
[/code]

Go Up