« [Business] Selling professional services intangibles: Four steps that really work | Main | [Best Practices] Relationships »

December 27, 2006

[Tip] Manipulating the z-axis

by David Workman
Data Mosaic

A question came up at Servoy World 2006's Q & A session—is it possible to control the z-axis of objects at runtime? In design mode you can set objects to the front or to the back allowing you to overlap objects as many layers deep as you would like. Currently there is no function to directly set the layer level (z-axis) of an object at runtime and the answer at Servoy World was that it was not likely going to happen anytime soon.

Why would you want this ability anyway? Well, what happens when a button is clicked at runtime is that the clicked button object is brought to the top most position of the z-axis stack of objects. If you designed your layout to have an object on top of or overlapping the clicked button, your layout design is now messed up when button is clicked. Another example would be if you want to rearrange the overlapping of objects based on a particular user interaction with your interface.

If you are not quite following yet, let's assume for a moment that controlling the z-axis of an object would allow for greater possibilities in user interface design. Maybe not a very high priority for the Servoy engineers to give us a direct function but as it turns out—we don't particularly need them to!

The fact is that you can reset the relative z-axis position of an object at runtime by hiding and then showing the object. The order in which you do this for a series of objects will set the z-axis position of these objects in relation to each other. So you can't directly set the absolute position of an object on the z-axis stack but you can sequentially hide and show a series of objects to reset their relative z-axis positions to each other.

Here is the code for the overlapping buttons you see above. This example is very basic and just shows how it works. Note that the function "application.updateUI()" is key to "saving" the new z-axis positions before the clicked object is brought back to the top:

var btnClicked = application.getMethodTriggerElementName()

//1. process unclicked buttons

for ( i = 1; i <= 5 ; i++ ) {

    if (("btn_" + i) != btnClicked ) {
    
        //set z-order
        elements["btn_" + i].visible = false
        elements["btn_" + i].visible = true
        
        //set font
        elements["btn_" + i].setFont('Verdana,0,10')
    }
}

//2. process clicked button

//set font
elements[btnClicked].setFont('Verdana,1,10')


//set z-order
application.updateUI()
elements[btnClicked].visible = true

We actually manipulate the z-axis in real life solutions similar to the following practical example. In this case we like to have rounded edge tabs to control a tab panel. We designed it such that the bottom edge of a rounded tab is covered by another border object so that the tabs look like they are attached to the tab panel. To retain this look, we have to bring the border object back to the top every time a tab is clicked or else the bottom edge of the tab will stick out above the border when it is clicked. Here is the code for this example:

//set formname
var formName = application.getMethodTriggerFormName();

//set the tab panel name
var tabPanelName = 'tabs_70';

//get button that called
var btn_name = application.getMethodTriggerElementName();

//set prefix for element
var prefix = 'tab_m';

//get number of tabs
var tab_num = forms[formName].elements[tabPanelName].getMaxTabIndex();

//layer control
forms[formName].elements.border.visible = false

//activate correct tab and flip tab buttons
for ( var i = 1 ; i <= tab_num ; i++ )
{    
    var tab_name = prefix + i;
    var tab_index = 'label_' + i;
    
    if (btn_name == tab_name)
    {
        forms[formName].elements[tab_index].bgcolor = '#727b8c';
        forms[formName].elements[tab_index].fgcolor = '#727b8c';
        forms[formName].elements[tab_name].setFont('Verdana,1,10');
        forms[formName].elements[tab_name].fgcolor = '#212121';
                
        //set tab index
        forms[formName].elements[tabPanelName].tabIndex = i;    
    }
    else
    {
        forms[formName].elements[tab_index].bgcolor = '#323a4b';
        forms[formName].elements[tab_index].fgcolor = '#323a4b';
        forms[formName].elements[tab_name].setFont('Verdana,0,10');
        forms[formName].elements[tab_name].fgcolor = '#ffffff';
    }                
}

//z-axis control
forms[formName].elements.border.visible = true

I've put together a demo solution showing all this in action. Download here (v3.1R2):

Picture_7_5

| Posted by David Workman on December 27, 2006 at 02:50 PM in Tips | Permalink

Comments

Thanks! I especially like the example with the tabbed panel... I think this is a stayer for me =)

Posted by: Eric | Dec 27, 2006 5:37:19 PM

Great example David! It only doesn't work with transparant buttons...

Posted by: Karel Broer | Jan 10, 2007 5:15:43 AM

Post a comment