Tuesday 13 December 2011

Adding Captcha in Flex !!!


public class Captcha extends Canvas
{
    private const CAPTCHA_WIDTH:uint = 120;
    private const CAPTCHA_HEIGHT:uint = 40;
    private var _securitycode:String;
 
    public function Captcha(type:String,counter:Number):void
    {
 
        // Set CAPTCHA Code
  _securitycode = randString(type, counter);
  generateDots();
  generatePolys(3);
  drawLines(0, 0, (CAPTCHA_WIDTH)-1, (CAPTCHA_HEIGHT)-1, 5, 5);
  displayCode(_securitycode);
  this.width = CAPTCHA_WIDTH;
  this.height = CAPTCHA_HEIGHT;
 this.horizontalScrollPolicy = "off";
  this.verticalScrollPolicy = "off";
 
        var largeMask:UIComponent = new UIComponent();
        largeMask.graphics.beginFill(0x00FFFF, 0.5);
        largeMask.graphics.drawRect(0, 0, CAPTCHA_WIDTH, CAPTCHA_HEIGHT);
        largeMask.graphics.endFill();
        largeMask.x = 0;
        largeMask.y = 0;
        this.addChild(largeMask);
  this.mask = largeMask;
    }
 
    // Generate random security code
    private function randString(type:String,counter:int):String
    {
  var i:int=1;
  var randStr:String="";
  var randNum:int=0;
  var useList:String="";
  var alphaChars:String="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
  var secure:String="!@$%&*-_=+?~";
  for (i = 1; i <= counter; i++) {
   if (type == "alphaChars") {
    useList=alphaChars;
   } else if (type == "alphaCharsnum") {
    useList=alphaChars+"0123456789";
   } else if (type == "secure") {
    useList=alphaChars+"0123456789"+secure;
   } else {
    useList="0123456789";
   }
 
   randNum=Math.floor(Math.random()*useList.length);
   randStr=randStr+useList.charAt(randNum);
  }
  return randStr;
    }
 
    // Generate Random Dots
    public function generateDots():void
    {
  for (var a:int=0; a < 1000; a++) {
   var tmpComponent:UIComponent = new UIComponent();
   var X:int = Math.floor(Math.random()*CAPTCHA_WIDTH);
   var Y:int = Math.floor(Math.random()*CAPTCHA_HEIGHT);
   tmpComponent.graphics.lineStyle(Math.floor(Math.random()*5),
                              RGBToHex(Math.floor(Math.random()*255),
                                                Math.floor(Math.random()*255),
                                                Math.floor(Math.random()*255)),
                              100);
   tmpComponent.graphics.moveTo(X, Y);
   tmpComponent.graphics.lineTo(X+1, Y);
   this.addChild(tmpComponent);
  }
    }
 
    // Converts color values from RGB to Hex
    private function RGBToHex (r:uint, g:uint, b:uint):uint {
  var hex:uint = r << 16 ^ g << 8 ^ b;
  return hex;
    }
 
    // Generate One Polygon
    private function generateOnePoly(sides:uint, radius:uint, color:uint):UIComponent {
        var tmpCmp:UIComponent = new UIComponent();
  var DSides:uint = Math.floor(360/sides);
        //Highest transparency is 100 - default is 50
  tmpCmp.graphics.beginFill(color, 50);
  var cnt:int = -1;
 
  while (++cnt < sides) {
   var X:int = Math.floor(radius*Math.sin(DSides*cnt/180*Math.PI));
   var Y:int = Math.floor(radius*Math.cos(DSides*cnt/180*Math.PI));
   if (!cnt) {
    tmpCmp.graphics.moveTo(X, Y);
   } else {
    tmpCmp.graphics.lineTo(X, Y);
   }
        }
  return tmpCmp;
    }
 
