Rating Star
rating.mxml
<?xml version="1.0" encoding="utf-8"?>
<s:HGroup xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark" width="400" height="300"
mouseDown="onMouseDown(event)">
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
<fx:Metadata>
[Event("change")]
</fx:Metadata>
<fx:Script>
<![CDATA[
private var _value:int = 0;
private var valueInvalidatedFlag:Boolean = true;
private var lastShownValue:int = value;
public var editable:Boolean = false;
public function get value():int {
return _value;
}
[Bindable]
public function set value(val:int):void {
_value = val;
valueInvalidatedFlag = true;
invalidateProperties();
}
override protected function commitProperties():void {
if (valueInvalidatedFlag) {
valueInvalidatedFlag = false;
showRating(_value);
}
}
private function onMouseDown(event:MouseEvent):void {
if(!editable) {
return;
}
var local:Point = globalToLocal(new Point(event.stageX, event.stageY));
showRating(x2rating(local.x));
stage.addEventListener(MouseEvent.MOUSE_UP, onMouseUp);
stage.addEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
}
private function onMouseMove(event:MouseEvent):void {
var local:Point = globalToLocal(new Point(event.stageX, event.stageY));
if(local.x > -90 && local.x < 160 && local.y > -100 && local.y < 110) {
showRating(x2rating(local.x));
} else {
showRating(value);
}
}
private function onMouseUp(event:MouseEvent):void {
stage.removeEventListener(MouseEvent.MOUSE_UP, onMouseUp);
stage.removeEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
if (value != lastShownValue) {
value = lastShownValue;
dispatchEvent(new Event(Event.CHANGE));
}
}
private function x2rating(x:int):uint {
var r:int = (x - 1) / 10;
r = Math.max(0, Math.min(5, r));
return r;
}
private function showRating(value:int):void {
lastShownValue = value;
star1.styleName = (value >= 1) ? "RatingStar" : "RatingDot";
star2.styleName = (value >= 2) ? "RatingStar" : "RatingDot";
star3.styleName = (value >= 3) ? "RatingStar" : "RatingDot";
star4.styleName = (value >= 4) ? "RatingStar" : "RatingDot";
star5.styleName = (value >= 5) ? "RatingStar" : "RatingDot";
}
]]>
</fx:Script>
<s:BorderContainer id="star1" x="10" width="23" height="19" styleName="RatingDot"/>
<s:BorderContainer id="star2" x="20" width="23" height="19" styleName="RatingDot"/>
<s:BorderContainer id="star3" x="30" width="23" height="19" styleName="RatingDot"/>
<s:BorderContainer id="star4" x="40" width="23" height="19" styleName="RatingDot"/>
<s:BorderContainer id="star5" x="50" width="23" height="19" styleName="RatingDot"/>
</s:HGroup>
styles.css
.RatingDot {
backgroundImage: Embed("/assets/black_dot.png");
}
.RatingStar {
backgroundImage: Embed("/assets/black_star.png");
}
.Label {
fontColor: #000000;
}
global
{
selection-color: #d3d0d0;
content-background-color: #C9AD63;
chrome-color: #C7A11E;
}
main.mxml
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:rating="rating.*">
<fx:Style source="assets/styles.css">
</fx:Style>
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
<s:VGroup verticalAlign="middle" horizontalAlign="center">
<s:Label text="Click (or click and drag) to give a rating" styleName="Label"/>
<rating:Rating editable="true"/>
</s:VGroup>
</s:Application>