Fla to FXG to Flex 4 Spark Skins

27 Oct

by DannyT

I’ve been taking a look at Flex 4 skinning recently, a little late to the game but as the rest of the team was getting familiar I decided it was my time to step up. My first impressions were not that great but after familiarising myself with it I started to see the benefits.

One fairly simple yet useful and perhaps not widely known discovery I made was how to go about getting assets designed in Flash into my Flex skin with just a bit of faffing about. I’d figured this wouldn’t be too high up on many people’s interest list with Catalyst weighing in as the main contender but Paul showed some interest so if for no one else, I know it’s of interest for at least someone out there!

Fla to Fxg to Spark

Will try to keep this to the point and let the visuals do the talking.

We start off with a simple Spark Button and assign it a custom skin:

<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
			   xmlns:s="library://ns.adobe.com/flex/spark" 
			   xmlns:mx="library://ns.adobe.com/flex/mx" 
			   minWidth="955" 
			   minHeight="600">
	<s:layout>
		<s:VerticalLayout gap="20" 
			paddingLeft="20"
			paddingTop="20" />
	</s:layout>
	<s:Button label="My Button" 
			 skinClass="skins.FlaFxgSkin" />
</s:Application>

To create the skin simply File, New, MXML Skin and set the host component to be a Spark Button as so:

With the generated skin we can actually remove everything down to the following which is just an empty button skin with a label:

<?xml version="1.0" encoding="utf-8"?>
<s:SparkSkin xmlns:fx="http://ns.adobe.com/mxml/2009" 
	     xmlns:s="library://ns.adobe.com/flex/spark" 
             xmlns:fb="http://ns.adobe.com/flashbuilder/2009" 
	     minWidth="21" 
	     minHeight="21" 
	     alpha.disabled="0.5">
 
    <fx:Metadata>
        [HostComponent("spark.components.Button")]
    </fx:Metadata>
 
    <s:states>
        <s:State name="up" />
        <s:State name="over" />
        <s:State name="down" />
        <s:State name="disabled" />
    </s:states>    
 
    <s:Label id="labelDisplay"
             textAlign="center"
             verticalAlign="middle"
             maxDisplayedLines="1"
             horizontalCenter="0" verticalCenter="1"
             left="10" right="10" top="2" bottom="2">
    </s:Label>
 
</s:SparkSkin>

At this point we have a pretty dull skin and want to jazz it up a little with some Flash sexyness, I suggest you find your own but this is what I’ll be using to demonstrate:

Once you have your masterpiece all you need do is File, Export, Export Image and choose the FXG file type. Point this file at your desktop or somewhere handy and you can open it in your text editor of choice.

What I noticed when I did this is that the FXG from Flash has near enough identical paths, fills, strokes, gradients etc as in spark (of course this is obviously by it’s very nature). The only thing that didn’t correlate was the spark namespace. If your shape is simple enough you can just go and manually add the s: by hand but if it isn’t then RegEx to the rescue. You’ll see I’ve used Notepad++* Programmers Notepad in the following screens to do a regex search and replace to insert the namespace we want.

Regex
find pattern - (<|</)(\w)
replace pattern - \1s:\2
(you might need to change the replace to $1s:$2 depending on text editor)

Before:

After:

Then you have your fxg code needed for your skin, simply copy and paste all of the the <s:Path> elements into your skin just above the label:

<?xml version="1.0" encoding="utf-8"?>
<s:SparkSkin xmlns:fx="http://ns.adobe.com/mxml/2009" 
	     xmlns:s="library://ns.adobe.com/flex/spark" 
             xmlns:fb="http://ns.adobe.com/flashbuilder/2009" 
	     minWidth="21" 
	     minHeight="21" 
	     alpha.disabled="0.5">
 
    <fx:Metadata>
        [HostComponent("spark.components.Button")]
    </fx:Metadata>
 
    <s:states>
        <s:State name="up" />
        <s:State name="over" />
        <s:State name="down" />
        <s:State name="disabled" />
    </s:states>    
 
	<s:Path data="M59.2 25.8 59.55 43.35 82.25 50.3 67.7 58.05 85.35 79.95 58.45 71.8 55.5 99.75 42.2 75 20.3 92.65 28.45 65.75 0.5 62.8 25.25 49.5 7.6 27.65 34.5 35.75 37.45 7.85 50.75 32.55 59.2 25.8">
		<s:fill>
			<s:SolidColor color="#009900"/>
		</s:fill>
	</s:Path>
	<s:Path data="M82.25 50.3 59.55 43.35 59.2 25.8 58.9 11.05 89.5 0.5 109 26.25 90.5 52.8 82.25 50.3">
		<s:fill>
			<s:LinearGradient x="58.9" y="26.65" scaleX="50.1">
				<s:GradientEntry ratio="0" color="#414142"/>
				<s:GradientEntry ratio="1" color="#686868"/>
			</s:LinearGradient>
		</s:fill>
	</s:Path>
	<s:Path data="M59.2 25.8 58.9 11.05 89.5 0.5 109 26.25 90.5 52.8 82.25 50.3 67.7 58.05 85.35 79.95 58.45 71.8 55.5 99.75 42.2 75 20.3 92.65 28.45 65.75 0.5 62.8 25.25 49.5 7.6 27.65 34.5 35.75 37.45 7.85 50.75 32.55 59.2 25.8M82.25 50.3 59.55 43.35 59.2 25.8">
		<s:stroke>
			<s:SolidColorStroke weight="1" color="#20343D"/>
		</s:stroke>
	</s:Path>
 
    <s:Label id="labelDisplay"
             textAlign="center"
             verticalAlign="middle"
             maxDisplayedLines="1"
             horizontalCenter="0" verticalCenter="1"
             left="10" right="10" top="2" bottom="2">
    </s:Label>
 
</s:SparkSkin>

And you’re done! Okay you’ll obviously want to do more with it than that, you can tie this into your button states and also do clever dynamic stuff with the FXG once it’s in but for now I figured this is enough. It would be really nice if this could be done without all the copying and pasting and I think possibly a JSFL script could do alot of the work for us so if anyone wants to contribute that, I’d be most grateful.

I’m going to try to expand on this and demonstrate a bit more of what I’ve been discovering as I find the time and figure more interesting things out.