Friday, March 30, 2012

PHP: Creating / Generating XML results

Despite with all the new web technologies around us, I guess that XML is something that wouldn't die out so easily. Especially that its a friendly file type that can be opened by different browsers and softwares. Ex: Mozilla Firefox, Google Chrome, Microsoft Excel, etc... Therefore I'm going to share an example using php that would display the results as a xml data.

But let me show you the codes first.

Here's a simple php file that contains the necessary functions.
<?php
 //Header needed to display content as xml
 header ("Content-Type:text/xml");

 //function to create xml node
 //if $hasIllegalCharacters is true, then we will use CDATA to wrap the node values
 function createNode($nameOfNode, $valueOfNode, $hasIllegalCharacters=true)
 {
  $result = "";
  $result .= "<" . $nameOfNode . ">";
  if($hasIllegalCharacters)
  {
   $result .= "<![CDATA[";
  }
  $result .= $valueOfNode;
  if($hasIllegalCharacters)
  {
   $result .= "]]>";
  }
  $result .= "</" . $nameOfNode . ">";
  return $result;
 }

 //function to save result as xml file
 function createAttachment($filename)
 {
  header('content-disposition: attachment; filename='.$filename.'.xml');
 }
?>

The following would be the source codes of the example
<?php
 //include the xml custon library
 include("php/library/xml/XmlMainClass.php");
  
 //Create the nodes and populate the nodes with data
 $message = createNode("message", 'Meow !@#$%^&*()-=_+{}[]\|:"'.";'<>?,./`~");
 $lat = createNode("lat", "1.281270");
 $lng = createNode("lng", "103.825318");
 $coordinates = createNode("coordinates", $lat . $lng, false);
 $country = createNode("country", "Singapore");
 $street = createNode("street", "Jalan Membina");
 $address = createNode("address", $street . $country . $coordinates, false);
 $dob = createNode("dob", "></></><");
 $age = createNode("age", "28++");
 $name = createNode("name", "nekyouto");
 $profile = createNode("profile", $name.$age.$dob.$address.$message, false);

 //Output the results
 echo $profile;
?>

A similar example to the previous one but this time round rather than displaying the results, it will create a downloadable xml file.
<?php
 //include the xml custon library
 include("php/library/xml/XmlMainClass.php");
  
 //Create the nodes and populate the nodes with data
 $message = createNode("message", "Meow !@#$%^&*()-=_+{}[]\|:\";'<>?,./`~");
 $lat = createNode("lat", "1.281270");
 $lng = createNode("lng", "103.825318");
 $coordinates = createNode("coordinates", $lat . $lng, false);
 $country = createNode("country", "Singapore");
 $street = createNode("street", "Jalan Membina");
 $address = createNode("address", $street . $country . $coordinates, false);
 $dob = createNode("dob", "></></><");
 $age = createNode("age", "28++");
 $name = createNode("name", "nekyouto");
 $profile = createNode("profile", $name.$age.$dob.$address.$message, false);

 createAttachment("profile");
 //Output the results
 echo $profile;
?>

* Click here to view the demo of the first example.
^ Click here to view the demo of the second example.
~ Click here for the source files of this demo.

Thursday, March 29, 2012

Fun with a NFC Android Phone

So you have got yourself a new Android NFC phone, so what's so great about this NFC capability? Firstly, I am not going to explain in depth about the NFC technology and this is something that you can google about. As for what can do with it... introducing an Android Application known as...


'FareBot'.
(Image taken from Google Play, previously known as Android Market.)

If you own one of the supported cards, you can use 'FareBot' to take at your remaining balance, recent transactions and some other informations about your card.
(Note: I was trying this with my Samsung Galaxy Nexus and it works. :D
Starting from today, I can check my ezlink transactions using my phone. :D
Time to say bye bye to the machines found at the MRT stations. :D)

Here's the list of cards that 'FareBot' currently supports:
  • ORCA - Seattle, WA, USA
  • Clipper - San Francisco, CA, USA
  • EZ-Link - Singapore
  • Suica/ICOCA/PASMO - Japan
  • MIFARE DESFire
  • CEPAS
  • FeliCa

And here's a simple step by step guide for 'FareBot'.
  1. Place your card on a flat surface.
  2. With your screen of your phone facing upwards, open the Android Application, 'FareBot'.
  3. Place the phone on top of your card and wait for a while.
