Tuesday 2 November 2010

Style Glitches when Loading Modules

We have just finished converting (where necessary) our Flex 3 project to be compilable with Flex 4 in Flash Builder 4. One of the biggest lumps in this otherwise pleasantly smooth process was styling. So we left it till last.

One of the last tasks with this styling — or at least we reckoned it was with styling — was addressing a peculiar flashing effect that occurred whenever particular modules were loaded. Upon closer scrutiny we realised something was triggering all the background colours and all the button skins to be redrawn — very perceptively — when some modules were first displayed.

On the off chance someone else is puzzling over this problem and cannot find any documentation on the matter, I lay down my findings here.

After systematically breaking down and comparing components that were being added at runtime (as children of the loaded modules) I found mx.controls.ButtonBar to be the common culprit. If this wasn't loaded, the flashing didn't happen.

I then systematically broke down the ButtonBar component and found that the problem was indeed relating to styling: witness the following code.

var typeSelector:CSSStyleDeclaration = styleManager.getMergedStyleDeclaration("mx.controls.ButtonBar");

if (typeSelector)
{
var borderSkin:* =
styleManager.getMergedStyleDeclaration("global").getStyle("borderSkin");

if (typeSelector.getStyle("borderSkin") !== borderSkin)
{
// Setting a merged style is not supported so get a local style.
typeSelector = styleManager.getStyleDeclaration("mx.controls.ButtonBar");

// Our style manager may not have a local definition of the
// button bar style so add a local one so we can modify it.
if (!typeSelector)
{
var selector:CSSSelector = new CSSSelector("mx.controls.ButtonBar", null, null);
typeSelector = new CSSStyleDeclaration(selector, styleManager);
}

typeSelector.setStyle("borderSkin", borderSkin);
}
}
The above snippet was extracted from the overridden setter function moduleFactory (line 497 of ButtonBar.as) and shows a comparison being made between the merged ButtonBar's borderSkin and the global borderSkin styles. In Flex 4 this equality comparison always returns false the first time it is encountered, causing a style to be set, and somehow manages to affect the global style; in the Flex 3 SDK this code doesn't exist.

There is no way to forcefully assign a borderSkin to the component, since the class defines the style as excluded, and — in our framework anyway — the component fails to inherit the style by this point from the halo theme's global style.

As any good workaround ever is, the solution was simple.

I added a child ButtonBar to the top-level application. Since by itself it's invisible and sizeless in the halo theme, adding <mx:buttonbar/> somewhere discreetly was fairly inoffensive.

Debugging the code again, we find that the borderSkin comparison still fails, but it doesn't matter since the application defines the style before first rendering; and any subsequent appearance of the component from within a module or anywhere else in the application inherits directly, and properly, from this definition.

Now the two components we needed to load — RichTextEditor and TabNavigator — in our modules are loaded and displayed without changing any application styles, hence no confounded flashing.

Thursday 6 March 2008

Swf fonts, flex and Unicode characters

If you have developed any scientific or mathematical applications you will know the headaches surrounding superscripts, subscripts and weird greek numerals etc in Flash or Flex. We have discovered a solution to some of these issues (well actually my good developer friend Thierry cracked this one but I thought it is worthy of a posting!)

Basically the situation is that you have found a good Unicode font that contains all the characters that you need to embed into a swf font for exporting into Flex. The problem you will encounter is that not all the characters end up being embeded even though they are included in the actual font. The font we have been using is Arial Unicode MS. I checked on windows using the character map to check whether the font contained the characters needed (which were all numerals sup and sub), it did but they weren't importing. The solution to this problem is fairly simple. What you need to do is add the characters you need to the Autofill box as shown below:

Here are the steps:
1. Go into character map in windows (programs/accessories/system tools/character map) choose the unicode font you want, in this case 'Arial Unicode MS'

2. Click on group by Unicode Subrange then choose super/subscript from the list that appears in the window, once you have selected that you will see the available characters in the main window.

3. Click on each character you need and click 'select' below this will add the selected character to the list.

4. Once you have selected the characters you want copy them all to the clipboard and paste them into a dynamic text box in flash.

5. Select the text box and click on 'embed' in the font properties window, then click on 'Auto Fill', this will add all the characters to the exported movie!

Hope that helps.

States, containers & design mode

Came across an annoying little glitch in flex builder today. If you have a basic application that say has 2 states and the base state contains a VBox componant, it can be difficult to add a new item to the VBox in the second state in design mode.

By default the VBox does not contain any height information, it just takes it's size from the items that are added to the cells of the container. In my application I have an HBox in the top cell and I wanted to add a label to the next VBox cell in the second state. What happens is that you cannot see any visual hint to show you that you are placing your item in the next cell of the VBox (this usually is shown by a blue horizontal line being displayed in the VBox when you drag an item into a potential cell area).

The solution is to go back to your Base State and give the VBox a height value, then go to the state you wish to add your item and you will now see a blue line appear. Once placed you will need to go back to your Base State and remove the height value.

Wednesday 5 March 2008

Flex 3 has arrived

Since this is my first post here I thought I would let you know that Adobe have now released Flex 3. After many months of beta testing (which was good as they allowed the community to beta test too) they have delivered what seems to be a nice application. On top of this, AIR v1.0 has also been released