PHP WinBinder 4: Rollover
PHP WinBinder 4 : Introduction | Rollover | Icons | Size and position | Configuration file | Command Processing | Coding | Final Tray Menu
|
|
UniServer 5-Nano PHP WinBinder 4 - Tray Menu. |
WinBinder Part 4 - Rollover effect
Introduction
Depending on the application creating a rollover effect with WinBinder is straightforward. We require this effect for our tray pop-up menu hence is explained in detail.
Type of window to use
First decision to make is the type of window to use. For a tray menu the NakedWindow is most suitable. This is a fixed-size application window with no border and no title bar. You can add standard windows components as required; our rollover example uses two buttons Minimize and Exit these are included for testing.
Menu items - draw text directly
Menu items can be displayed using labels however changing a label’s background and foreground colours is difficult. An alternative is to draw text directly to the window this gives us finer control and the ability to dynamically change both background and foreground colours.
Note: Drawing over a complete window would obscure our two test buttons. Examples avoid this by drawing in a space directly above them. Our final menu does not use any buttons hence the whole window is drawn over.
Starting point
Example 1
This tutorial includes working examples; rollover_1.phpw is a basic window that displays some text. Note the line that creates a window, it includes WBC_NOTIFY and parameter WBC_REDRAW. When a redraw is required this parameter is passed to the handler function. The following lines check parameter passed if a redraw is requested runs the function draw_on_window if($lparam1 & WBC_REDRAW) { // A redraw required.(e.g. minimize to max) draw_on_window($window); // Yes: Call redraw function } When a window is minimised and restored it generates a redraw request. To see this in action comment out the line
Run the script, minimize and restore the application. The redraw function is not executed hence a naked window is displayed. The draw_on_window function is called during initial windows creation process (just after the buttons are created) and then as required by the system. Note 1: the font to use is defined at the top of the script, of importance are colour setting and font height. Font height is defined in points and NOT pixels this becomes an issue when building a list of menu items this will be resolved later. Note 2: "Tahoma" is the system default font if you wish choose a different one.
|
|
---|
Script - rollover_1.phpw
<?php include "winbinder.php"; //=== Constants define("APPNAME", "WinBinder Borderless Window"); // Title displayed in taskbar $win_width = 300; $win_height = 200; $win_height2 = 140; // This would be full window height $win_x = 200; $win_y = 200; //== Font to use for drawing $font_text = wb_create_font("Tahoma", 8, BLACK, 0); // Create main window $mainwin = wb_create_window(NULL, NakedWindow, APPNAME, WBC_CENTER, WBC_CENTER, $win_width, $win_height, WBC_NOTIFY , WBC_REDRAW); // Add controls wb_create_control($mainwin, PushButton, "Exit", 10,160, 90, 25, IDCLOSE); wb_create_control($mainwin, PushButton, "Minimize", 200,160, 90, 25, WBC_MINIMIZED); draw_on_window($mainwin); // Draw additional features // Assign handler wb_set_handler($mainwin, "process_main"); // Start main loop wb_main_loop(); //=== Handler function ======================================================== /* Process main window commands */ function process_main($window, $id, $ctrl, $lparam1=0, $lparam2=0){ switch($id) { case IDDEFAULT: if($lparam1 & WBC_REDRAW) { // A redraw required.(e.g. minimize to max) draw_on_window($window); // Yes: Call redraw function } break; case WBC_MINIMIZED: // Minimise button clicked wb_set_size($window, WBC_MINIMIZED); // Minimize window break; case IDCLOSE: // Exit button clicked wb_destroy_window($window); // Destry window wb_destroy_font(); // Destroy all fonts break; } } //=== END Handler function ==================================================== //=== Draw on window ========================================================== function draw_on_window($win){ global $win_width; global $win_height2; global $font_text; // Draw rectangles wb_draw_rect($win, 0, 0, $win_width, $win_height2, WHITE); // White canvas wb_draw_rect($win, 0, 0, $win_width, $win_height2, BLACK,FALSE,5 ); // Border around window // Draw some text wb_draw_text($win, "Basic building block 基本构建块 and Unicode.", 25, 20, 0, 0, $font_text); wb_draw_text($win, "Basic building block 基本构建块 and Unicode.", 25, 50, 0, 0, $font_text); } //=== END Draw on window ====================================================== ?> |
Add text background and foreground colour
Example 2
We have a basic building block now let’s add text background and foreground colour. At beginning of the script we defined the following text and background colours: //== Font to use for drawing $font_text_black = wb_create_font("Tahoma", 8, BLACK, 0); $font_text_white = wb_create_font("Tahoma", 8, WHITE, 0); //== Background colour $back_black = BLACK; $back_white = WHITE; |
|
---|
The redraw section has been modified to the following:
function draw_on_window($win){ global $win_width; global $win_height2; global $font_text_black; global $font_text_white; global $back_black; global $back_white; // Draw rectangles wb_draw_rect($win, 0, 0, $win_width, $win_height2, GREEN); // Green canvas wb_draw_rect($win, 0, 0, $win_width, $win_height2, BLACK,FALSE,5 ); // Border around window // Draw backgrounds wb_draw_rect($win, 10, 15, 280, 30, $back_white); // Text Background wb_draw_rect($win, 10, 50, 280, 30, $back_black); // Text Background // Draw some text wb_draw_text($win, "Basic building block 基本构建块 and Unicode.", 25, 20, 0, 0, $font_text_black); wb_draw_text($win, "Basic building block 基本构建块 and Unicode.", 25, 55, 0, 0, $font_text_white);
Note: background rectangles are drawn before text otherwise the text will be obscured.
Run test script (double click on rolloever_2.bat) it almost looks like a menu!
Adding mouse support
Example 3
With the basic structure in place we need to add mouse support. This is achieved by specifying notification of mouse events in the window creation function. We require mouse down and move. The create function parameters are 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); The handler will now receives mouse events. Mouse x and y coordinates are obtained using the following lines: $x = $lparam2 & 0xFFFF; // Get mouse co-ords $y = ($lparam2 & 0xFFFF0000) >> 16; // Get mouse co-ords print "\nMouse $x $y\n"; // For test only Add above to the handler function jest below redrawn section. Run example 3. Mouse over window note mouse coordinates displayed in the command window. |
|
Add rollover effect
Example 4
Now we are ready to add the rollover effect. First we need to pass the x and y coordinates to the redraw function (see last line).
$x = $lparam2 & 0xFFFF; // Get mouse co-ords $y = ($lparam2 & 0xFFFF0000) >> 16; // Get mouse co-ords draw_on_window($window,$x,$y); // Run mouse over
We are parsing extra parameters to the “draw_on_window” function hence the function definition requires modification as follows:
function draw_on_window($win,$x=0,$y=0){
Note: The “=0” is added to both x and y, required because the function accepts one or three parameters.
Now we can target each rollover area and change background and foreground accordingly. Fore example:
// Create rollover for text 1 if( ($x >= 5) && ($x <= 280) && ($y >= 15) && ($y <= 40) ){ wb_draw_rect($win, 10, 15, 280, 30, $back_black); // Text Background wb_draw_text($win, "Basic building block 基本构建块 and Unicode.", 25, 20, 0, 0, $font_text_white); } else{ wb_draw_rect($win, 10, 15, 280, 30, $back_white); // Text Background wb_draw_text($win, "Basic building block 基本构建块 and Unicode.", 25, 20, 0, 0, $font_text_black); }
If mouse is within the defined area draw that colour else draw the inverse.
Redraw flicker problem
Run example 4 (double click on rollover_4.bat) and mouse over the text areas.
The mouse over effect works perfectly shame about the flickering artefacts.
Flickering explained
As the mouse moves each pixel movement forces a new window redrawn. Redraws occur in rapid succession and is processor intensive. For each active process a system allocates time slots and cycles through these giving each process a slice of processor time. This prevents the system stalling however switching can occur partway through a window redraw. Other application time slots are processed; on retuning to complete a redraw a significant amount of time has elapsed it’s this gap that produces flickering.
How to avoid redraw flicker
Example 5
Although flickering cannot be prevented there is a trick and that is to hide it from a user! Solution is to perform all redrawing in the background, on completion make that result visible. Switching is extremely fast hence no flicker.
The above is a general technique it can be applied in other situations where a noticeable flicker is present. |
|
Example 5 includes the following modification:
Under controls add a frame to place the image:
//== Add image frame $frame = wb_create_control($mainwin, Frame, "", 0, 0, $win_width, $win_height2, 101, WBC_IMAGE);
Modify “draw_on_window” function as follows:
Under “global” add the following lines:
global $frame; print "\nmmm$x $y\n"; // For test only //== Create an image $bmp = wb_create_image($win_width, $win_height2);
Change functions “wb_draw_rect” and “wb_draw_text” replace $win with $bmp each function now draws to the image.
Finally add the following to end of function:
wb_set_image($frame, $bmp); // Swith image to label wb_destroy_image($bmp); // Delete image
Run example 5 I think you will agree the result is dramatic.
Note: Additional information What is an image resource?
Complete rollover test script (Template)
rollover_5.phpw
<?php /* ############################################################################### # Name: rollover_5.phpw # Developed By: The Uniform Server Development Team # Modified Last By: Mike Gleaves (Ric) # Web: http://www.uniformserver.com # V1.0 2-5-2009 # Comment: WinBinder tutorial (Part 4) ############################################################################### */ include "winbinder.php"; //=== Constants define("APPNAME", "WinBinder Borderless Window"); // Title displayed in taskbar $win_width = 300; $win_height = 200; $win_height2 = 140; // This would be full window height $win_x = 200; $win_y = 200; //== Font to use for drawing $font_text_black = wb_create_font("Tahoma", 8, BLACK, 0); $font_text_white = wb_create_font("Tahoma", 8, WHITE, 0); //== Background colour $back_black = BLACK; $back_white = WHITE; // Create main window $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); // Add controls wb_create_control($mainwin, PushButton, "Exit", 10,160, 90, 25, IDCLOSE); wb_create_control($mainwin, PushButton, "Minimize", 200,160, 90, 25, WBC_MINIMIZED); //== Add image frame $frame = wb_create_control($mainwin, Frame, "", 0, 0, $win_width, $win_height2, 101, WBC_IMAGE); draw_on_window($mainwin); // Draw additional features // Assign handler wb_set_handler($mainwin, "process_main"); // Start main loop wb_main_loop(); //=== Handler function ======================================================== /* Process main window commands */ function process_main($window, $id, $ctrl, $lparam1=0, $lparam2=0){ switch($id) { case IDDEFAULT: if($lparam1 & WBC_REDRAW) { // A redraw required.(e.g. minimize to max) draw_on_window($window); // Yes: Call redraw function } $x = $lparam2 & 0xFFFF; // Get mouse co-ords $y = ($lparam2 & 0xFFFF0000) >> 16; // Get mouse co-ords draw_on_window($window,$x,$y); // Run mouse over break; case WBC_MINIMIZED: // Minimise button clicked wb_set_size($window, WBC_MINIMIZED); // Minimize window break; case IDCLOSE: // Exit button clicked wb_destroy_window($window); // Destry window wb_destroy_font(); // Destroy all fonts break; } } //=== END Handler function ==================================================== //=== Draw on window ========================================================== function draw_on_window($win,$x=0,$y=0){ global $win_width; global $win_height2; global $font_text_black; global $font_text_white; global $back_black; global $back_white; global $frame; print "\nmmm$x $y\n"; // For test only //== Create an image $bmp = wb_create_image($win_width, $win_height2); // Draw rectangles wb_draw_rect($bmp, 0, 0, $win_width, $win_height2, GREEN); // Green canvas wb_draw_rect($bmp, 0, 0, $win_width, $win_height2, BLACK,FALSE,5 ); // Border around window // Create rollover for text 1 if( ($x >= 5) && ($x <= 280) && ($y >= 15) && ($y <= 40) ){ wb_draw_rect($bmp, 10, 15, 280, 30, $back_black); // Text Background wb_draw_text($bmp, "Basic building block 基本构建块 and Unicode.", 25, 20, 0, 0, $font_text_white); } else{ wb_draw_rect($bmp, 10, 15, 280, 30, $back_white); // Text Background wb_draw_text($bmp, "Basic building block 基本构建块 and Unicode.", 25, 20, 0, 0, $font_text_black); } // Create rollover for text2 if( ($x >= 5) && ($x <= 280) && ($y >= 50) && ($y <= 80) ){ wb_draw_rect($bmp, 10, 50, 280, 30, $back_black); // Text Background wb_draw_text($bmp, "Basic building block 基本构建块 and Unicode.", 25, 55, 0, 0, $font_text_white); } else{ wb_draw_rect($bmp, 10, 50, 280, 30, $back_white); // Text Background wb_draw_text($bmp, "Basic building block 基本构建块 and Unicode.", 25, 55, 0, 0, $font_text_black); } wb_set_image($frame, $bmp); // Swith image to label wb_destroy_image($bmp); // Delete image } //=== END Draw on window ====================================================== ?> |
Summary
The above rollover effect is general purpose and can be applied to text and images.
What may not be obvious is the significance of function draw_on_window.
The rollover effect is purely cosmetic and secondary to the prime function of selecting a menu item. Knowing which menu item is selected allows us to extract its corresponding data from a master array and return it. The function is a major component in our final tray menu.
More cosmetics (Icons) are covered on the next page extracting a single image from an image strip.