Note: If the steps in the above doesn't work, try removing the phone casing and give it a try again.

Here's a video to guide you through the use of the Android APp.

* Click here to find out more about the Android App 'FareBot'.
^ Click here to find out more about NFC technology.
~ Click here to grab the latest list of NFC phones.

Friday, March 23, 2012

Flex 4: Auto Resize Text Area

In flex 4.0, you can easily create a resizeable text area by setting the property 'heightInLines' with a value of NaN. (I was pretty excited with this property and it really works.) But, when I update my flex version to 4.1 and beyond, this property doesn't really work as per what I had expected and after spending some time debugging and googling, it seems that this property has been ceased. Therefore I have created a temporary solution to a auto resize text area.

Sour codes for the resizeable Text Area Component:
<?xml version="1.0" encoding="utf-8"?>
<s:TextArea xmlns:fx="http://ns.adobe.com/mxml/2009" 
   xmlns:s="library://ns.adobe.com/flex/spark" 
   xmlns:mx="library://ns.adobe.com/flex/mx"
   width="0" height="0" 
    creationComplete="creationCompleteHandler(event)"
   widthInChars="1" heightInLines="1"
   change="changeHandler(event)"
      paddingBottom="2" paddingLeft="2" 
   paddingRight="2" paddingTop="2"
    borderVisible="false" contentBackgroundAlpha="0"
   selectable="false" editable="false" 
   initialize="initializeHandler(event)"
   verticalScrollPolicy="auto" horizontalScrollPolicy="auto">
 <fx:Script>
  <![CDATA[
   import flashx.textLayout.compose.TextFlowLine;
   import flashx.textLayout.conversion.TextConverter;
   import flashx.textLayout.edit.SelectionManager;
   import flashx.textLayout.elements.TextFlow;
   import flashx.textLayout.elements.TextRange;
   
   import mx.core.IUITextField;
   import mx.core.UIComponent;
   import mx.events.FlexEvent;
   
   import spark.components.RichEditableText;
   import spark.events.TextOperationEvent;
   import spark.utils.TextFlowUtil;
   
   //Variables to store the default width and height
   //of this textfield.
   private var _textWidth:Number = 0;
   private var _textHeight:Number = 0;
   
   private var _autoResizeH:Boolean = false;
   
   //Autoresize the height of the text
   //This property will be used to determine
   //whether u need to resize the height of this
   //textfield.
   public function get autoResizeH():Boolean
   {
    return _autoResizeH;
   }
   
   public function set autoResizeH(value:Boolean):void
   {
    _autoResizeH = value;
    if(_autoResizeH)
    {
     resizeContent();
    }
   }
   
   //Autoresize the width of the text
   //This property is pretty much redundant.
   private var _autoResizeW:Boolean = false;
   
   public function get autoResizeW():Boolean
   {
    return _autoResizeW;
   }
   
   public function set autoResizeW(value:Boolean):void
   {
    _autoResizeW = value;
    if(_autoResizeW)
    {
     resizeContent();
    }
   }
   
   //Autoresize the width and height of the text
   //This property will touch on both width and height
   //of this textfield. Rather than using
   //autoResizeW and autoResizeH, use this instead.
   private var _autoResize:Boolean = false;
   
   public function get autoResize():Boolean
   {
    return _autoResize;
   }
   
   public function set autoResize(value:Boolean):void
   {
    _autoResizeW = value;
    _autoResizeH = value;
    _autoResize = value;
    if(_autoResize)
    {
     resizeContent();
    }
   }
   
   //Override the default text function of a TextArea
   override public function set text(value:String):void
   {
    super.text = value;
    if(_autoResize)
    {
     resizeContent();
    }
   }
   
   //Create a new property for htmlText like what we have
   //in Flex 3.
   private var _htmlText:String = "";
   
   public function set htmlText(value:String):void
   {
    _htmlText = value;
    textFlow = TextConverter.importToFlow(value,
     TextConverter.TEXT_FIELD_HTML_FORMAT);
    if(_autoResize)
    {
     resizeContent();
    }
   }
   
   public function get htmlText():String
   {
    return _htmlText;
   }
   
   //This function will handle all the resizing.
   private function resizeContent():void
   {
    if(textFlow)
    {
     if(_autoResizeH && text != "" 
      && (_textHeight == 0 || isNaN(_textHeight)))
     {
      height = NaN;
      var tempToggle:Boolean = false;
      if(!editable)
      {
       tempToggle = true;
      }
      editable = true;
      textFlow.flowComposer.composeToPosition();              
      textFlow.flowComposer.updateAllControllers();
      if(tempToggle)
      {
       editable = false;
      }
      heightInLines = textFlow.flowComposer.numLines;
      validateNow();
     }
     if(_autoResizeW && text != "" 
      && (_textWidth == 0 || isNaN(_textWidth)))
     {
      width = NaN;
      typicalText = text;
      validateNow();
     }
    }else if(textDisplay){
     if(_autoResizeH && text != "" 
      && (_textHeight == 0 || isNaN(_textHeight)))
     {
      RichEditableText(textDisplay).height = NaN;
      RichEditableText(textDisplay).heightInLines = NaN;
      RichEditableText(textDisplay).validateNow();
      this.validateNow();
     }
     if(_autoResizeW && text != "" 
      && (_textWidth == 0 || isNaN(_textWidth)))
     {
      RichEditableText(textDisplay).width = NaN;
      RichEditableText(textDisplay).widthInChars = text.length;
      RichEditableText(textDisplay).validateNow();
      validateNow();
     }
    }
   }
   
   //On CreationComplete, check if resizing is needed.
   protected function creationCompleteHandler(event:FlexEvent):void
   {
    if(_autoResize)
    {
     resizeContent();
    }
   }
   
   //On Change, check if resizing is needed.
   protected function changeHandler(event:TextOperationEvent):void
   {
    if(_autoResize)
    {
     resizeContent();
    }
   }

   //Store the default width and height of this textfield.
   //Note: we need the default width and height when I'm
   //Resizing the Textfield, or when resizeContent() has
   //been executed.
   protected function initializeHandler(event:FlexEvent):void
   {
    if(width != _textWidth)
    {
     _textWidth = width;
    }
    if(height != _textHeight)
    {
     _textHeight = height;
    }
   }
  ]]>
 </fx:Script>
