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
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
<flex-config>
<compiler>
<namespaces>
<namespace>
<uri>http://almostflan.com</uri>
<manifest>mxml-manifest.xml</manifest>
</namespace>
</namespaces>
</compiler>
</flex-config>
mxml-manifest.xml
<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
<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
<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”.
Tags: custom, Flex, gameboy, import, mxml, Panel, skin, TitleWindow


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
on 20 Mar 2009 at 2:50 pm Frank Lam said …
I’ve fixed the code examples, view source is still a bit screwy.
on 23 Mar 2009 at 4:01 am DDDan said …
Cool, thanks!