Ui_Popup_Menu Command

by Jim Chapman

Whether from a menu bar, icon bar, button, or hot spot, the ui_popup_menu() function can be used to display a multi-level drop down menu. The ui_popup_menu() function is an easy and flexible method to create your own menus with all the richness of a professional looking menu with icon and conditional capabilities. Alpha's ui_popup_menu() function will, by default, drop down the menu where ever the mouse cursor is, at the time the command is fired. So putting the ui_popup_menu() command on a button's onPush event will position the menu at the button. To begin exploring the ui_popup_menu() command, put the following code on the onPush event of a button placed on a form:

vMenuItems = <<%a%
Choice One
Choice Two
Choice Three
%a%

ui_popup_menu(vMenuItems)
The variable, vMenuItems, is a crlf() delimited string that contains the menu choices displayed by the ui_popup_menu() command.
The above code produces the following drop down menu:



We have to respond to the user's selection and the above code does not do this. We can respond to the user's selection either inside or outside the ui_popup_menu() command. The following syntax demonstrates handling the users selection within ui_popup_menu() command:
ui_popup_menu(vMenuItems,<<%code%
if a_command = "Choice One"
	ui_msg_box("The User Selected:",a_command)
	else
	ui_msg_box("Choice One NOT Selected!","The user did not select Choice One")
end if 
%code%)
The "a_command" variable is internal to Alpha Five and holds the user's selection, so checking the value of a_command will reveal the selection, and allow us to process it. For menus with many choices, I prefer to process the user's selection outside of the ui_popup_menu() command. It really makes no difference, but in my mind it makes the code slightly more readable. The "a_command" variable is not available outside of the ui_popup_menu() command, so we have to create a new variable, in this tutorial I call it; vPopupReturn, to assign the return value of the ui_popup_menu() command to. The following code will handle the users selection outside of the ui_popup_menu() command:

vPopupReturn = ui_popup_menu(vMenuItems)

if vPopupReturn = "Choice One"
	ui_msg_box("The User Selected:",vPopupReturn)
	else
	ui_msg_box("Choice One NOT Selected!","The user did not select Choice One")
end if
Now I want to show how to easily create better looking cascading drop down menus. Assume I want two sub-selections to be available to the user if they select 'Choice One'. The following code does this:
vMenuItems = <<%a%
Choice One | sub-selection One
Choice One | sub-selection Two
Choice Two
Choice Three
%a%

vPopupReturn = ui_popup_menu(vMenuItems)
This code displays the following menu:



And this if the user selects Choice One:



The pipe symbol, "|" on the keyboard (above the backslash), defines the break between the first and second level menu items. You can continue to create lower level cascading menu selections as the following demonstrates:
vMenuItems = <<%a%
Choice One | sub-selection One
Choice One | sub-selection Two | third level selection one
Choice One | sub-selection Two | third level selection two
Choice Two
Choice Three
%a%

vPopupReturn = ui_popup_menu(vMenuItems)
This code creates:



If I want to separate Choice One from the other two choices, I can use the {sp} command as in the following:
vMenuItems = <<%a%
Choice One | sub-selection One
Choice One | sub-selection Two | third level selection one
Choice One | sub-selection Two | third level selection two
{sp}
Choice Two
Choice Three
%a%

vPopupReturn = ui_popup_menu(vMenuItems)
Produces the following:



I can further separate off Choice One by creating a line in the menu using the '-' command as in the following:
vMenuItems = <<%a%
Choice One | sub-selection One
Choice One | sub-selection Two | third level selection one
Choice One | sub-selection Two | third level selection two
{sp}
-
Choice Two
Choice Three
%a%

vPopupReturn = ui_popup_menu(vMenuItems)
Which displays the following:



To put a line separating the two choices at the third level I use the following code:
vMenuItems = <<%a%
Choice One | sub-selection One
Choice One | sub-selection Two | third level selection one
Choice One | sub-selection Two | -
Choice One | sub-selection Two | third level selection two
{sp}
-
Choice Two
Choice Three
%a%

vPopupReturn = ui_popup_menu(vMenuItems)
Produces this:



The ui_popup_menu() command automatically expands horizontally to accommodate the length of the menu, but if you want to force a larger horizontal size, you can use the {tab} command as in:
vMenuItems = <<%a%
Choice One | sub-selection One 
Choice One | sub-selection Two | third level selection one
Choice One | sub-selection Two | -
Choice One | sub-selection Two | third level selection two
{sp}
-
Choice Two {tab}
Choice Three
%a%

