Adobe Catalyst Beta is out and although it allows manipulating and creating some great skins, programmers are not off the hook just yet. Sometimes you need that extra knowledge on how to skin Spark component to get your component to look and behave exactly as you need. In this tutorial I will show you how to skin the ButtonBar component so it has a label text and an icon.
Solution
Implementation, which includes the ButtonBar tag pointing to our VerticalButtonBarSkin skin and a click event once the user selected an item. Notice that we define the data we will be passing to the skin, which includes the label text and the icon we will be using to create the button bar image icon.
Detailed explanation
Adobe Catalyst Beta is out and although it allows manipulating
and creating some great skins, programmers are not off the hook
just yet. Sometimes you need that extra knowledge on how to skin
Spark component to get your component to look and behave exactly as
you need. In this tutorial I will show you how to skin the
ButtonBar component so it has a label text and an icon. The final
results will look and behave as shown in the figure below:
Note you click the application and right click to
view the source code.
Create VerticalButtonBarSkin skin
First create a skin for the ButtonBar and call it
VerticalButtonBarSkin.mxml. VerticalButtonBarSkin includes the
states:
<s:states>
<s:State name=
"normal" />
<s:State name=
"disabled" />
</s:states>
Each Flex 4 Beta holds an instance to the HostComponent metadata
so the component can identify the skin you are creating.
[HostComponent("spark.components.ButtonBar")]
[HostComponent("spark.components.ButtonBar")]
The skin also includes a declaration tag and you can include the
button skin. In our case the button skin will hold the label and
icon image as well as code to handle the different states.
Lastly, we would need to draw a rectangle around the component
so I decided to that here. Notice that I am getting a reference to
the hostComponent component, so we can set the color of the button
bar component from the implementation. Also notice that we have the
data group to hold the data we will be passing to the button
skin.
Next step is to create the following skin:
components/IconButtonSkin.mxml. The IconButtonSkin skin will hold
the label a rectangle to be placed on the selected item and an
icon. I am overridden the updateDisplayList method and picking up
the data that will be set in the implementation in order to set the
icon image and the label text name. Additionally, I am setting the
width of the button to fit the 100% size of the host component so
once the user re-size the component the buttons will get re-sized
automatically.
<fx:Script>
<![CDATA[
override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void
{
super.updateDisplayList((this.hostComponent as Object).outerDocument.hostComponent.width, unscaledHeight);
var image:Class = Class((this as Object).hostComponent.data.imageIcon);
var label:String = (this as Object).hostComponent.data.label;
labelElement.text = label;
icon.source = image;
this.width = this.hostComponent.width;
this.minWidth = this.hostComponent.width;
}
]]>
</fx:Script>
<fx:Script>
<![CDATA[
override protected function
updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void
{
super.updateDisplayList((this.hostComponent
as Object).outerDocument.hostComponent.width, unscaledHeight);
var image:Class = Class((this as
Object).hostComponent.data.imageIcon);
var label:String = (this as
Object).hostComponent.data.label;
labelElement.text = label;
icon.source = image;
this.width = this.hostComponent.width;
this.minWidth = this.hostComponent.width;
}
]]>
</fx:Script>
We also need to set the states we will be using. In our case we
will be using some more advanced states other than the traditional:
up, down and over states, since we need to customize the component
to fit our exact need.
The code below create the square we will be drawing using the
FP10 drawing API utilizing the FXG code. GradientEntry sets the
color to match our button bar component and include the color
gradient once we select and item.
Now that we created all the skins all we have to do is to
implement. Take a look at the implementation below which includes
the ButtonBar tag pointing to our VerticalButtonBarSkin skin and a
click event once the user selected an item. Notice that we define
the data we will be passing to the skin, which includes the label
text and the icon we will be using to create the button bar image
icon.
The event handler for the user click event is listed below. It
take the selectedIndex property from the component and uses the
data provider to find the item.
protected function buttonClickHandler(event:MouseEvent):void
{
var index:int = event.currentTarget.selectedIndex;
var item:Object = (event.currentTarget.dataProvider as ArrayCollection).getItemAt(index);
trace(item.label+
" label was clicked");
}
protected function buttonClickHandler(event:MouseEvent):void
{
var index:int = event.currentTarget.selectedIndex;
var item:Object = (event.currentTarget.dataProvider as
ArrayCollection).getItemAt(index);
trace(item.label+" label was clicked");
}