Use css to style a custom spark skin in Flex 4
I’ve finally had a chance to dive in to Flex 4. One trick I learned is incredibly powerful. CSS is a powerful way to specify settings to something from the outside, but it quickly becomes a pain if you need to push pixels around. I’m going to show you how you can create a skin that reads its properties from a stylesheet. This allows css to do what it does best: set simple properties, and lets you do the pixel pushing in the Skin.
Let’s start with some Flex 3 code we’d like to duplicate. This will create a “modal” overlay that covers the app with a translucent screen. You might use this for a LightBox.
<!-- MyOverlay.mxml -->
<mx:Canvas
width="100%" height="100%"
styleName="overlay"
>
<!-- Put a panel or something here -->
</mx:Canvas>
/** styles.css **/
.overlay {
background-color: #000000;
background-alpha: 0.7;
}
Our First Skin
We want to create this in Flex 4. The (rough) equivalent to canvas is a Group, but it isn’t skinnable, so we can use a SkinnableContainer instead.
<!-- MyOverlay.mxml -->
<s:SkinnableContainer
width="100%" height="100%"
skinName="overlay"
>
<!-- Stuff -->
</s:SkinnableContainer>
SkinnableContainer doesn’t have a way to set backgroundColor or backgroundAlpha! The css will not work.
Let’s create the same functionality in a skin instead.
<!-- skins/OverlaySkin.mxml -->
<s:SparkSkin ... >
<!-- The highest-level base class that can use this-->
<fx:Metadata>
[HostComponent("spark.components.SkinnableContainer")]
</fx:Metadata>
<!-- specify all the states the host component uses -->
<s:states>
<s:State name="normal"/>
<s:State name="disabled"/>
</s:states>
<!-- Here's our overlay! -->
<s:Rect left="0" right="0" top="0" bottom="0">
<s:fill>
<s:SolidColor color="#000000" alpha="0.7"/>
</s:fill>
</s:Rect>
<!-- Put the panel, or whatever is in the component here -->
<s:Group id="contentGroup" verticalCenter="0" horizontalCenter="0">
<s:layout><s:BasicLayout/></s:layout>
</s:Group>
</s:SparkSkin>
That’s not too bad. We have a skin, and now we can apply it to our component by setting the skinClass property. For example:
<!-- MyOverlay.mxml -->
<s:SkinnableContainer
width="100%" height="100%"
skinClass="skins.OverlaySkin"
>
<!-- content -->
</s:SkinnableContainer>
Or we can set the skinClass in the style.
<!-- MyOverlay.mxml -->
<s:SkinnableContainer
width="100%" height="100%"
styleName="overlay"
>
<!-- content -->
</s:SkinnableContainer>
/** styles.css **/
.overlay {
skinClass: ClassReference("skins.OverlaySkin");
}
Using CSS on the Skin
Now we have a styleName we can apply to any SkinnableContainer and it will make it look like our black, translucent overlay. This works great, so we start using it, but pretty soon we realize that we need to be able to add a background to another container, but we don’t want to create a new skin just to tweak the color and alpha. Here is where it gets fun. We change the Rect tag in our skin to look like this:
<s:Rect left="0" right="0" top="0" bottom="0">
<s:fill>
<s:SolidColor color="{getStyle('backgroundColor')}" alpha="{getStyle('backgroundAlpha')}"/>
</s:fill>
</s:Rect>
Now it will get it’s color and alpha from the style. We can change our overlay style to look like this
/** styles.css **/
.overlay {
background-color: #000000;
background-alpha: 0.7;
skinClass: ClassReference("skins.OverlaySkin");
}
That looks a lot more like the Flex 3 version! We can then add more styles for other kinds of containers that need backgrounds, and our skin is now much more useful than before.
The Final Version
<!-- skins/BackgroundSkin.mxml -->
<?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:mx="library://ns.adobe.com/flex/halo">
<fx:Metadata>
[HostComponent("spark.components.SkinnableContainer")]
</fx:Metadata>
<s:states>
<s:State name="normal"/>
<s:State name="disabled"/>
</s:states>
<s:Rect left="0" right="0" top="0" bottom="0">
<s:fill>
<s:SolidColor color="{getStyle('backgroundColor')}" alpha="{getStyle('backgroundAlpha')}"/>
</s:fill>
</s:Rect>
<!-- Tells the skin where to put the children you have specified -->
<s:Group id="contentGroup" verticalCenter="0" horizontalCenter="0">
<s:layout><s:BasicLayout/></s:layout>
</s:Group>
</s:SparkSkin>
/** styles.css **/
.overlay {
background-color: #000000;
background-alpha: 0.7;
skinClass: ClassReference("skins.OverlaySkin");
}
.error {
background-color: #FF0000;
background-alpha: 1.0;
}
.success {
background-color: #00FF00;
background-alpha: 1.0;
}
Using this technique will allow you to play to the strengths of both CSS and Spark Skins.
FlashLib Library Index Features
In An Army of Small Libraries I suggested creating a site that indexes every known bit of reusable Actionscript code in existence. FlashLib.org is up, and I’d like to solicit feedback on the planned features as it progresses. Please look over these and let me know what you think.
An Army of Small Libraries
Ted Patrick, known on twitter as @adobeted, recently released two interesting as3 libraries: FDOT and Tubes. This is not unique to Ted. People constantly develop amazing solutions to common problems. The problem is that it is hard to find these solutions. Unless the developer already has a large following, his code usually dies in obscurity. Someone facing a common problem will either develop their own solution, or find a stale solution on google. Ted has been proposing that someone create a standard as3 library. I would like to recommend an alternative.
Client-Side Flex Logging with Shared Object
Having your app keep a detailed log can be indispensable for figuring out tricky user-reported bugs. This is easy on the server-side, where you can use any logging framework or just write to a file. Flash includes the trace function, which is useful while developing, but nearly impossible to get from an end-user. Flex, however, has a good logging api that lets you put log statements anywhere you want. I’ve always wanted the interface to be as easy as trace, so I write a couple of scripts to make it easier.
How to write your own PHP templating engine
MVC is all the rage. Choosing a framework, however, is not so easy. The view part of a standard php MVC framework usually involves grabbing one or more model objects and printing out some text (html) about them. There are several frameworks that do this, including the famous smarty. There are even more frameworks, like Zend and CakePHP that include templating as a subset of what they do.
Easy Daemons in PHP
This class and script makes it easy to turn a one-shot php script into a daemon that runs in the background on a timer. This is good for things you want to happen infrequently. For example, your site may need to use curl to fetch several different rss feeds, combining them into one feed. You don’t want to fetch all the feeds every time someone asks for the combined one. It is better to generate the combined feed every 5 minutes or so.
Create a Blog in Ruby and Sinatra - Part 2 - Models
This is part 2 of my Sinatra blog tutorial. Today I’m talking about the database layer. Don’t forget to check out the full source of my blog on github.
Page Stack - Navigate by Page Name
Building a navigation system in Flex is harder than it should be. Trying to figure out how to decouple your navigation model from the view is unintuitive. ViewStack is the obvious choice for it, but it leaves you with only two options, neither of which is good.
Custom Block Helper in ERB
Something I learned how to do in rails, but had a hard time replicating without it, is create a custom helper that accepts a block. I figured out how to write to the screen from the helper. @_out_buf is the name of the variable I needed.
A New Home
My blog has been going through a state of flux lately. I hadn’t posted in a couple of months, and when I discovered posterous, I thought I had found the perfect system. Well, it didn’t make me post any more than I used to - it just made my blog look worse.





