Go Down

Topic: MENWIZ: yet another character lcd menu wizard library (Read 85600 times) previous topic - next topic

brunialti

Thanks drjm! Fixed.
The serial messages were for debugging. Deleted. As soon as I can I would like to post a new version with some enhancement. Unfortunately I never find the time....

cno1

Is there any possibility to unload the menu at runtime and reload another one?
Or maybe one could assign a visible/not visible property to single nodes; that wold help me
out of my current problem.

I need to change the menu based on the rights of the user that´s logged in...

Greetings and tanks for the cool library

Chris from AT

brunialti

Unfortunately the library does not allow to unload menus at run time.
It is not intrinsically difficult to implement such a functionality , but due to the memory heap management, deallocation of previously dinamically allocated memory could return memory chunks not reusable for further allocations. This could very easily exhaust the (small) available memory and halt the sketch in unpredictable manners.
Sorry :-)

cno1

thanks for the information, I'm thinking about trying to hack some kind of property into the menu construction, like an integer value assigned to each node being e.G. 0 as always there, 1-9 being access levels at which the nodes get visible. e.G.

Root Menu ... 0 .. everyone gets that menu of course
Node 1 ....... 0 .. every user gets that menu
Node 2 ....... 1 .. only users with privileges 1 and higher get that menu
Node 3 ....... 2 .. users with 2 and higher see this ...

Since I´m not the best of programmers out there i imagine setting a global variable at user login.

What do yo think about the idea? This would make it possible to construct the full menu at startup and display only the menus the user has access to at runtime.

brunialti

That could be feasible. I like this solution. As far as I can get time i'll do it. The overall overhead is quite small (1 byte for each menu node)
thanks !

cno1

#380
Jun 17, 2013, 10:32 am Last Edit: Jun 17, 2013, 03:17 pm by cno1 Reason: 1
thinking about it again, one could even apply a kind of bit matrix onto the menu entries like:

User 1 Rights  (integer = 5)        0000 0101
User 2 Rights  (integer = 3)        0000 0011

Menu a needs bit 2                   0000 0100 .. user 1 has rights, user 2 won´t see thet one
Menu b needs bit 1                   0000 0010 .. user 2 has rights, user 1 won´t see that one
Menu c needs bit 0                   0000 0001 .. both users have rights

also doesn´t need more than one byte per entry, leaving 8 different access levels open for play. looking  into your code I see, that it goes way beyond my c knowledge, but i´ll hack around anyway, keeping a untouched copy secure ont the side.

have a nice day!

cno1

#381
Jun 17, 2013, 03:10 pm Last Edit: Jun 18, 2013, 09:34 am by cno1 Reason: 1
Got it, at least kind of. all it does is iterate over menu entries that the user has no right to see.
its cobbled together, works only for submenus and doesn't care about the menu_index, which counts menus that maybe never will appear but it solves my problem. if anyone is interested I could post it here, but since it´s not my code I abused  I´m not sure if it´s okay.

changes in usage of the library look like this:


the creation of the menu:, see the additional integer before 'F'
Code: [Select]

menu.setBehaviour(MW_MENU_INDEX,false); 
  menu.setBehaviour(MW_ACTION_CONFIRM,true);
  r=menu.addMenu(MW_ROOT,NULL,0,F("Hauptmenue")); <- the 0 means this menu is always shown
   s1=menu.addMenu(MW_VAR,r,0,F("Licht"));       
    s1->addVar(MW_BOOLEAN,&aussenlicht); 
    s1=menu.addMenu(MW_SUBMENU,r,8,F("Sauna"));    <-- the 8 means the bit 3 (integer 8) of the user's rights is needed for the menu to show up
      s2=menu.addMenu(MW_VAR,s1,8,F("Start/Stop"));     

setting the user right is simply a matter of adding up the single bit's numeric values of the menu entries you want to give him:
Code: [Select]

    menu.myrights=0;
    if (any user logged in) (menu.myrights)++;
    if (user may see menus with bit 1) (menu.myrights) = (menu.myrights) +2;
    if (user may see menus with bit 2) (menu.myrights) = (menu.myrights) +4;
    if (user may see menus with bit 3) (menu.myrights) = (menu.myrights) +8;

 

brunialti

@cno1
thanks for the effort! I would like to implement the permissions via a setBehaviour interface, in order to let the interface unchanged: by default all the nodes (menus) are visible to any user. When needed the menu can be restricted to one of the 8 available levels.

cno1

Sounds cool and a lot cleaner than my approach. I already mentioned I´m not keen in programming in cpp, Started writing spaghetti code with COBOL in 1985 and seem to be stuck in gotos and returns ever since :)



starbug

Though i m one of your greatest MENWIZ fan i sometimes have a small problem. Just like this one:
I am looking for a possibility to switch off the menu and use the LCD for some other output. With a button code i would switch on the menu again..
Can someone give me some help ????

brunialti

#386
Jun 25, 2013, 07:05 pm Last Edit: Jun 25, 2013, 07:24 pm by brunialti Reason: 1
Did you try the addUsrScreen method?
As an example:
Code: [Select]

menu.addUsrScreen(msc,10000);

.....

void msc(){
 static  char buf[7];
 strcpy(menu.sbuf,"User screen"); //1st lcd line
 strcat(menu.sbuf,"\nUptime (s): ");strcat(menu.sbuf,itoa((int)(millis()/1000),buf,10));//2nd lcd line
 strcat(menu.sbuf,"\nFree mem  : ");strcat(menu.sbuf,itoa((int)menu.freeRam(),buf,10));//3rd lcd line
 strcat(menu.sbuf,"\n"); //4th lcd line (empty)
 menu.drawUsrScreen(menu.sbuf);
 }



after 10000 miliseconds since the last menu interaction it launches the msc function where you can display your data. If any button is pushed again, the menu takes the display control again.
If this is not enough, try to tell me what would you like to do.
Please note as you should not use sprintf function in order to save about 2K of memory

EDIT: addUsrScreen must be used inside setup function

starbug

Wow what a fast answer. Thank you Roberto. Well i just tried your proposal. Works like a charm. The only problem is that 4th line is flickering fast . I think this depends on the Arduino loop. Any chance to leave this loop and return on demand ?

brunialti

#388
Jun 25, 2013, 10:50 pm Last Edit: Jun 25, 2013, 11:10 pm by brunialti Reason: 1
it should'nt flicker. It could be due to a slow refesh rate or to text on the 3rd line wider than the display size (if you have a 40 chars display, trying to display 41 characters it could produce some flickering). Control the string length and if it is correct, try to patch the 4th line filling it  with blanks before \n .
No chance to leave ... the draw method manage by itself all the stuff... but ... you can create a node of type action and then inside the action manage the display directly.

starbug

due to your help i could solve the problem. Everything is working now as it should. Though you suggested not to use sprintf i am using it. The space does not worry me. I am just using about 34.000 out of 131000 for my code. I surely could reduce the code down to use a smaller capacity chip but if you see the cost it is not worth the work.
Okay my next problems are the variables assigned in the menu.
Such as:
MW_AUTO_INT an integer value, with min/max boundaries and increment/decrement step
I don't want to use the left and right button. Instead of that i would like to directly input to the variable via a 4x3 matrix board. I have already implemented the keypad using menu.addUsrNav(menuKeys,6); and using the keys 2,8,4,6,* and #.
I don't hope that i'll have to write a whole keypad input? I read your quick tutorial several times. Have i missed something?
Can you help me with this?
Thanks

Go Up