US Tray Menu 2: Implementation
US Tray Menu 2 : Introduction | Implementation | Language support | cmd problem | Defensive | Binaries
|
|
UniServer 5-Nano US Tray Menu 2. UniServer 6-Carbo |
US Tray Menu 2 Implementation
Introduction
This page covers implementing a predefined command.
It assumes no additional commands have been implemented hence first covers how to integrate these into the menu architecture.
Master array
On starting our tray menu data from the configuration file is used to build a master array. Before drawing the menu we want to update this master array using an initialisation function.
This is run from two specific locations:
- Just after the main window creation
- Inside main handler function. Called (run) for each redraw request
Lets call this function main_init() integration as shown below:
$mainwin = wb_create_window(NULL, NakedWindow, APPNAME, $win_x, $win_y, $win_width, $win_height, WBC_NOTIFY | WBC_TOP | WBC_TASKBAR , WBC_DBLCLICK | WBC_MOUSEDOWN | WBC_MOUSEUP | WBC_MOUSEMOVE | WBC_REDRAW); //== Update server status main_init(); // Update main array to match server status
Main handler function
if($lparam1 & WBC_REDRAW) { // A redraw required.(e.g. minimize to max) main_init() ; // Update main array to match server status mouse_over($window,$frame_1,'main_menu',$win_width, $win_height); // Yes: Call redraw function }
When a menu item is clicked tray menu is always minimised. Every time our tray menu is maximised function main_init is executed providing real time monitoring of server status.
Command master array mapping
Main initialisation function (main_init) uses the following master array command mappings.
$main[$i][1] | men1[] | item[] | = "Longest text" | |
$main[$i][2] | men2[] | action[] | = "cmd_xxxx" | |
$main[$i][3] | men3[] | file[] | = "Text 1" | |
$main[$i][4] | men4[] | parameter[] | = "Text 2" | |
$main[$i][5] | men5[] | icon[] | = "Optional Id" |
From our point of view only element we know about is men2[]; its one of our predefined commands. If a user has included this menu item in the configuration file it will appear in the master array.
We cannot take for granted a user is using all predefined commands hence the master array is always scanned for existence of predefined commands.
Note: Complete mater array elements see this page
Icons such as start and stop are a complementary pair. Another icon pair is available and unavailable this applies to several menu items.
Currently in the icon image strip there is no icon for Unavailable. I have added a new icon (id 22) this is a circle with a slash indicating Unavailable.
Similarly complementary pairs applies to text, for example "Admin Panel" and "Admin Panel (Unavailable)" text pairs are user definable and translatable into other languages.
Apanel Example
The above ideas are better explained with a simple example for this we will use the Apanel menu item.
Apanel command
This we have already defined (cmd_apanel – Run Apanel)
Configuration file
The configuration file entry needs to be changed from this:
item[] = "Admin Panel" action[] = "runh" file[] = "php.exe" parameter[] = " -n unitray_info.php 1" icon[] = "11"
To this:
men1[] = "Admin Panel (Unavailable)" men2[] = "cmd_apanel" men3[] = "Admin Panel" men4[] = "Admin Panel (Unavailable)" men5[] = ""
Note 1: At first it would appear men1[] is not required however it is used to determine maximum width of the menu or sub-menu. Hence set its value to the longest of the two strings.
Note 2: It is possible to run with above changes only. Our menu will not be broken a menu item is displayed with incorrect text (Admin Panel (Unavailable) and no icon.
Initialisation function
Initialisation function determines current server status and configures menu items accordingly.
Master array is scanned for a command (cmd_apanel) configured in the configuration file and perform appropriate task for example:
//=== MAIN INIT ================================================================ // Update main array to match server status function main_init() { global $main; // Master array for($i = 0; $i < count($main); $i++) { // Scan main array if($main[$i][2] == "cmd_apanel"){ // Target command print "Command found"; // Do something } } } //================================================================ MAIN INIT ===
Appropriate task in this example is to print.
What we really require is for the menu item to reflect its availability. It has two states these are dependent on the Apache server’s state which can be determine with function “apache_running()”
If Apache running:
|
|
Apache not running
|
The following code implements the above
//=== MAIN INIT ================================================================ // Update main array to match server status function main_init() { global $main; // Master array for($i = 0; $i < count($main); $i++) { // Scan main array //==Command cmd_apanel if($main[$i][2] == "cmd_apanel"){ // Target command if(apache_running()){ // Is Apache running $main[$i][1] = $main[$i][3]; // Set available text $main[$i][5] = "7"; // Set available icon } else{ // No: $main[$i][1] = $main[$i][4]; // Set uavailable text $main[$i][5] = "22"; // Set unavailable icon } } //== End command cmd_apanel } } //================================================================ MAIN INIT ===
Command processor function
When menu item is clicked command processor needs to intercept the command and decide what to do.
There are two states again dependent on Apache serve’s status. If running execute indicated command.
Apache not running and user clicks menu item inform user to start Apache server.
The above states gives this code:
// There are only two types of command to process run and runh (run hidden) //==Command cmd_apanel if($command_array[0] == "cmd_apanel"){ // Intercept command if(apache_running()){ // Is Apache running $cmd = "php.exe -n unitray_info.php 1" ; // Cmd to run hidden $cmd = relative_to_absolute_paths( $cmd); // convert $cmd1 = "\""; // Start quote $cmd2 = $cmd; // Full path and file name to run $cmd3 = "\" "; // Add final quote $cmd4 = $cmd1.$cmd2.$cmd3; // build command string wb_exec( "uniserv.exe", $cmd4); } else{ // No: $str = "To enable and run this menu item\n"; $str .= "please start Apache server."; wb_message_box (NULL, $str, "Unavailable"); } } //== End command cmd_apanel //== Convert paths
First line (statement incorrect) and last line are provided to show where the new code is placed. Additional code for new commands are placed sequentially.
Code structure is intentionally unchanged to reflect existing code currently in this function.
Note 1: Each command added requires similar code. To prevent duplication all identical code is encapsulated into a function.
Note 2: Although the above code is functional in final code it introduces an undesirable side effect, command window opens for a short period this is addressed later.
Test
If you have been following this verbatim run the menu with and without Apache running.
Click Apanel menu item expected results as above.
Summary
I have show how easy it is to transform our static menu to provide dynamic user feedback. Price paid is additional code, however it is well worth it just to prevent that dead application feel after clicking a menu item.
Applying the above techniques to all other applicable menu items enhances the menu.
An interesting dilemma is one of pop-up message boxes more precisely text displayed. This text is currently embedded within our scripts making life difficult for translators clearly an undesirable situation.
Next page covers Language support