</s:TextArea>

And here's the source codes for my main application.
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
      xmlns:s="library://ns.adobe.com/flex/spark"
      xmlns:mx="library://ns.adobe.com/flex/mx"
      xmlns:CommonControls="CommonControls.*"
      viewSourceURL="srcview/index.html">
 <fx:Declarations>
  <!-- Place non-visual elements (e.g., services, value objects) here -->
 </fx:Declarations>
 <fx:Script>
  <![CDATA[
   //Dummy normal text
   [bindable]
   private var basicText:String = "Lorem ipsum dolor sit amet, " +
    "consectetur adipiscing elit. Fusce quis risus pellentesque " +
    "ipsum venenatis luctus a quis nulla. Cras rhoncus turpis " +
    "vel ligula iaculis sagittis. Donec eget dolor ac lectus " +
    "pharetra convallis et vitae eros. Pellentesque vestibulum " +
    "nisl ut dolor malesuada vel dictum sem ultricies. Ut " +
    "scelerisque mollis quam eu luctus. Curabitur erat massa, " +
    "accumsan sed adipiscing et, mollis quis lectus. Suspendisse " +
    "nec mauris quis mi varius ultricies at eleifend massa.";
   
   //Dummy HTML encoded text
   [bindable]
   private var specialText:String = "<b>Lorem ipsum dolor sit</b> " +
    "amet, <a target='_blank' href='http://www.google.com'>" +
    "consectetur</a> adipiscing elit. Fusce quis risus " +
    "pellentesque ipsum venenatis luctus a quis nulla. Cras " +
    "rhoncus turpis vel ligula iaculis sagittis. Donec eget " +
    "dolor ac lectus pharetra convallis et vitae eros. " +
    "Pellentesque vestibulum nisl ut dolor malesuada vel dictum " +
    "sem <b><a target='_blank' href='http://www.google.com'>" +
    "ultricies</a></b>. Ut scelerisque mollis quam eu luctus. " +
    "Curabitur erat massa, accumsan sed adipiscing et, mollis " +
    "quis lectus. Suspendisse nec mauris quis mi varius ultricies " +
    "at eleifend massa.";
  ]]>
 </fx:Script>
 <s:BorderContainer width="100%" height="100%">
  <s:layout>
   <s:VerticalLayout verticalAlign="middle" 
         horizontalAlign="center"
         gap="0"/>
  </s:layout>
  <s:BorderContainer width="100%">
   <s:layout>
    <s:HorizontalLayout verticalAlign="top" 
         horizontalAlign="left" 
         paddingLeft="2" 
         paddingRight="2"
         gap="0"/>
   </s:layout>
   <s:Label width="200" height="100%" 
      text="Basic Text with w='100%' h='100%' 
      and autoresize='true':" paddingTop="3"/>
   <CommonControls:CustomTextArea text="{basicText}"
             width="100%" 
             height="100%" 
             autoResize="true"/>
  </s:BorderContainer>
  <s:BorderContainer width="100%">
   <s:layout>
    <s:HorizontalLayout verticalAlign="top" 
         horizontalAlign="left" 
         paddingLeft="2" 
         paddingRight="2"
         gap="0"/>
   </s:layout>
   <s:Label width="200" height="100%" 
      text="Basic Text with w='350' h='100':" 
      paddingTop="3"/>
   <CommonControls:CustomTextArea text="{basicText}"
             width="350" 
             height="100" />
  </s:BorderContainer>
  <s:BorderContainer width="100%">
   <s:layout>
    <s:HorizontalLayout verticalAlign="top" 
         horizontalAlign="left" 
         paddingLeft="2" 
         paddingRight="2"
         gap="0"/>
   </s:layout>
   <s:Label width="200" height="100%" 
      text="Basic Text with w='350'
      and autoresize='true':" paddingTop="3"/>
   <CommonControls:CustomTextArea text="{basicText}"
             width="350" 
             autoResize="true"/>
  </s:BorderContainer>
  <s:BorderContainer width="100%">
   <s:layout>
    <s:HorizontalLayout verticalAlign="top" 
         horizontalAlign="left" 
         paddingLeft="2" 
         paddingRight="2"
         gap="0"/>
   </s:layout>
   <s:Label width="200" height="100%" 
      text="Html Text with w='100%' h='100%' 
      and autoresize='true':" paddingTop="3"/>
   <CommonControls:CustomTextArea htmlText="{specialText}"
             width="100%" 
             height="100%" 
             autoResize="true"/>
  </s:BorderContainer>
  <s:BorderContainer width="100%">
   <s:layout>
    <s:HorizontalLayout verticalAlign="top" 
         horizontalAlign="left" 
         paddingLeft="2" 
         paddingRight="2"
         gap="0"/>
   </s:layout>
   <s:Label width="200" height="100%" 
      text="Html Text with w='350' h='100':" 
      paddingTop="3"/>
   <CommonControls:CustomTextArea htmlText="{specialText}"
             width="350" 
             height="100" />
  </s:BorderContainer>
  <s:BorderContainer width="100%">
   <s:layout>
    <s:HorizontalLayout verticalAlign="top" 
         horizontalAlign="left" 
         paddingLeft="2" 
         paddingRight="2"
         gap="0"/>
   </s:layout>
   <s:Label width="200" height="100%" 
      text="Html Text with w='350'
      and autoresize='true':" paddingTop="3"/>
   <CommonControls:CustomTextArea htmlText="{specialText}"
             width="350" 
             autoResize="true"/>
  </s:BorderContainer>
 </s:BorderContainer>
