June 9th, 2010
Hi, we started making one of the our largest AIR projects with Flex SDK 3.5 version, but we had some problem while scrolling for example with mouse wheel or even more serious bug like: sometimes while resizing window or changing size of some block during runtime(for example HDivideBox) , application stops respond for any user action and we were seeing a wheel of death. I did not remember exactly why, but tried to compile application with Flex SDK 4, and some bugs are gone. So I recommend you to use Flex SDK 4 with compile option ” -compatibility-version=3.0″, you should use compatible mode with version three to compile your old projects with Flex SDK 4, as version 4 has some new architect structure and you wont wanna fix whole code by hands to make it works with Flex SDK 4.
February 26th, 2010
Hi, for example you have few components on the stage and you want to run different effects on them. So lets imagine we have label1, label2 and label3 and we want for example make label1 move to some place and after that animation is finished we will fade out label2 and label3 simultaneously.
So we can use Sequence and Parallel effects in Flex, to do this see code below:
<mx:Sequence >
<mx:Move target="{label1}" yTo="0" duration="1500" />
<mx:Parallel duration="2000">
<mx:Fade target="{label2}" alphaTo="0" />
<mx:Fade target="{label3}" alphaTo="0" />
</mx:Parallel>
</mx:Sequence>
So why I’m telling this ? This is very simple, but there is a trick you always should use there this syntax target=”{…}” instead of target=”…” other way it wont work and you will be getting Error #1006 Value is not function.
February 24th, 2010
If you want define size of component in percent during runtime you should user properties percentWidth and percentHeight (adobe docs)
February 21st, 2010
Hi, yesterday I was looking for fast answer on question “Can I have sub-menu for context menu in my adobe AIR application ?” Could not fast quick answer on 1st google page, with code example or explanation. It’s can be confusing cause actually Flex Web-based application can not implement context sub-menu, but in AIR application you can and it’s very simple! So I hope this post will be displayed on google 1st page when somebody will type similar question above.
So how to make it ?
First we need create our context menu:
var myContextMenu:ContextMenu = new ContextMenu();
Make our application use this contex menu:
this.contextMenu = myContextMenu;
Then we need to add some menu items for it:
var menuItem1:ContextMenuItem = new ContextMenuItem('Menu 1');
var menuItem2:ContextMenuItem = new ContextMenuItem('Menu 12);
Now will assign this items to our context menu:
// we should assign array of items to customItems property of the context menu
myContextMenu.customItems = [menuItem1, menuItem2 ];
For now you’ll see context menu consists from two items on right click. Now we will add nested sub-menu.
Again we need to create context menu with items:
var subMenuItem1:ContextMenuItem = new ContextMenuItem('Sub-Menu 1');
var myContextSubMenu:ContextMenu = new ContextMenu();
myContextSubMenu.customItems = [subMenuItem1];
And now magic line that will assign our context sub-menu to one of main context-menu items:
menuItem1.submenu = myContextSubMenu;
So all about this property submenu that enable for AIR but not for Flex.
Btw to run some action when click for some menu item you can use code below:
subMenuItem1.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, menuItemClick);
private function menuItemClick(event:Event):void{
Alert.show('TADA');
}
You can download simple source code.
February 14th, 2010
Hi, guys. In Flex we often should use different kind of list and selection of multiple items little bit complex there, you should press CTRL(win) or COMMAND(mac os) button and then select items one by one. But what if you want select multiple items from list like you select icons on your desktop ?
For this we need our list, in this example i will use TileList and we need Canvas(we can customize it in whatever way we want). Canvas and TileList should be in one container.
Before starting i should admit that we can use two ways of items selection: first one is select all items that are inside our selection rectangle, second is select items when they intersects with selection rectangle. From experience for first one way, we should to reduce bounds of item to make it selection little bit easier, it will looks like on the picture below

