Thursday, 21 February 2008

Flex 2 (maybe 3) - scrollbar skinning thickness

Upon skinning a Flex ScrollBar recently, using symbols from an external assets SWF, I came across a bit of a conundrum: Flex appeared to be resizing the skins to almost half their size. "Why can this be?", I thought. Quickly rummaging around Google and the Flex lists, I found that a few poor souls were having the same issue.

Whilst rooting around the ScrollBar source, it turned out there is a THICKNESS constant defined. A bit more sifting uncovered the fact it wasn't referenced anywhere: ScrollBar, VScrollBar, Canvas; nowhere. Until I found its one lonely existence: mx.skins.halo.ScrollArrowSkin - in its measuredWidth and measuredHeight getters.

It seems that, if you define less than the four - up, down, over, disabled - skins, at least one will be using the above Halo class, meaning all will be reskinned to the magic 16 defined in THICKNESS. Defining the remaining of these four states corrects the problem; in my case, just the disabled.

Magic; or so it seems.

Sunday, 10 February 2008

Flex and tabbing - get to anything...

Flex developers need to be aware of accessible content these days, and that includes the infamous tabbing phenomenon. Always been a bugbear with the Flash Player. Flex takes most of this pain away, but any custom components could have you tearing your hair out.

For instance, create custom button class extending Canvas; set buttonMode to true, set focusEnabled to true. Still nothing.

Step in IFocusManagerComponent. Interestingly, UIComponent implements this interface, which is what the FocusManager looks at to decide whether, or not, to focus your component. All you need to do is explicitly tell Flex that your component implements it, and you're away:

<?xml version="1.0"?>
<mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml" implements="mx.managers.IFocusManagerComponent"
buttonMode="true" focusEnabled="true">
...
</mx:Canvas>


Hopefully that'll clear this up for some people as this drove me round the bend several times.

Monday, 4 February 2008

XMLList length() gotcha

I thought I'd pass on a tip on traversing nodes in E4X. Consider the following common array loop:

[as3]
for (var i:uint=0; i&lt;myArray.length; i++)
{
// do something here
}
[/as3]

Now, take a similar approach to E4X:

[as3]
var myChildren:XMLList = myXML.item;
for (var i:uint=0; i&lt;myChildren.length(); i++)
{
// do something here
}
[/as3]

On the face of it, there's nothing wrong with the above code. It compiles fine, it works fine. Until you traverse 1,000-or-so nodes. Not so good.

Investigating this shortfall, you'd be forgiven for believing E4X isn't as quick as maybe you thought it was. But simply, calling length() on the above calls it 1,000 times, meaning E4X has to run through and count its children, 1,000 times - whereas an array.length is just a simple property - comparing it with the current state of i. So the following is a far more efficient way to go about it:

[as3]
var myChildren:XMLList = myXML.item;
var myLength:uint = myChildren.length();
for (var i:uint=0; i&lt;mylength; i++)
{
// do something here
}
[/as3]

This cuts down processing of 1,000 nodes to 20% of its original timings.