This is the example of rating component:
rating.mxml
<?xml version=”1.0″ encoding=”utf-8″?>
<mx:Application xmlns:mx=”http://www.adobe.com/2006/mxml” layout=”vertical”
xmlns=”com.Rating.*” horizontalAlign=”center” verticalAlign=”middle” >
<mx:Style>
Ratings{
horizontalGap:3;
paddingTop:3;
paddingLeft:6;
}
RatingItem{
borderAlpha:0;
fillEnabled:true;
fillColors:FFCC33,FFCC33;
fillSelectedColors:#FF9933,#FF9933;
fillAlphas:1,1;
fillRatios:0,255;
fillAngle:90;
}
</mx:Style>
<mx:Script>
<![CDATA[
import mx.controls.Alert;
import mx.events.*;
[Bindable] private var rate_number:Number;
private function handleChange(event:Event):void
{
rate_number=Number(event.currentTarget.value);
Alert.show(String(rate_number));
}
]]>
</mx:Script>
<Ratings id=”rateit” change=”handleChange(event);” horizontalGap=”3″
tooltips=”[‘Bad’,’Better’,’Average’,’Good’,’WOW!! +5′]”
value=”0″ width=”60″ height=”14″ x=”169″ y=”34″
points=”5″
innerRadius=”25″
outerRadius=”50″
angle=”90″
styleName=”example7″
/>
</mx:Application>
Here is the Components which we adding in our main file:
in folder com
Ratings.as
package com.Rating
{
import mx.core.UIComponent;
import flash.events.MouseEvent;
import flash.events.Event;
import mx.controls.dataGridClasses.DataGridListData;
import mx.controls.listClasses.BaseListData;
import mx.controls.listClasses.IDropInListItemRenderer;
import mx.controls.listClasses.IListItemRenderer;
import mx.core.IDataRenderer;
import mx.events.FlexEvent;
[Style(name=”horizontalGap”, type=”Number”, format=”Length”, inherit=”no”)]
[Style(name=”paddingLeft”, type=”Number”, format=”Length”, inherit=”no”)]
[Style(name=”paddingTop”, type=”Number”, format=”Length”, inherit=”no”)]
[Event(“change”)]
public class Ratings extends UIComponent implements IDataRenderer, IDropInListItemRenderer, IListItemRenderer
{
public function Ratings():void
{
//add the mouse move event listener so that we can update
//the display as the user moves out of the component capture both
//rollout and mouse out to ensure proper display updating
addEventListener(MouseEvent.MOUSE_OUT,handleMouseOut);
addEventListener(MouseEvent.ROLL_OUT,handleMouseOut);
//make sure we can get notified of the child events
mouseChildren = true;
}
/**
* Store the number of items to create.
**/
private const itemCount:Number =5;
private var contentWidth:Number=0;
/**
* Data storage.
**/
private var _data:Object;
[Bindable(“dataChange”)]
[Inspectable(environment=”none”)]
public function get data():Object
{
return _data;
}
public function set data(value:Object):void
{
_data = value;
try{
if (_listData && _listData is DataGridListData)
{
this.value = _data[DataGridListData(_listData).dataField];
}
else
{
this.value = int(_listData.label);
}
}
catch(e:Error){
this.value =0;
}
dispatchEvent(new FlexEvent(FlexEvent.DATA_CHANGE));
}
/**
* Storage for the listData property.
*/
private var _listData:BaseListData;
[Bindable(“dataChange”)]
public function get listData():BaseListData
{
return _listData;
}
public function set listData(value:BaseListData):void
{
_listData = value;
}
/**
* An array of tooltips for the rating items
**/
[Bindable]
[Inspectable]
private var _tooltips:Array = null;
public function set tooltips(value:Array):void
{
_tooltips = value;
}
public function get tooltips():Array
{
return _tooltips;
}
/**
* the value of the rating
**/
[Bindable(event=”change”)]
[Inspectable]
private var _value:int = 0;
public function set value(value:int):void
{
_value = value;
selectItems(value);
try{
if (_listData && _listData is DataGridListData)
{
_data[DataGridListData(_listData).dataField] = _value;
}
else
{
_listData.label = _value.toString();
}
}
catch(e:Error){
}
dispatchEvent(new Event(“change”));
}
public function get value():int
{
return _value;
}
[Bindable]
[Inspectable]
private var _outerRadius:Number=50;
public function set outerRadius(value:Number):void
{
_outerRadius = value;
updateChildren(“outerRadius”,value);
}
public function get outerRadius():Number
{
return _outerRadius;
}
[Bindable]
[Inspectable]
private var _innerRadius:Number=25;
public function set innerRadius(value:Number):void
{
_innerRadius = value;
updateChildren(“innerRadius”,value);
}
public function get innerRadius():Number
{
return _innerRadius;
}
[Bindable]
[Inspectable]
private var _points:Number=5;
public function set points(value:Number):void
{
_points = value;
updateChildren(“points”,value);
}
public function get points():Number
{
return _points;
}
[Bindable]
[Inspectable]
private var _angle:Number = 90;
public function set angle(value:Number):void
{
_angle = value;
updateChildren(“angle”,value);
}
public function get angle():Number
{
return _angle;
}
/**
* Update the children if the property changes.
**/
private function updateChildren(property:String, value:Number):void
{
for (var i:int = 1; i < itemCount+1; i++)
{
if (getChildByName(i.toString())){
RatingItem(getChildByName(i.toString()))[property]=value;
}
}
}
/**
* Add the star objects for rating and set thier properties and
* add the event listener for rollover and click
**/
override protected function childrenCreated():void
{
//use the horizontal Gap style for spacing between items
var horizontalGap:Number = getStyle(“horizontalGap”);
var paddingLeft:Number = getStyle(“paddingLeft”);
var paddingTop:Number = getStyle(“paddingTop”);
var lastX:Number = 0;
//create each item, set the properties, and add the listeners.
for (var i:int = 1; i < itemCount+1; i++)
{
var newItem:RatingItem = new RatingItem();
newItem.id = (i).toString();
newItem.name =(i).toString();
//if the tooltips are set apply it to the primitive
if (tooltips)
{
if (tooltips.length >(i-1)){
newItem.toolTip = tooltips[i-1].toString();
}
}
//set the default width and height
newItem.width = 12;
newItem.height = 12;
addChild(newItem);
if (lastX == 0)
{
newItem.x=paddingLeft;
}
else
{
newItem.x= ((12+horizontalGap)+lastX);
}
lastX = newItem.x;
newItem.y= paddingTop;
//set the inicial value based on this value
if ((i-1) < value)
{
newItem.selected = true;
}
newItem.addEventListener(MouseEvent.CLICK,handleItemClick,false,1);
newItem.addEventListener(MouseEvent.ROLL_OVER,handleMouseRoll);
newItem.addEventListener(MouseEvent.ROLL_OUT,handleMouseRoll);
}
width=newItem.x+horizontalGap;
height = 12;
}
override protected function updateDisplayList(unscaledWidth:Number,unscaledHeight:Number):void
{
super.updateDisplayList(unscaledWidth,unscaledHeight);
//draw a transparent background so we can get the
//rollout/over event on the ui object in not doing
//this we’ll get flashing when moving between items
graphics.lineStyle(0,0xFFFFFF,0);
graphics.beginFill(0xFFFFFF,0);
graphics.drawRect(0,0,unscaledWidth,unscaledHeight);
graphics.endFill();
}
//do the selection based on passed value
private function selectItems(value:Number):void{
//make sure items are selected up to the target name
//and any items after are not selected
var currentItem:RatingItem;
for (var i:int = 1; i < itemCount+1; i++)
{
currentItem = RatingItem(getChildByName(i.toString()));
if (currentItem)
{
if (i <= value)
{
//selected
currentItem.selected = true;
}
else
{
//not selected
currentItem.selected = false;
}
}
}
}
private function handleMouseRoll(event:MouseEvent):void{
selectItems(Number(event.currentTarget.name));
}
private function handleMouseOut(event:MouseEvent):void{
if (event.currentTarget is Ratings)
{
selectItems(value);
}
}
/**
* handle the click and dispatch the event
**/
private function handleItemClick(event:MouseEvent):void
{
//prevent the default and stop the propogation
//so that the base class does not select it.
event.preventDefault();
event.stopImmediatePropagation();
if (event.currentTarget.id == 1 && value == 1){
value=0;
}
else{
value= Number(event.currentTarget.id);
}
dispatchEvent(event);
}
}
}
RatingItem.as
package com.Rating
{
import com.Primitives.PrimitiveStar;
/**
* Add any specific things you require here for your rating component.
**/
public class RatingItem extends PrimitiveStar
{
public function RatingItem()
{
super();
}
}
}
in folder Primitives
This folder incudes 4 files
BasePrimitive.as
package com.Primitives
{
import flash.display.GradientType;
import flash.display.SpreadMethod;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.geom.*;
import mx.controls.dataGridClasses.DataGridListData;
import mx.controls.listClasses.BaseListData;
import mx.controls.listClasses.IDropInListItemRenderer;
import mx.controls.listClasses.IListItemRenderer;
import mx.core.EdgeMetrics;
import mx.core.IDataRenderer;
import mx.core.IFlexDisplayObject;
import mx.core.UIComponent;
import mx.core.mx_internal;
import mx.events.FlexEvent;
import mx.managers.IFocusManagerComponent;
use namespace mx_internal;
include “PrimitiveStyles.as”;
public class BasePrimitive extends UIComponent
implements IDataRenderer, IDropInListItemRenderer,
IFocusManagerComponent, IListItemRenderer
{
public var selectedField:String = null;
private var selectedSet:Boolean;
private var styleChangedFlag:Boolean = true;
public function BasePrimitive()
{
mouseChildren = false;
//setup the events
addEventListener(MouseEvent.ROLL_OVER, rollOverHandler);
addEventListener(MouseEvent.ROLL_OUT, rollOutHandler);
addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
addEventListener(MouseEvent.CLICK, clickHandler);
addEventListener(FlexEvent.UPDATE_COMPLETE, handleUpdateComplete);
}
private var toolTipSet:Boolean = false;
[Inspectable(category=”General”, defaultValue=”null”)]
override public function set toolTip(value:String):void
{
super.toolTip = value;
if (value)
{
toolTipSet = true;
}
else
{
toolTipSet = false;
invalidateDisplayList();
}
}
mx_internal var _selected:Boolean = false;
[Bindable(“click”)]
[Bindable(“valueCommit”)]
[Inspectable(category=”General”, defaultValue=”false”)]
public function get selected():Boolean
{
return _selected;
}
public function set selected(value:Boolean):void
{
selectedSet = true;
setSelected(value);
}
mx_internal function setSelected(value:Boolean):void
{
if (_selected != value)
{
_selected = value;
invalidateDisplayList();
if (toggle)
dispatchEvent(new Event(Event.CHANGE));
dispatchEvent(new FlexEvent(FlexEvent.VALUE_COMMIT));
}
}
mx_internal var _toggle:Boolean = false;
mx_internal var toggleChanged:Boolean = false;
[Bindable(“toggleChanged”)]
[Inspectable(category=”General”, defaultValue=”false”)]
public function get toggle():Boolean
{
return _toggle;
}
public function set toggle(value:Boolean):void
{
_toggle = value;
toggleChanged = true;
invalidateProperties();
invalidateDisplayList();
dispatchEvent(new Event(“toggleChanged”));
}
private var _data:Object;
[Bindable(“dataChange”)]
[Inspectable(environment=”none”)]
public function get data():Object
{
if (!_data)
_data = {};
return _data;
}
public function set data(value:Object):void
{
var newSelected:*;
_data = value;
if (_listData && _listData is DataGridListData)
{
newSelected = _data[DataGridListData(_listData).dataField];
}
else if (_listData)
{
if (selectedField)
newSelected = _data[selectedField];
}
else
{
newSelected = _data;
}
if (newSelected !== undefined && !selectedSet)
{
selected = newSelected as Boolean;
selectedSet = false;
}
dispatchEvent(new FlexEvent(FlexEvent.DATA_CHANGE));
}
/**
* Storage for the listData property.
*/
private var _listData:BaseListData;
[Bindable(“dataChange”)]
[Inspectable(environment=”none”)]
public function get listData():BaseListData
{
return _listData;
}
public function set listData(value:BaseListData):void
{
_listData = value;
}
/***
* Some extensions of this class may be required to not have a background drawn,
* so this provides and ability to specify that via the constructor
* of the extending class.
**/
private var _backgroundEnabled:Boolean = true;
public function set backgroundEnabled(value:Boolean):void
{
_backgroundEnabled = value;
invalidateProperties();
invalidateDisplayList();
}
public function get backgroundEnabled():Boolean
{
return _backgroundEnabled;
}
override public function styleChanged(styleProp:String):void
{
styleChangedFlag = true;
super.styleChanged(styleProp);
invalidateProperties();
invalidateDisplayList();
}
/**
* Events Handlers
**/
protected function rollOverHandler(event:MouseEvent):void
{
//trace(event);
}
protected function rollOutHandler(event:MouseEvent):void
{
//trace(event);
}
protected function mouseDownHandler(event:MouseEvent):void
{
//trace(event);
}
protected function mouseUpHandler(event:MouseEvent):void
{
//trace(event);
}
protected function clickHandler(event:MouseEvent):void
{
selected = !selected;
//trace(event);
}
/**
* End any fill or gradient fill drawing actions on this event
* so that the classes extending this one can do their specific
* drawing to the surface.
**/
private function handleUpdateComplete(event:FlexEvent):void
{
//End the fill always for each extension, since all common drawing is done in the
//base class. Including fills.
if (backgroundEnabled)
{
graphics.endFill();
}
}
override protected function updateDisplayList(unscaledWidth:Number,unscaledHeight:Number):void
{
super.updateDisplayList(unscaledWidth,unscaledHeight);
//clear the drawing surface.
graphics.clear();
/**
* Setup the line styles as required.
**/
//get the border color
var borderColor:uint;
if (!selected)
{
borderColor = getStyle(“borderColor”);
}
else
{
borderColor = getStyle(“borderSelectedColor”);
}
if (borderColor ==0)
{
borderColor = 0x000000;
}
var borderThickness:Number = getStyle(“borderThickness”);
var borderAlpha:Number = getStyle(“borderAlpha”);
var borderPixelHinting:Boolean = getStyle(“borderPixelHinting”);
var borderJointStyle:String = getStyle(“borderJointStyle”);
graphics.lineStyle(borderThickness,borderColor,borderAlpha,borderPixelHinting,”normal”,null,borderJointStyle);
if (getStyle(“borderFillEnabled”))
{
var borderColors:Array
if (!selected)
{
borderColors = getStyle(“borderColors”);
}
else
{
borderColors = getStyle(“borderSelectedColors”);
}
var borderAlphas:Array = getStyle(“borderAlphas”);
var borderRatios:Array = getStyle(“borderRatios”);
if (borderColors == null)
{
borderColors=[0x000000,0xFFFFFF];
}
if (borderAlphas == null)
{
borderAlphas=[1,1];
}
if (borderRatios == null)
{
borderRatios=[0,255];
}
var borderFillType:String = getStyle(“borderFillType”);
var borderSpreadMethod:String = getStyle(“borderSpreadMethod”);
var borderFocalPointRatio:Number = getStyle(“borderFocalPointRatio”);
var borderAngle:Number = getStyle(“borderAngle”);
if (!borderAngle)
{
borderAngle =0;
}
if (!borderFillType)
{
borderFillType = “linear”;
}
if (!borderSpreadMethod)
{
borderSpreadMethod = “pad”;
}
var borderMatrix:Matrix = new Matrix();
borderMatrix.createGradientBox(unscaledWidth,unscaledHeight,borderAngle, 0, 0);
graphics.lineGradientStyle(borderFillType, borderColors, borderAlphas, borderRatios, borderMatrix,borderSpreadMethod,”rgb”,borderFocalPointRatio);
}
//If fillcolors is set then use a gradient.
if (getStyle(“fillEnabled”) && backgroundEnabled)
{
var fillColors:Array;
if (!selected){
fillColors = getStyle(“fillColors”);
}
else{
fillColors = getStyle(“fillSelectedColors”);
}
var fillAlphas:Array = getStyle(“fillAlphas”);
var fillRatios:Array = getStyle(“fillRatios”);
if (fillColors == null)
{
fillColors=[0x000000,0xFFFFFF];
}
if (fillAlphas == null)
{
fillAlphas=[1,1];
}
if (fillRatios == null)
{
fillRatios=[0,255];
}
var fillType:String = getStyle(“fillType”);
var fillSpreadMethod:String = getStyle(“fillSpreadMethod”);
var fillFocalPointRatio:Number = getStyle(“fillFocalPointRatio”);
var fillAngle:Number = getStyle(“fillAngle”);
if (!fillAngle)
{
fillAngle =0;
}
if (!fillType)
{
fillType = “linear”;
}
if (!fillSpreadMethod)
{
fillSpreadMethod = “pad”;
}
var fillMatrix:Matrix = new Matrix();
fillMatrix.createGradientBox(unscaledWidth,unscaledHeight,fillAngle, 0, 0);
graphics.beginGradientFill(fillType, fillColors, fillAlphas, fillRatios, fillMatrix,SpreadMethod.REFLECT,”rgb”,fillFocalPointRatio);
}
else
{
if (backgroundEnabled){
var backgroundColor:uint;
if (!selected)
{
backgroundColor= getStyle(“backgroundColor”);
}
else
{
backgroundColor= getStyle(“backgroundSelectedColor”);
}
var backgroundAlpha:Number = getStyle(“backgroundAlpha”);
if (backgroundColor !=0)
{
graphics.beginFill(backgroundColor,backgroundAlpha);
}
}
}
}
}
}
DrawUtils.as
/**
* DrawUtils is a static class that provides a number of functions
* to draw shapes that are not part of the standard ActionScript Drawing
* API.
*
* based on source code found at:
* http://www.macromedia.com/devnet/mx/flash/articles/adv_draw_methods.html
*
* @author Ric Ewing – version 1.4 – 4.7.2002
* @author Kevin Williams – version 2.0 – 4.7.2005
* @author Jason Hawryluk – version 3.0 – 22.02.2007
* -Modified for Flex 2.01
*/
package com.Primitives
{
import mx.core.UIComponent;
public class DrawUtils
{
public static function dashLineToPattern(target:UIComponent, x1:Number, y1:Number,x2:Number, y2:Number,pattern:Array):void
{
var x:Number = x2 – x1;
var y:Number = y2 – y1;
var hyp:Number = Math.sqrt((x)*(x) + (y)*(y));
var units:Number = hyp/(pattern[0]+pattern[1]);
var dashSpaceRatio:Number = pattern[0]/(pattern[0]+pattern[1]);
var dashX:Number = (x/units)*dashSpaceRatio;
var spaceX:Number = (x/units)-dashX;
var dashY:Number = (y/units)*dashSpaceRatio;
var spaceY:Number = (y/units)-dashY;
target.graphics.moveTo(x1, y1);
while (hyp > 0)
{
x1 += dashX;
y1 += dashY;
hyp -= pattern[0];
if (hyp < 0)
{
x1 = x2;
y1 = y2;
}
target.graphics.lineTo(x1, y1);
x1 += spaceX;
y1 += spaceY;
target.graphics.moveTo(x1, y1);
hyp -= pattern[1];
}
target.graphics.moveTo(x2, y2);
}
/**
* Draws an arc from the starting position of x,y.
**/
public static function arcTo(target:UIComponent, x:Number, y:Number, startAngle:Number, arc:Number, radius:Number,yRadius:Number):void
{
var ax:Number;
var ay:Number;
// Circumvent drawing more than is needed
if (Math.abs(arc)>360)
{
arc = 360;
}
// Draw in a maximum of 45 degree segments. First we calculate how many
// segments are needed for our arc.
var segs:Number = Math.ceil(Math.abs(arc)/45);
// Now calculate the sweep of each segment
var segAngle:Number = arc/segs;
// The math requires radians rather than degrees. To convert from degrees
// use the formula (degrees/180)*Math.PI to get radians.
var theta:Number = -(segAngle/180)*Math.PI;
// convert angle startAngle to radians
var angle:Number = -(startAngle/180)*Math.PI;
// find our starting points (ax,ay) relative to the secified x,y
ax = x-Math.cos(angle)*radius;
ay = y-Math.sin(angle)*yRadius;
// Draw as 45 degree segments
if (segs>0)
{
target.graphics.moveTo(x,y);
// Loop for drawing arc segments
for (var i:int = 0; i<segs; i++)
{
// increment our angle
angle += theta;
//find the angle halfway between the last angle and the new one,
//calculate our end point, our control point, and draw the arc segment
target.graphics.curveTo(ax+Math.cos(angle-(theta/2))*(radius/Math.cos(theta/2)),
ay+Math.sin(angle-(theta/2))*(yRadius/Math.cos(theta/2)),
ax+Math.cos(angle)*radius, ay+Math.sin(angle)*yRadius);
}
}
}
/**
* Burst is a method for drawing star bursts.
*/
public static function burst(target:UIComponent, x:Number, y:Number,points:Number, innerRadius:Number, outerRadius:Number,angle:Number=0 ):void
{
if (points >=2)
{
// calculate length of sides
var step:Number = (Math.PI*2)/points;
var halfStep:Number = step/2;
var qtrStep:Number = step/4;
// calculate starting angle in radians
var start:Number = (angle/180)*Math.PI;
target.graphics.moveTo(x+(Math.cos(start)*outerRadius), y-(Math.sin(start)*outerRadius));
// draw curves
for (var i:int=1; i<=points; i++)
{
target.graphics.curveTo(x+Math.cos(start+(step*i)-(qtrStep*3))*(innerRadius/Math.cos(qtrStep)),
y-Math.sin(start+(step*i)-(qtrStep*3))*(innerRadius/Math.cos(qtrStep)),
x+Math.cos(start+(step*i)-halfStep)*innerRadius,
y-Math.sin(start+(step*i)-halfStep)*innerRadius);
target.graphics.curveTo(x+Math.cos(start+(step*i)-qtrStep)*(innerRadius/Math.cos(qtrStep)),
y-Math.sin(start+(step*i)-qtrStep)*(innerRadius/Math.cos(qtrStep)),
x+Math.cos(start+(step*i))*outerRadius,
y-Math.sin(start+(step*i))*outerRadius);
}
}
}
/**
* Draws a gear shape on the target. The gear position
* is indicated by the x and y arguments.
*/
public static function gear(target:UIComponent, x:Number, y:Number, points:Number, innerRadius:Number, outerRadius:Number, angle:Number=0, holeSides:Number=0, holeRadius:Number=0 ):void
{
if (points>=2)
{
// calculate length of sides
var step:Number = (Math.PI*2)/points;
var qtrStep:Number = step/4;
// calculate starting angle in radians
var start:Number = (angle/180)*Math.PI;
target.graphics.moveTo(x+(Math.cos(start)*outerRadius), y-(Math.sin(start)*outerRadius));
// draw lines
for (var i:int=1; i<=points; i++)
{
target.graphics.lineTo(x+Math.cos(start+(step*i)-(qtrStep*3))*innerRadius,
y-Math.sin(start+(step*i)-(qtrStep*3))*innerRadius);
target.graphics.lineTo(x+Math.cos(start+(step*i)-(qtrStep*2))*innerRadius,
y-Math.sin(start+(step*i)-(qtrStep*2))*innerRadius);
target.graphics.lineTo(x+Math.cos(start+(step*i)-qtrStep)*outerRadius,
y-Math.sin(start+(step*i)-qtrStep)*outerRadius);
target.graphics.lineTo(x+Math.cos(start+(step*i))*outerRadius,
y-Math.sin(start+(step*i))*outerRadius);
}
if (holeSides>=2)
{
if(holeRadius == 0)
{
holeRadius = innerRadius/3;
}
step = (Math.PI*2)/holeSides;
target.graphics.moveTo(x+(Math.cos(start)*holeRadius), y-(Math.sin(start)*holeRadius));
for (var j:int=1; j<=holeSides; j++)
{
target.graphics.lineTo(x+Math.cos(start+(step*j))*holeRadius,
y-Math.sin(start+(step*j))*holeRadius);
}
}
}
}
/**
* A method for creating polygon shapes.
*/
public static function polygon(target:UIComponent, x:Number, y:Number, points:Number, radius:Number, angle:Number=0):void
{
// convert sides to positive value
var count:int = Math.abs(points);
if (count>=2)
{
// calculate span of sides
var step:Number = (Math.PI*2)/points;
// calculate starting angle in radians
var start:Number = (angle/180)*Math.PI;
target.graphics.moveTo(x+(Math.cos(start)*radius), y-(Math.sin(start)*radius));
// draw the polygon
for (var i:int=1; i<=count; i++)
{
target.graphics.lineTo(x+Math.cos(start+(step*i))*radius,
y-Math.sin(start+(step*i))*radius);
}
}
}
/**
* Star draws a star shaped polygon.
*/
public static function star(target:UIComponent, x:Number, y:Number, points:Number, innerRadius:Number, outerRadius:Number,angle:Number=0 ):void
{
var count:int = Math.abs(points);
if (count>=2)
{
// calculate distance between points
var step:Number = (Math.PI*2)/points;
var halfStep:Number = step/2;
// calculate starting angle in radians
var start:Number = (angle/180)*Math.PI;
target.graphics.moveTo(x+(Math.cos(start)*outerRadius), y-(Math.sin(start)*outerRadius));
// draw lines
for (var i:int=1; i<=count; i++)
{
target.graphics.lineTo(x+Math.cos(start+(step*i)-halfStep)*innerRadius,
y-Math.sin(start+(step*i)-halfStep)*innerRadius);
target.graphics.lineTo(x+Math.cos(start+(step*i))*outerRadius,
y-Math.sin(start+(step*i))*outerRadius);
}
}
}
/**
* draws pie shaped wedge.
*/
public static function wedge(target:UIComponent, x:Number, y:Number, startAngle:Number, arc:Number, radius:Number,yRadius:Number):void
{
// move into position
target.graphics.moveTo(x, y);
// limit sweep to reasonable numbers
if (Math.abs(arc)>360)
{
arc = 360;
}
// Draw in a maximum of 45 degree segments. First we calculate how
// many segments are needed for our arc.
var segs:Number = Math.ceil(Math.abs(arc)/45);
// Now calculate the sweep of each segment.
var segAngle:Number = arc/segs;
// The math requires radians rather than degrees. To convert from degrees
// use the formula (degrees/180)*Math.PI to get radians.
var theta:Number =-(segAngle/180)*Math.PI;
// convert angle startAngle to radians
var angle:Number =-(startAngle/180)*Math.PI;
// draw the curve in segments no larger than 45 degrees.
if (segs>0)
{
// draw a line from the center to the start of the curve
target.graphics.lineTo(x+Math.cos(startAngle/180*Math.PI)*radius,
y+Math.sin(-startAngle/180*Math.PI)*yRadius);
//draw curve segments
for (var i:int = 0; i<segs; i++)
{
angle += theta;
var angleMid:Number = angle-(theta/2);
target.graphics.curveTo(x+Math.cos(angleMid)*(radius/Math.cos(theta/2)),
y+Math.sin(angleMid)*(yRadius/Math.cos(theta/2)),
x+Math.cos(angle)*radius, y+Math.sin(angle)*yRadius);
}
//close the wedge by drawing a line to the center
target.graphics.lineTo(x, y);
}
}
}
}
PrimitiveStar.as
package com.Primitives
{
import mx.core.UIComponent;
import com.Primitives.DrawUtils;
import com.Primitives.BasePrimitive;
public class PrimitiveStar extends BasePrimitive
{
public function PrimitiveStar():void
{
super();
}
[Bindable]
[Inspectable]
private var _outerRadius:Number=50;
public function set outerRadius(value:Number):void
{
_outerRadius = value;
invalidateProperties();
invalidateDisplayList();
}
public function get outerRadius():Number
{
return _outerRadius;
}
[Bindable]
[Inspectable]
private var _innerRadius:Number=25;
public function set innerRadius(value:Number):void
{
_innerRadius = value;
invalidateProperties();
invalidateDisplayList();
}
public function get innerRadius():Number
{
return _innerRadius;
}
[Bindable]
[Inspectable]
private var _points:Number=5;
public function set points(value:Number):void
{
_points = value;
invalidateProperties();
invalidateDisplayList();
}
public function get points():Number
{
return _points;
}
[Bindable]
[Inspectable]
private var _angle:Number = 90;
public function set angle(value:Number):void
{
_angle = value;
invalidateProperties();
invalidateDisplayList();
}
public function get angle():Number
{
return _angle;
}
override protected function updateDisplayList(unscaledWidth:Number,unscaledHeight:Number):void
{
super.updateDisplayList(unscaledWidth,unscaledHeight);
//get the ratio of the difference for the inner and outer radius
var ratio:Number= outerRadius/innerRadius;
//use the smallest of the width and height to do the
//size so we can use as much space as possible
var maxSize:Number = Math.min(unscaledHeight, unscaledWidth);
DrawUtils.star(this,unscaledWidth/2,unscaledHeight/2,points,(maxSize/2)/ratio,(maxSize/2),angle);
}
}
}
PrimitiveStyles.as
//background
[Style(name=”backgroundAlpha”, type=”Number”, inherit=”no”)]
[Style(name=”backgroundColor”, type=”uint”, format=”Color”, inherit=”no”)]
[Style(name=”backgroundSelectedColor”, type=”uint”, format=”Color”, inherit=”no”)]
//border
[Style(name=”borderColor”, type=”uint”, format=”Color”, inherit=”no”)]
[Style(name=”borderThickness”, type=”Number”, format=”Length”, inherit=”no”)]
[Style(name=”borderAlpha”, type=”Number”, inherit=”no”)]
[Style(name=”borderPixelHinting”, type=”Boolean”, inherit=”no”)]
[Style(name=”borderJointStyle”, type=”String”, enumeration=”bevel,miter,round”, inherit=”no”)]
[Style(name=”borderSelectedColor”, type=”uint”, format=”Color”, inherit=”no”)]
//border gradient
[Style(name=”borderFillEnabled”, type=”Boolean”,enumeration=”true,false”, inherit=”no”)]
[Style(name=”borderRatios”, type=”Array”, arrayType=”Number”, inherit=”no”)]
[Style(name=”borderFillType”, type=”string”,enumeration=”linear,radial”, inherit=”no”)]
[Style(name=”borderSpreadMethod”, type=”string”,enumeration=”pad,reflect,repeat”, inherit=”no”)]
[Style(name=”borderFocalPointRatio”, type=”Number”, inherit=”no”)]
[Style(name=”borderAlphas”, type=”Array”,arrayType=”Number”, inherit=”no”)]
[Style(name=”borderColors”, type=”Array”, arrayType=”uint”, format=”Color”, inherit=”no”)]
[Style(name=”borderSelectedColors”, type=”Array”, arrayType=”uint”, format=”Color”, inherit=”no”)]
[Style(name=”borderAngle”, type=”Number”, inherit=”no”)]
//fill gradient
[Style(name=”fillEnabled”, type=”Boolean”,enumeration=”true,false”, inherit=”no”)]
[Style(name=”fillRatios”, type=”Array”, arrayType=”Number”, inherit=”no”)]
[Style(name=”fillType”, type=”string”,enumeration=”linear,radial”, inherit=”no”)]
[Style(name=”fillSpreadMethod”, type=”string”,enumeration=”pad,reflect,repeat”, inherit=”no”)]
[Style(name=”fillFocalPointRatio”, type=”Number”, inherit=”no”)]
[Style(name=”fillAlphas”, type=”Array”, arrayType=”Number”, inherit=”no”)]
[Style(name=”fillColors”, type=”Array”, arrayType=”uint”, format=”Color”, inherit=”no”)]
[Style(name=”fillSelectedColors”, type=”Array”, arrayType=”uint”, format=”Color”, inherit=”no”)]
[Style(name=”fillAngle”, type=”Number”, inherit=”no”)]
These all above files are needed to do Rating things in Flex.
🙂