Flex tutorial: Enabling track pad (mouse wheel) scrolling on Mac OS X for Flex 4
March 17, 2010It’s been quite a while since I last worked on Flex after I became a Web Evangelist at Microsoft where I’m spending most of my time working on Silverlight (a very awesome technology too). Recently, I was working on a pet project using Flex 4 (to keep up with my Flex skill), and sadly despite all the new features, mouse wheel/track pad scrolling on the Mac OS is still not supported out-of-the-box. All the previous implementations by the Flash community doesn’t work on Flex 4 if you using the viewport approach introduced in the new version. So I decided to modify the codes in my previous post, and here you go… : )
Demo/Source codes:
Trackpad/Mousewheel Scrolling on Mac for Flex 4 (view source is enabled….because sharing is caring)
I also took an extra to tweak the scrolling speed for various browser… let me know if it’s not working well in a particular browser.
Flex tutorial: Convert unicode (UTF16) to text, and vice verse
February 27, 2009In contrary to most mashup api services that uses UTF8, Twitter returns non-Latin characters encoded in UTF16. After googling, seems like many people have issues with converting UTF16 encoded characters to proper text and vice verse. There might be other better ways, but here’s what I have done. Feel free to comment.
A UTF converter that I always used is this.
Demo:
Unicode Converter (view source enabled)
Source Codes
Right-click on application to view source.
Flex tutorial: Popup warning before browser closes
February 16, 2009As the title implies, this post will show you how to ask for user confirmation before the browser window closes or navigated away from the current url.
We will make use of the onbeforeunload event in javascript. So first of all, you will need to insert the following into index.template.html.
<script language="JavaScript" type="text/javascript">
window.onbeforeunload = function()
{
var swfApp = ${application};
return swfApp.onCloseApplication();
}
</script>
The all you need is to add a callback function onCloseApplication in your main application (see codes below).
Demo:
Application Exit Warning (view source enabled)
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"
creationComplete="onCreationComplete()">
<mx:Script>
<![CDATA[
private function onCreationComplete() : void
{
if ( ExternalInterface.available )
{
ExternalInterface.addCallback( "onCloseApplication",
function():String
{
if ( chkDisplayMessage.selected )
{
return txtMsg.text;
}
return null;
} );
}
}
]]>
</mx:Script>
<mx:CheckBox
id="chkDisplayMessage"
x="37" y="29"
label="Display message upon application exit"/>
<mx:Label x="37" y="59" text="Message:"/>
<mx:TextInput
id="txtMsg"
x="104" y="57"
text="Please don't close me."/>
<mx:Label x="37" y="107" color="#666666" text="*Check on the above checkbox, then close/navigate away from the current url."/>
</mx:Application>
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>
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>
Flex tutorial: Movable/Draggable window
January 30, 2009My very first assignment as a Flex developer back in 2007 was to create a UI for a web-based instant messaging application. Since a user can open multiple chat windows, I needed to make those windows movable. After Googling I can’t find any hints, but after some trial and errors, I manage to get it worked.
Recently, someone was asking me about similar issue, so I though I’d post it here and share with anyone that need this.
Demo:
Movable 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.core.UIComponent;
private var _window : UIComponent;
private var _originalPosition : Point;
private var _mouseDownPosition : Point;
private function onTitleBarMouseDown( 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, doMoving, true );
this.systemManager.addEventListener( MouseEvent.MOUSE_UP, doCommitMove, true );
// 3. save offsets
_originalPosition = new Point( _window.x, _window.y );
_mouseDownPosition = new Point( event.stageX, event.stageY );
}
private function doMoving( event : MouseEvent ) : void
{
// 1. prevent any other mouse up events to happen
event.stopImmediatePropagation();
// 2. calculate new position
var positionToMove : Point = new Point( _originalPosition.x + ( event.stageX - _mouseDownPosition.x ),
_originalPosition.y + ( event.stageY - _mouseDownPosition.y ) );
// 3. move window
_window.move( positionToMove.x, positionToMove.y );
}
private function doCommitMove( event : MouseEvent ) : void
{
// 1. prevent any other mouse up events to happen
event.stopImmediatePropagation();
// 2. remove event listeners
this.systemManager.removeEventListener( MouseEvent.MOUSE_MOVE, doMoving, true );
this.systemManager.removeEventListener( MouseEvent.MOUSE_UP, doCommitMove , true );
}
]]>
</mx:Script>
<mx:Canvas
x="37" y="31" width="245" height="156"
borderColor="#999999" backgroundColor="#FFFFFF" borderStyle="solid" dropShadowEnabled="true" borderThickness="2">
<!-- Title Bar-->
<mx:Canvas
x="0" y="0" width="100%" height="35"
backgroundColor="#B1DAFA"
mouseDown="onTitleBarMouseDown( event )">
<mx:Label x="10" y="7" text="Title" fontSize="14"/>
</mx:Canvas>
<!-- Instruction -->
<mx:Label x="27" y="73" text="Drag the title bar to move" fontSize="14"/>
</mx:Canvas>
</mx:Application>
This blog is powered by WordPress with GimpStyle Theme design by Horacio Bella.




