HP Forums

Full Version: LibMenu : a simple toolbox for easy menu handling
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Hi,
Here is a small Lib I made to handle menu in a simple way.

If you needed to use DRAWMENU(), you know that you have to handle yourself MOUSE events to trigger actions, this lib cover the whole process.

API :
- LibMenu.reset() : prepare for a (new) menu, call it first.
- LibMenu.entry(pos, label, action) : register a menu entry, at given position (1 to 6). action is a string with function name that will be triggered.
- LibMenu.draw() : draw the menu (like the buildin DRAWMENU)
- LibMenu.events() : check if user has clicked on a menu entry and trigger actions. it does not stop program execution, to be used in your program loop.


How to use :
Code:
EXPORT funct1() BEGIN ... END; // define function that will be called on menu click.
EXPORT funct2() BEGIN ... END;

LibMenu.reset() // first, call reset at each new menu
LibMenu.entry(1,"test1","funct1()"); // then you can define each menu entries with entry(position,"caption","function")
LibMenu.entry(2,"test2","funct2()");

LibMenu.draw();// when you want to draw your menu, just call draw method
WHILE 1 DO
 LibMenu.events();  // when you want to rise action call events() method.
END; // that's done !!!

Obviously, you had to define your own actions in func1() and funct2() functions.

Important : if your functions are not public (no EXPORT), you have to provide the full qualified name (with your program name), like this :
Code:
funct1() //without EXPORT
BEGIN
// do something
END;
...
LibMenu.entry(1,"test1","myprog.funct1()"); // <== full qualified function name
...

Download v1.1 :
[attachment=4183]

Changelog 1.1 :
fixed : don't multi call function until finger is not released.

===> Jump to version 2.1 * click here * - with a video.

===> Jump to version 3 * click here *


Note : This version 1 is very simple (next versions provide enhanced features)
Hello, some questions and others

1: I Remove some apparently unnecessary EXPORT
2: The local variables p,t,ar (if they are in lowercase) of the function entryMenu(p,t,ar) must be defined as local in the header (Why?)
3: The variable STAY is not working, when a subfunction f1() is called stay->0, why?

LIBRARY FILE:
PHP Code:
//FILE:=LibMenu;
#pragma mode( separator(.,;) integer(h32) )
// LibMenu  "simple" v 1.0 primer october 2016

local m,a// menu entries and actions
local p,t,ar;

// start to reset.
resetMenu()
begin
 m
:={"","","","","",""};
 
a:={"","","","","",""};
end;

// to draw menu entries
draw()
begin
 drawmenu
(m(1),m(2),m(3),m(4),m(5),m(6))
end;

// to register menu etries
export entryMenu(p,t,ar)
begin
 m
(p):=t;
 
a(p):=ar;
end;

callitMenu(f)
begin
 
if f=="" then return; end;
 
expr(f);
 
draw();
end;

// to manage events, trigger actions
eventsMenu()
begin
 local e
;
 if 
mouse(1)<200 then return; end;
 
e:=1+floor(mouse(2)/53);
 
callitMenu(a(e));
end

TEST FILE
PHP Code:
//FILE:=LibMenuTest;
#pragma mode( separator(.,;) integer(h32) )

local stay:=1;
export LibMenuTest()
begin
 stay
:=1;
 print(
"stay:="+stay); wait(0.5);
 
LibMenu.resetMenu();
 
entryMenu(1,"menu1","tstLibM.f1()");
 
entryMenu(2,"menu2","tstLibM.f2()");
 
entryMenu(4,"menu4","tstLibM.f4()");
 
entryMenu(6,"exit","tstLibM.quitMenu()");

 
LibMenu.draw(); //;
 
while stay==DO
   
LibMenu.eventsMenu();
 
end;
 print(
"stay:="+stay); wait(0.5);
 return 
"Done";
end;

f1()
begin
  msgbox
("1st menu " "stay:=" stay);
  
