Wednesday, July 11, 2007

FFC : LinkButton (Managing State)

A little while ago I wrote a few posts relating to creating a simple HRule Fireworks Flex Component (FFC). I chose the HRule because it wasn't interactive and hence relatively simple to implement. But now I'd like to move on and do something a little bit more interactive and to tackle some of the issues involved. Looking around I settled on the LinkButton. LinkButtons display a label with no background in the normal state. On rollover the background is displayed and the label changes color. On mouseDown the backround color changes and the label color could change (the default is that the rollover and selected label colors are the same).

Looking at the Button component from the Flex Components you'll notice a State property with three options ; Up, Over and Down. In the Button FFC changing the textRolloverColor and then selecting the Over state you'll see the FFC update to display the new textRolloverColor. This State property allows us to preview the style changes that relate to different states of an interactive component. Adding this State property to the setDefaultValues function is our first job when creating an interactive component. It looks like this :

values.push({ name:"State",type:"ComboBox", value:"Up,Up,Over,Down" });

Within applyCurrentValues we'll need to get the current selection of this property:

var state   = values[0].value.split(",")[0];

Then use the value of state to decide what values to apply. Before doing that lets take a look at the structure of LinkButton.graphic.png. Like the HRule it's very simple. There is a text field named 'label' and a rectangle named 'bg'. For each of the selected states we'll need to update the color of 'label' and the color and visibility of 'bg'. To do this we need to define 5 properties within setDefaultValues ;

values.push({ name:"color", type:"color", value:"#0B333C" });
values.push({ name:"textRollOverColor", type:"color", value:"#2B333C" });
values.push({ name:"textSelectedColor", type:"color", value:"#2B333C" });
values.push({ name:"rollOverColor", type:"color", value:"#AADEFF" });
values.push({ name:"selectionColor", type:"color", value:"#7FCDFE" });

Here's the code from applyCurrentValues that uses the current state to set these values;

var state   = values[0].value.split(",")[0];

var label_obj = Widget.GetObjectByName("label");
var bg_obj = Widget.GetObjectByName("bg");

switch (state)
{
case "Up" :
label_obj.pathAttributes.fillColor = values[2].value;
bg_obj.visible = false;
break;
case "Over":
label_obj.pathAttributes.fillColor = values[3].value;
bg_obj.pathAttributes.fillColor = values[5].value;
bg_obj.visible = true;
break;
case "Down":
label_obj.pathAttributes.fillColor = values[4].value;
bg_obj.pathAttributes.fillColor = values[6].value;
bg_obj.visible = true;
break;
}

As you probably spotted the tricky bit is getting the value of state. But this line is copied straight out of the Button component so the only credit I get is for being smart enough to look at those components. The rest is a matter of changing the fillColor for the 'label' and 'bg' to the relevant colors and setting the visible property of 'bg'. Set visible to false for the 'Up' state and true for the others.

There are a few other relevant properties/styles we can easily change. The simplest properties are the label property (controls the text visible on the LinkButton), font and fontSize :

//setDefaultValues after state
values.push({ name:"label",type:"Text",value:"Button"});
//setDefaultValues after selectionColor
values.push({ name:"fontFamily", type:"font", value:"Verdana" });
values.push({ name:"fontSize", type:"Text", value:"11" });

//applyCurrentValues after state switch statement
label_obj.textChars = values[1].value;
label_obj.font = values[7].value;
label_obj.fontsize = Number(values[8].value);

All this works nicely within Fireworks but there is a problem that you may have spotted. When we export to MXML Flex Builder will display an error because 'state' is not a valid attribute for the LinkButton (all Fireworks properties are added as attributes). For now we can simply remove the state attribute. But to fix the export we need to talk about "flexClassDefinition". Let's save that till the next post. In the meantime you can look ahead by downloading the source files.

No comments: