Category Archives: Classes

Flash Builder 4 : vertical+horizontal centering
of swf in ActionScript projects

Flashdevelop It’s possible to edit the html wrapper that Flash Builder generates for the output swf – so that it centres any swf both horizontally and vertically without Flashbuilders default and slightly strange scaling.

The hack comes from how I’ve had this setup in Flashdevelop with SWFObject and only requires a few lines of CSS:

1
2
3
4
5
6
7
8
9
10
11
<style>
      #divFloat {
      position:absolute;
      top:50%;
      left:50%;
      right:50%;
      bottom:50%;
      margin:-300px;       /* Half the height of your SWF*/
      margin-left:-400px; /* Half the width of your SWF*/
   }
   </style>

To get this to work all that is needed is a div with the matching id ‘divFloat’ added to the html body of the html page that acts as a wrapper for the swf; and this will centre the swf vertically and horizontally.

Based on the CSS above we can device a similar approach and apply it to Flash Builder’s publishing method. The part to figure out is how to insert it into Flash Builders template based creation of the html wrapper.

To do so we must edit the index.template.html in the html-template folder in the Flash Builder project directory: which is the blueprint for the html file generated in the bin-debug folder.

In Flash Builder our html wrapper and swf will be based on what name we choose for our main application file (the one that initializes our application). This value is held by the variable ${application} in index.template.html. It is also the id of our embedded content in the html page that results in bin-debug, based on our index.template.

So we can write in index.template.html:

1
2
3
4
5
6
7
8
9
10
11
12
<style>
body { margin: 0px;}
#${application} {
      position:absolute;
      top:50%;
      left:50%;
      right:50%;
      bottom:50%;
      margin:-300px;       /* Half the height of your SWF*/
      margin-left:-400px; /* Half the width of your SWF*/
   }
</style>

If the application class has the name ‘OrangeApp.as’ that will translate into #OrangeApp{ in the resulting html file in the bin-debug folder and target the id of the embedded swf so that the CSS is applied to centre it.

Of course the swf still needs to have the following code in it’s application class:

1
2
stage.scaleMode = StageScaleMode.NO_SCALE
stage.align = StageAlign.TOP_LEFT

Also specify the width and height of the swf in the index.template.html as usual by just replacing ‘width’ and ‘height’ with the real width and height of our swf. That will center html the swf in Flash Builder; and remove the pesky default ‘Flex scaling’ without too much work!

Formatting XML text with html tags +
the TextFormat Class

Recently I wrongly came to the conclusion that you can’t apply a TextFormat to dynamic textfield set to htmlText = “My text” without that the TextFormat overwrites the formatting done with html tags in the XML.

It turns out that the issue I was having had more to do with not being read up on the defaultTextFormat setter.

Let us take Arial as an example. To embed it in AS3 in bold, italic, and normal formatting we would like so:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
package
{
   import flash.display.*;
   import flash.text.*;

   /**
    * ...
    * @author Thomas James Thorstensson
    */

   public class TextFmt extends Sprite
   {

      [Embed(source='C:/Windows/Fonts/arial.ttf'
      ,fontFamily ='arialNormal'
      ,fontStyle ='normal' // normal|italic
      ,fontWeight ='normal' // normal|bold
      ,unicodeRange='U+0020-U+002F,U+0030-U+0039,U+003A-U+0040,U+0041-U+005A,U+005B-U+0060,U+0061-U+007A,U+007B-U+007E'
      //,cff='false'
      )]
      public static const arialNormal:Class;

      [Embed(source='C:/Windows/Fonts/arialbd.ttf'
      ,fontFamily ='arialBold'
      ,fontStyle ='normal' // normal|italic
      ,fontWeight ='bold' // normal|bold
      ,unicodeRange='U+0020-U+002F,U+0030-U+0039,U+003A-U+0040,U+0041-U+005A,U+005B-U+0060,U+0061-U+007A,U+007B-U+007E'
      //,cff='false'
      )]
      public static const arialBold:Class;
     
      [Embed(source='C:/Windows/Fonts/ariali.ttf'
      ,fontFamily ='arialItalic'
      ,fontStyle ='italic' // normal|italic
      ,fontWeight ='normal' // normal|bold
      ,unicodeRange='U+0020-U+002F,U+0030-U+0039,U+003A-U+0040,U+0041-U+005A,U+005B-U+0060,U+0061-U+007A,U+007B-U+007E'
      //,cff='false'
      )]
      public static const arialItalic:Class;

      public function TextFmt()
      {
         Font.registerFont(arialNormal);
         Font.registerFont(arialBold);
         Font.registerFont(arialItalic);
      }

   }
}

In our XML we can then directly refer to one of the versions of the font like so:

1
<xmlnode>Lorem ipsum<font face="arialItalic"> and some italic text</font> and end.</xmlnode>

If we set a dynamic textfield to the above content, we can still apply additional formatting to it
with a regular TextFormat as long as we use defaultTextFormat rather than setTextFormat :

1
2
3
4
5
6
arialNormal = new TextFormat();
arialNormal.font = 'arialNormal';
arialNormal.size = 11;
arialNormal.color = 0xCCCCCC;
myText.defaultTextFormat = arialNormal;
myText.htmlText= xmlnode;

The dynamic textfield will take the ‘arialNormal’ format without the arialItalic format being overwritten. The italic style will so to speak take on the arialItalic and the arialNormal.

If we instead would use setTextFormat after myText.htmlText= xmlnode; it would be the case that the formatting in the html would be overwritten by the TextFormat.

AS 3 Dictionary Object: a way to map instances of sealed Classes

In Action Script 3 most classes are sealed. This means that for most Objects we are not able to create new properties run time beyond those that where available compile time. This is not the case with Array and Object though which are both dynamic and regularly come in handy to us for example in the creation of an associative array (or sometimes called a ‘hash’) :

1
2
3
var myAssoc:Object = new Object();
myAssoc["oranges"] = 101;
trace ("number of oranges " + myAssoc["oranges"])

But what to do if you’re in need of creating properties upon an instance that belongs to a sealed class. For example say that we with flash.display.SimpleButton would like to add the property counter which tells us how what time interval to start a timer with. We could not:

1
2
3
(//import flash.display.SimpleButton etc...)
var myBtn:Simple Button = new SimpleButton();
myBtn.timestamp = 1000;

The above would throw an error as SimpleButton like most classes in ActionScript 3 are sealed. The solution would be to extend SimpleButton with a dynamic class like so :

1
2
3
4
5
6
7
8
9
10
11
package
{
import flash.display.SimpleButton;
public dynamic class DynamicButton extends SimpleButton
{
   public function DynamicButton()
   {

   }
}
}

Making use of our dynamic button we could now :

1
2
3
var dynBtn:DynamicButton = new DynamicButton();
dynBtn.timestamp = 1000;
trace ("dynamic button timestamp value " + dynBtn.timestamp);

And this would compile without errors and work nicely. However there is an other approach to this which comes very handy as a way of creating dynamic properties and referring to them. Here enters the Dictionary Object. This object is a bit like our associative array above but with the big difference that it can take an object itself as lookup key to find a value. For our oranges we get:

1
2
3
4
var dict:Dictionary = new Dictionary();
var myOrange:Object = new Object();
dict[myOrange] = 101;
trace ("number of oranges dictionary approach " + dict[myOrange]);

Using a Dictionary Object we thus have a way to lookup properties using the objects themselwes rather than using the variable names to refer to properties. This also works for instances of sealed classes such as our button example. We can write:

1
2
3
4
dict = new Dictionary();
var myButton: SimpleButton = new SimpleButton ();
dict[myButton] = 1001;
trace ("dictionary button counter value " + dict[myButton]);

Since the button is the key, it does not matter that SimpleButton is a sealed class. We are not trying to assign a new property to the SimpleButton instance by using a variable name. Instead we use the instance itself and thus we here have a handy way of assigning values also to instances that don’t take new dynamic properties.

Some further readings:
http://www.gskinner.com/blog/archives/2006/07/as3_dictionary.html
http://www.zombieflambe.com/actionscript-3/as3-dictionary-class-array-object-benchmark/
http://pixelwelders.com/blog/best-practices/2008/speed-tests-objects-vs-arrays-vs-dictionaries/