Monday, August 25, 2008

Flex TabNavigator Image Snapshot Icons


Example files below illustrate generating thumbnail snapshots of tabs in a Flex TabNavigator. The thumbnails are shows as tab icons.
See this flexcoders thread.

ImgSnapshot.mxml - Main Application File:


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

<mx:Script>
<![CDATA[
import mx.events.IndexChangedEvent;
import mx.containers.TabNavigator;

private var tabNav:TabNavigator = new TabNavigator();

private function init():void
{
// tab1
var tabChild1:MyComponent = new MyComponent(0);
this.tabNav.addChild(tabChild1);

// tab2
var tabChild2:MyComponent = new MyComponent(1);
this.tabNav.addChild(tabChild2);

this.tabNav.percentHeight = 100;
this.tabNav.percentWidth = 100;
this.addChild(this.tabNav);
}
]]>
</mx:Script>

</mx:Application>

MyComponent Class - MyComponent.as:
package
{
import flash.events.Event;

import mx.charts.PieChart;
import mx.charts.series.PieSeries;
import mx.collections.ArrayCollection;
import mx.containers.HBox;
import mx.containers.TabNavigator;
import mx.core.Container;
import mx.events.FlexEvent;

public class MyComponent extends Container
{
private var box:HBox = new HBox();
private var chart:PieChart = new PieChart();
private var index:int;

public function MyComponent(indx:int)
{
super();

this.index = indx;
this.label = "Tab " + this.index;
this.percentHeight = 100;
this.percentWidth = 100;

this.addEventListener(FlexEvent.UPDATE_COMPLETE, updateComplete);
}

override protected function createChildren():void
{
super.createChildren();
this.box.addChild(this.getPie());
this.addChild(this.box);
}

override protected function updateDisplayList(
unscaledWidth:Number, unscaledHeight:Number):void
{
super.updateDisplayList(unscaledWidth, unscaledHeight);
this.box.setActualSize(unscaledWidth, unscaledHeight);
this.chart.setActualSize(unscaledWidth, unscaledHeight);
}

private function updateComplete(event:Event):void
{
var tabNav:TabNavigator = TabNavigator(this.parent);
if (this.width == 0 && this.height == 0) {
var selTab:MyComponent = MyComponent(tabNav.getChildAt(tabNav.selectedIndex));

this.width = selTab.width;
this.height = selTab.height;
this.updateDisplayList(selTab.width, selTab.height);

return;
}
if (this.icon == null)
this.icon = IconUtil.getIconClass(this, tabNav.getTabAt(this.index), 150, 100);
}

private function getPie():PieChart
{
chart.percentWidth = 100;
chart.percentHeight = 100;
chart.showDataTips = true;
chart.dataProvider = this.getChartDataProvider();

var series:PieSeries = new PieSeries();
series.nameField = "label";
series.field = "data";
series.filters = [];
chart.series = [series];

return chart;
}

private function getChartDataProvider():ArrayCollection
{
var arr:Array = [];
arr.push({label:"East", data:24});
arr.push({label:"West", data:32});
arr.push({label:"North", data:22});
arr.push({label:"South", data:11});
arr.push({label:"Texas", data:5});
return new ArrayCollection(arr);
}
}
}
IconUtil.as:
package
{
import flash.display.BitmapData;
import flash.events.Event;
import flash.geom.Matrix;
import flash.utils.Dictionary;

import mx.core.BitmapAsset;
import mx.core.UIComponent;
import mx.graphics.ImageSnapshot;

public class IconUtil extends BitmapAsset
{
private static var dictionary:Dictionary = new Dictionary(true);

public function IconUtil()
{
addEventListener(Event.ADDED, addedHandler, false, 0, true);
}

private function addedHandler(event:Event):void
{
if (this.parent == null)
return;

var value:Object = dictionary[this.parent];
if (value == null)
return;

this.bitmapData = value.src;
UIComponent(this.parent).invalidateSize();
}

public static function getIconClass(source:UIComponent, target:UIComponent,
width:int, height:int):Class
{
if (source.width <= 0 || source.height <= 0)
return null;

var scaleWidth:Number = width/source.width;
var scaleHeight:Number = height/source.height;
var mtrx:Matrix = new Matrix(scaleWidth, 0, 0, scaleHeight);
var bitmap:BitmapData = ImageSnapshot.captureBitmapData(source, mtrx);
dictionary[target] = {src:bitmap, w:width, h:height};

return IconUtil;
}
}
}