    public function generatePolys(no:uint):void
    {
  for (var i:uint = 0; i < no; i++) {
   var tmpComponent:UIComponent = new UIComponent();
   var tmpRadius:int = Math.floor(Math.random()*40)+10;
   tmpComponent = generateOnePoly(Math.floor(Math.random()*6)+3, tmpRadius,
                               RGBToHex(Math.floor(Math.random()*255),
                                                  Math.floor(Math.random()*255),
                                                  Math.floor(Math.random()*255)));
   tmpComponent.x = Math.floor(Math.random()*CAPTCHA_WIDTH);
   tmpComponent.y = Math.floor(Math.random()*CAPTCHA_HEIGHT);
   tmpComponent.rotation = Math.floor(Math.random()*360);
   tmpComponent.alpha = 0.3;
   this.addChild(tmpComponent);
        }
    }
 
    // Generate Background Lines
    private function drawLines(x:int, y:int, wi:int, hi:int, r:int, c:int):void {
  var tmpComponent:UIComponent = new UIComponent();
        // (width, 0xHEXCOLOR, transparency)
        tmpComponent.graphics.lineStyle(1, 0x333333, 100);
        var i:int = 0;
        var xd:Number = wi/c;
        var yd:Number = hi/r;
        for (i=0; i<= r; i++) {
            var yy:Number = y+i*yd;
            tmpComponent.graphics.moveTo(x+wi, yy);
            tmpComponent.graphics.lineTo(x, yy);
        }
        for (var j:int=0; j < c; j++) {
            var xx:Number = x+j*xd;
            tmpComponent.graphics.lineTo(xx, y);
            tmpComponent.graphics.lineTo(xx+xd, y+hi);
 
        }
        tmpComponent.graphics.lineTo(x+wi, y);
        this.addChild(tmpComponent);
    }
 
    private function displayCode(code:String):void
    {
        var tmpText:Label = new Label();
  tmpText.text = code;
  tmpText.width = CAPTCHA_WIDTH;
  tmpText.height = CAPTCHA_HEIGHT;
  tmpText.setStyle("fontSize",30);
  tmpText.setStyle("horizontalCenter",0);
  tmpText.setStyle("verticalCenter",0);
  this.addChild(tmpText);
    }
 
    public function get securitycode():String
    {
        return this._securitycode;
    }
}

The class can generate three types of captcha codes:

- alphaCharsnum

- secure: alphaCharsnum and also !@$%&*-_=+?~ chars

- default: numbers

To generate a captcha:
private var _captcha:Captcha = new Captcha("alphaChars",7);
To retrieve the generated code for comparison:
private var _securityCode:String = _captcha.securitycode;

Friday 14 October 2011

Format Date & Time


First you will need a DateFormatter

<mx:DateFormatter id="formatDateTime" formatString="EEEE, MMM. D, YYYY at H:NN:SS A"/>
[Bindable] private var time:String;
private var ticker:Timer;