vPopupReturn = ui_popup_menu(vMenuItems)
Displays this:



To really pretty up your menus, consider putting icons on some or all of your menu items. Alpha Five contains a rich selection of icons built into the program that are available for your use. To see the internal icons, type the following command in the interactive code window:
A5_promopt_for_imagename()
And pressing the enter key displays the following:



As you can see, I have selected the hammer icon, and its name, "$a5_hammer" is displayed in the dialog. Using the command; {I=$a5_hammer}, before each line of "Choice One", as in:
vMenuItems = <<%a%
{I=$a5_hammer}Choice One | sub-selection One 
{I=$a5_hammer}Choice One | sub-selection Two | third level selection one
{I=$a5_hammer}Choice One | sub-selection Two | -
{I=$a5_hammer}Choice One | sub-selection Two | third level selection two
{sp}
-
Choice Two {tab}
Choice Three
%a%

vPopupReturn = ui_popup_menu(vMenuItems)
Displays the following:



Because I have several levels of sub-menu's associated with 'Choice One', I need to have the icon command in each line of choice one. I am also partial to the stop sign icon named; $a5_halt. The following code puts this icon on the last selection in the third level menu:
vMenuItems = <<%a%
{I=$a5_hammer}Choice One | sub-selection One 
{I=$a5_hammer}Choice One | sub-selection Two | third level selection one
{I=$a5_hammer}Choice One | sub-selection Two | -
{I=$a5_hammer}Choice One | sub-selection Two | {I=$a5_halt}third level selection two
{sp}
-
Choice Two {tab}
Choice Three
%a%

vPopupReturn = ui_popup_menu(vMenuItems)
Displaying:



Let me point out that these commands to add icons, and other commands such as {tab}, effect the return value of the ui_popup_menu() command. In the preceding code, if the user selects 'third level selection two', the a_command or the vPopupReturn variables would contain the following value:

{I=$a5_halt}third level selection two

Although this is not a problem, if you prefer a more explicit return value, you can specifically define the return value of a selection by using the {data=} command. Assume I want a value of "Shut Down" returned if the user selects the 'third level selection two' choice. Using the command, {data=Shut Down}, in the following code does this:
vMenuItems = <<%a%
{I=$a5_hammer}Choice One | sub-selection One 
{I=$a5_hammer}Choice One | sub-selection Two | third level selection one
{I=$a5_hammer}Choice One | sub-selection Two | -
{I=$a5_hammer}Choice One | sub-selection Two |{DATA=Shut Down}{I=$a5_halt}third level selection two
{sp}
-
Choice Two {tab}
Choice Three
%a%

vPopupReturn = ui_popup_menu(vMenuItems)
Be sure not to proceed the {DATA=} command with a space, or it will not work.

To add that final touch to your menus, you can conditionally enable or disable any of the menu choices with the {enable=} command. I will create a simple logical variable named vFlag to demonstrate this. In the following code I will set the vFlag variable to a false (.f.) value and put the command; {enable=vFlag}, immediately in front of "Choice Two":
vMenuItems = <<%a%
{I=$a5_hammer}Choice One | sub-selection One 
{I=$a5_hammer}Choice One | sub-selection Two | third level selection one
{I=$a5_hammer}Choice One | sub-selection Two | -
{I=$a5_hammer}Choice One | sub-selection Two |{DATA=Shut Down}{I=$a5_halt}third level selection two
{sp}
-
{enable=vFlag}Choice Two {tab}
Choice Three
%a%

vPopupReturn = ui_popup_menu(vMenuItems)
This code displays the following:



As you can see, "Choice Two" is now disabled and grayed out. Setting the vFlag variable to a true value (.t.) enables "Choice Two".

One last command I want to point out is the {position} command. Although by default, Alpha Five brings up your menu where ever the cursor is located, using the {position=x,y} command ,(where x is the horizontal axis and y the vertical axis in inches), you can determine where the menu is displayed. You can also use the constant, "mouse", to use the current mouse position to replace either the x or y axis. The command; {position=3,4} as in the following code positions the menu 3 inches from the left side of the screen and 4 inches down from the top:
vMenuItems = <<%a%
{position=3,4}
{I=$a5_hammer}Choice One | sub-selection One
……….
I hope from this short tutorial you find the ui_popup_menu() command to be an easy and fast way to create rich multi-level dropdown menus. It is a testament to Alpha Five's maturity that much of Alpha Five is built using Alpha Five. And of course it is great that Alpha Software has chosen to expose much of this capability to the end user so we also can create not only powerful database applications, but also provide a rich and professional user interface.