Flex tutorial: Setting tile image as background
February 9, 2009This tutorial shows you how to fill a Canvas background with repeated images. We will make use of the BitmapData.draw() function to achieve this. Note that if the image to be repeated is from another domain (i.e. a cross domain image), you have to ensure that the domain has a cross domain policy file, and you have to set checkPolicyFile=true in order to get it working. Otherwise, you will get a security sandbox error. More explanation here.
Demo:
Tile Image Background (view source enabled)
Source Codes: main application
<?xml version="1.0" encoding="utf-8"?>
<mx:Application
xmlns:mx="http://www.adobe.com/2006/mxml"
xmlns:alekkus="com.alekkus.*"
layout="absolute"
backgroundColor="#F8F8F8">
<mx:Script>
<![CDATA[
import mx.controls.Image;
private function onClick() : void
{
// 1. for crossdomain images, we need to create a LoaderContext object and set its checkPolicyFile to true.
var loaderContext : LoaderContext = new LoaderContext ();
loaderContext.checkPolicyFile = true;
// 2. assign that loaderContext object to an Image object
var image : Image = new Image();
image.loaderContext = loaderContext;
// 3. set source and load
image.source = "http://alekkus.com/flex3/extra/images/duck.jpg"
image.addEventListener( Event.COMPLETE, onImageLoaded );
image.load();
}
private function onImageLoaded( event : Event ) : void
{
var image : Image = Image( event.currentTarget );
// 1. set as tile image background
cvsMain.setTileImage( image );
}
]]>
</mx:Script>
<alekkus:TileImageCanvas id="cvsMain" width="100%" height="100%" />
<mx:Button x="10" y="10" label="Set background as tile image" click="onClick()" />
</mx:Application>
Source Codes: TileImageCanvas class
<?xml version="1.0" encoding="utf-8"?>
<mx:Canvas
xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:Script>
<![CDATA[
import mx.controls.Image;
private var _image : Image = null;
public function setTileImage( image : Image ) : void
{
this._image = image;
this.invalidateDisplayList();
}
override protected function updateDisplayList( unscaledWidth : Number, unscaledHeight : Number ) : void
{
super.updateDisplayList(unscaledWidth, unscaledHeight );
if ( _image != null )
{
var bitmap : Bitmap = Bitmap( _image.content );
var bitmapData : BitmapData = new BitmapData( bitmap.width, bitmap.height );
bitmapData.draw( bitmap );
graphics.clear();
graphics.beginBitmapFill( bitmapData );
graphics.drawRect(0, 0, unscaledWidth, unscaledHeight);
graphics.endFill();
}
}
]]>
</mx:Script>
</mx:Canvas>
Flex tutorial: Enabling track pad or mouse wheel scrolling on Mac OS X
February 5, 2009A couple of months back when Steve Jobs announced the new unibody MacBook Pro, I couldn’t resist and decided to switched to Mac. As I was settling in to the new OS, I was surprised when I learned that Flex applications do not support track pad (or mouse wheel) scrolling on the Mac OS X. This issue has been filed in the Adobe bug system, but they have yet to resolved it.
Good news is, Gabriel Bucknall has came out with an elegant solution. It’s built upon SWFObject, basically a small Javascript file used to embed Flash content (read my post on using SWFObject to embed Flash content here).
Here’s what you need to get it working using Flex Builder:
- Embed your Flash content using the SWFObject method. (see previous post)
- Include “swfmacmousewheel2.js” file into the “html-template” folder
- Replace the codes within “index.template.html” file with the codes below
- Lastly, in your application add the line “MacMouseWheel.setup( this.stage );” within the application’s addedToStage event listener
Note: If are trying this out on your local machine, you may get a security sandbox violation error #2060. You need to deploy it on a local/remote web server to get it working. I can’t find a way to get around this. Tried including crossdomain policy file, changing the params value when embedding, and tweaking the compiler options but to no luck. Let me know if anyone found a solution to this.
Demo:
Trackpad/Mousewheel Scrolling on Mac (view source enabled)
Source Codes: index.template.html
<!-- saved from url=(0014)about:internet -->
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<link rel="stylesheet" type="text/css" href="history/history.css" />
<title>${title}</title>
<script src="AC_OETags.js" language="javascript"></script>
<script src="history/history.js" language="javascript"></script>
<style>
body { margin: 0px; overflow:hidden }
</style>
</head>
<body scroll="no">
<script type="text/javascript" src="swfobject.js"></script>
<script type="text/javascript" src="swfmacmousewheel2.js"></script>
<script type="text/javascript">
var flashVars = {};
var params = { play: "true",
loop: "false",
quality: "high",
wmode: "window",
allowscriptaccess: "sameDomain" };
var attributes = { id: "${application}" };
swfobject.embedSWF( "${swf}.swf",
"divContent",
"100%", "100%",
"9.0.0",
"expressInstall.swf",
flashVars,
params,
attributes );
swfmacmousewheel.registerObject( attributes.id );
</script>
<div id="divContent">
<h1>Alternative content</h1>
<p><a href="http://www.adobe.com/go/getflashplayer"><img src="http://www.adobe.com/images/shared/download_buttons/get_flash_player.gif" alt="Get Adobe Flash player" /></a></p>
</div>
</body>
</html>
Source Codes: main application
<?xml version="1.0" encoding="utf-8"?>
<mx:Application
xmlns:mx="http://www.adobe.com/2006/mxml"
layout="absolute"
backgroundColor="#F8F8F8"
addedToStage="onAddedToStage()">
<mx:Script>
<![CDATA[
import com.pixelbreaker.ui.osx.MacMouseWheel;
private function onAddedToStage() : void
{
if ( this.stage != null )
{
MacMouseWheel.setup( this.stage );
}
}
]]>
</mx:Script>
<mx:Canvas x="28" y="26" width="239" height="332" backgroundColor="#C6DFF6">
<mx:Text
x="10" y="10"
width="201"
text="The quick brown fox jumps over the lazy dog quick brown fox jumps over the lazy dog..... and then, the quick brown fox jumps over the lazy dog....and then, the quick brown fox jumps over the lazy dog....and then, the quick brown fox jumps over the lazy dog....and then, the quick brown fox jumps over the lazy dog....and then, the quick brown fox jumps over the lazy dog....and then, the quick brown fox jumps over the lazy dog....and then, the quick brown fox jumps over the lazy dog....and then, the quick brown fox jumps over the lazy dog....and then, the quick brown fox jumps over the lazy dog"
fontSize="18"/>
</mx:Canvas>
<mx:Label x="28" y="366" text="Place your cursor within the canvas and scroll using the mouse wheel or trackpad." fontSize="12"/>
</mx:Application>
Flex tutorial: Embedding Flash content with SWFObject 2
February 4, 2009If you are building your Flash content with Flex Builder 3 or Flash CS3, you will see that both came with a default HTML template that provides a way to embed your compiled SWF file. Although there’s nothing wrong with that way of doing it, SWFObject seems to be a better way (the author’s explanation is here). In fact in the CS4 release, Adobe has made this the standard way of embedding Flash content.
To manually work with SWFObject in Flex Builder, replace the codes in “html-template/index.template.html” with the codes below. Then place the following files into the “html-template” folder.
- swfobject.js
- expressInstall.swf
The files are available here, or you can download the my source files to get those files.
[update] If you are using Flex SDK 3.1 and below, deep linking (more specifically, the BrowserManager class) may not work with SWFObject. If that happens, simply replace the codes in the “history.js” file with this
Demo:
SWFObject 2 (view source enabled)
Source Codes:
<!-- saved from url=(0014)about:internet -->
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<link rel="stylesheet" type="text/css" href="history/history.css" />
<title>${title}</title>
<script src="AC_OETags.js" language="javascript"></script>
<script src="history/history.js" language="javascript"></script>
<style>
body { margin: 0px; overflow:hidden }
</style>
</head>
<body scroll="no">
<script type="text/javascript" src="swfobject.js"></script>
<script type="text/javascript">
var flashVars = {};
var params = { play: "true",
loop: "false",
quality: "high",
wmode: "window",
allowscriptaccess: "sameDomain" };
var attributes = { id: "${application}" };
swfobject.embedSWF( "${swf}.swf",
"divContent",
"100%", "100%",
"9.0.0",
"expressInstall.swf",
flashVars,
params,
attributes );
</script>
<div id="divContent">
<h1>Alternative content</h1>
<p><a href="http://www.adobe.com/go/getflashplayer"><img src="http://www.adobe.com/images/shared/download_buttons/get_flash_player.gif" alt="Get Adobe Flash player" /></a></p>
</div>
</body>
</html>
Flex tutorial: URL-based navigation using Deep Linking
February 3, 2009One of the best new features in Flex 3 is Deep Linking. By default, a Flex application is accessible via one URL; that poses several limitations on the users. Firstly, the browser back/forward buttons no longer works the usual way. Secondly, consider an ecommerce site, if a user wants to show his/her friends a particular product information, he/she can no longer simply give out the url, as the the url will always show the default state/page of the application.
The following shows you how to solve these issues by using the BrowserManager class.
Demo:
Deep Linking (view source enabled)
Source Codes:
<?xml version="1.0" encoding="utf-8"?>
<mx:Application
xmlns:mx="http://www.adobe.com/2006/mxml"
layout="absolute"
backgroundColor="#F8F8F8"
creationComplete="onCreationComplete()">
<mx:Script>
<![CDATA[
import mx.events.ItemClickEvent;
import mx.containers.Canvas;
import mx.events.BrowserChangeEvent;
import mx.managers.BrowserManager;
import mx.managers.IBrowserManager;
private var _browserManager : IBrowserManager = null;
private function onCreationComplete() : void
{
// 1. add browserManager event listeners here
_browserManager = BrowserManager.getInstance();
_browserManager.addEventListener( BrowserChangeEvent.BROWSER_URL_CHANGE, onURLChange ); //dispatch when user typed into addr bar
_browserManager.addEventListener( BrowserChangeEvent.APPLICATION_URL_CHANGE, onURLChange ); //necessary to update the url in address bar when gotoURL called has a same base url, orignially used to dispatch when setFragment is called although not use for that purpose. now setFragent is used again.
_browserManager.init( "" );
// 2. explicitly call process url if fragment is empty when loaded
if ( _browserManager.fragment == "" )
{
onURLChange();
}
}
private function onURLChange( event:BrowserChangeEvent = null ) : void
{
switch ( _browserManager.fragment.toLowerCase() )
{
case "about":
{
_browserManager.setTitle( "About us | Alekkus.com" );
vsMain.selectedIndex = 1;
break;
}
case "contact":
{
_browserManager.setTitle( "Contact us | Alekkus.com" );
vsMain.selectedIndex = 2;
break;
}
default:
{
_browserManager.setTitle( "Home | Alekkus.com" );
vsMain.selectedIndex = 0;
}
}
}
private function onChildIndexChange( event : ItemClickEvent ) : void
{
var canvasLabel : String = Canvas( vsMain.getChildAt( event.index ) ).label;
_browserManager.setFragment( canvasLabel.toLowerCase() );
}
]]>
</mx:Script>
<mx:LinkBar x="10" y="10" dataProvider="{ vsMain }" itemClick="onChildIndexChange( event )"/>
<mx:ViewStack
id="vsMain"
x="0" y="36"
width="252" height="177">
<!-- Home -->
<mx:Canvas
label="Home"
width="100%" height="100%">
<mx:Label text="Home page" x="10" y="10" fontSize="28"/>
</mx:Canvas>
<!-- About us -->
<mx:Canvas
label="About"
width="100%" height="100%">
<mx:Label text="About us" x="10" y="10" fontSize="28"/>
</mx:Canvas>
<!-- Contact us -->
<mx:Canvas
label="Contact"
width="100%" height="100%">
<mx:Label text="Contact us" x="10" y="10" fontSize="28"/>
</mx:Canvas>
</mx:ViewStack>
<!-- Instructions -->
<mx:Label x="10" y="224" text="*Notice that the url changes when you navigate thru different pages."/>
<mx:Label x="10" y="250" text="*You can also use the browser back/forward button to navigate."/>
<mx:Label x="10" y="276" text="*Manually typing in the url also works. e.g. .http://alekkus.com/...#contact"/>
</mx:Application>
Fiat’s Eco:Drive AIR Application at Adobe Max 2008/09
February 1, 2009During the Adobe Max 2008/09 in Milan, team members from AKQA demonstrated a very interesting AIR application, the Fiat’s Eco:Drive.

