Flex MXML ArrayCollection cannot ObjectUtil.compare

The ObjectUtil Class has lots of fun things in it that can make your life easier. When I needed to check to see if an ArrayCollection had changed, I thought to myself, why not use ObjectUtil.compare? Turns out that no matter what you do, every ArrayCollection is unique because they produce a UID parameter in every ArrayCollection instance that differentiates it. What’s the purpose of this? I have no idea, but someone thought it was a good idea.

Sadly, I did not find a solution to this problem, so I ended up using an Array instead of an ArrayCollection.

Determine Goal Width and Height in Image Resizing

I find myself doing image manipulation on a regular basis. One of the common things I have to do is to fit an image into a max width or height. I’ve distilled this as best I can, and I think this is as simple as it gets. It’s in PHP, but the logic should be applicable to any language.

$max_size=200;
$ratio = $image_width/$image_height;
if($ratio>1)
{
	$goal_width = $max_size;
	$goal_height = $max_size/$ratio;
}
else
{
	$goal_width = $max_size*$ratio;
	$goal_height = $max_size;
}

ActionScript 3 Math.round < Number().toFixed()

I just found out some of the fancy features that Numbers have in AS3 and how they’re going to make my life so much nicer.

Typically if I wanted to round a number, I’d write it the following way:

trace(Math.round(5.4321));

But this way is much easier:

trace(5.4321.toFixed());

the toFixed method of numbers rounds to a specified decimal place. It assumes you mean 0 places, so toFixed() rounds to 0 decimal places. This means you don’t need to mess with any of the Math things for rounding.

Flash IDE / AS3 [object global] Inside of Dynamic Function

I ran across an odd situation inside the Flash IDE where I was trying to trace out parameters about the timeline’s class.

Here’s the code I was running:

import flash.events.*
this.addEventListener(Event.ENTER_FRAME, function(e:Event){trace(this)});

the result looked something like this:

[object global]
[object global]
[object global]

This is a result of the dynamically created function created in the event listener. The function is created in some alternate universe called “global” and has nothing to do with the scope of the stage onto which it is placed. The correct code should be:

import flash.events.*
this.addEventListener(Event.ENTER_FRAME, handleFrame);
function handleFrame(e:Event):void
{
	trace(this);
}

This will produce something like:

[object MyClass]
[object MyClass]
[object MyClass]

Coding for Understandability

Often I have a number of options in how to code a particular piece of functionality. I’m constantly balancing between brevity, simplicity, speed, size, and readability. I often find that if I put a little more focus on simplicity and readability, I save myself time and headaches, in addition to making my code more readable, more object oriented, and more accessible to other coders.

I’m going to provide some examples in ECMAScript, but I know that similar problems exist in other languages, as well.

I recently ran across some code that was coded for brevity:

var userdefined:Object = (_model.partner || {}).userdefined || {},
bsb:BannerShownBeacon = new BannerShownBeacon(
	userdefined.dims 
		? userdefined.dims
		: userdefined.width && userdefined.height
			? userdefined.width + 'x' + userdefined.height
			: 'fixed_bottom'
)
;

Now, this is fully valid, well-written code, and it’s also tabbed and line-broken for readability, but what exactly is it doing? What is the purpose of this code?

The difficulty I find is that when someone is trying to determine whether their particular implementation is going to be executed — lets say we have dims, width, and height in our userdefined param, and we’re looking at this the first time. Since coding standards aren’t set for how to structure ? : style if statements, it’s difficult to go through this by instinct and take a guess at what it’s doing. Every language has if/else statements and most coders are intimately familiar with them.

First, we look to see if _model.partner exists and if it doesn’t, we create it, then we check to see if _model.partner.userdefined exists and if not, we create it and assign that to a variable.
Then, we create a second variable called bsb that expects a BannerShownBeacon;
If userdefined has a dims param, we use it, otherwise, we check if it has width and height params, and if it does, we combine them with an x in between, otherwise, we just use the term “fixed_bottom” and make a BannerShownBeacon out of that.

The final option is to include large amounts of comments (which is excellent for non-compiled languages like JS), but in compiled languages, this often doesn’t save any time or lines of code.

I’ve rewritten this here using if/else statements

var bsbText:String = "fixed_bottom";
if(_model.hasOwnProperty("partner"))
{
	if(_model.partner.hasOwnProperty("userdefined"))
	{
		var userdefined:Object = _model.partner.userdefined;
		if(userdefined.hasOwnProperty("dims"))
		{
			bsbText = userdefined.dims;
		}
		else if(userdefined.hasOwnProperty("width") && userdefined.hasOwnProperty("height"))
		{
			bsbText = userdefined.width + "x" + userdefined.height;
		}
	}
}
var bsb:BannerShownBeacon = new BannerShownBeacon(bsbText);