public function showTime():void
{
var currentTime:Date = new Date();
this.time = formatDateTime.format(currentTime); 
this.ticker = new Timer(1,1);
this.ticker.addEventListener(TimerEvent.TIMER_COMPLETE, onTimerComplete);
this.ticker.start();
}
public function onTimerComplete(event:TimerEvent):void
{
showTime();


Pattern Example
Year
YY 09 (Year Number Short)
YYY 2009 (Year Number Full)
YYYY 02009 (I have no clue why you would need this)
Month
M 7 (Month Number Short)
MM 07 (Month Number Full)
MMM Jul (Month Name Short)
MMMM July (Month Name Full)
Day
D 4 (Day Number Short)
DD 04 (Day Number Full)
Day Name
E 1 (Day Number Short)
EE 01 (Day Number Full)
EEE Mon (Day Name Short)
EEEE Monday (Day Name Full)
A AM/PM
J Hour in day (0-23)
H Hour in day (1-24)
K Hour in AM/PM (0-11)
L Hour in AM/PM(1-12)
N 3 (Minutes)
NN 03 (Minutes)
SS 30 (Seconds)

Monday 19 September 2011

Restrict Popup Window Move


public function restrictPopUpMove(event:MoveEvent):void
{
var window:UIComponent = this ;
var mainWindowArg:DisplayObjectContainer = Application.application as DisplayObjectContainer;

if ((window.x + window.width) > mainWindowArg.width)
window.x = mainWindowArg.width - window.width;

if((window.y + window.height) > mainWindowArg.height)
window.y = mainWindowArg.height - window.height;

if(window.x < 0)
window.x = 0;

if(window.y < 0)
window.y = 0;

window.move(window.x, window.y);
}

Wednesday 14 September 2011

Popup Window with Spark (Solved Dragging Isuue)


package
{
import flash.events.Event;
import mx.core.FlexGlobals;
import mx.events.CloseEvent;
import mx.events.FlexEvent;
import mx.logging.ILogger;
import mx.managers.PopUpManager;
import spark.components.TitleWindow;
import spark.events.TitleWindowBoundsEvent;
/**
* This TitleWindow is designed so that the window cannot be dragged outside
* the boundaries of the application. This component is made to be opened with <code>PopUpManager</code>
* so that when it is closed, it will be removed from <code>PopUpManager</code>.
* @author rrubalcava
*/
public class PopUpWindow extends TitleWindow
{
public function PopUpWindow()
{
super();
this.addEventListener(FlexEvent.CREATION_COMPLETE, onCreationComplete_handler, false, 0, true);
this.addEventListener(CloseEvent.CLOSE, onCloseClicked_handler, false, 0, true);
this.addEventListener(TitleWindowBoundsEvent.WINDOW_MOVE, onTitleWindowMove_handler, false, 0, true);
}
/**
* Right position of window when it opens.
* @default
*/
public var popupRight:Number;
/**
* Left position of window when it opens.
* @default
*/
public var popupTop:Number;
/**
* X postion of window when it opens.
* @default
*/
public var popupX:Number;
/**
* Y postion of window when it opens.
* @default
*/
public var popupY:Number;
/**
* Will remove all elements and this window from <code>PopUpManager</code>.
* @param e
*/
protected function onCloseClicked_handler(e:CloseEvent):void
{
this.removeEventListener(CloseEvent.CLOSE, onCloseClicked_handler);
this.removeAllElements();
PopUpManager.removePopUp(this);
}
/**
* Will assign given position assignments when window is created.
* @param e
*/
protected function onCreationComplete_handler(e:FlexEvent):void
{
this.removeEventListener(FlexEvent.CREATION_COMPLETE, onCreationComplete_handler);
if (popupX > 0)
this.x = popupX;
else if (popupRight > 0)
this.right = popupRight;
if (popupY > 0)
this.y = popupY;
else if (popupTop > 0)
this.top = popupTop;
}
/**
* Repositions window so that it cannot be dragged outside of <code>Application</code> area.
* @param event
*/
protected function onTitleWindowMove_handler(event:Event):void
{
var w:Number = FlexGlobals.topLevelApplication["width"];
var h:Number = FlexGlobals.topLevelApplication["height"];
if (this.x < 0)
this.x = 5;
if (this.y < 0)
this.y = 5;
if (this.x > w - 25)
this.x = w - this.width;
if (this.y > h - 25)
this.y = h - this.height;
}
}
}

Auto Intelligent Combobox



package
{
import flash.events.Event;
import flash.events.KeyboardEvent;
import flash.events.TimerEvent;
import flash.ui.Keyboard;
import flash.utils.Timer;

import mx.controls.ComboBox;
import mx.utils.ArrayUtil;


public class ComboBoxItemRenderer extends ComboBox
{
//--------------------------------------------------------------------------
//
//  Constructor
//
//--------------------------------------------------------------------------

public function ComboBoxItemRenderer()
{
super();

_searchString = '';
_clearTimer = new Timer( 1000, 1 );
_clearTimer.addEventListener( TimerEvent.TIMER_COMPLETE, clearTimerCompleteHandler );
}

//--------------------------------------------------------------------------
//
//  Variables
//
//--------------------------------------------------------------------------

/**
* The string that is added to as the user types to use as the search string
*/
private var _searchString:String;

/**
* The timer that we use to clear the search string after a period of inactivity
*/
private var _clearTimer:Timer;

/**
* Keys we don't want to be bothered about handling
*/
private var _keysSuperHandles:Array = [ Keyboard.DOWN, Keyboard.UP, Keyboard.ESCAPE, Keyboard.ENTER, Keyboard.PAGE_UP, Keyboard.PAGE_DOWN ];

/**
* Used to keep track of whether we're inside the keyDownHandler or not, this
* allows us to stop the close() method from executing (default behaviour on
* selecting an item) when we're selecting an item as type.
*/
protected var _selectingItemAsTyping:Boolean = false;

//--------------------------------------------------------------------------
//
//  Properties
//
//--------------------------------------------------------------------------

/**
* The time, in milliseconds, of keyboard inactivity before the search string
* is reset
*
* @tiptext Time, in milliseconds, of keyboard inactivity before the search string is reset
* @default 1000
*/
public var inactivityResetTimeout:int = 1000;

//--------------------------------------------------------------------------
//
//  Methods
//
//--------------------------------------------------------------------------

/**
* Override the close function to take account of us changing
* the selected item (see keyDownHandler & _foxyInKeyDown)
*
* @see mx.controls.ComboBox::close()
*/
override public function close(trigger:Event = null):void
{
if( !_selectingItemAsTyping )
{
super.close();
}
}

//--------------------------------------------------------------------------
//
//  Overridden event handlers
//
//--------------------------------------------------------------------------

override protected function keyDownHandler(event:KeyboardEvent):void
{
var tmpCode:int = event.keyCode;
/*
* Note: In an ideal world the best place to do this work would be within a sub class
* of the List, but for some reason if the user doesn't open the drop down and
* starts typing (e.g. tabs to the ComboBox and starts typing) then the ComboBox
* keeps getting a new List from the factory. This stops us from keeping any sort
* of state within our List sub class, and having the feature only when the user
* has opened the drop down AND typed while it's open is not really very nice.
*
* So rather than going into overkill, by sub classing a few things and overriding
* far much more than I would like to, this compromise seemed the best option.
*/
if( ArrayUtil.getItemIndex( tmpCode, _keysSuperHandles ) != -1 )
{
// it's one of the keys we don't want to handle, let the parent handle it
super.keyDownHandler( event );
}
else if(( tmpCode >= 33 && tmpCode <= 126 ) || tmpCode == Keyboard.SPACE )
{
// Internally the ComboBox uses a private variable called
// bInKeyDown to make sure not to close the dropdown (if open)
// in this situation (where we have changed the selected item
// ourselves), we have to do something similar with a variable
// we have access to (see the overridden close() method for more details)
_selectingItemAsTyping = true;

// it's one of the keys we want to handle
_searchString += String.fromCharCode( tmpCode );

// backup the selected index incase the findString doesn't find any matches
var prevSelectedIndex:int = dropdown.selectedIndex;

// reset the selectedIndex stops from cycling through values as your typing, e.g.
// if there were the values united kingdom and united states then while typing united
// the selected item would cycle between the two (which isn't very attractive)
dropdown.selectedIndex = -1;

var matchedString:Boolean = dropdown.findString( _searchString );

if( !matchedString )
{
// if we didn't find a match we put the selection back to where it was
// as it was us that removed the selection (when we set it to -1 above)
dropdown.selectedIndex = prevSelectedIndex;
}

// kick off the clear timer
_clearTimer.reset();
_clearTimer.start();

_selectingItemAsTyping = false;
}
else
{
/*
it's another key that we don't care about (but not one we've explicitally
said we don't care about), so let the parent handle it
*/
super.keyDownHandler( event );
}
}

//--------------------------------------------------------------------------
//
//  Event handlers
//
//--------------------------------------------------------------------------

private function clearTimerCompleteHandler( event:TimerEvent ):void
{
this._searchString = '';
}

}
}

How to keep dragged TitleWindow within Flex Application Boundary

package
{
import flash.events.Event;
import flash.events.MouseEvent;
import flash.geom.Rectangle;

import mx.containers.Canvas;
import mx.containers.TitleWindow;
import mx.events.CloseEvent;
import mx.managers.PopUpManager;

public class AdvancedTitleWindow extends TitleWindow
{
private var titleBarOverlay:TitleWindow;

public function AdvancedTitleWindow()
{
super();
}

override protected function createChildren():void
{
super.createChildren();

if(!this.titleBarOverlay)
{
this.titleBarOverlay = new TitleWindow();
this.titleBarOverlay.width = this.width;
this.titleBarOverlay.height = this.titleBar.height;

this.titleBarOverlay.showCloseButton = true;
this.titleBarOverlay.addEventListener(CloseEvent.CLOSE, onClose);

rawChildren.addChild(this.titleBarOverlay);
}

addDragEventListeners();
}

override protected function updateDisplayList(unscaledWidthArg:Number, unscaledHeightArg:Number):void
{
super.updateDisplayList(unscaledWidthArg, unscaledHeightArg);

this.titleBarOverlay.width = this.width;
this.titleBarOverlay.height = this.titleBar.height;
}

private function addDragEventListeners():void
{
this.titleBarOverlay.addEventListener(MouseEvent.MOUSE_DOWN, onTitleBarPress, false, 0, true);
this.titleBarOverlay.addEventListener(MouseEvent.MOUSE_UP, onTitleBarRelease, false, 0, true);
}

private function onTitleBarPress(mouseEventArg:MouseEvent):void
{
// Here you can set the boundary using owner, parent, parentApplication, etc.
this.startDrag(false, new Rectangle(0, 0, parent.width - this.width, parent.height - this.height));
}

private function onTitleBarRelease(mouseEventArg:MouseEvent):void
{
this.stopDrag();
}

private function onClose(closeEventArg:CloseEvent):void
{
PopUpManager.removePopUp(this);
}
}
}

Thursday 23 June 2011

Library Files Used in Google 3D Map

The List of .swc Library Files used in Google Map Application are:
map_1_9.swc
map_flex_1_20.swc
map_flex_1_8b.swc
GoogleMapsAPIUtilityLibrary_01262009.swc



Title Window Direction


<?xml version="1.0" encoding="utf-8"?>
<utils:TitleWindowWpath xmlns:mx="http://www.adobe.com/2006/mxml"
xmlns:mapDesign="com.mapDesign.*" xmlns:local="*"
xmlns:mapPAttern="com.mapPAttern.*" xmlns:utils="utils.*"
       layout="vertical" horizontalScrollPolicy="off" verticalScrollPolicy="off"
       width="500" height="500" titleStyleName="titleText" 
      backgroundColor="#ffffff" backgroundAlpha="1" color="#333333" 
       borderAlpha=".9" cornerRadius="0" dropShadowEnabled="true" 
       shadowDistance="3" shadowDirection="left" showCloseButton="true" 
       close="onTitleWindowClose(event)" creationComplete="centerMe()">

    <mx:Script>
        <![CDATA[
            import mx.core.Application;
            import mx.events.CloseEvent;
            import mx.managers.PopUpManager;
            import mx.printing.*;


            private function onTitleWindowClose(evt:CloseEvent):void
{
            PopUpManager.removePopUp(this);
            }

private function doPrint():void 
{
                var printJob:FlexPrintJob = new FlexPrintJob();

                if (printJob.start() != true)
return;

                printJob.addObject(textCanvas, FlexPrintJobScaleType.SHOW_ALL);
                printJob.send();
}
                
            public function centerMe():void
{
            this.x = ((Application.application.stage.stageWidth)/2) - (this.width/2);
            this.y = ((Application.application.stage.stageHeight)/2) - (this.height/2);
            }
        ]]>
    </mx:Script>


<mx:Canvas id="textCanvas" width="100%" height="100%" horizontalScrollPolicy="off" verticalScrollPolicy="off" backgroundColor="#ffffff" backgroundAlpha="1">
<mx:TextArea width="95%" height="95%" htmlText="{this.path}" top="40" horizontalCenter="0"/>
</mx:Canvas>

<mx:Button id="print" label="Print Directions" click="doPrint()" bottom="0" right="0"/>


</utils:TitleWindowWpath>

Title Window


package utils
{
import mx.containers.TitleWindow;


public class TitleWindowWpath extends TitleWindow
{
public function TitleWindowWpath()
{
super();

}
[Bindable]
public var path:String="";
}
}

Tile Loader Timer


package utils
{
import com.google.maps.MapEvent;
import com.google.maps.controls.ControlBase;
import com.google.maps.controls.ControlPosition;
import com.google.maps.interfaces.IMap;

import flash.events.Event;
import flash.geom.Point;
import flash.utils.getTimer;

/**
* A basic timer control that shows elapsed time between TILES_LOADED_PENDING
* and TILES_LOADED events.
*/
public class TileLoadTimer extends ControlBase 
{
/**
* Radius of the timer dial.
*/
private static const RADIUS:Number = 25;

/**
* getTimer()'s value when TILES_LOADED_PENDING was first received, or 0
* if we are not timing.
*/
private var startTimer:int;

/**
* getTimer()'s value when we most recently were timing. 3 seconds after
* timing we reset the max elapsed time indicator back to 0.
*/
private var activityTimer:int;

/**
* Elapsed milliseconds since we started timing.
*/
private var elapsed:int;

/**
* Maximum recent value of elapsed milliseconds.
*/
private var elapsedMax:int;

/**
* Constructs a new TileLoadTimer.
* @constructor
*/
public function TileLoadTimer()
{
super(new ControlPosition(ControlPosition.ANCHOR_BOTTOM_RIGHT, 45, 45));
}

/**
* Sets the instance of the map that the control operates on.
* Normally invoked from the call to Map.addControl().
* @param map  Map interface
*/
public override function initControlWithMap(map:IMap):void
{
super.initControlWithMap(map);
map.addEventListener(MapEvent.TILES_LOADED_PENDING, onTilesLoadedPending);
map.addEventListener(MapEvent.TILES_LOADED, onTilesLoaded);
map.addEventListener(Event.ENTER_FRAME, onEnterFrame);
startTimer = 0;
}

/**
* Called on each frame. Updates the timing variables and draws the dial.
* @param event Event that triggered this call.
*/
private function onEnterFrame(event:Event):void
{
var timerNow:int = getTimer();
if (startTimer) {
activityTimer = timerNow;
elapsed = timerNow - startTimer;
if (elapsed > elapsedMax) {
elapsedMax = elapsed;
}
} else {
if (timerNow - activityTimer > 3000) {
elapsedMax = 0;
}
}
graphics.clear();
graphics.beginFill(0x006633);
graphics.drawRect(-RADIUS - 2, -RADIUS - 2,
RADIUS * 2 + 4, RADIUS * 2 + 4);
graphics.endFill();
drawDialArc(elapsed, 0x00CC99);
drawDialLine(elapsedMax, 0x009900);
}

/**
* Draws a filled arc on the dial.
* @param angle Angle (in units of 0.001 radians).
* @param color Fill color.
*/
private function drawDialArc(angle:Number, color:uint):void 
{
graphics.beginFill(color);
graphics.moveTo(0, 0);
for (var i:int = 0; i <= angle; i += 10) {
var p:Point = getPointOnCircle(i);
graphics.lineTo(p.x, p.y);
}
graphics.endFill();
}

/**
* Draws a line on the dial.
* @param angle Angle (in units of 0.001 radians).
* @param color Line color.
*/
private function drawDialLine(angle:Number, color:uint):void
{
var end:Point = getPointOnCircle(angle);
graphics.lineStyle(2, color);
graphics.moveTo(0, 0);
graphics.lineTo(end.x, end.y);
}

/**
* Returns the location of a point on the edge of the dial.
* @param angle Angle (in units of 0.001 radians).
* @return Point on the edge of the dial.
*/
private static function getPointOnCircle(angle:Number):Point
{
var radians:Number = angle / 1000.0;
return new Point(RADIUS * Math.sin(radians),
-RADIUS * Math.cos(radians));
}

/**
* Handles TILES_LOADED_PENDING. Starts the timer if it is not already
* running.
* @param event Event that triggered this call.
*/
private function onTilesLoadedPending(event:MapEvent):void
{
if (!startTimer) {
startTimer = getTimer();
}
}

/**
* Handles TILES_LOADED. Stops the timer and resets the elapsed time.
* @param event Event that triggered this call.
*/
private function onTilesLoaded(event:MapEvent):void
{
startTimer = 0;
elapsed = 0;
}
}
}