But in demo you can see using of second way.
So every selection should start with mouse button down:
private function mouseDownS(event:MouseEvent):void{
// start selection only if we clicked on our List(not outside or it's items)
if(event.target.parent != tileList)
return;
//storing point from where we will start selection
selectionRectRightBottom = new Point(event.localX, event.localY);
// disable interactions with all childrens(items) of list
tileList.mouseChildren = false;
// show our canvas rect
selectRectCanvas.visible = true;
selectRectCanvas.width = 0;
selectRectCanvas.height = 0;
// this is array for storing rectangles(bounds) of items for further comparing them and selection
// but we will make them little bit smaller to make their selection easier
animatedGridItemsRect = new Array();
// we should use this value if we will select items when they whole inside selection rectangle
// if we will select items that will be selected just while intersection with selection rectangle this value should be 0
var RECT_PADDING_DELTA:Number = 0;
var count:int = tileList.dataProvider.length;
for(var i:int = 0; i < count; i++){
var data:Object = new Object();
var rendererRect:Rectangle = tileList.indexToItemRenderer(i).getRect(tileList);
rendererRect.x += RECT_PADDING_DELTA;
rendererRect.y += RECT_PADDING_DELTA;
rendererRect.width -= RECT_PADDING_DELTA * 2;
rendererRect.height -= RECT_PADDING_DELTA * 2;
// here is we storing item data + item reducedd bounds
data.rect = rendererRect;
data.item = tileList.indexToItemRenderer(i).data;
animatedGridItemsRect.push(data);
}
}
then continue selection when mouse moving:
private function mouseMoveS(e:MouseEvent):void{
if(!selectionRectRightBottom)
return;
// end-poing of our selection rectangle
selectionRectLeftTop = new Point(tileList.mouseX, tileList.mouseY);
// calculating selection rectangle height and width
var selectionRectWidth:Number = -selectionRectRightBottom.x + selectionRectLeftTop.x;
var selectionRectHeight:Number = -selectionRectRightBottom.y + selectionRectLeftTop.y;
// set selection rect canvas size and position
selectRectCanvas.width = selectionRectWidth;
selectRectCanvas.height = selectionRectHeight;
selectRectCanvas.x = selectionRectRightBottom.x + tileList.x;
selectRectCanvas.y = selectionRectRightBottom.y + tileList.y;
// getting Rectangle instance of selection canvas
var selectRect:Rectangle = selectRectCanvas.getRect(tileList);
// actually array that will contain indecies of newly selected items
var newSelectedIndicies:Array = new Array();
var i:int = 0;
for each(var itemData:Object in animatedGridItemsRect){
// we should use this line if we will select items when they whole inside selection rectangle
//if(selectRect.containsRect(Rectangle(itemData.rect)))
// we should use this line if we will select items that will be selected just while intersection with selection rectangle
if(selectRect.intersects(Rectangle(itemData.rect)))
newSelectedIndicies.push(i);
i++;
}
tileList.selectedIndices = newSelectedIndicies;
// force list to refresh
tileList.invalidateDisplayList();
// call this for forcing flash to handle all stuff above after every mouse move
e.updateAfterEvent();
}
and ends when mouse up:
private function mouseUpS():void{
// if mouse up, then restore all states
selectionRectRightBottom = null;
selectionRectLeftTop = null;
tileList.mouseChildren = true;
selectRectCanvas.visible = false;
animatedGridItemsRect = null;
}
Source code and demo
February 6th, 2010
Quick tip:
Did you set component’s cornerRadius to some value bigger then zero and expect corners to be rounded but it does not work ? Simply just set style borderStyle of that component to solid.
February 4th, 2010
I’v spent a lot of time today trying to solve one issue. I had TileList and was using custom itemrenderer to display list’s item. My item-renderer had some textfields and image.
Issue: while dragging list’s item – image inside this draggable stuff does not displays. Was trying a lot of different ways, custom TileLists, dragProxies etc, no luck.
So how turned up, problem was with loading this image after dragImage created, actually image seems to be loading, but! does not displays. So solution of this nightmare below:
1. Open custom item-renderer component mxml file
2. find your image tag, and change it to looks like this:
<mx:Image complete="thumbImageLoadComplete(event)" source="{data['thumb']}" width="64" height="64" id="img" scaleContent="true" horizontalCenter="0" />
where is source=”{data['thumb']}” image source that accept url to image(data['thumb']) and complete=”thumbImageLoadComplete(event)” event handler while image loading complete
3. Add this code
private function thumbImageLoadComplete(event:Event):void{
var bp:Bitmap=dupeImage(img.content as Bitmap);
img.source = bp;
data['thumb'] = dupeImage(bp);
}
private function dupeImage(source:Bitmap):Bitmap {
var data:BitmapData = Bitmap(source).bitmapData;
var bitmap:Bitmap = new Bitmap(data);
return bitmap;
}
override public function set data(value:Object):void{
super.data = value;
if(data['thumb'] is Bitmap)
data['thumb'] = dupeImage(data['thumb']); // we should copy bitmap itself everytime data changes, for example while filtering
}
Where dupeImage is function that returns copied Bitmap from image content (source.content), in thumbImageLoadComplete we assign newly copied Bitmap to image source (img.source). And now attention!
data['thumb'] = dupeImage(img);
This line reassign data source value and assign Bitmap (copy of our image) instead using URL to image. Now i should to explain why we made this. By default TileList class using this class ListItemDragProxy for displaying stuff when drag items. If you’ll look inside this class you can see it create instances from your custom itemrenderer class and assign them the same values as in original items. So in code above we force images to use image Bitmap instead or url for loading image.
In this way we solve two problems – first is enabling image displaying(visible) while dragging item, second is preventing image loading second time(bandwidth & time saving)
data['thumb'] = dupeImage(img);