package tink.graphics { import flash.display.BitmapData; import flash.display.Graphics; import flash.geom.Matrix; public class CloneableGraphics { private var _graphics:Graphics; private var _clone:Array; /** * Constructor. */ public function CloneableGraphics( graphics:Graphics = null ):void { if( graphics ) _graphics = graphics; initialize(); } /** * Initializes the class by creating an Array to store all the drawing methods that take place. */ private function initialize():void { _clone = new Array(); } /** * Creates a CloneableGraphicsVO instance. * This object stores the method name as a String and the arguments as an Array. * * Each instance is then push into a Array. */ private function createStep( method:String, arguments:Array ):void { var vo:CloneableGraphicsVO = new CloneableGraphicsVO(); vo.method = method; vo.arguements = arguments; _clone.push( vo ); } /** * This is where the re-drawing takes place. * The method String is evaluated and then invoked in the switch statement, passing the correct parameters. */ private function invokeStep( step:Object ):void { var vo:Object = step; var method:Function = _graphics[ vo.method ]; method.apply( this, vo.arguements ); } /** * Concat * * Joins the Array of CloneableGraphicsVO instances with another Array of CloneableGraphicsVO instances * that were created in another CloneableGraphics instance. */ public function concat( concat:Array ):void { _clone = _clone.concat( concat ); var iterations:int = concat.length; for( var i:int = 0; i < iterations; i++ ) { invokeStep( concat[ i ] ); } } /** * Setter for graphics object * * Sets the Graphics instances to invoke the drawing methods on. */ public function set graphics( graphics:Graphics ):void { _graphics = graphics; } /** * Getter/Setters for cloning * * Get * Returns an Array of CloneableGraphicsVO instances created in tthe instance of this class. * * Set * Clears the current Graphics instance and Array storing CloneableGraphicsVO instances by invoking 'clear()'. * Then invokes 'concat()' passing the Array of CloneableGraphicsVO instance passed to the setter. */ public function get clone():Array { return _clone; } public function set clone( clone:Array ):void { clear(); concat( clone ); } /** * Graphics methods. * * Duplication of all public drawing methods of the Graphics class. * * Each invokes the drawing method on the reference Graphics instance, * then invokes 'createStep' passing the method (callee) name, and the arguments passed. */ public function beginBitmapFill( bitmap:BitmapData, matrix:Matrix = null, repeat:Boolean = true, smooth:Boolean = false ):void { _graphics.beginBitmapFill( bitmap, matrix, repeat, smooth ); createStep( "beginBitmapFill", arguments ); } public function beginFill( color:uint, alpha:Number = 1.0 ):void { _graphics.beginFill( color, alpha ); createStep( "beginFill", arguments ); } public function beginGradientFill( type:String, colors:Array, alphas:Array, ratios:Array, matrix:Matrix = null, spreadMethod:String = "pad", interpolationMethod:String = "rgb", focalPointRatio:Number = 0 ):void { _graphics.beginGradientFill(type, colors, alphas, ratios, matrix, spreadMethod, interpolationMethod, focalPointRatio ); createStep( "beginGradientFill", arguments ); } public function clear():void { _graphics.clear(); _clone = new Array(); } public function curveTo( controlX:Number, controlY:Number, anchorX:Number, anchorY:Number ):void { _graphics.curveTo( controlX, controlY, anchorX, anchorY ); createStep( "curveTo", arguments ); } public function drawCircle( x:Number, y:Number, radius:Number ):void { _graphics.drawCircle( x, y, radius ); createStep( "drawCircle", arguments ); } public function drawEllipse( x:Number, y:Number, width:Number, height:Number ):void { _graphics.drawEllipse( x, y, width, height ); createStep( "drawEllipse", arguments ); } public function drawRect( x:Number, y:Number, width:Number, height:Number ):void { _graphics.drawRect( x, y, width, height ); createStep( "drawRect", arguments ); } public function drawRoundRect( x:Number, y:Number, width:Number, height:Number, ellipseWidth:Number, ellipseHeight:Number ):void { _graphics.drawRoundRect( x, y, width, height, ellipseWidth, ellipseHeight ); createStep( "drawRoundRect", arguments ); } public function endFill():void { _graphics.endFill(); createStep( "endFill", arguments ); } public function lineGradientStyle( type:String, colors:Array, alphas:Array, ratios:Array, matrix:Matrix = null, spreadMethod:String = "pad", interpolationMethod:String = "rgb", focalPointRatio:Number = 0 ):void { _graphics.lineGradientStyle( type , colors, alphas, ratios, matrix, spreadMethod, interpolationMethod, focalPointRatio ); createStep( "lineGradientStyle", arguments ); } public function lineStyle( thickness:Number, color:uint = 0, alpha:Number = 1.0, pixelHinting:Boolean = false, scaleMode:String = "normal", caps:String = null, joints:String = null, miterLimit:Number = 3 ):void { _graphics.lineStyle( thickness, color, alpha, pixelHinting, scaleMode, caps, joints, miterLimit ); createStep( "lineStyle", arguments ); } public function lineTo(x:Number, y:Number):void { _graphics.lineTo( x, y ); createStep( "lineTo", arguments ); } public function moveTo(x:Number, y:Number):void { _graphics.moveTo( x, y ); createStep( "moveTo", arguments ); } } }