Skinning a Flex button with one MXML file (and Degrafa)

Skinning a flex button can often take multiple graphics and/or MXML files for each state. Here’s how to skin a button using MXML and Degrafa to handle three button states with just one file (plus a bonus ‘glow’ filter as an alternate way to get a drop shadow).

The secret is to override the updateDisplayList method and use the skin’s current name in a switch statement to apply different Degrafa strokes and fills to the button. Click to view an example with source.

Flex button skinning

<?xml version="1.0" encoding="utf-8"?>
<GraphicBorderSkin xmlns:mx="http://www.adobe.com/2006/mxml"
    xmlns="http://www.degrafa.com/2007">

    <mx:Script>
        <![CDATA[

            //////////////////////////////////////////////////////////////////////
            //
            // PRIVATE VARIABLES
            //
            //////////////////////////////////////////////////////////////////////

            [Bindable]
            private var awidth:Number=0;

            [Bindable]
            private var aheight:Number=0;

            //////////////////////////////////////////////////////////////////////
            //
            // PROTECTED METHODS
            //
            //////////////////////////////////////////////////////////////////////

            override protected function updateDisplayList( unscaledWidth:Number, unscaledHeight:Number ):void
            {
                super.updateDisplayList( unscaledWidth, unscaledHeight );

                awidth = unscaledWidth;
                aheight = unscaledHeight;

                // drop shadow is actually a black 'glow'
                var glow:GlowFilter = new GlowFilter();
                glow.color = 0x000000;
                glow.alpha = 1;
                glow.strength = .75;
                glow.quality = BitmapFilterQuality.MEDIUM;

                // which skin state?
                switch ( name )
                {
                    case "upSkin":
                        buttonRect.fill = upFill;
                        buttonRect.stroke = upStroke;
                        glow.blurX = 4;
                        glow.blurY = 4;
                        break;

                    case "overSkin":
                        buttonRect.fill = overFill;
                        buttonRect.stroke = overStroke;
                        glow.blurX = 5;
                        glow.blurY = 5;
                        break;

                    case "downSkin":
                        buttonRect.fill = downFill;
                        buttonRect.stroke = downStroke;
                        glow.blurX = 3;
                        glow.blurY = 3;
                        break;
                }

                // apply filter
                this.filters = [glow];
            }

        ]]>
    </mx:Script>

    <!-- FILLS -->
    <fills>

        <!-- UP -->
        <LinearGradientFill id="upFill" angle="90" >
            <GradientStop ratio="0" alpha="1" color="#666666" />
            <GradientStop ratio=".5" alpha="1" color="#333333" />
            <GradientStop ratio=".5" alpha="1" color="#000000" />
            <GradientStop ratio="1" alpha="1" color="#666666" />
        </LinearGradientFill>

        <!-- OVER -->
        <LinearGradientFill id="overFill" angle="90" >
            <GradientStop ratio="0" alpha="1" color="#666666" />
            <GradientStop ratio=".5" alpha="1" color="#333333" />
            <GradientStop ratio=".5" alpha="1" color="#000000" />
            <GradientStop ratio="1" alpha="1" color="#666666" />
        </LinearGradientFill>

        <!-- DOWN -->
        <LinearGradientFill id="downFill" angle="90" >
            <GradientStop ratio="0" alpha="1" color="#000000" />
            <GradientStop ratio=".5" alpha="1" color="#333333" />
            <GradientStop ratio=".5" alpha="1" color="#444444" />
            <GradientStop ratio="1" alpha="1" color="#777777" />
        </LinearGradientFill>

    </fills>

    <!-- STROKES -->
    <strokes>

        <!-- UP -->
        <SolidStroke id="upStroke" color="#ffffff" alpha="1" weight="1.5" />

        <!-- OVER -->
        <LinearGradientStroke id="overStroke" angle="90" weight="1.5">
            <GradientStop alpha="1" ratio="0" color="#ccffff"/>
            <GradientStop alpha="1" ratio="1" color="#66ccff"/>
        </LinearGradientStroke>

        <!-- DOWN -->
        <SolidStroke id="downStroke" color="#f4f4f4" alpha="1" weight="1.5" />

    </strokes>

    <!-- GEOMETRY -->
    <geometry>
        <RoundedRectangleComplex id="buttonRect" height="{aheight}" width="{awidth}"
            bottomLeftRadius="4" bottomRightRadius="4" topLeftRadius="4" topRightRadius="4" />
    </geometry>

</GraphicBorderSkin>

Display Rails associations in a Flex DataGridColumn

Frameworks like Ruby on Rails and CakePHP make it easy to set up model associations with belongs_to, has_many, and the ever popular has_and_belongs_to_many. However, getting those associations to show up in a Flex DataGridColumn’s dataField isn’t immediately obvious, you’d assume you could just do parent.child or child.parent but that just gives a blank column. After some digging I found the answer is to use a labelFunction.

In the example below there are two models in Rails, ‘Group’ and ‘Category’, Group has_many Categories and Category belongs_to Group. Here’s the Flex code for the Categories DataGrid, groupName is the labelFunction that spits out a Category’s Group name (equivalent to @category.group.name in ruby):