The concept of Eco:Drive is explained here:
Serge Jespers and Andrew Shorten had an interview with the team after that. You can watch the interview here.
Flex tutorial: Resizable window
February 1, 2009Often, a movable/draggable window is also resizable. The following will show you how to make your customized window resizable.
Demo:
Resizable Window (view source enabled)
Source Codes:
<?xml version="1.0" encoding="utf-8"?>
<mx:Application
xmlns:mx="http://www.adobe.com/2006/mxml"
layout="absolute"
backgroundColor="#F8F8F8">
<mx:Script>
<![CDATA[
import mx.events.FlexEvent;
import mx.core.UIComponent;
private var _window : UIComponent;
private var _originalWidth : Number;
private var _originalHeight : Number;
private var _mouseDownPosition : Point;
private function onResizeMouseDown( event : MouseEvent ) : void
{
// 1. set _window
_window = UIComponent( UIComponent( event.currentTarget ).parent );
// 2. add mouse move and mouse up event listeners
this.systemManager.addEventListener( MouseEvent.MOUSE_MOVE, onResizeMouseMove, true );
this.systemManager.addEventListener( MouseEvent.MOUSE_UP, onResizeMouseUp, true );
// 3. save original width, height, rotation
_originalWidth = _window.width;
_originalHeight = _window.height;
// 4. save mouse down position
_mouseDownPosition = new Point( event.stageX, event.stageY );
}
private function onResizeMouseMove( event : MouseEvent ) : void
{
// 1. prevent any other mouse up events to happen
event.stopImmediatePropagation();
// 2. calculate new width, height
var newWidth:Number = _originalWidth + ( event.stageX - _mouseDownPosition.x );
var newHeight:Number = _originalHeight + ( event.stageY - _mouseDownPosition.y );
// 3. resize window
_window.setActualSize( newWidth, newHeight );
}
private function onResizeMouseUp( event : MouseEvent ) : void
{
// 1. prevent any other mouse up events to happen
event.stopImmediatePropagation();
// 2. remove event listeners
this.systemManager.removeEventListener( MouseEvent.MOUSE_MOVE, onResizeMouseMove, true );
this.systemManager.removeEventListener( MouseEvent.MOUSE_UP, onResizeMouseUp , true );
}
private function doDrawTriangle( event : FlexEvent ) : void
{
var uiComp : UIComponent = UIComponent( event.currentTarget );
uiComp.graphics.clear();
uiComp.graphics.beginFill( 0xB1DAFA );
uiComp.graphics.moveTo( uiComp.width, 0 );
uiComp.graphics.lineTo( uiComp.width, uiComp.height );
uiComp.graphics.lineTo( 0, uiComp.height );
}
]]>
</mx:Script>
<mx:Canvas
id="cvsMain"
x="37" y="31" width="260" height="160"
borderColor="#999999" backgroundColor="#FFFFFF" borderStyle="solid" dropShadowEnabled="true" borderThickness="2"
horizontalScrollPolicy="off" verticalScrollPolicy="off">
<!-- Resize triangle -->
<mx:UIComponent
x="{ cvsMain.width - 24 }" y="{ cvsMain.height - 24 }"
width="20" height="20"
creationComplete="doDrawTriangle( event )"
mouseDown="onResizeMouseDown( event )" />
<!-- Instruction -->
<mx:Label x="16" y="59" text="Drag the blue triangle to resize" fontSize="14"/>
</mx:Canvas>
</mx:Application>
This blog is powered by WordPress with GimpStyle Theme design by Horacio Bella.




