Joel Carras
Flexactly Right!
Friday December 12, 2008
Flex 4 - Skinning Gumbo
The new Flex 4 Gumbo skinning capabilities allow developers to directly tap into all visual elements of a component using a single skin. Gumbo components can now handle layout and interaction design using a more systematic lifecycle with the FxComponent base class. Additionally, the FXG language allows developers to directly access all visual aspects of the Flash player. Gumbo skins can be created in tools such as Adobe Flash Catalyst, Adobe Illustrator, or Adobe Fireworks and exported into a Flex project.
Currently, Gumbo Fx components in the Flex SDK 4 are only for a subset of the visual components available in the Flex 3 SDK, such as FxButton, FxText, FxList ect… Gumbo components consist of a Model, View, Controller, and Skin. The model contains properties of each component that are not related to visual aspects. For example, “editable” for a text input component or “selectable” for a text component. The controller is where the states, event handlers, and “skin parts” of the components are defined. Furthermore, the view is where we define the sizing and positioning of components “skin parts”. Finally, the component’s skin is where all of the visual elements of a component are defined.
To bind data into our skin from the control we are using it with, we use the HostComponent metadata tag. Below is a Gumbo FxButton component with our skin applied to it. In this case our skin code is binding to the FxButton’s label property to display the “One Way” text by saying text="{ hostComponent.label }" in the TextBox control of our skin.
Screenshot:
Here is our skin code:
<?xml version="1.0" encoding="utf-8"?>
<Skin xmlns=http://ns.adobe.com/mxml/2009 currentStateChange="onStateChange()">
<Script>
<![CDATA[
private function onStateChange():void{
switch(currentState)
{
case "down":
fxRotate3DNeg.play();
break;
}
}
]]>
</Script>
<Metadata>
[HostComponent("mx.components.FxButton")]
</Metadata>
<states>
<State name="up"/>
<State name="over"/>
<State name="down"/>
<State name="disabled"/>
</states>
<Declarations>
<FxRotate3D id="fxRotate3DNeg" target="{group1}" yBy="-60" duration="400" />
</Declarations>
<VGroup id="group1">
<BitmapGraphic id="logo"
source="@Embed(source='../assets/OneWay.png')"
left="20"
verticalCenter="-2"/>
<TextBox
text="{ hostComponent.label }"
fontFamily="Arial"
fontSize="40"
fontWeight="bold"
color="#FFFFFF"
color.down="#000000"
right="50"
verticalCenter="0"/>
</Skin>
The Gumbo controls define the specific skin states available to it based on the component we are using it with. For example, an FxButton has “up, down, over, and disabled” skin states. A skin’s state corresponds with the HostComponent’s SkinState but does not necessary correspond to the HostComponent’s CurrentState property. You can change a component’s SkinState in actionscript by calling invalidateSkinState, and you can also call getCurrentSkinState to return a component's skinState. Component’s properties can bind directly to a skin's state. For example, color.down="#000000" would set our TextBox component's text color to black in a “down” state as seen below.
Screenshot:
States can also be used to control transitions and visual properties. For example, when we mouse over the following component we can see the glow and fade transitions applied to it.
Screenshot:
Additionally, when we mouse down on the component the rotation property is animated on our gradient.
Screenshot:
Here is what the skin code looks like for this component. Also note we are using the new FXG language to define our graphics.
<?xml version="1.0" encoding="utf-8"?>
<Skin xmlns="http://ns.adobe.com/mxml/2009">
<layout>
<BasicLayout/>
</layout>
<Metadata>
[HostComponent("mx.components.FxButton")]
</Metadata>
<states>
<State name="up"/>
<State name="over"/>
<State name="down"/>
<State name="disabled"/>
</states>
<transitions>
<Transition includeIn="up">
<Sequence>
<Fade target="{ hostComponent }"
alphaFrom="1"
alphaTo=".5"
duration="500"
effectEnd="{ hostComponent.alpha=1 }"/>
<Glow id="glowImage" target="{ hostComponent }"
duration="1000"
blurXFrom="0.0"
blurXTo="300"
blurYFrom="0.0"
blurYTo="300"
color="0xFFFFFF"/>
</Sequence>
</Transition>
<Transition includeIn="down">
<Sequence id="animateRotationPos" >
<AnimateProperty target="{ linearGrad }"
property="rotation"
toValue="360"
duration="600"
effectEnd="{ linearGrad.rotation=-720 }" />
</Sequence>
</Transition>
</transitions>
<Graphic>
<Ellipse id="ellipse"
width="100"
height="100">
<fill>
<LinearGradient id="linearGrad"
rotation="-180">
<GradientEntry color="0x333333" />
<GradientEntry color="0x808080" />
<GradientEntry color="black" />
</LinearGradient>
</fill>
<stroke>
<SolidColorStroke id="stroke" weight="2" color="0x333333"/>
</stroke>
</Ellipse>
</Graphic>
<Label text="{ hostComponent.label }"
fontFamily="Arial"
paddingLeft="15"
paddingTop="35"
fontSize="12"
color="0xC0C0C0"
fontWeight="bold"/>
</Skin>
Flex 3 Halo custom components are mainly made up of other controls added using the createChildren method and visual changes using updateDisplayList, measure, and commitProperties. With the new Gumbo skinning lifecycle we can piece together “skin parts”, which we have previously created in different ways; thus making it easier to give our application a fluid and interactive user experience.
You can see can see the above examples in action below. Flash Player 10 is required.
For more information about Gumbo Skinning check out:
http://opensource.adobe.com/wiki/display/flexsdk/Gumbo+Skinning