<?xml version="1.0" encoding="utf-8"?>
<mx:VBox xmlns:mx="http://www.adobe.com/2006/mxml" width="100%" height="100%">

    <mx:Script>
        <![CDATA[
            import mx.controls.dataGridClasses.DataGridColumn;

            private function groupName( item:Object, column:DataGridColumn ):String
            {
                return item.group.name;
            }

        ]]>
    </mx:Script>

    <mx:DataGrid id="dataGrid" width="100%" height="100%">
        <mx:columns>
            <mx:DataGridColumn headerText="Name" dataField="name" />
            <mx:DataGridColumn headerText="Group" labelFunction="groupName" />
        </mx:columns>
    </mx:DataGrid>

</mx:VBox>

New job! I’m now an ActionScript Developer at OpenSoft

After three years of consulting I’m heading back to a ‘real’ job as a Flash/Flex (mostly the latter) developer at OpenSoft (aka Farheap Solutions). It was a tough call but doing full time Flex work a mere 15 minute commute away was too good to pass up.

The blog, which was about 50/50 Ruby/Flex, will probably now swing wildly to ActionScript/Flex topics as I’m all business in the front from here on out. I now have smarter people than me to take care of the back-end (which at OpenSoft is Java and PHP, with a dash of Ruby thrown in for kicks).

Consulting was fun but a bit scattered, I always had like four projects in various stages of completion (not recommended). Not only was I switching between Ruby and Flex but also between design, business development, tech support, accounting, collections, db admin, server admin and on and on. However I learnt a ton, and really only because I was working for myself could I decide to take a day or two off to learn Rails or Flex. If you’re on the younger side (or have limited attachments, i.e., single, no mortgage) I highly recommend consulting for a couple of years to learn new skills and build a reputation.

So my conversion to the dark side is now complete, five jobs ago I was designing Teletubby books for the BBC and now I’m an evil flex developer.

PS OpenSoft is looking for a couple more ActionScripters, Flex jobs in OC are still pretty rare so send me a resume if you’re interested (alastairdotdawson at farheapdotcom).

Some App Engine links

Aral Balkan on Building Flash applications with Google App Engine.

PureMVC Python / Google App Engine Demo

Run your web applications on Google’s infrastructure

Google releases App Engine. It’s Python only for now, but there are rumors more languages (Ruby!) will soon be available.

Here’s a video intro. And Django runs out of the box (in the box?) – well some parts are missing like no relational db – still you can’t beat the one line deployment!

Docs! Running Django on Google App Engine

List of Flex resources and tutorials

Paranoid Ferret Productions, who themselves are a great Flex resource, have a list of the ‘Best Adobe Flex Resources and Tutorial Sites‘.

ActionScript MVC minimalist example for PureMVC 2.0.3

I’ve updated Chandima Cumaranatunge’s excellent PureMVC walk-through to work with the latest version of PureMVC (2.0.3). Although PureMVC has extensive documentation nothing beats a simple demo for wrapping your brain around the framework. The most helpful part of Chandima’s tutorial is when he steps through the sequence of actions which includes initialization and then following a user’s gesture on a round trip through the framework.

1. The Concrete Facade class called ApplicationFacade broadcasts a STARTUP Notification.

2. The STARTUP Notification triggers the StartupCommand command object which registers the KeyDataProxy proxy, and StageMediator mediator.

3. StageMediator mediator registers a KEY_DOWN Event handler to the stage to intercept key presses. It also registers to receive KEYUPDATE Notifications.

4. User presses a key generating a KEY_DOWN Event that is intercepted by the key down event handler in the StageMediator.

5. StageMediator broadcasts a KEYDOWN Notification with the character code of the key in the notification body.

6. The KEYDOWN Notification triggers the StoreKeyCommand command object, which accesses the KeyDataProxy proxy and updates the model (data object).

7. The KeyDataProxy proxy stores the data in a data object (just a property in the proxy in this case).

8. The KeyDataProxy proxy broadcasts a KEYUPDATE Notification with the character code of the key in the notification body.

9. The KEYUPDATE Notification handler in StageMediator intercepts the KEYUPDATE Notification and traces the key value.

In my updated example I trace out each action to clarify when (and in which file) they occur. Make sure you have PureMVC in your class path before running the demo.

PureMVC for Ruby

The PureMVC framework is considered one of the best for Flash/Flex development (definitely the best documented), I hadn’t checked out the site in a while (which has undergone an overhaul and is much improved!) and since my last visit PureMVC is now available for not only AS2 and AS3 but C#, ColdFusion, Java, Perl, PHP, Python, and Ruby as well.

I should say plans for Ruby as they are looking for a project owner to work on the port. I’d volunteer myself (famous last words) but while I love Ruby I don’t know the ins and outs of the language as well as I do ActionScript.

In any case having one framework “to rule them all” would be a great boost to productivity as you wouldn’t have to mentally switch gears between the front (Flash/Flex) and back (PHP/Ruby etc.) ends.

Deep linking in Flex and Flash with Django

Aral Balkan shows you how.

Build Flash with Ruby

Via Flex on Rails…

Using HotRuby it is possible to use straight Ruby to build a Flash app.