向上按钮:
//package
//{
// public class VerticalUpButton extends Button
// {
// public function VerticalUpButton($text:String="button")
// {
// super($text);
// }
// }
//}
package
{
public class VerticalUpButton extends Button
{
public function VerticalUpButton()
{
super();
width=10;
height=10;
}
protected override function refreshBackground():void
{
//super.refreshBackground();
//背景也居中
this.graphics.clear();
this.graphics.beginFill(0x55aa00, 0.5);
this.graphics.drawRect(0,0,10,10);
this.graphics.endFill();
//边框
this.graphics.moveTo(0,0);
this.graphics.lineStyle(1,0,.5);
this.graphics.lineTo(10,0);
this.graphics.lineTo(10,10);
this.graphics.lineTo(0,10);
this.graphics.lineTo(0,0);
//三角形
this.graphics.moveTo(5,2);
this.graphics.lineStyle(1,0,.5);
this.graphics.lineTo(8,8);
this.graphics.lineTo(2,8);
this.graphics.lineTo(5,2);
}
}
}
向下按钮类:
//package
//{
// public class VerticalDownButton
// {
// public function VerticalDownButton()
// {
// }
// }
//}
package
{
public class VerticalDownButton extends Button
{
public function VerticalDownButton()
{
super();
width=10;
height=10;
}
protected override function refreshBackground():void
{
//super.refreshBackground();
//背景也居中
this.graphics.clear();
this.graphics.beginFill(0x55aa00, 0.5);
this.graphics.drawRect(0,0,10,10);
this.graphics.endFill();
//边框
this.graphics.moveTo(0,0);
this.graphics.lineStyle(1,0,.5);
this.graphics.lineTo(10,0);
this.graphics.lineTo(10,10);
this.graphics.lineTo(0,10);
this.graphics.lineTo(0,0);
//三角形
this.graphics.moveTo(5,8);
this.graphics.lineStyle(1,0,.5);
this.graphics.lineTo(8,2);
this.graphics.lineTo(2,2);
this.graphics.lineTo(5,8);
}
}
}
整个垂直滚动条组件:
//package
//{
// public class VerticalScroller extends Control
// {
// public function VerticalScroller()
// {
// super();
// }
// }
//}
package
{
import controlsEvents.ScrollerEvent;
import flash.display.Shape;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.filters.GlowFilter;
import flash.geom.Point;
import flash.utils.getTimer;
/**
* 垂直滚动条
* (纯graphics控件,后期可能要考虑开放更多的一些重绘制接口:方便外部的写重绘制这部分)
* @author Jave.Lin
*/
public class VerticalScroller extends Control
{
private var _upBtn:VerticalUpButton;//向上的按钮--减量操作
private var _downBtn:VerticalDownButton;//向右的按钮--增量操作
private var _rollPacker:ScrollPacker;//滚动器
private var _buttonInterval:Number=20;
private var _curValue:int=0;//当前值
private var _minValue:int=0;//最小值
private var _maxValue:int=100;//最大值
private var _increment:int=5;//每次操作的增/减量
private var _isAdding:Boolean=false;
//续持性快速操作的控件参数
private var _quickCurTime:int=0;
private var _quickOperateTime:int=0;
private var _quickOperateTimeMax:int=500;
private var _maxPos:Number;//滚动器最远的距离
private var _curVisibleRate:Number=1;//当前可视范围比率,直接影响滚动器的宽度
public function get curVisibleRate():Number
{
return _curVisibleRate;
}
public function set curVisibleRate(value:Number):void
{
if(_curVisibleRate!=value)
{
_curVisibleRate=value;
if(_curVisibleRate<=0)_curVisibleRate=0;
if(_curVisibleRate >=1)_curVisibleRate=1;
onLayout();
}
}
public function get maxValue():int
{
return _maxValue;
}
public function set maxValue(value:int):void
{
if(_maxValue!=value)
{
if(_minValue>value)throw new Error("HorizontalScroller maxValue less then minValue error! maxValue:"+value+" minValue:"+_minValue);
_maxValue=value;
if(curValue>_maxValue)curValue=_maxValue;
}
}
public function get minValue():int
{
return _minValue;
}
public function set minValue(value:int):void
{
if(_minValue!=value)
{
if(value>_maxValue)throw new Error("HorizontalScroller minValue more then maxValue error! minValue:"+value+" maxValue:"+_maxValue);
_minValue=value;
if(curValue<_minValue)curValue=_minValue;
}
}
public function get curValue():int
{
return _curValue;
}
public function set curValue(value:int):void
{
if(_curVisibleRate>=1)return;
if(_curValue!=value)
{
var preValue:int=value;
if(preValue<_minValue)preValue=_minValue;
else if(preValue>_maxValue)preValue=_maxValue;
if(preValue!=_curValue)
{
_curValue=preValue;
if(_minValue==_maxValue)
{
_rollPacker.y=fixAndSetRollPackerY(_upBtn.height);
}
else
{
_rollPacker.y=fixAndSetRollPackerY(_upBtn.height+(_buttonInterval-_rollPacker.height)*((_curValue-_minValue)/(_maxValue-_minValue)));
}
dispatchEvent(new ScrollerEvent(ScrollerEvent.VALUE_CHANGED,_curValue));
}
}
}
public override function get width():Number
{
return super.width;
}
public override function get height():Number
{
if(isNaN(_h))
{
_h=super.height;
}
return _h;
}
public override function set height(value:Number):void
{
if(_h!=value)
{
var sourceBI:Number=_buttonInterval;
var sumH:Number=_upBtn.height+_downBtn.height;
_buttonInterval=value-sumH;
if(_h<value)
{
_h=value;
if(_buttonInterval<10)
{
_buttonInterval=10;
_h=sumH+_buttonInterval;
}
}
else
{
_h=value;
}
refreshBackground();
onLayout();
}
}
public function VerticalScroller()
{
super();
}
private function fixAndSetRollPackerY(prePos:Number):Number
{
if(prePos<_upBtn.height)prePos=_upBtn.height;
else if(prePos>_maxPos)prePos=_maxPos;
return prePos;
}
private function yTransformToValueAndSetIt(prePos:Number):void
{
if(_curVisibleRate>=1)return;
if(_rollPacker.y==prePos)
{
return;
}
curValue=(prePos-_upBtn.height)/(_maxPos-_upBtn.height)*(_maxValue-_minValue)+_minValue;
}
protected override function initialize():void
{
_upBtn=new VerticalUpButton();
addChild(_upBtn);
_rollPacker=new ScrollPacker();
addChild(_rollPacker);
_downBtn=new VerticalDownButton();
addChild(_downBtn);
if(stage)
{
onAddedToStageHandler();
}
else
{
addEventListener(Event.ADDED_TO_STAGE,onAddedToStageHandler);
}
this.width=_upBtn.width;
this.height=100;
onLayout();
refreshBackground();
}
private function onLayout():void
{
_upBtn.x=0;
_upBtn.y=0;
_rollPacker.x=0;
_rollPacker.y=_upBtn.height;
_rollPacker.height=(1-_curVisibleRate)*_buttonInterval;
_rollPacker.width=_upBtn.width;
_downBtn.x=0;
_downBtn.y=_upBtn.y+_upBtn.height+_buttonInterval;
_maxPos=_upBtn.height+_buttonInterval-_rollPacker.height;
}
private function onAddedToStageHandler(e:Event=null):void
{
removeEventListener(Event.ADDED_TO_STAGE,onAddedToStageHandler);
addEventListener(Event.REMOVED_FROM_STAGE,onRemovedFromStageHandler);
_upBtn.addEventListener(MouseEvent.CLICK,onUpBtnMouseClickHandler);
_upBtn.addEventListener(MouseEvent.MOUSE_OUT,onUpBtnMouseOutHandler);
_upBtn.addEventListener(MouseEvent.MOUSE_DOWN,onUpBtnMouseDownHandler);
_upBtn.addEventListener(MouseEvent.MOUSE_UP,onUpBtnMouseUpHandler);
_downBtn.addEventListener(MouseEvent.CLICK,onDownBtnMouseClickHandler);
_downBtn.addEventListener(MouseEvent.MOUSE_OUT,onDownBtnMouseOutHandler);
_downBtn.addEventListener(MouseEvent.MOUSE_DOWN,onDownBtnMouseDownHandler);
_downBtn.addEventListener(MouseEvent.MOUSE_UP,onDownBtnMouseUpHandler);
_rollPacker.addEventListener(MouseEvent.MOUSE_DOWN,onRollPackerMouseDownHandler);
}
//鼠标点下滚动器时,滚动器的备份坐标
private var _mouseDownRollPackerSourceY:Number=0;
//鼠标点下滚动器时,相对舞台的鼠标x坐标
private var _mouseDownStageMouseSourceY:Number=0;
//鼠标点下滚动器时,相对舞台的上一次的鼠标x坐标
private var _lastStageMouseY:Number=0;
private function onStageEnterFrameHandler(e:Event):void
{
if(_lastStageMouseY!=stage.mouseY)
{
yTransformToValueAndSetIt(fixAndSetRollPackerY(_mouseDownRollPackerSourceY+(stage.mouseY-_mouseDownStageMouseSourceY)));
_lastStageMouseY=stage.mouseY;
}
}
private function onStageMouseUpHandler(e:MouseEvent):void
{
stage.removeEventListener(Event.ENTER_FRAME,onStageEnterFrameHandler);
_rollPacker.addEventListener(MouseEvent.MOUSE_DOWN,onRollPackerMouseDownHandler);
}
private function onRollPackerMouseDownHandler(e:MouseEvent):void
{
_mouseDownRollPackerSourceY=_rollPacker.y;
_mouseDownStageMouseSourceY=stage.mouseY;
_rollPacker.removeEventListener(MouseEvent.MOUSE_DOWN,onRollPackerMouseDownHandler);
stage.addEventListener(Event.ENTER_FRAME,onStageEnterFrameHandler);
stage.addEventListener(MouseEvent.MOUSE_UP,onStageMouseUpHandler);
}
private function onDownBtnMouseClickHandler(e:MouseEvent):void
{
if(_curVisibleRate>=1)return;
curValue+=_increment;
}
private function onDownBtnMouseUpHandler(e:MouseEvent):void
{
removeEventListener(Event.ENTER_FRAME,onEnterFrameHandler);
_quickOperateTime=0;
}
private function onDownBtnMouseDownHandler(e:MouseEvent):void
{
if(_curVisibleRate>=1)return;
_quickCurTime=getTimer();
_isAdding=true;
addEventListener(Event.ENTER_FRAME,onEnterFrameHandler);
}
private function onDownBtnMouseOutHandler(e:MouseEvent):void
{
removeEventListener(Event.ENTER_FRAME,onEnterFrameHandler);
_quickOperateTime=0;
}
private function onUpBtnMouseUpHandler(e:MouseEvent):void
{
removeEventListener(Event.ENTER_FRAME,onEnterFrameHandler);
_quickOperateTime=0;
}
private function onUpBtnMouseDownHandler(e:MouseEvent):void
{
if(_curVisibleRate>=1)return;
_quickCurTime=getTimer();
_isAdding=false;
addEventListener(Event.ENTER_FRAME,onEnterFrameHandler);
}
private function onUpBtnMouseOutHandler(e:MouseEvent):void
{
removeEventListener(Event.ENTER_FRAME,onEnterFrameHandler);
_quickOperateTime=0;
}
private function onUpBtnMouseClickHandler(e:MouseEvent):void
{
if(_curVisibleRate>=1)return;
curValue-=_increment;
}
private function onEnterFrameHandler(e:Event):void
{
_quickOperateTime+=getTimer()-_quickCurTime;
if(_quickOperateTime>_quickOperateTimeMax)
{
if(_isAdding)
{
curValue+=_increment;
}
else
{
curValue-=_increment;
}
}
}
private function onRemovedFromStageHandler(e:Event):void
{
removeEventListener(Event.REMOVED_FROM_STAGE,onRemovedFromStageHandler);
_upBtn.removeEventListener(MouseEvent.CLICK,onUpBtnMouseClickHandler);
_upBtn.removeEventListener(MouseEvent.MOUSE_OUT,onUpBtnMouseOutHandler);
_upBtn.removeEventListener(MouseEvent.MOUSE_DOWN,onUpBtnMouseDownHandler);
_upBtn.removeEventListener(MouseEvent.MOUSE_UP,onUpBtnMouseUpHandler);
_downBtn.removeEventListener(MouseEvent.CLICK,onDownBtnMouseClickHandler);
_downBtn.removeEventListener(MouseEvent.MOUSE_OUT,onDownBtnMouseOutHandler);
_downBtn.removeEventListener(MouseEvent.MOUSE_DOWN,onDownBtnMouseDownHandler);
_downBtn.removeEventListener(MouseEvent.MOUSE_UP,onDownBtnMouseUpHandler);
_rollPacker.removeEventListener(MouseEvent.MOUSE_DOWN,onRollPackerMouseDownHandler);
stage.removeEventListener(Event.ENTER_FRAME,onStageEnterFrameHandler);
stage.removeEventListener(MouseEvent.MOUSE_UP,onStageMouseUpHandler);
}
protected override function refreshBackground():void
{
this.graphics.clear();
//背景
this.graphics.beginFill(0x008800,.5);
this.graphics.drawRect(0,0,width,height);
this.graphics.endFill();
}
}
}
测试代码:
package
{
import controlsEvents.RadioButtonEvent;
import controlsEvents.ScrollerEvent;
import flash.display.Sprite;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.events.MouseEvent;
public class ControlsTest extends Sprite
{
private var rbt:RadioButton;
private var bt:Button;
private var hs:HorizontalScroller;
private var vs:VerticalScroller;
private var hsLb:Label;
private var vsLb:Label;
public function ControlsTest()
{
stage.color=0;
stage.frameRate=60;
stage.align=StageAlign.TOP_LEFT;
stage.scaleMode=StageScaleMode.NO_SCALE;
rbt=new RadioButton();
rbt.text="test";
rbt.x=50;
rbt.y=50;
rbt.checked=true;
addChild(rbt);
rbt.addEventListener(RadioButtonEvent.ON_CHECKED_CHANGED,onCheckedChangedHandler);
bt=new Button("testButton");
addChild(bt);
bt.x=100;
bt.y=100;
bt.addEventListener(MouseEvent.CLICK,onBtClickHandler);
//bt.width=50;
hs=new HorizontalScroller();
hs.curVisibleRate=.5;
addChild(hs);
hs.x=100;
hs.y=200;
hs.maxValue=1000;
hs.minValue=500;
hs.width=200;
hs.addEventListener(ScrollerEvent.VALUE_CHANGED,onHsValueChangedHandler);
hsLb=new Label();
addChild(hsLb);
hsLb.x=100;
hsLb.y=200+10;
hsLb.text="HorizontalScroller.value:"+hs.curValue;
vs=new VerticalScroller();
vs.curVisibleRate=.5;
addChild(vs);
vs.x=100;
vs.y=250;
vs.maxValue=1000;
vs.minValue=500;
vs.height=200;
vs.addEventListener(ScrollerEvent.VALUE_CHANGED,onVsValueChangedHandler);
vsLb=new Label();
addChild(vsLb);
vsLb.x=100;
vsLb.y=200+60;
vsLb.text="HorizontalScroller.value:"+vs.curValue;
}
private function onBtClickHandler(e:MouseEvent):void
{
hs.minValue+=100;
if(hs.minValue>=hs.maxValue)
{
hs.minValue=0;
}
hs.curVisibleRate+=.1;
if(hs.curVisibleRate>=1)
{
hs.curVisibleRate=.1;
}
}
private function onVsValueChangedHandler(e:ScrollerEvent):void
{
vsLb.text="VerticalScroller.value:"+e.value;
}
private function onHsValueChangedHandler(e:ScrollerEvent):void
{
hsLb.text="HorizontalScroller.value:"+e.value;
}
private function onCheckedChangedHandler(e:RadioButtonEvent):void
{
trace(rbt.checked);
}
}
}
运行效果图: