Post Reply 
Code snippet: drawmenu with catching user action
02-24-2014, 06:26 PM (This post was last modified: 03-03-2014 10:09 PM by Stefan.)
Post: #1
Code snippet: drawmenu with catching user action
Here is a code snippet which someone might find useful. I adapted an earlier example of veeblefester, and made it a little bit shorter.
It can be used as a drop-in replacement for the drawmenu() function: The function takes as argument a list with the labels for the 6 softbuttons. It returns the ID of the button which was pressed.

Edit: Thanks to Han a better version is available in my post below. I removed the old code.
Find all posts by this user
Quote this message in a reply
03-01-2014, 05:04 AM
Post: #2
RE: Code snippet: drawmenu with catching user action
There is a brief example of how to capture ALL input types in the intro to programming article. You can easily adapt it to your case. Basically, it uses the WAIT(-1) command instead (which is better than doing a while loop).

Graph 3D | QPI | SolveSys
Find all posts by this user
Quote this message in a reply
03-03-2014, 10:08 PM
Post: #3
RE: Code snippet: drawmenu with catching user action
Thank you Han! That works much better and is even simpler now. Here is my reworked code:

Code:

EXPORT DrawMenuSelect(buttonlabellist)
// Parameters: menustringlist is a list which should contain at most 6 strings for the button labels
// Returns: The ID (1 to 6) of the button that was pressed
BEGIN
 LOCAL selection, mouselist;
 DRAWMENU(buttonlabellist);
 mouselist:=WAIT(-1); // Wait until screen is touched
 selection := -1; //preinitialize with -1 which is returned if none of the buttons is pressed
 // Check whether one of the on-screen buttons was pressed:
 IF (mouselist(1)==3 AND mouselist(3) >= #DD:-16h) THEN
  selection:=CEILING((mouselist(2)+1)*6/320); // Screen is 320px wide. There are six buttons. hence divide
// mouse value by 320/6. To avoid getting a value of zero when the user presses exactly at the left 
//border a 1 is added to the mouse value
 END;

 RETURN selection;
END;
Find all posts by this user
Quote this message in a reply
03-03-2014, 10:37 PM
Post: #4
RE: Code snippet: drawmenu with catching user action
What happens if the user presses a key instead of touching the screen?

TW

Although I work for the HP calculator group, the views and opinions I post here are my own.
Find all posts by this user
Quote this message in a reply
03-04-2014, 03:43 AM
Post: #5
RE: Code snippet: drawmenu with catching user action
(03-03-2014 10:37 PM)Tim Wessman Wrote:  What happens if the user presses a key instead of touching the screen?

As Tim pointed out, you do have to address this instance -- this is why I had to check the TYPE of the result from WAIT(-1). You must use TYPE(), and it must be done separately from the mouse event type check (i.e. don't use AND). Otherwise a keyboard event will generate an error.

Graph 3D | QPI | SolveSys
Find all posts by this user
Quote this message in a reply
03-04-2014, 04:52 AM (This post was last modified: 03-04-2014 04:52 AM by patrice.)
Post: #6
RE: Code snippet: drawmenu with catching user action
(03-03-2014 10:08 PM)Stefan Wrote:  
Code:
 // Check whether one of the on-screen buttons was pressed:
 IF (mouselist(1)==3 AND mouselist(3) >= #DD:-16h) THEN
You even have to split this test in 2.
Because you can be unlucky and get a "mouse up" event with no coordinate.

Patrice
“Everything should be made as simple as possible, but no simpler.” Albert Einstein
Find all posts by this user
Quote this message in a reply
03-04-2014, 03:36 PM
Post: #7
RE: Code snippet: drawmenu with catching user action
Thanks everyone for finding the mentioned error sources! Here is the reworked version.

Important note for everyone who has used the code before: I changed the return value for the case where no on-screen button was pressed to "0" instead of "-1", because of the following change:
Now the code also checks whether the button which was pressed is in the list of labels. If this is not the case the negative of the button ID is returned.

Example: DrawMenuSelect({"one", "two"})
If user presses button 4, returns "-4"
If user presses button 2, returns "2"
If user presses none of the on-screen buttons (e.g. by pressing the screen elsewhere, or typing the keyboard) returns "0"

Code:

EXPORT DrawMenuSelect(buttonlabellist)
// Parameters: buttonlabellist is a list which should contain at most 6 strings for the button labels
// Returns: 
//  * If one of the buttons in "buttonlabellist" was pressed returns the ID (1 to 6) of the button.
//  * If a button is pressed which is not labeled by "buttonlabellist" returns negative ID of the button (-6 to -1)
//  * If none of the on screen buttons was pressed returns 0
BEGIN
 LOCAL selection, mouselist;
 DRAWMENU(buttonlabellist);
 selection := 0; //preinitialize with 0 which is returned if none of the buttons is pressed
 mouselist:=WAIT(-1); // Wait until screen is touched
 // Check whether one of the on-screen buttons was pressed:
 IF (TYPE(mouselist)==6) THEN // Check whether we have a touch event (==list)
  IF (mouselist(1)==3) THEN // Check whether a button was pressed
   IF (mouselist(3) >= #DD:-16h) THEN // check whether it was one of the 6 buttons at the bottom
    selection:=CEILING((mouselist(2)+1)*6/320); // Screen is 320px wide. There are six buttons. hence divide
// mouse value by 320/6. To avoid getting a value of zero when the user presses exactly at the left 
//border a 1 is added to the mouse value
    IF (selection > length(buttonlabellist)) THEN // Check whether a valid button was pressed.
     selection := -selection;
    END;
   END;
  END;
 END;

 RETURN selection;
END;

@Han: You mention in your article that a mouse click actually causes three events. Can you explain this a bit more? If I use wait(-1) I only get one list as return value. Are there cases in which I could get a list of lists with more than 1 event? Or is this just an issue if I loop over WAIT(-1), where I would catch the same user action three times?
Find all posts by this user
Quote this message in a reply
03-04-2014, 04:02 PM (This post was last modified: 03-04-2014 04:03 PM by Han.)
Post: #8
RE: Code snippet: drawmenu with catching user action
(03-04-2014 03:36 PM)Stefan Wrote:  @Han: You mention in your article that a mouse click actually causes three events. Can you explain this a bit more? If I use wait(-1) I only get one list as return value.

Correct.

Quote:Are there cases in which I could get a list of lists with more than 1 event?

Not that I am aware of.

Quote:Or is this just an issue if I loop over WAIT(-1), where I would catch the same user action three times?

Correct. If you issue a loop over WAIT(-1), then you would catch the same user action three times (as a mouse down, mouse up, and a "click"). Since your handler only checks for the click event, the other two are simply ignored.

Graph 3D | QPI | SolveSys
Find all posts by this user
Quote this message in a reply
Post Reply 




User(s) browsing this thread: 1 Guest(s)