The Flex framework provides a rich library of components right out of the box, but often creating a custom component is necessary. When the component is a container, you might want to use it as the base of an mxml file. Here’s how.

Of course, you should have a container-based class ready. For this example, I’m using an extension of the class TitleWindow. I needed to completely style this class in one of my recent projects, so I hacked in a convenient way to do it using a new skin.

DialogBox.as

package containers {
    import flash.display.DisplayObject;
    import flash.filters.DropShadowFilter;
   
    import mx.containers.TitleWindow;
    import mx.core.mx_internal;

    use namespace mx_internal;
   
    [Style(name="everythingSkin",type="Class")]
    [Style(name="dropShadowAlpha",type="Number")]
    public class DialogBox extends TitleWindow {
        private var allSkin:DisplayObject;
        override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void {
            super.updateDisplayList(unscaledWidth,unscaledHeight);
           
            var es:Class = getStyle("everythingSkin");
           
            if (!es && allSkin) {
                if (rawChildren.contains(allSkin))
                    rawChildren.removeChild(allSkin);
                allSkin = null;
                mx_internal::border.visible = true;
            } else if (!allSkin || !allSkin.isPrototypeOf(es)) {
                if (es) {
                    allSkin = DisplayObject(new es());
                    allSkin.width = unscaledWidth;
                    allSkin.height = unscaledHeight;
                    rawChildren.addChildAt(allSkin,0);
                    mx_internal::border.visible = false;
                   
                    //apply shadow to skin if necessary
                    if (getStyle("dropShadowEnabled")) {
                        var c:uint = getStyle("dropShadowColor");
                        var a:Number = getStyle("dropShadowAlpha");
                        var dist:Number = getStyle("shadowDistance");
                        var dir:String = getStyle("shadowDirection");
                        var angle:Number = 90;
                        if (dir == "right") angle = 0;
                        if (dir == "left") angle = 180;
                       
                        allSkin.filters = [new DropShadowFilter(dist?dist:2,angle,c?c:0,a?a:1)];
                    }
                   
                }
            }
        }
    }
}

Now for the next step, you need to create two new files in your src directory.

flex-config.xml

<?xml version="1.0"?>
<flex-config>
    <compiler>
      <namespaces>
         <namespace>
            <uri>http://almostflan.com</uri>
            <manifest>mxml-manifest.xml</manifest>
         </namespace>
      </namespaces>
    </compiler>
</flex-config>

mxml-manifest.xml

<?xml version="1.0"?>
<componentPackage>
    <component id="DialogBox" class="containers.DialogBox"/>
</componentPackage>

Now you need to tell the Flex compiler about the config file. The argument is -load-config. In Flex Builder, you can right-click your project, then go to Properties -> Flex Compiler. Under “Additional compiler arguments” add “-load-config+=flex-config.xml” and that should do the trick. Now you should be ready to use your class as an mxml base.

For some impractical reason, I made a gameboy.

Gameboy.mxml

<?xml version="1.0" encoding="utf-8"?>
<af:DialogBox xmlns:af="http://almostflan.com" xmlns:mx="http://www.adobe.com/2006/mxml"
    everythingSkin="@Embed(source='resources/images/gameboy/blank.png')" width="180" height="300">
    <mx:Canvas width="100%" height="100%" clipContent="false">
        <mx:Button skin="@Embed(source='resources/images/gameboy/a_button.png')" x="132" y="144"
            click="buttonClicked('a button')"/>
        <mx:Button skin="@Embed(source='resources/images/gameboy/b_button.png')" x="99" y="144"
            click="buttonClicked('b button')"/>
        <mx:Button skin="@Embed(source='resources/images/gameboy/start.png')" x="72" y="207"
            click="close()"/>
        <mx:Button skin="@Embed(source='resources/images/gameboy/select.png')" x="40" y="208"
            click="buttonClicked('select button')"/>
        <mx:Button skin="@Embed(source='resources/images/gameboy/dpad.png')" x="-8" y="145"
            click="buttonClicked('dpad')"/>
    </mx:Canvas>
    <mx:Script>
        <![CDATA[
            import mx.controls.Alert;
            import mx.managers.PopUpManager;
            private function close():void {
                PopUpManager.removePopUp(this);
            }
            private function buttonClicked(s:String):void {
                Alert.show(s+" clicked!");
            }
        ]]>
    </mx:Script>
</af:DialogBox>

dialogBoxExample.mxml

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" width="300" height="400">
    <mx:Button click="gameboyPopup()" />
    <mx:Script>
        <![CDATA[
            import mx.controls.Alert;
            import dialogs.Gameboy;
            import mx.managers.PopUpManager;
            private function gameboyPopup():void {
                var gb:Gameboy = new Gameboy;
                PopUpManager.addPopUp(gb,this);
                Alert.show("you can drag from top bar;\nclick start to close");
            }
        ]]>
    </mx:Script>
</mx:Application>

I made the buttons on the gameboy clickable and since it is based on TitleWindow, you can drag it from the top “titleBar”.

The Flash plugin is required to view this object.

Tags: , , , , , , ,

3 Responses to “Using a custom class as an mxml base to completely style a TitleWindow”

  1. on 20 Mar 2009 at 6:22 am DDDan said …

    Hey there..

    I can’t see any of your code examples in my browser :-(
    I tried it with IE 7 and FF3. And also the “view source” of the demo doesn’t work. It would be really great if you could fix that.

    Cheers,
    Dan

  2. on 20 Mar 2009 at 2:50 pm Frank Lam said …

    I’ve fixed the code examples, view source is still a bit screwy.

  3. on 23 Mar 2009 at 4:01 am DDDan said …

    Cool, thanks!

Trackback This Post | Subscribe to the comments through RSS Feed

Leave a Reply