//print("stay:="+stay); wait(0.5);
end;

f2()
begin
  msgbox
("2st menu " "stay:=" stay);
  
//print("stay:="+stay); wait(0.5);
end;

f4()
begin
  msgbox
("4 menu " "stay:=" stay);
  
//print("stay:="+stay); wait(0.5);
end;

quitMenu()
begin
 stay
:=0// you will quit nicely the WHILE loop
// print("stay:="+stay); wait(0.5);
end
(11-17-2016 04:54 PM)compsystems Wrote: [ -> ]1: I Remove some apparently unnecessary EXPORT
Yes, you are right, we don't need the EXPORT, I'll removed them later.

(11-17-2016 04:54 PM)compsystems Wrote: [ -> ]2: The local variables p,t,ar (if they are in lowercase) of the function entryMenu(p,t,ar) must be defined as local in the header (Why?)
I don't understand...
these variables are not lowercase, I defined them uppercase.
Code:
EXPORT entry(P,T,A)
BEGIN
 m(P):=T;
 a(P):=A;
END;
By the way, I see you rename function names, if you change API, it won't ease you to integrate updates.

(11-17-2016 04:54 PM)compsystems Wrote: [ -> ]3: The variable STAY is not working, when a subfunction f1() is called stay->0, why?
that's because you touch the 6th menu to end the msgbox (you press the "OK") then your finger is still on that menu and then it catch your exit...

That's an issue I've already seen : if you let your finger on the screen, functions are continuously called. I'm working on a fix for that.
edit : it's now fixed, see version 1.1 on first post.
Version 2.1 :

Changelog :
- added a new entry type : toggle button.
- can now display up to 10 menu entries (on two screens, automatically set "next"/"prev")

Added API :
- LibMenu.entrytoggle(pos,label) : add entry <pos> as a toggle button.
- LibMenu.gettoggle(pos) : return toggle status for entry number <pos>.

Download :
[attachment=4210]

Demonstration :



video
the program to test LibMenu used in the video :[attachment=4211]
Works very well

Ideas

1: Make the [menu] key hide or re-display the menu bar

2: to be able to add an icon to each menu, I think you should use the manipulation of graphics and no longer the function DRAWMENU

[Image: ABAAAAo_MAH-10.jpg]

[Image: 86257.gif]

Thanks
(11-28-2016 01:24 PM)compsystems Wrote: [ -> ]2: to be able to add an icon to each menu, I think you should use the manipulation of graphics and no longer the function DRAWMENU

hey,
I have a very good news for you... you can already use icon for menu entries (but not toggle ones)

Look at this example :
[Image: syv2v8.png]

