Moving Origin to trunk by way of a bulk copy merge is a bit hairy. Will need to make a release note as this may disrupt some that are still using the old trunk version. Note they should not be.

This commit is contained in:
FlexibleExperiments 2009-11-11 13:51:39 +00:00
parent 857081d6d8
commit f1415bdae4
283 changed files with 56271 additions and 0 deletions

View File

@ -0,0 +1,226 @@
////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2008 The Degrafa Team : http://www.Degrafa.com/team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
////////////////////////////////////////////////////////////////////////////////
package com.degrafa{
import com.degrafa.core.collections.FillCollection;
import com.degrafa.core.collections.StrokeCollection;
import com.degrafa.geometry.Geometry;
import flash.display.Graphics;
import flash.geom.Rectangle;
import mx.events.PropertyChangeEvent;
[DefaultProperty("geometry")]
//--------------------------------------
// Other metadata
//--------------------------------------
[IconFile("GeometryComposition.png")]
/**
* GeometryComposition allows composing only objects that
* extend Geometry. This is not Sprite based like GeometryGroup and as such
* can be used in situations where a sprite is not allowed, for example skins.
*
* If you just want to draw to a arbitrary graphics context like Canvas, this
* object is recommended for the opening tag of your composition.
**/
public class GeometryComposition extends Geometry implements IGeometry{
public function GeometryComposition(){
super();
}
private var _fills:FillCollection;
[Inspectable(category="General", arrayType="com.degrafa.core.IGraphicsFill")]
[ArrayElementType("com.degrafa.core.IGraphicsFill")]
/**
* A array of IGraphicsFill objects.
**/
public function get fills():Array{
initFillsCollection();
return _fills.items;
}
public function set fills(value:Array):void{
initFillsCollection();
_fills.items = value;
}
/**
* Access to the Degrafa fill collection object for this graphic object.
**/
public function get fillCollection():FillCollection{
initFillsCollection();
return _fills;
}
/**
* Initialize the collection by creating it and adding an event listener.
**/
private function initFillsCollection():void{
if(!_fills){
_fills = new FillCollection();
//add a listener to the collection
if(enableEvents){
_fills.addEventListener(PropertyChangeEvent.PROPERTY_CHANGE,propertyChangeHandler);
}
}
}
private var _strokes:StrokeCollection;
[Inspectable(category="General", arrayType="com.degrafa.core.IGraphicsStroke")]
[ArrayElementType("com.degrafa.core.IGraphicsStroke")]
/**
* A array of IStroke objects.
**/
public function get strokes():Array{
initSrokesCollection();
return _strokes.items;
}
public function set strokes(value:Array):void{
initSrokesCollection();
_strokes.items = value;
}
/**
* Access to the Degrafa stroke collection object for this graphic object.
**/
public function get strokeCollection():StrokeCollection{
initSrokesCollection();
return _strokes;
}
/**
* Initialize the collection by creating it and adding an event listener.
**/
private function initSrokesCollection():void{
if(!_strokes){
_strokes = new StrokeCollection();
//add a listener to the collection
if(enableEvents){
_strokes.addEventListener(PropertyChangeEvent.PROPERTY_CHANGE,propertyChangeHandler);
}
}
}
/**
* Returns the tight bounds for this objects children
* not including this object.
**/
public function get childBounds():Rectangle{
var tempRect:Rectangle;
for each (var item:Geometry in geometry){
if(!tempRect || tempRect.isEmpty()){
tempRect = item.bounds;
}
else{
tempRect=tempRect.union(item.bounds);
}
}
return tempRect;
}
private var _bounds:Rectangle;
/**
* The tight bounds of this element as represented by a Rectangle object.
**/
override public function get bounds():Rectangle{
return _bounds;
}
/**
* Calculates the bounds for this element.
**/
public function calcBounds():void{
if(_layoutConstraint){
super.calculateLayout();
_bounds = layoutRectangle;
}
else if(parent && parent is Geometry){
_bounds=Geometry(parent).bounds;
}
else if (_currentGraphicsTarget){
_bounds= _currentGraphicsTarget.getRect(_currentGraphicsTarget)
}
else{
_bounds= new Rectangle();
}
}
/**
* @inheritDoc
**/
override public function preDraw():void{
//in the case of geom comp the predraw only sets up the bounds
calcBounds();
}
/**
* Performs the specific layout work required by this Geometry.
* @param childBounds the bounds to be layed out. If not specified a rectangle
* of (0,0,1,1) is used.
**/
override public function calculateLayout(childBounds:Rectangle=null):void{
if(_layoutConstraint){
if (_layoutConstraint.invalidated){
var tempLayoutRect:Rectangle = new Rectangle(0,0,1,1);
super.calculateLayout(tempLayoutRect);
_layoutRectangle = _layoutConstraint.layoutRectangle;
}
}
}
/**
* Begins the draw phase for geometry objects. All geometry objects
* override this to do their specific rendering.
*
* @param graphics The current context to draw to.
* @param rc A Rectangle object used for fill bounds.
**/
override public function draw(graphics:Graphics,rc:Rectangle):void{
//init the layout in this case done before predraw.
calculateLayout();
//re init if required
preDraw();
super.draw(graphics, (rc)? rc:_bounds);
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 471 B

View File

@ -0,0 +1,155 @@
////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2008 The Degrafa Team : http://www.Degrafa.com/team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
////////////////////////////////////////////////////////////////////////////////
package com.degrafa{
import com.degrafa.core.collections.GeometryCollection;
import com.degrafa.geometry.Geometry;
import flash.display.DisplayObject;
import flash.display.Graphics;
import flash.geom.Rectangle;
import mx.events.PropertyChangeEvent;
[DefaultProperty("geometry")]
[Bindable(event="propertyChange")]
//--------------------------------------
// Other metadata
//--------------------------------------
[IconFile("GeometryGroup.png")]
/**
* GeometryGroup is where composition is achieved for
* all Degrafa objects that render to a graphics context. Nested GeometryGroups
* can be added each of which may contain IGraphic or IGeometry type objects.
* GeometryGroup is the principle building block for compositing.
**/
public class GeometryGroup extends Graphic implements IGraphic, IGeometry{
public function GeometryGroup(){
super();
}
private var _geometry:GeometryCollection;
[Inspectable(category="General", arrayType="com.degrafa.IGeometry")]
[ArrayElementType("com.degrafa.IGeometry")]
/**
* A array of IGeometry objects. Objects of type GraphicText, GraphicImage
* and GeometryGroup are added to the target display list.
**/
public function get geometry():Array{
initGeometryCollection();
return _geometry.items;
}
public function set geometry(value:Array):void
{
initGeometryCollection();
_geometry.items = value;
//add the children is required
for each (var item:IGeometry in _geometry.items){
if(item is IGraphic){
addChild(DisplayObject(item));
}
//set the root geometry IGraphicParent
if (item is Geometry){
Geometry(item).IGraphicParent = this;
}
}
}
/**
* Access to the Degrafa geometry collection object for this graphic object.
**/
public function get geometryCollection():GeometryCollection{
initGeometryCollection();
return _geometry;
}
/**
* Initialize the geometry collection by creating it and adding an event listener.
**/
private function initGeometryCollection():void{
if(!_geometry){
_geometry = new GeometryCollection();
//add a listener to the collection
if(enableEvents){
_geometry.addEventListener(PropertyChangeEvent.PROPERTY_CHANGE,propertyChangeHandler);
}
}
}
/**
* Principle event handler for any property changes to a
* graphic object or it's child objects.
**/
private function propertyChangeHandler(event:PropertyChangeEvent):void{
draw(null,null);
}
/**
* Begins the draw phase for graphic objects. All graphic objects
* override this to do their specific rendering.
*
* @param graphics The current context to draw to.
* @param rc A Rectangle object used for fill bounds.
**/
override public function draw(graphics:Graphics,rc:Rectangle):void{
if(!parent){return;}
super.draw(null,null);
if (_geometry){
for each (var geometryItem:IGeometry in _geometry.items){
if(geometryItem is IGraphic){
//a IGraphic is a sprite and does not draw to
//this graphics object
geometryItem.draw(null,null);
}
else{
geometryItem.draw(this.graphics,null);
}
}
}
super.endDraw(null);
}
/**
* Data is required for the IGeometry interface and has no effect here.
* @private
**/
public function get data():Object{return null;}
public function set data(value:Object):void{}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 547 B

View File

@ -0,0 +1,489 @@
////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2008 The Degrafa Team : http://www.Degrafa.com/team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
////////////////////////////////////////////////////////////////////////////////
package com.degrafa{
import com.degrafa.core.IGraphicsFill;
import com.degrafa.core.IGraphicsStroke;
import com.degrafa.core.collections.FillCollection;
import com.degrafa.core.collections.StrokeCollection;
import flash.display.DisplayObject;
import flash.display.DisplayObjectContainer;
import flash.display.Graphics;
import flash.display.Sprite;
import flash.events.Event;
import flash.geom.Rectangle;
import mx.events.FlexEvent;
import mx.utils.NameUtil;
import mx.core.IMXMLObject;
import mx.events.PropertyChangeEvent;
import mx.events.PropertyChangeEventKind;
[Event(name="initialize", type="mx.events.FlexEvent")]
[Event(name="propertyChange", type="mx.events.PropertyChangeEvent")]
[Bindable(event="propertyChange",type="mx.events.PropertyChangeEvent")]
/**
* Graphic is the base class for Degrafa objects that allow complete composition
* GeometryGroup for example.
*
* @see flash.display.Sprite
**/
public class Graphic extends Sprite implements IMXMLObject{
/**
* Number that specifies the vertical position, in pixels, within the target.
**/
override public function get y():Number{
return super.y;
}
override public function set y(value:Number):void{
super.y = value;
}
/**
* Number that specifies the horizontal position, in pixels, within the target.
**/
override public function get x():Number{
return super.x;
}
override public function set x(value:Number):void{
super.x = value;
}
private var _width:Number=0;
[PercentProxy("percentWidth")]
/**
* Number that specifies the width, in pixels, in the target's coordinates.
**/
override public function get width():Number{
return _width;
}
override public function set width(value:Number):void{
_width = value;
draw(null,null);
dispatchEvent(new Event("change"));
}
private var _height:Number=0;
[PercentProxy("percentHeight")]
/**
* Number that specifies the height, in pixels, in the target's coordinates.
**/
override public function get height():Number{
return _height;
}
override public function set height(value:Number):void{
_height = value;
draw(null,null);
dispatchEvent(new Event("change"));
}
/**
* The default height, in pixels.
**/
public function get measuredHeight():Number{
return _height;
}
/**
* The default width, in pixels.
**/
public function get measuredWidth():Number{
return _width;
}
private var _percentWidth:Number;
[Inspectable(environment="none")]
/**
* Number that specifies the width as a percentage of the target.
**/
public function get percentWidth():Number{
return _percentWidth;
}
public function set percentWidth(value:Number):void{
if (_percentWidth == value){return};
_percentWidth = value;
}
private var _percentHeight:Number;
[Inspectable(environment="none")]
/**
* Number that specifies the height as a percentage of the target.
**/
public function get percentHeight():Number{
return _percentHeight;
}
public function set percentHeight(value:Number):void{
if (_percentHeight == value){return;}
_percentHeight = value;
}
private var _target:DisplayObjectContainer;
/**
* A target DisplayObjectContainer that this graphic object should be added or drawn to.
**/
public function get target():DisplayObjectContainer{
return _target;
}
public function set target(value:DisplayObjectContainer):void{
if (!value){return;}
//reparent if nessesary
if (_target != value && _target!=null)
{
//remove this obejct from previous parent
_target.removeChild(this);
}
_target = value;
_target.addChild(this);
//draw the obejct
draw(null,null);
endDraw(null);
}
private var _stroke:IGraphicsStroke;
/**
* Defines the stroke object that will be used for
* rendering this graphic object.
**/
public function get stroke():IGraphicsStroke{
return _stroke;
}
public function set stroke(value:IGraphicsStroke):void{
_stroke = value;
}
private var _fill:IGraphicsFill;
/**
* Defines the fill object that will be used for
* rendering this graphic object.
**/
public function get fill():IGraphicsFill{
return _fill;
}
public function set fill(value:IGraphicsFill):void{
_fill=value;
}
private var _fills:FillCollection;
[Inspectable(category="General", arrayType="com.degrafa.core.IGraphicsFill")]
[ArrayElementType("com.degrafa.core.IGraphicsFill")]
/**
* A array of IGraphicsFill objects.
**/
public function get fills():Array{
initFillsCollection();
return _fills.items;
}
public function set fills(value:Array):void{
initFillsCollection();
_fills.items = value;
}
/**
* Access to the Degrafa fill collection object for this graphic object.
**/
public function get fillCollection():FillCollection{
initFillsCollection();
return _fills;
}
/**
* Initialize the fills collection by creating it and adding an event listener.
**/
private function initFillsCollection():void{
if(!_fills){
_fills = new FillCollection();
//add a listener to the collection
if(enableEvents){
_fills.addEventListener(PropertyChangeEvent.PROPERTY_CHANGE,propertyChangeHandler);
}
}
}
private var _strokes:StrokeCollection;
[Inspectable(category="General", arrayType="com.degrafa.core.IGraphicsStroke")]
[ArrayElementType("com.degrafa.core.IGraphicsStroke")]
/**
* A array of IStroke objects.
**/
public function get strokes():Array{
initSrokesCollection();
return _strokes.items;
}
public function set strokes(value:Array):void{
initSrokesCollection();
_strokes.items = value;
}
/**
* Access to the Degrafa stroke collection object for this graphic object.
**/
public function get strokeCollection():StrokeCollection{
initSrokesCollection();
return _strokes;
}
/**
* Initialize the strokes collection by creating it and adding an event listener.
**/
private function initSrokesCollection():void{
if(!_strokes){
_strokes = new StrokeCollection();
//add a listener to the collection
if(enableEvents){
_strokes.addEventListener(PropertyChangeEvent.PROPERTY_CHANGE,propertyChangeHandler);
}
}
}
/**
* Principle event handler for any property changes to a
* graphic object or it's child objects.
**/
private function propertyChangeHandler(event:PropertyChangeEvent):void{
draw(null,null);
}
/**
* Ends the draw phase for geometry objects.
*
* @param graphics The current Graphics context being drawn to.
**/
public function endDraw(graphics:Graphics):void{
if (fill){
fill.end(this.graphics);
}
}
/**
* Begins the draw phase for geometry objects. All geometry objects
* override this to do their specific rendering.
*
* @param graphics The current context to draw to.
* @param rc A Rectangle object used for fill bounds.
**/
public function draw(graphics:Graphics,rc:Rectangle):void{
if (!parent){return;}
if(percentWidth || percentHeight)
{
//calculate based on the parent
_width = (parent.width/100)*_percentHeight;
_height = (parent.height/100)*_percentHeight;
}
this.graphics.clear();
if (stroke)
{
if(!rc){
stroke.apply(this.graphics,null);
}
else{
stroke.apply(this.graphics,rc);
}
}
else
{
this.graphics.lineStyle(0, 0xFFFFFF, 0);
}
if (fill){
if(!rc){
var rect:Rectangle = new Rectangle(0,0,width,height);
fill.begin(this.graphics, rect);
}
else{
fill.begin(this.graphics, rc);
}
}
}
private var _enableEvents:Boolean=true;
/**
* Enable events for this object.
**/
[Inspectable(category="General", enumeration="true,false")]
public function get enableEvents():Boolean{
return _enableEvents;
}
public function set enableEvents(value:Boolean):void{
_enableEvents=value;
}
private var _suppressEventProcessing:Boolean=false;
/**
* Temporarily suppress event processing for this object.
**/
[Inspectable(category="General", enumeration="true,false")]
public function get suppressEventProcessing():Boolean{
return _suppressEventProcessing;
}
public function set suppressEventProcessing(value:Boolean):void{
if(_suppressEventProcessing==true && value==false){
_suppressEventProcessing=value;
initChange("suppressEventProcessing",false,true,this);
}
else{
_suppressEventProcessing=value;
}
}
/**
* Dispatches an event into the event flow.
*
* @see EventDispatcher
**/
override public function dispatchEvent(event:Event):Boolean{
if(_suppressEventProcessing){return false;}
return(super.dispatchEvent(event));
}
/**
* Dispatches an property change event into the event flow.
**/
public function dispatchPropertyChange(bubbles:Boolean = false,
property:Object = null, oldValue:Object = null,
newValue:Object = null, source:Object = null):Boolean{
return dispatchEvent(new PropertyChangeEvent("propertyChange",bubbles,false,PropertyChangeEventKind.UPDATE,property,oldValue,newValue,source));
}
/**
* Helper function for dispatching property changes
**/
public function initChange(property:String,oldValue:Object,newValue:Object,source:Object):void{
if(hasEventManager){
dispatchPropertyChange(false,property,oldValue,newValue,source);
}
}
/**
* Tests to see if a EventDispatcher instance has been created for this object.
**/
public function get hasEventManager():Boolean{
return true;
}
//specific identity code
private var _id:String;
/**
* The identifier used by document to refer to this object.
**/
public function get id():String{
if(_id){
return _id;
}
else{
_id =NameUtil.createUniqueName(this);
name=_id;
return _id;
}
}
public function set id(value:String):void{
_id = value;
name=_id;
}
private var _document:Object;
/**
* The MXML document that created this object.
**/
public function get document():Object{
return _document;
}
/**
* Called after the implementing object has been created and all component properties specified on the MXML tag have been initialized.
*
* @param document The MXML document that created this object.
* @param id The identifier used by document to refer to this object.
**/
public function initialized(document:Object, id:String):void {
//if the id has not been set (through as perhaps)
if(!_id){
if(id){
_id = id;
}
else{
//if no id specified create one
_id = NameUtil.createUniqueName(this);
}
}
//sprit has a name property and it is set
//to the instance value. Make sure it is the
//same as the id
name=_id;
_document=document;
if(enableEvents && !suppressEventProcessing){
dispatchEvent(new FlexEvent(FlexEvent.INITIALIZE));
}
}
}
}

View File

@ -0,0 +1,113 @@
////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2008 The Degrafa Team : http://www.Degrafa.com/team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
////////////////////////////////////////////////////////////////////////////////
package com.degrafa{
import flash.display.DisplayObject;
import flash.display.Graphics;
import flash.display.Loader;
import flash.events.Event;
import flash.geom.Rectangle;
import flash.net.URLRequest;
[Bindable(event="propertyChange")]
//--------------------------------------
// Other metadata
//--------------------------------------
[IconFile("GraphicImage.png")]
/**
* GraphicImage Enables support for images to be added to compositions.
**/
public class GraphicImage extends Graphic implements IGraphic, IGeometry{
public function GraphicImage(){
super();
}
/**
* Data is required for the IGeometry interface and has no effect here.
* @private
**/
public function get data():Object{return null;}
public function set data(value:Object):void{}
private var loader:Loader;
private var _source:Object;
/**
* The URL, class or string name of a class to load as the content
**/
public function get source():Object{
return _source;
}
public function set source(value:Object):void{
_source = value;
var newClass:Class;
if (_source is Class)
{
newClass = Class(_source);
}
else if (_source is String)
{
//treat as a url so need a loader
loader = new Loader();
var urlRequest:URLRequest = new URLRequest(String(_source));
loader.load(urlRequest);
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onLoaded);
}
if(newClass){
var child:DisplayObject;
child = new newClass();
addChild(child);
}
}
/**
* Called when the image has been successfully loaded.
**/
protected function onLoaded(event:Event):void{
addChild(event.target.content);
loader.contentLoaderInfo.removeEventListener(Event.COMPLETE, onLoaded);
}
/**
* draw is required for the IGeometry interface and has no effect here.
* @private
**/
override public function draw(graphics:Graphics,rc:Rectangle):void{}
/**
* endDraw is required for the IGeometry interface and has no effect here.
* @private
**/
override public function endDraw(graphics:Graphics):void{}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 344 B

View File

@ -0,0 +1,39 @@
////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2008 The Degrafa Team : http://www.Degrafa.com/team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
////////////////////////////////////////////////////////////////////////////////
package com.degrafa{
import flash.geom.Point;
[Bindable]
/**
* Simple point definition.
*
* @see flash.geom.Point
**/
public class GraphicPoint extends Point implements IGraphicPoint{
public function GraphicPoint(x:Number=0, y:Number=0){
super(x, y);
}
}
}

View File

@ -0,0 +1,259 @@
////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2008 The Degrafa Team : http://www.Degrafa.com/team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
////////////////////////////////////////////////////////////////////////////////
package com.degrafa{
/**
* servers as a proxy wrapper so we can get the event manager in here.
* This should/can not be used in a matrix where flex/flash expect a
* point. But rather use/pass/set the point property when required. It should
* never evenr be used on a complex graphic. It is intended to be wrapped for
* a current object if manipulation is required.
**/
import com.degrafa.core.DegrafaObject;
import flash.geom.Point;
[Bindable(event="propertyChange")]
/**
* Extended Degrafa event enabled point definition.
*
* @see flash.geom.Point
**/
public class GraphicPointEX extends DegrafaObject implements IGraphicPoint{
/**
* Constructor.
*
* <p>The graphic extended point constructor accepts 2 optional arguments that define it's
* x, and y coordinate values.</p>
*
* @param x A number indicating the x-axis coordinate.
* @param y A number indicating the y-axis coordinate.
*
*/
public function GraphicPointEX(x:Number=0, y:Number=0){
this.x=x
this.y=y
this.point.x=x
this.point.y=y
}
private var _data:String;
/**
* GraphicPointEX short hand data value.
*
* <p>The extended graphic point data property expects exactly 2 values x and
* y separated by spaces.</p>
**/
public function get data():String{
return _data;
}
public function set data(value:String):void
{
if(_data != value){
var oldValue:String=_data;
_data = value;
var tempArray:Array = value.split(" ");
if (tempArray.length == 2)
{
_x=tempArray[0];
_y=tempArray[1];
}
_point.x=_x
_point.y=_y
//call local helper to dispatch event
if(enableEvents){
initChange("data",oldValue,value,this);
}
}
}
private var _point:Point=new Point();
/**
* The internal point object.
**/
public function get point():Point{
return _point;
}
public function set point(value:Point):void{
if(!_point.equals(value)){
var oldValue:Point=_point;
_point = value;
_x=_point.x;
_y=_point.y;
//call local helper to dispatch event
if(enableEvents){
initChange("data",oldValue,value,this);
}
}
}
private var _x:Number=0;
/**
* The x-coordinate of the point. If not specified
* a default value of 0 is used.
**/
public function get x():Number{
return _x;
}
public function set x(value:Number):void{
if(_x != value){
var oldValue:Number=_x;
_x = value;
_point.y=_x;
//call local helper to dispatch event
if(enableEvents){
initChange("x",oldValue,_x,this);
}
}
}
private var _y:Number=0;
/**
* The y-coordinate of the point. If not specified
* a default value of 0 is used.
**/
public function get y():Number{
return _y;
}
public function set y(value:Number):void{
if(_y != value){
var oldValue:Number=_y;
_y = value;
_point.y=_y;
//call local helper to dispatch event
if(enableEvents){
initChange("y",oldValue,_y,this);
}
}
}
/**
* Adds the coordinates of another point to the coordinates of this point to create a new point.
*
* @see flash.geom.Point
**/
public function add(v:Point):Point{
return _point.add(v);
}
/**
* Creates a copy of this Point object.
*
* @see flash.geom.Point
**/
public function clone():Point {
return _point.clone();
}
/**
* Returns the distance between pt1 and pt2.
*
* @see flash.geom.Point
**/
public static function distance(pt1:Point, pt2:Point):Number{
return Point.distance(pt1,pt2);
}
/**
* Determines whether two points are equal.
*
* @see flash.geom.Point
**/
public function equals(toCompare:Point):Boolean {
return _point.equals(toCompare);
}
/**
* Determines a point between two specified points.
*
* @see flash.geom.Point
**/
public static function interpolate(pt1:Point, pt2:Point, f:Number):Point{
return Point.interpolate(pt1,pt2,f);
}
/**
* Scales the line segment between (0,0) and the current point to a set length.
*
* @see flash.geom.Point
**/
public function normalize(thickness:Number):void {
_point.normalize(thickness);
}
/**
* Offsets the Point object by the specified amount.
*
* @see flash.geom.Point
**/
public function offset(dx:Number, dy:Number):void {
_point.offset(dx,dy);
}
/**
* Converts a pair of polar coordinates to a Cartesian point coordinate.
*
* @see flash.geom.Point
**/
public static function polar(len:Number, angle:Number):Point{
return Point.polar(len,angle);
}
/**
* Subtracts the coordinates of another point from the coordinates of this point to create a new point.
*
* @see flash.geom.Point
**/
public function subtract(v:Point):Point{
return _point.subtract(v);
}
/**
* The length from (0,0) to this point.
*
* @see flash.geom.Point
**/
public function get length():Number{
return _point.length;
}
}
}

View File

@ -0,0 +1,554 @@
////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2008 The Degrafa Team : http://www.Degrafa.com/team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
////////////////////////////////////////////////////////////////////////////////
package com.degrafa
{
import com.degrafa.core.IGraphicsFill;
import com.degrafa.core.IGraphicsStroke;
import com.degrafa.core.collections.FillCollection;
import com.degrafa.core.collections.StrokeCollection;
import com.degrafa.paint.SolidFill;
import flash.display.DisplayObjectContainer;
import flash.display.Graphics;
import flash.events.Event;
import flash.geom.Rectangle;
import flash.text.TextField;
import flash.text.TextFormat;
import mx.core.IMXMLObject;
import mx.events.FlexEvent;
import mx.events.PropertyChangeEvent;
import mx.events.PropertyChangeEventKind;
import mx.utils.NameUtil;
//--------------------------------------
// Other metadata
//--------------------------------------
[IconFile("GraphicText.png")]
/**
* some of these will be added back at a later date
**/
[Exclude(name="percentHeight", kind="property")]
[Exclude(name="percentWidth", kind="property")]
[Exclude(name="measuredWidth", kind="property")]
[Exclude(name="measuredHeight", kind="property")]
[Exclude(name="target", kind="property")]
[Exclude(name="stroke", kind="property")]
[Exclude(name="fills", kind="property")]
[Exclude(name="strokes", kind="property")]
[Bindable(event="propertyChange")]
/**
* GraphicText extends TextField and enables support for text fields
* to be added to compositions.
*
* @see flash.text.TextField
**/
public class GraphicText extends TextField implements IGraphic, IGeometry, IMXMLObject
{
public function GraphicText()
{
super();
defaultTextFormat = _textFormat;
}
/**
* Data is required for the IGeometry interface and has no effect here.
* @private
**/
public function get data():Object{return null;}
public function set data(value:Object):void{}
/**
* Text format.
*
* @see flash.text.TextFormat
**/
private var _textFormat:TextFormat=new TextFormat();
public function get textFormat():TextFormat{
return _textFormat;
}
public function set textFormat(value:TextFormat):void{
_textFormat = value;
defaultTextFormat = _textFormat;
}
/**
* Controls automatic sizing and alignment of text fields.
*
* @see flash.text.TextField
**/
private var _autoSize:String="none";
[Inspectable(category="General", enumeration="none,left,center", defaultValue="none")]
override public function get autoSize():String{
return _autoSize;
}
override public function set autoSize(value:String):void{
_autoSize = value;
super.autoSize =_autoSize;
}
/**
* Autosize the text field to text size. When set to true the
* GraphicText object will size to fit the height and width of
* the text.
**/
private var _autoSizeField:Boolean=true;
[Inspectable(category="General", enumeration="true,false")]
public function get autoSizeField():Boolean{
return _autoSizeField;
}
public function set autoSizeField(value:Boolean):void{
_autoSizeField = value;
//NOTE: added the 4px offset as the left and bottom was
//being cut off requires investigation. Was changed
//from 5px to 4px to address the "walking text" issue
if(text != ""){
width = textWidth + 4;
height = textHeight + 4;
}
}
/**
* A string that is the current text in the text field.
**/
override public function set text(value:String):void{
super.text = value;
//NOTE: added the 4px offset as the left and bottom was
//being cut off requires investigation. Was changed
//from 5px to 4px to address the "walking text" issue
if(_autoSizeField){
width = textWidth + 4;
height = textHeight + 4;
}
}
/**
* Indicates the color of the text.
*
* @see flash.text.TextFormat
**/
private var _color:uint;
public function set color(value:uint):void{
_color = value;
_textFormat.color = _color;
defaultTextFormat = _textFormat;
}
public function get color():uint{
return _color;
}
/**
* The name of the font for text in this text format, as a string.
*
* @see flash.text.TextFormat
**/
private var _fontFamily:String;
public function set fontFamily(value:String):void{
_fontFamily = value;
_textFormat.font = _fontFamily;
defaultTextFormat = _textFormat;
}
public function get fontFamily():String{
return _fontFamily;
}
/**
* The point size of text in this text format.
*
* @see flash.text.TextFormat
**/
private var _fontSize:Number;
public function set fontSize(value:Number):void{
_fontSize = value;
_textFormat.size = _fontSize;
defaultTextFormat = _textFormat;
}
public function get fontSize():Number{
return _fontSize;
}
/**
* Specifies whether the text is normal or boldface.
*
* @see flash.text.TextFormat
**/
private var _fontWeight:String="normal";
[Inspectable(category="General", enumeration="normal,bold", defaultValue="normal")]
public function set fontWeight(value:String):void{
_fontWeight = value;
_textFormat.bold = (_fontWeight == "bold") ? true: false;
defaultTextFormat = _textFormat;
}
public function get fontWeight():String{
return _fontWeight;
}
/**
* A number representing the amount of space that is uniformly distributed between all characters.
*
* @see flash.text.TextFormat
**/
private var _letterSpacing:int;
public function set letterSpacing(value:int):void{
_letterSpacing = value;
_textFormat.letterSpacing = _letterSpacing;
defaultTextFormat = _textFormat;
}
public function get letterSpacing():int{
return _letterSpacing;
}
private var _stroke:IGraphicsStroke;
/**
* Defines the stroke object that will be used for
* rendering this geometry object. Coming soon has no effect here.
*
* @private
**/
public function get stroke():IGraphicsStroke{
return _stroke;
}
public function set stroke(value:IGraphicsStroke):void{
if(_stroke != value){
if(_stroke){
if(_stroke.hasEventManager){
_stroke.removeEventListener(PropertyChangeEvent.PROPERTY_CHANGE,propertyChangeHandler);
}
}
_stroke = value;
if(enableEvents){
_stroke.addEventListener(PropertyChangeEvent.PROPERTY_CHANGE,propertyChangeHandler,false,0,true);
}
}
}
/**
* Defines the fill object that will be used for
* rendering this geometry object. Coming soon has no effect here.
*
* @private
**/
private var _fill:IGraphicsFill;
public function get fill():IGraphicsFill{
return _fill;
}
public function set fill(value:IGraphicsFill):void{
_fill=value;
if (_fill is SolidFill){
color = uint(SolidFill(_fill).color);
}
else{
//gradient fill need to do runtime mask
}
}
private var _fills:FillCollection;
[Inspectable(category="General", arrayType="com.degrafa.core.IGraphicsFill")]
[ArrayElementType("com.degrafa.core.IGraphicsFill")]
/**
* A array of IGraphicsFill objects.
**/
public function get fills():Array{
initFillsCollection();
return _fills.items;
}
public function set fills(value:Array):void{
initFillsCollection();
_fills.items = value;
}
/**
* Access to the Degrafa fill collection object for this graphic object.
**/
public function get fillCollection():FillCollection{
initFillsCollection();
return _fills;
}
/**
* Initialize the fills collection by creating it and adding an event listener.
**/
private function initFillsCollection():void{
if(!_fills){
_fills = new FillCollection();
//add a listener to the collection
if(enableEvents){
_fills.addEventListener(PropertyChangeEvent.PROPERTY_CHANGE,propertyChangeHandler);
}
}
}
private var _strokes:StrokeCollection;
[Inspectable(category="General", arrayType="com.degrafa.core.IGraphicsStroke")]
[ArrayElementType("com.degrafa.core.IGraphicsStroke")]
/**
* A array of IStroke objects.
**/
public function get strokes():Array{
initSrokesCollection();
return _strokes.items;
}
public function set strokes(value:Array):void{
initSrokesCollection();
_strokes.items = value;
}
/**
* Access to the Degrafa stroke collection object for this graphic object.
**/
public function get strokeCollection():StrokeCollection{
initSrokesCollection();
return _strokes;
}
/**
* Initialize the strokes collection by creating it and adding an event listener.
**/
private function initSrokesCollection():void{
if(!_strokes){
_strokes = new StrokeCollection();
//add a listener to the collection
if(enableEvents){
_strokes.addEventListener(PropertyChangeEvent.PROPERTY_CHANGE,propertyChangeHandler);
}
}
}
/**
* Principle event handler for any property changes to a
* graphic object or it's child objects.
*
* @private
**/
private function propertyChangeHandler(event:PropertyChangeEvent):void{
draw(null,null);
}
/**
* draw is required for the IGeometry interface and has no effect here.
* @private
**/
public function draw(graphics:Graphics,rc:Rectangle):void{}
/**
* endDraw is required for the IGeometry interface and has no effect here.
* @private
**/
public function endDraw(graphics:Graphics):void{}
/**
* the below are all excluded for now
**/
/**
* @private
**/
public function get percentHeight():Number{return 0;}
public function set percentHeight(value:Number):void{}
/**
* @private
**/
public function get percentWidth():Number{return 0;}
public function set percentWidth(value:Number):void{}
/**
* @private
**/
public function get measuredWidth():Number{return 0;}
/**
* @private
**/
public function get measuredHeight():Number{return 0;}
/**
* @private
**/
public function get target():DisplayObjectContainer{return null;}
public function set target(value:DisplayObjectContainer):void{}
//event related stuff
private var _enableEvents:Boolean=true;
/**
* Enable events for this object.
**/
[Inspectable(category="General", enumeration="true,false")]
public function get enableEvents():Boolean{
return _enableEvents;
}
public function set enableEvents(value:Boolean):void{
_enableEvents=value;
}
private var _suppressEventProcessing:Boolean=false;
/**
* Temporarily suppress event processing for this object.
**/
[Inspectable(category="General", enumeration="true,false")]
public function get suppressEventProcessing():Boolean{
return _suppressEventProcessing;
}
public function set suppressEventProcessing(value:Boolean):void{
if(_suppressEventProcessing==true && value==false){
_suppressEventProcessing=value;
initChange("suppressEventProcessing",false,true,this);
}
else{
_suppressEventProcessing=value;
}
}
/**
* Dispatches an event into the event flow.
*
* @see EventDispatcher
**/
override public function dispatchEvent(event:Event):Boolean{
if(_suppressEventProcessing){return false;}
return(super.dispatchEvent(event));
}
/**
* Dispatches an property change event into the event flow.
**/
public function dispatchPropertyChange(bubbles:Boolean = false,
property:Object = null, oldValue:Object = null,
newValue:Object = null, source:Object = null):Boolean{
return dispatchEvent(new PropertyChangeEvent("propertyChange",bubbles,false,PropertyChangeEventKind.UPDATE,property,oldValue,newValue,source));
}
/**
* Helper function for dispatching property changes
**/
public function initChange(property:String,oldValue:Object,newValue:Object,source:Object):void{
if(hasEventManager){
dispatchPropertyChange(false,property,oldValue,newValue,source);
}
}
/**
* Tests to see if a EventDispatcher instance has been created for this object.
**/
public function get hasEventManager():Boolean{
return true;
}
//specific identity code
private var _id:String;
/**
* The identifier used by document to refer to this object.
**/
public function get id():String{
if(_id){
return _id;
}
else{
_id =NameUtil.createUniqueName(this);
name=_id;
return _id;
}
}
public function set id(value:String):void{
_id = value;
name=_id;
}
private var _document:Object;
/**
* The MXML document that created this object.
**/
public function get document():Object{
return _document;
}
/**
* Called after the implementing object has been created and all component properties specified on the MXML tag have been initialized.
*
* @param document The MXML document that created this object.
* @param id The identifier used by document to refer to this object.
**/
public function initialized(document:Object, id:String):void {
//if the id has not been set (through as perhaps)
if(!_id){
if(id){
_id = id;
}
else{
//if no id specified create one
_id = NameUtil.createUniqueName(this);
}
}
//sprit has a name property and it is set
//to the instance value. Make sure it is the
//same as the id
name=_id;
_document=document;
if(enableEvents && !suppressEventProcessing){
dispatchEvent(new FlexEvent(FlexEvent.INITIALIZE));
}
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 420 B

View File

@ -0,0 +1,159 @@
////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2008 The Degrafa Team : http://www.Degrafa.com/team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
////////////////////////////////////////////////////////////////////////////////
package com.degrafa
{
import flash.display.DisplayObjectContainer;
import flash.display.Graphics;
import flash.events.Event;
import flash.geom.Rectangle;
import flash.text.TextField;
import flash.text.TextFormat;
/**
* GraphicText extends TextField and enables support for text fields
* to be added to compositions.
*
* @see flash.text.TextField
**/
public class GraphicTextPlus extends GraphicText
{
public function GraphicTextPlus()
{
super();
addEventListener(Event.RENDER, renderHandler);
addEventListener(Event.INIT, initHandler);
}
/**
* The render handler is used to enable runtime resizing/alignment
* @private
**/
private function renderHandler(event:Event):void {
realign();
}
/**
* The init handler is used to enable runtime resizing/alignment
* @private
**/
private function initHandler(event:Event):void {
realign();
}
/**
* Indicates the horizontal alignment of the anchored text object. Valid values are center, left, and right.
*
* @see flash.text.TextFormat
**/
private var _halign:String="left";
[Inspectable(category="General", enumeration="left,center,right", defaultValue="left")]
public function set halign(value:String):void{
_halign = value;
realign();
}
public function get halign():String{
return _halign;
}
/**
* Indicates the vertical alignment of the anchored text object. Valid values are center, left, and right.
*
* @see flash.text.TextFormat
**/
private var _valign:String="top";
[Inspectable(category="General", enumeration="top,middle,bottom", defaultValue="top")]
public function set valign(value:String):void{
_valign = value;
realign();
}
public function get valign():String{
return _valign;
}
/**
* An integer representing the horizontal anchor point
*
* @see flash.text.TextFormat
**/
private var _anchorx:Number;
public function set anchorx(value:Number):void{
_anchorx = value;
realign();
}
public function get anchorx():Number{
return _anchorx;
}
/**
* An integer representing the vertical anchor point
*
* @see flash.text.TextFormat
**/
private var _anchory:Number;
public function set anchory(value:Number):void{
_anchory = value;
realign();
}
public function get anchory():Number{
return _anchory;
}
/**
* draw is required for the IGeometry interface and has no effect here.
* @private
**/
public override function draw(graphics:Graphics,rc:Rectangle):void{
realign();
super.draw(graphics,rc);
}
public function realign() : void {
if(isNaN(anchorx))
this.anchorx = x;
if(isNaN(anchory))
this.anchory = y;
if(halign == "left") {
this.x = this.anchorx;
}
if(halign == "center") {
this.x = this.anchorx - (this.width / 2);
}
if(halign == "right") {
this.x = this.anchorx - this.width;
}
if(valign == "top") {
this.y = this.anchory;
}
if(valign == "middle") {
this.y = this.anchory - (this.height/ 2);
}
if(valign == "bottom") {
this.y = this.anchory - this.height;
}
}
}
}

View File

@ -0,0 +1,43 @@
////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2008 The Degrafa Team : http://www.Degrafa.com/team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
////////////////////////////////////////////////////////////////////////////////
package com.degrafa{
import com.degrafa.core.IGraphicsFill;
import com.degrafa.core.IGraphicsStroke;
import flash.display.Graphics;
import flash.geom.Rectangle;
/**
* Base interface for all Degrafa geometry objects.
**/
public interface IGeometry{
function draw(graphics:Graphics,rc:Rectangle):void
function endDraw(graphics:Graphics):void
function get stroke():IGraphicsStroke
function set stroke(value:IGraphicsStroke):void
function get fill():IGraphicsFill
function set fill(value:IGraphicsFill):void
function get data():Object
function set data(value:Object):void
}
}

View File

@ -0,0 +1,40 @@
////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2008 The Degrafa Team : http://www.Degrafa.com/team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
////////////////////////////////////////////////////////////////////////////////
package com.degrafa{
import com.degrafa.geometry.command.CommandStack;
import flash.display.Graphics;
import flash.geom.Rectangle;
/**
* Base interface for all composable Degrafa objects.
**/
public interface IGeometryComposition{
function draw(graphics:Graphics,rc:Rectangle):void
function endDraw(graphics:Graphics):void
function get bounds():Rectangle
function preDraw():void
function get commandStack():CommandStack;
function set commandStack(value:CommandStack):void;
}
}

View File

@ -0,0 +1,85 @@
////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2008 The Degrafa Team : http://www.Degrafa.com/team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
////////////////////////////////////////////////////////////////////////////////
package com.degrafa{
import com.degrafa.core.IGraphicsFill;
import com.degrafa.core.IGraphicsStroke;
import flash.display.DisplayObject;
import flash.geom.Rectangle;
import flash.display.DisplayObjectContainer;
import flash.display.Graphics;
/**
* Base interface for Degrafa Graphic objects.
**/
public interface IGraphic{
function get width():Number
function set width(value:Number):void
function get height():Number
function set height(value:Number):void
function get x():Number
function set x(value:Number):void
function get y():Number
function set y(value:Number):void
function get name():String
function set name(value:String):void
function addEventListener(type:String, listener:Function, useCapture:Boolean = false, priority:int = 0, useWeakReference:Boolean = false):void
function removeEventListener(type:String, listener:Function, useCapture:Boolean = false):void
function get fills():Array
function set fills(value:Array):void
function get strokes():Array
function set strokes(value:Array):void
function set percentHeight(value:Number):void
function get percentHeight():Number
function set percentWidth(value:Number):void
function get percentWidth():Number
function get measuredWidth():Number
function get measuredHeight():Number
function get parent():DisplayObjectContainer
function draw(graphics:Graphics,rc:Rectangle):void
function endDraw(graphics:Graphics):void
function set target(value:DisplayObjectContainer):void
function get target():DisplayObjectContainer
function get stroke():IGraphicsStroke
function set stroke(value:IGraphicsStroke):void
function get fill():IGraphicsFill
function set fill(value:IGraphicsFill):void
}
}

View File

@ -0,0 +1,33 @@
////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2008 The Degrafa Team : http://www.Degrafa.com/team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
////////////////////////////////////////////////////////////////////////////////
package com.degrafa{
//NOTE: though this has no details it is required to limit
//the types of points.
/**
* Base interface for Degrafa point objects.
**/
public interface IGraphicPoint{
}
}

View File

@ -0,0 +1,273 @@
////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2008 The Degrafa Team : http://www.Degrafa.com/team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
////////////////////////////////////////////////////////////////////////////////
package com.degrafa{
import com.degrafa.core.collections.FillCollection;
import com.degrafa.core.collections.GraphicsCollection;
import com.degrafa.core.collections.StrokeCollection;
import flash.display.DisplayObject;
import flash.events.Event;
import mx.core.UIComponent;
import mx.events.PropertyChangeEvent;
import mx.events.PropertyChangeEventKind;
[DefaultProperty("graphicsData")]
[Bindable(event="propertyChange")]
//--------------------------------------
// Other metadata
//--------------------------------------
[IconFile("Surface.png")]
/**
* Surface is a simple UIComponent extension that allows Degrafa objects
* to be added to it's display list. Fills and strokes set here have no
* effect and only serve organizational purposes.
**/
public class Surface extends UIComponent{
public function Surface(){
super();
}
private var _graphicsData:GraphicsCollection;
[Inspectable(category="General", arrayType="com.degrafa.IGraphic")]
[ArrayElementType("com.degrafa.IGraphic")]
/**
* A array of IGraphic objects. Objects of type GraphicText, GraphicImage
* and GeometryGroup are accepted and to this objects display list.
**/
public function get graphicsData():Array{
initGraphicsCollection();
return _graphicsData.items;
}
public function set graphicsData(value:Array):void{
initGraphicsCollection();
_graphicsData.items = value;
for each(var item:IGraphic in _graphicsData.items){
addChild(DisplayObject(item));
if (item.target==null){
item.target=this;
}
}
}
/**
* Access to the Degrafa graphics collection object for this graphic object.
**/
public function get graphicsCollection():GraphicsCollection{
initGraphicsCollection();
return _graphicsData;
}
/**
* Initialize the strokes collection by creating it and adding an event listener.
**/
private function initGraphicsCollection():void{
if(!_graphicsData){
_graphicsData = new GraphicsCollection();
//add a listener to the collection
if(enableEvents){
_graphicsData.addEventListener(PropertyChangeEvent.PROPERTY_CHANGE,propertyChangeHandler);
}
}
}
/**
* Principle event handler for any property changes to a
* graphic object or it's child objects.
**/
private function propertyChangeHandler(event:PropertyChangeEvent):void{
dispatchEvent(event);
// trace("propertyChange: " + event.property + " " + event.source);
}
private var _fills:FillCollection;
[Inspectable(category="General", arrayType="com.degrafa.core.IGraphicsFill")]
[ArrayElementType("com.degrafa.core.IGraphicsFill")]
/**
* A array of IGraphicsFill objects.
**/
public function get fills():Array{
initFillsCollection();
return _fills.items;
}
public function set fills(value:Array):void{
initFillsCollection();
_fills.items = value;
}
/**
* Access to the Degrafa fill collection object for this graphic object.
**/
public function get fillCollection():FillCollection{
initFillsCollection();
return _fills;
}
/**
* Initialize the fills collection by creating it and adding an event listener.
**/
private function initFillsCollection():void{
if(!_fills){
_fills = new FillCollection();
//add a listener to the collection
if(enableEvents){
_fills.addEventListener(PropertyChangeEvent.PROPERTY_CHANGE,propertyChangeHandler);
}
}
}
private var _strokes:StrokeCollection;
[Inspectable(category="General", arrayType="com.degrafa.core.IGraphicsStroke")]
[ArrayElementType("com.degrafa.core.IGraphicsStroke")]
/**
* A array of IStroke objects.
**/
public function get strokes():Array{
initSrokesCollection();
return _strokes.items;
}
public function set strokes(value:Array):void{
initSrokesCollection();
_strokes.items = value;
}
/**
* Access to the Degrafa stroke collection object for this graphic object.
**/
public function get strokeCollection():StrokeCollection{
initSrokesCollection();
return _strokes;
}
/**
* Initialize the strokes collection by creating it and adding an event listener.
**/
private function initSrokesCollection():void{
if(!_strokes){
_strokes = new StrokeCollection();
//add a listener to the collection
if(enableEvents){
_strokes.addEventListener(PropertyChangeEvent.PROPERTY_CHANGE,propertyChangeHandler);
}
}
}
/**
* Draws the object and/or sizes and positions its children.
**/
protected override function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void{
super.updateDisplayList(unscaledWidth, unscaledHeight);
setActualSize(getExplicitOrMeasuredWidth(), getExplicitOrMeasuredHeight());
}
//event related stuff
private var _enableEvents:Boolean=true;
/**
* Enable events for this object.
**/
[Inspectable(category="General", enumeration="true,false")]
public function get enableEvents():Boolean{
return _enableEvents;
}
public function set enableEvents(value:Boolean):void{
_enableEvents=value;
}
private var _suppressEventProcessing:Boolean=false;
/**
* Temporarily suppress event processing for this object.
**/
[Inspectable(category="General", enumeration="true,false")]
public function get suppressEventProcessing():Boolean{
return _suppressEventProcessing;
}
public function set suppressEventProcessing(value:Boolean):void{
if(_suppressEventProcessing==true && value==false){
_suppressEventProcessing=value;
initChange("suppressEventProcessing",false,true,this);
}
else{
_suppressEventProcessing=value;
}
}
/**
* Dispatches an event into the event flow.
*
* @see EventDispatcher
**/
override public function dispatchEvent(event:Event):Boolean{
if(_suppressEventProcessing){return false;}
return(super.dispatchEvent(event));
}
/**
* Dispatches an property change event into the event flow.
**/
public function dispatchPropertyChange(bubbles:Boolean = false,
property:Object = null, oldValue:Object = null,
newValue:Object = null, source:Object = null):Boolean{
return dispatchEvent(new PropertyChangeEvent("propertyChange",bubbles,false,PropertyChangeEventKind.UPDATE,property,oldValue,newValue,source));
}
/**
* Helper function for dispatching property changes
**/
public function initChange(property:String,oldValue:Object,newValue:Object,source:Object):void{
if(hasEventManager){
dispatchPropertyChange(false,property,oldValue,newValue,source);
}
}
/**
* Tests to see if a EventDispatcher instance has been created for this object.
**/
public function get hasEventManager():Boolean{
return true;
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 374 B

View File

@ -0,0 +1,259 @@
////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2008 The Degrafa Team : http://www.Degrafa.com/team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
////////////////////////////////////////////////////////////////////////////////
package com.degrafa.core{
import flash.events.Event;
import flash.events.EventDispatcher;
import mx.core.IMXMLObject;
import mx.events.FlexEvent;
import mx.events.PropertyChangeEvent;
import mx.events.PropertyChangeEventKind;
import mx.utils.NameUtil;
import com.degrafa.core.degrafa_internal;
[Event(name="initialize", type="mx.events.FlexEvent")]
[Event(name="propertyChange", type="mx.events.PropertyChangeEvent")]
/**
* Base class for all event enabled Degrafa objects.
**/
public class DegrafaObject implements IDegrafaObject, IMXMLObject{
//if false the internal listeners will not be
//set for the objects at creation time in other words
//if you don't want runtime events set this to false
//if you do then set it to true
private var _enableEvents:Boolean=true;
/**
* Enable events for this object.
**/
[Inspectable(category="General", enumeration="true,false")]
public function get enableEvents():Boolean{
return _enableEvents;
}
public function set enableEvents(value:Boolean):void{
_enableEvents=value;
}
//if true all event processing will stop being dispatched
//used when you need to update many properties when set back
//to true the event that gets dispatched will cause the display
//update (draw)
private var _suppressEventProcessing:Boolean=false;
/**
* Temporarily suppress event processing for this object.
**/
[Inspectable(category="General", enumeration="true,false")]
public function get suppressEventProcessing():Boolean{
return _suppressEventProcessing;
}
public function set suppressEventProcessing(value:Boolean):void{
if(_suppressEventProcessing==true && value==false){
_suppressEventProcessing=value;
initChange("suppressEventProcessing",false,true,this);
}
else{
_suppressEventProcessing=value;
}
}
/**
* Tests to see if a EventDispatcher instance has been created for this object.
**/
public function get hasEventManager():Boolean{
return (_eventDispatcher) ? true:false;
}
/**
* Registers an event listener object with an EventDispatcher object so that the listener receives notification of an event.
*
* @see EventDispatcher
**/
public function addEventListener(type:String, listener:Function, useCapture:Boolean = false, priority:int = 0, useWeakReference:Boolean = true):void{
eventDispatcher.addEventListener(type, listener, useCapture, priority,useWeakReference);
}
/**
* Dispatches an event into the event flow.
*
* @see EventDispatcher
**/
public function dispatchEvent(evt:Event):Boolean{
if(_suppressEventProcessing){
evt.stopImmediatePropagation();
return false;
}
return eventDispatcher.dispatchEvent(evt);
}
/**
* Checks whether the EventDispatcher object has any listeners registered for a specific type of event.
*
* @see EventDispatcher
**/
public function hasEventListener(type:String):Boolean{
return eventDispatcher.hasEventListener(type);
}
/**
* Removes a listener from the EventDispatcher object.
*
* @see EventDispatcher
**/
public function removeEventListener(type:String, listener:Function, useCapture:Boolean = false):void{
eventDispatcher.removeEventListener(type, listener, useCapture);
}
/**
* Checks whether an event listener is registered with this EventDispatcher object or any of its ancestors for the specified event type.
*
* @see EventDispatcher
**/
public function willTrigger(type:String):Boolean {
return eventDispatcher.willTrigger(type);
}
/**
* Dispatches an property change event into the event flow.
**/
public function dispatchPropertyChange(bubbles:Boolean = false,
property:Object = null, oldValue:Object = null,
newValue:Object = null, source:Object = null):Boolean{
return dispatchEvent(new PropertyChangeEvent("propertyChange",bubbles,false,PropertyChangeEventKind.UPDATE,property,oldValue,newValue,source));
}
/**
* Helper function for dispatching property changes
**/
public function initChange(property:String,oldValue:Object,newValue:Object,source:Object):void{
if(hasEventManager && !suppressEventProcessing){
dispatchPropertyChange(false,property,oldValue,newValue,source);
}
}
private var _eventDispatcher:EventDispatcher;
/**
* EventDispatcher instance for this object.
**/
protected function get eventDispatcher():EventDispatcher{
if(!_eventDispatcher){
_eventDispatcher=new EventDispatcher(this)
}
return _eventDispatcher;
}
protected function set eventDispatcher(value:EventDispatcher):void{
_eventDispatcher = value;
}
private var _id:String;
/**
* The identifier used by document to refer to this object.
**/
public function get id():String{
if(_id){
return _id;
}
else{
_id =NameUtil.createUniqueName(this);
return _id;
}
}
public function set id(value:String):void{
_id = value;
}
/**
* The name that refers to this object.
**/
public function get name():String{
return id;
}
private var _document:Object;
/**
* The MXML document that created this object.
**/
public function get document():Object{
return _document;
}
/**
* Called after the implementing object has been created and all component properties specified on the MXML tag have been initialized.
*
* @param document The MXML document that created this object.
* @param id The identifier used by document to refer to this object.
**/
public function initialized(document:Object, id:String):void{
//if the id has not been set (through as perhaps)
if(!_id){
if(id){
_id = id;
}
else{
//if no id specified create one
_id = NameUtil.createUniqueName(this);
}
}
_document=document;
_isInitialized = true;
if(enableEvents && ! _suppressEventProcessing){
dispatchEvent(new FlexEvent(FlexEvent.INITIALIZE));
}
}
/**
* A boolean value indicating that this object has been initialized
**/
private var _isInitialized:Boolean;
public function get isInitialized():Boolean{
return _isInitialized;
}
degrafa_internal var _parent:IDegrafaObject;
/**
* The current degrafa object parent.
* At this time only used for geometry.
**/
public function get parent():IDegrafaObject{
return degrafa_internal::_parent;
}
public function set parent(value:IDegrafaObject):void{
degrafa_internal::_parent=value;
}
//an array of current bindings for this object
public var objectBindings:Array;
}
}

View File

@ -0,0 +1,31 @@
////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2008 The Degrafa Team : http://www.Degrafa.com/team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
////////////////////////////////////////////////////////////////////////////////
package com.degrafa.core{
/**
* Base interface for Degrafa objects that require a blend mode.
**/
public interface IBlend{
function get blendMode():String;
function set blendMode(value:String):void;
}
}

View File

@ -0,0 +1,38 @@
////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2008 The Degrafa Team : http://www.Degrafa.com/team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
////////////////////////////////////////////////////////////////////////////////
package com.degrafa.core{
import flash.events.IEventDispatcher;
/**
* Base interface for all event enabled Degrafa objects.
**/
public interface IDegrafaObject extends IEventDispatcher{
function dispatchPropertyChange(bubbles:Boolean = false, property:Object = null, oldValue:Object = null,newValue:Object = null, source:Object = null):Boolean
function get enableEvents():Boolean
function set enableEvents(value:Boolean):void
function get hasEventManager():Boolean
function get suppressEventProcessing():Boolean
function set suppressEventProcessing(value:Boolean):void
function get parent():IDegrafaObject
function set parent(value:IDegrafaObject):void
}
}

View File

@ -0,0 +1,37 @@
////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2008 The Degrafa Team : http://www.Degrafa.com/team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
////////////////////////////////////////////////////////////////////////////////
package com.degrafa.core{
import com.degrafa.IGraphic;
import com.degrafa.core.collections.GeometryCollection;
[Exclude(name="graphicsData", kind="property")]
/**
* Base interface for all Degrafa skin objects.
**/
public interface IGraphicSkin extends IGraphic{
function set geometry(value:Array):void
function get geometry():Array
function get geometryCollection():GeometryCollection
function invalidateDisplayList():void
}
}

View File

@ -0,0 +1,44 @@
////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2008 The Degrafa Team : http://www.Degrafa.com/team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
////////////////////////////////////////////////////////////////////////////////
package com.degrafa.core{
import com.degrafa.core.IDegrafaObject;
import com.degrafa.IGeometryComposition;
import flash.geom.Rectangle;
import flash.display.Graphics;
import mx.graphics.IFill;
/**
* Base interface for all Degrafa fill objects.
**/
public interface IGraphicsFill extends IDegrafaObject, IFill {
//no difference as of yet basically used to limit the list
// we have to be careful as we would like the ability to use
//IGraphicsFill objects for charts etc..
function set requester(value:IGeometryComposition ):void;
function get restartFunction():Function;
function get lastArgs():Array;
function get lastRectangle():Rectangle;
}
}

View File

@ -0,0 +1,56 @@
////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2008 The Degrafa Team : http://www.Degrafa.com/team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
////////////////////////////////////////////////////////////////////////////////
package com.degrafa.core{
import flash.display.Graphics;
import flash.geom.Rectangle;
/**
* Base interface for all Degrafa stroke objects.
**/
public interface IGraphicsStroke extends IDegrafaObject{
function get weight():Number;
function set weight(value:Number):void;
function get scaleMode():String;
function set scaleMode(value:String):void;
function get pixelHinting():Boolean;
function set pixelHinting(value:Boolean):void;
function get miterLimit():Number;
function set miterLimit(value:Number):void;
function get joints():String;
function set joints(value:String):void;
function get caps():String;
function set caps(value:String):void;
function apply(graphics:Graphics, rc:Rectangle):void
function get reApplyFunction():Function;
function get lastArgs():Array;
function get lastRectangle():Rectangle;
}
}

View File

@ -0,0 +1,34 @@
////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2008 The Degrafa Team : http://www.Degrafa.com/team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
////////////////////////////////////////////////////////////////////////////////
package com.degrafa.core{
import com.degrafa.transform.ITransform;
/**
* Base interface for all Degrafa transformable fill and stroke objects.
**/
public interface ITransformablePaint extends IDegrafaObject, IGraphicsFill{
function get transform():ITransform;
function set transform(value:ITransform):void
}
}

View File

@ -0,0 +1,135 @@
////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2008 The Degrafa Team : http://www.Degrafa.com/team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
////////////////////////////////////////////////////////////////////////////////
package com.degrafa.core{
import flash.system.Capabilities;
/**
* Constant and conversion class for css skin values.
*/
public class Measure{
// relative length units
public static const EM:String = "em";
public static const EX:String = "ex";
public static const PIXELS:String = "pixels";
//public static const GRID:String = "gd";
//public static const REM:String = "rem";
//public static const VIEWPORT_WIDTH:String = "vw";
//public static const VIEWPORT_HEIGHT:String = "vh";
//public static const VIEWPORT_MEASURE:String = "vm";
public static const CH:String = "ch";
public static const PERCENT:String = "percent"; // 0 to 100
public static const RATIO:String = "ratio"; // 0 to 1
// absolute length units
public static const INCHES:String = "inches";
public static const CENTIMETERS:String = "centimeters";
public static const MILLIMETERS:String = "millimeters";
public static const POINTS:String = "points";
public static const PICAS:String = "picas";
// alternative
public static const DEGREES:String = "degrees";
// todo: implement real font measurement?
public var emSize:Number = -1;
public var exSize:Number = -1;
public var chSize:Number = -1;
public var unit:String;
public var value:Number;
public function Measure(value:Number = 0, unit:String = Measure.PIXELS):void {
this.value = value;
this.unit = unit;
}
public function relativeTo(length:Number, object:Object = null):Number {
switch(unit) {
case Measure.PIXELS:
return value;
break;
case Measure.PERCENT:
return length*(value/100);
break;
case Measure.RATIO:
return length*value;
break;
case Measure.POINTS:
return (value/72)*Capabilities.screenDPI;
break;
case Measure.INCHES:
return value*Capabilities.screenDPI;
break;
case Measure.CENTIMETERS:
return (value/2.54)*Capabilities.screenDPI;
break;
case Measure.MILLIMETERS:
return (value/25.4)*Capabilities.screenDPI;
break;
case Measure.PICAS:
return (value/6)*Capabilities.screenDPI;
break;
case Measure.EM:
updateFontSizes();
return value*emSize;
break;
case Measure.EX:
updateFontSizes();
return value*exSize;
break;
case Measure.CH:
updateFontSizes();
return value*chSize;
break;
default:
return value;
break;
}
}
private function updateFontSizes():void {
if(emSize < 0) {
emSize = (12/72)*Capabilities.screenDPI; // 12pt?
}
if(exSize < 0) {
exSize = (6/72)*Capabilities.screenDPI; // half line of 12pt?
}
if(chSize < 0) {
chSize = (12/72)*Capabilities.screenDPI; // 12pt?
}
}
//Object Cohersion Methods
public function toString():String {
return value.toString() + unit;
}
public function valueOf():Number {
return relativeTo(100);
}
}
}

View File

@ -0,0 +1,134 @@
////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2008 The Degrafa Team : http://www.Degrafa.com/team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
////////////////////////////////////////////////////////////////////////////////
package com.degrafa.core.collections{
import com.degrafa.decorators.IDecorator;
/**
* The DecoratorCollection stores a collection of IDecorator objects
**/
public class DecoratorCollection extends DegrafaCollection{
/**
* Constructor.
*
* <p>The DecoratorCollection collection constructor accepts 2 optional arguments
* that specify the IDecorator objects to be added and a event operation flag.</p>
*
* @param array An array of IDecorator objects.
* @param suppressEvents A boolean value indicating if events should not be
* dispatched for this collection.
*/
public function DecoratorCollection(array:Array=null,suppressEvents:Boolean=false){
super(IDecorator,array,suppressEvents);
}
/**
* Adds a IDecorator item to the collection.
*
* @param value The IDecorator object to be added.
* @return The IDecorator object that was added.
**/
public function addItem(value:IDecorator):IDecorator{
return super._addItem(value);
}
/**
* Removes an IDecorator item from the collection.
*
* @param value The IDecorator object to be removed.
* @return The IDecorator object that was removed.
**/
public function removeItem(value:IDecorator):IDecorator{
return super._removeItem(value);
}
/**
* Retrieve a IDecorator item from the collection based on the index value
* requested.
*
* @param index The collection index of the IDecorator object to retrieve.
* @return The IDecorator object that was requested if it exists.
**/
public function getItemAt(index:Number):IDecorator{
return super._getItemAt(index);
}
/**
* Retrieve a IDecorator item from the collection based on the object value.
*
* @param value The IDecorator object for which the index is to be retrieved.
* @return The IDecorator index value that was requested if it exists.
**/
public function getItemIndex(value:IDecorator):int{
return super._getItemIndex(value);
}
/**
* Adds a IDecorator item to this collection at the specified index.
*
* @param value The IDecorator object that is to be added.
* @param index The position in the collection at which to add the IDecorator object.
*
* @return The IDecorator object that was added.
**/
public function addItemAt(value:IDecorator,index:Number):IDecorator{
return super._addItemAt(value,index);
}
/**
* Removes a IDecorator object from this collection at the specified index.
*
* @param index The index of the IDecorator object to remove.
* @return The IDecorator object that was removed.
**/
public function removeItemAt(index:Number):IDecorator{
return super._removeItemAt(index);
}
/**
* Change the index of the IDecorator object within this collection.
*
* @param value The IDecorator object that is to be repositioned.
* @param newIndex The position at which to place the IDecorator object within the collection.
* @return True if the operation is successful False if unsuccessful.
**/
public function setItemIndex(value:IDecorator,newIndex:Number):Boolean{
return super._setItemIndex(value,newIndex);
}
/**
* Adds a series of IDecorator objects to this collection.
*
* @param value The collection to be added to this IDecorator collection.
* @return The resulting DecoratorCollection after the objects are added.
**/
public function addItems(value:DecoratorCollection):DecoratorCollection{
//todo
super.concat(value.items)
return this;
}
}
}

View File

@ -0,0 +1,597 @@
////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2008 The Degrafa Team : http://www.Degrafa.com/team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
////////////////////////////////////////////////////////////////////////////////
package com.degrafa.core.collections{
import com.degrafa.core.DegrafaObject;
import com.degrafa.core.IDegrafaObject;
import flash.utils.getQualifiedClassName;
import mx.events.PropertyChangeEvent;
//base degrafa collection that proxies the array type
[DefaultProperty("items")]
/**
* The Degrafa collection stores a collection of objects
* of a specific type and is the base class for all collection
* objects.
**/
public class DegrafaCollection extends DegrafaObject
{
/**
* The type of objects being stored in this colelction.
**/
private var type:Class;
/**
* Constructor.
*
* <p>The Degrafa collection constructor accepts 4 optional arguments
* that specify it's type, an array of values of the expected type to be added
* and 2 event operation flags.</p>
*
* @param type An class value specifing the types of objects being stored here.
* @param array An array of objects that are of the specified type.
* @param suppressEvents A boolean value indicating if events should not be
* dispatched for this collection.
* @param enableTypeChecking A boolean value indicating if type checking should be performed.
*/
public function DegrafaCollection(type:Class,array:Array=null,suppressEvents:Boolean=false,enableTypeChecking:Boolean=true){
this.type = type;
_enableTypeChecking = enableTypeChecking;
suppressEventProcessing = suppressEvents;
if(array){
items =array;
}
}
private var _enableTypeChecking:Boolean=true;
/**
* Allows internal type checking to be turned off.
**/
[Inspectable(category="General", enumeration="true,false")]
public function get enableTypeChecking():Boolean{
return _enableTypeChecking;
}
public function set enableTypeChecking(value:Boolean):void{
_enableTypeChecking=value;
}
/**
* Verifies each item in the passed array for a valid
* type and throws a runtime error if an object with
* out a valid type is found.
*
* @param value An array of objects to test on.
**/
private function checkValidTypes(value:Array):void{
//type check and throw exception if invalid type found
if(_enableTypeChecking){
for each (var item:Object in value){
if(!item is type){
throw new TypeError(flash.utils.getQualifiedClassName(item) +
" is not a valid " +
flash.utils.getQualifiedClassName(type));
return;
}
}
}
}
private var _items:Array=[];
/**
* An array of items being stored in this collection.
**/
public function get items():Array{
return _items;
}
public function set items(value:Array):void{
//support null assignments
if (value==null) value=[];
//type check items
checkValidTypes(value);
//compare and update
if(value !=_items){
//clear any event listeners
if(_items && _items.length && enableEvents && hasEventManager){
removeListeners();
}
var oldValue:Array = _items;
_items=value;
if(enableEvents && hasEventManager){
//call local helper to dispatch event (but only if either the old or new array had at least one element)
if (value.length||oldValue.length) initChange("items",oldValue,_items,this);
}
}
//add event listeners
if (value && value.length) addListeners();
}
/**
* Adds a new item to the collection.
*
* @param value The item to add.
* @return The item added.
**/
protected function _addItem(value:*):*{
addListener(value);
concat(value);
return value;
}
/**
* Removes a item from the collection.
*
* @param value The item to remove.
* @return The item removed.
**/
protected function _removeItem(value:*):*{
//get the index
var index:int = indexOf(value,0);
_removeItemAt(index);
return null;
}
/**
* Return a item at the given index.
*
* @param value The item index to return.
* @return The item requested.
**/
protected function _getItemAt(index:Number):*{
return items[index];
}
/**
* Return the index for the item in the collection.
*
* @param value The item to find.
* @return The index location of the item.
**/
protected function _getItemIndex(value:*):int{
return indexOf(value,0);
}
/**
* Add a item at the given index.
*
* @param value The item to add to the collection.
* @param index The index at which to add the item.
* @return The item added.
**/
protected function _addItemAt(value:Object,index:Number):*{
addListener(value);
splice(index,0,value);
return value;
}
/**
* Removes a item from the collection.
*
* @param value The item index to remove.
* @return The removed item.
**/
protected function _removeItemAt(index:Number):*{
//clean up
removeListener(items[index]);
return splice(index,1)[0];
}
/**
* Change the position of an item in the collection
*
* @param index The items new index.
* @param value The item to be repositioned.
* @return True if the item was repositioned.
**/
protected function _setItemIndex(value:*,newIndex:Number):Boolean{
var spliced:Array = items.splice(items.indexOf(value),1);
items.splice(newIndex, 0, spliced[0]);
return true;
}
//to be overidden in subclasse if nessesary
/**
* Addes a property change event listener and a parent reference to each item in the collection.
**/
public function addListeners():void{
if(enableEvents){
for each (var item:Object in items){
if(item is IDegrafaObject){
//update parent reff
IDegrafaObject(item).parent = this.parent;
if(IDegrafaObject(item).enableEvents){
IDegrafaObject(item).addEventListener(PropertyChangeEvent.PROPERTY_CHANGE,propertyChangeHandler);
}
}
}
}
}
/**
* Removes the property change event listener and parent reference from each item in the collection.
**/
public function removeListeners():void{
for each (var item:Object in items){
if(item is IDegrafaObject){
//update parent reff
IDegrafaObject(item).parent = null;
IDegrafaObject(item).removeEventListener(PropertyChangeEvent.PROPERTY_CHANGE,propertyChangeHandler);
}
}
}
/**
* Addes a property change event listener and a parent reference to the passed object.
**/
public function addListener(value:*):void{
if(value is IDegrafaObject){
//update parent reff
IDegrafaObject(value).parent = this.parent;
if(enableEvents){
if(IDegrafaObject(value).enableEvents){
IDegrafaObject(value).addEventListener(PropertyChangeEvent.PROPERTY_CHANGE,propertyChangeHandler);
}
}
}
}
/**
* Removes the property change event listener and parent reference from the passed object.
**/
public function removeListener(value:*):void{
if(value is IDegrafaObject){
//update parent reff
IDegrafaObject(value).parent = null;
IDegrafaObject(value).removeEventListener(PropertyChangeEvent.PROPERTY_CHANGE,propertyChangeHandler);
}
}
/**
* Property change event handler for this collection.
**/
public function propertyChangeHandler(event:PropertyChangeEvent):void{
if(!suppressEventProcessing){
dispatchEvent(event);
}
}
//proxy for array calls in some cases the subclasses may override these
//to provide additional function or safety
/**
* Concatenates the elements specified in the parameters with the elements in an array and creates a new array.
*
* @see Array
**/
public function concat(... args):Array{
var oldValue:Array = _items;
//type check item(s)
checkValidTypes(args);
var i:int = 0
var length:int = args.length
for (; i<length;i++){
addListener(args[i]);
}
_items = items.concat(args);
//call local helper to dispatch event
initChange("items",oldValue,_items,this);
return _items;
}
/**
* Executes a test function on each item in the array until an item is reached that returns false for the specified function.
*
* @see Array
**/
public function every(callback:Function, thisObject:* = null):Boolean{
return items.every(callback,thisObject);
}
/**
* Executes a test function on each item in the array and constructs a new array for all items that return true for the specified function.
*
* @see Array
**/
public function filter(callback:Function, thisObject:* = null):Array{
return items.filter(callback,thisObject);
}
/**
* Executes a function on each item in the array.
*
* @see Array
**/
public function forEach(callback:Function, thisObject:* = null):void{
items.forEach(callback, thisObject);
}
/**
* Searches for an item in an array by using strict equality (===) and returns the index position of the item.
*
* @see Array
**/
public function indexOf(searchElement:*, fromIndex:int = 0):int{
return items.indexOf(searchElement, fromIndex);
}
/**
* Converts the elements in an array to strings, inserts the specified separator between the elements, concatenates them, and returns the resulting string.
*
* @see Array
**/
public function join(sep:*):String{
return items.join(sep);
}
/**
* Searches for an item in an array, working backward from the last item, and returns the index position of the matching item using strict equality (===).
*
* @see Array
**/
public function lastIndexOf(searchElement:*, fromIndex:int = 0x7fffffff):int{
return items.lastIndexOf(searchElement, fromIndex);
}
/**
* Executes a function on each item in an array, and constructs a new array of items corresponding to the results of the function on each item in the original array.
*
* @see Array
**/
public function map(callback:Function, thisObject:* = null):Array{
return items.map(callback, thisObject);
}
/**
* Removes the last element from an array and returns the value of that element.
*
* @see Array
**/
public function pop():*{
removeListener(items[items.length-1]);
var oldValue:Array = _items;
var item:* =items.pop();
//call local helper to dispatch event
initChange("items",oldValue,_items,this);
return item;
}
/**
* Adds one or more elements to the end of an array and returns the new length of the array.
*
* @see Array
**/
public function push(... args):uint{
var oldValue:Array = _items;
//type check item(s)
checkValidTypes(args);
var i:int=0;
var len:int=args.length;
for (i; i<len;i++){
addListener(args[i]);
items.push(args[i]);
}
//call local helper to dispatch event
initChange("items",oldValue,_items,this);
return items.length;
}
/**
* Reverses the array in place.
*
* @see Array
**/
public function reverse():Array{
var oldValue:Array = _items;
items = items.reverse();
//call local helper to dispatch event
initChange("items",oldValue,_items,this);
return items;
}
/**
* Removes the first element from an array and returns that element.
*
* @see Array
**/
public function shift():*{
removeListener(items[0]);
var oldValue:Array = _items;
var item:* =items.shift();
//call local helper to dispatch event
initChange("items",oldValue,_items,this);
return item;
}
/**
* Returns a new array that consists of a range of elements from the original array, without modifying the original array.
*
* @see Array
**/
public function slice(startIndex:int = 0, endIndex:int = 16777215):Array{
return items.slice(startIndex, endIndex);
}
/**
* Executes a test function on each item in the array until an item is reached that returns true.
*
* @see Array
**/
public function some(callback:Function, thisObject:* = null):Boolean{
return items.some(callback, thisObject);
}
/**
* Sorts the elements in an array.
*
* @see Array
**/
public function sort(... args):Array{
return items.sort(args);
}
/**
* Sorts the elements in an array according to one or more fields in the array.
*
* @see Array
**/
public function sortOn(fieldName:Object, options:Object = null):Array{
return items.sortOn(fieldName,options);
}
/**
* Adds elements to and removes elements from an array.
*
* @see Array
**/
public function splice(startIndex:int, deleteCount:uint, ... values):Array{
//type check item(s)
checkValidTypes(values);
var i:int=0;
var len:int=values.length;
for (i; i<len;i++){
addListener(values[i]);
}
var oldValue:Array = _items;
var returnArray:Array
if(values.length == 1){
returnArray=_items.splice(startIndex,deleteCount,values[0]);
}
else if(values.length > 1){
returnArray=_items.splice(startIndex,deleteCount,values);
}
else{
returnArray=_items.splice(startIndex,deleteCount);
}
if(returnArray){
len=returnArray.length;
for (i= 0; i<len;i++){
removeListener(returnArray[i]);
}
}
//call local helper to dispatch event
initChange("items",oldValue,_items,this);
return returnArray;
}
/**
* Adds one or more elements to the beginning of an array and returns the new length of the array.
*
* @see Array
**/
public function unshift(... args):uint{
//type check item(s)
checkValidTypes(args);
var oldValue:Array = _items;
var i:int=0;
var len:int=args.length;
for (i; i<len;i++){
addListener(args[i]);
items.unshift(args[i]);
}
//call local helper to dispatch event
initChange("items",oldValue,_items,this);
return items.length;
}
/**
* Gets a cursor for the items Array
*/
protected var _cursor:DegrafaCursor;
public function get cursor():DegrafaCursor
{
if(!_cursor)
_cursor = new DegrafaCursor(items);
return _cursor;
}
}
}

View File

@ -0,0 +1,242 @@
////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2008 The Degrafa Team : http://www.Degrafa.com/team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
////////////////////////////////////////////////////////////////////////////////
package com.degrafa.core.collections
{
import mx.collections.CursorBookmark;
/**
* The DegrafaCursor is a class that aids enumeration and modification of the enclosed Array.
*/
public class DegrafaCursor
{
public var source:Array;
/**
* The value representing the current location of the cursor.
*/
public var currentIndex:int;
protected static const BEFORE_FIRST_INDEX:int = -1;
protected static const AFTER_LAST_INDEX:int = -2;
/**
* @param source A reference to the enclosed Array.
*/
public function DegrafaCursor(source:Array)
{
this.source = source;
currentIndex = BEFORE_FIRST_INDEX;
}
/**
* Returns the Object at the currentIndex.
* If the currentIndex is before the first index, a null value is returned;
*
* @return Object or null.
*/
public function get current():*
{
if(currentIndex > BEFORE_FIRST_INDEX)
return source[currentIndex];
else
return null;
}
/**
* Moves the cursor up one item in the currentIndex unless it is at the end.
*
* @return Boolean value of whether or not the cursor is at the end of the array.
*
*/
public function moveNext():Boolean
{
//the afterLast getter checks validity and also checks length > 0
if (afterLast)
{
return false;
}
// we can't set the index until we know that we can move there first.
var tempIndex:int = beforeFirst ? 0 : currentIndex + 1;
if (tempIndex >= source.length)
{
tempIndex = AFTER_LAST_INDEX;
}
currentIndex = tempIndex;
return !afterLast;
}
/**
* Moves the cursor down one item in the currentIndex unless it is at the beginning.
*
* @return Boolean value of whether or not the cursor is at the beginning of the array.
*
*/
public function movePrevious():Boolean
{
//the afterLast getter checks validity and also checks length > 0
if (beforeFirst)
{
return false;
}
// we can't set the index until we know that we can move there first
var tempIndex:int = afterLast ? source.length - 1 : currentIndex - 1;
currentIndex = tempIndex;
return !beforeFirst;
}
/**
* Moves cursor to the front.
*/
public function moveFirst():void
{
currentIndex = BEFORE_FIRST_INDEX;
}
/**
* Moves cursor to the end.
*/
public function moveLast():void
{
currentIndex = source.length;
}
/**
* Inserts a Object into the array at the currentIndex.
*
* @param value The Object to be inserted into the array.
*
*/
public function insert(value:*):void
{
var insertIndex:int;
if (afterLast || beforeFirst)
{
source.push(value);
}
else
{
source.splice(currentIndex, 0, value);
}
}
/**
* Removes a Object from the array at the currentIndex.
*
* @return The Object removed from the array.
*/
public function remove():*
{
var value:Object = source[currentIndex];
source = source.splice(currentIndex, 1);
return value;
}
/**
* Moves the currentIndex using the bookmark and offset.
*
* @param bookmark CursorBookmark used to assist the seek. The enumeration values are FIRST, CURRENT, LAST.
* @param offset Number of places away from the bookmark the currentIndex should be moved.
*/
public function seek(bookmark:CursorBookmark, offset:int = 0):void
{
if (source.length == 0)
{
currentIndex = AFTER_LAST_INDEX;
return;
}
var newIndex:int = currentIndex;
if (bookmark == CursorBookmark.FIRST)
{
newIndex = 0;
}
else if (bookmark == CursorBookmark.LAST)
{
newIndex = source.length - 1;
}
newIndex += offset;
if (newIndex >= source.length)
{
currentIndex = AFTER_LAST_INDEX;
}
else if (newIndex < 0)
{
currentIndex = BEFORE_FIRST_INDEX;
}
else
{
currentIndex = newIndex;
}
}
/**
* Checks whether or not the cursor is before the first item.
*/
public function get beforeFirst():Boolean
{
return currentIndex == BEFORE_FIRST_INDEX || source.length == 0;
}
/**
* Checks whether or not the cursor is after the last item.
*/
public function get afterLast():Boolean
{
return currentIndex == AFTER_LAST_INDEX || source.length == 0;
}
/**
* Gets the Object before the currentIndex
*/
public function get previousObject():*
{
if (beforeFirst)
return null;
var tempIndex:int = afterLast ? source.length - 1 : currentIndex - 1;
if (tempIndex == BEFORE_FIRST_INDEX)
return null;
return source[tempIndex];
}
/**
* Gets the Object after the currentIndex
*/
public function get nextObject():*
{
if(afterLast)
return null;
var tempIndex:int = beforeFirst ? 0 : currentIndex + 1;
if (tempIndex >= source.length)
return null;
return source[tempIndex];
}
}
}

View File

@ -0,0 +1,137 @@
////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2008 The Degrafa Team : http://www.Degrafa.com/team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
////////////////////////////////////////////////////////////////////////////////
package com.degrafa.core.collections{
import flash.display.DisplayObject;
/**
* The DisplayObjectCollection stores a collection of flash.display.DisplayObject
* objects.
**/
public class DisplayObjectCollection extends DegrafaCollection{
/**
* Constructor.
*
* <p>The display object collection constructor accepts 2 optional arguments
* that specify the display objects to be added and a event operation flag.</p>
*
* @param array An array of DisplayObject objects.
* @param suppressEvents A boolean value indicating if events should not be
* dispatched for this collection.
*/
public function DisplayObjectCollection(array:Array=null,suppressEvents:Boolean=false){
super(DisplayObject,array,suppressEvents);
}
/**
* Adds a DisplayObject item to the collection.
*
* @param value The DisplayObject object to be added.
* @return The DisplayObject object that was added.
**/
public function addItem(value:DisplayObject):DisplayObject{
return super._addItem(value);
}
/**
* Removes an DisplayObject item from the collection.
*
* @param value The DisplayObject object to be removed.
* @return The DisplayObject object that was removed.
**/
public function removeItem(value:DisplayObject):DisplayObject{
return super._removeItem(value);
}
/**
* Retrieve a DisplayObject item from the collection based on the index value
* requested.
*
* @param index The collection index of the DisplayObject object to retrieve.
* @return The DisplayObject object that was requested if it exists.
**/
public function getItemAt(index:Number):DisplayObject{
return super._getItemAt(index);
}
/**
* Retrieve a DisplayObject item from the collection based on the object value.
*
* @param value The DisplayObject object for which the index is to be retrieved.
* @return The DisplayObject index value that was requested if it exists.
**/
public function getItemIndex(value:DisplayObject):int{
return super._getItemIndex(value);
}
/**
* Adds a DisplayObject item to this collection at the specified index.
*
* @param value The DisplayObject object that is to be added.
* @param index The position in the collection at which to add the DisplayObject object.
*
* @return The DisplayObject object that was added.
**/
public function addItemAt(value:DisplayObject,index:Number):DisplayObject{
return super._addItemAt(value,index);
}
/**
* Removes a DisplayObject object from this collection at the specified index.
*
* @param index The index of the DisplayObject object to remove.
* @return The DisplayObject object that was removed.
**/
public function removeItemAt(index:Number):DisplayObject{
return super._removeItemAt(index);
}
/**
* Change the index of the DisplayObject object within this collection.
*
* @param value The DisplayObject object that is to be repositioned.
* @param newIndex The position at which to place the DisplayObject object within the collection.
* @return True if the operation is successful False if unsuccessful.
**/
public function setItemIndex(value:DisplayObject,newIndex:Number):Boolean{
return super._setItemIndex(value,newIndex);
}
/**
* Adds a series of DisplayObject objects to this collection.
*
* @param value The collection to be added to this DisplayObject collection.
* @return The resulting DisplayObjectCollection after the objects are added.
**/
public function addItems(value:DisplayObjectCollection):DisplayObjectCollection{
//todo
super.concat(value.items)
return this;
}
}
}

View File

@ -0,0 +1,135 @@
////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2008 The Degrafa Team : http://www.Degrafa.com/team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
////////////////////////////////////////////////////////////////////////////////
package com.degrafa.core.collections{
import com.degrafa.core.IGraphicsFill;
/**
* The FillCollection stores a collection of IGraphicsFill objects
**/
public class FillCollection extends DegrafaCollection{
/**
* Constructor.
*
* <p>The fill collection constructor accepts 2 optional arguments
* that specify the fills to be added and a event operation flag.</p>
*
* @param array An array of IGraphicsFill objects.
* @param suppressEvents A boolean value indicating if events should not be
* dispatched for this collection.
*/
public function FillCollection(array:Array=null,suppressEvents:Boolean=false){
super(IGraphicsFill,array,suppressEvents);
}
/**
* Adds a IGraphicsFill item to the collection.
*
* @param value The IGraphicsFill object to be added.
* @return The IGraphicsFill object that was added.
**/
public function addItem(value:IGraphicsFill):IGraphicsFill{
return super._addItem(value);
}
/**
* Removes an IGraphicsFill item from the collection.
*
* @param value The IGraphicsFill object to be removed.
* @return The IGraphicsFill object that was removed.
**/
public function removeItem(value:IGraphicsFill):IGraphicsFill{
return super._removeItem(value);
}
/**
* Retrieve a IGraphicsFill item from the collection based on the index value
* requested.
*
* @param index The collection index of the IGraphicsFill object to retrieve.
* @return The IGraphicsFill object that was requested if it exists.
**/
public function getItemAt(index:Number):IGraphicsFill{
return super._getItemAt(index);
}
/**
* Retrieve a IGraphicsFill item from the collection based on the object value.
*
* @param value The IGraphicsFill object for which the index is to be retrieved.
* @return The IGraphicsFill index value that was requested if it exists.
**/
public function getItemIndex(value:IGraphicsFill):int{
return super._getItemIndex(value);
}
/**
* Adds a IGraphicsFill item to this collection at the specified index.
*
* @param value The IGraphicsFill object that is to be added.
* @param index The position in the collection at which to add the IGraphicsFill object.
*
* @return The IGraphicsFill object that was added.
**/
public function addItemAt(value:IGraphicsFill,index:Number):IGraphicsFill{
return super._addItemAt(value,index);
}
/**
* Removes a IGraphicsFill object from this collection at the specified index.
*
* @param index The index of the IGraphicsFill object to remove.
* @return The IGraphicsFill object that was removed.
**/
public function removeItemAt(index:Number):IGraphicsFill{
return super._removeItemAt(index);
}
/**
* Change the index of the IGraphicsFill object within this collection.
*
* @param value The IGraphicsFill object that is to be repositioned.
* @param newIndex The position at which to place the IGraphicsFill object within the collection.
* @return True if the operation is successful False if unsuccessful.
**/
public function setItemIndex(value:IGraphicsFill,newIndex:Number):Boolean{
return super._setItemIndex(value,newIndex);
}
/**
* Adds a series of IGraphicsFill objects to this collection.
*
* @param value The collection to be added to this IGraphicsFill collection.
* @return The resulting FillCollection after the objects are added.
**/
public function addItems(value:FillCollection):FillCollection{
//todo
super.concat(value.items)
return this;
}
}
}

View File

@ -0,0 +1,194 @@
////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2008 The Degrafa Team : http://www.Degrafa.com/team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
////////////////////////////////////////////////////////////////////////////////
package com.degrafa.core.collections{
import com.degrafa.filters.DegrafaFilter;
import flash.filters.BitmapFilter;
import mx.events.PropertyChangeEvent;
/**
* The FilterCollection stores a collection of BitmapFilter objects
**/
public class FilterCollection extends DegrafaCollection{
/**
* Constructor.
*
* <p>The filter collection constructor accepts 2 optional arguments
* that specify the filters to be added and a event operation flag.</p>
*
* @param array An array of BitmapFilter objects.
* @param suppressEvents A boolean value indicating if events should not be
* dispatched for this collection.
*/
public function FilterCollection(array:Array=null,suppressEvents:Boolean=false){
super(BitmapFilter,array,suppressEvents);
}
//Internal list of watched degrafa filter proxies
private var degrafaFilters:Array=[];
override public function set items(value:Array):void
{
if (!value)
value=[];
removeAllWatchers();
degrafaFilters=[];
var actualFilters:Array=[];
var i:uint;
for (i=0; i < value.length; i++)
{
var item:*=value[i];
var df:DegrafaFilter=item as DegrafaFilter;
if (df)
{
actualFilters.push(df.bitmapFilter);
degrafaFilters.push(df);
addWatcher(df);
}
else
{
actualFilters.push(item);
}
}
super.items=actualFilters;
}
private function removeAllWatchers():void
{
for each (var df:DegrafaFilter in degrafaFilters)
{
df.removeEventListener(PropertyChangeEvent.PROPERTY_CHANGE, filterPropertyChangeHandler);
}
}
private function addWatcher(df:DegrafaFilter):void
{
df.addEventListener(PropertyChangeEvent.PROPERTY_CHANGE, filterPropertyChangeHandler, false, 0, true);
}
private function filterPropertyChangeHandler(event:PropertyChangeEvent):void
{
var actualFilter:BitmapFilter=DegrafaFilter(event.target).bitmapFilter;
dispatchPropertyChange(false, event.property, event.oldValue, event.newValue, actualFilter);
}
/**
* Adds a BitmapFilter item to the collection.
*
* @param value The BitmapFilter object to be added.
* @return The BitmapFilter object that was added.
**/
public function addItem(value:BitmapFilter):BitmapFilter{
return super._addItem(value);
}
/**
* Removes an BitmapFilter item from the collection.
*
* @param value The BitmapFilter object to be removed.
* @return The BitmapFilter object that was removed.
**/
public function removeItem(value:BitmapFilter):BitmapFilter{
return super._removeItem(value);
}
/**
* Retrieve a BitmapFilter item from the collection based on the index value
* requested.
*
* @param index The collection index of the BitmapFilter object to retrieve.
* @return The BitmapFilter object that was requested if it exists.
**/
public function getItemAt(index:Number):BitmapFilter{
return super._getItemAt(index);
}
/**
* Retrieve a BitmapFilter item from the collection based on the object value.
*
* @param value The BitmapFilter object for which the index is to be retrieved.
* @return The BitmapFilter index value that was requested if it exists.
**/
public function getItemIndex(value:BitmapFilter):int{
return super._getItemIndex(value);
}
/**
* Adds a BitmapFilter item to this collection at the specified index.
*
* @param value The BitmapFilter object that is to be added.
* @param index The position in the collection at which to add the BitmapFilter object.
*
* @return The BitmapFilter object that was added.
**/
public function addItemAt(value:BitmapFilter,index:Number):BitmapFilter{
return super._addItemAt(value,index);
}
/**
* Removes a BitmapFilter object from this collection at the specified index.
*
* @param index The index of the BitmapFilter object to remove.
* @return The BitmapFilter object that was removed.
**/
public function removeItemAt(index:Number):BitmapFilter{
return super._removeItemAt(index);
}
/**
* Change the index of the BitmapFilter object within this collection.
*
* @param value The BitmapFilter object that is to be repositioned.
* @param newIndex The position at which to place the BitmapFilter object within the collection.
* @return True if the operation is successful False if unsuccessful.
**/
public function setItemIndex(value:BitmapFilter,newIndex:Number):Boolean{
return super._setItemIndex(value,newIndex);
}
/**
* Adds a series of BitmapFilter objects to this collection.
*
* @param value The collection to be added to this BitmapFilter collection.
* @return The resulting FillCollection after the objects are added.
**/
public function addItems(value:FilterCollection):FilterCollection{
//todo
super.concat(value.items)
return this;
}
}
}

View File

@ -0,0 +1,134 @@
////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2008 The Degrafa Team : http://www.Degrafa.com/team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
////////////////////////////////////////////////////////////////////////////////
package com.degrafa.core.collections{
import com.degrafa.IGeometry;
/**
* The GeometryCollection stores a collection of IGeometry objects
**/
public class GeometryCollection extends DegrafaCollection{
/**
* Constructor.
*
* <p>The geometry collection constructor accepts 2 optional arguments
* that specify the geometry objects to be added and a event operation flag.</p>
*
* @param array An array of IGeometry objects.
* @param suppressEvents A boolean value indicating if events should not be
* dispatched for this collection.
*/
public function GeometryCollection(array:Array=null,suppressEvents:Boolean=false){
super(IGeometry,array,suppressEvents);
}
/**
* Adds a IGeometry item to the collection.
*
* @param value The IGeometry object to be added.
* @return The IGeometry object that was added.
**/
public function addItem(value:IGeometry):IGeometry{
return super._addItem(value);
}
/**
* Removes an IGeometry item from the collection.
*
* @param value The IGeometry object to be removed.
* @return The IGeometry object that was removed.
**/
public function removeItem(value:IGeometry):IGeometry{
return super._removeItem(value);
}
/**
* Retrieve a IGeometry item from the collection based on the index value
* requested.
*
* @param index The collection index of the IGeometry object to retrieve.
* @return The IGeometry object that was requested if it exists.
**/
public function getItemAt(index:Number):IGeometry{
return super._getItemAt(index);
}
/**
* Retrieve a IGeometry item from the collection based on the object value.
*
* @param value The IGeometry object for which the index is to be retrieved.
* @return The IGeometry index value that was requested if it exists.
**/
public function getItemIndex(value:IGeometry):int{
return super._getItemIndex(value);
}
/**
* Adds a IGeometry item to this collection at the specified index.
*
* @param value The IGeometry object that is to be added.
* @param index The position in the collection at which to add the IGeometry object.
*
* @return The IGeometry object that was added.
**/
public function addItemAt(value:IGeometry,index:Number):IGeometry{
return super._addItemAt(value,index);
}
/**
* Removes a IGeometry object from this collection at the specified index.
*
* @param index The index of the IGeometry object to remove.
* @return The IGeometry object that was removed.
**/
public function removeItemAt(index:Number):IGeometry{
return super._removeItemAt(index);
}
/**
* Change the index of the IGeometry object within this collection.
*
* @param value The IGeometry object that is to be repositioned.
* @param newIndex The position at which to place the IGeometry object within the collection.
* @return True if the operation is successful False if unsuccessful.
**/
public function setItemIndex(value:IGeometry,newIndex:Number):Boolean{
return super._setItemIndex(value,newIndex);
}
/**
* Adds a series of IGeometry objects to this collection.
*
* @param value The collection to be added to this IGeometry collection.
* @return The resulting GeometryCollection after the objects are added.
**/
public function addItems(value:GeometryCollection):GeometryCollection{
//todo
super.concat(value.items)
return this;
}
}
}

View File

@ -0,0 +1,132 @@
////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2008 The Degrafa Team : http://www.Degrafa.com/team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
////////////////////////////////////////////////////////////////////////////////
package com.degrafa.core.collections{
import com.degrafa.paint.GradientStop;
/**
* The GradientStopsCollection stores a collection of GradientStop objects
**/
public class GradientStopsCollection extends DegrafaCollection{
/**
* Constructor.
*
* <p>The gradient stops collection constructor accepts 2 optional arguments
* that specify the gradient stops to be added and a event operation flag.</p>
*
* @param array An array of GradientStop objects.
* @param suppressEvents A boolean value indicating if events should not be
* dispatched for this collection.
*/
public function GradientStopsCollection(array:Array=null,suppressEvents:Boolean=false){
super(GradientStop,array,suppressEvents);
}
/**
* Adds a GradientStop item to the collection.
*
* @param value The GradientStop object to be added.
* @return The GradientStop object that was added.
**/
public function addItem(value:GradientStop):GradientStop{
return super._addItem(value);
}
/**
* Removes an GradientStop item from the collection.
*
* @param value The GradientStop object to be removed.
* @return The GradientStop object that was removed.
**/
public function removeItem(value:GradientStop):GradientStop{
return super._removeItem(value);
}
/**
* Retrieve a GradientStop item from the collection based on the index value
* requested.
*
* @param index The collection index of the GradientStop object to retrieve.
* @return The GradientStop object that was requested if it exists.
**/
public function getItemAt(index:Number):GradientStop{
return super._getItemAt(index);
}
/**
* Retrieve a GradientStop item from the collection based on the object value.
*
* @param value The GradientStop object for which the index is to be retrieved.
* @return The GradientStop index value that was requested if it exists.
**/
public function getItemIndex(value:GradientStop):int{
return super._getItemIndex(value);
}
/**
* Adds a GradientStop item to this collection at the specified index.
*
* @param value The GradientStop object that is to be added.
* @param index The position in the collection at which to add the GradientStop object.
*
* @return The GradientStop object that was added.
**/
public function addItemAt(value:GradientStop,index:Number):GradientStop{
return super._addItemAt(value,index);
}
/**
* Removes a GradientStop object from this collection at the specified index.
*
* @param index The index of the GradientStop object to remove.
* @return The GradientStop object that was removed.
**/
public function removeItemAt(index:Number):GradientStop{
return super._removeItemAt(index);
}
/**
* Change the index of the GradientStop object within this collection.
*
* @param value The GradientStop object that is to be repositioned.
* @param newIndex The position at which to place the GradientStop object within the collection.
* @return True if the operation is successful False if unsuccessful.
**/
public function setItemIndex(value:GradientStop,newIndex:Number):Boolean{
return super._setItemIndex(value,newIndex);
}
/**
* Adds a series of GradientStop objects to this collection.
*
* @param value The collection to be added to this GradientStop collection.
* @return The resulting GradientStopsCollection after the objects are added.
**/
public function addItems(value:GradientStopsCollection):GradientStopsCollection{
//todo
super.concat(value.items)
return this;
}
}
}

View File

@ -0,0 +1,134 @@
////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2008 The Degrafa Team : http://www.Degrafa.com/team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
////////////////////////////////////////////////////////////////////////////////
package com.degrafa.core.collections{
import com.degrafa.IGraphicPoint;
/**
* The GraphicPointCollection stores a collection of IGraphicPoint objects
**/
public class GraphicPointCollection extends DegrafaCollection{
/**
* Constructor.
*
* <p>The graphic point collection constructor accepts 2 optional arguments
* that specify the graphic points to be added and a event operation flag.</p>
*
* @param array An array of IGraphicPoint objects.
* @param suppressEvents A boolean value indicating if events should not be
* dispatched for this collection.
*/
public function GraphicPointCollection(array:Array=null,suppressEvents:Boolean=false){
super(IGraphicPoint,array,suppressEvents);
}
/**
* Adds a IGraphicPoint item to the collection.
*
* @param value The IGraphicPoint object to be added.
* @return The IGraphicPoint object that was added.
**/
public function addItem(value:IGraphicPoint):IGraphicPoint{
return super._addItem(value);
}
/**
* Removes an IGraphicPoint item from the collection.
*
* @param value The IGraphicPoint object to be removed.
* @return The IGraphicPoint object that was removed.
**/
public function removeItem(value:IGraphicPoint):IGraphicPoint{
return super._removeItem(value);
}
/**
* Retrieve a IGraphicPoint item from the collection based on the index value
* requested.
*
* @param index The collection index of the IGraphicPoint object to retrieve.
* @return The IGraphicPoint object that was requested if it exists.
**/
public function getItemAt(index:Number):IGraphicPoint{
return super._getItemAt(index);
}
/**
* Retrieve a IGraphicPoint item from the collection based on the object value.
*
* @param value The IGraphicPoint object for which the index is to be retrieved.
* @return The IGraphicPoint index value that was requested if it exists.
**/
public function getItemIndex(value:IGraphicPoint):int{
return super._getItemIndex(value);
}
/**
* Adds a IGraphicPoint item to this collection at the specified index.
*
* @param value The IGraphicPoint object that is to be added.
* @param index The position in the collection at which to add the IGraphicPoint object.
*
* @return The IGraphicPoint object that was added.
**/
public function addItemAt(value:IGraphicPoint,index:Number):IGraphicPoint{
return super._addItemAt(value,index);
}
/**
* Removes a IGraphicPoint object from this collection at the specified index.
*
* @param index The index of the IGraphicPoint object to remove.
* @return The IGraphicPoint object that was removed.
**/
public function removeItemAt(index:Number):IGraphicPoint{
return super._removeItemAt(index);
}
/**
* Change the index of the IGraphicPoint object within this collection.
*
* @param value The IGraphicPoint object that is to be repositioned.
* @param newIndex The position at which to place the IGraphicPoint object within the collection.
* @return True if the operation is successful False if unsuccessful.
**/
public function setItemIndex(value:IGraphicPoint,newIndex:Number):Boolean{
return super._setItemIndex(value,newIndex);
}
/**
* Adds a series of IGraphicPoint objects to this collection.
*
* @param value The collection to be added to this IGraphicPoint collection.
* @return The resulting GraphicPointCollection after the objects are added.
**/
public function addItems(value:GraphicPointCollection):GraphicPointCollection{
//todo
super.concat(value.items)
return this;
}
}
}

View File

@ -0,0 +1,134 @@
////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2008 The Degrafa Team : http://www.Degrafa.com/team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
////////////////////////////////////////////////////////////////////////////////
package com.degrafa.core.collections{
import com.degrafa.GraphicPointEX;
/**
* The GraphicPointEXCollection stores a collection of GraphicPointEX objects
**/
public class GraphicPointEXCollection extends DegrafaCollection{
/**
* Constructor.
*
* <p>The extended graphic point collection constructor accepts 2 optional arguments
* that specify the graphic points to be added and a event operation flag.</p>
*
* @param array An array of GraphicPointEX objects.
* @param suppressEvents A boolean value indicating if events should not be
* dispatched for this collection.
*/
public function GraphicPointEXCollection(array:Array=null,suppressEvents:Boolean=false){
super(GraphicPointEX,array,suppressEvents);
}
/**
* Adds a GraphicPointEX item to the collection.
*
* @param value The GraphicPointEX object to be added.
* @return The GraphicPointEX object that was added.
**/
public function addItem(value:GraphicPointEX):GraphicPointEX{
return super._addItem(value);
}
/**
* Removes an GraphicPointEX item from the collection.
*
* @param value The GraphicPointEX object to be removed.
* @return The GraphicPointEX object that was removed.
**/
public function removeItem(value:GraphicPointEX):GraphicPointEX{
return super._removeItem(value);
}
/**
* Retrieve a GraphicPointEX item from the collection based on the index value
* requested.
*
* @param index The collection index of the GraphicPointEX object to retrieve.
* @return The GraphicPointEX object that was requested if it exists.
**/
public function getItemAt(index:Number):GraphicPointEX{
return super._getItemAt(index);
}
/**
* Retrieve a GraphicPointEX item from the collection based on the object value.
*
* @param value The GraphicPointEX object for which the index is to be retrieved.
* @return The GraphicPointEX index value that was requested if it exists.
**/
public function getItemIndex(value:GraphicPointEX):int{
return super._getItemIndex(value);
}
/**
* Adds a GraphicPointEX item to this collection at the specified index.
*
* @param value The GraphicPointEX object that is to be added.
* @param index The position in the collection at which to add the GraphicPointEX object.
*
* @return The GraphicPointEX object that was added.
**/
public function addItemAt(value:GraphicPointEX,index:Number):GraphicPointEX{
return super._addItemAt(value,index);
}
/**
* Removes a GraphicPointEX object from this collection at the specified index.
*
* @param index The index of the GraphicPointEX object to remove.
* @return The GraphicPointEX object that was removed.
**/
public function removeItemAt(index:Number):GraphicPointEX{
return super._removeItemAt(index);
}
/**
* Change the index of the GraphicPointEX object within this collection.
*
* @param value The GraphicPointEX object that is to be repositioned.
* @param newIndex The position at which to place the GraphicPointEX object within the collection.
* @return True if the operation is successful False if unsuccessful.
**/
public function setItemIndex(value:GraphicPointEX,newIndex:Number):Boolean{
return super._setItemIndex(value,newIndex);
}
/**
* Adds a series of GraphicPointEX objects to this collection.
*
* @param value The collection to be added to this GraphicPointEX collection.
* @return The resulting GraphicPointEXCollection after the objects are added.
**/
public function addItems(value:GraphicPointEXCollection):GraphicPointEXCollection{
//todo
super.concat(value.items)
return this;
}
}
}

View File

@ -0,0 +1,138 @@
////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2008 The Degrafa Team : http://www.Degrafa.com/team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
////////////////////////////////////////////////////////////////////////////////
package com.degrafa.core.collections{
//these subclasses are to make api access easier and to ensure
//the the correct types are returned.
import com.degrafa.core.IGraphicSkin;
/**
* The GraphicSkinCollection stores a collection of IGraphicSkin objects
**/
public class GraphicSkinCollection extends DegrafaCollection{
/**
* Constructor.
*
* <p>The graphic skin collection constructor accepts 2 optional arguments
* that specify the graphic skins to be added and a event operation flag.</p>
*
* @param array An array of IGraphicSkin objects.
* @param suppressEvents A boolean value indicating if events should not be
* dispatched for this collection.
*/
public function GraphicSkinCollection(array:Array=null,suppressEvents:Boolean=false){
super(IGraphicSkin,array,suppressEvents);
}
/**
* Adds a IGraphicSkin item to the collection.
*
* @param value The IGraphicSkin object to be added.
* @return The IGraphicSkin object that was added.
**/
public function addItem(value:IGraphicSkin):IGraphicSkin{
return super._addItem(value);
}
/**
* Removes an IGraphicSkin item from the collection.
*
* @param value The IGraphicSkin object to be removed.
* @return The IGraphicSkin object that was removed.
**/
public function removeItem(value:IGraphicSkin):IGraphicSkin{
return super._removeItem(value);
}
/**
* Retrieve a IGraphicSkin item from the collection based on the index value
* requested.
*
* @param index The collection index of the IGraphicSkin object to retrieve.
* @return The IGraphicSkin object that was requested if it exists.
**/
public function getItemAt(index:Number):IGraphicSkin{
return super._getItemAt(index);
}
/**
* Retrieve a IGraphicSkin item from the collection based on the object value.
*
* @param value The IGraphicSkin object for which the index is to be retrieved.
* @return The IGraphicSkin index value that was requested if it exists.
**/
public function getItemIndex(value:IGraphicSkin):int{
return super._getItemIndex(value);
}
/**
* Adds a IGraphicSkin item to this collection at the specified index.
*
* @param value The IGraphicSkin object that is to be added.
* @param index The position in the collection at which to add the IGraphicSkin object.
*
* @return The IGraphicSkin object that was added.
**/
public function addItemAt(value:IGraphicSkin,index:Number):IGraphicSkin{
return super._addItemAt(value,index);
}
/**
* Removes a IGraphicSkin object from this collection at the specified index.
*
* @param index The index of the IGraphicSkin object to remove.
* @return The IGraphicSkin object that was removed.
**/
public function removeItemAt(index:Number):IGraphicSkin{
return super._removeItemAt(index);
}
/**
* Change the index of the IGraphicSkin object within this collection.
*
* @param value The IGraphicSkin object that is to be repositioned.
* @param newIndex The position at which to place the IGraphicSkin object within the collection.
* @return True if the operation is successful False if unsuccessful.
**/
public function setItemIndex(value:IGraphicSkin,newIndex:Number):Boolean{
return super._setItemIndex(value,newIndex);
}
/**
* Adds a series of IGraphicSkin objects to this collection.
*
* @param value The collection to be added to this IGraphicSkin collection.
* @return The resulting GraphicSkinCollection after the objects are added.
**/
public function addItems(value:GraphicSkinCollection):GraphicSkinCollection{
//todo
super.concat(value.items)
return this;
}
}
}

View File

@ -0,0 +1,132 @@
////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2008 The Degrafa Team : http://www.Degrafa.com/team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
////////////////////////////////////////////////////////////////////////////////
package com.degrafa.core.collections{
import com.degrafa.IGraphic;
/**
* The GraphicsCollection stores a collection of IGraphic objects
**/
public class GraphicsCollection extends DegrafaCollection{
/**
* Constructor.
*
* <p>The graphics collection constructor accepts 2 optional arguments
* that specify the graphics to be added and a event operation flag.</p>
*
* @param array An array of IGraphic objects.
* @param suppressEvents A boolean value indicating if events should not be
* dispatched for this collection.
*/
public function GraphicsCollection(array:Array=null,suppressEvents:Boolean=false){
super(IGraphic,array,suppressEvents);
}
/**
* Adds a IGraphic item to the collection.
*
* @param value The IGraphic object to be added.
* @return The IGraphic object that was added.
**/
public function addItem(value:IGraphic):IGraphic{
return super._addItem(value);
}
/**
* Removes an IGraphic item from the collection.
*
* @param value The IGraphic object to be removed.
* @return The IGraphic object that was removed.
**/
public function removeItem(value:IGraphic):IGraphic{
return super._removeItem(value);
}
/**
* Retrieve a IGraphic item from the collection based on the index value
* requested.
*
* @param index The collection index of the IGraphic object to retrieve.
* @return The IGraphic object that was requested if it exists.
**/
public function getItemAt(index:Number):IGraphic{
return super._getItemAt(index);
}
/**
* Retrieve a IGraphic item from the collection based on the object value.
*
* @param value The IGraphic object for which the index is to be retrieved.
* @return The IGraphic index value that was requested if it exists.
**/
public function getItemIndex(value:IGraphic):int{
return super._getItemIndex(value);
}
/**
* Adds a IGraphic item to this collection at the specified index.
*
* @param value The IGraphic object that is to be added.
* @param index The position in the collection at which to add the IGraphic object.
*
* @return The IGraphic object that was added.
**/
public function addItemAt(value:IGraphic,index:Number):IGraphic{
return super._addItemAt(value,index);
}
/**
* Removes a IGraphic object from this collection at the specified index.
*
* @param index The index of the IGraphic object to remove.
* @return The IGraphic object that was removed.
**/
public function removeItemAt(index:Number):IGraphic{
return super._removeItemAt(index);
}
/**
* Change the index of the IGraphic object within this collection.
*
* @param value The IGraphic object that is to be repositioned.
* @param newIndex The position at which to place the IGraphic object within the collection.
* @return True if the operation is successful False if unsuccessful.
**/
public function setItemIndex(value:IGraphic,newIndex:Number):Boolean{
return super._setItemIndex(value,newIndex);
}
/**
* Adds a series of IGraphic objects to this collection.
*
* @param value The collection to be added to this IGraphic collection.
* @return The resulting GraphicsCollection after the objects are added.
**/
public function addItems(value:GraphicsCollection):GraphicsCollection{
//todo
super.concat(value.items)
return this;
}
}
}

View File

@ -0,0 +1,34 @@
////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2008 The Degrafa Team : http://www.Degrafa.com/team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
////////////////////////////////////////////////////////////////////////////////
package com.degrafa.core.collections{
import com.degrafa.core.IDegrafaObject;
/**
* Base interface for all Degrafa collection classes.
**/
public interface IDegrafaCollection extends IDegrafaObject{
function get items():Array
function set items(value:Array):void
}
}

View File

@ -0,0 +1,133 @@
////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2008 The Degrafa Team : http://www.Degrafa.com/team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
////////////////////////////////////////////////////////////////////////////////
package com.degrafa.core.collections{
import com.degrafa.repeaters.IRepeaterModifier;
/**
* The RepeaterModifierCollection stores a collection of RepeaterModifier objects
**/
public class RepeaterModifierCollection extends DegrafaCollection{
/**
* Constructor.
*
* <p>The repeater modifier collection constructor accepts 2 optional arguments
* that specify the repeater modifiers to be added and a event operation flag.</p>
*
* @param array An array of RepeaterModifier objects.
* @param suppressEvents A boolean value indicating if events should not be
* dispatched for this collection.
*/
public function RepeaterModifierCollection(array:Array=null,suppressEvents:Boolean=false){
super(IRepeaterModifier,array,suppressEvents);
}
/**
* Adds a RepeaterModifier item to the collection.
*
* @param value The RepeaterModifier object to be added.
* @return The RepeaterModifier object that was added.
**/
public function addItem(value:IRepeaterModifier):IRepeaterModifier{
return super._addItem(value);
}
/**
* Removes an RepeaterModifier item from the collection.
*
* @param value The RepeaterModifier object to be removed.
* @return The RepeaterModifier object that was removed.
**/
public function removeItem(value:IRepeaterModifier):IRepeaterModifier{
return super._removeItem(value);
}
/**
* Retrieve a RepeaterModifier item from the collection based on the index value
* requested.
*
* @param index The collection index of the RepeaterModifier object to retrieve.
* @return The RepeaterModifier object that was requested if it exists.
**/
public function getItemAt(index:Number):IRepeaterModifier{
return super._getItemAt(index);
}
/**
* Retrieve a RepeaterModifier item from the collection based on the object value.
*
* @param value The RepeaterModifier object for which the index is to be retrieved.
* @return The RepeaterModifier index value that was requested if it exists.
**/
public function getItemIndex(value:IRepeaterModifier):int{
return super._getItemIndex(value);
}
/**
* Adds a RepeaterModifier item to this collection at the specified index.
*
* @param value The RepeaterModifier object that is to be added.
* @param index The position in the collection at which to add the RepeaterModifier object.
*
* @return The RepeaterModifier object that was added.
**/
public function addItemAt(value:IRepeaterModifier,index:Number):IRepeaterModifier{
return super._addItemAt(value,index);
}
/**
* Removes a RepeaterModifier object from this collection at the specified index.
*
* @param index The index of the RepeaterModifier object to remove.
* @return The RepeaterModifier object that was removed.
**/
public function removeItemAt(index:Number):IRepeaterModifier{
return super._removeItemAt(index);
}
/**
* Change the index of the RepeaterModifier object within this collection.
*
* @param value The RepeaterModifier object that is to be repositioned.
* @param newIndex The position at which to place the RepeaterModifier object within the collection.
* @return True if the operation is successful False if unsuccessful.
**/
public function setItemIndex(value:IRepeaterModifier,newIndex:Number):Boolean{
return super._setItemIndex(value,newIndex);
}
/**
* Adds a series of RepeaterModifier objects to this collection.
*
* @param value The collection to be added to this RepeaterModifier collection.
* @return The resulting RepeaterModifiersCollection after the objects are added.
**/
public function addItems(value:RepeaterModifierCollection):RepeaterModifierCollection{
//todo
super.concat(value.items)
return this;
}
}
}

View File

@ -0,0 +1,134 @@
////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2008 The Degrafa Team : http://www.Degrafa.com/team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
////////////////////////////////////////////////////////////////////////////////
package com.degrafa.core.collections{
import com.degrafa.geometry.segment.ISegment;
/**
* The SegmentsCollection stores a collection of ISegment objects
**/
public class SegmentsCollection extends DegrafaCollection{
/**
* Constructor.
*
* <p>The segments collection constructor accepts 2 optional arguments
* that specify the segments to be added and a event operation flag.</p>
*
* @param array An array of ISegment objects.
* @param suppressEvents A boolean value indicating if events should be
* dispatched for this collection.
*/
public function SegmentsCollection(array:Array=null,suppressEvents:Boolean=false){
super(ISegment,array,suppressEvents);
}
/**
* Adds a ISegment item to the collection.
*
* @param value The ISegment object to be added.
* @return The ISegment object that was added.
**/
public function addItem(value:ISegment):ISegment{
return super._addItem(value);
}
/**
* Removes an ISegment item from the collection.
*
* @param value The ISegment object to be removed.
* @return The ISegment object that was removed.
**/
public function removeItem(value:ISegment):ISegment{
return super._removeItem(value);
}
/**
* Retrieve a ISegment item from the collection based on the index value
* requested.
*
* @param index The collection index of the ISegment object to retrieve.
* @return The ISegment object that was requested if it exists.
**/
public function getItemAt(index:Number):ISegment{
return super._getItemAt(index);
}
/**
* Retrieve a ISegment item from the collection based on the object value.
*
* @param value The ISegment object for which the index is to be retrieved.
* @return The ISegment index value that was requested if it exists.
**/
public function getItemIndex(value:ISegment):int{
return super._getItemIndex(value);
}
/**
* Adds a ISegment item to this collection at the specified index.
*
* @param value The ISegment object that is to be added.
* @param index The position in the collection at which to add the ISegment object.
*
* @return The ISegment object that was added.
**/
public function addItemAt(value:ISegment,index:Number):ISegment{
return super._addItemAt(value,index);
}
/**
* Removes a ISegment object from this collection at the specified index.
*
* @param index The index of the ISegment object to remove.
* @return The ISegment object that was removed.
**/
public function removeItemAt(index:Number):ISegment{
return super._removeItemAt(index);
}
/**
* Change the index of the ISegment object within this collection.
*
* @param value The ISegment object that is to be repositioned.
* @param newIndex The position at which to place the ISegment object within the collection.
* @return True if the operation is successful False if unsuccessful.
**/
public function setItemIndex(value:ISegment,newIndex:Number):Boolean{
return super._setItemIndex(value,newIndex);
}
/**
* Adds a series of ISegment objects to this collection.
*
* @param value The collection to be added to this ISegment collection.
* @return The resulting SegmentsCollection after the objects are added.
**/
public function addItems(value:SegmentsCollection):SegmentsCollection{
//todo
super.concat(value.items)
return this;
}
}
}

View File

@ -0,0 +1,132 @@
////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2008 The Degrafa Team : http://www.Degrafa.com/team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
////////////////////////////////////////////////////////////////////////////////
package com.degrafa.core.collections{
import com.degrafa.core.IGraphicsStroke;
/**
* The StrokeCollection stores a collection of IGraphicsStroke objects
**/
public class StrokeCollection extends DegrafaCollection{
/**
* Constructor.
*
* <p>The stroke collection constructor accepts 2 optional arguments
* that specify the strokes to be added and a event operation flag.</p>
*
* @param array An array of IGraphicsStroke objects.
* @param suppressEvents A boolean value indicating if events should be
* dispatched for this collection.
*/
public function StrokeCollection(array:Array=null,suppressEvents:Boolean=false){
super(IGraphicsStroke,array,suppressEvents);
}
/**
* Adds a IGraphicsStroke item to the collection.
*
* @param value The IGraphicsStroke object to be added.
* @return The IGraphicsStroke object that was added.
**/
public function addItem(value:IGraphicsStroke):IGraphicsStroke{
return super._addItem(value);
}
/**
* Removes an IGraphicsStroke item from the collection.
*
* @param value The IGraphicsStroke object to be removed.
* @return The IGraphicsStroke object that was removed.
**/
public function removeItem(value:IGraphicsStroke):IGraphicsStroke{
return super._removeItem(value);
}
/**
* Retrieve a IGraphicsStroke item from the collection based on the index value
* requested.
*
* @param index The collection index of the IGraphicsStroke object to retrieve.
* @return The IGraphicsStroke object that was requested if it exists.
**/
public function getItemAt(index:Number):IGraphicsStroke{
return super._getItemAt(index);
}
/**
* Retrieve a IGraphicsStroke item from the collection based on the object value.
*
* @param value The IGraphicsStroke object for which the index is to be retrieved.
* @return The IGraphicsStroke index value that was requested if it exists.
**/
public function getItemIndex(value:IGraphicsStroke):int{
return super._getItemIndex(value);
}
/**
* Adds a IGraphicsStroke item to this collection at the specified index.
*
* @param value The IGraphicsStroke object that is to be added.
* @param index The position in the collection at which to add the IGraphicsStroke object.
*
* @return The IGraphicsStroke object that was added.
**/
public function addItemAt(value:IGraphicsStroke,index:Number):IGraphicsStroke{
return super._addItemAt(value,index);
}
/**
* Removes a IGraphicsStroke object from this collection at the specified index.
*
* @param index The index of the IGraphicsStroke object to remove.
* @return The IGraphicsStroke object that was removed.
**/
public function removeItemAt(index:Number):IGraphicsStroke{
return super._removeItemAt(index);
}
/**
* Change the index of the IGraphicsStroke object within this collection.
*
* @param value The IGraphicsStroke object that is to be repositioned.
* @param newIndex The position at which to place the IGraphicsStroke object within the collection.
* @return True if the operation is successful False if unsuccessful.
**/
public function setItemIndex(value:IGraphicsStroke,newIndex:Number):Boolean{
return super._setItemIndex(value,newIndex);
}
/**
* Adds a series of IGraphicsStroke objects to this collection.
*
* @param value The collection to be added to this IGraphicsStroke collection.
* @return The resulting StrokeCollection after the objects are added.
**/
public function addItems(value:StrokeCollection):StrokeCollection{
//todo
super.concat(value.items)
return this;
}
}
}

View File

@ -0,0 +1,136 @@
////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2008 The Degrafa Team : http://www.Degrafa.com/team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
////////////////////////////////////////////////////////////////////////////////
package com.degrafa.core.collections{
import com.degrafa.transform.ITransform;
/**
* The TransformCollection stores a collection of ITransform objects
**/
public class TransformCollection extends DegrafaCollection{
/**
* Constructor.
*
* <p>The transform collection constructor accepts 2 optional arguments
* that specify the transforms to be added and a event operation flag.</p>
*
* @param array An array of ITransform objects.
* @param suppressEvents A boolean value indicating if events should be
* dispatched for this collection.
*/
public function TransformCollection(array:Array=null,suppressEvents:Boolean=false){
super(ITransform,array,suppressEvents);
}
/**
* Adds a ITransform item to the collection.
*
* @param value The ITransform object to be added.
* @return The ITransform object that was added.
**/
public function addItem(value:ITransform):ITransform{
return super._addItem(value);
}
/**
* Removes an ITransform item from the collection.
*
* @param value The ITransform object to be removed.
* @return The ITransform object that was removed.
**/
public function removeItem(value:ITransform):ITransform{
return super._removeItem(value);
}
/**
* Retrieve a ITransform item from the collection based on the index value
* requested.
*
* @param index The collection index of the ITransform object to retrieve.
* @return The ITransform object that was requested if it exists.
**/
public function getItemAt(index:Number):ITransform{
return super._getItemAt(index);
}
/**
* Adds a ITransform item to this collection at the specified index.
*
* @param value The ITransform object that is to be added.
* @param index The position in the collection at which to add the ITransform object.
*
* @return The ITransform object that was added.
**/
public function getItemIndex(value:ITransform):int{
return super._getItemIndex(value);
}
/**
* Adds a ITransform item to this collection at the specified index.
*
* @param value The ITransform object that is to be added.
* @param index The position in the collection at which to add the ITransform object.
*
* @return The ITransform object that was added.
**/
public function addItemAt(value:ITransform,index:Number):ITransform{
return super._addItemAt(value,index);
}
/**
* Removes a ITransform object from this collection at the specified index.
*
* @param index The index of the ITransform object to remove.
* @return The ITransform object that was removed.
**/
public function removeItemAt(index:Number):ITransform{
return super._removeItemAt(index);
}
/**
* Change the index of the ITransform object within this collection.
*
* @param value The ITransform object that is to be repositioned.
* @param newIndex The position at which to place the ITransform object within the collection.
* @return True if the operation is successful False if unsuccessful.
**/
public function setItemIndex(value:ITransform,newIndex:Number):Boolean{
return super._setItemIndex(value,newIndex);
}
/**
* Adds a series of ITransform objects to this collection.
*
* @param value The collection to be added to this ITransform collection.
* @return The resulting TransformCollection after the objects are added.
**/
public function addItems(value:TransformCollection):TransformCollection{
//todo
super.concat(value.items)
return this;
}
}
}

View File

@ -0,0 +1,11 @@
package com.degrafa.core
{
/**
* This namespace is used for undocumented APIs -- usually implementation
* details -- which can't be private because they need to visible
* to other classes.
*/
public namespace degrafa_internal = "http://www.degrafa.com/2009/internal";
}

View File

@ -0,0 +1,194 @@
////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2008 The Degrafa Team : http://www.Degrafa.com/team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
////////////////////////////////////////////////////////////////////////////////
package com.degrafa.core.manipulators{
import com.degrafa.core.DegrafaObject;
import com.degrafa.core.IGraphicSkin;
import com.degrafa.core.collections.GraphicSkinCollection;
import flash.display.DisplayObject;
import flash.display.DisplayObjectContainer;
import flash.events.Event;
import mx.events.FlexEvent;
import mx.events.PropertyChangeEvent;
[Bindable]
/**
* The DegrafaSkinManipulator allows one to tie in and manipulate the specified
* IGraphicSkin for an object. Degrafa Geometry, fills and strokes can then be
* manipulated and bound to like you would do with any other Degrafa graphic
* or geometry object. ** Experimental.
**/
public class DegrafaSkinManipulator extends DegrafaObject{
private var _target:DisplayObjectContainer;
/**
* Target UI Object for this manipulator
**/
public function get target():DisplayObjectContainer
{
return _target;
}
public function set target(value:DisplayObjectContainer):void{
if (!value){return;}
_target = value;
_target.addEventListener("added",onChildAdded);
//add the creation complete handler
_target.addEventListener(FlexEvent.CREATION_COMPLETE,onTargetCreationComplete);
}
/**
* Return the requested skin if available by name.
**/
public function getSkinByName(value:String):IGraphicSkin{
for each (var item:IGraphicSkin in skinsCollection.items){
if (item.name == value){
return item;
}
}
return null;
}
/**
* Processes skins as they are instantiated.
**/
private function onChildAdded(event:Event):void{
//add item to the skins collection if not already present
if(event.target is IGraphicSkin){
var exists:Boolean;
for each (var item:IGraphicSkin in skinsCollection.items){
if (item == IGraphicSkin(event.target)){
exists = true;
}
}
if(!exists){
skinsCollection.addItem(IGraphicSkin(event.target));
}
}
}
/**
* Sets up this manipulator.
**/
private function onTargetCreationComplete(event:FlexEvent):void{
var i:int;
//loop through the children and get the first IGraphicSkin that matches
//the targetSkinClass.
if(event.currentTarget is DisplayObject){
if(event.currentTarget.hasOwnProperty("rawChildren")){
if(targetSkinClass){
for (i=0;i<event.currentTarget.rawChildren.numChildren;i++){
if (event.currentTarget.rawChildren.getChildAt(i) is targetSkinClass &&
event.currentTarget.rawChildren.getChildAt(i) is IGraphicSkin){
_currentSkin=event.currentTarget.rawChildren.getChildAt(i);
}
}
}
}
else{
for (i=0;i<event.currentTarget.numChildren;i++){
var x:Object = event.currentTarget.getChildAt(i);
if (event.currentTarget.getChildAt(i) is targetSkinClass &&
event.currentTarget.getChildAt(i) is IGraphicSkin){
_currentSkin=event.currentTarget.getChildAt(i);
}
}
}
}
}
private var _targetSkinClass:Class;
/**
* Desired IGraphicSkin object we wish to tie into.
**/
public function set targetSkinClass(value:Class):void{
if (!value){return;}
_targetSkinClass = value;
}
public function get targetSkinClass():Class{
return _targetSkinClass;
}
private var _currentSkin:IGraphicSkin;
/**
* Desired IGraphicSkin object for this hook
**/
public function get currentSkin():IGraphicSkin{
return _currentSkin;
}
public function set currentSkin(value:IGraphicSkin):void{
if (!value){return;}
if(_currentSkin !=value){
_currentSkin.removeEventListener(PropertyChangeEvent.PROPERTY_CHANGE,propertyChangeHandler);
}
_currentSkin = value;
_currentSkin.addEventListener(PropertyChangeEvent.PROPERTY_CHANGE,propertyChangeHandler);
}
private var _skins:GraphicSkinCollection;
/**
* Access to an array of IGeometry items added as children
* to the skin.
**/
public function get skinsCollection():GraphicSkinCollection{
if(!_skins){
_skins = new GraphicSkinCollection();
_skins.addEventListener(PropertyChangeEvent.PROPERTY_CHANGE,propertyChangeHandler);
}
return _skins;
}
/**
* Principle event handler for any property changes to a
* skin object or it's child objects.
**/
private function propertyChangeHandler(event:PropertyChangeEvent):void{
dispatchEvent(event);
}
}
}

View File

@ -0,0 +1,47 @@
////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2008 The Degrafa Team : http://www.Degrafa.com/team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
////////////////////////////////////////////////////////////////////////////////
package com.degrafa.core.utils{
import flash.utils.ByteArray;
/**
* A helper utility class for cloning objects.
**/
public class CloneUtil{
public static function clone(source:Object,classType:Class=null):*{
var objectByteArray:ByteArray = new ByteArray();
objectByteArray.writeObject(source);
objectByteArray.position = 0;
if(classType){
return(objectByteArray.readObject() as classType);
}
else{
return(objectByteArray.readObject())
}
}
}
}

View File

@ -0,0 +1,178 @@
////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2008 The Degrafa Team : http://www.Degrafa.com/team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
////////////////////////////////////////////////////////////////////////////////
package com.degrafa.core.utils{
/**
* A list of colorKey name constants that respect the SVG
* specification of ColorKeys.
**/
public final class ColorKeys{
public static const ALICEBLUE:uint = 0xF0F8FF;//240,248,255
public static const ANTIQUEWHITE:uint = 0xFAEBD7;//250,235,215
public static const AQUA:uint = 0x00FFFF;//0,255,255
public static const AQUAMARINE:uint = 0x7FFFD4;//127,255,212
public static const AZURE:uint = 0xF0FFFF;//240,255,255
public static const BEIGE:uint = 0xF5F5DC;//245,245,220
public static const BISQUE:uint = 0xFFE4C4;//255,228,196
public static const BLACK:uint = 0x000000;//0,0,0
public static const BLANCHEDALMOND:uint = 0xFFEBCD;//255,235,205
public static const BLUE:uint = 0x0000FF;//0,0,255
public static const BLUEVIOLET:uint = 0x8A2BE2;//138,43,226
public static const BROWN:uint = 0xA52A2A;//165,42,42
public static const BURLYWOOD:uint = 0xDEB887;//222,184,135
public static const CADETBLUE:uint = 0x5F9EA0;//95,158,160
public static const CHARTREUSE:uint = 0x7FFF00;//127,255,0
public static const CHOCOLATE:uint = 0xD2691E;//210,105,30
public static const CORAL:uint = 0xFF7F50;//255,127,80
public static const CORNFLOWERBLUE:uint = 0x6495ED;//100,149,237
public static const CORNSILK:uint = 0xFFF8DC;//255,248,220
public static const CRIMSON:uint = 0xDC143C;//220,20,60
public static const CYAN:uint = 0x00FFFF;//0,255,255
public static const DARKBLUE:uint = 0x00008B;//0,0,139
public static const DARKCYAN:uint = 0x008B8B;//0,139,139
public static const DARKGOLDENROD:uint = 0xB8860B;//184,134,11
public static const DARKGRAY:uint = 0xA9A9A9;//169,169,169
public static const DARKGREEN:uint = 0x006400;//0,100,0
public static const DARKGREY:uint = 0xA9A9A9;//169,169,169
public static const DARKKHAKI:uint = 0xBDB76B;//189,183,107
public static const DARKMAGENTA:uint = 0x8B008B;//139,0,139
public static const DARKOLIVEGREEN:uint = 0x556B2F;//85,107,47
public static const DARKORANGE:uint = 0xFF8C00;//255,140,0
public static const DARKORCHID:uint = 0x9932CC;//153,50,204
public static const DARKRED:uint = 0x8B0000;//139,0,0
public static const DARKSALMON:uint = 0xE9967A;//233,150,122
public static const DARKSEAGREEN:uint = 0x8FBC8F;//143,188,143
public static const DARKSLATEBLUE:uint = 0x483D8B;//72,61,139
public static const DARKSLATEGRAY:uint = 0x2F4F4F;//47,79,79
public static const DARKSLATEGREY:uint = 0x2F4F4F;//47,79,79
public static const DARKTURQUOISE:uint = 0x00CED1;//0,206,209
public static const DARKVIOLET:uint = 0x9400D3;//148,0,211
public static const DEEPPINK:uint = 0xFF1493;//255,20,147
public static const DEEPSKYBLUE:uint = 0x00BFFF;//0,191,255
public static const DIMGRAY:uint = 0x696969;//105,105,105
public static const DIMGREY:uint = 0x696969;//105,105,105
public static const DODGERBLUE:uint = 0x1E90FF;//30,144,255
public static const FIREBRICK:uint = 0xB22222;//178,34,34
public static const FLORALWHITE:uint = 0xFFFAF0;//255,250,240
public static const FORESTGREEN:uint = 0x228B22;//34,139,34
public static const FUCHSIA:uint = 0xFF00FF;//255,0,255
public static const GAINSBORO:uint = 0xDCDCDC;//220,220,220
public static const GHOSTWHITE:uint = 0xF8F8FF;//248,248,255
public static const GOLD:uint = 0xFFD700;//255,215,0
public static const GOLDENROD:uint = 0xDAA520;//218,165,32
public static const GRAY:uint = 0x808080;//128,128,128
public static const GREEN:uint = 0x008000;//0,128,0
public static const GREENYELLOW:uint = 0xADFF2F;//173,255,47
public static const GREY:uint = 0x808080;//128,128,128
public static const HONEYDEW:uint = 0xF0FFF0;//240,255,240
public static const HOTPINK:uint = 0xFF69B4;//255,105,180
public static const INDIANRED:uint = 0xCD5C5C;//205,92,92
public static const INDIGO:uint = 0x4B0082;//75,0,130
public static const IVORY:uint = 0xFFFFF0;//255,255,240
public static const KHAKI:uint = 0xF0E68C;//240,230,140
public static const LAVENDER:uint = 0xE6E6FA;//230,230,250
public static const LAVENDERBLUSH:uint = 0xFFF0F5;//255,240,245
public static const LAWNGREEN:uint = 0x7CFC00;//124,252,0
public static const LEMONCHIFFON:uint = 0xFFFACD;//255,250,205
public static const LIGHTBLUE:uint = 0xADD8E6;//173,216,230
public static const LIGHTCORAL:uint = 0xF08080;//240,128,128
public static const LIGHTCYAN:uint = 0xE0FFFF;//224,255,255
public static const LIGHTGOLDENRODYELLOW:uint = 0xFAFAD2;//250,250,210
public static const LIGHTGRAY:uint = 0xD3D3D3;//211,211,211
public static const LIGHTGREEN:uint = 0x90EE90;//144,238,144
public static const LIGHTGREY:uint = 0xD3D3D3;//211,211,211
public static const LIGHTPINK:uint = 0xFFB6C1;//255,182,193
public static const LIGHTSALMON:uint = 0xFFA07A;//255,160,122
public static const LIGHTSEAGREEN:uint = 0x20B2AA;//32,178,170
public static const LIGHTSKYBLUE:uint = 0x87CEFA;//135,206,250
public static const LIGHTSLATEGREY:uint = 0x778899;//119,136,153
public static const LIGHTSTEELBLUE:uint = 0xB0C4DE;//176,196,222
public static const LIGHTYELLOW:uint = 0xFFFFE0;//255,255,224
public static const LIME:uint = 0x00FF00;//0,255,0
public static const LIMEGREEN:uint = 0x32CD32;//50,205,50
public static const LINEN:uint = 0xFAF0E6;//250,240,230
public static const MAGENTA:uint = 0xFF00FF;//255,0,255
public static const MAROON:uint = 0x800000;//128,0,0
public static const MEDIUMAQUAMARINE:uint = 0x66CDAA;//102,205,170
public static const MEDIUMBLUE:uint = 0x0000CD;//0,0,205
public static const MEDIUMORCHID:uint = 0xBA55D3;//186,85,211
public static const MEDIUMPURPLE:uint = 0x9370DB;//147,112,219
public static const MEDIUMSEAGREEN:uint = 0x3CB371;//60,179,113
public static const MEDIUMSLATEBLUE:uint = 0x7B68EE;//123,104,238
public static const MEDIUMSPRINGGREEN:uint = 0x00FA9A;//0,250,154
public static const MEDIUMTURQUOISE:uint = 0x48D1CC;//72,209,204
public static const MEDIUMVIOLETRED:uint = 0xC71585;//199,21,133
public static const MIDNIGHTBLUE:uint = 0x191970;//25,25,112
public static const MINTCREAM:uint = 0xF5FFFA;//245,255,250
public static const MISTYROSE:uint = 0xFFE4E1;//255,228,225
public static const MOCCASIN:uint = 0xFFE4B5;//255,228,181
public static const NAVAJOWHITE:uint = 0xFFDEAD;//255,222,173
public static const NAVY:uint = 0x000080;//0,0,128
public static const OLDLACE:uint = 0xFDF5E6;//253,245,230
public static const OLIVE:uint = 0x808000;//128,128,0
public static const OLIVEDRAB:uint = 0x6B8E23;//107,142,35
public static const ORANGE:uint = 0xFFA500;//255,165,0
public static const ORANGERED:uint = 0xFF4500;//255,69,0
public static const ORCHID:uint = 0xDA70D6;//218,112,214
public static const PALEGOLDENROD:uint = 0xEEE8AA;//238,232,170
public static const PALEGREEN:uint = 0x98FB98;//152,251,152
public static const PALETURQUOISE:uint = 0xAFEEEE;//175,238,238
public static const PALEVIOLETRED:uint = 0xDB7093;//219,112,147
public static const PAPAYAWHIP:uint = 0xFFEFD5;//255,239,213
public static const PEACHPUFF:uint = 0xFFDAB9;//255,218,185
public static const PERU:uint = 0xCD853F;//205,133,63
public static const PINK:uint = 0xFFC0CB;//255,192,203
public static const PLUM:uint = 0xDDA0DD;//221,160,221
public static const POWDERBLUE:uint = 0xB0E0E6;//176,224,230
public static const PURPLE:uint = 0x800080;//128,0,128
public static const RED:uint = 0xFF0000;//255,0,0
public static const ROSYBROWN:uint = 0xBC8F8F;//188,143,143
public static const ROYALBLUE:uint = 0x4169E1;//65,105,225
public static const SADDLEBROWN:uint = 0x8B4513;//139,69,19
public static const SALMON:uint = 0xFA8072;//250,128,114
public static const SANDYBROWN:uint = 0xF4A460;//244,164,96
public static const SEAGREEN:uint = 0x2E8B57;//46,139,87
public static const SEASHELL:uint = 0xFFF5EE;//255,245,238
public static const SIENNA:uint = 0xA0522D;//160,82,45
public static const SILVER:uint = 0xC0C0C0;//192,192,192
public static const SKYBLUE:uint = 0x87CEEB;//135,206,235
public static const SLATEBLUE:uint = 0x6A5ACD;//106,90,205
public static const SLATEGRAY:uint = 0x708090;//112,128,144
public static const SLATEGREY:uint = 0x708090;//112,128,144
public static const SNOW:uint = 0xFFFAFA;//255,250,250
public static const SPRINGGREEN:uint = 0x00FF7F;//0,255,127
public static const STEELBLUE:uint = 0x4682B4;//70,130,180
public static const TAN:uint = 0xD2B48C;//210,180,140
public static const TEAL:uint = 0x008080;//0,128,128
public static const THISTLE:uint = 0xD8BFD8;//216,191,216
public static const TOMATO:uint = 0xFF6347;//255,99,71
public static const TURQUOISE:uint = 0x40E0D0;//64,224,208
public static const VIOLET:uint = 0xEE82EE;//238,130,238
public static const WHEAT:uint = 0xF5DEB3;//245,222,179
public static const WHITE:uint = 0xFFFFFF;//255,255,255
public static const WHITESMOKE:uint = 0xF5F5F5;//245,245,245
public static const YELLOW:uint = 0xFFFF00;//255,255,0
public static const YELLOWGREEN:uint = 0x9ACD32;//154,205,50
}
}

View File

@ -0,0 +1,190 @@
////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2008 The Degrafa Team : http://www.Degrafa.com/team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
////////////////////////////////////////////////////////////////////////////////
package com.degrafa.core.utils{
import com.degrafa.paint.palette.PaletteEntry;
/**
* A helper utility class for color conversion.
**/
public class ColorUtil{
/**
* Resolves the color value passed to a valid hex value.
**/
public static function resolveColor(value:Object, none:uint = 0):uint {
if (value is uint) {
//CHANGE: do not attempt to identify shorthand hex notation from a uint value
//this will break some previous code examples with shorthand notation, but needs to be fixed
//there is no way to discriminate with certainty if the value is uint when checked
/*LEGACY TRACE WARNING CODE*/
if (value.toString(16).length==3){
trace('WARNING: #000'+value.toString(16) +' not assumed to be #'+value.toString(16)+'! If your color definitions contain shorthand hex notation(e.g. #FFF for white) this will no longer be supported/interpreted as shorthand in this and future versions of Degrafa. Please adjust your mxml source code to not assume shorthand hex notation or use older versions of Degrafa. This trace messaage will be removed for version 1 of Degrafa onwards')
//return parseColorNotation(value.toString(16));
}
return value as uint;
}
else if(value is String){
return resolveColorFromString(value as String, none);
}
else if(value is PaletteEntry){
return resolveColor(PaletteEntry(value).value, none);
}
else{
//always return black if not valid or no color found
return 0x000000;
}
}
private static function resolveColorFromString(value:String, none:uint = 0):uint {
// todo: evaluate for functions?
if(value.search(",")==3) { // rgb assumption
//check and see if it is a percent list or a numeric list
if (value.search("%")!=-1) {
return resolveColorFromRGBPercent(value as String);
} else {
return resolveColorFromRGB(value as String);
}
} else if(value.search(",")==4) { // cmyk assumption
return resolveColorFromCMYK(value as String);
}
var color:uint = 0;
if(String(value).charAt(0)=="#" || String(value).substr(0,2)=="0x") {
value = value.replace("#", "");
//shorthand e.g #FDF expands to #FFDDFF
if (value.length == 3) color = parseColorNotation(value);
else color = parseInt(value, 16);
} else { color = parseInt(String(value), 10); }
if(isNaN(color) || color==0) {
color = resolveColorFromKey(value as String, none);
}
return color;
}
/**
* Converts Color Keys to color values. If the specified color key is not
* supported then black is used.
**/
public static function resolveColorFromKey(value:String, none:uint = 0):uint {
var colorKey:String = value.toUpperCase();
if(ColorKeys[colorKey] != null){
return uint(ColorKeys[colorKey]);
} else {
return none;
}
}
/**
* Allows an comma-separated list of 4 numerical
* values that represent cmyk and are then converted to
* a decimal color value.
**/
/**
* Conversion from CMYK to RGB values.
**/
public static function resolveColorFromCMYK(value:String):uint {
var tempColors:Array = value.split(",");
var cyan:int = (0xFF * tempColors[0])/100;
var magenta:int = (0xFF * tempColors[1])/100;
var yellow:int = (0xFF * tempColors[2])/100;
var key:int = (0xFF * tempColors[3])/100;
var red:int = int(decColorToHex(Math.round((0xFF-cyan)*(0xFF-key)/0xFF)));
var green:int = int(decColorToHex(Math.round((0xFF-magenta)*(0xFF-key)/0xFF)));
var blue:int = int(decColorToHex(Math.round((0xFF-yellow)*(0xFF-key)/0xFF)));
return resolveColorFromRGB(red +","+ green +","+blue);
}
/**
* Allows an comma-separated list of three numerical or
* percent values that are then converted to a hex value.
**/
/**
* Converts an RGB percentage comma separated list
* to a decimal color value. Expected order is R,G,B.
**/
public static function resolveColorFromRGBPercent(value:String):uint {
//Note: Should be verified for rounding differences
//depending on the industry norms
var tempColors:Array = value.replace(/%/g,"").split(",");
//convert as a percentage of 0 to 255 before the bitwise op
return uint((int(Math.round(tempColors[0]/100*255))<<16) | (int(Math.round(tempColors[1]/100*255))<< 8) | int(Math.round(tempColors[2]/100*255)));
}
/**
* Converts an RGB numeric comma separated list
* to a decimal color value. Expected order R,G,B.
**/
public static function resolveColorFromRGB(value:String):Number{
var tempColors:Array = value.split(",");
return uint((int(tempColors[0])<<16) | (int(tempColors[1])<< 8) | int(tempColors[2]));
}
/**
* Converts a HEX color value to an RGB value object.
**/
public static function hexToRgb(hex:Number):Object{
var red:Number = hex>>16;
var greenBlue:Number = hex-(red<<16);
var green:Number = greenBlue>>8;
var blue:Number = greenBlue-(green<<8);
return({red:red, green:green, blue:blue})
}
/**
* Converts a decimal color to a hex value.
**/
public static function decColorToHex(color:uint,prefix:String="0x"):String{
var hexVal:String = ("00000" + color.toString(16).toUpperCase()).substr( -6);
return prefix + hexVal;
}
/**
* Take a short color notation and convert it to a full color.
* Repeats each value once so that #FB0 expands to #FFBB00
**/
public static function parseColorNotation(color:String):uint
{
//dev note:extra check here for #, although it's already removed when requested from inside resolveColorFromString method above
color = color.replace("#", "");
color = '0x'+color.charAt(0) + color.charAt(0) + color.charAt(1) + color.charAt(1) + color.charAt(2) + color.charAt(2);
return uint(color);
}
}
}

View File

@ -0,0 +1,434 @@
////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2008 The Degrafa Team : http://www.Degrafa.com/team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
////////////////////////////////////////////////////////////////////////////////
package com.degrafa.core.utils{
import com.degrafa.core.Measure;
import com.degrafa.paint.BitmapFill;
import com.degrafa.paint.ComplexFill;
import com.degrafa.paint.GradientStop;
import com.degrafa.paint.LinearGradientFill;
import com.degrafa.paint.SolidFill;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.DisplayObject;
import flash.filters.DropShadowFilter;
import flash.geom.Point;
import flash.utils.Dictionary;
import mx.graphics.IFill;
import mx.graphics.SolidColor;
/**
* A helper utility class for style processing.
*/
public class StyleUtil{
public static var LEGACY:String = "BETA";
private static var functions:Dictionary;
//********************************************
// Public Methods
//********************************************
/**
* Return an IFill object based on the CSS input given.
* @param value May be a uint, String, asset, or Array of uints, Strings, or assets.
*/
public static function resolveFill(value:Object, none:IFill = null):IFill {
if(value is uint) {
return new SolidFill(value as uint, 1);
} else if(value is Class || value is BitmapData || value is Bitmap || value is DisplayObject) { // causes duplicate type checking
return new BitmapFill(value);
} else if(value is String) {
return resolveFillFromString(value as String);
} else if(value is Array) {
return resolveFillFromArray(value as Array);
} else if(value is IFill) {
return value as IFill;
} else {
return none;
}
}
public static function resolveRepeat(value:Object, none:Array = null):Array {
if(value is String) {
return [resolveRepeatFromString(value as String)]
} else if(value is Array) {
return resolveRepeatFromArray(value as Array);
}
return none;
}
public static function resolvePosition(value:Object, none:Array = null):Array {
if(value is String) {
return [resolvePositionFromString(value as String)];
} else if(value is Array) {
return resolvePositionFromArray(value as Array);
} else {
return none;
}
}
/**
* Returns an array of DropShadowFilter objects based on the CSS input given.
* @parameter value may be a Number, String or Array of Numbers or Strings
*/
public static function resolveShadow(value:Object, none:Array = null ):Array {
if(value is Array) {
return resolveShadowFromArray(value as Array);
} else if(value is String || value is Number || value is int || value is uint) {
return [resolveShadowFromString(value.toString())];
} else {
return none;
}
return result;
}
public static function resolveRadius(value:Object, none:Point = null):Object {
if(value is Number) {
return {x:new Measure(Number(value)), y:new Measure(Number(value))};
} else {
// should be none
return {x:new Measure(0), y:new Measure(0)};
}
}
public static function resolveMeasure(value:Object, none:Measure = null):Measure {
if(value is Number || value is int || value is uint) {
return new Measure(value as Number);
} else if(value is String) {
return resolveMeasureFromString(value as String);
} else {
return none;
}
}
public static function registerFunction(name:String, f:Function):void {
if(functions == null) {
functions = new Dictionary();
}
functions[name] = f;
}
//*******************************
// Parsing Functions
//*******************************
private static function resolveFillFromArray(value:Array):IFill {
if(LEGACY == "ALPHA") { return resolveFillFromArrayOld(value); }
var complex:ComplexFill = new ComplexFill();
var fills:Array = complex.fills = new Array();
var i:int = value.length;
while(i-->0) {
var object:Object = value[i];
var fill:IFill = resolveFill(object);
fills.push(fill);
}
return complex;
}
// this whole thing needs refactoring
private static function resolveFillFromString(value:String):IFill {
if(value == null) { return null; }
if(value.toLowerCase() == "none") { return null; }
if(value.indexOf(" ") > 0) { // gradient definitions must have at least one space
return resolveGradientFromString(value);
} else {
return new SolidFill(ColorUtil.resolveColor(value));
}
}
private static function resolveGradientFromString(value:String):IFill {
var fill:LinearGradientFill = new LinearGradientFill();
fill.gradientStops = new Array();
var split:Array = splitString(value);
var length:int = split.length;
if(length > 0) {
var i:int = 0;
var angle:Measure = resolveMeasure(split[0]);
if(angle != null && angle.unit == Measure.DEGREES) {
fill.angle = angle.value;
i = 1;
}
while(i < length) {
var entry:GradientStop = new GradientStop();
var measure:Measure = resolveMeasureFromString(split[i]);
if(measure != null) {
entry.ratio = measure.value;
entry.ratioUnit = measure.unit;
i++
}
var alpha:Measure = resolveMeasureFromString(split[i]);
if(alpha != null) {
entry.alpha = Number(alpha)/100;
i++;
}
// this should be optimized better
var color:IFill = new SolidColor(ColorUtil.resolveColor(split[i]));
if(color != null && color is SolidColor) {
entry.color = (color as SolidColor).color;
i++;
}
fill.gradientStops.push(entry);
//fill.entries = [new MeasuredGradientEntry(0xFF0000, new Measure(0, "px")), new MeasuredGradientEntry(0x0000FF, new Measure(100, "px"))];
}
}
return fill;
}
private static function resolveRepeatFromString(value:String):Object {
switch(value) {
case "repeat":
return {x:"repeat", y:"repeat"};
break;
case "repeat-x":
return {x:"repeat", y:"none"};
break;
case "repeat-y":
return {x:"none", y:"repeat"};
break;
case "no-repeat":
return {x:"none", y:"none"};
break;
case "space":
return {x:"space", y:"space"};
break;
case "stretch":
return {x:"stretch", y:"stretch"};
break;
default:
return {x:"repeat", y:"repeat"};
break;
}
}
private static function resolveRepeatFromArray(value:Array):Array {
if(LEGACY == "ALPHA") { return resolveRepeatFromArrayOld(value); }
var result:Array = new Array();
var i:int = value.length;
while(i-->0) {
var item:Object = value[i];
if(item is String) {
result.push(resolveRepeatFromString(item as String));
} else {
result.push(item);
}
}
return result;
}
private static function resolvePositionFromString(value:String):Object {
var properties:Array = expandProperty(value, ["top", -1]);
return {x:resolveMeasureFromString(properties[1] as String), y:resolveMeasureFromString(properties[0] as String)};
}
private static function resolvePositionFromArray(value:Array):Array {
if(LEGACY == "ALPHA") { return resolvePositionFromArrayOld(value); }
var result:Array = new Array();
var i:int = value.length;
while(i-->0) {
var item:Object = value[i];
if(item is String) {
result.push(resolvePositionFromString(item as String));
} else {
result.push(item);
}
}
return result;
}
private static function resolveMeasureFromString(value:String):Measure {
if(value == null) { return null; }
switch(value) {
case "bottom":
case "right":
return new Measure(100, Measure.PERCENT);
break;
case "top":
case "left":
return new Measure(0, Measure.PIXELS);
break;
case "center":
return new Measure(50, Measure.PERCENT);
break;
}
value = value.replace(" ", "");
var length:int = value.length;
for(var i:int = 0; i < length; i++) {
var ch:String = value.charAt(i);
switch(ch) {
case "0":
case "1":
case "2":
case "3":
case "4":
case "5":
case "6":
case "7":
case "8":
case "9":
case "-":
break;
default:
var v:Number = Number(value.substring(0, i));
var u:String = value.substring(i);
switch(u) {
case "px":
return new Measure(v, Measure.PIXELS);
break;
case "pt":
return new Measure(v, Measure.POINTS);
break;
case "%":
return new Measure(v, Measure.PERCENT);
break;
case "deg":
return new Measure(v, Measure.DEGREES);
break;
case "in":
return new Measure(v, Measure.INCHES);
break;
default:
return null;
break;
}
}
}
return new Measure(Number(value));
}
private static function resolveShadowFromArray(value:Array):Array {
var filters:Array = new Array();
var i:int = value.length;
while(i-->0) {
filters.push( resolveShadow(value[i]) );
}
return filters;
}
private static function resolveShadowFromString(value:String):DropShadowFilter {
var result:DropShadowFilter = new DropShadowFilter(0, 0, 0, 1, 0, 0);
var array:Array = expandProperty(value, [0, -1, 0, 0] );
var point:Point = new Point(resolveLength(array[0]), resolveLength(array[1]));
result.distance = Math.sqrt(Math.pow(point.x, 2) + Math.pow(point.y, 2));
result.angle = Math.atan2(point.y, point.x)*(180/Math.PI);
result.blurX = result.blurY = resolveLength(array[2]);
result.color = (resolveFill(array[3]) as SolidColor).color;
return result;
}
private static function resolveLength( object:Object ):Number {
return Number( object );
}
// legacy code
private static function resolveFillFromArrayOld(value:Array):IFill {
var complex:ComplexFill = new ComplexFill();
var fills:Array = complex.fills = new Array();
for each(var object:Object in value as Array) {
var fill:IFill = resolveFill(object);
fills.push(fill);
}
return complex;
}
private static function resolveRepeatFromArrayOld(value:Array):Array {
var result:Array = new Array();
for each(var item:Object in value) {
if(item is String) {
result.push(resolveRepeatFromString(item as String));
} else {
result.push(item);
}
}
return result;
}
private static function resolvePositionFromArrayOld(value:Array):Array {
var result:Array = new Array();
for each(var item:Object in value) {
if(item is String) {
result.push(resolvePositionFromString(item as String));
} else {
result.push(item);
}
}
return result;
}
//*******************************
// generic utility functions
//*******************************
/**
* Expands shorthand properties into an Array of values.
* This is used to evaluate shorthand CSS properties where ommited values may
* have a default value or be inherited from other values defined by the property.
* @argument property A shorthand property declaration (usually a String).
* @argument relationships An array of values used to determine the value of ommited values in the property.
* <ul>
* <li>A negative integer defines that the default value should be inherited from a value to the left.</li>
* <li>All other values define an explicit default.</li>
* </ul>
*/
public static function expandProperty(property:Object, relationships:Array):Array {
var split:Array = splitString(property.toString());
var length:int = relationships.length;
for(var i:int = split.length; i < length; i++) {
var v:Object = relationships[i];
if(v is int && v < 0) {
split.push(split[i+v]);
} else {
split.push(v);
}
}
return split;
}
/**
* Converts space seperated values into an Array.
*/
public static function splitString( value:String ):Array {
var split:Array = value.split(" ");
for(var i:uint = 0; i < split.length; i++) {
if(split[i]==""){
split.splice(i,1);
i--;
}
}
return split;
}
}
}

View File

@ -0,0 +1,67 @@
////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2008 The Degrafa Team : http://www.Degrafa.com/team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
////////////////////////////////////////////////////////////////////////////////
package com.degrafa.decorators{
import com.degrafa.core.DegrafaObject;
import com.degrafa.geometry.command.CommandStack;
/**
* DecoratorBase is intended to be extended for basic decoration creation.
* Decorations that use a delegate type manipulation extend from this base
* class.
**/
public class DecoratorBase extends DegrafaObject implements IDecorator{
public function DecoratorBase():void{
super();
}
//overridden in sub classes
/**
* Called during render setup and provides the opportunity to add
* item delegates or perform other initialization tasks.
* Decorators should use this to reset any tracking variables back to their
* original state, as the same decorator may have been used previously
* and there is no 'end' call at the completion of the rendering phase.
* To be overridden in sub classes.
**/
public function initialize(stack:CommandStack):void{
//walk the stack to add the delegates
}
//overridden in sub classes
/**
* Called at the end of the render phase for the current object.
* Provides opportunity to perform any post-decoration tasks, including any cleanup/reset activities before next request.
* To be overridden in sub classes.
**/
/**/
public function end(stack:CommandStack):void{
//perform any post-decoration tasks, including any reset activities before next request
}
}
}

View File

@ -0,0 +1,35 @@
////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2008 The Degrafa Team : http://www.Degrafa.com/team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
////////////////////////////////////////////////////////////////////////////////
package com.degrafa.decorators{
import com.degrafa.geometry.command.CommandStack;
import flash.display.Graphics;
/**
* IDecorator is the base interface for basic decorations. See DecoratorBase.
**/
public interface IDecorator{
function initialize(stack:CommandStack):void;
function end(stack:CommandStack):void;
}
}

View File

@ -0,0 +1,35 @@
////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2008 The Degrafa Team : http://www.Degrafa.com/team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
////////////////////////////////////////////////////////////////////////////////
package com.degrafa.decorators{
import flash.display.Graphics;
/**
* IRenderDecorator is the base interface for complex render time decorations. See RenderDecoratorBase.
**/
public interface IRenderDecorator extends IDecorator {
function get isValid():Boolean;
function moveTo(x:Number,y:Number,graphics:Graphics):void
function lineTo(x:Number,y:Number,graphics:Graphics):void
function curveTo(cx:Number, cy:Number, x:Number, y:Number,graphics:Graphics):void
}
}

View File

@ -0,0 +1,69 @@
////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2008 The Degrafa Team : http://www.Degrafa.com/team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
////////////////////////////////////////////////////////////////////////////////
package com.degrafa.decorators{
import flash.display.Graphics;
/**
* RenderDecoratorBase is intended to be extended for complex decorations.
* Decorations that use a render time type manipulation extend from this base
* class. Extensions of this class are expected to render the actual data to the
* graphics context passed and as such provides the nessesary proxy methods which
* can be overridden.
**/
public class RenderDecoratorBase extends DecoratorBase implements IRenderDecorator{
public function RenderDecoratorBase(){
super();
}
//override in sub classes.
/**
* A test, which is used to skip a particular decorator if it determines its current state is not valid or would
* not have an effect based on its current settings. A decorator is not executed if this returns false at the time it would
* normally be executed.
**/
public function get isValid():Boolean {
return true;
}
//override in sub classes.
/**
* moveTo proxy method. The graphics property is the current context being rendered to.
* This method is expected to be overridden by subclasses.
**/
public function moveTo(x:Number,y:Number,graphics:Graphics):void {}
/**
* lineTo proxy method. The graphics property is the current context being rendered to.
* This method is expected to be overridden by subclasses.
**/
public function lineTo(x:Number,y:Number,graphics:Graphics):void {}
/**
* curveTo proxy method. The graphics property is the current context being rendered to.
* This method is expected to be overridden by subclasses.
**/
public function curveTo(cx:Number, cy:Number, x:Number, y:Number,graphics:Graphics):void {}
}
}

View File

@ -0,0 +1,572 @@
////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2008 The Degrafa Team : http://www.Degrafa.com/team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
//
// Some algorithms based on code from Trevor McCauley, www.senocular.com
////////////////////////////////////////////////////////////////////////////////
package com.degrafa.decorators.standard{
import com.degrafa.core.IGraphicsStroke;
import com.degrafa.decorators.RenderDecoratorBase;
import com.degrafa.geometry.command.CommandStack;
import flash.display.Graphics;
import flash.geom.Rectangle;
import mx.events.PropertyChangeEvent;
public class SVGDashLine extends RenderDecoratorBase{
/**
* A value representing the accuracy used in determining the length
* of curveTo curves.
*/
public var _curveaccuracy:Number =6;
private var isLine:Boolean = true;
private var overflow:Number = 0;
private var _penx:Number = 0;
private var _peny:Number = 0;
private var _dashArray:Array; //same as SVG's dasharray
private var _dashIndex:uint = 0; //where are we in the _dashArray currently
private var _dashVal:Number = 0; //offset from beginning of current dash
private var _dashoffset:Number = 0; //dash offset
private var _alternateStroke:IGraphicsStroke; //an optional alternate stroke to use instead of unstroked gaps
private static var DEFAULT_DASH_PATTERN:Array = [10, 10];
public function SVGDashLine(){
super();
}
/**
* Allows a short hand property setting that is
* similar to the stroke-dasharray setting in SVG. Populates dashArray from a comma-delimited list of values.
* @see dashArray
**/
public function get data():String{
return dashArray.join(",");
}
public function set data(value:String):void{
var temp:Array = value.split(",");
if (temp[temp.length-1]=="") temp.pop();
//avoid unnecesary updates:
if ((temp.join(",")+(temp.length&1?","+temp.join(","):""))!=dashArray.join(",")){
dashArray = temp;
}
}
//is this Decorator valid
//with a default dash pattern this decorator is now initialized as valid:
private var _isValid:Boolean=true;
override public function get isValid():Boolean {
return _isValid;
}
/**
* Sets new lengths for dash sizes. Follows SVG rules for dasharray stroke style.
* The contents specify a list of on and off dash lengths similar to SVG's dasharray setting.
* If the array assigned contains an odd number of elements, then it is duplicated to
* create an even number of elements.
* Unlike SVG, only pixel units are supported here. Any non-numeric or negative numeric values are in error.
* @see http://www.w3.org/TR/SVG/painting.html#StrokeProperties
*/
public function set dashArray(value:Array):void {
if (value == _dashArray ) return;
//check for errors
for (var i:uint = 0; i < value.length;i++) {
if (isNaN(value[i] = Number(value[i])) || value[i]<0) return; //error
}
//if its an odd length, make it even by doubling it
if (value.length &1) {
value = value.concat(value);
}
_totalLength = 0;
for each(var v:Number in value) _totalLength += v;
if (_totalLength) {
_isValid = true;
} else _isValid = false;
initChange("dashArray", _dashArray, _dashArray = value, this);
}
/**
* Gets the current lengths for dash sizes
* @return Array containing the onLength and offLength values
* respectively in that order
*/
public function get dashArray():Array {
if (_dashArray) return _dashArray;
var defaultArr:Array = DEFAULT_DASH_PATTERN.concat();
if (isNaN(_totalLength)) {
_totalLength = 0;
for each(var v:Number in defaultArr) _totalLength += v;
_isValid = (_totalLength > 0);
}
return defaultArr;
}
/**
* Gets the total length of the dash sequence for dash on/dash-off combinations
* @return length of the total dash sequence
*/
public function get totalLength():Number {
if (isNaN(_totalLength)) {
var defaultArr:Array = DEFAULT_DASH_PATTERN.concat();
_totalLength = 0;
for each(var v:Number in defaultArr) _totalLength += v;
_isValid = (_totalLength > 0);
}
return _totalLength;
}
/**
* Specifies the distance into the stroke to start the dash pattern
* similar to the stroke-dashoffset setting in SVG. Negative values are permitted.
* @see http://www.w3.org/TR/SVG/painting.html#StrokeProperties
**/
public function get dashOffset():Number{
return _dashoffset;
}
public function set dashOffset(value:Number):void {
if (value != _dashoffset) {
initChange("dashOffset", _dashoffset, _dashoffset = value, this);
}
}
/**
* alternateStroke permits an alternate stroke to be used instead of unstroked gaps (this is a degrafa extension, not part of SVG 1.1)
*
**/
public function get alternateStroke():IGraphicsStroke{
return _alternateStroke;
}
public function set alternateStroke(value:IGraphicsStroke):void {
if (value != _alternateStroke) {
if (_alternateStroke) _alternateStroke.removeEventListener(PropertyChangeEvent.PROPERTY_CHANGE, propertyChangeHandler);
var oldVal:IGraphicsStroke = _alternateStroke;
_alternateStroke = value;
if (_alternateStroke) _alternateStroke.addEventListener(PropertyChangeEvent.PROPERTY_CHANGE, propertyChangeHandler,false,0,true);
initChange("alternateStroke", oldVal, _alternateStroke, this);
}
}
private var _matchCommonStrokeSettings:Boolean = true;
/**
* when an alternateStroke is in use, this setting, if true (the default), matches weight, pixelHinting, caps, joints, scaleMode and miterLimit
* with those of the primary stroke on the original geometry being decorated, otherwise the alternateStroke's own settings for these properties will be used
**/
public function get matchCommonStrokeSettings():Boolean{
return _matchCommonStrokeSettings;
}
public function set matchCommonStrokeSettings(value:Boolean):void {
if (value != _matchCommonStrokeSettings) {
_matchCommonStrokeSettings = value;
initChange("matchCommonStrokeSettings", !_matchCommonStrokeSettings, _matchCommonStrokeSettings, this);
}
}
private var _disableAlternateStroke:Boolean;
/**
* when an alternateStroke is in use, this setting, if true (it defaults to false), will disable the alternate stroke, rendering the dash pattern
* with unstroked gaps as per SVG's standard dash strokes.
**/
public function get disableAlternateStroke():Boolean{
return _disableAlternateStroke;
}
public function set disableAlternateStroke(value:Boolean):void {
if (value != _disableAlternateStroke) {
_disableAlternateStroke = value;
initChange("disableAlternateStroke", !_disableAlternateStroke, _disableAlternateStroke, this);
}
}
/**
* @private local handler for referenced external objects
**/
protected function propertyChangeHandler(event:PropertyChangeEvent):void {
//ignore changes from the alternate stroke if it's disabled
if (_disableAlternateStroke && _alternateStroke && event.source == _alternateStroke ) return;
//for now:
dispatchEvent(event);
//so far just alternateStroke:
//initChange("alternateStroke." + event.property, event.oldValue, event.newValue, this);
}
private var _totalLength:Number;
private var _currentStrokeArgs:Array;
private var _currentRectangle:Rectangle;
private var _altStrokeArgs:Array;
/**
* initialize override, to set up local reStroking support and adjust for dashoffset, nothing else is required at this point.
* If no stroke was originally set on the decorated geometry, no original stroke will be drawn.
* @param stack
*/
override public function initialize(stack:CommandStack):void {
var i:uint;
_reStrokeActive = true;
if (CommandStack.currentStroke) {
_currentRectangle = CommandStack.currentStroke.lastRectangle;
_currentStrokeArgs = CommandStack.currentStroke.lastArgs;
var restroke:Function = CommandStack.currentStroke.reApplyFunction;
_reStroke = function(graphics:Graphics):void {
restroke(graphics,_currentStrokeArgs);
_reStrokeActive = true;
}
if (_alternateStroke && !_disableAlternateStroke) {
_alternateStroke.apply(null, _currentRectangle);
_altStrokeArgs = _alternateStroke.lastArgs.concat();
if (_matchCommonStrokeSettings) {
var targ:Array = (_altStrokeArgs[0] is Array)?_altStrokeArgs[0]:_altStrokeArgs;
var copyFrom:Array= (_currentStrokeArgs[0] is Array)? _currentStrokeArgs[0]:_currentStrokeArgs;
targ[0] = copyFrom[0];//weight
targ[3] = copyFrom[3];//pixelhinting
targ[4] = copyFrom[4];//scaling
targ[5] = copyFrom[5];//caps
targ[6] = copyFrom[6];//joints
targ[7] = copyFrom[7];//miterlimit
}
var destroke:Function = _alternateStroke.reApplyFunction;
_deStroke = function(graphics:Graphics):void {
destroke(graphics,_altStrokeArgs);
}
} else if (_deStroke!=null) _deStroke = null;
} else {
_isValid = false;
return;
}
isLine = true;
overflow = 0;
var dashcalc:Number = Math.abs(_dashoffset) % _totalLength;
if (dashcalc) {
var dir:int = (_dashoffset < 0)? -1:1;
isLine=(dir==1)
for (i = (dir == -1)? _dashArray.length - 1:0; i > -1 && i < _dashArray.length; i += dir) {
if (dashcalc < _dashArray[i]) {
_dashIndex = i;
_dashVal = (dir == -1)? _dashArray[i] - dashcalc:dashcalc;
dashcalc = 0;
break;
} else {
dashcalc -= _dashArray[i];
isLine = !isLine;
}
}
} else {
_dashIndex = 0;
_dashVal = 0;
}
if (_dashArray) {
var len:uint = _dashArray.length;
} else _dashArray = DEFAULT_DASH_PATTERN.concat();
}
/**
* Moves the current drawing position in graphics to (x, y).
*/
override public function moveTo(x:Number, y:Number,graphics:Graphics):void {
graphics.moveTo(x, y);
_penx = x;_peny=y
}
/**
* Draws a dashed line in graphics from the current drawing position
* to (x, y).
*/
override public function lineTo(x:Number, y:Number, graphics:Graphics):void {
var dx:Number = x-_penx
var dy:Number = y-_peny;
var a:Number = Math.atan2(dy, dx);
var ca:Number
var sa:Number ;
var segLength:Number = lineLength(dx, dy);
if (overflow) {
if (overflow > segLength) {
//then we won't advance to the next index in dashArray with this lineTo
if (isLine) doLineTo(x,y,graphics);
else doAltLineTo(x,y,graphics);
overflow -= segLength;
_dashVal += segLength;
return;
}
//otherwise we're dealing with a switch inside this lineto following an overflow:
ca = Math.cos(a);
sa = Math.sin(a);
if (isLine) doLineTo(_penx + ca*overflow, _peny + sa*overflow,graphics);
else doAltLineTo(_penx + ca*overflow, _peny + sa*overflow,graphics);
segLength -= overflow;
overflow = 0;
_dashVal = 0;
_dashIndex++
if (_dashIndex == _dashArray.length)_dashIndex = 0;
isLine = !isLine;
if (!segLength) return;
} else {
ca = Math.cos(a);
sa = Math.sin(a);
}
while ((_dashVal + segLength) > _dashArray[_dashIndex]) {
var remaining:Number = _dashArray[_dashIndex] - _dashVal;
if (segLength > remaining) {
if (isLine) doLineTo(_penx + ca * (remaining), _peny + sa * (remaining), graphics);
else doAltLineTo(_penx + ca * (remaining), _peny + sa * (remaining), graphics);
_dashVal = 0;
//reduce the length of this segment
segLength -= remaining;
//advance to next dash value
_dashIndex++
if (_dashIndex == _dashArray.length)_dashIndex = 0;
//flip dash state
isLine = !isLine;
}else {
if (isLine) doLineTo(x, y, graphics);
else doAltLineTo(x, y, graphics);
if (segLength == remaining){
overflow = 0;
_dashVal = 0;
segLength-=remaining;
_dashIndex++
if (_dashIndex == _dashArray.length)_dashIndex = 0;
isLine = !isLine;
}else{
overflow = remaining - segLength;
_dashVal += segLength;
if (isLine) doLineTo(x, y,graphics);
else doAltLineTo(x, y,graphics);
}
}
}
if (_dashVal+segLength <= _dashArray[_dashIndex]) {
_dashVal += segLength;
overflow = _dashArray[_dashIndex] - _dashVal;
if (isLine) {
doLineTo(_penx+ca*(_dashArray[_dashIndex]-overflow), _peny+sa*(_dashArray[_dashIndex]-overflow),graphics);
} else {
doAltLineTo(_penx+ca*(_dashArray[_dashIndex]-overflow), _peny+sa*(_dashArray[_dashIndex]-overflow),graphics);
}
}
}
/**
* Draws a dashed curve in graphics using the current from the current drawing position to
* (x, y) using the control point specified by (cx, cy).
*/
override public function curveTo(cx:Number, cy:Number, x:Number, y:Number, graphics:Graphics):void {
var sx:Number = _penx;
var sy:Number = _peny;
var segLength:Number = curveLength(sx, sy, cx, cy, x, y,_curveaccuracy);
var t:Number = 0;
var t2:Number = 0;
var c:Array;
var d:Array;
if (overflow) {
if (overflow > segLength){
if (isLine) doCurveTo(cx, cy, x, y,graphics);
else doAltCurveTo(cx, cy, x, y, graphics);
overflow -= segLength;
_dashVal += segLength;
return;
}
t = overflow/segLength;
c = curveSliceUpTo(sx, sy, cx, cy, x, y, t);
d = curveSliceFrom(sx, sy, cx, cy, x, y, t);
if (isLine) doCurveTo(c[2], c[3], c[4], c[5],graphics);
else doAltCurveTo(c[2], c[3], c[4], c[5], graphics);
segLength -= overflow;
overflow = 0;
_dashVal = 0;
_dashIndex++
if (_dashIndex == _dashArray.length)_dashIndex = 0;
isLine = !isLine;
if (!segLength) return;
sx = d[0]; sy = d[1];
cx = d[2]; cy = d[3];
}
while ((_dashVal + segLength) > _dashArray[_dashIndex]) {
var remaining:Number = _dashArray[_dashIndex] - _dashVal;
if (segLength > remaining) {
t = remaining / segLength;
c = curveSliceUpTo(sx, sy, cx, cy, x, y, t);
d = curveSliceFrom(sx, sy, cx, cy, x, y, t);
if (isLine) doCurveTo(c[2], c[3], c[4], c[5], graphics);
else doAltCurveTo(c[2], c[3], c[4], c[5], graphics);
_dashVal = 0;
//reduce the length of this segment
segLength -= remaining;
//advance to next dash value
_dashIndex++
if (_dashIndex == _dashArray.length)_dashIndex = 0;
//flip dash state
isLine = !isLine;
sx = d[0]; sy = d[1];
cx = d[2]; cy = d[3];
}else {
if (isLine) doCurveTo(cx, cy, x, y, graphics);
else doAltCurveTo(cx, cy, x, y, graphics);
if (segLength == remaining) {
overflow = 0;
_dashVal = 0;
segLength-=remaining;
_dashIndex++
if (_dashIndex == _dashArray.length)_dashIndex = 0;
isLine = !isLine;
}else{
overflow = remaining - segLength;
_dashVal += segLength;
if (isLine) doCurveTo(cx, cy, x, y, graphics);
else doAltCurveTo(cx, cy, x, y, graphics);
return;
}
}
}
if (_dashVal+segLength <= _dashArray[_dashIndex]) {
_dashVal += segLength;
overflow = _dashArray[_dashIndex] - _dashVal;
if (isLine) {
doCurveTo(cx, cy, x, y, graphics);
} else {
doAltCurveTo(cx, cy, x, y, graphics);
}
}
}
private var _reStrokeActive:Boolean;
private var _restrokeArgs:Array;
private var _reStroke:Function;
private var _deStroke:Function;
private var _destrokeArgs:Array;
private var deStroke:Function = function (graphics:Graphics):void {
//use the alternate stroke if one is specified
if (_deStroke!=null) _deStroke(graphics)
else graphics.lineStyle();
_reStrokeActive = false;
}
private function doAltLineTo(x:Number, y:Number, graphics:Graphics):void {
if (x == _penx && y == _peny) return;
_penx = x; _peny = y;
if (_reStrokeActive) deStroke(graphics);
graphics.lineTo(x, y);
}
private function doLineTo(x:Number, y:Number, graphics:Graphics):void {
if (x == _penx && y == _peny) return;
_penx = x; _peny = y;
if (!_reStrokeActive)_reStroke(graphics);
graphics.lineTo(x, y);
}
private function doCurveTo(cx:Number, cy:Number, x:Number, y:Number, graphics:Graphics):void {
if (cx == x && cy == y && x == _penx && y == _peny) return;
_penx = x; _peny = y;
if (!_reStrokeActive) _reStroke(graphics);
graphics.curveTo(cx, cy, x, y);
}
private function doAltCurveTo(cx:Number, cy:Number, x:Number, y:Number, graphics:Graphics):void {
if (cx == x && cy == y && x == _penx && y == _peny) return;
_penx = x; _peny = y;
if (_reStrokeActive) deStroke(graphics);
graphics.curveTo(cx, cy, x, y);
}
//the below to be moved into a shared class.
// private methods
private function lineLength(sx:Number, sy:Number, ex:Number=0, ey:Number=0):Number {
if (arguments.length == 2) return Math.sqrt(sx*sx + sy*sy);
var dx:Number = ex - sx;
var dy:Number = ey - sy;
return Math.sqrt(dx*dx + dy*dy);
}
private function curveLength(sx:Number, sy:Number, cx:Number, cy:Number, ex:Number, ey:Number, accuracy:Number):Number {
var total:Number = 0;
var tx:Number = sx;
var ty:Number = sy;
var px:Number, py:Number, t:Number, it:Number, a:Number, b:Number, c:Number;
var n:Number = (accuracy) ? accuracy : _curveaccuracy;
for (var i:Number = 1; i<=n; i++){
t = i/n;
it = 1-t;
a = it*it; b = 2*t*it; c = t*t;
px = a*sx + b*cx + c*ex;
py = a*sy + b*cy + c*ey;
total += lineLength(tx, ty, px, py);
tx = px;
ty = py;
}
return total;
}
private function curveSlice(sx:Number, sy:Number, cx:Number, cy:Number, ex:Number, ey:Number, t1:Number, t2:Number):Array {
if (t1 == 0) return curveSliceUpTo(sx, sy, cx, cy, ex, ey, t2);
else if (t2 == 1) return curveSliceFrom(sx, sy, cx, cy, ex, ey, t1);
var c:Array = curveSliceUpTo(sx, sy, cx, cy, ex, ey, t2);
c.push(t1/t2);
return curveSliceFrom.apply(this, c);
}
private function curveSliceUpTo(sx:Number, sy:Number, cx:Number, cy:Number, ex:Number, ey:Number, t:Number):Array {
if (isNaN(t)) t = 1;
if (t != 1) {
var midx:Number = cx + (ex-cx)*t;
var midy:Number = cy + (ey-cy)*t;
cx = sx + (cx-sx)*t;
cy = sy + (cy-sy)*t;
ex = cx + (midx-cx)*t;
ey = cy + (midy-cy)*t;
}
return [sx, sy, cx, cy, ex, ey];
}
private function curveSliceFrom(sx:Number, sy:Number, cx:Number, cy:Number, ex:Number, ey:Number, t:Number):Array {
if (isNaN(t)) t = 1;
if (t != 1) {
var midx:Number = sx + (cx-sx)*t;
var midy:Number = sy + (cy-sy)*t;
cx = cx + (ex-cx)*t;
cy = cy + (ey-cy)*t;
sx = midx + (cx-midx)*t;
sy = midy + (cy-midy)*t;
}
return [sx, sy, cx, cy, ex, ey];
}
}
}

View File

@ -0,0 +1,243 @@
////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2008 The Degrafa Team : http://www.Degrafa.com/team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
////////////////////////////////////////////////////////////////////////////////
package com.degrafa.decorators.standard{
import com.degrafa.GeometryComposition;
import com.degrafa.core.collections.GeometryCollection;
import com.degrafa.geometry.Geometry;
import com.degrafa.transform.RotateTransform;
import flash.display.Graphics;
import flash.geom.Rectangle;
import mx.events.PropertyChangeEvent;
/**
* ShapeStrokeDecorator is intended as an example wrapper type decoration.
* Given a source object the ShapeStrokeDecorator will repeat that object
* along the wrapped geometry. ShapeStrokeDecorator is based on GeometryComposition,
* so all contained geometry will be decorated.
**/
public class ShapeStrokeDecorator extends GeometryComposition{
private var coords:Array=[]; //stores coordinates and angles along the path
public function ShapeStrokeDecorator(){
super();
invalidated = true;
}
private var _sourceGeometry:GeometryCollection;
[Inspectable(category="General", arrayType="com.degrafa.IGeometryComposition")]
[ArrayElementType("com.degrafa.IGeometryComposition")]
/**
* A array of IGeometryComposition objects. For ShapeStrokeDecorator
* at this time only one is allowed.
**/
public function get sourceGeometry():Array{
initSourceGeometryCollection();
return _sourceGeometry.items;
}
public function set sourceGeometry(value:Array):void{
initSourceGeometryCollection();
_sourceGeometry.items = value;
}
/**
* Access to the Degrafa geometry collection object for this geometry object.
**/
public function get sourceGeometryCollection():GeometryCollection{
initSourceGeometryCollection();
return _sourceGeometry;
}
/**
* Initialize the geometry collection by creating it and adding an event listener.
**/
private function initSourceGeometryCollection():void{
if(!_sourceGeometry){
_sourceGeometry = new GeometryCollection();
//add the parent so it can be managed by the collection
_sourceGeometry.parent = this;
//add a listener to the collection
if(enableEvents){
_sourceGeometry.addEventListener(PropertyChangeEvent.PROPERTY_CHANGE,propertyChangeHandler);
}
}
}
private var _explicitRepeatCount:int=-1;
/**
* Use an explicit count. If not specified the optimal will be calculated.
**/
public function get explicitRepeatCount():int{
return _explicitRepeatCount;
}
public function set explicitRepeatCount(value:int):void{
_explicitRepeatCount=value;
invalidated =true;
}
private var _gap:Number=0;
/**
* The gap of empty space between repeated items. Only applicable
* when explicitRepeatCount is not set.
**/
public function get gap():Number{
return _gap;
}
public function set gap(value:Number):void{
_gap=value;
invalidated =true;
}
/**
* @inheritDoc
**/
override public function preDraw():void{
if(invalidated){
for each (var geom:Geometry in geometry){
geom.preDraw();
geom.calculateLayout();
geom.commandStack.lengthInvalidated =true;
}
invalidated =false;
}
}
/**
* Ends the draw phase for geometry objects.
*
* @param graphics The current Graphics context being drawn to.
**/
override public function endDraw(graphics:Graphics):void {
super.endDraw(graphics);
//we have drawn our object that we will be repeating around, predrawn the source
//object to repeat and stored the angles and points on our geometry that are required.
executeStroke(graphics);
}
/**
* Begins the draw phase for geometry objects. All geometry objects
* override this to do their specific rendering.
*
* @param graphics The current context to draw to.
* @param rc A Rectangle object used for fill bounds.
**/
override public function draw(graphics:Graphics, rc:Rectangle):void{
//init the layout in this case done before predraw.
calculateLayout();
//re init if required
preDraw();
super.draw(graphics, (rc)? rc:bounds);
}
/**
* Calculates the values required for distribution.
**/
private function calcValues(geom:Geometry):void{
var repeateCount:int;
if(_explicitRepeatCount==-1){
//calculate optimal based on geometric length
var optimalDivisor:Number = Math.min(Geometry(sourceGeometry[0]).bounds.height,Geometry(sourceGeometry[0]).bounds.width);
repeateCount = (geom.commandStack.transformedPathLength / (optimalDivisor+_gap));
}
else{
//use explicit count setting
repeateCount=_explicitRepeatCount;
}
for (var i:int=0;i<(repeateCount+1);i++){
coords.push({point:geom.pointAt(i/repeateCount),angle:geom.angleAt(i/repeateCount)*(180/Math.PI)})
}
//add item at t:1
coords.push({point:geom.pointAt(1),angle:geom.angleAt(1)*(180/Math.PI)})
}
/**
* Executes the distribution.
**/
private function executeStroke(graphics:Graphics):void{
if(sourceGeometry.length==0){return;}
coords.length=0;
var trans:RotateTransform = new RotateTransform();
trans.angle = 0;
trans.registrationPoint = "center";
trans.enableEvents = false;
var geom:Geometry;
for each (geom in sourceGeometry){
geom.suppressEventProcessing = true;
geom.transform = trans;
geom.preDraw();
}
//get the angles and points
for each (geom in geometry){
calcValues(geom);
}
var xOffset:Number=0;
var yOffset:Number=0;
var sourceRect:Rectangle;
var sourcelength:int=sourceGeometry.length;
var sourceIndex:int=0
for (var i:int=0;i<coords.length-1;i++){
if(sourceIndex==sourcelength){
sourceIndex=0;
}
sourceRect=sourceGeometry[sourceIndex].bounds;
xOffset = sourceRect.width/2;
yOffset = sourceRect.height/2;
trans.angle=coords[i].angle;
sourceGeometry[sourceIndex].x = coords[i].point.x-xOffset;
sourceGeometry[sourceIndex].y = coords[i].point.y-yOffset;
sourceGeometry[sourceIndex].draw(graphics,null);
sourceIndex +=1;
}
}
}
}

View File

@ -0,0 +1,76 @@
////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2008 The Degrafa Team : http://www.Degrafa.com/team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
//
////////////////////////////////////////////////////////////////////////////////
package com.degrafa.decorators.standard{
import com.degrafa.geometry.command.CommandStack;
import flash.display.Graphics;
import com.degrafa.decorators.RenderDecoratorBase;
/**
* Randomly perturbs the line and curve segments
* that make up a Geometry.
**/
public class SloppyLineDecorator extends RenderDecoratorBase{
public function SloppyLineDecorator(){
super();
}
private var _sloppiness:int = 20;
private var _startx:Number;
private var _starty:Number;
private var _penx:Number;
private var _peny:Number;
private var started:Boolean;
private var _context:Graphics;
override public function initialize(stack:CommandStack):void {
started = false;
}
override public function end(stack:CommandStack):void {
if (_penx == _startx && _peny == _starty) _context.lineTo(_startx, _starty);
}
//override in sub classes.
override public function moveTo(x:Number, y:Number, graphics:Graphics):void {
if (!started) { _startx = x; _starty = y ; _context = graphics; started = true }
_penx = x; _peny = y;
graphics.moveTo(_penx,_peny);
}
override public function lineTo(x:Number, y:Number, graphics:Graphics):void {
if (!started) { _startx = 0; _starty = 0 ; _context = graphics; started = true }
_penx = x; _peny = y;
graphics.lineTo(perturb(x),perturb(y));
}
override public function curveTo(cx:Number, cy:Number, x:Number, y:Number, graphics:Graphics):void {
if (!started) { _startx = 0; _starty = 0 ; _context = graphics; started = true }
_penx = x; _peny = y;
graphics.curveTo(perturb(cx),perturb(cy),perturb(x),perturb(y));
}
private function perturb(value:Number):Number{
return value += ((Math.random()*2-1.0)*_sloppiness);
}
}
}

View File

@ -0,0 +1,44 @@
////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2008 The Degrafa Team : http://www.Degrafa.com/team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
////////////////////////////////////////////////////////////////////////////////
package com.degrafa.events
{
import flash.events.Event;
/**
* Base class for Degrafa-specific events
*/
public class DegrafaEvent extends Event
{
public static const PRE_RENDER:String = "preRender";
public static const RENDER:String = "render";
public function DegrafaEvent(type:String ,bubbles:Boolean=false,cancelable:Boolean=false):void
{
super(type, bubbles, cancelable);
}
}
}

View File

@ -0,0 +1,251 @@
package com.degrafa.filters
{
import flash.filters.BevelFilter;
import flash.filters.BitmapFilter;
/**
* A bindable Degrafa-fied wrapper for flash.filters.BevelFilter.
*
* todo: poach documentation for filter properties from Flex SDK.
*
* @author josh
*/
public class DegrafaBevelFilter extends DegrafaFilter
{
//--------------------------------------------------------------------------
//
// Actual (proxied) filter
//
//--------------------------------------------------------------------------
private var _bitmapFilter : BevelFilter;
/**
* @return the proxied flash.filters.BevelFilter
*/
override public function get bitmapFilter() : BitmapFilter
{
return _bitmapFilter;
}
//--------------------------------------------------------------------------
//
// Constructor
//
//--------------------------------------------------------------------------
public function DegrafaBevelFilter(distance : Number = 4.0,
angle : Number = 45,
highlightColor : uint = 0xFFFFFF,
highlightAlpha : Number = 1.0,
shadowColor : uint = 0x000000,
shadowAlpha : Number = 1.0,
blurX : Number = 4.0,
blurY : Number = 4.0,
strength : Number = 1,
quality : int = 1,
type : String = "inner",
knockout : Boolean = false)
{
super();
_bitmapFilter = new BevelFilter(distance,
angle,
highlightColor,
highlightAlpha,
shadowColor,
shadowAlpha,
blurX,
blurY,
strength,
quality,
type,
knockout);
}
//--------------------------------------------------------------------------
//
// Work
//
//--------------------------------------------------------------------------
//----------------------------------
// distance
//----------------------------------
[Bindable("propertyChange")]
public function get distance() : Number
{
return _bitmapFilter.distance;
}
public function set distance(value : Number) : void
{
setValue("distance", value);
}
//----------------------------------
// angle
//----------------------------------
[Bindable("propertyChange")]
public function get angle() : Number
{
return _bitmapFilter.angle;
}
public function set angle(value : Number) : void
{
setValue("angle", value);
}
//----------------------------------
// highlightColor
//----------------------------------
[Bindable("propertyChange")]
public function get highlightColor() : uint
{
return _bitmapFilter.highlightColor;
}
public function set highlightColor(value : uint) : void
{
setValue("highlightColor", value);
}
//----------------------------------
// highlightAlpha
//----------------------------------
[Bindable("propertyChange")]
public function get highlightAlpha() : Number
{
return _bitmapFilter.highlightAlpha;
}
public function set highlightAlpha(value : Number) : void
{
setValue("highlightAlpha", value);
}
//----------------------------------
// shadowColor
//----------------------------------
[Bindable("propertyChange")]
public function get shadowColor() : uint
{
return _bitmapFilter.shadowColor;
}
public function set shadowColor(value : uint) : void
{
setValue("shadowColor", value);
}
//----------------------------------
// shadowAlpha
//----------------------------------
[Bindable("propertyChange")]
public function get shadowAlpha() : Number
{
return _bitmapFilter.shadowAlpha;
}
public function set shadowAlpha(value : Number) : void
{
setValue("shadowAlpha", value);
}
//----------------------------------
// blurX
//----------------------------------
[Bindable("propertyChange")]
public function get blurX() : Number
{
return _bitmapFilter.blurX;
}
public function set blurX(value : Number) : void
{
setValue("blurX", value);
}
//----------------------------------
// blurY
//----------------------------------
[Bindable("propertyChange")]
public function get blurY() : Number
{
return _bitmapFilter.blurY;
}
public function set blurY(value : Number) : void
{
setValue("blurY", value);
}
//----------------------------------
// strength
//----------------------------------
[Bindable("propertyChange")]
public function get strength() : Number
{
return _bitmapFilter.strength;
}
public function set strength(value : Number) : void
{
setValue("strength", value);
}
//----------------------------------
// quality
//----------------------------------
[Bindable("propertyChange")]
public function get quality() : int
{
return _bitmapFilter.quality;
}
public function set quality(value : int) : void
{
setValue("quality", value);
}
//----------------------------------
// type
//----------------------------------
[Bindable("propertyChange")]
public function get type() : String
{
return _bitmapFilter.type;
}
public function set type(value : String) : void
{
setValue("type", value);
}
//----------------------------------
// knockout
//----------------------------------
[Bindable("propertyChange")]
public function get knockout() : Boolean
{
return _bitmapFilter.knockout;
}
public function set knockout(value : Boolean) : void
{
setValue("knockout", value);
}
}
}

View File

@ -0,0 +1,98 @@
package com.degrafa.filters
{
import flash.filters.BitmapFilter;
import flash.filters.BlurFilter;
/**
* A bindable Degrafa-fied wrapper for flash.filters.BlurFilter.
*
* todo: poach documentation for filter properties from Flex SDK.
*
* @author josh
*/
public class DegrafaBlurFilter extends DegrafaFilter
{
//--------------------------------------------------------------------------
//
// Actual (proxied) filter
//
//--------------------------------------------------------------------------
private var _bitmapFilter : BlurFilter;
/**
* @return the proxied flash.filters.BlurFilter
*/
override public function get bitmapFilter() : BitmapFilter
{
return _bitmapFilter;
}
//--------------------------------------------------------------------------
//
// Constructor
//
//--------------------------------------------------------------------------
public function DegrafaBlurFilter(blurX : Number = 4.0,
blurY : Number = 4.0,
quality : int = 1)
{
super();
_bitmapFilter = new BlurFilter(blurX,
blurY,
quality);
}
//--------------------------------------------------------------------------
//
// Work
//
//--------------------------------------------------------------------------
//----------------------------------
// blurX
//----------------------------------
[Bindable("propertyChange")]
public function get blurX() : Number
{
return _bitmapFilter.blurX;
}
public function set blurX(value : Number) : void
{
setValue("blurX", value);
}
//----------------------------------
// blurY
//----------------------------------
[Bindable("propertyChange")]
public function get blurY() : Number
{
return _bitmapFilter.blurY;
}
public function set blurY(value : Number) : void
{
setValue("blurY", value);
}
//----------------------------------
// quality
//----------------------------------
[Bindable("propertyChange")]
public function get quality() : int
{
return _bitmapFilter.quality;
}
public function set quality(value : int) : void
{
setValue("quality", value);
}
}
}

View File

@ -0,0 +1,64 @@
package com.degrafa.filters
{
import flash.filters.BitmapFilter;
import flash.filters.ColorMatrixFilter;
/**
* A bindable Degrafa-fied wrapper for flash.filters.ColorMatrixFilter.
*
* todo: poach documentation for filter properties from Flex SDK.
*
* @author josh
*/
public class DegrafaColorMatrixFilter extends DegrafaFilter
{
//--------------------------------------------------------------------------
//
// Actual (proxied) filter
//
//--------------------------------------------------------------------------
private var _bitmapFilter : ColorMatrixFilter;
/**
* @return the proxied flash.filters.ColorMatrixFilter
*/
override public function get bitmapFilter() : BitmapFilter
{
return _bitmapFilter;
}
//--------------------------------------------------------------------------
//
// Constructor
//
//--------------------------------------------------------------------------
public function DegrafaColorMatrixFilter(matrix : Array = null)
{
super();
_bitmapFilter = new ColorMatrixFilter(matrix);
}
//--------------------------------------------------------------------------
//
// Work
//
//--------------------------------------------------------------------------
//----------------------------------
// matrix
//----------------------------------
[Bindable("propertyChange")]
public function get matrix() : Array
{
return _bitmapFilter.matrix;
}
public function set matrix(value : Array) : void
{
setValue("matrix", value);
}
}
}

View File

@ -0,0 +1,200 @@
package com.degrafa.filters
{
import flash.filters.BitmapFilter;
import flash.filters.ConvolutionFilter;
/**
* A bindable Degrafa-fied wrapper for flash.filters.ConvolutionFilter.
*
* todo: poach documentation for filter properties from Flex SDK.
*
* @author josh
*/
public class DegrafaConvolutionFilter extends DegrafaFilter
{
//--------------------------------------------------------------------------
//
// Actual (proxied) filter
//
//--------------------------------------------------------------------------
private var _bitmapFilter : ConvolutionFilter;
/**
* @return the proxied flash.filters.ConvolutionFilter
*/
override public function get bitmapFilter() : BitmapFilter
{
return _bitmapFilter;
}
//--------------------------------------------------------------------------
//
// Constructor
//
//--------------------------------------------------------------------------
public function DegrafaConvolutionFilter(matrixX : Number = 0,
matrixY : Number = 0,
matrix : Array = null,
divisor : Number = 1.0,
bias : Number = 0.0,
preserveAlpha : Boolean = true,
clamp : Boolean = true,
color : uint = 0,
alpha : Number = 0.0)
{
super();
_bitmapFilter = new ConvolutionFilter(matrixX,
matrixY,
matrix,
divisor,
bias,
preserveAlpha,
clamp,
color,
alpha);
}
//--------------------------------------------------------------------------
//
// Work
//
//--------------------------------------------------------------------------
//----------------------------------
// matrixX
//----------------------------------
[Bindable("propertyChange")]
public function get matrixX() : Number
{
return _bitmapFilter.matrixX;
}
public function set matrixX(value : Number) : void
{
setValue("matrixX", value);
}
//----------------------------------
// matrixY
//----------------------------------
[Bindable("propertyChange")]
public function get matrixY() : Number
{
return _bitmapFilter.matrixY;
}
public function set matrixY(value : Number) : void
{
setValue("matrixY", value);
}
//----------------------------------
// matrix
//----------------------------------
[Bindable("propertyChange")]
public function get matrix() : Array
{
return _bitmapFilter.matrix;
}
public function set matrix(value : Array) : void
{
setValue("matrix", value);
}
//----------------------------------
// divisor
//----------------------------------
[Bindable("propertyChange")]
public function get divisor() : Number
{
return _bitmapFilter.divisor;
}
public function set divisor(value : Number) : void
{
setValue("divisor", value);
}
//----------------------------------
// bias
//----------------------------------
[Bindable("propertyChange")]
public function get bias() : Number
{
return _bitmapFilter.bias;
}
public function set bias(value : Number) : void
{
setValue("bias", value);
}
//----------------------------------
// preserveAlpha
//----------------------------------
[Bindable("propertyChange")]
public function get preserveAlpha() : Boolean
{
return _bitmapFilter.preserveAlpha;
}
public function set preserveAlpha(value : Boolean) : void
{
setValue("preserveAlpha", value);
}
//----------------------------------
// clamp
//----------------------------------
[Bindable("propertyChange")]
public function get clamp() : Boolean
{
return _bitmapFilter.clamp;
}
public function set clamp(value : Boolean) : void
{
setValue("clamp", value);
}
//----------------------------------
// color
//----------------------------------
[Bindable("propertyChange")]
public function get color() : uint
{
return _bitmapFilter.color;
}
public function set color(value : uint) : void
{
setValue("color", value);
}
//----------------------------------
// alpha
//----------------------------------
[Bindable("propertyChange")]
public function get alpha() : Number
{
return _bitmapFilter.alpha;
}
public function set alpha(value : Number) : void
{
setValue("alpha", value);
}
}
}

View File

@ -0,0 +1,202 @@
package com.degrafa.filters
{
import flash.display.BitmapData;
import flash.filters.BitmapFilter;
import flash.filters.DisplacementMapFilter;
import flash.geom.Point;
/**
* A bindable Degrafa-fied wrapper for flash.filters.DisplacementMapFilter.
*
* todo: poach documentation for filter properties from Flex SDK.
*
* @author josh
*/
public class DegrafaDisplacementMapFilter extends DegrafaFilter
{
//--------------------------------------------------------------------------
//
// Actual (proxied) filter
//
//--------------------------------------------------------------------------
private var _bitmapFilter : DisplacementMapFilter;
/**
* @return the proxied flash.filters.DisplacementMapFilter
*/
override public function get bitmapFilter() : BitmapFilter
{
return _bitmapFilter;
}
//--------------------------------------------------------------------------
//
// Constructor
//
//--------------------------------------------------------------------------
public function DegrafaDisplacementMapFilter(mapBitmap : BitmapData = null,
mapPoint : Point = null,
componentX : uint = 0,
componentY : uint = 0,
scaleX : Number = 0.0,
scaleY : Number = 0.0,
mode : String = "wrap",
color : uint = 0,
alpha : Number = 0.0)
{
super();
_bitmapFilter = new DisplacementMapFilter(mapBitmap,
mapPoint,
componentX,
componentY,
scaleX,
scaleY,
mode,
color,
alpha);
}
//--------------------------------------------------------------------------
//
// Work
//
//--------------------------------------------------------------------------
//----------------------------------
// mapBitmap
//----------------------------------
[Bindable("propertyChange")]
public function get mapBitmap() : BitmapData
{
return _bitmapFilter.mapBitmap;
}
public function set mapBitmap(value : BitmapData) : void
{
setValue("mapBitmap", value);
}
//----------------------------------
// mapPoint
//----------------------------------
[Bindable("propertyChange")]
public function get mapPoint() : Point
{
return _bitmapFilter.mapPoint;
}
public function set mapPoint(value : Point) : void
{
setValue("mapPoint", value);
}
//----------------------------------
// componentX
//----------------------------------
[Bindable("propertyChange")]
public function get componentX() : uint
{
return _bitmapFilter.componentX;
}
public function set componentX(value : uint) : void
{
setValue("componentX", value);
}
//----------------------------------
// componentY
//----------------------------------
[Bindable("propertyChange")]
public function get componentY() : uint
{
return _bitmapFilter.componentY;
}
public function set componentY(value : uint) : void
{
setValue("componentY", value);
}
//----------------------------------
// scaleX
//----------------------------------
[Bindable("propertyChange")]
public function get scaleX() : Number
{
return _bitmapFilter.scaleX;
}
public function set scaleX(value : Number) : void
{
setValue("scaleX", value);
}
//----------------------------------
// scaleY
//----------------------------------
[Bindable("propertyChange")]
public function get scaleY() : Number
{
return _bitmapFilter.scaleY;
}
public function set scaleY(value : Number) : void
{
setValue("scaleY", value);
}
//----------------------------------
// mode
//----------------------------------
[Bindable("propertyChange")]
public function get mode() : String
{
return _bitmapFilter.mode;
}
public function set mode(value : String) : void
{
setValue("mode", value);
}
//----------------------------------
// color
//----------------------------------
[Bindable("propertyChange")]
public function get color() : uint
{
return _bitmapFilter.color;
}
public function set color(value : uint) : void
{
setValue("color", value);
}
//----------------------------------
// alpha
//----------------------------------
[Bindable("propertyChange")]
public function get alpha() : Number
{
return _bitmapFilter.alpha;
}
public function set alpha(value : Number) : void
{
setValue("alpha", value);
}
}
}

View File

@ -0,0 +1,234 @@
package com.degrafa.filters
{
import flash.filters.BitmapFilter;
import flash.filters.DropShadowFilter;
/**
* A bindable Degrafa-fied wrapper for flash.filters.DropShadowFilter.
*
* todo: poach documentation for filter properties from Flex SDK.
*
* @author josh
*/
public class DegrafaDropShadowFilter extends DegrafaFilter
{
//--------------------------------------------------------------------------
//
// Constructor
//
//--------------------------------------------------------------------------
public function DegrafaDropShadowFilter(distance : Number = 4.0,
angle : Number = 45,
color : uint = 0,
alpha : Number = 1.0,
blurX : Number = 4.0,
blurY : Number = 4.0,
strength : Number = 1.0,
quality : int = 1,
inner : Boolean = false,
knockout : Boolean = false,
hideObject : Boolean = false)
{
super();
_bitmapFilter = new DropShadowFilter(distance,
angle,
color,
alpha,
blurX,
blurY,
strength,
quality,
inner,
knockout,
hideObject);
}
//--------------------------------------------------------------------------
//
// Actual (proxied) filter
//
//--------------------------------------------------------------------------
private var _bitmapFilter : DropShadowFilter;
/**
* @return the proxied flash.filters.DropShadowFilter
*/
override public function get bitmapFilter() : BitmapFilter
{
return _bitmapFilter;
}
//--------------------------------------------------------------------------
//
// Work
//
//--------------------------------------------------------------------------
//----------------------------------
// distance
//----------------------------------
[Bindable("propertyChange")]
public function get distance() : Number
{
return _bitmapFilter.distance;
}
public function set distance(value : Number) : void
{
setValue("distance", value);
}
//----------------------------------
// angle
//----------------------------------
[Bindable("propertyChange")]
public function get angle() : Number
{
return _bitmapFilter.angle;
}
public function set angle(value : Number) : void
{
setValue("angle", value);
}
//----------------------------------
// color
//----------------------------------
[Bindable("propertyChange")]
public function get color() : Number
{
return _bitmapFilter.color;
}
public function set color(value : Number) : void
{
setValue("color", value);
}
//----------------------------------
// alpha
//----------------------------------
[Bindable("propertyChange")]
public function get alpha() : Number
{
return _bitmapFilter.alpha;
}
public function set alpha(value : Number) : void
{
setValue("alpha", value);
}
//----------------------------------
// blurX
//----------------------------------
[Bindable("propertyChange")]
public function get blurX() : Number
{
return _bitmapFilter.blurX;
}
public function set blurX(value : Number) : void
{
setValue("blurX", value);
}
//----------------------------------
// blurY
//----------------------------------
[Bindable("propertyChange")]
public function get blurY() : Number
{
return _bitmapFilter.blurY;
}
public function set blurY(value : Number) : void
{
setValue("blurY", value);
}
//----------------------------------
// strength
//----------------------------------
[Bindable("propertyChange")]
public function get strength() : Number
{
return _bitmapFilter.strength;
}
public function set strength(value : Number) : void
{
setValue("strength", value);
}
//----------------------------------
// quality
//----------------------------------
[Bindable("propertyChange")]
public function get quality() : Number
{
return _bitmapFilter.quality;
}
public function set quality(value : Number) : void
{
setValue("quality", value);
}
//----------------------------------
// inner
//----------------------------------
[Bindable("propertyChange")]
public function get inner() : Boolean
{
return _bitmapFilter.inner;
}
public function set inner(value : Boolean) : void
{
setValue("inner", value);
}
//----------------------------------
// knockout
//----------------------------------
[Bindable("propertyChange")]
public function get knockout() : Boolean
{
return _bitmapFilter.knockout;
}
public function set knockout(value : Boolean) : void
{
setValue("knockout", value);
}
//----------------------------------
// hideObject
//----------------------------------
[Bindable("propertyChange")]
public function get hideObject() : Boolean
{
return _bitmapFilter.hideObject;
}
public function set hideObject(value : Boolean) : void
{
setValue("hideObject", value);
}
}
}

View File

@ -0,0 +1,84 @@
package com.degrafa.filters
{
import com.degrafa.core.DegrafaObject;
import flash.filters.BitmapFilter;
/**
* Base for all filter proxies required to support bindings and states
* @author josh
*
*/
public class DegrafaFilter extends DegrafaObject
{
public function DegrafaFilter()
{
super();
}
/**
* Returns the actual filter to be applied
* @return the native BitmapFilter instance - subclasses to override :)
*/
public function get bitmapFilter() : BitmapFilter
{
throw new Error("Subclass to override get bitmapFilter()");
}
/**
* To cut down on boilerplate in subclasses. Boilerplate would of course be faster.
*
* todo: replace with boilerplate - the list of filters ain't gonna change soon :D
*
* @param name
* @param value
*
*/
protected function setValue(name : String, value : *) : void
{
var oldValue : * = bitmapFilter[name];
if (oldValue == value)
return;
bitmapFilter[name] = value;
dispatchPropertyChange(false, name, oldValue, value);
}
//TODO - Josh: impl this :)
// private var _enabled : Boolean = true;
//
// //TODO: Custom bindable event
// [Bindable]
// /**
// * If false, this effect will not be applied
// */
// public function get enabled() : Boolean
// {
// return _enabled;
// }
//
// public function set enabled(value : Boolean) : void
// {
// _enabled = value;
// }
//
// private var _state : String;
//
// //TODO: Custom bindable event
// [Bindable]
// /**
// * The state at which to apply this filter. This property is specific to Skinning.
// */
// public function get state() : String
// {
// return state;
// }
//
// public function set state(value : String) : void
// {
// _state = value;
// }
}
}

View File

@ -0,0 +1,183 @@
package com.degrafa.filters
{
import flash.filters.BitmapFilter;
import flash.filters.GlowFilter;
/**
* A bindable Degrafa-fied wrapper for flash.filters.GlowFilter.
*
* todo: poach documentation for filter properties from Flex SDK.
*
* @author josh
*/
public class DegrafaGlowFilter extends DegrafaFilter
{
//--------------------------------------------------------------------------
//
// Actual (proxied) filter
//
//--------------------------------------------------------------------------
private var _bitmapFilter : GlowFilter;
/**
* @return the proxied flash.filters.GlowFilter
*/
override public function get bitmapFilter() : BitmapFilter
{
return _bitmapFilter;
}
//--------------------------------------------------------------------------
//
// Constructor
//
//--------------------------------------------------------------------------
public function DegrafaGlowFilter(color : uint = 0xFF0000,
alpha : Number = 1.0,
blurX : Number = 6.0,
blurY : Number = 6.0,
strength : Number = 2,
quality : int = 1,
inner : Boolean = false,
knockout : Boolean = false)
{
super();
_bitmapFilter = new GlowFilter(color,
alpha,
blurX,
blurY,
strength,
quality,
inner,
knockout);
}
//--------------------------------------------------------------------------
//
// Work
//
//--------------------------------------------------------------------------
//----------------------------------
// color
//----------------------------------
[Bindable("propertyChange")]
public function get color() : uint
{
return _bitmapFilter.color;
}
public function set color(value : uint) : void
{
setValue("color", value);
}
//----------------------------------
// alpha
//----------------------------------
[Bindable("propertyChange")]
public function get alpha() : Number
{
return _bitmapFilter.alpha;
}
public function set alpha(value : Number) : void
{
setValue("alpha", value);
}
//----------------------------------
// blurX
//----------------------------------
[Bindable("propertyChange")]
public function get blurX() : Number
{
return _bitmapFilter.blurX;
}
public function set blurX(value : Number) : void
{
setValue("blurX", value);
}
//----------------------------------
// blurY
//----------------------------------
[Bindable("propertyChange")]
public function get blurY() : Number
{
return _bitmapFilter.blurY;
}
public function set blurY(value : Number) : void
{
setValue("blurY", value);
}
//----------------------------------
// strength
//----------------------------------
[Bindable("propertyChange")]
public function get strength() : Number
{
return _bitmapFilter.strength;
}
public function set strength(value : Number) : void
{
setValue("strength", value);
}
//----------------------------------
// quality
//----------------------------------
[Bindable("propertyChange")]
public function get quality() : int
{
return _bitmapFilter.quality;
}
public function set quality(value : int) : void
{
setValue("quality", value);
}
//----------------------------------
// inner
//----------------------------------
[Bindable("propertyChange")]
public function get inner() : Boolean
{
return _bitmapFilter.inner;
}
public function set inner(value : Boolean) : void
{
setValue("inner", value);
}
//----------------------------------
// knockout
//----------------------------------
[Bindable("propertyChange")]
public function get knockout() : Boolean
{
return _bitmapFilter.knockout;
}
public function set knockout(value : Boolean) : void
{
setValue("knockout", value);
}
}
}

View File

@ -0,0 +1,234 @@
package com.degrafa.filters
{
import flash.filters.BitmapFilter;
import flash.filters.GradientBevelFilter;
/**
* A bindable Degrafa-fied wrapper for flash.filters.GradientBevelFilter.
*
* todo: poach documentation for filter properties from Flex SDK.
*
* @author josh
*/
public class DegrafaGradientBevelFilter extends DegrafaFilter
{
//--------------------------------------------------------------------------
//
// Actual (proxied) filter
//
//--------------------------------------------------------------------------
private var _bitmapFilter : GradientBevelFilter;
/**
* @return the proxied flash.filters.GradientBevelFilter
*/
override public function get bitmapFilter() : BitmapFilter
{
return _bitmapFilter;
}
//--------------------------------------------------------------------------
//
// Constructor
//
//--------------------------------------------------------------------------
public function DegrafaGradientBevelFilter(distance : Number = 4.0,
angle : Number = 45,
colors : Array = null,
alphas : Array = null,
ratios : Array = null,
blurX : Number = 4.0,
blurY : Number = 4.0,
strength : Number = 1,
quality : int = 1,
type : String = "inner",
knockout : Boolean = false)
{
super();
_bitmapFilter = new GradientBevelFilter(distance,
angle,
colors,
alphas,
ratios,
blurX,
blurY,
strength,
quality,
type,
knockout);
}
//--------------------------------------------------------------------------
//
// Work
//
//--------------------------------------------------------------------------
//----------------------------------
// distance
//----------------------------------
[Bindable("propertyChange")]
public function get distance() : Number
{
return _bitmapFilter.distance;
}
public function set distance(value : Number) : void
{
setValue("distance", value);
}
//----------------------------------
// angle
//----------------------------------
[Bindable("propertyChange")]
public function get angle() : Number
{
return _bitmapFilter.angle;
}
public function set angle(value : Number) : void
{
setValue("angle", value);
}
//----------------------------------
// colors
//----------------------------------
[Bindable("propertyChange")]
public function get colors() : Array
{
return _bitmapFilter.colors;
}
public function set colors(value : Array) : void
{
setValue("colors", value);
}
//----------------------------------
// alphas
//----------------------------------
[Bindable("propertyChange")]
public function get alphas() : Array
{
return _bitmapFilter.alphas;
}
public function set alphas(value : Array) : void
{
setValue("alphas", value);
}
//----------------------------------
// ratios
//----------------------------------
[Bindable("propertyChange")]
public function get ratios() : Array
{
return _bitmapFilter.ratios;
}
public function set ratios(value : Array) : void
{
setValue("ratios", value);
}
//----------------------------------
// blurX
//----------------------------------
[Bindable("propertyChange")]
public function get blurX() : Number
{
return _bitmapFilter.blurX;
}
public function set blurX(value : Number) : void
{
setValue("blurX", value);
}
//----------------------------------
// blurY
//----------------------------------
[Bindable("propertyChange")]
public function get blurY() : Number
{
return _bitmapFilter.blurY;
}
public function set blurY(value : Number) : void
{
setValue("blurY", value);
}
//----------------------------------
// strength
//----------------------------------
[Bindable("propertyChange")]
public function get strength() : Number
{
return _bitmapFilter.strength;
}
public function set strength(value : Number) : void
{
setValue("strength", value);
}
//----------------------------------
// quality
//----------------------------------
[Bindable("propertyChange")]
public function get quality() : int
{
return _bitmapFilter.quality;
}
public function set quality(value : int) : void
{
setValue("quality", value);
}
//----------------------------------
// type
//----------------------------------
[Bindable("propertyChange")]
public function get type() : String
{
return _bitmapFilter.type;
}
public function set type(value : String) : void
{
setValue("type", value);
}
//----------------------------------
// knockout
//----------------------------------
[Bindable("propertyChange")]
public function get knockout() : Boolean
{
return _bitmapFilter.knockout;
}
public function set knockout(value : Boolean) : void
{
setValue("knockout", value);
}
}
}

View File

@ -0,0 +1,234 @@
package com.degrafa.filters
{
import flash.filters.BitmapFilter;
import flash.filters.GradientGlowFilter;
/**
* A bindable Degrafa-fied wrapper for flash.filters.GradientGlowFilter.
*
* todo: poach documentation for filter properties from Flex SDK.
*
* @author josh
*/
public class DegrafaGradientGlowFilter extends DegrafaFilter
{
//--------------------------------------------------------------------------
//
// Actual (proxied) filter
//
//--------------------------------------------------------------------------
private var _bitmapFilter : GradientGlowFilter;
/**
* @return the proxied flash.filters.GradientGlowFilter
*/
override public function get bitmapFilter() : BitmapFilter
{
return _bitmapFilter;
}
//--------------------------------------------------------------------------
//
// Constructor
//
//--------------------------------------------------------------------------
public function DegrafaGradientGlowFilter(distance : Number = 4.0,
angle : Number = 45,
colors : Array = null,
alphas : Array = null,
ratios : Array = null,
blurX : Number = 4.0,
blurY : Number = 4.0,
strength : Number = 1,
quality : int = 1,
type : String = "inner",
knockout : Boolean = false)
{
super();
_bitmapFilter = new GradientGlowFilter(distance,
angle,
colors,
alphas,
ratios,
blurX,
blurY,
strength,
quality,
type,
knockout);
}
//--------------------------------------------------------------------------
//
// Work
//
//--------------------------------------------------------------------------
//----------------------------------
// distance
//----------------------------------
[Bindable("propertyChange")]
public function get distance() : Number
{
return _bitmapFilter.distance;
}
public function set distance(value : Number) : void
{
setValue("distance", value);
}
//----------------------------------
// angle
//----------------------------------
[Bindable("propertyChange")]
public function get angle() : Number
{
return _bitmapFilter.angle;
}
public function set angle(value : Number) : void
{
setValue("angle", value);
}
//----------------------------------
// colors
//----------------------------------
[Bindable("propertyChange")]
public function get colors() : Array
{
return _bitmapFilter.colors;
}
public function set colors(value : Array) : void
{
setValue("colors", value);
}
//----------------------------------
// alphas
//----------------------------------
[Bindable("propertyChange")]
public function get alphas() : Array
{
return _bitmapFilter.alphas;
}
public function set alphas(value : Array) : void
{
setValue("alphas", value);
}
//----------------------------------
// ratios
//----------------------------------
[Bindable("propertyChange")]
public function get ratios() : Array
{
return _bitmapFilter.ratios;
}
public function set ratios(value : Array) : void
{
setValue("ratios", value);
}
//----------------------------------
// blurX
//----------------------------------
[Bindable("propertyChange")]
public function get blurX() : Number
{
return _bitmapFilter.blurX;
}
public function set blurX(value : Number) : void
{
setValue("blurX", value);
}
//----------------------------------
// blurY
//----------------------------------
[Bindable("propertyChange")]
public function get blurY() : Number
{
return _bitmapFilter.blurY;
}
public function set blurY(value : Number) : void
{
setValue("blurY", value);
}
//----------------------------------
// strength
//----------------------------------
[Bindable("propertyChange")]
public function get strength() : Number
{
return _bitmapFilter.strength;
}
public function set strength(value : Number) : void
{
setValue("strength", value);
}
//----------------------------------
// quality
//----------------------------------
[Bindable("propertyChange")]
public function get quality() : int
{
return _bitmapFilter.quality;
}
public function set quality(value : int) : void
{
setValue("quality", value);
}
//----------------------------------
// type
//----------------------------------
[Bindable("propertyChange")]
public function get type() : String
{
return _bitmapFilter.type;
}
public function set type(value : String) : void
{
setValue("type", value);
}
//----------------------------------
// knockout
//----------------------------------
[Bindable("propertyChange")]
public function get knockout() : Boolean
{
return _bitmapFilter.knockout;
}
public function set knockout(value : Boolean) : void
{
setValue("knockout", value);
}
}
}

View File

@ -0,0 +1,708 @@
////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2008 The Degrafa Team : http://www.Degrafa.com/team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
// Programmed by: Jim Armstrong
//
// This software is derived from source containing the following copyright notice
//
// copyright (c) 2006-2007, Jim Armstrong. All Rights Reserved.
//
// This software program is supplied 'as is' without any warranty, express, implied,
// or otherwise, including without limitation all warranties of merchantability or fitness
// for a particular purpose. Jim Armstrong shall not be liable for any special incidental, or
// consequential damages, including, without limitation, lost revenues, lost profits, or
// loss of prospective economic advantage, resulting from the use or misuse of this software
// program.
//
////////////////////////////////////////////////////////////////////////////////
package com.degrafa.geometry
{
import com.degrafa.IGeometry;
import com.degrafa.geometry.utilities.GeometryUtils;
import com.degrafa.utilities.math.SimpleRoot;
import flash.display.Graphics;
import flash.geom.Rectangle;
import flash.geom.Point;
import com.degrafa.utilities.math.SimpleRoot;
import com.degrafa.utilities.math.Solve2x2;
//--------------------------------------
// Other metadata
//--------------------------------------
[IconFile("CubicBezier.png")]
[Bindable]
/**
* The AdvancedCubicBezier element draws a cubic Bézier using the specified start point,
* end point and 2 control points. and contains several additional methods
* that are useful in advanced applications.
*
*
**/
public class AdvancedCubicBezier extends CubicBezier
{
// bezier polynomial coefficients
private var _c0X:Number;
private var _c0Y:Number;
private var _c1X:Number;
private var _c1Y:Number;
private var _c2X:Number;
private var _c2Y:Number;
private var _c3X:Number;
private var _c3Y:Number;
// limit on interval width before interval is considered completely bisected
private var _bisectLimit:Number;
// bisection interval bounds
private var _left:Number;
private var _right:Number;
private var _twbrf:SimpleRoot;
// stationary points of x(t) and y(t)
private var _t1X:Number;
private var _t1Y:Number;
private var _t2X:Number;
private var _t2Y:Number;
// specialized 2x2 solver using Cramer's rule
private var _solver:Solve2x2;
/**
* Constructor.
*
* <p>The advanced cubic Bézier constructor accepts 8 optional arguments that define it's
* start, end and controls points.</p>
*
* @param x0 A number indicating the starting x-axis coordinate.
* @param y0 A number indicating the starting y-axis coordinate.
* @param cx A number indicating the first control x-axis coordinate.
* @param cy A number indicating the first control y-axis coordinate.
* @param cx1 A number indicating the second control x-axis coordinate.
* @param cy1 A number indicating the second control y-axis coordinate.
* @param x1 A number indicating the ending x-axis coordinate.
* @param y1 A number indicating the ending y-axis coordinate.
*/
public function AdvancedCubicBezier(x0:Number=NaN,y0:Number=NaN,cx:Number=NaN,cy:Number=NaN,cx1:Number=NaN,cy1:Number=NaN,x1:Number=NaN,y1:Number=NaN)
{
super();
this.x0 = x0;
this.y0 = y0;
this.cx = cx;
this.cy = cy;
this.x1 = x1;
this.y1 = y1;
_bisectLimit = 0.05;
_left = 0;
_right = 1;
_t1X = 0;
_t1Y = 0;
_t2X = 0;
_t2Y = 0;
// Jack Crenshaw's TWBRF and 2x2 solver, both instantiated on demand
_twbrf = null;
_solver = null;
}
/**
* @inheritDoc
**/
override public function preDraw():void
{
if( invalidated )
{
commandStack.length=0;
// add a MoveTo at the start of the commandStack rendering chain
commandStack.addMoveTo(x0,y0);
commandStack.addCubicBezierTo(x0,y0,cx,cy,cx1,cy1,x1,y1,1);
if( close )
{
commandStack.addLineTo(x0,y0);
}
getBezierCoef();
invalidated = false;
}
}
override public function pointAt(_t:Number):Point
{
var t:Number = _t < 0 ? 0 : _t;
t = t > 1 ? 1 : t;
return new Point( _c0X + t*(_c1X + t*(_c2X + t*_c3X)), _c0Y + t*(_c1Y + t*(_c2Y + t*_c3Y)) );
}
/**
* interpolate
*
* <p>Compute control points so that quadratic Bezier passes through three points at the specified parameter value.
*
* @param _points:Array - array of three <code>Point</code> references, representing the coordinates of the interpolation points.
*
* @return Array the parameter values in [0,1] at which the Bezier curve passes through the second and third interpolation points (determined by a chord-length parameterization).
* A negative value is returned if less than three interpolation points are provided.
*
*/
public function interpolate(points:Array):Array
{
// compute t-value using chord-length parameterization
if( points.length < 4 )
{
return [-1];
}
// no error-checking ... you break it, you buy it.
var p0:Point = points[0];
var p1:Point = points[1];
var p2:Point = points[2];
var p3:Point = points[3];
x0 = p0.x;
y0 = p0.y;
x1 = p3.x;
y1 = p3.y;
// currently, this method auto-parameterizes the curve using chord-length parameterization. A future version might allow inputting the two t-values, but this is more
// user-friendly (what an over-used term :)
var deltaX:Number = p1.x - p0.x;
var deltaY:Number = p1.y - p0.y;
var d1:Number = Math.sqrt(deltaX*deltaX + deltaY*deltaY);
deltaX = p2.x - p1.x;
deltaY = p2.y - p1.y;
var d2:Number = Math.sqrt(deltaX*deltaX + deltaY*deltaY);
deltaX = p3.x - p2.x;
deltaY = p3.y - p2.y;
var d3:Number = Math.sqrt(deltaX*deltaX + deltaY*deltaY);
var d:Number = d1 + d2 + d3;
var t1:Number = d1/d;
var t2:Number = (d1+d2)/d;
// there are four unknowns (x- and y-coords for P1 and P2), which are solved as two separate sets of two equations in two unknowns
var t12:Number = t1*t1;
var t13:Number = t1*t12;
var t22:Number = t2*t2;
var t23:Number = t2*t22;
// x-coordinates of P1 and P2 (t = t1 and t2) - exercise: eliminate redudant computations in these equations
var a11:Number = 3*t13 - 6*t12 + 3*t1;
var a12:Number = -3*t13 + 3*t12;
var a21:Number = 3*t23 - 6*t22 + 3*t2;
var a22:Number = -3*t23 + 3*t22;
var b1:Number = -t13*x1 + x0*(t13 - 3*t12 + 3*t1 - 1) + p1.x;
var b2:Number = -t23*x1 + x0*(t23 - 3*t22 + 3*t2 - 1) + p2.x;
if( _solver == null )
{
_solver = new Solve2x2();
}
// beware nearly or exactly coincident interior interpolation points
var p:Point = _solver.solve(a11, a12, a21, a22, b1, b2);
if( _solver.determinant < 0.000001 )
{
// degenerates to a parabolic interpolation
var t1m1:Number = 1.0-t1;
var tSq:Number = t1*t1;
var denom:Number = 2.0*t1*t1m1;
// to do - handle case where this degenerates into all overlapping points (i.e. denom is numerically zero)
cx = (p1.x - t1m1*t1m1*x0 - tSq*p2.x)/denom;
cy = (p1.y - t1m1*t1m1*y0 - tSq*p2.y)/denom;
cx1 = cx;
cy1 = cy;
getBezierCoef();
return [t1, t1];
}
else
{
cx = p.x
cx1 = p.y;
}
// y-coordinates of P1 and P2 (t = t1 and t2)
b1 = -t13*y1 + y0*(t13 - 3*t12 + 3*t1 - 1) + p1.y;
b2 = -t23*y1 + y0*(t23 - 3*t22 + 3*t2 - 1) + p2.y;
// resolving with same coefficients, but new RHS
p = _solver.solve(a11, a12, a21, a22, b1, b2, 0.00001, true);
cy = p.x
cy1 = p.y;
getBezierCoef();
return [t1, t2];
}
/**
* tAtMinX
*
* <p>Find t-parameter at which the x-coordinate is a minimum.</p>
*
* @return Number Parameter value in [0,1] at which the cubic Bezier curve's x-coordinate is a minimum
*
* @since 1.0
*
*/
public function tAtMinX():Number
{
getStationaryPoints();
var t:Number = 0;
var minX:Number = x0;
if( x1 < minX )
{
t = 1;
minX = x1;
}
if( _t1X > 0 && _t1X < 1 )
{
var myX:Number = pointAt(_t1X).x;
if( myX < minX )
{
t = _t1X;
minX = myX;
}
}
if( _t2X > 0 && _t2X < 1 )
{
if( pointAt(_t2X).x < minX )
{
t = _t2X;
}
}
return t;
}
/**
* tAtMaxX
*
* <p>Find t-parameter at which the x-coordinate is a maximum.</p>
*
* @return Number Parameter value in [0,1] at which the cubic Bezier curve's x-coordinate is a maximum.
*
*/
public function tAtMaxX():Number
{
getStationaryPoints();
var t:Number = 0;
var maxX:Number = x0;
if( x1 > maxX )
{
t = 1;
maxX = x1;
}
if( _t1X > 0 && _t1X < 1 )
{
var myX:Number = pointAt(_t1X).x;
if( myX > maxX )
{
t = _t1X;
maxX = myX;
}
}
if( _t2X > 0 && _t2X < 1 )
{
if( pointAt(_t2X).x > maxX )
{
t = _t2X;
}
}
return t;
}
/**
* tAtMinY
*
* <p>Find t-parameter at which the y-coordinate is a minimum.</p<>
*
* @return Number - Parameter value in [0,1] at which the cubic Bezier curve's y-coordinate is a minimum.
*
*/
public function tAtMinY():Number
{
getStationaryPoints(false);
var t:Number = 0;
var minY:Number = y0;
if( y1 < minY )
{
t = 1;
minY = y1;
}
if( _t1Y > 0 && _t1Y < 1 )
{
var myY:Number = pointAt(_t1Y).y;
if( myY < minY )
{
t = _t1Y;
minY = myY;
}
}
if( _t2Y > 0 && _t2Y < 1 )
{
if( pointAt(_t2Y).y < minY )
{
t = _t2Y;
}
}
return t;
}
/**
* tAtMaxY
*
* <p>Find t-parameter at which the y-coordinate is a maximum.</p>
*
* @return Number Parameter value in [0,1] at which the cubic Bezier curve's y-coordinate is a maximum.
*
*/
public function tAtMaxY():Number
{
getStationaryPoints(false);
var t:Number = 0;
var maxY:Number = y0;
if( y1 > maxY )
{
t = 1;
maxY = y1;
}
if( _t1Y > 0 && _t1Y < 1 )
{
var myY:Number = pointAt(_t1Y).y;
if( myY > maxY )
{
t = _t1Y;
maxY = myY;
}
}
if( _t2Y > 0 && _t2Y < 1 )
{
if( pointAt(_t2Y).y > maxY )
{
t = _t2Y;
}
}
return t;
}
/**
* yAtX
*
* <p>Return the set of y-coordinates corresponding to the input x-coordinate.</p>
*
* @param _x:Number x-coordinate at which the desired y-coordinates are desired
*
* @return Array set of (t,y)-coordinates at the input x-coordinate provided that the x-coordinate is inside the range
* covered by the quadratic Bezier in [0,1]; that is there must exist t in [0,1] such that Bx(t) = _x. If the input
* x-coordinate is not inside the range covered by the Bezier curve, the returned array is empty. Otherwise, the
* array contains either one, two, or three y-coordinates. There are issues with curves that are exactly or nearly (for
* numerical purposes) vertical in which there could theoretically be an infinite number of y-coordinates for a single
* x-coordinate. This method does not work in such cases, although compensation might be added in the future.
*
* <p>Each array element is a reference to an <code>Object</code> whose 't' parameter represents the Bezier t parameter. The
* <code>Object</code> 'y' property is the corresponding y-value. The returned (t,y) coordinates may be used by the caller
* to determine which of the (up to three) returned y-coordinates might be preferred over the others.</p>
*
*/
public function yAtX(_x:Number):Array
{
if( isNaN(_x) )
{
return [];
}
// check bounds
var xMax:Number = pointAt(tAtMaxX()).x;
var xMin:Number = pointAt(tAtMinX()).x;
if( _x < xMin || _x > xMax )
{
return [];
}
// the necessary y-coordinates are the intersection of the curve with the line x = _x. The curve is generated in the
// form c0 + c1*t + c2*t^2 + c3*t^3, so the intersection satisfies the equation
// Bx(t) = _x or Bx(t) - _x = 0, or c0x-_x + c1x*t + c2x*t^2 + c3x*t^3 = 0.
getBezierCoef();
// Find one root - any root - then factor out (t-r) to get a quadratic poly. for the remaining roots
var f:Function = function(_t:Number):Number { return _t*(_c1X + _t*(_c2X + _t*(_c3X))) + _c0X-_x; }
if( _twbrf == null )
_twbrf = new SimpleRoot();
// some curves that loop around on themselves may require bisection
_left = 0;
_right = 1;
__bisect(f, 0, 1);
// experiment with tolerance - but not too tight :)
var t0:Number = _twbrf.findRoot(_left, _right, f, 50, 0.000001);
var eval:Number = Math.abs(f(t0));
if( eval > 0.00001 )
return []; // compensate in case method quits due to error (no event listener here)
var result:Array = new Array();
if( t0 <= 1 )
result.push({t:t0, y:pointAt(t0).y});
// Factor theorem: t-r is a factor of the cubic polynomial if r is a root. Use this to reduce to a quadratic poly.
// using synthetic division
var a:Number = _c3X;
var b:Number = t0*a+_c2X;
var c:Number = t0*b+_c1X;
// process the quadratic for the remaining two possible roots
var d:Number = b*b - 4*a*c;
if( d < 0 )
{
return result;
}
d = Math.sqrt(d);
a = 1/(a + a);
var t1:Number = (d-b)*a;
var t2:Number = (-b-d)*a;
if( t1 >= 0 && t1 <=1 )
result.push( {t:t1, y:pointAt(t1).y} );
if( t2 >= 0 && t2 <=1 )
result.push( {t:t2, y:pointAt(t2).y} );
return result;
}
/**
* xAtY
*
* <p>Return the set of x-coordinates corresponding to the input y-coordinate.</p>
*
* @param _y:Number y-coordinate at which the desired x-coordinates are desired
*
* @return Array set of (t,x)-coordinates at the input y-coordinate provided that the y-coordinate is inside the range
* covered by the quadratic Bezier in [0,1]; that is there must exist t in [0,1] such that By(t) = _y. If the input
* y-coordinate is not inside the range covered by the Bezier curve, the returned array is empty. Otherwise, the
* array contains either one, two, or three x-coordinates. There are issues with curves that are exactly or nearly (for
* numerical purposes) horizontal in which there could theoretically be an infinite number of x-coordinates for a single
* y-coordinate. This method does not work in such cases, although compensation might be added in the future.
*
* <p>Each array element is a reference to an <code>Object</code> whose 't' parameter represents the Bezier t parameter. The
* <code>Object</code> 'x' property is the corresponding x-coordinate. The returned (t,x) coordinates may be used by the caller
* to determine which of the (up to three) returned x-coordinates might be preferred over the others.</p>
*
*/
public function xAtY(_y:Number):Array
{
if( isNaN(_y) )
{
return [];
}
// check bounds
var yMax:Number = pointAt(tAtMaxY()).y;
var yMin:Number = pointAt(tAtMinY()).y;
if( _y < yMin || _y > yMax )
{
return [];
}
// the necessary y-coordinates are the intersection of the curve with the line y = _y. The curve is generated in the
// form c0 + c1*t + c2*t^2 + c3*t^3, so the intersection satisfies the equation
// By(t) = _y or By(t) - _y = 0, or c0y-_y + c1y*t + c2y*t^2 + c3y*t^3 = 0.
getBezierCoef();
// Find one root - any root - then factor out (t-r) to get a quadratic poly. for the remaining roots
var f:Function = function(_t:Number):Number { return _t*(_c1Y + _t*(_c2Y + _t*(_c3Y))) + _c0Y-_y; }
if( _twbrf == null )
_twbrf = new SimpleRoot();
// some curves that loop around on themselves may require bisection
_left = 0;
_right = 1;
__bisect(f, 0, 1);
// experiment with tolerance - but not too tight :)
var t0:Number = _twbrf.findRoot(_left, _right, f, 50, 0.000001);
var eval:Number = Math.abs(f(t0));
if( eval > 0.00001 )
return []; // compensate in case method quits due to error (no event listener here)
var result:Array = new Array();
if( t0 <= 1 )
result.push({t:t0, x:pointAt(t0).x});
// Factor theorem: t-r is a factor of the cubic polynomial if r is a root. Use this to reduce to a quadratic poly. using synthetic division
var a:Number = _c3Y;
var b:Number = t0*a+_c2Y;
var c:Number = t0*b+_c1Y;
// process the quadratic for the remaining two possible roots
var d:Number = b*b - 4*a*c;
if( d < 0 )
{
return result;
}
d = Math.sqrt(d);
a = 1/(a + a);
var t1:Number = (d-b)*a;
var t2:Number = (-b-d)*a;
if( t1 >= 0 && t1 <=1 )
result.push( {t:t1, x:pointAt(t1).x} );
if( t2 >= 0 && t2 <=1 )
result.push( {t:t2, x:pointAt(t2).x} );
return result;
}
// recompute polynomial coefficients
private function getBezierCoef():void
{
_c0X = x0;
_c0Y = y0;
var dX:Number = 3.0*(cx-x0);
var dY:Number = 3.0*(cy-y0);
_c1X = dX;
_c1Y = dY;
var bX:Number = 3.0*(cx1-cx) - dX;
var bY:Number = 3.0*(cy1-cy) - dY;
_c2X = bX;
_c2Y = bY;
_c3X = x1 - x0 - dX - bX;
_c3Y = y1 - y0 - dY - bY;
}
// bisect the specified range to isolate an interval with a root.
private function __bisect(_f:Function, _l:Number, _r:Number):void
{
if( Math.abs(_r-_l) <= _bisectLimit )
{
return;
}
var left:Number = _l;
var right:Number = _r;
var middle:Number = 0.5*(left+right);
if( _f(left)*_f(right) <= 0 )
{
_left = left;
_right = right;
return;
}
else
{
__bisect(_f, left, middle);
__bisect(_f, middle, right);
}
}
// get the statonary points of x(t) and y(t)
private function getStationaryPoints(pX:Boolean=true):void
{
// in a future release, this will be made more efficient - don't want to mess with the invalidated flag just yet :)
getBezierCoef();
// given polynomial coefficients, the bezier curve equation is of the form c0 + c1*t + c2*t^2 + c3*t^3, so the derivative is of
// the form c1 + 2*c2*t + 3*c3*t^2, which has two roots
var d:Number = -1;
var t1:Number = -1;
var t2:Number = -1;
if( pX )
{
d = 4*_c2X*_c2X - 12*_c1X*_c3X;
if( d >= 0 )
{
d = Math.sqrt(d);
var a:Number = 6*_c3X;
var b:Number = 2*_c2X;
t1 = (-b + d)/a;
t2 = (-b - d)/a;
}
_t1X = t1 >= 0 && t1 <= 1 ? t1 : -1;
_t2X = t2 >= 0 && t2 <= 1 ? t2 : -1;
}
else
{
d = 4*_c2Y*_c2Y - 12*_c1Y*_c3Y;
if( d >= 0 )
{
d = Math.sqrt(d);
a = 6*_c3Y;
b = 2*_c2Y;
t1 = (-b + d)/a;
t2 = (-b - d)/a;
}
_t1Y = t1 >= 0 && t1 <= 1 ? t1 : -1;
_t2Y = t2 >= 0 && t2 <= 1 ? t2 : -1;
}
}
}
}

View File

@ -0,0 +1,497 @@
////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2008 The Degrafa Team : http://www.Degrafa.com/team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
// Programmed by: Jim Armstrong
//
// This software is derived from source containing the following copyright notice
//
// copyright (c) 2006-2007, Jim Armstrong. All Rights Reserved.
//
// This software program is supplied 'as is' without any warranty, express, implied,
// or otherwise, including without limitation all warranties of merchantability or fitness
// for a particular purpose. Jim Armstrong shall not be liable for any special incidental, or
// consequential damages, including, without limitation, lost revenues, lost profits, or
// loss of prospective economic advantage, resulting from the use or misuse of this software
// program.
//
////////////////////////////////////////////////////////////////////////////////
package com.degrafa.geometry
{
import com.degrafa.IGeometry;
import com.degrafa.geometry.utilities.GeometryUtils;
import flash.display.Graphics;
import flash.geom.Rectangle;
import flash.geom.Point;
//--------------------------------------
// Other metadata
//--------------------------------------
[IconFile("QuadraticBezier.png")]
[Bindable]
/**
* The AdvancedQuadraticBezier element draws a quadratic Bézier using the specified
* start point, end point and control point and contains several additional methods
* that are useful in advanced applications.
*
*
**/
public class AdvancedQuadraticBezier extends QuadraticBezier
{
// bezier polynomial coefficients
private var _c0X:Number;
private var _c0Y:Number;
private var _c1X:Number;
private var _c1Y:Number;
private var _c2X:Number;
private var _c2Y:Number;
/**
* Constructor.
*
* <p>The advanced quadratic Bézier constructor accepts 6 optional arguments that define it's
* start, end and controls points.</p>
*
* @param x0 A number indicating the starting x-axis coordinate.
* @param y0 A number indicating the starting y-axis coordinate.
* @param cx A number indicating the control x-axis coordinate.
* @param cy A number indicating the control y-axis coordinate.
* @param x1 A number indicating the ending x-axis coordinate.
* @param y1 A number indicating the ending y-axis coordinate.
*/
public function AdvancedQuadraticBezier(x0:Number=NaN,y0:Number=NaN,cx:Number=NaN,cy:Number=NaN,x1:Number=NaN,y1:Number=NaN)
{
super();
this.x0 = x0;
this.y0 = y0;
this.cx = cx;
this.cy = cy;
this.x1 = x1;
this.y1 = y1;
}
/**
* @inheritDoc
**/
override public function preDraw():void
{
// i should just call super.preDraw() then add the new stuff, but this reminds me what is going on under the hood :)
if( invalidated )
{
commandStack.length=0;
commandStack.resetBounds();
commandStack.addMoveTo(x0,y0);
commandStack.addCurveTo(cx,cy,x1,y1);
if( close )
commandStack.addLineTo(x0,y0);
getBezierCoef();
invalidated = false;
}
}
/**
* interpolate
*
* <p>Compute control points so that quadratic Bezier passes through three points at the specified parameter value.
*
* @param _points:Array - array of three <code>Point</code> references, representing the coordinates of the interpolation points.
*
* @return Number the parameter value in [0,1] at which the Bezier curve passes through the second control point (determined by a chord-length parameterization).
* A negative value is returned if less than three interpolation points are provided.
*
*/
public function interpolate(points:Array):Number
{
// compute t-value using chord-length parameterization
if( points.length < 3 )
{
return -1;
}
var p0:Point = points[0];
var p1:Point = points[1];
var p2:Point = points[2];
var dX:Number = p1.x - p0.x;
var dY:Number = p1.y - p0.y;
var d1:Number = Math.sqrt(dX*dX + dY*dY);
var d:Number = d1;
dX = p2.x - p1.x;
dY = p2.y - p1.y;
d += Math.sqrt(dX*dX + dY*dY);
var t:Number = d1/d;
var t1:Number = 1.0-t;
var tSq:Number = t*t;
var denom:Number = 2.0*t*t1;
x0 = p0.x;
y0 = p0.y;
cx = (p1.x - t1*t1*p0.x - tSq*p2.x)/denom;
cy = (p1.y - t1*t1*p0.y - tSq*p2.y)/denom;
x1 = p2.x;
y1 = p2.y;
getBezierCoef();
return t;
}
/**
* tAtMinX
*
* <p>Find t-parameter at which the x-coordinate is a minimum.</p>
*
* @return Number Parameter value in [0,1] at which the qudratic Bezier curve's x-coordinate is a minimum
*
* @since 1.0
*
*/
public function tAtMinX():Number
{
var denom:Number = (x0 - 2*cx + x1);
var tStar:Number = 0;
if( Math.abs(denom) > 0.0000001 )
tStar = (x0 - cx)/denom;
var t:Number = 0;
var minX:Number = x0;
if( x1 < minX )
{
t = 1;
minX = x1;
}
if( tStar > 0 && tStar < 1 )
{
if( pointAt(tStar).x < minX )
{
t = tStar;
}
}
return t;
}
/**
* tAtMaxX
*
* <p>Find t-parameter at which the x-coordinate is a maximum.</p>
*
* @return Number Parameter value in [0,1] at which the quadratic Bezier curve's x-coordinate is a maximum.
*
*/
public function tAtMaxX():Number
{
var denom:Number = (x0 - 2*cx + x1);
var tStar:Number = 0;
if( Math.abs(denom) > 0.0000001 )
tStar = (x0 - cx)/denom;
var t:Number = 0;
var maxX:Number = x0;
if( x1 > maxX )
{
t = 1;
maxX = x1;
}
if( tStar > 0 && tStar < 1 )
{
if( pointAt(tStar).x > maxX )
{
t = tStar;
}
}
return t;
}
/**
* tAtMinY
*
* <p>Find t-parameter at which the y-coordinate is a minimum.</p<>
*
* @return Number - Parameter value in [0,1] at which the quadratic Bezier curve's y-coordinate is a minimum.
*
*/
public function tAtMinY():Number
{
var denom:Number = (y0 - 2*cy + y1);
var tStar:Number = 0;
if( Math.abs(denom) > 0.0000001 )
tStar = (y0 - cy)/denom;
var t:Number = 0;
var minY:Number = y0;
if( y1 < minY )
{
t = 1;
minY = y1;
}
if( tStar > 0 && tStar < 1 )
{
if( pointAt(tStar).y < minY )
{
t = tStar;
}
}
return t;
}
/**
* tAtMaxY
*
* <p>Find t-parameter at which the y-coordinate is a maximum.</p>
*
* @return Number Parameter value in [0,1] at which the quadratic Bezier curve's y-coordinate is a maximum.
*
*/
public function tAtMaxY():Number
{
var denom:Number = (y0 - 2*cy + y1);
var tStar:Number = 0;
if( Math.abs(denom) > 0.0000001 )
tStar = (y0 - cy)/denom;
var t:Number = 0;
var maxY:Number = y0;
if( y1 > maxY )
{
t = 1;
maxY = y1;
}
if( tStar > 0 && tStar < 1 )
{
if( pointAt(tStar).y > maxY )
{
t = tStar;
}
}
return t;
}
/**
* yAtX
*
* <p>Return the set of y-coordinates corresponding to the input x-coordinate.</p>
*
* @param _x:Number x-coordinate at which the desired y-coordinates are desired
*
* @return Array set of (t,y)-coordinates at the input x-coordinate provided that the x-coordinate is inside the range
* covered by the quadratic Bezier in [0,1]; that is there must exist t in [0,1] such that Bx(t) = _x. If the input
* x-coordinate is not inside the range covered by the Bezier curve, the returned array is empty. Otherwise, the
* array contains either one or two y-coordinates. There are issues with curves that are exactly or nearly (for
* numerical purposes) vertical in which there could theoretically be an infinite number of y-coordinates for a single
* x-coordinate. This method does not work in such cases, although compensation might be added in the future.
*
* <p>Each array element is a reference to an <code>Object</code> whose 't' parameter represents the Bezier t parameter. The
* <code>Object</code> 'y' property is the corresponding y-value. The returned (t,y) coordinates may be used by the caller
* to determine which of two returned y-coordinates might be preferred over the other.</p>
*
*/
public function yAtX(_x:Number):Array
{
if( isNaN(_x) )
{
return [];
}
// check bounds
var xMax:Number = pointAt(tAtMaxX()).x;
var xMin:Number = pointAt(tAtMinX()).x;
if( _x < xMin || _x > xMax )
{
return [];
}
// the necessary y-coordinates are the intersection of the curve with the line x = _x. The curve is generated in the
// form c0 + c1*t + c2*t^2, so the intersection satisfies the equation Bx(t) = _x or Bx(t) - _x = 0, or c0x-_x + c1x*t + c2x*t^2 = 0,
// which is quadratic in t. I wonder what formula can be used to solve that ????
getBezierCoef();
// this is written out in individual steps for clarity
var c:Number = _c0X - _x;
var b:Number = _c1X;
var a:Number = _c2X;
var d:Number = b*b - 4*a*c;
if( d < 0 )
{
return [];
}
d = Math.sqrt(d);
a = 1/(a + a);
var t0:Number = (d-b)*a;
var t1:Number = (-b-d)*a;
var result:Array = new Array();
if( t0 <= 1 )
result.push( {t:t0, y:pointAt(t0).y} );
if( t1 >= 0 && t1 <=1 )
result.push( {t:t1, y:pointAt(t1).y} );
return result;
}
/**
* xAtY
*
* <p>Return the set of x-coordinates corresponding to the input y-coordinate.</p>
*
* @param _y:Number y-coordinate at which the desired x-coordinates are desired
*
* @return Array set of (t,x)-coordinates at the input y-coordinate provided that the y-coordinate is inside the range
* covered by the quadratic Bezier in [0,1]; that is there must exist t in [0,1] such that By(t) = _y. If the input
* y-coordinate is not inside the range covered by the Bezier curve, the returned array is empty. Otherwise, the
* array contains either one or two x-coordinates. There are issues with curves that are exactly or nearly (for
* numerical purposes) horizontal in which there could theoretically be an infinite number of x-coordinates for a single
* y-coordinate. This method does not work in such cases, although compensation might be added in the future.
*
* <p>Each array element is a reference to an <code>Object</code> whose 't' parameter represents the Bezier t parameter. The
* <code>Object</code> 'x' property is the corresponding x-coordinate. The returned (t,x) coordinates may be used by the caller
* to determine which of two returned x-coordinates might be preferred over the other.</p>
*
*/
public function xAtY(_y:Number):Array
{
if( isNaN(_y) )
{
return [];
}
// check bounds
var yMax:Number = pointAt(tAtMaxY()).y;
var yMin:Number = pointAt(tAtMinY()).y;
if( _y < yMin || _y > yMax )
{
return [];
}
// the necessary x-coordinates are the intersection of the curve with the horizontal line y = _y. The curve is generated in the
// form c0 + c1*t + c2*t^2, so the intersection satisfies the equation By(t) = _y or By(t) - _y = 0, or c0y-_y + c1y*t + c2y*t^2 = 0,
// which is quadratic in t. I wonder what formula can be used to solve that ????
getBezierCoef();
// this is written out in individual steps for clarity
var c:Number = _c0Y - _y;
var b:Number = _c1Y;
var a:Number = _c2Y;
var d:Number = b*b - 4*a*c;
if( d < 0 )
{
return [];
}
d = Math.sqrt(d);
a = 1/(a + a);
var t0:Number = (d-b)*a;
var t1:Number = (-b-d)*a;
var result:Array = new Array();
if( t0 <= 1 )
result.push( {t:t0, x:pointAt(t0).x} );
if( t1 >= 0 && t1 <=1 )
result.push( {t:t1, x:pointAt(t1).x} );
return result;
}
/**
* join
*
* <p>Given the current <code>AdvancedQuadraticBezier</code> and an arbitrary point, return a new <code>AdvancedQuadraticBezier</code> instance so that the new quadratic
* Bezier interpolates the input point and matches tangent with the current quadratic Bezier at its origin. In other words, given the current (x0,y0), (cx,cy), and (x1,y1),
* return a new <code>AdvancedQuadraticBezier</code> with parameters (w0,u0), (zx,zy), and (w1,u1) so that w0 = x1, u0 = y1, and the segment from (cx,cy) to (x1,y1) and
* (w0,u0) to (zx,zy) have the same slope. This is one prelude to a more general quadratic spline.</p>
*
* @param _x:Number x-coordinate of final interpolation point of output quadratic Bezier.
* @param _y:Number y-coordinate of final interpolation point of output quadratic Bezier.
* @param _tension:Number - tension parameter between 0 and 1. 0 produces a near linear curve while 1 produces a curve whose control point is the projection of (_x,_y),
* onto the vector from (cx,cy) to (x1,y1), unless that point is less than one third the distance from (cx,cy) to (x1,y1). This may be broken into two parameters in
* the future for more control. Values outside the interval [0,1] are clipped to either 0 or 1.
*
* @return <code>AdvancedQuadraticBezier</code> reference to quadratic Bezier that can be considered an 'add on' curve to the current quadratic bezier with matching
* tangents at the join (x1,y1).
*
*/
public function join(_x:Number, _y:Number, _tension:Number=1):AdvancedQuadraticBezier
{
// tension parameter not yet implemented
var deltaX:Number = x1 - cx;
var deltaY:Number = y1 - cy;
var m1:Number = 0;
var m2:Number = 0;
var pX:Number = 0;
var pY:Number = 0;
var tension:Number = Math.max(_tension,0);
tension = Math.min(tension,1);
// get the t-parameter corresponding to projecting the vector from (_x,_y) to (px,py) onto the vector from (cx,cy) to (x1,y1). This determines the 'direction'
// of the projection point, which we want to test vs. the tension parameter to avoid kinking.
var t:Number = ((_x-cx)*(x1-cx) + (_y-cy)*(y1-cy)) / (deltaX*deltaX + deltaY*deltaY);
var target:Number = 1 + tension/3;
t = t < target ? target : 1 + tension*(t-1);
pX = cx + t*deltaX;
pY = cy + t*deltaY;
return new AdvancedQuadraticBezier(x1,y1,pX,pY,_x,_y);
}
// recompute polynomial coefficients
private function getBezierCoef():void
{
_c0X = x0;
_c0Y = y0;
_c1X = 2.0*(cx-x0);
_c1Y = 2.0*(cy-y0);
_c2X = x0-2.0*cx+x1;
_c2Y = y0-2.0*cy+y1;
}
}
}

View File

@ -0,0 +1,342 @@
////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2008 The Degrafa Team : http://www.Degrafa.com/team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
////////////////////////////////////////////////////////////////////////////////
package com.degrafa.geometry{
import com.degrafa.IGeometry;
import com.degrafa.geometry.layout.LayoutConstraint;
import flash.display.Graphics;
import flash.geom.Rectangle;
import mx.graphics.IFill;
import mx.graphics.IStroke;
import mx.graphics.SolidColor;
import mx.graphics.Stroke;
//--------------------------------------
// Other metadata
//--------------------------------------
[IconFile("AdvancedRectangle.png")]
/**
* Used by the CSSSkin for graphics rendering.
*/
public class AdvancedRectangle extends Geometry implements IGeometry{
public var backgroundFill:IFill;
public var leftWidth:Number;
public var topWidth:Number;
public var rightWidth:Number;
public var bottomWidth:Number;
public var leftFill:IFill;
public var topFill:IFill;
public var rightFill:IFill;
public var bottomFill:IFill;
public var topLeftRadiusX:Number;
public var topLeftRadiusY:Number;
public var topRightRadiusX:Number;
public var topRightRadiusY:Number;
public var bottomLeftRadiusX:Number;
public var bottomLeftRadiusY:Number;
public var bottomRightRadiusX:Number;
public var bottomRightRadiusY:Number;
public var topLeftFill:IFill;
public var topRightFill:IFill;
public var bottomLeftFill:IFill;
public var bottomRightFill:IFill;
public function AdvancedRectangle(){
super();
}
//Layout is Not yet implemented here so override to avoid mass havoc
override public function get layoutConstraint():LayoutConstraint{return null}
override public function set layoutConstraint(value:LayoutConstraint):void{}
override public function get layoutRectangle():Rectangle{return null}
override public function set width(value:Number):void{}
override public function set percentWidth(value:Number):void{}
override public function set maxWidth(value:Number):void{}
override public function set minWidth(value:Number):void{}
override public function set height(value:Number):void{}
override public function set percentHeight(value:Number):void{}
override public function set maxHeight(value:Number):void{}
override public function set minHeight(value:Number):void{}
override public function set x(value:Number):void{}
override public function set maxX(value:Number):void{}
override public function set minX(value:Number):void{}
override public function set y(value:Number):void{}
override public function set maxY(value:Number):void{}
override public function set minY(value:Number):void{}
override public function set horizontalCenter(value:Number):void{}
override public function set verticalCenter(value:Number):void{}
override public function set top(value:Number):void{}
override public function set bottom(value:Number):void{}
override public function set left(value:Number):void{}
override public function set right(value:Number):void{}
override public function set maintainAspectRatio(value:Boolean):void{}
override public function draw(graphics:Graphics, rc:Rectangle):void {
// test for simpler drawing methods
var isRoundRectComplex:Boolean = topWidth == rightWidth == bottomWidth == leftWidth && topLeftRadiusX == topLeftRadiusY && topRightRadiusX == topRightRadiusY && bottomLeftRadiusX == bottomLeftRadiusY && bottomRightRadiusX == bottomRightRadiusY && isEquivalentSolidFill([topFill,rightFill,bottomFill,leftFill]);
var isRoundRect:Boolean = isRoundRectComplex && topLeftRadiusX == topRightRadiusX == bottomLeftRadiusX == bottomRightRadiusX;
var isRect:Boolean = isRoundRect && topLeftRadiusX == 0;
if(isRect || isRoundRect || isRoundRectComplex) {
var stroke:IStroke = convertSolidColorToStroke(topFill as SolidColor, topWidth);
stroke.apply(graphics);
backgroundFill.begin(graphics, rc);
if(isRect) {
graphics.drawRect(rc.x, rc.y, rc.width, rc.height);
} else if(isRoundRect) {
graphics.drawRoundRect(rc.x, rc.y, rc.width, rc.height, topLeftRadiusX, topLeftRadiusY);
} else if(isRoundRectComplex) {
graphics.drawRoundRectComplex(rc.x, rc.y, rc.width, rc.height, topLeftRadiusX, topRightRadiusX, bottomLeftRadiusX, bottomRightRadiusX);
}
backgroundFill.end(graphics);
} else {
drawLeftBorder(graphics, rc);
drawTopLeftRadius(graphics, rc);
drawTopBorder(graphics, rc);
drawTopRightRadius(graphics, rc);
drawRightBorder(graphics, rc);
drawBottomLeftRadius(graphics, rc);
drawBottomBorder(graphics, rc);
drawBottomRightRadius(graphics, rc);
drawBackground(graphics, rc);
}
}
//**************************************************************************
// Drawing Functions
//**************************************************************************
private function drawLeftBorder(graphics:Graphics, rectangle:Rectangle):void {
if(leftFill != null) {
var rc:Rectangle = new Rectangle(0, topLeftRadiusY, leftWidth, rectangle.height - topLeftRadiusY - bottomLeftRadiusY);
graphics.lineStyle(0, 0, 0);
leftFill.begin(graphics, rc);
graphics.moveTo(0, topLeftRadiusY); // top outside
graphics.lineTo(leftWidth, Math.max(topLeftRadiusY, topWidth)); // top inside
graphics.lineTo(leftWidth, rectangle.height - Math.max(bottomLeftRadiusY, bottomWidth)); // bottom inside
graphics.lineTo(0, rectangle.height - bottomLeftRadiusY); // bottom outside
graphics.lineTo(0, topLeftRadiusY); // top outside
leftFill.end(graphics);
}
}
private function drawTopBorder(graphics:Graphics, rectangle:Rectangle):void {
if(topFill != null) {
var rc:Rectangle = new Rectangle(topLeftRadiusX, 0, rectangle.width - topLeftRadiusX - topRightRadiusX, topWidth);
graphics.lineStyle(0, 0, 0);
topFill.begin(graphics, rc);
graphics.moveTo(topLeftRadiusX, 0);
graphics.lineTo(rectangle.width - topRightRadiusX, 0);
graphics.lineTo(rectangle.width - Math.max(topRightRadiusX, rightWidth), topWidth);
graphics.lineTo(Math.max(topLeftRadiusX, leftWidth), topWidth);
graphics.lineTo(topLeftRadiusX, 0);
topFill.end(graphics);
}
}
private function drawRightBorder(graphics:Graphics, rectangle:Rectangle):void {
if(rightFill != null) {
var rc:Rectangle = new Rectangle(0, topRightRadiusY, rightWidth, rectangle.height - topRightRadiusY - bottomRightRadiusY);
graphics.lineStyle(0, 0, 0);
rightFill.begin(graphics, rc);
graphics.moveTo(rectangle.width, Math.max(topRightRadiusY, topWidth)); // top outside
graphics.lineTo(rectangle.width, rectangle.height - bottomRightRadiusY); // bottom outside
graphics.lineTo(rectangle.width - rightWidth, rectangle.height - Math.max(bottomRightRadiusY, bottomWidth));
graphics.lineTo(rectangle.width - rightWidth, Math.max(topRightRadiusY, topWidth));
graphics.lineTo(rectangle.width, topRightRadiusY); // top outside
rightFill.end(graphics);
}
}
private function drawBottomBorder(graphics:Graphics, rectangle:Rectangle):void {
if(bottomFill != null) {
var rc:Rectangle = new Rectangle(bottomLeftRadiusX, 0, rectangle.width - bottomLeftRadiusX - bottomRightRadiusX, bottomWidth);
graphics.lineStyle(0, 0, 0);
bottomFill.begin(graphics, rc);
graphics.moveTo(Math.max(bottomLeftRadiusX, leftWidth), rectangle.height - bottomWidth); // left inside
graphics.lineTo(rectangle.width - Math.max(bottomRightRadiusX, rightWidth), rectangle.height - bottomWidth); // right inside
graphics.lineTo(rectangle.width - bottomRightRadiusX, rectangle.height); // right outside
graphics.lineTo(bottomLeftRadiusX, rectangle.height); // left outside
graphics.lineTo(Math.max(bottomLeftRadiusX, leftWidth), rectangle.height - bottomWidth); // left inside
graphics.endFill();
bottomFill.end(graphics);
}
}
private function drawTopLeftRadius(graphics:Graphics, rc:Rectangle):void {
// draw top left curve
if(topLeftRadiusX > 0){
topLeftFill.begin(graphics, rc);
graphics.moveTo(0, topLeftRadiusY);
graphics.curveTo(0, 0, topLeftRadiusX, 0);
graphics.lineTo(Math.max(topLeftRadiusX, leftWidth), topWidth);
graphics.curveTo(leftWidth, topWidth, leftWidth, Math.max(topLeftRadiusY, topWidth));
graphics.lineTo(0, topLeftRadiusY);
topLeftFill.end(graphics);
}
}
private function drawTopRightRadius(graphics:Graphics, rc:Rectangle):void {
// draw top right curve
if(topRightRadiusX > 0){
var trc:Rectangle = new Rectangle(rc.width - Math.max(rightWidth, topRightRadiusX), 0, Math.max(topRightRadiusX, rightWidth), Math.max(topRightRadiusY, topWidth));
topRightFill.begin(graphics, trc);
graphics.moveTo(rc.width - topRightRadiusX, 0);
graphics.curveTo(rc.width, 0, rc.width, topRightRadiusY);
graphics.lineTo(rc.width - rightWidth, Math.max(topRightRadiusY, topWidth));
graphics.curveTo(rc.width - rightWidth, topWidth, rc.width - Math.max(topRightRadiusX, rightWidth), topWidth);
graphics.lineTo(rc.width - topRightRadiusX, 0);
topRightFill.end(graphics);
}
}
private function drawBottomLeftRadius(graphics:Graphics, rc:Rectangle):void {
// draw bottom left curve
if(bottomLeftRadiusX > 0){
var brc:Rectangle = new Rectangle(0, rc.height - Math.max(bottomWidth, bottomLeftRadiusY), Math.max(leftWidth, bottomLeftRadiusX), Math.max(bottomWidth, bottomLeftRadiusY));
bottomLeftFill.begin(graphics, brc);
graphics.moveTo(bottomLeftRadiusX, rc.height);
graphics.curveTo(0, rc.height, 0, rc.height - bottomLeftRadiusY);
graphics.lineTo(leftWidth, Math.min(rc.height - bottomLeftRadiusY, rc.height - bottomWidth));
graphics.curveTo(leftWidth, rc.height - bottomWidth, Math.max(bottomLeftRadiusX, leftWidth), rc.height - bottomWidth);
graphics.lineTo(bottomLeftRadiusX, rc.height);
bottomLeftFill.end(graphics);
}
}
private function drawBottomRightRadius(graphics:Graphics, rc:Rectangle):void {
// draw bottom right curve
if(bottomRightRadiusX > 0){
bottomRightFill.begin(graphics, rc);
graphics.moveTo(rc.width - bottomRightRadiusX , rc.height);
graphics.curveTo(rc.width, rc.height, rc.width, rc.height - bottomRightRadiusY);
graphics.lineTo(rc.width - rightWidth, Math.min(rc.height - bottomRightRadiusY, rc.height - bottomWidth));
graphics.curveTo(rc.width - rightWidth, rc.height - bottomWidth, Math.min(rc.width - bottomRightRadiusX, rc.width - rightWidth), rc.height - bottomWidth);
graphics.moveTo(rc.width - bottomRightRadiusX , rc.height);
bottomRightFill.end(graphics);
}
}
private function drawBackground(graphics : Graphics, rc : Rectangle) : void
{
var brc : Rectangle = new Rectangle(rc.x + leftWidth,
rc.y + topWidth,
rc.width - (leftWidth + rightWidth),
rc.height - (topWidth + bottomWidth));
// draw background
backgroundFill.begin(graphics, brc);
// todo: lots more optimizing =D
//Calculate inner radii
var tl_x : Number = Math.max(topLeftRadiusX - leftWidth, 0);
var tl_y : Number = Math.max(topLeftRadiusY - topWidth, 0);
var tr_x : Number = Math.max(topRightRadiusX - rightWidth, 0);
var tr_y : Number = Math.max(topRightRadiusY - topWidth, 0);
var br_x : Number = Math.max(bottomRightRadiusX - rightWidth, 0);
var br_y : Number = Math.max(bottomRightRadiusY - bottomWidth, 0);
var bl_x : Number = Math.max(bottomLeftRadiusX - leftWidth, 0);
var bl_y : Number = Math.max(bottomLeftRadiusY - bottomWidth, 0);
//Calculate inner pixel positions
var innerTop : Number = topWidth;
var innerRight : Number = rc.width - rightWidth;
var innerBottom : Number = rc.height - bottomWidth;
var innerLeft : Number = leftWidth;
graphics.moveTo(innerLeft + tl_x, innerTop);
//Top
graphics.lineTo(innerRight - tr_x, innerTop);
//Top Right
graphics.curveTo(innerRight, innerTop, innerRight, innerTop + tr_y);
//Right
graphics.lineTo(innerRight, innerBottom - br_y);
//Bottom right
graphics.curveTo(innerRight, innerBottom, innerRight - br_x, innerBottom);
//Bottom
graphics.lineTo(innerLeft + bl_x, innerBottom);
//Bottom left
graphics.curveTo(innerLeft, innerBottom, innerLeft, innerBottom - bl_y);
//Left
graphics.lineTo(innerLeft, innerTop + tl_y);
//Top Left
graphics.curveTo(innerLeft, innerTop, innerLeft + tl_x, innerTop);
backgroundFill.end(graphics);
}
//************************************************************
// Utility Functions
//************************************************************
private function convertSolidColorToStroke(fill:SolidColor, weight:Number):IStroke {
if(fill != null) {
return new Stroke(fill.color, weight, fill.alpha);
} else {
return new Stroke(0, 0, 0);
}
}
private function isEquivalentSolidFill(fills:Array):Boolean {
var temp:SolidColor;
for each(var fill:IFill in fills) {
if(fill is SolidColor || fill == null) {
if(temp != null) {
var solid:SolidColor = fill as SolidColor;
if(solid.color != temp.color || solid.alpha == temp.alpha) {
return false;
}
}
temp = fill as SolidColor;
} else {
return false;
}
}
return true;
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 375 B

View File

@ -0,0 +1,284 @@
////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2008 The Degrafa Team : http://www.Degrafa.com/team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
////////////////////////////////////////////////////////////////////////////////
package com.degrafa.geometry{
import com.degrafa.IGeometry;
import flash.display.Graphics;
import flash.geom.Rectangle;
//--------------------------------------
// Other metadata
//--------------------------------------
[IconFile("Circle.png")]
[Bindable]
/**
* The Circle element draws a circle using the specified center point
* and radius.
*
* @see http://samples.degrafa.com/Circle/Circle.html
*
**/
public class Circle extends Geometry implements IGeometry{
/**
* Constructor.
*
* <p>The circle constructor accepts 3 optional arguments that define it's
* center point and radius.</p>
*
* @param centerX A number indicating the center x-axis coordinate.
* @param centerY A number indicating the center y-axis coordinate.
* @param radius A number indicating the radius of the circle.
*/
public function Circle(centerX:Number=NaN,centerY:Number=NaN,radius:Number=NaN){
super();
if (centerX) this.centerX=centerX;
if (centerY) this.centerY=centerY;
if (radius) this.radius=radius;
}
/**
* Circle short hand data value.
*
* <p>The circle data property expects exactly 3 values centerX,
* centerY and radius separated by spaces.</p>
*
* @see Geometry#data
*
**/
override public function set data(value:Object):void{
if(super.data != value){
//parse the string
var tempArray:Array = value.split(" ");
if (tempArray.length == 3)
{
super.data = value;
_centerX= tempArray[0];
_centerY= tempArray[1];
_radius = tempArray[2];
invalidated = true;
}
}
}
private var _centerX:Number;
/**
* The x-axis coordinate of the center of the circle. If not specified
* a default value of 0 is used.
**/
public function get centerX():Number{
if(!_centerX){return (hasLayout)? 0.5:0;}
return _centerX;
}
public function set centerX(value:Number):void{
if (_centerX != value) {
_centerX = value;
invalidated = true;
}
}
private var _centerY:Number;
/**
* The y-axis coordinate of the center of the circle. If not specified
* a default value of 0 is used.
**/
public function get centerY():Number{
if(!_centerY){return (hasLayout)? 0.5:0;}
return _centerY;
}
public function set centerY(value:Number):void{
if(_centerY != value){
_centerY = value;
invalidated = true;
}
}
private var _radius:Number;
/**
* The radius of the circle. If not specified a default value of 0
* is used.
**/
public function get radius():Number{
if(!_radius){return (hasLayout)? .5:0;}
return _radius;
}
public function set radius(value:Number):void{
if(_radius != value){
_radius = value;
if (hasLayout)super.width= super.height = value*2;
invalidated = true;
}
}
private var _accuracy:Number;
/**
* The accuracy of the circle. If not specified a default value of 8
* is used.
**/
public function get accuracy():Number{
if(!_accuracy){return 8;}
return _accuracy;
}
public function set accuracy(value:Number):void{
if(_accuracy != value){
_accuracy = value;
invalidated = true;
}
}
/**
* @inheritDoc
**/
override public function preDraw():void{
if(invalidated){
commandStack.source.length = 0;
var span:Number = Math.PI/accuracy;
var controlRadius:Number = radius/Math.cos(span);
var anchorAngle:Number=0
var controlAngle:Number=0;
//add the move to the command stack
commandStack.addMoveTo(
centerX+Math.cos(anchorAngle)*radius,
centerY+Math.sin(anchorAngle)*radius);
var i:int=0;
//loop through and add the curve commands
for (i; i<accuracy; ++i) {
controlAngle = anchorAngle+span;
anchorAngle = controlAngle+span;
commandStack.addCurveTo(
centerX + Math.cos(controlAngle)*controlRadius,
centerY + Math.sin(controlAngle)*controlRadius,
centerX + Math.cos(anchorAngle)*radius,
centerY + Math.sin(anchorAngle)*radius)
};
invalidated = false;
}
}
/**
* Performs the specific layout work required by this Geometry.
* @param childBounds the bounds to be layed out. If not specified a rectangle
* of (0,0,1,1) is used or the most appropriate size is calculated.
**/
override public function calculateLayout(childBounds:Rectangle=null):void{
if(_layoutConstraint){
if (_layoutConstraint.invalidated){
var tempLayoutRect:Rectangle = new Rectangle(0,0,1,1);
if(_radius){
tempLayoutRect.width = tempLayoutRect.height = radius*2;
}
if(_centerX){
tempLayoutRect.x = _centerX-(_radius? _radius:0);
}
if(_centerY){
tempLayoutRect.y = _centerY - (_radius? _radius:0);
}
super.calculateLayout(tempLayoutRect);
_layoutRectangle = _layoutConstraint.layoutRectangle;
//dev note: possible startup ISSUE here with one test
//layout for Circle.... when centerX and centerY are
//defined, but layout sets radius. Initial layoutRectangle
//has bad x and y settings
if (isNaN(_radius)) {
//handle layout defined startup values:
_radius = _layoutRectangle.width / 2;
if (isNaN(_centerX)){
_centerX = layoutRectangle.width / 2 + layoutRectangle.x;
}
else{
_layoutRectangle.x -= _radius;
}
if (isNaN(_centerY)){
_centerY = layoutRectangle.height / 2 + layoutRectangle.y;
}
else{
_layoutRectangle.y -= _radius;
}
invalidated = true;
}
}
}
}
/**
* Begins the draw phase for geometry objects. All geometry objects
* override this to do their specific rendering.
*
* @param graphics The current context to draw to.
* @param rc A Rectangle object used for fill bounds.
**/
override public function draw(graphics:Graphics,rc:Rectangle):void{
//init the layout in this case done before predraw.
if (hasLayout) calculateLayout();
//re init if required
if (invalidated) preDraw();
//apply the fill retangle for the draw
super.draw(graphics,(rc)? rc:bounds);
}
/**
* An object to derive this objects properties from. When specified this
* object will derive it's unspecified properties from the passed object.
**/
public function set derive(value:Circle):void{
if (!fill){fill=value.fill;}
if (!stroke){stroke = value.stroke;}
if (!_centerX){_centerX = value.centerX;}
if (!_centerY){_centerY = value.centerY;}
if (!_radius){_radius = value.radius;}
if (!_accuracy){_accuracy = value.accuracy;}
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 656 B

View File

@ -0,0 +1,359 @@
////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2008 The Degrafa Team : http://www.Degrafa.com/team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
////////////////////////////////////////////////////////////////////////////////
package com.degrafa.geometry{
import com.degrafa.IGeometry;
import com.degrafa.geometry.command.CommandStackItem;
import com.degrafa.geometry.utilities.GeometryUtils;
import flash.display.Graphics;
import flash.geom.Rectangle;
//--------------------------------------
// Other metadata
//--------------------------------------
[IconFile("CubicBezier.png")]
[Bindable]
/**
* The CubicBezier element draws a cubic Bézier using the specified start point,
* end point and 2 control points.
*
* @see http://degrafa.com/samples/CubicBezier_Element.html
*
**/
public class CubicBezier extends Geometry implements IGeometry{
/**
* Constructor.
*
* <p>The cubic Bézier constructor accepts 8 optional arguments that define it's
* start, end and controls points.</p>
*
* @param x0 A number indicating the starting x-axis coordinate.
* @param y0 A number indicating the starting y-axis coordinate.
* @param cx A number indicating the first control x-axis coordinate.
* @param cy A number indicating the first control y-axis coordinate.
* @param cx1 A number indicating the second control x-axis coordinate.
* @param cy1 A number indicating the second control y-axis coordinate.
* @param x1 A number indicating the ending x-axis coordinate.
* @param y1 A number indicating the ending y-axis coordinate.
*/
public function CubicBezier(x0:Number=NaN,y0:Number=NaN,cx:Number=NaN,cy:Number=NaN,cx1:Number=NaN,cy1:Number=NaN,x1:Number=NaN,y1:Number=NaN){
super();
this.x0=x0;
this.y0=y0;
this.cx=cx;
this.cy=cy;
this.cx1=cx1;
this.cy1=cy1;
this.x1=x1;
this.y1=y1;
}
/**
* CubicBezier short hand data value.
*
* <p>The cubic Bézier data property expects exactly 8 values x0,
* y0, cx, cy, cx1, cy1, x1 and y1 separated by spaces.</p>
*
* @see Geometry#data
*
**/
override public function set data(value:Object):void{
if(super.data != value){
super.data = value;
//parse the string on the space
var tempArray:Array = value.split(" ");
if (tempArray.length == 8){
_x0=tempArray[0];
_y0=tempArray[1];
_cx=tempArray[2];
_cy=tempArray[3];
_cx1=tempArray[4];
_cy1=tempArray[5];
_x1=tempArray[6];
_y1=tempArray[7];
}
invalidated = true;
}
}
private var _x0:Number;
/**
* The x0-coordinate of the start point of the curve. If not specified
* a default value of 0 is used.
**/
public function get x0():Number{
if(isNaN(_x0)){return 0;}
return _x0;
}
public function set x0(value:Number):void{
if(_x0 != value){
_x0 = value;
invalidated = true;
}
}
private var _y0:Number;
/**
* The y0-coordinate of the start point of the curve. If not specified
* a default value of 0 is used.
**/
public function get y0():Number{
if(isNaN(_y0)){return (hasLayout)? 2:0;}
return _y0;
}
public function set y0(value:Number):void{
if(_y0 != value){
_y0 = value;
invalidated = true;
}
}
private var _x1:Number;
/**
* The x-coordinate of the end point of the curve. If not specified
* a default value of 0 is used.
**/
public function get x1():Number{
if(isNaN(_x1)){return (hasLayout)? 2:0;}
return _x1;
}
public function set x1(value:Number):void{
if(_x1 != value){
_x1 = value;
invalidated = true;
}
}
private var _y1:Number;
/**
* The y-coordinate of the end point of the curve. If not specified
* a default value of 0 is used.
**/
public function get y1():Number{
if(isNaN(_y1)){return (hasLayout)? 2:0;}
return _y1;
}
public function set y1(value:Number):void{
if(_y1 != value){
_y1 = value;
invalidated = true;
}
}
private var _cx:Number;
/**
* The x-coordinate of the first control point of the curve. If not specified
* a default value of 0 or cx1 if specified is used.
**/
public function get cx():Number{
if(isNaN(_cx)){return (hasLayout)? 1:0;}
return _cx;
}
public function set cx(value:Number):void{
if(_cx != value){
_cx = value;
invalidated = true;
}
}
private var _cy:Number;
/**
* The y-coordinate of the first control point of the curve. If not specified
* a default value of 0 or cy1 if specified is used.
**/
public function get cy():Number{
if(isNaN(_cy)){return (hasLayout)? .66:0;}
return _cy;
}
public function set cy(value:Number):void{
if(_cy != value){
_cy = value;
invalidated = true;
}
}
private var _cx1:Number;
/**
* The x-coordinate of the second control point of the curve. If not specified
* a default value of 0 or cx if specified is used.
**/
public function get cx1():Number{
if(isNaN(_cx1)){return (hasLayout)? 1:0;}
return _cx1;
}
public function set cx1(value:Number):void{
if(_cx1 != value){
_cx1 = value;
invalidated = true;
}
}
private var _cy1:Number;
/**
* The y-coordinate of the second control point of the curve. If not specified
* a default value of 0 or cy if specified is used.
**/
public function get cy1():Number{
if(isNaN(_cy1)){return (hasLayout)? .66:0;}
return _cy1;
}
public function set cy1(value:Number):void{
if(_cy1 != value){
_cy1 = value;
invalidated = true;
}
}
private var _close:Boolean=false;
/**
* If true draws a line from the end point to the start point to
* close this curve.
**/
[Inspectable(category="General", enumeration="true,false")]
public function get close():Boolean{
return _close;
}
public function set close(value:Boolean):void{
if(_close != value){
_close = value;
invalidated = true;
}
}
/**
* @inheritDoc
**/
override public function preDraw():void{
if(invalidated){
commandStack.length=0;
//add a MoveTo at the start of the commandStack
//rendering chain
commandStack.addMoveTo(x0,y0);
commandStack.addCubicBezierTo(x0,y0,cx,cy,cx1,cy1,x1,y1,1);
if(close){
commandStack.addLineTo(x0,y0);
}
invalidated = false;
}
}
/**
* Performs the specific layout work required by this Geometry.
* @param childBounds the bounds to be layed out. If not specified a rectangle
* of (0,0,1,1) is used.
**/
override public function calculateLayout(childBounds:Rectangle=null):void{
if(_layoutConstraint){
if (_layoutConstraint.invalidated){
var tempLayoutRect:Rectangle = new Rectangle(0,0,1,1);
if(isNaN(_layoutConstraint.width)){
tempLayoutRect.width = bounds.width;
}
if(isNaN(_layoutConstraint.height)){
tempLayoutRect.height = bounds.height;
}
if(isNaN(_layoutConstraint.x)){
tempLayoutRect.x = bounds.x;
}
if(isNaN(_layoutConstraint.y)){
tempLayoutRect.y = bounds.y;
}
trace(tempLayoutRect)
super.calculateLayout(tempLayoutRect);
_layoutRectangle = _layoutConstraint.layoutRectangle;
}
}
}
/**
* Begins the draw phase for geometry objects. All geometry objects
* override this to do their specific rendering.
*
* @param graphics The current context to draw to.
* @param rc A Rectangle object used for fill bounds.
**/
override public function draw(graphics:Graphics,rc:Rectangle):void{
//re init if required
if (invalidated) preDraw();
//init the layout in this case done after predraw.
if (_layoutConstraint) calculateLayout();
super.draw(graphics, (rc)? rc:bounds);
}
/**
* An object to derive this objects properties from. When specified this
* object will derive it's unspecified properties from the passed object.
**/
public function set derive(value:CubicBezier):void{
if (!fill){fill=value.fill;}
if (!stroke){stroke = value.stroke}
if (!_x0){_x0 = value.x0;}
if (!_y0){_y0 = value.y0;}
if (!_x1){_x1 = value.x1;}
if (!_y1){_y1 = value.y1;}
if (!_cx){_cx = value.cx;}
if (!_cy){_cy = value.cy;}
if (!_cx1){_cx1 = value.cx1;}
if (!_cy1){_cy1 = value.cy1;}
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 344 B

View File

@ -0,0 +1,291 @@
////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2008 The Degrafa Team : http://www.Degrafa.com/team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
////////////////////////////////////////////////////////////////////////////////
package com.degrafa.geometry{
import com.degrafa.IGeometry;
import flash.display.Graphics;
import flash.geom.Rectangle;
//--------------------------------------
// Other metadata
//--------------------------------------
[IconFile("Ellipse.png")]
[Bindable]
/**
* The Ellipse element draws a ellipse using the specified x,y,
* width and height.
*
* @see http://samples.degrafa.com/Ellipse/Ellipse.html
*
**/
public class Ellipse extends Geometry implements IGeometry{
/**
* Constructor.
*
* <p>The ellipse constructor accepts 4 optional arguments that define it's
* x, y, width and height.</p>
*
* @param x A number indicating the upper left x-axis coordinate.
* @param y A number indicating the upper left y-axis coordinate.
* @param width A number indicating the width.
* @param height A number indicating the height.
*/
public function Ellipse(x:Number=NaN,y:Number=NaN,width:Number=NaN,height:Number=NaN){
super();
if (x) this.x=x;
if (y) this.y=y;
if (width) this.width=width;
if (height) this.height=height;
}
/**
* Ellipse short hand data value.
*
* <p>The ellipse data property expects exactly 4 values x,
* y, width and height separated by spaces.</p>
*
* @see Geometry#data
*
**/
override public function set data(value:Object):void{
if(super.data != value){
super.data = value;
//parse the string on the space
var tempArray:Array = value.split(" ");
if (tempArray.length == 4){
_x=tempArray[0];
_y=tempArray[1];
_width=tempArray[2];
_height=tempArray[3];
}
invalidated = true;
}
}
private var _x:Number;
/**
* The x-axis coordinate of the upper left point of the ellipse. If not specified
* a default value of 0 is used.
**/
override public function get x():Number{
if(isNaN(_x)){return 0;}
return _x;
}
override public function set x(value:Number):void{
if(_x != value){
_x = value;
if (hasLayout) super.x=value
invalidated = true;
}
}
private var _y:Number;
/**
* The y-axis coordinate of the upper left point of the ellipse. If not specified
* a default value of 0 is used.
**/
override public function get y():Number{
if(isNaN(_y)){return 0;}
return _y;
}
override public function set y(value:Number):void{
if(_y != value){
_y = value;
if (hasLayout) super.y=value
invalidated = true;
}
}
private var _width:Number;
/**
* The width of the ellipse.
**/
[PercentProxy("percentWidth")]
override public function get width():Number{
if(isNaN(_width)){return (hasLayout)? 1:0;}
return _width;
}
override public function set width(value:Number):void{
if(_width != value){
_width = value;
if (hasLayout) super.width=value
invalidated = true;
}
}
private var _height:Number;
/**
* The height of the ellipse.
**/
[PercentProxy("percentHeight")]
override public function get height():Number{
if(isNaN(_height)){return (hasLayout)? 1:0;}
return _height;
}
override public function set height(value:Number):void{
if(_height != value){
_height = value;
if (hasLayout) super.height=value
invalidated = true;
}
}
private var _accuracy:Number;
/**
* The accuracy of the ellipse. If not specified a default value of 8
* is used.
**/
public function get accuracy():Number{
if(!_accuracy){return 8;}
return _accuracy;
}
public function set accuracy(value:Number):void{
if(_accuracy != value){
_accuracy = value;
invalidated = true;
}
}
/**
* @inheritDoc
**/
override public function preDraw():void{
if(invalidated){
commandStack.length=0;
var angleDelta:Number = Math.PI / (accuracy/2);
var rx: Number = width/2;
var ry: Number = height/2;
var dx:Number = rx/Math.cos(angleDelta/2);
var dy:Number = ry/Math.cos(angleDelta/2);
commandStack.addMoveTo((x+rx) + rx,(y+ry));
var i:Number = 0
var angle:Number=0;
for (i= 0; i < accuracy; i++) {
angle += angleDelta;
commandStack.addCurveTo(
(x+rx) + Math.cos(angle-(angleDelta/2))*(dx),
(y+ry) + Math.sin(angle-(angleDelta/2))*(dy),
(x+rx) + Math.cos(angle)*rx,
(y+ry) + Math.sin(angle)*ry);
}
invalidated = false;
}
}
/**
* Performs the specific layout work required by this Geometry.
* @param childBounds the bounds to be layed out. If not specified a rectangle
* of (0,0,1,1) is used.
**/
override public function calculateLayout(childBounds:Rectangle=null):void{
if(_layoutConstraint){
if (_layoutConstraint.invalidated){
var tempLayoutRect:Rectangle = new Rectangle(0,0,1,1);
if(_width){
tempLayoutRect.width = _width;
}
if(_height){
tempLayoutRect.height = _height;
}
if(_x){
tempLayoutRect.x = _x;
}
if(_y){
tempLayoutRect.y = _y;
}
super.calculateLayout(tempLayoutRect);
_layoutRectangle = _layoutConstraint.layoutRectangle;
if (isNaN(_width) || isNaN(_height)) {
//layout defined initial state:
_width = isNaN(_width)? layoutRectangle.width:_width;
_height = isNaN(_height) ? layoutRectangle.height: _height;
invalidated = true;
}
}
}
}
/**
* Begins the draw phase for geometry objects. All geometry objects
* override this to do their specific rendering.
*
* @param graphics The current context to draw to.
* @param rc A Rectangle object used for fill bounds.
**/
override public function draw(graphics:Graphics,rc:Rectangle):void{
//init the layout in this case done before predraw.
if (_layoutConstraint) calculateLayout();
//re init if required
if (invalidated) preDraw();
super.draw(graphics,(rc)? rc:bounds);
}
/**
* An object to derive this objects properties from. When specified this
* object will derive it's unspecified properties from the passed object.
**/
public function set derive(value:Ellipse):void{
if (!fill){fill=value.fill;}
if (!stroke){stroke = value.stroke;}
if (!_x){_x = value.x;}
if (!_y){_y = value.y;}
if (!_width){_width = value.width;}
if (!_height){_height = value.height;}
if (!_accuracy){_accuracy = value.accuracy;}
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 452 B

View File

@ -0,0 +1,364 @@
////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2008 The Degrafa Team : http://www.Degrafa.com/team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
////////////////////////////////////////////////////////////////////////////////
package com.degrafa.geometry{
import com.degrafa.geometry.utilities.GeometryUtils;
import com.degrafa.IGeometry;
import com.degrafa.geometry.command.CommandStackItem;
import com.degrafa.geometry.utilities.ArcUtils;
import flash.display.Graphics;
import flash.geom.Rectangle;
//--------------------------------------
// Other metadata
//--------------------------------------
[IconFile("EllipticalArc.png")]
[Bindable]
/**
* The EllipticalArc element draws an elliptical arc using the specified
* x, y, width, height, start angle, arc and closure type.
*
* @see http://degrafa.com/samples/EllipticalArc_Element.html
*
**/
public class EllipticalArc extends Geometry implements IGeometry{
/**
* Constructor.
*
* <p>The elliptical arc constructor accepts 7 optional arguments that define it's
* x, y, width, height, start angle, arc and closure type.</p>
*
* @param x A number indicating the upper left x-axis coordinate.
* @param y A number indicating the upper left y-axis coordinate.
* @param width A number indicating the width.
* @param height A number indicating the height.
* @param startAngle A number indicating the beginning angle of the arc.
* @param arc A number indicating the the angular extent of the arc, relative to the start angle.
* @param closureType A string indicating the method used to close the arc.
*/
public function EllipticalArc(x:Number=NaN,y:Number=NaN,width:Number=NaN,
height:Number=NaN,startAngle:Number=NaN,arc:Number=NaN,closureType:String=null){
super();
if (!isNaN(x)) this.x=x;
if (!isNaN(y)) this.y=y;
if (!isNaN(width)) this.width=width;
if (!isNaN(height)) this.height=height;
if (!isNaN(startAngle)) this.startAngle=startAngle;
if (!isNaN(arc)) this.arc=arc;
if (closureType) this.closureType=closureType;
}
/**
* EllipticalArc short hand data value.
*
* <p>The elliptical arc data property expects exactly 6 values x,
* y, width, height, startAngle and arc separated by spaces.</p>
*
* @see Geometry#data
*
**/
override public function set data(value:Object):void{
if(super.data != value){
super.data = value;
//parse the string on the space
var tempArray:Array = value.split(" ");
if (tempArray.length == 6){
_x=tempArray[0];
_y=tempArray[1];
_width=tempArray[2]; //radius
_height=tempArray[3]; //yRadius
_startAngle=tempArray[4]; //angle
_arc=tempArray[5]; //extent
invalidated = true;
}
}
}
private var _x:Number;
/**
* The x-axis coordinate of the upper left point of the arcs enclosure. If not specified
* a default value of 0 is used.
**/
override public function get x():Number{
if(!_x){return 0;}
return _x;
}
override public function set x(value:Number):void{
if(_x != value){
_x = value;
if (hasLayout) super.x=value
invalidated = true;
}
}
private var _y:Number;
/**
* The y-axis coordinate of the upper left point of the arcs enclosure. If not specified
* a default value of 0 is used.
**/
override public function get y():Number{
if(!_y){return 0;}
return _y;
}
override public function set y(value:Number):void{
if(_y != value){
_y = value;
if (hasLayout) super.y=value
invalidated = true;
}
}
private var _startAngle:Number;
/**
* The beginning angle of the arc. If not specified
* a default value of 0 is used.
**/
public function get startAngle():Number{
if(!_startAngle){return 0;}
return _startAngle;
}
public function set startAngle(value:Number):void{
if(_startAngle != value){
_startAngle = value;
invalidated = true;
}
}
private var _arc:Number;
/**
* The angular extent of the arc. If not specified
* a default value of 0 is used.
**/
public function get arc():Number{
if(!_arc){return 0;}
return _arc;
}
public function set arc(value:Number):void{
if(_arc != value){
_arc = value;
invalidated = true;
}
}
private var _width:Number;
/**
* The width of the arc.
**/
[PercentProxy("percentWidth")]
override public function get width():Number{
if(isNaN(_width)){return (hasLayout)? 1:0;}
return _width;
}
override public function set width(value:Number):void{
if(_width != value){
_width = value;
if (hasLayout) super.width=value
invalidated = true;
}
}
private var _height:Number;
/**
* The height of the arc.
**/
[PercentProxy("percentHeight")]
override public function get height():Number{
if(isNaN(_height)){return (hasLayout)? 1:0;}
return _height;
}
override public function set height(value:Number):void{
if(_height != value){
_height = value;
if (hasLayout) super.height=value
invalidated = true;
}
}
private var _closureType:String;
[Inspectable(category="General", enumeration="open,chord,pie", defaultValue="open")]
/**
* The method in which to close the arc.
* <p>
* <li><b>open</b> will apply no closure.</li>
* <li><b>chord</b> will close the arc with a strait line to the start.</li>
* <li><b>pie</b> will draw a line from center to start and end to center forming a pie shape.</li>
* </p>
**/
public function get closureType():String{
if(!_closureType){return "open";}
return _closureType;
}
public function set closureType(value:String):void{
if(_closureType != value){
_closureType = value;
invalidated = true;
}
}
/**
* @inheritDoc
**/
override public function preDraw():void{
if(invalidated){
//calculate based on startangle, radius, width, and height to get the drawing
//x and y so that our arc is always in the bounds of the rectangle. may want
//to store this local sometime
var newX:Number = (width/2) + (width/2) *
Math.cos(startAngle * (Math.PI / 180))+x;
var newY:Number = (height/2) - (height/2) *
Math.sin(startAngle * (Math.PI / 180))+y;
commandStack.length=0;
//Calculate the center point. We only needed is we have a pie type
//closeur. May want to store this local sometime
var ax:Number=newX-Math.cos(-(startAngle/180)*Math.PI)*width/2;
var ay:Number=newY-Math.sin(-(startAngle/180)*Math.PI)*height/2;
//draw the start line in the case of a pie type
if (closureType =="pie"){
if(Math.abs(arc)<360){
commandStack.addMoveTo(ax,ay);
commandStack.addLineTo(newX,newY);
}
} else commandStack.addMoveTo(newX,newY);
//fill the quad array with curve to segments
//which we'll use to draw and calc the bounds
ArcUtils.drawEllipticalArc(newX,newY,startAngle,arc,width/2,height/2,commandStack);
//close the arc if required
if(Math.abs(arc)<360){
if (closureType == "pie"){
commandStack.addLineTo(ax,ay);
}
if(closureType == "chord"){
commandStack.addLineTo(newX,newY);
}
}
invalidated = false;
}
}
/**
* Performs the specific layout work required by this Geometry.
* @param childBounds the bounds to be layed out. If not specified a rectangle
* of (0,0,1,1) is used.
**/
override public function calculateLayout(childBounds:Rectangle=null):void{
if(_layoutConstraint){
if (_layoutConstraint.invalidated){
var tempLayoutRect:Rectangle = new Rectangle(0,0,1,1);
if(_width){
tempLayoutRect.width = _width;
}
if(_height){
tempLayoutRect.height = _height;
}
if(_x){
tempLayoutRect.x = _x;
}
if(_y){
tempLayoutRect.y = _y;
}
super.calculateLayout(tempLayoutRect);
_layoutRectangle = _layoutConstraint.layoutRectangle;
if (isNaN(_width) || isNaN(_height)) {
//layout defined initial state:
_width = isNaN(_width)? layoutRectangle.width:_width;
_height = isNaN(_height) ? layoutRectangle.height: _height;
invalidated = true;
}
}
}
}
/**
* Begins the draw phase for geometry objects. All geometry objects
* override this to do their specific rendering.
*
* @param graphics The current context to draw to.
* @param rc A Rectangle object used for fill bounds.
**/
override public function draw(graphics:Graphics,rc:Rectangle):void{
//init the layout in this case done before predraw.
if (_layoutConstraint) calculateLayout();
//re init if required
if (invalidated) preDraw();
super.draw(graphics,(rc)? rc:bounds);
}
/**
* An object to derive this objects properties from. When specified this
* object will derive it's unspecified properties from the passed object.
**/
public function set derive(value:EllipticalArc):void{
if (!fill){fill=value.fill;}
if (!stroke){stroke = value.stroke}
if (!_x){_x = value.x;}
if (!_y){_y = value.y;}
if (!_width){_width = value.width;}
if (!_height){_height = value.height;}
if (!_startAngle){_startAngle = value.startAngle;}
if (!_arc){_arc = value.arc;}
if (!_closureType){_closureType = value.closureType;}
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 309 B

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,143 @@
////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2008 The Degrafa Team : http://www.Degrafa.com/team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
////////////////////////////////////////////////////////////////////////////////
package com.degrafa.geometry
{
import com.degrafa.IGeometry;
import com.degrafa.IGeometryComposition;
import com.degrafa.core.ITransformablePaint;
import com.degrafa.events.DegrafaEvent;
import com.degrafa.geometry.command.CommandStack;
import com.degrafa.geometry.command.CommandStackItem;
import flash.display.Graphics;
import flash.geom.Rectangle;
import mx.events.PropertyChangeEvent;
/**
* Unions child geometries into one large closed path
* Note: Child geometries fill and strokes will be ignored
*/
public class GeometryUnion extends Geometry implements IGeometry
{
public function GeometryUnion()
{
super();
}
/**
* Performs the specific layout work required by this Geometry.
* @param childBounds the bounds to be layed out. If not specified a rectangle
* of (0,0,1,1) is used.
**/
override public function calculateLayout(childBounds:Rectangle=null):void{
if(_layoutConstraint){
if (_layoutConstraint.invalidated){
var tempLayoutRect:Rectangle = new Rectangle(x,y,width,height);
super.calculateLayout(tempLayoutRect);
_layoutRectangle = _layoutConstraint.layoutRectangle;
}
}
// this._layoutRectangle=this.commandStack.bounds;
}
/**
* Principle event handler for any property changes to a
* geometry object or it's child objects.
**/
override protected function propertyChangeHandler(event:PropertyChangeEvent):void{
super.propertyChangeHandler(event);
invalidated=true;
}
//override to combine geometry
override public function preDraw():void{
//predraw each child and grab the command stack adding it to
//this command stack one item at time
//Remove any move to operations that would leave the path open and not filled.
commandStack.source=new Array();
var i:int=0;
for each (var item:IGeometryComposition in geometry){
item.preDraw();
for each (var cmd:CommandStackItem in item.commandStack.source) {
if (cmd.type !=CommandStackItem.MOVE_TO || i==0) {
commandStack.addItem(cmd);
}
else if (cmd.type==CommandStackItem.MOVE_TO && i > 0) {
cmd.type=CommandStackItem.LINE_TO;
commandStack.addItem(cmd);
}
i++;
}
}
this.commandStack.invalidated=true;
var t:Rectangle=this.commandStack.bounds; //Force calc on bounds
}
//may need to do stuff here for the fill side
override public function initFill(graphics:Graphics,rc:Rectangle):void{
if (_fill)
{
//we can't pass a reference to the requesting Geometry in the method signature with IFill - its required for transform inheritance by some fills
if (_fill is ITransformablePaint) (_fill as ITransformablePaint).requester = this;
_fill.begin(graphics, (rc) ? rc:null);
CommandStack.currentFill = _fill;
} else
CommandStack.currentFill = null;
}
//override for now
override public function draw(graphics:Graphics, rc:Rectangle):void{
//re init if required
calculateLayout();
preDraw();
super.draw(graphics, (rc)? rc:bounds);
}
override public function endDraw(graphics:Graphics):void {
if (fill) {
fill.end(graphics);
}
//append a null moveTo following a stroke without a fill
//forces a break in continuity with moveTo before the next
//path - if we have the last point coords we could use them
//instead of null, null or perhaps any value
if (stroke && !fill) graphics.moveTo.call(graphics, null, null);
dispatchEvent(new DegrafaEvent(DegrafaEvent.RENDER));
}
}
}

View File

@ -0,0 +1,242 @@
////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2008 The Degrafa Team : http://www.Degrafa.com/team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
////////////////////////////////////////////////////////////////////////////////
package com.degrafa.geometry{
import com.degrafa.IGeometry;
import com.degrafa.core.IGraphicsFill;
import flash.display.Graphics;
import flash.geom.Rectangle;
//excluded here
[Exclude(name="fill", kind="property")]
[Exclude(name="height", kind="property")]
[Exclude(name="percentHeight", kind="property")]
[Exclude(name="maxHeight", kind="property")]
[Exclude(name="minHeight", kind="property")]
//--------------------------------------
// Other metadata
//--------------------------------------
[IconFile("HorizontalLine.png")]
[Bindable]
/**
* The HorizontalLine element draws a horizontal line using the specified x, y,
* and x1 coordinate values.
*
* @see http://samples.degrafa.com/HorizontalLine/HorizontalLine.html
*
**/
public class HorizontalLine extends Geometry implements IGeometry{
/**
* Constructor.
*
* <p>The horizontal line constructor accepts 3 optional arguments that define it's
* center point and radius.</p>
*
* @param x A number indicating the starting x-axis coordinate.
* @param y A number indicating the starting y-axis coordinate.
* @param x1 A number indicating the ending x-axis coordinate.
*/
public function HorizontalLine(x:Number=NaN,y:Number=NaN,x1:Number=NaN){
super();
if (x) this.x=x;
if (y) this.y=y;
if (x1) this.x1=x1;
}
//excluded here
override public function set fill(value:IGraphicsFill):void{}
override public function set height(value:Number):void{}
override public function set percentHeight(value:Number):void{}
override public function set maxHeight(value:Number):void{}
override public function set minHeight(value:Number):void{}
/**
* HorizontalLine short hand data value.
*
* <p>The horizontal line data property expects exactly 3 values x,
* y and x1 separated by spaces.</p>
*
* @see Geometry#data
*
**/
override public function set data(value:Object):void{
if(super.data != value){
super.data = value;
//parse the string on the space
var tempArray:Array = value.split(" ");
if (tempArray.length == 3){
_x=tempArray[0];
_y=tempArray[1];
_x1 = tempArray[2];
invalidated = true;
}
}
}
private var _x:Number;
/**
* The x-coordinate of the start point of the line. If not specified
* a default value of 0 is used.
**/
override public function get x():Number{
if(!_x){return 0;}
return _x;
}
override public function set x(value:Number):void{
if(_x != value){
_x = value;
invalidated = true;
}
}
private var _y:Number;
/**
* The y-coordinate of the start point of the line. If not specified
* a default value of 0 is used.
**/
override public function get y():Number{
if(!_y){return 0;}
return _y;
}
override public function set y(value:Number):void{
if(_y != value){
_y = value;
invalidated = true;
}
}
private var _x1:Number;
/**
* The x-coordinate of the end point of the line. If not specified
* a default value of 0 is used.
**/
public function get x1():Number{
if(isNaN(_x1)){return (hasLayout)? 0.0001:0;}
return _x1;
}
public function set x1(value:Number):void{
if(_x1 != value){
_x1 = value;
invalidated = true;
}
}
/**
* @inheritDoc
**/
override public function preDraw():void{
if(invalidated){
commandStack.length=0;
commandStack.addMoveTo(x,y);
commandStack.addLineTo(x1,y);
invalidated = false;
}
}
/**
* Performs the specific layout work required by this Geometry.
* @param childBounds the bounds to be layed out. If not specified a rectangle
* of (0,0,1,1) is used.
**/
override public function calculateLayout(childBounds:Rectangle=null):void{
if(_layoutConstraint){
if (_layoutConstraint.invalidated){
var tempLayoutRect:Rectangle = new Rectangle(0,0,0.0001,0.0001);
if(!isNaN(_x1) || !isNaN(_x)){
if (_x1?_x1:0 - _x?_x:0) tempLayoutRect.width = Math.abs(_x1?_x1:0 - _x?_x:0);
tempLayoutRect.x = Math.min(_x?_x:0,_x1?_x1:0);
}
if(_y){
tempLayoutRect.y = _y;
}
super.calculateLayout(tempLayoutRect);
_layoutRectangle = _layoutConstraint.layoutRectangle;
//force the layout to minimum height in this case
_layoutRectangle.height = 0.0001;
if (isNaN(_x1)) {
//layout defined initial settings
if (isNaN(_x)) _x = _layoutRectangle.x;
if (isNaN(_y)) _y = _layoutRectangle.y;
_x1 = _layoutRectangle.right;
invalidated = true;
}
}
}
}
/**
* Begins the draw phase for geometry objects. All geometry objects
* override this to do their specific rendering.
*
* @param graphics The current context to draw to.
* @param rc A Rectangle object used for fill bounds.
**/
override public function draw(graphics:Graphics,rc:Rectangle):void{
//init the layout in this case done before predraw.
if (_layoutConstraint) calculateLayout();
//re init if required
if (invalidated) preDraw();
super.draw(graphics,(rc)? rc:bounds);
}
/**
* An object to derive this objects properties from. When specified this
* object will derive it's unspecified properties from the passed object.
**/
public function set derive(value:HorizontalLine):void{
if (!fill){fill=value.fill;}
if (!stroke){stroke = value.stroke;}
if (!_x){_x = value.x;}
if (!_y){_y = value.y;}
if (!_x1){_x1 = value.x1;}
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 183 B

View File

@ -0,0 +1,302 @@
////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2008 The Degrafa Team : http://www.Degrafa.com/team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
////////////////////////////////////////////////////////////////////////////////
package com.degrafa.geometry{
import com.degrafa.IGeometry;
import com.degrafa.core.IGraphicsFill;
import flash.display.Graphics;
import flash.geom.Rectangle;
//excluded here
[Exclude(name="fill", kind="property")]
//--------------------------------------
// Other metadata
//--------------------------------------
[IconFile("Line.png")]
[Bindable]
/**
* The Line element draws a line using the specified x, y,
* x1 and y1 coordinate values.
*
* @see http://samples.degrafa.com/Line/Line.html
*
**/
public class Line extends Geometry implements IGeometry{
/**
* Constructor.
*
* <p>The circle constructor accepts 4 optional arguments that define it's
* center point and radius.</p>
*
* @param x A number indicating the starting x-axis coordinate.
* @param y A number indicating the starting y-axis coordinate.
* @param x1 A number indicating the ending x-axis coordinate.
* @param y1 A number indicating the ending y-axis coordinate.
*
*/
public function Line(x:Number=NaN,y:Number=NaN,x1:Number=NaN,y1:Number=NaN){
super();
this.x=x;
this.y=y;
this.x1=x1;
this.y1=y1;
}
//excluded here
override public function set fill(value:IGraphicsFill):void{}
/**
* Line short hand data value.
*
* <p>The line data property expects exactly 3 values x,
* y, x1 and y1 separated by spaces.</p>
*
* @see Geometry#data
*
**/
override public function set data(value:Object):void{
if(super.data != value){
//parse the string on the space
var tempArray:Array = value.split(" ");
if (tempArray.length == 4){
_x=tempArray[0];
_y=tempArray[1];
_x1=tempArray[2];
_y1=tempArray[3];
}
invalidated = true;
}
}
private var _x:Number;
/**
* The x-coordinate of the start point of the line. If not specified
* a default value of 0 is used.
**/
override public function get x():Number{
if(!_x){return 0;}
return _x;
}
override public function set x(value:Number):void{
if(_x != value){
_x = value;
invalidated = true;
}
}
private var _y:Number;
/**
* The y-coordinate of the start point of the line. If not specified
* a default value of 0 is used.
**/
override public function get y():Number{
if(!_y){return 0;}
return _y;
}
override public function set y(value:Number):void{
if(_y != value){
_y = value;
invalidated = true;
}
}
private var _x1:Number;
/**
* The x-coordinate of the end point of the line. If not specified
* a default value of 0 is used.
**/
public function get x1():Number{
if(!_x1){return (hasLayout)? 1:0;}
return _x1;
}
public function set x1(value:Number):void{
if(_x1 != value){
_x1 = value;
invalidated = true;
}
}
private var _y1:Number;
/**
* The y-coordinate of the end point of the line. If not specified
* a default value of 0 is used.
**/
public function get y1():Number{
if(!_y1){return (hasLayout)? 1:0;}
return _y1;
}
public function set y1(value:Number):void{
if(_y1 != value){
_y1 = value;
invalidated = true;
}
}
private var _length:Number;
/**
* The length of the line in pixels. Setting this value will modify
* the end point of the line to the appropriate length. If both x1
* and y1 are not set then setting the length will impact x1 only,
* set y1 to y and effectively create a horizontal line.
**/
public function get length():Number{
var dx:Number = x1 - x;
var dy:Number = y1 - y;
return Math.sqrt(dx*dx + dy*dy);
}
public function set length(value:Number):void{
if(_length != value){
_length = value;
//if both x1 and y1 are NaN then set x1 to length
if(!_x1 && !_y1 ){
_x1 = _length;
}
//this needs to be done before setting the values
var newX1:Number = Math.abs(_length * Math.cos(angle));
var newY1:Number = Math.abs(_length * Math.sin(angle));
_x1=newX1;
_y1=newY1;
invalidated = true;
}
}
/**
* The angle of the line in radians.
**/
public function get angle():Number{
return Math.atan((y1 - y)/(x1 - x));
}
/**
* @inheritDoc
**/
override public function preDraw():void{
if(invalidated){
commandStack.length=0;
commandStack.addMoveTo(x,y);
commandStack.addLineTo(x1,y1);
invalidated = false;
}
}
/**
* Performs the specific layout work required by this Geometry.
* @param childBounds the bounds to be layed out. If not specified a rectangle
* of (0,0,1,1) is used.
**/
override public function calculateLayout(childBounds:Rectangle=null):void{
if(_layoutConstraint){
if (_layoutConstraint.invalidated){
var tempLayoutRect:Rectangle = new Rectangle(0,0,0.0001,0.0001);
if(!isNaN(_x1) || !isNaN(_x)){
if (_x1?_x1:0-_x?_x:0) tempLayoutRect.width = Math.abs(_x1?_x1:0-_x?_x:0);
}
if(!isNaN(_y1) || !isNaN(_y)){
if (_y1?_y1:0-_y?_y:0) tempLayoutRect.height = Math.abs(_y1?_y1:0-_y?_y:0);
}
if(!isNaN(_x) || !isNaN(_x1)){
tempLayoutRect.x = Math.min(_x?_x:0,_x1?_x1:0);
}
if(!isNaN(_y) || !isNaN(_y1)){
tempLayoutRect.y = Math.min(_y?_y:0,_y1?_y1:0);
}
super.calculateLayout(tempLayoutRect);
_layoutRectangle = _layoutConstraint.layoutRectangle;
if (isNaN(_x1) && isNaN(_y1) && !_x && !_y) {
//layout defined initial state
_x = _layoutRectangle.x;
_y = _layoutRectangle.y;
_x1 = _layoutRectangle.right;
_y1 = _layoutRectangle.bottom;
invalidated = true;
}
}
}
}
/**
* Begins the draw phase for geometry objects. All geometry objects
* override this to do their specific rendering.
*
* @param graphics The current context to draw to.
* @param rc A Rectangle object used for fill bounds.
**/
override public function draw(graphics:Graphics,rc:Rectangle):void{
//init the layout in this case done before predraw.
if (_layoutConstraint) calculateLayout();
//re init if required
if (invalidated) preDraw();
super.draw(graphics,(rc)? rc:bounds);
}
/**
* An object to derive this objects properties from. When specified this
* object will derive it's unspecified properties from the passed object.
**/
public function set derive(value:Line):void{
if (!stroke){stroke = value.stroke;}
if (!_x){_x = value.x;}
if (!_y){_y = value.y;}
if (!_x1){_x1 = value.x1;}
if (!_y1){_y1 = value.y1;}
if (!_length){_length = value.length;}
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 241 B

View File

@ -0,0 +1,145 @@
////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2008 The Degrafa Team : http://www.Degrafa.com/team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
////////////////////////////////////////////////////////////////////////////////
package com.degrafa.geometry{
import com.degrafa.IGeometry;
import flash.display.Graphics;
import flash.geom.Rectangle;
[Exclude(name="fill", kind="property")]
[Exclude(name="stroke", kind="property")]
[Bindable]
/**
* The Move element moves the drawing context current point to a specified x and y
* coordinate value.
*
* @see http://degrafa.com/samples/Move_Element.html
*
**/
public class Move extends Geometry implements IGeometry{
/**
* Constructor.
*
* <p>The move constructor accepts 2 optional arguments that define it's
* x, and y coordinate values.</p>
*
* @param x A number indicating the x-axis coordinate to move to.
* @param y A number indicating the y-axis coordinate to move to.
*
*/
public function Move(x:Number=0,y:Number=0){
super();
this.x=x;
this.y=y;
}
/**
* Move short hand data value.
*
* <p>The move data property expects exactly 2 values x and
* y separated by spaces.</p>
*
* @see Geometry#data
*
**/
override public function set data(value:Object):void{
if(super.data != value){
super.data = value;
//parse the string on the space
var tempArray:Array = value.split(" ");
if (tempArray.length == 2){
_x=tempArray[0];
_y=tempArray[1];
}
invalidated = true;
}
}
private var _x:Number=0;
/**
* The x-coordinate to move to. If not specified
* a default value of 0 is used.
**/
override public function get x():Number{
return _x;
}
override public function set x(value:Number):void{
if(_x != value){
_x = value;
invalidated = true;
}
}
private var _y:Number=0;
/**
* The y-coordinate to move to. If not specified
* a default value of 0 is used.
**/
override public function get y():Number{
return _y;
}
override public function set y(value:Number):void{
if(_y != value){
_y = value;
invalidated = true;
}
}
/**
* @inheritDoc
**/
override public function preDraw():void{
if(invalidated){
commandStack.length=0;
commandStack.addMoveTo(x,y);
invalidated = false;
}
}
/**
* Begins the draw phase for geometry objects. All geometry objects
* override this to do their specific rendering.
*
* @param graphics The current context to draw to.
* @param rc A Rectangle object used for fill bounds.
**/
override public function draw(graphics:Graphics,rc:Rectangle):void{
//re init if required
if (invalidated) preDraw();
super.draw(graphics,(rc)? rc:bounds);
}
}
}

View File

@ -0,0 +1,600 @@
////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2008 The Degrafa Team : http://www.Degrafa.com/team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
////////////////////////////////////////////////////////////////////////////////
package com.degrafa.geometry{
// import com.degrafa.core.utils.CloneUtil;
import com.degrafa.IGeometry;
import com.degrafa.core.collections.SegmentsCollection;
import com.degrafa.geometry.segment.*;
import com.degrafa.geometry.utilities.*;
import flash.display.Graphics;
import flash.geom.Point;
import flash.geom.Rectangle;
import mx.events.PropertyChangeEvent;
//--------------------------------------
// Other metadata
//--------------------------------------
[IconFile("Path.png")]
[DefaultProperty("segments")]
[Bindable]
/**
* The Path element draws a path comprised of several
* available path commands using the specified path data
* value.
*
* <p>Paths represent the geometry of the outline of an object,
* defined in terms of moveto (set a new current point), lineto
* (draw a straight line), curveto (draw a curve using a cubic Bézier),
* arc (elliptical or circular arc) and closepath (close the current shape
* by drawing a line to the last moveto) elements.</p>
*
*
* @see http://www.w3.org/TR/SVG/paths.html
* @see http://samples.degrafa.com/Path/Path.html
*
**/
public class Path extends Geometry implements IGeometry{
/**
* Constructor.
*
* <p>The path constructor accepts 1 optional argument that
* defines it's segments.</p>
*
* @param data A string representing 1 or more segment commands
* with which to draw the path.
*/
public function Path(data:String=null){
super();
if (data) this.data=data;
}
/**
* Path short hand data value.
*
* <p>The line data property expects exactly 1 value that
* defines the path. See below link to SVG path specification
* of which we follow most of.</p>
*
* @see Geometry#data
* @see http://www.w3.org/TR/SVG/paths.html
*
**/
override public function set data(value:Object):void{
if(super.data != value){
super.data = value;
//clear the data
commandStack.length = 0;
/**
* Parse the path data using svg commands:
* ClosePath = z
* Moveto = M,m
* LineTo = L,l
* EllipticalArcTo = A,a
* HorizontalLineTo = H,h
* VerticalLineTo = V,v
* Quadratic Bezier = Q,q,T,t
* Cubic Bezier = C,c,S,s
**/
var pathDataArray:Array = PathDataToArray(String(value))
//store the array as we add items and set the segments after
var segmentStack:Array=[];
var length:int = pathDataArray.length;
var i:int = 0;
var seg:int=-1;
for (;i<length;i++)
{
switch((pathDataArray[i] as String))
{
case "L":
segmentStack[seg+=1]=(new LineTo(Number(pathDataArray[i+1]),Number(pathDataArray[i+2])));
i+=2;
//if the next item in the array is a number
//assume that the line is a continued array
//so create a new line segment for each point
//pair until we get to another item
if (!isNaN(Number(pathDataArray[i+1]))){
while (!isNaN(Number(pathDataArray[i+1]))){
segmentStack[seg+=1]=(new LineTo(Number(pathDataArray[i+1]),Number(pathDataArray[i+2])));
i += 2;
}
}
break;
case "l":
segmentStack[seg+=1]=(new LineTo(Number(pathDataArray[i+1]),Number(pathDataArray[i+2]),null,"relative"));
i += 2;
//if the next item in the array is a number
//assume that the line is a continued array
//so create a new line segment for each point
//pair until we get to another item
if (!isNaN(Number(pathDataArray[i+1]))){
while (!isNaN(Number(pathDataArray[i+1]))){
segmentStack[seg+=1]=(new LineTo(Number(pathDataArray[i+1]),Number(pathDataArray[i+2]),null,"relative"));
i += 2;
}
}
break;
case "h":
segmentStack[seg+=1]=(new HorizontalLineTo(Number(pathDataArray[i+1]),null,"relative"));
i +=1;
if (!isNaN(Number(pathDataArray[i+1]))){
while (!isNaN(Number(pathDataArray[i+1]))){
segmentStack[seg+=1]=(new HorizontalLineTo(Number(pathDataArray[i+1]),null,"relative"));
i +=1;
}
}
break;
case "H":
segmentStack[seg+=1]=(new HorizontalLineTo(Number(pathDataArray[i+1])));
i +=1;
if (!isNaN(Number(pathDataArray[i+1]))){
while (!isNaN(Number(pathDataArray[i+1]))){
segmentStack[seg+=1]=(new HorizontalLineTo(Number(pathDataArray[i+1])));
i +=1;
}
}
break;
case "v":
segmentStack[seg+=1]=(new VerticalLineTo(Number(pathDataArray[i+1]),null,"relative"));
i +=1;
if (!isNaN(Number(pathDataArray[i+1]))){
while (!isNaN(Number(pathDataArray[i+1]))){
segmentStack[seg+=1]=(new VerticalLineTo(Number(pathDataArray[i+1]),null,"relative"));
i +=1;
}
}
break;
case "V":
segmentStack[seg+=1]=(new VerticalLineTo(Number(pathDataArray[i+1])));
i +=1;
if (!isNaN(Number(pathDataArray[i+1]))){
while (!isNaN(Number(pathDataArray[i+1]))){
segmentStack[seg+=1]=(new VerticalLineTo(Number(pathDataArray[i+1])));
i +=1;
}
}
break;
case "q":
segmentStack[seg+=1]=(new QuadraticBezierTo(Number(pathDataArray[i+1]),
Number(pathDataArray[i+2]), Number(pathDataArray[i+3]),
pathDataArray[i + 4], null, "relative"));
i += 4;
if (!isNaN(Number(pathDataArray[i+1]))){
while (!isNaN(Number(pathDataArray[i+1]))){
segmentStack[seg+=1]=(new QuadraticBezierTo(Number(pathDataArray[i+1]),
Number(pathDataArray[i+2]), Number(pathDataArray[i+3]),
pathDataArray[i + 4], null, "relative"));
i += 4;
}
}
break;
case "Q":
segmentStack[seg+=1]=(new QuadraticBezierTo(Number(pathDataArray[i+1]),
Number(pathDataArray[i+2]), Number(pathDataArray[i+3]),
Number(pathDataArray[i+4])));
i += 4;
if (!isNaN(Number(pathDataArray[i+1]))){
while (!isNaN(Number(pathDataArray[i+1]))){
segmentStack[seg+=1]=(new QuadraticBezierTo(Number(pathDataArray[i+1]),
Number(pathDataArray[i+2]), Number(pathDataArray[i+3]),
pathDataArray[i + 4]));
i += 4;
}
}
break;
case "t":
segmentStack[seg+=1]=(new QuadraticBezierTo(0, 0,
Number(pathDataArray[i+1]), Number(pathDataArray[i+2]),null,"relative",true))
i += 2;
if (!isNaN(Number(pathDataArray[i+1]))){
while (!isNaN(Number(pathDataArray[i+1]))){
segmentStack[seg+=1]=(new QuadraticBezierTo(0, 0,
Number(pathDataArray[i+1]), Number(pathDataArray[i+2]),null,"relative",true))
i += 2;
}
}
break;
case "T":
segmentStack[seg+=1]=(new QuadraticBezierTo(0,0,
Number(pathDataArray[i+1]), Number(pathDataArray[i+2]),null,"absolute",true))
i += 2;
if (!isNaN(Number(pathDataArray[i+1]))){
while (!isNaN(Number(pathDataArray[i+1]))){
segmentStack[seg+=1]=(new QuadraticBezierTo(0,0,
Number(pathDataArray[i+1]), Number(pathDataArray[i+2]),null,"absolute",true))
i += 2;
}
}
break;
case "c":
segmentStack[seg+=1]=(new CubicBezierTo(
Number(pathDataArray[i+1]),Number(pathDataArray[i+2]),
Number(pathDataArray[i+3]),Number(pathDataArray[i+4]),
Number(pathDataArray[i+5]),Number(pathDataArray[i+6]),null,"relative"))
i += 6;
if (!isNaN(Number(pathDataArray[i+1]))){
while (!isNaN(Number(pathDataArray[i+1]))){
segmentStack[seg+=1]=(new CubicBezierTo(
Number(pathDataArray[i+1]),Number(pathDataArray[i+2]),
Number(pathDataArray[i+3]),Number(pathDataArray[i+4]),
Number(pathDataArray[i+5]),Number(pathDataArray[i+6]),null,"relative"))
i += 6;
}
}
break;
case "C":
segmentStack[seg+=1]=(new CubicBezierTo(
Number(pathDataArray[i+1]),Number(pathDataArray[i+2]),Number(pathDataArray[i+3]),
Number(pathDataArray[i+4]),Number(pathDataArray[i+5]),Number(pathDataArray[i+6])))
i += 6;
if (!isNaN(Number(pathDataArray[i+1]))){
while (!isNaN(Number(pathDataArray[i+1]))){
segmentStack[seg+=1]=(new CubicBezierTo(
Number(pathDataArray[i+1]),Number(pathDataArray[i+2]),
Number(pathDataArray[i+3]),Number(pathDataArray[i+4]),
Number(pathDataArray[i+5]),Number(pathDataArray[i+6])))
i += 6;
}
}
break;
case "s":
segmentStack[seg+=1]=(new CubicBezierTo(
0,0,Number(pathDataArray[i+1]),Number(pathDataArray[i+2]),
Number(pathDataArray[i+3]),Number(pathDataArray[i+4]),null,"relative",true))
i += 4;
if (!isNaN(Number(pathDataArray[i+1]))){
while (!isNaN(Number(pathDataArray[i+1]))){
segmentStack[seg+=1]=(new CubicBezierTo(
0,0,Number(pathDataArray[i+1]),Number(pathDataArray[i+2]),
Number(pathDataArray[i+3]),Number(pathDataArray[i+4]),null,"relative",true))
i += 4;
}
}
break;
case "S":
segmentStack[seg+=1]=(new CubicBezierTo(
0,0,Number(pathDataArray[i+1]),Number(pathDataArray[i+2]),
Number(pathDataArray[i+3]),Number(pathDataArray[i+4]),null,"absolute",true))
i += 4;
if (!isNaN(Number(pathDataArray[i+1]))){
while (!isNaN(Number(pathDataArray[i+1]))){
segmentStack[seg+=1]=(new CubicBezierTo(
0,0,Number(pathDataArray[i+1]),Number(pathDataArray[i+2]),
Number(pathDataArray[i+3]),Number(pathDataArray[i+4]),null,"absolute",true))
i += 4;
}
}
break;
case "a":
segmentStack[seg+=1]=(new EllipticalArcTo(
Number(pathDataArray[i+1]),
Number(pathDataArray[i+2]),
Number(pathDataArray[i+3]),
Number(pathDataArray[i+4]),
Number(pathDataArray[i+5]),
Number(pathDataArray[i+6]),
Number(pathDataArray[i+7]),null,"relative"));
i += 7;
break;
case "A":
segmentStack[seg+=1]=(new EllipticalArcTo(
Number(pathDataArray[i+1]),
Number(pathDataArray[i+2]),
Number(pathDataArray[i+3]),
Number(pathDataArray[i+4]),
Number(pathDataArray[i+5]),
Number(pathDataArray[i+6]),
Number(pathDataArray[i+7])));
i += 7;
break;
case "m":
segmentStack[seg+=1]=(new MoveTo(Number(pathDataArray[i+1]),Number(pathDataArray[i+2]),null,"relative"));
i += 2;
//if the next item in the array is a number
//assume that the items are a continued array
//of line segments so create a new line segment
//for each point pair until we get to another item
if (!isNaN(Number(pathDataArray[i+1]))){
while (!isNaN(Number(pathDataArray[i+1]))){
segmentStack[seg+=1]=(new LineTo(Number(pathDataArray[i+1]),Number(pathDataArray[i+2]),null,"relative"));
i += 2;
}
}
break;
case "M":
segmentStack[seg+=1]=(new MoveTo(Number(pathDataArray[i+1]),Number(pathDataArray[i+2])));
i += 2;
//if the next item in the array is a number
//assume that the items are a continued array
//of line segments so create a new line segment
//for each point pair until we get to another item
if (!isNaN(Number(pathDataArray[i+1]))){
while (!isNaN(Number(pathDataArray[i+1]))){
segmentStack[seg+=1]=(new LineTo(Number(pathDataArray[i+1]),Number(pathDataArray[i+2])));
i += 2;
}
}
break;
case "z":
case "Z":
segmentStack[seg+=1]=(new ClosePath());
break;
default:
break;
}
}
segments = segmentStack;
invalidated = true;
}
}
/**
* Converts the path data string value to an array of workable items
**/
private static function PathDataToArray(value:String):Array{
//trim whitespace at start:
value = value.replace(/^[\s]+/, "");
value=value.replace(/[\s]+|\-|[MmLlCcQqZzAaSsHhVvTt]/g,getReplaceValue)
value = value.replace(/,{2,}/g, ",")
return value.split(",");
}
/**
*
* Helper function used when parsing the path data string
**/
private static function getReplaceValue(matchedSubstring:String, itemIndex:uint, theString:String):String {
switch (matchedSubstring.charAt(0)){
case " ":
case ",":
case "\t":
case "\n":
case "\r":
case "\f":
return ",";
break;
case "-":
//don't put a comma in front of a negative exponent
if (theString.charAt(itemIndex - 1).toUpperCase() == 'E') {
return matchedSubstring;
} else return "," + matchedSubstring;
break;
default:
if (!itemIndex){
return matchedSubstring + ",";
}
return "," + matchedSubstring + ",";
break
}
}
private var _segments:SegmentsCollection;
[Inspectable(category="General", arrayType="com.degrafa.geometry.segment.ISegment")]
[ArrayElementType("com.degrafa.geometry.segment.ISegment")]
/**
* A array of segments that describe this path.
**/
public function get segments():Array{
initSegmentsCollection();
return _segments.items;
}
public function set segments(value:Array):void{
initSegmentsCollection();
_segments.items = value;
//do initial invalidation
invalidated = true;
}
/**
* Access to the Degrafa segment collection object for this path.
**/
public function get segmentCollection():SegmentsCollection{
initSegmentsCollection();
return _segments;
}
/**
* Initialize the segment collection by creating it and adding the event listener.
**/
private function initSegmentsCollection():void{
if(!_segments){
_segments = new SegmentsCollection();
_segments.parent = this;
//add a listener to the collection
if(enableEvents){
_segments.addEventListener(PropertyChangeEvent.PROPERTY_CHANGE,propertyChangeHandler);
}
}
}
/**
* Principle event handler for any property changes to a
* geometry object or it's child objects.
**/
override protected function propertyChangeHandler(event:PropertyChangeEvent):void{
//invalidated = true;
if (event.source==_segments || event.source is ISegment) invalidated = true;
super.propertyChangeHandler(event);
}
/**
* Initialize each segment and construct an internal array of l,m,c
* (lineTo, moveTo, CurveTo) commands.
**/
private function buildFlashCommandStack():void{
//each object hase a type l,m or c
//keep track of the last point used during drawing
var lastPoint:Point = new Point(0,0);
//keep track of the first point of current
//path for the close command
var firstPoint:Point = lastPoint.clone();
//store he last control point in case ShortSequence =true in
//which case we need to mirror the last used control point (s,S,t,T)
var lastControlPoint:Point=lastPoint.clone();
var curSegment:ISegment;
for each(curSegment in _segments.items){
curSegment.computeSegment(firstPoint,lastPoint,lastControlPoint,commandStack);
}
}
/**
* @inheritDoc
**/
override public function preDraw():void{
//see if any segments are invalid but only if we are not already invalid
//we do this as in the case of segments with events disabled we could not
//know otherwise
if(!invalidated){
//verify
var i:int = 0;
var length:int = segments.length;
for (;i<length;i++){
if(segments[i].invalidated){
invalidated = true;
break;
}
}
}
//rebuild an array of flash commands and
//recalculate the bounds if required
if(invalidated){
// commandStack.length=0; removed as this was causing segment binding to fail
buildFlashCommandStack();
invalidated = false;
}
}
/**
* Performs the specific layout work required by this Geometry.
* @param childBounds the bounds to be layed out. If not specified a rectangle
* of (0,0,1,1) is used.
**/
override public function calculateLayout(childBounds:Rectangle=null):void{
if(_layoutConstraint){
if (_layoutConstraint.invalidated){
var tempLayoutRect:Rectangle = new Rectangle(0,0,1,1);
//default to bounds if no width or height is set
//and we have layout
if(isNaN(_layoutConstraint.width)){
tempLayoutRect.width = bounds.width;
} else tempLayoutRect.width=_layoutConstraint.width
if(isNaN(_layoutConstraint.height)){
tempLayoutRect.height = bounds.height;
} else tempLayoutRect.height=_layoutConstraint.height
if(isNaN(_layoutConstraint.x)){
tempLayoutRect.x = bounds.x;
} else tempLayoutRect.y=_layoutConstraint.y
if(isNaN(_layoutConstraint.y)){
tempLayoutRect.y = bounds.y;
} else tempLayoutRect.y=_layoutConstraint.y
super.calculateLayout(tempLayoutRect);
_layoutRectangle = _layoutConstraint.layoutRectangle;
}
}
}
/**
* Begins the draw phase for geometry objects. All geometry objects
* override this to do their specific rendering.
*
* @param graphics The current context to draw to.
* @param rc A Rectangle object used for fill bounds.
**/
override public function draw(graphics:Graphics,rc:Rectangle):void{
//re init if required
if (invalidated) preDraw();
//init the layout in this case done after predraw.
if (_layoutConstraint) calculateLayout();
super.draw(graphics, (rc)? rc:bounds);
}
/**
* An object to derive this objects properties from. When specified this
* object will derive it's unspecified properties from the passed object.
**/
public function set derive(value:Path):void{
if (!fill){fill=value.fill;}
if (!stroke) { stroke = value.stroke }
if (!_segments && value.segments.length != 0) {
segments = value.segments;
commandStack.source = value.commandStack.source;
invalidated = false;
};
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 557 B

View File

@ -0,0 +1,291 @@
////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2008 The Degrafa Team : http://www.Degrafa.com/team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
////////////////////////////////////////////////////////////////////////////////
package com.degrafa.geometry{
import com.degrafa.GraphicPoint;
import com.degrafa.IGeometry;
import com.degrafa.core.collections.GraphicPointCollection;
import flash.display.Graphics;
import flash.geom.Rectangle;
import mx.events.PropertyChangeEvent;
//--------------------------------------
// Other metadata
//--------------------------------------
[IconFile("Polygon.png")]
[DefaultProperty("points")]
[Bindable]
/**
* The Polygon element draws a polygon using the specified points.
*
* @see http://degrafa.com/samples/Polygon_Element.html
*
**/
public class Polygon extends Geometry implements IGeometry{
/**
* Constructor.
*
* <p>The polygon constructor accepts 1 optional argument that describes it's points.</p>
*
* @param points An array of points describing the polygon.
*/
public function Polygon(points:Array=null){
super();
if(points){
this.points=points;
}
}
/**
* Polygon short hand data value.
*
* <p>The polygon data property expects a list of space seperated points. For example
* "10,20 30,35". </p>
*
* @see Geometry#data
*
**/
override public function set data(value:Object):void{
if(super.data != value){
super.data = value;
//parse the string on the space
var pointsArray:Array = value.split(" ");
//create a temporary point array
var pointArray:Array=[];
var pointItem:Array;
//and then create a point struct for each resulting pair
//eventually throw excemption is not matching properly
var i:int = 0;
var length:int = pointsArray.length;
for (; i< length;i++){
pointItem = String(pointsArray[i]).split(",");
//skip past blank items as there may have been bad
//formatting in the value string, so make sure it is
//a length of 2 min
if(pointItem.length==2){
pointArray.push(new GraphicPoint(pointItem[0],pointItem[1]));
}
}
//set the points property
points=pointArray;
invalidated = true;
}
}
private var _points:GraphicPointCollection;
[Inspectable(category="General", arrayType="com.degrafa.IGraphicPoint")]
[ArrayElementType("com.degrafa.IGraphicPoint")]
/**
* A array of points that describe this polygon.
**/
public function get points():Array{
initPointsCollection();
return _points.items;
}
public function set points(value:Array):void{
initPointsCollection();
_points.items = value;
invalidated = true;
}
/**
* Access to the Degrafa point collection object for this polyline.
**/
public function get pointCollection():GraphicPointCollection{
initPointsCollection();
return _points;
}
/**
* Initialize the point collection by creating it and adding the event listener.
**/
private function initPointsCollection():void{
if(!_points){
_points = new GraphicPointCollection();
//add a listener to the collection
if(enableEvents){
_points.addEventListener(PropertyChangeEvent.PROPERTY_CHANGE,propertyChangeHandler);
}
}
}
/**
* Principle event handler for any property changes to a
* geometry object or it's child objects.
**/
override protected function propertyChangeHandler(event:PropertyChangeEvent):void{
invalidated = true;
super.propertyChangeHandler(event);
}
private var _x:Number;
/**
* The x-coordinate of the upper left point to begin drawing from. If not specified
* a default value of 0 is used.
**/
override public function get x():Number{
if(!_x){return 0;}
return _x;
}
override public function set x(value:Number):void{
if(_x != value){
_x = value;
invalidated = true;
}
}
private var _y:Number;
/**
* The y-coordinate of the upper left point to begin drawing from. If not specified
* a default value of 0 is used.
**/
override public function get y():Number{
if(!_y){return 0;}
return _y;
}
override public function set y(value:Number):void{
if(_y != value){
_y = value;
invalidated = true;
}
}
/**
* @inheritDoc
**/
override public function preDraw():void{
if(invalidated){
if(!_points || !_points.items || _points.items.length<1){return;}
commandStack.length=0;
commandStack.addMoveTo(_points.items[0].x+x,_points.items[0].y+y);
var i:int = 0;
var length:int = _points.items.length;
for (;i < length; i++){
commandStack.addLineTo(_points.items[i].x+x,_points.items[i].y+y);
}
//close if not done already
if (_points.items[_points.items.length-1].x+x !=_points.items[0].x+x || _points.items[_points.items.length-1].y+y !=_points.items[0].y+y){
commandStack.addLineTo(_points.items[0].x+x,_points.items[0].y+y);
}
invalidated = false;
}
}
/**
* Performs the specific layout work required by this Geometry.
* @param childBounds the bounds to be layed out. If not specified a rectangle
* of (0,0,1,1) is used.
**/
override public function calculateLayout(childBounds:Rectangle=null):void{
if(_layoutConstraint){
if (_layoutConstraint.invalidated){
var tempLayoutRect:Rectangle = new Rectangle(0,0,1,1);
//default to bounds if no width or height is set
//and we have layout
if(isNaN(_layoutConstraint.width)){
tempLayoutRect.width = bounds.width;
}
if(isNaN(_layoutConstraint.height)){
tempLayoutRect.height = bounds.height;
}
tempLayoutRect.x = (_x)? _x:0;
tempLayoutRect.y = (_y)? _y:0;
super.calculateLayout(tempLayoutRect);
_layoutRectangle = _layoutConstraint.layoutRectangle;
}
}
}
/**
* Begins the draw phase for geometry objects. All geometry objects
* override this to do their specific rendering.
*
* @param graphics The current context to draw to.
* @param rc A Rectangle object used for fill bounds.
**/
override public function draw(graphics:Graphics,rc:Rectangle):void{
//re init if required
if (invalidated) preDraw();
//init the layout in this case done after predraw.
if (_layoutConstraint) calculateLayout();
super.draw(graphics,(rc)? rc:bounds);
}
/**
* An object to derive this objects properties from. When specified this
* object will derive it's unspecified properties from the passed object.
**/
public function set derive(value:Polygon):void{
if (!fill){fill=value.fill;}
if (!stroke){stroke = value.stroke}
if (!_x){_x = value.x};
if (!_y){_y = value.y};
if (!_points && value.points.length!=0){points = value.points};
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 401 B

View File

@ -0,0 +1,301 @@
////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2008 The Degrafa Team : http://www.Degrafa.com/team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
////////////////////////////////////////////////////////////////////////////////
package com.degrafa.geometry{
import com.degrafa.GraphicPoint;
import com.degrafa.IGeometry;
import com.degrafa.core.collections.GraphicPointCollection;
import flash.display.Graphics;
import flash.geom.Rectangle;
import mx.events.PropertyChangeEvent;
//--------------------------------------
// Other metadata
//--------------------------------------
[IconFile("Polyline.png")]
[DefaultProperty("points")]
[Bindable]
/**
* The Polyline element draws a polyline using the specified points.
*
* @see http://degrafa.com/samples/Polyline_Element.html
*
**/
public class Polyline extends Geometry implements IGeometry{
/**
* Constructor.
*
* <p>The polyline constructor accepts 1 optional argument that describes it's points.</p>
*
* @param points An array of points describing this polyline.
*/
public function Polyline(points:Array=null){
super();
if(points){
this.points=points;
}
}
/**
* Polyline short hand data value.
*
* <p>The polyline data property expects a list of space seperated points. For example
* "10,20 30,35". </p>
*
* @see Geometry#data
*
**/
override public function set data(value:Object):void{
if(super.data != value){
super.data = value;
//parse the string on the space
var pointsArray:Array = value.split(" ");
//create a temporary point array
var pointArray:Array=[];
var pointItem:Array;
//and then create a point struct for each resulting pair
//eventually throw excemption is not matching properly
var i:int = 0;
var length:int = pointsArray.length;
for (; i< length;i++){
pointItem = String(pointsArray[i]).split(",");
//skip past blank items as there may have been bad
//formatting in the value string, so make sure it is
//a length of 2 min
if(pointItem.length==2){
pointArray.push(new GraphicPoint(pointItem[0],pointItem[1]));
}
}
//set the points property
points=pointArray;
invalidated = true;
}
}
private var _points:GraphicPointCollection;
[Inspectable(category="General", arrayType="com.degrafa.IGraphicPoint")]
[ArrayElementType("com.degrafa.IGraphicPoint")]
/**
* A array of points that describe this polyline.
**/
public function get points():Array{
initPointsCollection();
return _points.items;
}
public function set points(value:Array):void{
initPointsCollection();
_points.items = value;
invalidated = true;
}
/**
* Access to the Degrafa point collection object for this polyline.
**/
public function get pointCollection():GraphicPointCollection{
initPointsCollection();
return _points;
}
/**
* Initialize the point collection by creating it and adding the event listener.
**/
private function initPointsCollection():void{
if(!_points){
_points = new GraphicPointCollection();
//add a listener to the collection
if(enableEvents){
_points.addEventListener(PropertyChangeEvent.PROPERTY_CHANGE,propertyChangeHandler);
}
}
}
/**
* Principle event handler for any property changes to a
* geometry object or it's child objects.
**/
override protected function propertyChangeHandler(event:PropertyChangeEvent):void{
invalidated = true;
super.propertyChangeHandler(event);
}
private var _x:Number;
/**
* The x-coordinate of the upper left point to begin drawing from. If not specified
* a default value of 0 is used.
**/
override public function get x():Number{
if(!_x){return 0;}
return _x;
}
override public function set x(value:Number):void{
if(_x != value){
_x = value;
invalidated = true;
}
}
private var _y:Number;
/**
* The y-coordinate of the upper left point to begin drawing from. If not specified
* a default value of 0 is used.
**/
override public function get y():Number{
if(!_y){return 0;}
return _y;
}
override public function set y(value:Number):void{
if(_y != value){
_y = value;
invalidated = true;
}
}
private var _autoClose:Boolean;
/**
* Specifies if this polyline is to be automatically closed.
* If true a line is drawn to the first point.
**/
[Inspectable(category="General", enumeration="true,false")]
public function get autoClose():Boolean{
return _autoClose;
}
public function set autoClose(value:Boolean):void{
if(_autoClose != value){
_autoClose = value;
invalidated = true;
}
}
/**
* @inheritDoc
**/
override public function preDraw():void{
if(invalidated){
if(!_points || !_points.items || _points.items.length<1){return;}
commandStack.length=0;
commandStack.addMoveTo(_points.items[0].x+x,_points.items[0].y+y);
var i:int = 0;
var length:int = _points.items.length;
for (;i < length; i++){
commandStack.addLineTo(_points.items[i].x+x,_points.items[i].y+y);
}
//close if required
if(_autoClose){
commandStack.addLineTo(_points.items[0].x+x,_points.items[0].y+y);
}
invalidated = false;
}
}
/**
* Performs the specific layout work required by this Geometry.
* @param childBounds the bounds to be layed out. If not specified a rectangle
* of (0,0,1,1) is used.
**/
override public function calculateLayout(childBounds:Rectangle=null):void{
if(_layoutConstraint){
if (_layoutConstraint.invalidated){
var tempLayoutRect:Rectangle = new Rectangle(0,0,1,1);
//default to bounds if no width or height is set
//and we have layout
if(isNaN(_layoutConstraint.width)){
tempLayoutRect.width = bounds.width;
}
if(isNaN(_layoutConstraint.height)){
tempLayoutRect.height = bounds.height;
}
tempLayoutRect.x = (_x)? _x:0;
tempLayoutRect.y = (_y)? _y:0;
super.calculateLayout(tempLayoutRect);
_layoutRectangle = _layoutConstraint.layoutRectangle;
}
}
}
/**
* Begins the draw phase for geometry objects. All geometry objects
* override this to do their specific rendering.
*
* @param graphics The current context to draw to.
* @param rc A Rectangle object used for fill bounds.
**/
override public function draw(graphics:Graphics,rc:Rectangle):void{
//re init if required
if (invalidated) preDraw();
//init the layout in this case done after predraw.
if (_layoutConstraint) calculateLayout();
super.draw(graphics,(rc)? rc:bounds);
}
/**
* An object to derive this objects properties from. When specified this
* object will derive it's unspecified properties from the passed object.
**/
public function set derive(value:Polyline):void{
if (!fill){fill=value.fill;}
if (!stroke){stroke = value.stroke}
if (!_x){_x = value.x};
if (!_y){_y = value.y};
if (!_points && value.points.length!=0){points = value.points};
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 264 B

View File

@ -0,0 +1,314 @@
////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2008 The Degrafa Team : http://www.Degrafa.com/team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
////////////////////////////////////////////////////////////////////////////////
package com.degrafa.geometry{
import com.degrafa.IGeometry;
import com.degrafa.geometry.utilities.GeometryUtils;
import flash.display.Graphics;
import flash.geom.Rectangle;
//--------------------------------------
// Other metadata
//--------------------------------------
[IconFile("QuadraticBezier.png")]
[Bindable]
/**
* The QuadraticBezier element draws a quadratic Bézier using the specified
* start point, end point and control point.
*
* @see http://degrafa.com/samples/QuadraticBezier_Element.html
*
**/
public class QuadraticBezier extends Geometry implements IGeometry{
/**
* Constructor.
*
* <p>The quadratic Bézier constructor accepts 6 optional arguments that define it's
* start, end and controls points.</p>
*
* @param x0 A number indicating the starting x-axis coordinate.
* @param y0 A number indicating the starting y-axis coordinate.
* @param cx A number indicating the control x-axis coordinate.
* @param cy A number indicating the control y-axis coordinate.
* @param x1 A number indicating the ending x-axis coordinate.
* @param y1 A number indicating the ending y-axis coordinate.
*/
public function QuadraticBezier(x0:Number=NaN,y0:Number=NaN,cx:Number=NaN,cy:Number=NaN,x1:Number=NaN,y1:Number=NaN){
super();
this.x0=x0;
this.y0=y0;
this.cx=cx;
this.cy=cy;
this.x1=x1;
this.y1=y1;
}
/**
* QuadraticBezier short hand data value.
*
* <p>The quadratic Bézier data property expects exactly 6 values x0,
* y0, cx, cy, x1 and y1 separated by spaces.</p>
*
* @see Geometry#data
*
**/
override public function set data(value:Object):void{
if(super.data != value){
super.data = value;
//parse the string on the space
var tempArray:Array = value.split(" ");
if (tempArray.length == 6){
_x0=tempArray[0];
_y0=tempArray[1];
_cx=tempArray[2];
_cy=tempArray[3];
_x1=tempArray[4];
_y1=tempArray[5];
}
invalidated = true;
}
}
private var _x0:Number;
/**
* The x0-coordinate of the start point of the curve. If not specified
* a default value of 0 is used.
**/
public function get x0():Number{
if(!_x0){return 0;}
return _x0;
}
public function set x0(value:Number):void{
if(_x0 != value){
_x0 = value;
invalidated = true;
}
}
private var _y0:Number;
/**
* The y0-coordinate of the start point of the curve. If not specified
* a default value of 0 is used.
**/
public function get y0():Number{
if(!_y0){return (hasLayout)? 2:0;}
return _y0;
}
public function set y0(value:Number):void{
if(_y0 != value){
_y0 = value;
invalidated = true;
}
}
private var _x1:Number;
/**
* The x-coordinate of the end point of the curve. If not specified
* a default value of 0 is used.
**/
public function get x1():Number{
if(!_x1){return (hasLayout)? 2:0;}
return _x1;
}
public function set x1(value:Number):void{
if(_x1 != value){
_x1 = value;
invalidated = true;
}
}
private var _y1:Number;
/**
* The y-coordinate of the end point of the curve. If not specified
* a default value of 0 is used.
**/
public function get y1():Number{
if(!_y1){return (hasLayout)? 2:0;}
return _y1;
}
public function set y1(value:Number):void{
if(_y1 != value){
_y1 = value;
invalidated = true;
}
}
private var _cx:Number;
/**
* The x-coordinate of the control point of the curve. If not specified
* a default value of 0 is used.
**/
public function get cx():Number{
if(!_cx){return (hasLayout)? 1:0;}
return _cx;
}
public function set cx(value:Number):void{
if(_cx != value){
_cx = value;
invalidated = true;
}
}
private var _cy:Number;
/**
* The y-coordinate of the control point of the curve. If not specified
* a default value of 0 is used.
**/
public function get cy():Number{
if(!_cy){return 0;}
return _cy;
}
public function set cy(value:Number):void{
if(_cy != value){
_cy = value;
invalidated = true;
}
}
private var _close:Boolean=false;
/**
* If true draws a line from the end point to the start point to
* close this curve.
**/
[Inspectable(category="General", enumeration="true,false")]
public function get close():Boolean{
return _close;
}
public function set close(value:Boolean):void{
if(_close != value){
_close = value;
invalidated = true;
}
}
/**
* @inheritDoc
**/
override public function preDraw():void{
if(invalidated){
commandStack.length=0;
commandStack.resetBounds();
commandStack.addMoveTo(x0,y0);
commandStack.addCurveTo(cx,cy,x1,y1);
if(close){
commandStack.addLineTo(x0,y0);
}
invalidated = false;
}
}
/**
* Performs the specific layout work required by this Geometry.
* @param childBounds the bounds to be layed out. If not specified a rectangle
* of (0,0,1,1) is used.
**/
override public function calculateLayout(childBounds:Rectangle=null):void{
if(_layoutConstraint){
if (_layoutConstraint.invalidated){
var tempLayoutRect:Rectangle = new Rectangle(0, 0, 1, 1);
if(isNaN(_layoutConstraint.width)){
tempLayoutRect.width = bounds.width;
}
if(isNaN(_layoutConstraint.height)){
tempLayoutRect.height = bounds.height;
}
if(isNaN(_layoutConstraint.x)){
tempLayoutRect.x = bounds.x;
}
if(isNaN(_layoutConstraint.y)){
tempLayoutRect.y = bounds.y;
}
super.calculateLayout(tempLayoutRect);
_layoutRectangle = _layoutConstraint.layoutRectangle;
}
}
}
/**
* Begins the draw phase for geometry objects. All geometry objects
* override this to do their specific rendering.
*
* @param graphics The current context to draw to.
* @param rc A Rectangle object used for fill bounds.
**/
override public function draw(graphics:Graphics,rc:Rectangle):void{
//re init if required
if (invalidated) preDraw();
//init the layout in this case done after predraw.
if (_layoutConstraint) calculateLayout();
super.draw(graphics, (rc)? rc:bounds);
}
/**
* An object to derive this objects properties from. When specified this
* object will derive it's unspecified properties from the passed object.
**/
public function set derive(value:QuadraticBezier):void{
if (!fill){fill=value.fill;}
if (!stroke){stroke = value.stroke}
if (!_x0){_x0 = value.x0;}
if (!_y0){_y0 = value.y0;}
if (!_cx){_cx = value.cx;}
if (!_cy){_cy = value.cy;}
if (!_x1){_x1 = value.x1;}
if (!_y1){_y1 = value.y1;}
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 332 B

View File

@ -0,0 +1,468 @@
////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2008 The Degrafa Team : http://www.Degrafa.com/team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
////////////////////////////////////////////////////////////////////////////////
package com.degrafa.geometry{
import com.degrafa.geometry.display.IDisplayObjectProxy;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.geom.Matrix;
import com.degrafa.core.IGraphicsFill;
import flash.events.Event;
import flash.display.DisplayObject;
import flash.display.Graphics;
import flash.display.Sprite;
import flash.geom.Rectangle;
import flash.utils.getDefinitionByName;
import mx.events.PropertyChangeEvent;
import mx.events.PropertyChangeEventKind;
import com.degrafa.utilities.external.ExternalBitmapData;
import com.degrafa.utilities.external.ExternalDataAsset;
import com.degrafa.utilities.external.LoadingLocation;
import com.degrafa.utilities.external.ExternalDataPropertyChangeEvent;
import flash.utils.setTimeout;
import mx.events.PropertyChangeEvent;
[Exclude(name="data", kind="property")]
[Exclude(name="fill", kind="property")]
[Bindable(event = "propertyChange")]
/**
* The RasterImage element draws a Bitmap Rectangle to the
* drawing target.
*
* <p>RasterImage represents a bitmap image that can be part of a geometry composition
* with behavior similar to a regular geometry object. The source of the image mirrors the
* flexibility provided by the paint BitmapFill object, including the possibility of externally
* loaded iamges.</p>
*
*
**/
public class RasterImage extends Geometry implements IDisplayObjectProxy{
public var sprite:Sprite = new Sprite();
private var _externalBitmapData:ExternalBitmapData;
private var _loadingLocation:LoadingLocation;
private var _contentWidth:Number;
private var _contentHeight:Number;
/**
* Constructor.
*
* <p>The RasterImage constructor has no arguments . RasterImage does not inherit stroke by default unlike other Geometry items.</p>
*
*/
public function RasterImage(){
super();
//default to false for images on stroke inheritance
inheritStroke = false;
inheritFill = false;
}
/**
* Excluded Items
**/
/**
* Data is required for the IGeometry interface and has no effect here.
* @private
**/
override public function get data():Object{return null;}
override public function set data(value:Object):void{}
/**
* This item currently has no regular fill. We may add this to behave as a background fill (visible through transparent pixels in the image) in the future.
*/
override public function get fill():IGraphicsFill { return null };
override public function set fill(value:IGraphicsFill):void { };
private var _x:Number;
/**
* The x-axis coordinate of the upper left point of the regular rectangle. If not specified
* a default value of 0 is used.
**/
override public function get x():Number{
if(!_x){return 0;}
return _x;
}
override public function set x(value:Number):void{
if(_x != value){
_x = value;
invalidated = true;
}
}
private var _y:Number;
/**
* The y-axis coordinate of the upper left point of the regular rectangle. If not specified
* a default value of 0 is used.
**/
override public function get y():Number{
if(!_y){return 0;}
return _y;
}
override public function set y(value:Number):void{
if(_y != value){
_y = value;
invalidated = true;
}
}
private var _width:Number;
/**
* The width of the regular rectangle.
**/
[PercentProxy("percentWidth")]
override public function get width():Number{
if(!_width){return (hasLayout)? 1:0;}
return _width;
}
override public function set width(value:Number):void{
if(_width != value){
_width = value;
invalidated = true;
}
}
private var _height:Number;
/**
* The height of the regular rectangle.
**/
[PercentProxy("percentHeight")]
override public function get height():Number{
if(!_height){return (hasLayout)? 1:0;}
return _height;
}
override public function set height(value:Number):void{
if(_height != value){
_height = value;
invalidated = true;
}
}
/**
* Returns this objects displayObject.
**/
public function get displayObject():DisplayObject{
if (sprite.numChildren == 0) return null;
//provide the container object
return sprite;
}
/**
* A support property for binding to in the event of an external loading wait.
* permits a simple binding to indicate that the wait is over
*/
private var _waiting:Boolean;
[Bindable("externalDataPropertyChange")]
public function get waiting():Boolean
{
return (_waiting==true);
}
public function set waiting(val:Boolean):void
{
if (val != _waiting )
{
_waiting = val;
//support binding, but don't use propertyChange to avoid Degrafa redraws for no good reason
dispatchEvent(new ExternalDataPropertyChangeEvent(ExternalDataPropertyChangeEvent.EXTERNAL_DATA_PROPERTY_CHANGE, false, false, PropertyChangeEventKind.UPDATE , "waiting", !_waiting, _waiting, this))
}
}
private var _internalDO:DisplayObject;
/**
* handles the ready state for an ExternalBitmapData as the source of a RasterImage
* @param evt an ExternalDataAsset.STATUS_READY event
*/
private function externalBitmapHandler(evt:Event):void {
switch(evt.type)
{
case ExternalDataAsset.STATUS_READY:
var oldValue:Object = (sprite.numChildren) ? sprite.removeChildAt(0) : null;
var bitmapData:BitmapData = evt.target.content;
swapInContent(new Bitmap(bitmapData, "auto", true));
invalidated = true;
initChange("source", oldValue, _internalDO, this);
waiting = false;
break;
}
}
private function swapInContent(dobj :DisplayObject):void {
if (sprite.numChildren) sprite.removeChildAt(0);
_internalDO = dobj;
sprite.addChild(dobj);
//cache original values:
_contentWidth = sprite.width;
_contentHeight = sprite.height;
//if there were no explicit assigned width and height, use the content's width and height
if (isNaN(_width)) _width = _contentWidth;
if (isNaN(_height)) _height = _contentHeight;
invalidated = true;
}
/**
* Optional loadingLocation reference. Only relevant when a subsequent source assignment is made as
* a url string. Using a LoadingLocation simplifies management of loading from external domains
* and is required if a crossdomain policy file is not in the default location (web root) and with the default name (crossdomain.xml)
* In actionscript, a loadingLocation assignment MUST precede a change in the url assigned to the source property
* If a LoadingLocation is being used, the url assigned to the source property MUST be relative to the base path
* defined in the LoadingLocation, otherwise loading will fail.
* If a LoadingLocation is NOT used and the source property assignment is an external domain url, then the crossdomain permissions
* must exist in the default location and with the default name crossdomain.xml, otherwise loading will fail.
*/
public function get loadingLocation():LoadingLocation { return _loadingLocation; }
public function set loadingLocation(value:LoadingLocation):void
{
if (value) _loadingLocation = value;
}
private var target:DisplayObject;
//used in actionscript when a remote load is done
private var instantiationTimer:uint=5;
public function set source(value:Object):void {
var oldValue:Object = _internalDO;
target = null;
if (_externalBitmapData) {
_externalBitmapData.removeEventListener(ExternalDataAsset.STATUS_READY, externalBitmapHandler);
_externalBitmapData = null;
}
if (!value) {
_internalDO = null;
if (sprite.numChildren) sprite.removeChildAt(0);
if (oldValue!=null) initChange("source", oldValue, null, this);
return;
}
if (value is ExternalBitmapData) {
_externalBitmapData = value as ExternalBitmapData;
if (value.content) {
value = value.content;
} else {
value.addEventListener(ExternalDataAsset.STATUS_READY, externalBitmapHandler)
waiting = true;
return;
}
}
if (value is BitmapData)
{
swapInContent( new Bitmap(value as BitmapData,"auto",true));
initChange("source", oldValue, _internalDO, this);
return;
}
if (value is Class)
{
target= new value() as DisplayObject;
}
else if (value is Bitmap)
{
target = value as Bitmap;
}
else if (value is DisplayObject)
{
target = value as DisplayObject;
}
else if (value is String)
{
//is it a class name or an external url?
try {
var cls:Class = Class(getDefinitionByName(value as String));
} catch (e:Error)
{
//if its not a class name, assume url string for an ExternalBitmapData
//and wait for isInitialized to check/access loadingLocation mxml assignment
//if not isInitialized after 5 ms, assume actionscript instantiation and not mxml
if (!isInitialized && instantiationTimer) {
instantiationTimer--;
setTimeout(
function():void
{source = value }, 1);
} else {
source = ExternalBitmapData.getUniqueInstance(value as String, _loadingLocation);
}
return;
}
target = new cls();
}
else
{
_internalDO = null;
if (sprite.numChildren) sprite.removeChildAt(0);
invalidated = true;
if (oldValue!=null) initChange("source", oldValue, null, this);
return;
}
if( target != null)
{
swapInContent(target as DisplayObject)
invalidated = true;
initChange("source", oldValue, _internalDO, this);
}
}
private var _bounds:Rectangle;
/**
* The tight bounds of this element as represented by a Rectangle object.
**/
override public function get bounds():Rectangle {
return commandStack.bounds;
}
/**
* Performs the specific layout work required by this Geometry.
* @param childBounds the bounds to be layed out. If not specified a rectangle
* of (0,0,1,1) is used or the most appropriate size is calculated.
**/
override public function calculateLayout(childBounds:Rectangle=null):void{
if(_layoutConstraint){
if (_layoutConstraint.invalidated){
var tempLayoutRect:Rectangle = new Rectangle(0,0,1,1);
if (isNaN(_width)) _width = _contentWidth;
if (isNaN(_height)) _height = _contentHeight;
tempLayoutRect.width = _width
tempLayoutRect.height = _height
tempLayoutRect.x =_x?_x: _x=0;
tempLayoutRect.y =_y?_y: _y=0;;
super.calculateLayout(tempLayoutRect);
_layoutRectangle = _layoutConstraint.layoutRectangle.isEmpty()? tempLayoutRect: _layoutConstraint.layoutRectangle;
_layoutMode = "scale";
invalidated = true;
}
} else {
//size into regular settings
_transformBeforeRender = false;
if (isNaN(_width)) _width = _contentWidth;
if (isNaN(_height)) _height = _contentHeight;
_internalDO.x = x;
_internalDO.y = y
if (_width !=_contentWidth) _internalDO.scaleX = _width / _contentWidth;
if (_height != _contentHeight) _internalDO.scaleY = _height / _contentHeight;
invalidated = true;
}
}
/**
* @inheritDoc
**/
override public function preDraw():void {
if(invalidated){
commandStack.length=0;
//frame it in a rectangle to permit transforms
//(whether this is used or not will depend on the
//transformBeforeRender setting
commandStack.addMoveTo(x, y);
commandStack.addLineTo(x+_width, y);
commandStack.addLineTo(x+_width, y+_height);
commandStack.addLineTo(x, y + _height);
commandStack.addLineTo(x, y);
invalidated = false;
}
}
private var _layoutMode:String = "scale";
/**
* The layout mode associated with this IDisplayObjectProxy. For an image this is always scale only.
*/
public function get layoutMode():String {
return _layoutMode;
}
private var _transformBeforeRender:Boolean;
/**
* A setting to determine at what point transforms are performed when capturing the bitmap representation of this object internally
* before final rendering. Unless otherwise needed, the default setting of false uses less memory.
*/
[Inspectable(category="General", enumeration="true,false", defaultValue="false")]
public function get transformBeforeRender():Boolean {
return Boolean(_transformBeforeRender);
}
public function set transformBeforeRender(value:Boolean):void {
if (_transformBeforeRender != value) {
_transformBeforeRender = value;
}
}
/**
* Begins the draw phase for geometry/IDisplayObjectProxy objects. All geometry objects
* override this to do their specific rendering.
*
* @param graphics The current context to draw to.
* @param rc A Rectangle object used for fill bounds.
**/
override public function draw(graphics:Graphics, rc:Rectangle):void {
if (!_internalDO || _internalDO.getBounds(_internalDO).isEmpty()) return;
//init the layout in this case done after predraw.
calculateLayout();
if (invalidated) preDraw();
super.draw(graphics, rc?rc:bounds);
}
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,262 @@
////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2008 The Degrafa Team : http://www.Degrafa.com/team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
////////////////////////////////////////////////////////////////////////////////
package com.degrafa.geometry{
import com.degrafa.IGeometry;
import flash.display.Graphics;
import flash.geom.Rectangle;
//--------------------------------------
// Other metadata
//--------------------------------------
[IconFile("RegularRectangle.png")]
[Bindable]
/**
* The RegularRectangle element draws a regular rectangle using the specified x,y,
* width and height.
*
* @see http://samples.degrafa.com/RegularRectangle/RegularRectangle.html
*
**/
public class RegularRectangle extends Geometry implements IGeometry{
/**
* Constructor.
*
* <p>The regular rectangle constructor accepts 4 optional arguments that define it's
* x, y, width and height.</p>
*
* @param x A number indicating the upper left x-axis coordinate.
* @param y A number indicating the upper left y-axis coordinate.
* @param width A number indicating the width.
* @param height A number indicating the height.
*/
public function RegularRectangle(x:Number=NaN,y:Number=NaN,width:Number=NaN,height:Number=NaN){
super();
if(x) this.x=x;
if(y) this.y=y;
if(width) this.width=width;
if(height) this.height=height;
}
/**
* RegularRectangle short hand data value.
*
* <p>The regular rectangle data property expects exactly 4 values x,
* y, width and height separated by spaces.</p>
*
* @see Geometry#data
*
**/
override public function set data(value:Object):void{
if(super.data != value){
super.data = value;
//parse the string on the space
var tempArray:Array = value.split(" ");
if (tempArray.length == 4){
_x=tempArray[0];
_y=tempArray[1];
_width=tempArray[2];
_height=tempArray[3];
invalidated = true;
}
}
}
private var _x:Number;
/**
* The x-axis coordinate of the upper left point of the regular rectangle. If not specified
* a default value of 0 is used.
**/
override public function get x():Number{
if(isNaN(_x)){return 0;}
return _x;
}
override public function set x(value:Number):void{
if(_x != value){
_x = value;
if (hasLayout) super.x=value
invalidated = true;
}
}
private var _y:Number;
/**
* The y-axis coordinate of the upper left point of the regular rectangle. If not specified
* a default value of 0 is used.
**/
override public function get y():Number{
if(isNaN(_y)){return 0;}
return _y;
}
override public function set y(value:Number):void{
if(_y != value){
_y = value;
if (hasLayout) super.y=value
invalidated = true;
}
}
private var _width:Number;
/**
* The width of the regular rectangle.
**/
[PercentProxy("percentWidth")]
override public function get width():Number{
if(isNaN(_width)){return (hasLayout)? 1:0;}
return _width;
}
override public function set width(value:Number):void{
if(_width != value){
_width = value;
if (hasLayout) super.width=value
invalidated = true;
}
}
private var _height:Number;
/**
* The height of the regular rectangle.
**/
[PercentProxy("percentHeight")]
override public function get height():Number{
if(isNaN(_height)){return (hasLayout)? 1:0;}
return _height;
}
override public function set height(value:Number):void{
if(_height != value){
_height = value;
if (hasLayout) super.height=value
invalidated = true;
}
}
/**
* @inheritDoc
**/
override public function preDraw():void{
if(invalidated){
commandStack.length = 0;
commandStack.addMoveTo(x,y);
commandStack.addLineTo(x+width,y);
commandStack.addLineTo(x+width,y+height)
commandStack.addLineTo(x,y+height);
commandStack.addLineTo(x,y);
invalidated = false;
}
}
/**
* Performs the specific layout work required by this Geometry.
* @param childBounds the bounds to be layed out. If not specified a rectangle
* of (0,0,1,1) is used.
**/
override public function calculateLayout(childBounds:Rectangle=null):void{
if(_layoutConstraint){
if (_layoutConstraint.invalidated){
var tempLayoutRect:Rectangle = new Rectangle(0,0,1,1);
if(_width){
tempLayoutRect.width = _width;
}
if(_height){
tempLayoutRect.height = _height;
}
if(_x){
tempLayoutRect.x = _x;
}
if(_y){
tempLayoutRect.y = _y;
}
super.calculateLayout(tempLayoutRect);
_layoutRectangle = _layoutConstraint.layoutRectangle;
if (isNaN(_width) || isNaN(_height)) {
//layout defined initial state:
_width = isNaN(_width)? layoutRectangle.width:_width;
_height = isNaN(_height) ? layoutRectangle.height: _height;
invalidated = true;
}
}
}
}
/**
* Begins the draw phase for geometry objects. All geometry objects
* override this to do their specific rendering.
*
* @param graphics The current context to draw to.
* @param rc A Rectangle object used for fill bounds.
**/
override public function draw(graphics:Graphics,rc:Rectangle):void{
//init the layout in this case done before predraw.
if (_layoutConstraint) calculateLayout();
//re init if required
if (invalidated) preDraw();
super.draw(graphics,(rc)? rc:bounds);
}
/**
* An object to derive this objects properties from. When specified this
* object will derive it's unspecified properties from the passed object.
**/
public function set derive(value:RegularRectangle):void{
if (!fill){fill=value.fill;}
if (!stroke){stroke = value.stroke;}
if (!_x){_x = value.x;}
if (!_y){_y = value.y;}
if (!_width){_width = value.width;}
if (!_height){_height = value.height;}
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 334 B

View File

@ -0,0 +1,584 @@
////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2008 The Degrafa Team : http://www.Degrafa.com/team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
////////////////////////////////////////////////////////////////////////////////
package com.degrafa.geometry{
import com.degrafa.IGeometry;
import com.degrafa.geometry.command.CommandStack;
import com.degrafa.geometry.command.CommandStackItem;
import flash.display.Graphics;
import flash.geom.Rectangle;
//--------------------------------------
// Other metadata
//--------------------------------------
[IconFile("RoundedRectangle.png")]
[Bindable]
/**
* The RoundedRectangle element draws a rounded rectangle using the specified x,y,
* width, height and corner radius.
*
* @see http://degrafa.org/source/RoundedRectangle/RoundedRectangle.html
*
**/
public class RoundedRectangle extends Geometry implements IGeometry {
/**
* private constant used to avoid unnecessary trignometry calculations
*/
private static const TRIG:Number = 0.4142135623730950488016887242097;
/**
* Constructor.
*
* <p>The rounded rectangle constructor accepts 5 optional arguments that define it's
* x, y, width, height and corner radius.</p>
*
* @param x A number indicating the upper left x-axis coordinate.
* @param y A number indicating the upper left y-axis coordinate.
* @param width A number indicating the width.
* @param height A number indicating the height.
* @param cornerRadius A number indicating the radius of each corner.
*/
public function RoundedRectangle(x:Number=NaN,y:Number=NaN,width:Number=NaN,height:Number=NaN,cornerRadius:Number=NaN){
super();
if (x) this.x=x;
if (y) this.y=y;
if (width) this.width=width;
if (height) this.height=height;
if (cornerRadius)this.cornerRadius=cornerRadius;
}
/**
* RoundedRectangle short hand data value.
*
* <p>The rounded rectangle data property expects exactly 5 values x,
* y, width, height and corner radius separated by spaces.</p>
*
* @see Geometry#data
*
**/
override public function set data(value:Object):void{
if(super.data != value){
super.data = value;
//parse the string on the space
var tempArray:Array = value.split(" ");
if (tempArray.length == 5){
_x=tempArray[0];
_y=tempArray[1];
_width=tempArray[2];
_height=tempArray[3];
_cornerRadius = tempArray[4];
invalidated = true;
}
}
}
private var _x:Number;
/**
* The x-axis coordinate of the upper left point of the rounded rectangle. If not specified
* a default value of 0 is used.
**/
override public function get x():Number{
if(!_x){return 0;}
return _x;
}
override public function set x(value:Number):void{
if(_x != value){
_x = value;
if (hasLayout) super.y=value
invalidated = true;
}
}
private var _y:Number;
/**
* The y-axis coordinate of the upper left point of the rounded rectangle. If not specified
* a default value of 0 is used.
**/
override public function get y():Number{
if(!_y){return 0;}
return _y;
}
override public function set y(value:Number):void{
if(_y != value){
_y = value;
if (hasLayout) super.y=value
invalidated = true;
}
}
private var _width:Number;
/**
* The width of the rounded rectangle.
**/
[PercentProxy("percentWidth")]
override public function get width():Number{
if(!_width){return (hasLayout)? 1:0;}
return _width;
}
override public function set width(value:Number):void{
if(_width != value){
_width = value;
if (hasLayout) super.width=value
invalidated = true;
}
}
private var _height:Number;
/**
* The height of the rounded rectangle.
**/
[PercentProxy("percentHeight")]
override public function get height():Number{
if(!_height){return (hasLayout)? 1:0;}
return _height;
}
override public function set height(value:Number):void{
if(_height != value){
_height = value;
if (hasLayout) super.height=value
invalidated = true;
}
}
private var _cornerRadius:Number;
/**
* The radius to be used for each corner of the rounded rectangle.
**/
public function get cornerRadius():Number{
if(!_cornerRadius){return 0;}
return _cornerRadius;
}
public function set cornerRadius(value:Number):void{
if (_cornerRadius != value) {
var oldval:Number = _cornerRadius;
_cornerRadius = value;
invalidated = true;
}
}
private var _permitCornerInversion:uint;
[Inspectable(category="General", enumeration="true,false")]
/**
* If any of the corner radii are negative, the corners with negative values will cut inwards if permitCornerInversion is true.
* Defaults to false, in which case negative corner radius values represent a zero corner radius.
*/
public function get permitCornerInversion():Boolean {
return _permitCornerInversion? true:false;
}
public function set permitCornerInversion(value:Boolean):void {
if (value=!_permitCornerInversion) {
_permitCornerInversion = value?1:0;
invalidated = true;
}
}
/**
* The tight bounds of this element as represented by a Rectangle object.
**/
override public function get bounds():Rectangle {
//exception here for now, not using commandStack bounds:
return new Rectangle(x, y, width, height);
}
/**
* private internal function to update the values in the commandStack for rendering.
* This approach is taken to enforce the cornerRadius rules under layout. This method handles the corner calculations and variants with cornerInversion settings
* called from the render pipeline in CommandStack and also in preDraw for when layout is not active.
* @param cStack
* @param item
* @param graphics
* @param currentIndex
* @return
*/
private function updateCommandStack(cStack:CommandStack=null, item:CommandStackItem=null, graphics:Graphics=null,currentIndex:int=0):CommandStackItem {
var _cornerRadius:Number = cornerRadius;
//use local vars instead of the main getters
var x:Number;
var y:Number;
var width:Number ;
var height:Number
if (hasLayout && cStack) { //handle layout variant call at render time
CommandStack.transMatrix = CommandStack.currentTransformMatrix;
x = layoutRectangle.x;
y = layoutRectangle.y;
width = layoutRectangle.width;
height = layoutRectangle.height;
} else {
x = this.x;
y = this.y;
width = this.width;
height = this.height;
}
if (!_permitCornerInversion) {
if (_cornerRadius<0) _cornerRadius=0;
}
//set to skip
topRightCorner1.skip = topRightCorner2.skip =
bottomRightCorner1.skip = bottomRightCorner2.skip=
bottomLeftCorner1.skip = bottomLeftCorner2.skip =
topLeftCorner1.skip=topLeftCorner2.skip = (_cornerRadius)? false:true;
if(_cornerRadius){
// make sure that width + h are larger than 2*cornerRadius
if (Math.abs(_cornerRadius)>Math.min(width, height)/2) {
_cornerRadius = Math.min(width, height) / 2 * (_cornerRadius < 0? -1:1);
}
//round to nearest
// _cornerRadius = Math.round(_cornerRadius);
}
var adjx:Number = 0;
var adjy:Number = 0;
//apply fix for player rendering bug
if ( stroke && stroke.weight < 4 &&!stroke.pixelHinting ) {
//player rendering bug workaround: make sure the coords are offset from integer pixel values by at least 3 twips
//this seems to solve an anti-aliasing error with small stroke weights that is very obvious for RoundedRectangles
var adjbase:Number = 0.15;
var under:Boolean;
var diff:Number;
if ((stroke.weight != 2 && (diff = Math.abs(x -Math.round(x ))) < adjbase) ) {
under== x < Math.round(x);
adjx = (adjbase-diff)* (under?-1:1);
x += adjx;
} else {
if (stroke.weight == 2) { //variation - artefact seems to be centered around midpixel values with stroke.weight==2
under = x < Math.round(x * 2 ) / 2;
if ((diff = Math.abs(x -Math.round(x * 2 ) / 2)) < adjbase) {
adjx = (adjbase-diff)* (under?-1:1);
x += adjx;
}
}
}
under = y < Math.round(y);
if (stroke.weight!=2 && (diff = Math.abs(y -Math.round(y ))) < adjbase) {
adjy = (adjbase-diff)* (under?-1:1);
y += adjy;
} else {
if (stroke.weight == 2) { //variation - artefact seems to be centered around midpixel values with stroke.weight==2
if ((diff = Math.abs(y -Math.round(y * 2 ) / 2)) < adjbase) {
under = y < Math.round(y * 2 ) / 2;
adjy = (adjbase-diff)* (under?-1:1);
y += adjx;
}
}
}
}
//dev note:through initial testing this seems fine, but may also need to test for being on a pixel boundaries as well
var bottom:Number = y + height-adjy;
var right:Number = x + width-adjx;
var innerRight:Number = right - Math.abs(_cornerRadius);
var innerLeft:Number = x + Math.abs(_cornerRadius);
var innerTop:Number = y + Math.abs(_cornerRadius);
var innerBottom:Number = bottom - Math.abs(_cornerRadius);
// manipulate the commandStack
//basic rectangle:
startPoint.x = innerLeft;
startPoint.y = y;
topLine.x = innerRight;
topLine.y = y;
rightLine.x = right;
rightLine.y = innerBottom;
bottomLine.x = innerLeft;
bottomLine.y = bottom;
leftLine.x = x;
leftLine.y = innerTop;
//corners if necessary
if (_cornerRadius) {
var cornersplitoffset:Number;
var controlPointOffset:Number;
var innerRightcx:Number;
var innerRightx:Number ;
var innerBottomcy:Number ;
var innerBottomy:Number ;
var innerLeftcx:Number ;
var innerLeftx:Number ;
var innerTopcy:Number ;
var innerTopy:Number ;
cornersplitoffset = Math.SQRT1_2 * _cornerRadius;
controlPointOffset = TRIG * _cornerRadius;
if (_cornerRadius>0){
innerRightcx = innerRight + controlPointOffset;
innerRightx = innerRight + cornersplitoffset;
innerBottomcy = innerBottom + controlPointOffset;
innerBottomy = innerBottom + cornersplitoffset;
innerLeftcx = innerLeft - controlPointOffset;
innerLeftx = innerLeft - cornersplitoffset;
innerTopcy = innerTop - controlPointOffset;
innerTopy = innerTop - cornersplitoffset;
topRightCorner1.cx = innerRightcx;
topRightCorner1.cy = y;
topRightCorner1.x1 = innerRightx;
topRightCorner1.y1 = innerTopy;
topRightCorner2.cx = right;
topRightCorner2.cy = innerTopcy;
topRightCorner2.x1 = right;
topRightCorner2.y1 = innerTop;
bottomRightCorner1.cx = right;
bottomRightCorner1.cy = innerBottomcy;
bottomRightCorner1.x1 = innerRightx;
bottomRightCorner1.y1 = innerBottomy;
bottomRightCorner2.cx = innerRightcx;
bottomRightCorner2.cy = bottom;
bottomRightCorner2.x1 = innerRight;
bottomRightCorner2.y1 = bottom;
bottomLeftCorner1.cx = innerLeftcx;
bottomLeftCorner1.cy = bottom;
bottomLeftCorner1.x1 = innerLeftx;
bottomLeftCorner1.y1 = innerBottomy;
bottomLeftCorner2.cx = x;
bottomLeftCorner2.cy = innerBottomcy;
bottomLeftCorner2.x1 = x;
bottomLeftCorner2.y1 = innerBottom;
topLeftCorner1.cx = x;
topLeftCorner1.cy = innerTopcy;
topLeftCorner1.x1 = innerLeftx;
topLeftCorner1.y1 = innerTopy;
topLeftCorner2.cx = innerLeftcx;
topLeftCorner2.cy = y;
topLeftCorner2.x1 = innerLeft;
topLeftCorner2.y1 = y;/**/
} else {
innerRightcx = right+ controlPointOffset;
innerRightx = right + cornersplitoffset;
innerBottomcy = bottom+ controlPointOffset;
innerBottomy = bottom + cornersplitoffset;
innerLeftcx = x - controlPointOffset;
innerLeftx = x - cornersplitoffset;
innerTopcy = y - controlPointOffset;
innerTopy = y - cornersplitoffset;
topRightCorner1.cx = innerRight;
topRightCorner1.cy = innerTopcy;
topRightCorner1.x1 = innerRightx;
topRightCorner1.y1 = innerTopy;
topRightCorner2.cx = innerRightcx;
topRightCorner2.cy = innerTop;
topRightCorner2.x1 = right;
topRightCorner2.y1 = innerTop;
bottomRightCorner1.cx = innerRightcx;
bottomRightCorner1.cy = innerBottom;
bottomRightCorner1.x1 = innerRightx;
bottomRightCorner1.y1 = innerBottomy;
bottomRightCorner2.cx = innerRight;
bottomRightCorner2.cy = innerBottomcy;
bottomRightCorner2.x1 = innerRight;
bottomRightCorner2.y1 = bottom;
bottomLeftCorner1.cx = innerLeft;
bottomLeftCorner1.cy = innerBottomcy;
bottomLeftCorner1.x1 = innerLeftx;
bottomLeftCorner1.y1 = innerBottomy;
bottomLeftCorner2.cx = innerLeftcx;
bottomLeftCorner2.cy = innerBottom;
bottomLeftCorner2.x1 = x;
bottomLeftCorner2.y1 = innerBottom;
topLeftCorner1.cx = innerLeftcx;
topLeftCorner1.cy = innerTop
topLeftCorner1.x1 = innerLeftx;
topLeftCorner1.y1 = innerTopy;
topLeftCorner2.cx = innerLeft;
topLeftCorner2.cy = innerTopcy;
topLeftCorner2.x1 = innerLeft;
topLeftCorner2.y1 = y;
}
}
return commandStack.source[0];
}
private var startPoint:CommandStackItem;
private var topLine:CommandStackItem;
private var topRightCorner1:CommandStackItem;
private var topRightCorner2:CommandStackItem;
private var rightLine:CommandStackItem;
private var bottomRightCorner1:CommandStackItem;
private var bottomRightCorner2:CommandStackItem;
private var bottomLine:CommandStackItem;
private var bottomLeftCorner1:CommandStackItem
private var bottomLeftCorner2:CommandStackItem
private var leftLine:CommandStackItem;
private var topLeftCorner1:CommandStackItem;
private var topLeftCorner2:CommandStackItem;
/**
* @inheritDoc
**/
override public function preDraw():void{
if(invalidated){
if (!commandStack.length) {
//one top level item permits a single renderDelegate call
//var commandStackItem:CommandStackItem = commandStack.addItem(new CommandStackItem(CommandStackItem.COMMAND_STACK,NaN,NaN,NaN,NaN,NaN,NaN,new CommandStack())) ;
var commandStackItem:CommandStackItem = commandStack.addItem(new CommandStackItem(CommandStackItem.DELEGATE_TO));
commandStackItem.delegate = updateCommandStack;
//set up quick references to manipulate items directly
startPoint=commandStack.addItem(new CommandStackItem(CommandStackItem.MOVE_TO));
topLine = commandStack.addItem(new CommandStackItem(CommandStackItem.LINE_TO));
topRightCorner1=commandStack.addItem(new CommandStackItem(CommandStackItem.CURVE_TO));
topRightCorner2=commandStack.addItem(new CommandStackItem(CommandStackItem.CURVE_TO));
rightLine=commandStack.addItem(new CommandStackItem(CommandStackItem.LINE_TO));
bottomRightCorner1=commandStack.addItem(new CommandStackItem(CommandStackItem.CURVE_TO));
bottomRightCorner2=commandStack.addItem(new CommandStackItem(CommandStackItem.CURVE_TO));
bottomLine=commandStack.addItem(new CommandStackItem(CommandStackItem.LINE_TO));
bottomLeftCorner1=commandStack.addItem(new CommandStackItem(CommandStackItem.CURVE_TO));
bottomLeftCorner2=commandStack.addItem(new CommandStackItem(CommandStackItem.CURVE_TO));
leftLine=commandStack.addItem(new CommandStackItem(CommandStackItem.LINE_TO));
topLeftCorner1=commandStack.addItem(new CommandStackItem(CommandStackItem.CURVE_TO));
topLeftCorner2=commandStack.addItem(new CommandStackItem(CommandStackItem.CURVE_TO));
}
updateCommandStack();
invalidated = false;
}
}
/**
* Performs the specific layout work required by this Geometry.
* @param childBounds the bounds to be layed out. If not specified a rectangle
* of (0,0,1,1) is used.
**/
override public function calculateLayout(childBounds:Rectangle=null):void{
if(_layoutConstraint){
if (_layoutConstraint.invalidated){
var tempLayoutRect:Rectangle = new Rectangle(0,0,1,1);
if(_width){
tempLayoutRect.width = _width;
}
if(_height){
tempLayoutRect.height = _height;
}
if(_x){
tempLayoutRect.x = _x;
}
if(_y){
tempLayoutRect.y = _y;
}
super.calculateLayout(tempLayoutRect);
_layoutRectangle = _layoutConstraint.layoutRectangle;
if (isNaN(_width) || isNaN(_height)) {
//layout defined initial state
_width = layoutRectangle.width;
_height = layoutRectangle.height;
_x = layoutRectangle.x;
_y = layoutRectangle.y;
invalidated = true;
}
}
}
}
/**
* Begins the draw phase for geometry objects. All geometry objects
* override this to do their specific rendering.
*
* @param graphics The current context to draw to.
* @param rc A Rectangle object used for fill bounds.
**/
override public function draw(graphics:Graphics,rc:Rectangle):void{
//init the layout in this case done before predraw.
if(_layoutConstraint) calculateLayout();
//re init if required
if (invalidated) preDraw();
super.draw(graphics,(rc)? rc:bounds);
}
/**
* An object to derive this objects properties from. When specified this
* object will derive it's unspecified properties from the passed object.
**/
public function set derive(value:RoundedRectangle):void{
if (!fill){fill=value.fill;}
if (!stroke){stroke = value.stroke;}
if (!_x){_x = value.x;}
if (!_y){_y = value.y;}
if (!_width){_width = value.width;}
if (!_height){_height = value.height;}
if (!_cornerRadius) { _cornerRadius = value.cornerRadius; }
if (isNaN(_permitCornerInversion)) { _permitCornerInversion = value.permitCornerInversion?1:0; }
}
}
}

Some files were not shown because too many files have changed in this diff Show More