</s:Application>

* Click here to view the demo of this example.
^ Click here for the source files of this demo.

Thursday, March 15, 2012

Flex: Drawing Shapes in Flex

Every single shape in this world are made out of simple shapes like circles, triangles and squares. Therefore, there might be situations where a coded shape or graphic can turn out to be much much more useful and flexible and lighter (in terms of the files size) than a normal image file(*.png, *.jpg, etc...). As for this week, I'm going to show you the steps in creating a simple Shape in flex.

Source codes for the main application
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" 
    layout="absolute"
     creationComplete="creationCompleteHandler(event)">
 <mx:Script>
  <![CDATA[
   import com.shapes.ShapeClass;
   
   import mx.core.UIComponent;
   import mx.events.FlexEvent;
   
   //Array to store a list of blue colors
   private var blueColorArray:Array = [0xFFFFFF, 0xEEEEFF, 
    0xDDDDFF, 0xCCCCFF, 0xBBBBFF, 0xAAAAFF,
    0x8888FF, 0x6666FF, 0x4444FF, 0x2222FF];
   private var blueColorCount:int = 0;
   
   //Array to store a list of black colors
   private var blackColorArray:Array = [0xFFFFFF, 0xCCCCCC, 
    0x999999, 0x666666, 0x333333, 0x000000];
   private var blackColorCount:int = 0;   
   
   //A timer that will be used to draw the Shapes
   //over and over again.
   private var timer:Timer = new Timer(100,0);
   
   protected function creationCompleteHandler(event:FlexEvent):void
   {
    timer.addEventListener(TimerEvent.TIMER, executeTimer);
    executeTimer();
   }
   
   //Function that will return an array of colors
   //based on the starting point, so that the Shapes
   //will appear to be animating
   private function getBlueColorsArray(tempColorArray:Array, 
            tempCount:int):Array
   {
    var tempArray:Array = new Array();
    for(var i:int = tempCount; 
     i < tempColorArray.length; i ++)
    {
     tempArray.push(tempColorArray[i]);
    }
    for(i = 0; i < tempCount; i ++)
    {
     tempArray.push(tempColorArray[i]);
    }
    return tempArray;
   }
   
   //This function will be trigger once the timer has 
   //run finish a cycle.
   private function executeTimer(event:Event = null):void
   {
    //Stops the timer first.
    if(timer.running)
    {
     timer.stop();
    }
    //Remove all the graphics and draw a new Shape
    layer1.removeAllChildren();
    layer1.addChild(ShapeClass.drawCircleTower(50, 
     getBlueColorsArray(blueColorArray, blueColorCount)));
    //Remove all the graphics and draw a new Shape
    layer2.removeAllChildren();
    layer2.addChild(ShapeClass.drawCircleTower(layer2.width, 
     getBlueColorsArray(blackColorArray, blackColorCount)));
    //As the shape is position at (0,0) we will need to
    //reassign the position of the shape everytime we draw
    //it so that the shape will always appear on the point
    //(10,10).
    layer3.removeAllChildren();
    var tempDisplayObject:DisplayObject;
    tempDisplayObject = layer3.addChild(
     ShapeClass.drawCircle(layer3.width/2,
     blueColorArray[Math.round(Math.random()*
      (blueColorArray.length - 1))],
     true));
    tempDisplayObject.x = layer3.width/2;
    tempDisplayObject.y = layer3.height/2;
    blueColorCount ++;
    if(blueColorCount >= blueColorArray.length)
    {
     blueColorCount = 0;
    }
    blackColorCount ++;
    if(blackColorCount >= blackColorArray.length)
    {
     blackColorCount = 0;
    }
    timer.start();
   }
   
  ]]>
 </mx:Script>
 <mx:Canvas width="100%" height="100%">
  <mx:VBox width="100%" height="100%" 
     verticalAlign="middle" 
     horizontalAlign="center">
   <mx:Canvas id="layer1"/>
  </mx:VBox>
  <mx:Canvas width="100%" height="100%">
   <mx:Canvas id="layer3"  
        width="150" height="150"
        top="10" left="10"/>
   <mx:Canvas id="layer2" 
        width="100" height="100"
        right="10" bottom="10"/>
  </mx:Canvas>
 </mx:Canvas>