DIMGROB_P(G5,60,22,#83E0h); // blue

DIMGROB_P(G6,60,22,#FC00h); //green
TRIANGLE_P(G6,0,4,40,0,50,18,#83E0h,#FF0000h,#D5AD35h);

LibMenu.entry(1,G5,"tstLibM.f1()"); // *** 1 ***
LibMenu.entry(2,G6,"tstLibM.f2()"); // *** 2 ***
Version 3 :

Changelog :
- added a new entry type : tab button.
- can now change toggle flag
- removed EXPORT from methods, you must prefix method with LibMenu.

Added API :
- LibMenu.deftab(pos1,pos2,active) : each entries are now tab entries. (from pos1 to pos2)
- LibMenu.chgflag(pos) : change toggle flag.

Tab usage example :
Code:
 LibMenu.entry(1,"tab1","tstLibM.f1()");    //   define action : f1()
 LibMenu.entry(2,"tab2","tstLibM.f2()");    //   define action : f2()
 LibMenu.deftab(1,2,1);  // entries 1 and 2 are tab, active tab is 1.
[attachment=4285]

download
[attachment=4286]
.
Idea: a function is required to determine the number of menus, currently works maximum with 12 =(

n:=#
entryMenus( n );

m:={"","","","","","","","","","","",""}; // => m:=MAKELIST("",X,1,n)
a:={"","","","","","","","","","","",""}; // => a:=MAKELIST("",X,1,n)
f:={0,0,0,0,0,0,0,0,0,0,0,0}; // => f:=MAKELIST(0,X,1,n)
Hello Primer,
thank you very much for porting the menus to the Prime. It works very well for me. I had an older version without the next/prev soft buttons...

Congrats also for the code which is very elegant.

Thanks

Giancarlo from Italy
Thanks for this library of menu related functions - arguably this should be built into the Prime!

A few questions and tips:
  1. Question: Just wondering what 'LibMenu.deftab' is for and why is it has 'tab' in its name? It seems to create a mutually exclusive set of 'toggle-like' menu buttons, which call functions. My only guess is that the user is expected to build a tabbed UI of some kind and the menu buttons are supposed to indicate which tab in the UI is active - is that right? Since there is no built in Prime tabbed UI - I'm wondering how often this kind of menu button system would get used - as not many users are likely to be building a custom tabbed UI from scratch? Or am I missing something?
  2. Tip: For some reason MSGBOX messages and INPUT forms are not cleared away after being invoked/displayed and completed - which is likely to confuse users. I recommend that these commands should be followed by a RECT() call to clear the screen.
  3. Tip: PRINT() has its issues as previously raised - viz. displaying the terminal ok but not allowing you to scroll, much less see text which has scrolled off the bottom of the terminal. Clearing the terminal first with PRINT() and limiting output to approx 12 lines is a workaround.
  4. Tip: I have had success with TERM the replacement terminal http://www.hpmuseum.org/forum/thread-2667.html, which displays output created by OUT() when you call SHOW() and unlike the built in terminal, lets you actually scroll through the resulting output, and then helpfully, allows you to hit ESC which takes you back to the Lib menu.
  5. Question: With not that many options for displaying results to users - presumably we should also be considering drawing graphic text to the screen?
  6. Tip: It would be nice to be able to exit the menu by pressing the ESC key - here is my technique to do so. Note I check for the ESC key in the main while loop. The 'stay' variable is set to false either by the ESC key or by the 'Exit' menu function.

Code:

local stay, key;

local AA, BB;

EXPORT funct1() BEGIN msgbox("f1"); msgbox("f1 again");  END; // define function that will be called on menu click.
EXPORT funct2() BEGIN INPUT({{A,1}, {B,1},{L0, [6]},{C,{"SI","US"}},{D,{"SIQ","USQ"}},{AA,[2]},{BB,[2]},{M0,[4]}},"Mega input form"); END;
EXPORT funct3() BEGIN rect(); END;
EXPORT funct4() BEGIN local i; for i from 0 to 10 do print("hi there " + i); end; END;
EXPORT funct5() BEGIN local i; for i from 0 to 10 do TERM.OUT("hi there " + i); end; SHOW(); END;

init() begin stay:=true; LibMenu.reset(); end;
exitMenu() begin stay:=false; end; 

EXPORT libmenu_test()
BEGIN
  init(); // resets menu and initialises exit flag
  LibMenu.entry(1,"msg1","funct1()");
  LibMenu.entry(2,"choose","funct2()");
  LibMenu.entry(3,"clear screen","funct3()");
  LibMenu.entry(4,"print","funct4()");
  LibMenu.entry(5,"out","funct5()");
  LibMenu.entry(6,"exit","libmenu_test.exitMenu()");

  LibMenu.draw();
  WHILE stay DO
     LibMenu.events();

    // check for esc
    key := getkey();
    if key = 4 then stay:=false; end;

  END;

  return "all done, thanks"; 
END;
An idea, inspired by the calculators casio, please make each menu, have three options one with the key [alpha] (left side), another with the key [shift] (center), and the third option (right side) from the menu.


[Image: 2043_1536750617_5b98f4194818b.png]

[Image: file.php?id=4089&amp;t=1]
Reference URL's