Monday, January 31, 2011

Localizing Flex application preloader

Recently there was a request to localize labels on preloader of Flex application, such as "Initializing" and "Loading":



First of all I've provided modification for HTMl content page to path needed parameters with "FlashWars":

AC_FL_RunContent(
"src", "${swf}",
"width", "${width}",
"height", "${height}",
"align", "middle",
"id", "${application}",
"quality", "high",
"bgcolor", "${bgcolor}",
"name", "${application}",
"wmode", "transparent",
"FlashVars", "initLabel=Init Some Application&downloadLabel=Downloading Some Application",
"allowScriptAccess","sameDomain",
"type", "application/x-shockwave-flash",
"pluginspage", "http://www.adobe.com/go/getflashplayer",
"allowFullScreen", "true"
);


Populating "FlashVars" can be done dynamically for example if you have JSP page. In such case you can access needed bundle and get corresponding labels:

"FlashVars", "initLabel=<%= localizedInitLbl%>&downloadLabel=<%= localizedDownloadLbl%>"

Next step is to create custom preloader for your application and use it. Custom preloader is set to Flex application in next way:

<:mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
preloader="com.somecompany.preloader.DownloadProgressBarCustom">


Code of preloader is next:

package com.somecompany.preloader
{
import flash.events.Event;
import flash.geom.Rectangle;

import mx.preloaders.DownloadProgressBar;

public class DownloadProgressBarCustom extends DownloadProgressBar
{
public function DownloadProgressBarCustom()
{
super();
// Clear the initialization label till translation is received.
initializingLabel = "";
// Clear download label till translation is received.
downloadingLabel = "";
// Set the minimum display time to 5 seconds (for testing only).
//MINIMUM_DISPLAY_TIME = 5000;

this.addEventListener(Event.ADDED_TO_STAGE, addToStageHandler);
}

// Need to get parameters for label translation.
private function addToStageHandler(e:Event):void
{
//more safe to remove EventListener than using weak reference
this.removeEventListener(Event.ADDED_TO_STAGE, addToStageHandler);

var params:Object = this.stage.loaderInfo.parameters;
initializingLabel = params.hasOwnProperty("initLabel") ? params.initLabel : "Initializing";
downloadingLabel = params.hasOwnProperty("downloadLabel") ? params.downloadLabel : "Loading";

}

// More space for text.
override protected function get labelRect():Rectangle
{
return new Rectangle(5, 17, 170, 16);
}
}
}


Main idea is listen to "Added To Stage" event to have access to "FlashVars" with help of loaderInfo instance.

As result, you will have custom message on preloader:

Flex: White color issue with "wmode" set to "transparent" under 16-bit color depth

Recently I've faced with pretty strange issue in Flash Player. Our application written in Flex was using "wmode" parameter set to "transparent" in params for embeding flash to HTML:

AC_FL_RunContent(
"src", "${swf}",
"width", "${width}",
"height", "${height}",
"align", "middle",
"id", "${application}",
"quality", "high",
"bgcolor", "${bgcolor}",
"name", "${application}",
"allowScriptAccess","sameDomain",
"wmode","transparent",
"type", "application/x-shockwave-flash",
"pluginspage", "http://www.adobe.com/go/getflashplayer"
);


Issue was related to rendering labels with white color when user had set up 16-bit color depth:


Example of code in Flex is pretty simple:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">

<mx:VBox>
<mx:Label text="Some Label" color="#FFFFFF" fontFamily="Arial" fontSize="14" fontWeight="bold" />
<mx:Text text="Some Text" color="#FFFFFF" fontFamily="Arial" fontSize="14" fontWeight="bold" />

</mx:VBox>

</mx:Application>


After some investigation, solution was found - I've used "cacheAsBitmap" property set to "true" for text and label. After that issue vanished:

<mx:Label text="Some Label" cacheAsBitmap="true" color="#FFFFFF" fontFamily="Arial" fontSize="14" fontWeight="bold" />
<mx:Text text="Some Text" cacheAsBitmap="true" color="#FFFFFF" fontFamily="Arial" fontSize="14" fontWeight="bold" />


As result text and label was rendered correctly: