riaxe snippets
flex
Alive PDF from Flash Player 10 issue
Mar 7th
I had an issue generating PDF from dynamic components from Flex. I used a VBox and added buttons as child dynamically. I created pages each time a child is added and at the end generated the PDF. The PDF created blank pages. I posted the issue in Kalen Gibbons’ Blog. Thanks to Kalen……the issue was solved. I would like to share the code with all of you.
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical" initialize="initializeHandler()">
<mx:Script>
<![CDATA[
import mx.events.CloseEvent;
import mx.controls.Alert;
import org.alivepdf.saving.Download;
import org.alivepdf.images.ResizeMode;
import org.alivepdf.saving.Method;
import org.alivepdf.images.ImageFormat;
import org.alivepdf.pages.Page;
import org.alivepdf.display.*;
import org.alivepdf.layout.*
import org.alivepdf.pdf.PDF;
private var mPDF:PDF;
private var numChildrenToAdd:Number = 10;
private function initializeHandler():void{
//initialize PDF
mPDF = new PDF(Orientation.PORTRAIT, Unit.MM, Size.A4 );
mPDF.setDisplayMode( Display.FULL_PAGE, Layout.SINGLE_PAGE );
}
private function onPDFCreate():void
{
/* Kick off a loop of adding children to the vbox.
When the child is added, the updateComplete handler will add
a page to the PDF and add another button to the vbox, which will
trigger the updateComplete handler and start the loop over again...
until all children have been added. */
var btn:Button = new Button();
btn.label = 'Click 1';
vbox.addChild(btn);
}
private function updateHandler():void{
//get the current number of children
var currentChildren:int = vbox.numChildren;
if(currentChildren == 0){ return; }
//add new page
var newPage:Page = new Page( Orientation.PORTRAIT, Unit.MM, Size.A4 );
mPDF.addPage( newPage );
mPDF.addImage(vbox, 0, 0, 0, 0, ImageFormat.PNG, 100, 1 );
//keep the loop going until all children have been addded
if(currentChildren < numChildrenToAdd){
var btn:Button = new Button();
btn.label = 'Click '+ (currentChildren+1);
vbox.addChild(btn);
}else if(currentChildren == numChildrenToAdd){
//all children are added so it's okay to print now
//mPDF.save(Method.REMOTE, "http://kalengibbons.com/assets/pages/pdfCreator.cfm", Download.INLINE);
Alert.show('Do u wanna pdf?', 'PDF Creation', Alert.OK|Alert.CANCEL, this, alertListener, null, Alert.OK);
}
}
private function alertListener(vEvent:CloseEvent):void
{
if(vEvent.detail == Alert.OK){
var file:FileReference = new FileReference();
file.save(mPDF.save(Method.LOCAL), "Module.pdf.pdf");
}
}
]]>
</mx:Script>
<mx:VBox id="vbox" borderStyle="solid" borderColor="0xff00ff"
width="100%" height="100%" updateComplete="updateHandler()" />
<mx:Button id="btn" label="CreatePDF" click="onPDFCreate()"/>
</mx:Application>
Dynamic TextArea control that resizes with the text content
Feb 6th
I found myself quite helpless creating a custom TextArea control resize itself with the text content. I followed the docs, help, googled the web to find something called textHeight and textWidth properties of the TextArea but that was not enough because it doesn’t resize itself on initialisation according to the text available within itself. For resizing the text on initialisation, the text should be validated. I tried validateNow() for validating the text but that too didn’t work. For making it work I created a custom TextArea component in mxml with a StringValidator. I have also added the text formatting part from keyboard shortcuts into the code using a TextRange.
The working example for this can be found here.
Here’s the code for the above example:
<?xml version="1.0" encoding="utf-8"?>
<mx:TextArea xmlns:mx="http://www.adobe.com/2006/mxml"
htmlText="Welcome to Flex3.0" wordWrap="false" change="onValidation()"
verticalScrollPolicy="off" horizontalScrollPolicy="off"
height="22" width="108" creationComplete="init()"
keyDown="onKeyDown(event)" updateComplete="onValidation()">
<mx:Script>
<![CDATA[
import mx.controls.textClasses.TextRange;
private function init():void
{
this.validateNow();
}
private function onValidation():void
{
var metrics:TextLineMetrics = this.getLineMetrics(0);
this.width = this.textWidth + 10;
this.height = this.textHeight + 10;
this.verticalScrollPosition = 0;
this.horizontalScrollPosition = 0;
}
private function onKeyDown(e:KeyboardEvent):void
{
var tr:TextRange = new TextRange(this, true);
if(e.ctrlKey && e.keyCode == 66){
if(tr.fontWeight == "normal"){
tr.fontWeight = "bold";
}
else{ tr.fontWeight = "normal" }
}
if(e.ctrlKey && e.keyCode == 73){
if(tr.fontStyle == "normal"){
tr.fontStyle = "italic";
}
else{ tr.fontStyle = "normal" }
}
if(e.ctrlKey && e.keyCode == 85){
if(tr.textDecoration == "normal"){
tr.textDecoration = "underline";
}
else{ tr.textDecoration = "normal" }
}
}
]]>
</mx:Script>
<mx:StringValidator source="{this}" property="text"
minLength="10" valid="onValidation()"/>
</mx:TextArea>
Using mouse position from Javascript into Flex
Jan 29th
MouseEvents can be captured from Javascript and can be used for some amazing things in Flex. I have used ExternalInterface and FlexBridge to capture mouse positions from a html page to rotate a 3D Flex Cube as shown below:

The demo of the same can be seen here
The following javascript is used to capture the mouse move positions:
document.onmousemove = getMouseXY;
var flexApp;
// Temporary variables to hold mouse x-y pos.s
var tempX = 0
var tempY = 0
// Main function to retrieve mouse x-y pos.s
function initCallback() {
flexApp = FABridge.mousecapture.root()
alert("initCallback");
}
function getMouseXY(e) {
if (IE) { // grab the x-y pos.s if browser is IE
tempX = event.clientX + document.body.scrollLeft
tempY = event.clientY + document.body.scrollTop
} else { // grab the x-y pos.s if browser is NS
tempX = e.pageX
tempY = e.pageY
}
// catch possible negative values in NS4
if (tempX < 0){tempX = 0}
if (tempY < 0){tempY = 0}
// show the position values in the form named Show
// in the text fields named MouseX and MouseY
document.Show.MouseX.value = tempX
document.Show.MouseY.value = tempY
return true
}
function getMousex(){
return tempX
}
function getMousey(){
return tempY
}
The mouse positions can be recieved in Flex by calling getMousex() and getMousey() methods using External Interface.
Effective use of TextLineMetrics in Flex TextField components
Jan 29th
By Defination – The TextLineMetrics class contains information about the text position and measurements of a line of text within a text field. All measurements are in pixels. Objects of this class are returned by the flash.text.TextField.getLineMetrics() method.
While creating a text animation part for a application I faced the problem with the size of the individual characters in the TextField. The width and the height of the text characters inside the textfield differed from that of the actual size of the font as shown below :

One can see the final output of the demo part here
The code for the part is as below:
<?xml version="1.0" encoding="utf-8"?>
<mx:Label xmlns:mx="http://www.adobe.com/2006/mxml"
creationComplete="play()" fontSize="{size}" fontFamily="Arial"
text="7" textAlign="center" color="#F1E912" fontWeight="bold"
resizeEffect="{uResize}">
<mx:Script>
<![CDATA[
[Bindable]
public var size:int = 12;
[Bindable]
public var duration:int = 800;
public var initialSize:Number = 2;
public var rotateEnabled:Boolean = true;
public var fadeEnabled:Boolean = true;
public var scaleEnabled:Boolean = true;
public var delayCount:int = 0;
public function play():void
{
//setTextSize();
if(rotateEnabled){
uRotate.end();
uRotate.angleFrom = 0;
uRotate.angleTo = 360;
uRotate.play();
}
if(fadeEnabled){
uFade.end();
uFade.alphaFrom = 0;
uFade.alphaTo = 1;
uFade.play();
}
if(scaleEnabled){
uZoom.end();
uZoom.zoomHeightFrom = initialSize;
uZoom.zoomWidthFrom = initialSize;
uZoom.zoomHeightTo = 1;
uZoom.zoomWidthTo = 1;
uZoom.play();
}
}
public function setTextSize():void
{
var txtLineMetrics:TextLineMetrics = this.getLineMetrics(0);
if(text == ' '){
width = txtLineMetrics.width+size;
height = txtLineMetrics.height+size;
}
else{
width = txtLineMetrics.width+size/2;
height = txtLineMetrics.height+size/2;
}
}
public function stop():void
{
uRotate.stop();
uFade.stop();
}
]]>
</mx:Script>
<mx:Fade id="uFade" duration="{duration}" target="{this}" effectEnd="setTextSize()"/>
<mx:Rotate id="uRotate" duration="{duration}" target="{this}"
originX="{width/2}" originY="{height/2}" effectEnd="setTextSize()"/>
<mx:Resize id="uResize" duration="{duration}" target="{this}"/>
<mx:Zoom id="uZoom" duration="{duration}" target="{this}" effectEnd="setTextSize()"/>
</mx:Label>
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
creationComplete="init()" xmlns:comp="comp.*">
<mx:Script>
<![CDATA[
import comp.RotateText;
import mx.effects.Tween;
[Bindable]
private var mText:String = 'Hello World';
private var mTimer:Timer = new Timer(200);
private var count:int = 0;
private var mIsRotate:Boolean = true;
private var mIsScale:Boolean = true;
private var mIsFade:Boolean = true;
private function init():void
{
mTimer.addEventListener(TimerEvent.TIMER, onTimerStart);
}
private function onTextChange(e:Event):void
{
mText = e.target.text;
}
private function startAnimation(e:MouseEvent):void
{
mTimer.stop();
count = 0;
hb.removeAllChildren();
mTimer.start();
}
private function onTimerStart(e:TimerEvent):void
{
if(count < mText.length){
var rTxt:RotateText = new RotateText();
rTxt.duration = hsDur.value;
rTxt.text = mText.charAt(count);
rTxt.fadeEnabled = mIsFade;
rTxt.scaleEnabled = mIsScale;
rTxt.rotateEnabled = mIsRotate;
rTxt.size = hsSize.value;
rTxt.delayCount = count;
rTxt.initialSize = hsZoom.value;
hb.addChild(rTxt);
count++;
}
else{ mTimer.stop(); }
}
private function onDoubleClick(e:Event):void
{
txtInp.visible = !txtInp.visible;
hb.visible = !hb.visible;
}
]]>
</mx:Script>
<mx:Style>
@font-face {
src:url("assets/arial.ttf");
font-weight: normal;
font-style: normal;
font-family: Arial;
}
@font-face {
src:url("assets/arialbd.ttf");
font-weight: bold;
font-style: normal;
font-family: Arial;
}
</mx:Style>
<mx:Canvas y="177" x="441">
<mx:HBox id="hb" horizontalGap="{hs.value}" doubleClickEnabled="true"
doubleClick="onDoubleClick(event)"/>
<mx:TextInput id="txtInp" text="{mText}" fontSize="20" visible="false"
enter="onDoubleClick(event)"/>
</mx:Canvas>
<mx:Text text="{mText}" fontFamily="Arial" x="26" y="45"/>
<mx:TextInput text="{mText}" change="onTextChange(event)" x="26" y="71"/>
<mx:Button label="Animate" click="startAnimation(event)" x="26" y="101"/>
<mx:Rotate id="uRotate"/>
<mx:VBox x="26" y="149" width="171" height="279">
<mx:Label text="Horizontal Gap"/>
<mx:HSlider id="hs" minimum="-40" maximum="40"
snapInterval="5" liveDragging="true" enabled="true" showTrackHighlight="true"
showDataTip="false" value="0" tickInterval="5"/>
<mx:Label text="Font Size"/>
<mx:HSlider id="hsSize" minimum="8" maximum="76"
liveDragging="true" enabled="true" showTrackHighlight="true"
showDataTip="false" value="16" snapInterval="1"/>
<mx:Label text="Duration"/>
<mx:HSlider id="hsDur" minimum="100" maximum="2000" snapInterval="100" liveDragging="true" value="500" showTrackHighlight="true"/>
<mx:Label text="Initial Size"/>
<mx:HSlider id="hsZoom" minimum="0.1" maximum="4" snapInterval="0.1" liveDragging="true" showTrackHighlight="true"/>
<mx:HRule width="100%"/>
<mx:CheckBox label="Rotate" selected="true" change="{mIsRotate = !mIsRotate}"/>
<mx:CheckBox label="Scale" selected="true" change="{mIsScale = !mIsScale}"/>
<mx:CheckBox label="Fade" selected="true" change="{mIsFade = !mIsFade}"/>
</mx:VBox>
</mx:Application>
You will need to add the fonts arial.ttf and arailbd.ttf to the assets folder to make it work.
Hope this would be helpful