Preloading SWF in Firefox using SWFobject doesn’t support overflow = null

I was using the following code to pre-load my SWFs so I could instantiate them later.

swfDiv.style.width = '1px';
swfDiv.style.height = '1px';
swfDiv.style.overflow = 'hidden';
swfDiv.style.position='fixed';
swfDiv.style.top = '0px';
swfDiv.style.left = '0px';

And then, when I wanted to show my SWF, I would call

swfDiv.width = '100%';
swfDiv.height = '100%';
swfDiv.zIndex = 1000;
swfDiv.overflow = null;

This works great in Chrome, but in Firefox, things go really bad and REALLY strange things start happening. Turns out that Firefox doesn’t like null as an overflow attribute.
Setting this to “” instead works fine.

swfDiv.width = '100%';
swfDiv.height = '100%';
swfDiv.zIndex = 1000;
swfDiv.overflow = "";

Cannot Trace using Debugger on OSX

Oh good lord, all I wanted to do was trace the output of my flash debug player, yet there was nothing in the usual location. Typically I just run

tail -f ~/Library/Preferences/Macromedia/Flash\ Player/Logs/flashlog.txt

in the Terminal and it spits out everything Flash does. The file didn’t exist on my system, so I couldn’t tail it. The solution turned out to be a missing mm.cfg file.
in ~/Library/Application\ Support/, produce a mm.cfg file with the following content:

TraceOutputFileEnable=1
ErrorReportingEnable=1

This, along with a correct debugger, should produce traces.

ExternalInterface Callbacks not Firing in Firefox when Using SWFObject

Your externalinterface call works fine in chrome, safari, maybe even IE. That’s because it takes a second for Firefox to get with the program and actually shove your object into the element.

here’s a happy little hack to make things work again:
Flash:

import flash.external.ExternalInterface;
ExternalInterface.addCallback("myFunction", myFunction);
function myFunction():void
{
	trace("JS Callback Successful");
}

Javascript:

//the swf id is the object into which SWFobject has loaded your SWF file
var swf= document.getElementById("my_swf_id");
try {
	swf.myFunction();
}
catch (e) { 
	//swf is not loaded yet, wait a bit and try again
	setTimeout(function(){
		swf.myFunction();
	}, 10);
}

ExternalInterface in AS3

Just spent a minute looking for how ExternalInterface works. Here’s some handy code of how to make specific things happen in AS3:

ExternalInterface.call("alert","message");

Launches an alert window with “message” as the content.

trace(ExternalInterface.call("function(){return window.location.href;}"));

The call returns the window.location.href of the current page and is then traced to the output.

CS5 Classic Dynamic TextField Font Embedding

Here’s the concept:
In a file that’s publishing to Flash 9, create a textfield, give it an instance name of “tf1”, set the font to comic sans, and make it dynamic.
In the actionscript, do the following:

tf1.text = "this text is normal";
tf1.rotation = 30;

when you compile, you should get an error like
Fonts should be embedded for any text that may be edited at runtime, other than text with the "Use Device Fonts" setting. Use the Text > Font Embedding command to embed fonts.
This is solved by embedding the fonts, but when you’ve got one font with multiple states, things get a little weird.
Duplicate your textfield and set the instance name to tf2
Set the font to comic sans bold
Click the Embed button. Comic Sans Bold will be added. Choose the typical settings for embedding, Upper, Lower, Numbers, Punctuation and hit ok.
Click your other textfield and hit Embed. The second font, Comic Sans Regular will be added. Choose the typical settings for embedding, Upper, Lower, Numbers, Punctuation and hit ok.
Set your actionscript to

tf1.text = "this text is normal";
tf1.rotation = 30;
tf2.text = "this text is bold";
tf2.rotation = 30;

An odd thing happens. Whichever font we embedded first seems to be the only one that’s used. This is fixed in one of two ways:

Okay way:
Use htmlText with italic and bold indicators to produce the effect you want.

tf1.text = "this text is normal";
tf1.rotation = 30;
tf2.htmlText = "<b>this text is bold</b>";
tf2.rotation = 30;

Better way:
use getTextFormat and setTextFormat

var format:TextFormat = tf1.getTextFormat();
tf1.text = "this text is normal";
tf1.setTextFormat(format);
tf1.rotation = 30;
format = tf2.getTextFormat();
tf2.text = "this text is bold";
tf2.setTextFormat(format);
tf2.rotation = 30;

this can also be done more dynamically using functions:

function setText(txt, val)
{
	var format:TextFormat = txt.getTextFormat();
	txt.text = val;
	txt.setTextFormat(format);
}
setText(tf1, "this text is normal");
setText(tf2, "this text is bold");
tf1.rotation=30;
tf2.rotation=30;

cs5_font_embedding.fla