</mx:Application>

Source codes for a Shape Class that I have written:
package com.shapes
{
 import flash.display.Shape;
 
 import mx.core.UIComponent;

 public class ShapeClass
 {
  public function ShapeClass()
  {
  }
  
  /**
   * 
   * @param radius - radius of the circle 
   * @param color - fill color of the circle
   * @param createView - do you need this function
   * to return a view that can be added to any view
   * or a Shape using (0,0) as the midpoint.
   * @return either a Shape or a View
   * 
   */  
  public static function drawCircle(radius:int, 
            color:uint,
            createView:Boolean = false):*
  {
   var shape:Shape = new Shape();
   shape.graphics.beginFill(color,1);
   shape.graphics.drawCircle(0,0,radius);
   shape.graphics.endFill();
   if(createView)
   {
    var tempUI:UIComponent = new UIComponent();
    tempUI.addChild(shape);
    return tempUI;
   }else{
    return shape;
   }
  }
  
  /**
   * 
   * @param radius - radius of the circle 
   * @param colors - an array of colors of this Shape
   * @return a view that shows a sequence of Circles
   * using (0,0) as the midpoint.
   * 
   */  
  public static function drawCircleTower(radius:int, 
              colors:Array):*
  {
   var length:int = colors.length;
   var diff:Number = radius / length;
   var tempUI:UIComponent = new UIComponent();
   var tempShape:Shape = null;
   for(var i:int = 0; i < length; i ++)
   {
    tempShape = drawCircle(radius - (i * diff),
     colors[i]);
    tempUI.addChild(tempShape); 
   }
   return tempUI;
  }
 }
}
* Click here to view the demo of this example.
^ Click here for the source files of this demo.

