

(click to see it in action)


    var parts = path.split(' ');
    while (parts.length > 0) {
        var part = parts.shift();
        if (part == 'M') {
        } else if (part == 'L') {
        } else if (part == 'Z') {
            coords = part.split(',');


If you call it like this:


You’d get a nice 10px by 10px square as expected.










public class MyObjFlattenedList extends ArrayList {
    //the root object
    private var _root:MyObj;
    //list of open nodes
    private var _openList:Array;
    public function MyObjFlattenedList(root:MyObj) {
        _root = root;
        _openList = [];
    public function reset(openList:Array = null):void {
        //init the flattened list, starting at root
        var a:Array = [];
        addItemToList(_root, a);
        this.source = a;
    private function addItemToList(obj:MyObj, a:Array):void {
        //a flattened list that is returned in array a
    public function isItemOpen(obj:MyObj):Boolean {
        //true if obj has children and is "open"
    public function openItem(obj:MyObj):void {
    public function closeItem(obj:MyObj):void {




            [Bindable] private var _obj:MyObj;
            [Bindable] private var _hasChildren:Boolean = false;
            private var _list:MyObjFlattenedList;
            override public function set data(val:Object):void {
       = val;
                if (val != null) {
                    _obj = val as MyObj;
                    var ownerList:List = owner as List;
                    _list = ownerList.dataProvider as MyObjFlattenedList;
                    btn.selected = _list.isItemOpen(_obj);
            private function toggleHandler():void {
                if (btn.selected) {
                } else {
        <s:State name="normal" />
        <s:State name="hovered" />
        <s:State name="selected" />
    <s:Rect ...>
    <s:HGroup ...>
        <s:Label ... />





Here’s the finished product (view source enabled):

Flash is required. Get it here!

Use it and enjoy.




(click to see it in action)


public class Clock extends SkinnableComponent {
    public var secAngle:Number = 0.0;
    public var minAngle:Number = 0.0;
    public var hourAngle:Number = 0.0;
    private var _timer:Timer;
    private var _tween:GTween;
    public function Clock() {
        _tween = new GTween(this, 2, ...);
        _timer = new Timer(2000,30);
        _timer.addEventListener(TimerEvent.TIMER, tickHandler);
    private function tickHandler(e:TimerEvent):void {
        var t:Date = new Date();
        var h:Number = t.getHours();
        var m:Number = t.getMinutes() + h * 60;
        var s:Number = t.getSeconds() + m * 60;
        var ms:Number = t.getMilliseconds();
        _tween.proxy.secAngle = -90 + s * 6 + ms * 0.006;
        _tween.proxy.minAngle = -90 + s * 0.1;
        _tween.proxy.hourAngle = -90 + (s / 120);

At the core of the Clock component is a single timer. When the timer fires, it uses the current date to compute the angle of the hour hand, minute hand, and second hand. The actual motion of the hands is managed via the awesome proxy functionality in Grant Skinner’s GTween library.

All the interesting FXG action takes place in the skin, so let’s check it out:

            private function complete():void {
                ...lots of programmatic FXG here...
    ...lots of vanilla FXG here...
    <s:Path rotation="{hostComponent.minAngle}" ...
    <s:Path rotation="{hostComponent.hourAngle}" ...
    <s:Path rotation="{hostComponent.secAngle}" ...

Getting data to the skin is done via the standard binding to hostComponent. There is no need for the more complicated partAdded() and partRemoved() mechanism, because the Clock component is not intended for general use, unlike my previous components: Terrific TabBar, SuperTextInput, and Drawer.

The skin has a big block of programmatic FXG skinning, done in actionscript code inside the complete() handler which is fired by the creationComplete event. It also has a big block of vanilla MXML declarative FXG skinning, which, most importantly, includes the clock hands and the previously mentioned binding to hostComponent.

By its nature, a clock has a lot of identical elements that are positioned in a circle. The obvious attack is to put the repeated elements in a loop, or set of loops, and go the programmatic route to construct the skin. For example, the long thin ticks along the outer ring are constructed with a double loop. Here’s the relevant snippet of code from inside the complete() handler:

for each (var i:int in [0,30,60,90,120,150,180,210,240,270,300,330]) {
    for each (var j:int in [6,12,18,24]) {
        var p:Path = new Path(); = "M 174,-0.5 L 184,-0.5 184,0.5 174,0.5 Z";
        p.x = 250;
        p.y = 250;
        p.rotation = i + j;
        p.fill = gray;
        this.addElementAt(p, 1);

A new Path element is created and its data property is set. Our tick mark is 10px long, but only 1px wide. With each iteration, a tick mark is created and rotated into place. There are two important tricks in this code that are worth pointing out. First, the rotation origin is at (0,0) for each element, so we must construct our path from -0.5 to 0.5 for it to rotate correctly. Second, we must use addElementAt() to place each element into the proper layer of the drawing because the programmatic FXG code runs after all the vanilla (aka non-programmatic) FXG has been drawn.


No one in their right mind would ever build a clock skin like this. To do this the right way, you’d definitely want to use an image or two to construct the skin. The only reason I went the programmatic FXG skinning route was to verify to myself that it could be done. So, yes it can be done, and I enjoyed the trip.




The Flex 3 Way


<mx:HBox id="header">
        <mx:Text text="Sidebar" />
<mx:VBox id="footer">


The 3-in-4 Way, aka The Wrong Way



<s:HGroup id="header">
<s:VGroup id="footer">


The Flex 4 Way



            <s:p>sidebar content</s:p>
        <s:p>main content</s:p>


Building a Multi Content Area Container




package containers {
    import spark.components.Group;
    import spark.components.Application;
    public class MainApp extends Application {
        public var sidebarGroup:Group;
        private var _sidebarContent:Array = [];
        public function MainApp() {
        public function get sidebarContent():Array {
            return _sidebarContent;
        public function set sidebarContent(value:Array):void {
            _sidebarContent = value;
            if (sidebarGroup) {
                sidebarGroup.mxmlContent = value;
        override protected function partAdded(partName:String, instance:Object):void {
            super.partAdded(partName, instance);
            if (instance == sidebarGroup) {
                sidebarGroup.mxmlContent = _sidebarContent;
        override protected function partRemoved(partName:String, instance:Object):void {
            super.partRemoved(partName, instance);
            if (instance == sidebarGroup) {
                sidebarGroup.mxmlContent = null;


Skinning a Multi Content Area Container




Here is a trivial skin:

<s:Skin ... >
        <s:State name="normal" />
        <s:State name="disabled" />



containers|MainApp {




» view MultiConentArea sample (view source enabled)



Photoshop does this annoying thing where purely vertical gradients have some horizontal variation. Yes, it’s usually only plus or minus one bit of color, but it offends! I’ve battled Photoshop for a while on this, but I just can’t seem to get exactly what I want out of it. So to make a perfect gradient, I decided to write some code. The requirements are simple: given a starting color and a set of deltas, output a perfect gradient.

Here are some quick examples:

4, 1, 0.25
-2.2, -1, -0.3
-1, 0, 1

If we zoom in on example #1, which starts with black (#000000) and has deltas of 4, 1, 0.25, we see the following:

zoomed gradient

The diagram shows the first ten rows of the gradient. The delta values are accumulated with each row, and only the whole part of the resulting color value is used (aka I take the floor of each color bit). So in this example, using the fractional delta of 0.25 results in exactly one additional blue bit every four rows. Ahhh, perfect!

The Code

No need to use some fancy new language, I wrote a simple PHP program to handle commandline input and output a perfect PNG gradient. The interesting part is the function that generates and saves the gradient:

function build_image($filename, $w, $h, $color, $delta) {
  $img = imagecreatetruecolor($w, $h);
  $c = imagecolorallocate($img, $color[0], $color[1], $color[2]);
  $d = $delta;
    imagefilledrectangle($img, 0, $y, $w - 1, $y + 1, $c);
    $c = imagecolorallocate($img,
      clamp(floor($color[0] + $d[0])),
      clamp(floor($color[1] + $d[1])),
      clamp(floor($color[2] + $d[2]))
    $d = array($d[0] + $delta[0], $d[1] + $delta[1], $d[2] + $delta[2]);
  imagepng($img, $filename);

The code is straight forward. First, create the image via imagecreatetruecolor(). Then, starting with the starting color, draw a one pixel tall rectangle for each row of the image. The next row’s color is computed in each iteration by adding the accumulated delta to the starting color. Finally, output the image as a PNG via imagepng() and free the memory. The complete php source can be downloaded here.

Button Time

Once we have our perfect gradient engine in place, it’s time to make some perfect buttons. To achieve the standard glass button look-and-feel, I typically fuse two gradients together: light on the top, dark on the bottom.

Here are the two halves of a pretty red button, along with their starting color and deltas:


And the two commandline invocations of gradient.php to create the gradients:

php gradient.php 100x16 ff8080 -3,-3,-3 top.png
php gradient.php 100x16 d23c3c -3,-3,-3 bottom.png

If I want my buttons to be sexy, rounded corners are a must. My favorite photoshop trick to create multiple rounded buttons is to use a rounded alpha-transparent button with each gradient as a clipping mask. Using a clipping mask is a simple way to guarantee button geometry remains fixed while colors are changed.

Here is the layers pane showing the two gradients fused together and used as a clipping mask for the rounded alpha-transparent button:

clip mask

The result is a horizontally stretchable gradient button, that doesn’t look half bad. See for yourself:


Custom UIButton

The final button asset can be used as desired, but here is a simple Objective-C example since I’ve been in iPhone world lately:

UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
[btn setFrame:CGRectMake(20, 20, 140, 32)];
[btn setBackgroundImage:[[UIImage imageNamed:@"btn-red.png"]
      topCapHeight:0.0] forState:UIControlStateNormal];
[btn setTitle:@"BUTTON" forState:UIControlStateNormal];
[btn setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
[btn.titleLabel setFont:[UIFont boldSystemFontOfSize:14]];

Create a new UIButton of type UIButtonTypeCustom and then set the button skin as the backgroundImage. The horizontal stretchability is due to the stretchableImageWithLeftCapWidth and topCapHeight.

Here is a screenshot from the iPhone simulator showing the button in action:

  • gradient.php – the perfect gradient engine
  • gradient-button.psd – the photoshop source for the red button image, including the rounded alpha-transparent button and fused red gradients
  • btn-red.png – the red button image

© 2018