Friday, March 9, 2012

Flex: Smart way of Clipping Content

In flex, there are various situation where masking of a content is needed, but yet at the same time, rather than creating a separate Component to work as a mask, they is a property 'clipContent' that allows you to display part of a content too.

Rather than doing some crazy explanation, let us look at a simple demo.

The following would be the source code of the demo.
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" 
    layout="absolute"
    width="100%" height="100%"
    creationComplete="creationCompleteHandler(event)">
 
 <mx:Script>
  <![CDATA[
   import mx.events.FlexEvent;
   
   [Embed(source="../assets/image.jpeg")]
   [Bindable]
   public var imgCls:Class;
   
   //Here's the mouse Down handler for the red border box
   //at the same time allows it to be draggable around
   //the canvas
   protected function mouseDownHandler(event:MouseEvent):void
   {
    stage.addEventListener(MouseEvent.MOUSE_MOVE, mouseMoveEvent);
    stage.addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
    dragger.startDrag(false,
     new Rectangle(0,0,
      dragCanvas.width - dragger.width, 
      dragCanvas.height - dragger.height));
   }
   
   //Here's the mouse Up handler for the red border box
   //stops all the crazy dragging.
   protected function mouseUpHandler(event:MouseEvent):void
   {
    stage.removeEventListener(MouseEvent.MOUSE_MOVE, mouseMoveEvent);
    stage.removeEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
    dragger.stopDrag();
   }
   
   //Function to update the position of the main Image
   //base on the position of the draggable red border
   //box.
   private function mouseMoveEvent(event:Event):void
   {
    var maxX:int = dragCanvas.width - dragger.width;
    var maxY:int = dragCanvas.height - dragger.height;
    var minX:int = dragger.width;
    var minY:int = dragger.height;
    var currX:int = (dragger.x + dragger.width - minX);
    var currY:int = (dragger.y + dragger.height - minY);
    currX = Math.ceil((currX / maxX) * 100);
    currY = Math.ceil((currY / maxY) * 100);
    
    maxX = mainImg.width - mainCanvas.width;
    maxY = mainImg.height - mainCanvas.height;
    minX = mainCanvas.width;
    minY = mainCanvas.height;
    mainImg.x = currX * (maxX/100) * -1;
    mainImg.y = currY * (maxY/100) * -1;
   }
   
   protected function creationCompleteHandler(event:FlexEvent):void
   {
    mouseMoveEvent(null);
   }
   
  ]]>
 </mx:Script>
 <mx:HBox width="100%" height="100%"
    verticalAlign="middle" 
    horizontalAlign="center">
  <mx:Spacer width="100%"/>
  <mx:VBox height="100%"
     width="100%" 
     verticalAlign="middle" 
     horizontalAlign="center">
   <mx:HBox width="100%" horizontalAlign="center">
    <mx:Label text="Drag the red box around..."/>
   </mx:HBox>
   <mx:Canvas width="150" height="100"
        id="dragCanvas"
        verticalScrollPolicy="off" 
        horizontalScrollPolicy="off">
    <mx:Image source="{imgCls}" 
        width="150" height="100" 
        scaleContent="true" 
        maintainAspectRatio="true"/>
    <mx:Canvas backgroundAlpha="0"
         id="dragger"
         width="20"
         height="20"
         x="0" y="0"
         borderThickness="1"
         borderColor="#FF0000"
         borderStyle="solid"
         backgroundColor="#000000"
         mouseDown="mouseDownHandler(event)"
         mouseUp="mouseUpHandler(event)"/>
   </mx:Canvas>
   <mx:HBox width="100%" horizontalAlign="center">
    <mx:Label text="Clip Main Content?"/>
    <!-- Checkbox used to toggle the clipContent
     property of the main Canvas-->
    <mx:CheckBox id="chkClipContent" 
        selected="true"/>
   </mx:HBox>
  </mx:VBox>
  <mx:VBox width="100%" height="100%"
     verticalAlign="middle" 
     horizontalAlign="center">
   <mx:HBox width="100%" horizontalAlign="center">
    <mx:Label text="Selection is shown here."/>
   </mx:HBox>
   <mx:Canvas id="mainCanvas"
        verticalScrollPolicy="off" 
        horizontalScrollPolicy="off"
        width="80"
        height="80"
        clipContent="{chkClipContent.selected}">
    <mx:Image source="{imgCls}"
        x="0" y="0" id="mainImg"
        scaleContent="false"/>
    <mx:Canvas width="80"
         height="80"
         borderThickness="1"
         borderColor="#FF0000"
         borderStyle="solid"/>
   </mx:Canvas>
  </mx:VBox>
  <mx:Spacer width="100%"/>
 </mx:HBox>
</mx:Application>
* Click here to view the demo of this example.
^ Click here for the source files of this demo.

By the way the following URLs are pretty good in generating dummy contents.

Friday, March 2, 2012

Flex: Accessing a function of a loaded/embedded SWF file

Flex is pretty powerful when it comes to handling and displaying data, but there times when I would still prefer using the WYSIWYG interface of Flash Professional, especially when I just want to create a simple animation. Therefore, I shall show you my method of accessing the functions of a loaded SWF today.

Here's the code of the Main Flex Application.
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" 
    layout="absolute" 
    creationComplete="creationCompleteHandler(event)">
 <mx:Script>
  <![CDATA[
   import mx.events.FlexEvent;
   
   //Embed a swf file
   [Embed(source="../assets/simpleAnimation.swf")]
   private var simpleSWF:Class;
   
   //Assign the source of the SWFLoader to the embedded swf
   protected function creationCompleteHandler(event:FlexEvent):void
   {
    swfLoader2.source = simpleSWF;
   }
   
   //Upon clicking on the button, access the swf files that
   //are loaded in swfLoader and pass a parameter into the
   //functions in the swf file.
   //Note: SWF file must be exported in as3 otherwise it
   //don't work.
   protected function clickHandler(event:MouseEvent):void
   {
    var tempSWFLoader:* = getSWFLoaderContent(swfLoader1);
    tempSWFLoader["startMovie"](txtInput.text);
    tempSWFLoader = getSWFLoaderContent(swfLoader2);
    tempSWFLoader["startMovie"](txtInput.text);
   }
   
   //Function that will access the given SWFLoader component
   //and return a direct pointer to the swf file so that you
   //can gain access to the functions inside.
   private function getSWFLoaderContent(tempSWF:SWFLoader):*
   {
    var tempSWFContent:*;
    var tempSWFContent1:*;
    tempSWFContent1 = tempSWF.content;
    tempSWFContent = tempSWFContent1.getChildAt(0);
    tempSWFContent = tempSWFContent.content;
    if(tempSWFContent)
    {
     return tempSWFContent; 
    }else{
     return tempSWFContent1;     
    }
   }   
  ]]>
 </mx:Script>
 <mx:VBox width="100%" height="100%" 
     verticalAlign="middle" 
     horizontalAlign="center">
  <mx:HBox verticalAlign="middle"
      horizontalAlign="center"
      width="100%">
   <mx:Spacer width="100%"/>
   <!-- Load a SWF file on demand -->
   <mx:SWFLoader id="swfLoader1" 
       source="simpleAnimation.swf"/>
   <mx:Spacer width="100%"/>
   <mx:SWFLoader id="swfLoader2"/>
   <mx:Spacer width="100%"/>
  </mx:HBox>
  <mx:TextInput id="txtInput" text="5" restrict="0-9"/>
  <mx:Button id="btnAnimateNow" label="Animate Now!"
      click="clickHandler(event)"/>
 </mx:VBox>
</mx:Application>

And the script inside the SWF file that I am going to load.
In the 1st Frame
stop();
var count:Number;
function startMovie(tempNum)
{
 count = tempNum;
 init();
}

function stopMovie()
{
 this.gotoAndStop(1);
}

function init()
{
 if(count < 0)
 {
  movie_mc.text_txt.text = "";
  count = 0;
  stop();
 }else{
  movie_mc.text_txt.text = count;
  count --;
  this.gotoAndPlay(2);
 }
}
In the last Frame
init();
* Click here to view the demo of this example.
^ Click here for the source files of this demo.