code:
/**
 * RotarySelector.as
 * Keith Peters
 * version 0.9.10
 *
 * A rotary selector component for choosing among different values.
 *
 * Copyright (c) 2011 Keith Peters
 *
 * 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.bit101.components
{
	import flash.display.DisplayObjectContainer;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;

	[Event(name="change", type="flash.events.Event")]
	public class RotarySelector extends Component
	{
		public static const ALPHABETIC:String = "alphabetic";
		public static const NUMERIC:String = "numeric";
		public static const NONE:String = "none";
		public static const ROMAN:String = "roman";

		protected var _label:Label;
		protected var _labelText:String = "";
		protected var _knob:Sprite;
		protected var _numChoices:int = 2;
		protected var _choice:Number = 0;
		protected var _labels:Sprite;
		protected var _labelMode:String = ALPHABETIC;

		/**
		 * Constructor
		 * @param parent The parent DisplayObjectContainer on which to add this CheckBox.
		 * @param xpos The x position to place this component.
		 * @param ypos The y position to place this component.
		 * @param label String containing the label for this component.
		 * @param defaultHandler The event handling function to handle the default event for this component (change in this case).
		 */
		public function RotarySelector(parent:DisplayObjectContainer = null, xpos:Number = 0, ypos:Number =  0, label:String = "", defaultHandler:Function = null)
		{
			_labelText = label;
			super(parent, xpos, ypos);
			if(defaultHandler != null)
			{
				addEventListener(Event.CHANGE, defaultHandler);
			}
		}

		/**
		 * Initializes the component.
		 */
		override protected function init():void
		{
			super.init();
			setSize(60, 60);
		}

		/**
		 * Creates the children for this component
		 */
		override protected function addChildren():void
		{
			_knob = new Sprite();
			_knob.buttonMode = true;
			_knob.useHandCursor = true;
			addChild(_knob);

			_label = new Label();
			_label.autoSize = true;
			addChild(_label);

			_labels = new Sprite();
			addChild(_labels);

			_knob.addEventListener(MouseEvent.CLICK, onClick);
		}

		/**
		 * Decrements the index of the current choice.
		 */
		protected function decrement():void
		{
			if(_choice > 0)
			{
				_choice--;
				draw();
				dispatchEvent(new Event(Event.CHANGE));
			}
		}

		/**
		 * Increments the index of the current choice.
		 */
		protected function increment():void
		{
			if(_choice < _numChoices - 1)
			{
				_choice++;
				draw();
				dispatchEvent(new Event(Event.CHANGE));
			}
		}

		/**
		 * Removes old labels.
		 */
		protected function resetLabels():void
		{
			while(_labels.numChildren > 0)
			{
				_labels.removeChildAt(0);
			}
			_labels.x = _width / 2 - 5;
			_labels.y = _height / 2 - 10;
		}

		/**
		 * Draw the knob at the specified radius.
		 * @param radius The radius with which said knob will be drawn.
		 */
		protected function drawKnob(radius:Number):void
		{
			_knob.graphics.clear();
			_knob.graphics.beginFill(Style.BACKGROUND);
			_knob.graphics.drawCircle(0, 0, radius);
			_knob.graphics.endFill();

			_knob.graphics.beginFill(Style.BUTTON_FACE);
			_knob.graphics.drawCircle(0, 0, radius - 2);

			_knob.x = _width / 2;
			_knob.y = _height / 2;
		}

		///////////////////////////////////
		// public methods
		///////////////////////////////////

		/**
		 * Draws the visual ui of the component.
		 */
		override public function draw():void
		{
			super.draw();

			var radius:Number = Math.min(_width, _height) / 2;
			drawKnob(radius);
			resetLabels();

			var arc:Number = Math.PI * 1.5 / _numChoices; // the angle between each choice
			var start:Number = - Math.PI / 2 - arc * (_numChoices - 1) / 2; // the starting angle for choice 0

			graphics.clear();
			graphics.lineStyle(4, Style.BACKGROUND, .5);
			for(var i:int = 0; i < _numChoices; i++)
			{
				var angle:Number = start + arc * i;
				var sin:Number = Math.sin(angle);
				var cos:Number = Math.cos(angle);

				graphics.moveTo(_knob.x, _knob.y);
				graphics.lineTo(_knob.x + cos * (radius + 2), _knob.y + sin * (radius + 2));

				var lab:Label = new Label(_labels, cos * (radius + 10), sin * (radius + 10));
				lab.mouseEnabled = true;
				lab.buttonMode = true;
				lab.useHandCursor = true;
				lab.addEventListener(MouseEvent.CLICK, onLabelClick);
				if(_labelMode == ALPHABETIC)
				{
					lab.text = String.fromCharCode(65 + i);
				}
				else if(_labelMode == NUMERIC)
				{
					lab.text = (i + 1).toString();
				}
				else if(_labelMode == ROMAN)
				{
					var chars:Array = ["I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX", "X"];
					lab.text = chars[i];
				}
				if(i != _choice)
				{
					lab.alpha = 0.5;
				}
			}

			angle = start + arc * _choice;
			graphics.lineStyle(4, Style.LABEL_TEXT);
			graphics.moveTo(_knob.x, _knob.y);
			graphics.lineTo(_knob.x + Math.cos(angle) * (radius + 2), _knob.y + Math.sin(angle) * (radius + 2));

			_label.text = _labelText;
			_label.draw();
			_label.x = _width / 2 - _label.width / 2;
			_label.y = _height + 2;
		}

		///////////////////////////////////
		// event handler
		///////////////////////////////////

		/**
		 * Internal click handler.
		 * @param event The MouseEvent passed by the system.
		 */
		protected function onClick(event:MouseEvent):void
		{
			if(mouseX < _width / 2)
			{
				decrement();
			}
			else
			{
				increment();
			}
		}

		protected function onLabelClick(event:Event):void
		{
			var lab:Label = event.target as Label;
			choice = _labels.getChildIndex(lab);
		}

		///////////////////////////////////
		// getter/setters
		///////////////////////////////////

		/**
		 * Gets / sets the number of available choices (maximum of 10).
		 */
		public function set numChoices(value:uint):void
		{
			_numChoices = Math.min(value, 10);
			draw();
		}
		public function get numChoices():uint
		{
			return _numChoices;
		}

		/**
		 * Gets / sets the current choice, keeping it in range of 0 to numChoices - 1.
		 */
		public function set choice(value:uint):void
		{
			_choice = Math.max(0, Math.min(_numChoices - 1, value));
			draw();
			dispatchEvent(new Event(Event.CHANGE));
		}
		public function get choice():uint
		{
			return _choice;
		}

		/**
		 * Specifies what will be used as labels for each choice. Valid values are "alphabetic", "numeric", and "none".
		 */
		public function set labelMode(value:String):void
		{
			_labelMode = value;
			draw();
		}
		public function get labelMode():String
		{
			return _labelMode;
		}
	}
}


code:
/**
 * ScrollBar.as
 * Keith Peters
 * version 0.9.10
 *
 * Base class for HScrollBar and VScrollBar
 *
 * Copyright (c) 2011 Keith Peters
 *
 * 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.bit101.components
{
	import flash.display.DisplayObjectContainer;
	import flash.display.Shape;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.events.TimerEvent;
	import flash.utils.Timer;

	[Event(name="change", type="flash.events.Event")]
	public class ScrollBar extends Component
	{
		protected const DELAY_TIME:int = 500;
		protected const REPEAT_TIME:int = 100;
		protected const UP:String = "up";
		protected const DOWN:String = "down";

		protected var _autoHide:Boolean = false;
		protected var _activated:Boolean = true;
		protected var _upButton:PushButton;
		protected var _downButton:PushButton;
		protected var _scrollSlider:ScrollSlider;
		protected var _orientation:String;
		protected var _lineSize:int = 1;
		protected var _delayTimer:Timer;
		protected var _repeatTimer:Timer;
		protected var _direction:String;
		protected var _shouldRepeat:Boolean = false;

		/**
		 * Constructor
		 * @param orientation Whether this is a vertical or horizontal slider.
		 * @param parent The parent DisplayObjectContainer on which to add this Slider.
		 * @param xpos The x position to place this component.
		 * @param ypos The y position to place this component.
		 * @param defaultHandler The event handling function to handle the default event for this component (change in this case).
		 */
		public function ScrollBar(orientation:String, parent:DisplayObjectContainer=null, xpos:Number=0, ypos:Number=0, defaultHandler:Function = null)
		{
			_orientation = orientation;
			super(parent, xpos, ypos);
			if(defaultHandler != null)
			{
				addEventListener(Event.CHANGE, defaultHandler);
			}
		}

		/**
		 * Creates and adds the child display objects of this component.
		 */
		override protected function addChildren():void
		{
			_scrollSlider = new ScrollSlider(_orientation, this, 0, 10, onChange);
			_upButton = new PushButton(this, 0, 0, "");
			_upButton.addEventListener(MouseEvent.MOUSE_DOWN, onUpClick);
			_upButton.setSize(10, 10);
			var upArrow:Shape = new Shape();
			_upButton.addChild(upArrow);

			_downButton = new PushButton(this, 0, 0, "");
			_downButton.addEventListener(MouseEvent.MOUSE_DOWN, onDownClick);
			_downButton.setSize(10, 10);
			var downArrow:Shape = new Shape();
			_downButton.addChild(downArrow);

			if(_orientation == Slider.VERTICAL)
			{
				upArrow.graphics.beginFill(Style.DROPSHADOW, 0.5);
				upArrow.graphics.moveTo(5, 3);
				upArrow.graphics.lineTo(7, 6);
				upArrow.graphics.lineTo(3, 6);
				upArrow.graphics.endFill();

				downArrow.graphics.beginFill(Style.DROPSHADOW, 0.5);
				downArrow.graphics.moveTo(5, 7);
				downArrow.graphics.lineTo(7, 4);
				downArrow.graphics.lineTo(3, 4);
				downArrow.graphics.endFill();
			}
			else
			{
				upArrow.graphics.beginFill(Style.DROPSHADOW, 0.5);
				upArrow.graphics.moveTo(3, 5);
				upArrow.graphics.lineTo(6, 7);
				upArrow.graphics.lineTo(6, 3);
				upArrow.graphics.endFill();

				downArrow.graphics.beginFill(Style.DROPSHADOW, 0.5);
				downArrow.graphics.moveTo(7, 5);
				downArrow.graphics.lineTo(4, 7);
				downArrow.graphics.lineTo(4, 3);
				downArrow.graphics.endFill();
			}

		}

		/**
		 * Initializes the component.
		 */
		protected override function init():void
		{
			super.init();
			if(_orientation == Slider.HORIZONTAL)
			{
				setSize(100, 10);
			}
			else
			{
				setSize(10, 100);
                this.scaleX += 0.5;
            }
			_delayTimer = new Timer(DELAY_TIME, 1);
			_delayTimer.addEventListener(TimerEvent.TIMER_COMPLETE, onDelayComplete);
			_repeatTimer = new Timer(REPEAT_TIME);
			_repeatTimer.addEventListener(TimerEvent.TIMER, onRepeat);
		}

		///////////////////////////////////
		// public methods
		///////////////////////////////////

		/**
		 * Convenience method to set the three main parameters in one shot.
		 * @param min The minimum value of the slider.
		 * @param max The maximum value of the slider.
		 * @param value The value of the slider.
		 */
		public function setSliderParams(min:Number, max:Number, value:Number):void
		{
			_scrollSlider.setSliderParams(min, max, value);
		}

		/**
		 * Sets the percentage of the size of the thumb button.
		 */
		public function setThumbPercent(value:Number):void
		{
			_scrollSlider.setThumbPercent(value);
		}

		/**
		 * Draws the visual ui of the component.
		 */
		override public function draw():void
		{
			super.draw();
			if(_orientation == Slider.VERTICAL)
			{
				_scrollSlider.x = 0;
				_scrollSlider.y = 10;
				_scrollSlider.width = 10;
				_scrollSlider.height = _height - 20;
				_downButton.x = 0;
				_downButton.y = _height - 10;
			}
			else
			{
				_scrollSlider.x = 10;
				_scrollSlider.y = 0;
				_scrollSlider.width = _width - 20;
				_scrollSlider.height = 10;
				_downButton.x = _width - 10;
				_downButton.y = 0;
			}
			_scrollSlider.draw();
			if (!_activated)
			{
				visible = false;
			}
			else
			{
				if (_autoHide)
				{
					visible = _scrollSlider.thumbPercent < 1.0;
				}
				else
				{
					visible = true;
				}
			}
		}

		///////////////////////////////////
		// getter/setters
		///////////////////////////////////

		/**
		 * Sets / gets whether the scrollbar will be activated
		 */
		public function set activated(value:Boolean):void
		{
			_activated = value;
			invalidate();
		}
		public function get activated():Boolean
		{
			return _activated;
		}

		/**
		 * Sets / gets whether the scrollbar will auto hide when there is nothing to scroll.
		 */
		public function set autoHide(value:Boolean):void
		{
			_autoHide = value;
			invalidate();
		}
		public function get autoHide():Boolean
		{
			return _autoHide;
		}

		/**
		 * Sets / gets the current value of this scroll bar.
		 */
		public function set value(v:Number):void
		{
			_scrollSlider.value = v;
		}
		public function get value():Number
		{
			return _scrollSlider.value;
		}

		/**
		 * Sets / gets the minimum value of this scroll bar.
		 */
		public function set minimum(v:Number):void
		{
			_scrollSlider.minimum = v;
		}
		public function get minimum():Number
		{
			return _scrollSlider.minimum;
		}

		/**
		 * Sets / gets the maximum value of this scroll bar.
		 */
		public function set maximum(v:Number):void
		{
			_scrollSlider.maximum = v;
		}
		public function get maximum():Number
		{
			return _scrollSlider.maximum;
		}

		/**
		 * Sets / gets the amount the value will change when up or down buttons are pressed.
		 */
		public function set lineSize(value:int):void
		{
			_lineSize = value;
		}
		public function get lineSize():int
		{
			return _lineSize;
		}

		/**
		 * Sets / gets the amount the value will change when the back is clicked.
		 */
		public function set pageSize(value:int):void
		{
			_scrollSlider.pageSize = value;
			invalidate();
		}
		public function get pageSize():int
		{
			return _scrollSlider.pageSize;
		}

		///////////////////////////////////
		// event handlers
		///////////////////////////////////

		protected function onUpClick(event:MouseEvent):void
		{
			goUp();
			_shouldRepeat = true;
			_direction = UP;
			_delayTimer.start();
			stage.addEventListener(MouseEvent.MOUSE_UP, onMouseGoUp);
		}

		protected function goUp():void
		{
			_scrollSlider.value -= _lineSize;
			dispatchEvent(new Event(Event.CHANGE));
		}

		protected function onDownClick(event:MouseEvent):void
		{
			goDown();
			_shouldRepeat = true;
			_direction = DOWN;
			_delayTimer.start();
			stage.addEventListener(MouseEvent.MOUSE_UP, onMouseGoUp);
		}

		protected function goDown():void
		{
			_scrollSlider.value += _lineSize;
			dispatchEvent(new Event(Event.CHANGE));
		}

		protected function onMouseGoUp(event:MouseEvent):void
		{
			_delayTimer.stop();
			_repeatTimer.stop();
			_shouldRepeat = false;
		}

		protected function onChange(event:Event):void
		{
			dispatchEvent(event);
		}

		protected function onDelayComplete(event:TimerEvent):void
		{
			if(_shouldRepeat)
			{
				_repeatTimer.start();
			}
		}

		protected function onRepeat(event:TimerEvent):void
		{
			if(_direction == UP)
			{
				goUp();
			}
			else
			{
				goDown();
			}
		}

	}
}

import flash.display.DisplayObjectContainer;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.geom.Rectangle;
import com.bit101.components.Slider;
import com.bit101.components.Style;

/**
 * Helper class for the slider portion of the scroll bar.
 */
class ScrollSlider extends Slider
{
	protected var _thumbPercent:Number = 1.0;
	protected var _pageSize:int = 1;

	/**
	 * Constructor
	 * @param orientation Whether this is a vertical or horizontal slider.
	 * @param parent The parent DisplayObjectContainer on which to add this Slider.
	 * @param xpos The x position to place this component.
	 * @param ypos The y position to place this component.
	 * @param defaultHandler The event handling function to handle the default event for this component (change in this case).
	 */
	public function ScrollSlider(orientation:String, parent:DisplayObjectContainer=null, xpos:Number=0, ypos:Number=0, defaultHandler:Function = null)
	{
		super(orientation, parent, xpos, ypos);
		if(defaultHandler != null)
		{
			addEventListener(Event.CHANGE, defaultHandler);
		}
	}

	/**
	 * Initializes the component.
	 */
	protected override function init():void
	{
		super.init();
		setSliderParams(1, 1, 0);
		backClick = true;
	}

	/**
	 * Draws the handle of the slider.
	 */
	override protected function drawHandle() : void
	{
		var size:Number;
		_handle.graphics.clear();
		if(_orientation == HORIZONTAL)
		{
			size = Math.round(_width * _thumbPercent);
			size = Math.max(_height, size);
			_handle.graphics.beginFill(0, 0);
			_handle.graphics.drawRect(0, 0, size, _height);
			_handle.graphics.endFill();
			_handle.graphics.beginFill(Style.BUTTON_FACE);
			_handle.graphics.drawRect(1, 1, size - 2, _height - 2);
		}
		else
		{
			size = Math.round(_height * _thumbPercent);
			size = Math.max(_width, size);
			_handle.graphics.beginFill(0, 0);
			_handle.graphics.drawRect(0, 0, _width  - 2, size);
			_handle.graphics.endFill();
			_handle.graphics.beginFill(Style.BUTTON_FACE);
			_handle.graphics.drawRect(1, 1, _width - 2, size - 2);
		}
		_handle.graphics.endFill();
		positionHandle();
	}

	/**
	 * Adjusts position of handle when value, maximum or minimum have changed.
	 * TODO: Should also be called when slider is resized.
	 */
	protected override function positionHandle():void
	{
		var range:Number;
		if(_orientation == HORIZONTAL)
		{
			range = width - _handle.width;
			_handle.x = (_value - _min) / (_max - _min) * range;
		}
		else
		{
			range = height - _handle.height;
			_handle.y = (_value - _min) / (_max - _min) * range;
		}
	}

	///////////////////////////////////
	// public methods
	///////////////////////////////////

	/**
	 * Sets the percentage of the size of the thumb button.
	 */
	public function setThumbPercent(value:Number):void
	{
		_thumbPercent = Math.min(value, 1.0);
		invalidate();
	}

	///////////////////////////////////
	// event handlers
	///////////////////////////////////

	/**
	 * Handler called when user clicks the background of the slider, causing the handle to move to that point. Only active if backClick is true.
	 * @param event The MouseEvent passed by the system.
	 */
	protected override function onBackClick(event:MouseEvent):void
	{
		if(_orientation == HORIZONTAL)
		{
			if(mouseX < _handle.x)
			{
				if(_max > _min)
				{
					_value -= _pageSize;
				}
				else
				{
					_value += _pageSize;
				}
				correctValue();
			}
			else
			{
				if(_max > _min)
				{
					_value += _pageSize;
				}
				else
				{
					_value -= _pageSize;
				}
				correctValue();
			}
			positionHandle();
		}
		else
		{
			if(mouseY < _handle.y)
			{
				if(_max > _min)
				{
					_value -= _pageSize;
				}
				else
				{
					_value += _pageSize;
				}
				correctValue();
			}
			else
			{
				if(_max > _min)
				{
					_value += _pageSize;
				}
				else
				{
					_value -= _pageSize;
				}
				correctValue();
			}
			positionHandle();
		}
		dispatchEvent(new Event(Event.CHANGE));

	}

	/**
	 * Internal mouseDown handler. Starts dragging the handle.
	 * @param event The MouseEvent passed by the system.
	 */
	protected override function onDrag(event:MouseEvent):void
	{
		stage.addEventListener(MouseEvent.MOUSE_UP, onDrop);
		stage.addEventListener(MouseEvent.MOUSE_MOVE, onSlide);
		if(_orientation == HORIZONTAL)
		{
			_handle.startDrag(false, new Rectangle(0, 0, _width - _handle.width, 0));
		}
		else
		{
			_handle.startDrag(false, new Rectangle(0, 0, 0, _height - _handle.height));
		}
	}

	/**
	 * Internal mouseMove handler for when the handle is being moved.
	 * @param event The MouseEvent passed by the system.
	 */
	protected override function onSlide(event:MouseEvent):void
	{
		var oldValue:Number = _value;
		if(_orientation == HORIZONTAL)
		{
			if(_width == _handle.width)
			{
				_value = _min;
			}
			else
			{
				_value = _handle.x / (_width - _handle.width) * (_max - _min) + _min;
			}
		}
		else
		{
			if(_height == _handle.height)
			{
				_value = _min;
			}
			else
			{
				_value = _handle.y / (_height - _handle.height) * (_max - _min) + _min;
			}
		}
		if(_value != oldValue)
		{
			dispatchEvent(new Event(Event.CHANGE));
		}
	}

	///////////////////////////////////
	// getter/setters
	///////////////////////////////////

	/**
	 * Sets / gets the amount the value will change when the back is clicked.
	 */
	public function set pageSize(value:int):void
	{
		_pageSize = value;
		invalidate();
	}
	public function get pageSize():int
	{
		return _pageSize;
	}

	public function get thumbPercent():Number
	{
		return _thumbPercent;
	}
}

license: unknown


code:
/**
 * ScrollPane.as
 * Keith Peters
 * version 0.9.10
 *
 * A panel with scroll bars for scrolling content that is larger.
 *
 * Copyright (c) 2011 Keith Peters
 *
 * 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.bit101.components
{

	import flash.display.DisplayObjectContainer;
	import flash.display.Shape;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.geom.Rectangle;

	public class ScrollPane extends Panel
	{
		protected var _vScrollbar:VScrollBar;
		protected var _hScrollbar:HScrollBar;
		protected var _corner:Shape;
		protected var _dragContent:Boolean = true;

		/**
		 * Constructor
		 * @param parent The parent DisplayObjectContainer on which to add this ScrollPane.
		 * @param xpos The x position to place this component.
		 * @param ypos The y position to place this component.
		 */
		public function ScrollPane(parent:DisplayObjectContainer=null, xpos:Number=0, ypos:Number=0)
		{
			super(parent, xpos, ypos);
		}

		/**
		 * Initializes this component.
		 */
		override protected function init():void
		{
			super.init();
			addEventListener(Event.RESIZE, onResize);
			_background.addEventListener(MouseEvent.MOUSE_DOWN, onMouseGoDown);
			_background.useHandCursor = true;
			_background.buttonMode = true;
			setSize(100, 100);
		}

		/**
		 * Creates and adds the child display objects of this component.
		 */
		override protected function addChildren():void
		{
			super.addChildren();
			_vScrollbar = new VScrollBar(null, width - 10, 0, onScroll);
			_hScrollbar = new HScrollBar(null, 0, height - 10, onScroll);
			addRawChild(_vScrollbar);
			addRawChild(_hScrollbar);
			_corner = new Shape();
			_corner.graphics.beginFill(Style.BUTTON_FACE);
			_corner.graphics.drawRect(0, 0, 10, 10);
			_corner.graphics.endFill();
			addRawChild(_corner);
			//hide the horizontal scrollbar by default
			_hScrollbar.autoHide = true;
		}

		///////////////////////////////////
		// public methods
		///////////////////////////////////

		/**
		 * Draws the visual ui of the component.
		 */
		override public function draw():void
		{
			super.draw();

			var vPercent:Number = (_height - 10) / content.height;
			var hPercent:Number = (_width - 10) / content.width;

			_vScrollbar.x = width - 5;
			_hScrollbar.y = height - 10;

			if(hPercent >= 1)
			{
				_vScrollbar.height = height;
				_mask.height = height;
			}
			else
			{
				_vScrollbar.height = height - 10;
				_mask.height = height - 10;
			}
			if(vPercent >= 1)
			{
				_hScrollbar.width = width;
				_mask.width = width;
			}
			else
			{
				_hScrollbar.width = width - 10;
				_mask.width = width - 10;
			}
			_vScrollbar.setThumbPercent(vPercent);
			_vScrollbar.maximum = Math.max(0, content.height - _height + 10);
			_vScrollbar.pageSize = _height - 10;

			_hScrollbar.setThumbPercent(hPercent);
			_hScrollbar.maximum = Math.max(0, content.width - _width + 10);
			_hScrollbar.pageSize = _width - 10;

			_corner.x = width - 10;
			_corner.y = height - 10;
			_corner.visible = (hPercent < 1) && (vPercent < 1);
			content.x = -_hScrollbar.value;
			content.y = -_vScrollbar.value;
		}

		/**
		 * Updates the scrollbars when content is changed. Needs to be done manually.
		 */
		public function update():void
		{
			invalidate();
		}

		///////////////////////////////////
		// event handlers
		///////////////////////////////////

		/**
		 * Called when either scroll bar is scrolled.
		 */
		protected function onScroll(event:Event):void
		{
			content.x = -_hScrollbar.value;
			content.y = -_vScrollbar.value;
		}

		protected function onResize(event:Event):void
		{
			invalidate();
		}

		protected function onMouseGoDown(event:MouseEvent):void
		{
			content.startDrag(false, new Rectangle(0, 0, Math.min(0, _width - content.width - 10), Math.min(0, _height - content.height - 10)));
			stage.addEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
			stage.addEventListener(MouseEvent.MOUSE_UP, onMouseGoUp);
		}

		protected function onMouseMove(event:MouseEvent):void
		{
			_hScrollbar.value = -content.x;
			_vScrollbar.value = -content.y;
		}

		protected function onMouseGoUp(event:MouseEvent):void
		{
			content.stopDrag();
			stage.removeEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
			stage.removeEventListener(MouseEvent.MOUSE_UP, onMouseGoUp);
		}

		public function set dragContent(value:Boolean):void
		{
			_dragContent = value;
			if(_dragContent)
			{
				_background.addEventListener(MouseEvent.MOUSE_DOWN, onMouseGoDown);
				_background.useHandCursor = true;
				_background.buttonMode = true;
			}
			else
			{
				_background.removeEventListener(MouseEvent.MOUSE_DOWN, onMouseGoDown);
				_background.useHandCursor = false;
				_background.buttonMode = false;
			}
		}
		public function get dragContent():Boolean
		{
			return _dragContent;
		}

        /**
         * Sets / gets whether the scrollbar will auto hide when there is nothing to scroll.
         */
        public function set autoHideScrollBar(value:Boolean):void
        {
            _vScrollbar.autoHide = value;
            _hScrollbar.autoHide = value;
        }
        public function get autoHideScrollBar():Boolean
        {
            return _vScrollbar.autoHide;
        }

	}
}


code:
/**
 * Slider.as
 * Keith Peters
 * version 0.9.10
 *
 * Abstract base slider class for HSlider and VSlider.
 *
 * Copyright (c) 2011 Keith Peters
 *
 * 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.bit101.components
{
	import flash.display.DisplayObjectContainer;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.geom.Rectangle;

	[Event(name="change", type="flash.events.Event")]
	public class Slider extends Component
	{
		protected var _handle:Sprite;
		protected var _back:Sprite;
		protected var _backClick:Boolean = true;
		protected var _value:Number = 0;
		protected var _max:Number = 100;
		protected var _min:Number = 0;
		protected var _orientation:String;
		protected var _tick:Number = 0.01;

		public static const HORIZONTAL:String = "horizontal";
		public static const VERTICAL:String = "vertical";

		/**
		 * Constructor
		 * @param orientation Whether the slider will be horizontal or vertical.
		 * @param parent The parent DisplayObjectContainer on which to add this Slider.
		 * @param xpos The x position to place this component.
		 * @param ypos The y position to place this component.
		 * @param defaultHandler The event handling function to handle the default event for this component (change in this case).
		 */
		public function Slider(orientation:String = Slider.HORIZONTAL, parent:DisplayObjectContainer = null, xpos:Number = 0, ypos:Number =  0, defaultHandler:Function = null)
		{
			_orientation = orientation;
			super(parent, xpos, ypos);
			if(defaultHandler != null)
			{
				addEventListener(Event.CHANGE, defaultHandler);
			}
		}

		/**
		 * Initializes the component.
		 */
		override protected function init():void
		{
			super.init();

			if(_orientation == HORIZONTAL)
			{
				setSize(100, 10);
			}
			else
			{
				setSize(10, 100);
			}
		}

		/**
		 * Creates and adds the child display objects of this component.
		 */
		override protected function addChildren():void
		{
			_back = new Sprite();
			_back.filters = [getShadow(2, true)];
			addChild(_back);

			_handle = new Sprite();
			_handle.filters = [getShadow(1)];
			_handle.addEventListener(MouseEvent.MOUSE_DOWN, onDrag);
			_handle.buttonMode = true;
			_handle.useHandCursor = true;
			addChild(_handle);
		}

		/**
		 * Draws the back of the slider.
		 */
		protected function drawBack():void
		{
			_back.graphics.clear();
			_back.graphics.beginFill(Style.BACKGROUND);
			_back.graphics.drawRect(0, 0, _width, _height);
			_back.graphics.endFill();

			if(_backClick)
			{
				_back.addEventListener(MouseEvent.MOUSE_DOWN, onBackClick);
			}
			else
			{
				_back.removeEventListener(MouseEvent.MOUSE_DOWN, onBackClick);
			}
		}

		/**
		 * Draws the handle of the slider.
		 */
		protected function drawHandle():void
		{
			_handle.graphics.clear();
			_handle.graphics.beginFill(Style.BUTTON_FACE);
			if(_orientation == HORIZONTAL)
			{
				_handle.graphics.drawRect(1, 1, _height - 2, _height - 2);
			}
			else
			{
				_handle.graphics.drawRect(1, 1, _width - 2, _width - 2);
			}
			_handle.graphics.endFill();
			positionHandle();
		}

		/**
		 * Adjusts value to be within minimum and maximum.
		 */
		protected function correctValue():void
		{
			if(_max > _min)
			{
				_value = Math.min(_value, _max);
				_value = Math.max(_value, _min);
			}
			else
			{
				_value = Math.max(_value, _max);
				_value = Math.min(_value, _min);
			}
		}

		/**
		 * Adjusts position of handle when value, maximum or minimum have changed.
		 * TODO: Should also be called when slider is resized.
		 */
		protected function positionHandle():void
		{
			var range:Number;
			if(_orientation == HORIZONTAL)
			{
				range = _width - _height;
				_handle.x = (_value - _min) / (_max - _min) * range;
			}
			else
			{
				range = _height - _width;
				_handle.y = _height - _width - (_value - _min) / (_max - _min) * range;
			}
		}

		///////////////////////////////////
		// public methods
		///////////////////////////////////

		/**
		 * Draws the visual ui of the component.
		 */
		override public function draw():void
		{
			super.draw();
			drawBack();
			drawHandle();
		}

		/**
		 * Convenience method to set the three main parameters in one shot.
		 * @param min The minimum value of the slider.
		 * @param max The maximum value of the slider.
		 * @param value The value of the slider.
		 */
		public function setSliderParams(min:Number, max:Number, value:Number):void
		{
			this.minimum = min;
			this.maximum = max;
			this.value = value;
		}

		///////////////////////////////////
		// event handlers
		///////////////////////////////////

		/**
		 * Handler called when user clicks the background of the slider, causing the handle to move to that point. Only active if backClick is true.
		 * @param event The MouseEvent passed by the system.
		 */
		protected function onBackClick(event:MouseEvent):void
		{
			if(_orientation == HORIZONTAL)
			{
				_handle.x = mouseX - _height / 2;
				_handle.x = Math.max(_handle.x, 0);
				_handle.x = Math.min(_handle.x, _width - _height);
				_value = _handle.x / (width - _height) * (_max - _min) + _min;
			}
			else
			{
				_handle.y = mouseY - _width / 2;
				_handle.y = Math.max(_handle.y, 0);
				_handle.y = Math.min(_handle.y, _height - _width);
				_value = (_height - _width - _handle.y) / (height - _width) * (_max - _min) + _min;
			}
			dispatchEvent(new Event(Event.CHANGE));

		}

		/**
		 * Internal mouseDown handler. Starts dragging the handle.
		 * @param event The MouseEvent passed by the system.
		 */
		protected function onDrag(event:MouseEvent):void
		{
			stage.addEventListener(MouseEvent.MOUSE_UP, onDrop);
			stage.addEventListener(MouseEvent.MOUSE_MOVE, onSlide);
			if(_orientation == HORIZONTAL)
			{
				_handle.startDrag(false, new Rectangle(0, 0, _width - _height, 0));
			}
			else
			{
				_handle.startDrag(false, new Rectangle(0, 0, 0, _height - _width));
			}
		}

		/**
		 * Internal mouseUp handler. Stops dragging the handle.
		 * @param event The MouseEvent passed by the system.
		 */
		protected function onDrop(event:MouseEvent):void
		{
			stage.removeEventListener(MouseEvent.MOUSE_UP, onDrop);
			stage.removeEventListener(MouseEvent.MOUSE_MOVE, onSlide);
			stopDrag();
		}

		/**
		 * Internal mouseMove handler for when the handle is being moved.
		 * @param event The MouseEvent passed by the system.
		 */
		protected function onSlide(event:MouseEvent):void
		{
			var oldValue:Number = _value;
			if(_orientation == HORIZONTAL)
			{
				_value = _handle.x / (width - _height) * (_max - _min) + _min;
			}
			else
			{
				_value = (_height - _width - _handle.y) / (height - _width) * (_max - _min) + _min;
			}
			if(_value != oldValue)
			{
				dispatchEvent(new Event(Event.CHANGE));
			}
		}

		///////////////////////////////////
		// getter/setters
		///////////////////////////////////

		/**
		 * Sets / gets whether or not a click on the background of the slider will move the handler to that position.
		 */
		public function set backClick(b:Boolean):void
		{
			_backClick = b;
			invalidate();
		}
		public function get backClick():Boolean
		{
			return _backClick;
		}

		/**
		 * Sets / gets the current value of this slider.
		 */
		public function set value(v:Number):void
		{
			_value = v;
			correctValue();
			positionHandle();

		}
		public function get value():Number
		{
			return Math.round(_value / _tick) * _tick;
		}

        /**
         * Gets the value of the slider without rounding it per the tick value.
         */
        public function get rawValue():Number
        {
            return _value;
        }

		/**
		 * Gets / sets the maximum value of this slider.
		 */
		public function set maximum(m:Number):void
		{
			_max = m;
			correctValue();
			positionHandle();
		}
		public function get maximum():Number
		{
			return _max;
		}

		/**
		 * Gets / sets the minimum value of this slider.
		 */
		public function set minimum(m:Number):void
		{
			_min = m;
			correctValue();
			positionHandle();
		}
		public function get minimum():Number
		{
			return _min;
		}

		/**
		 * Gets / sets the tick value of this slider. This round the value to the nearest multiple of this number.
		 */
		public function set tick(t:Number):void
		{
			_tick = t;
		}
		public function get tick():Number
		{
			return _tick;
		}

	}
}


code:
/**
 * Style.as
 * Keith Peters
 * version 0.9.10
 *
 * A collection of style variables used by the components.
 * If you want to customize the colors of your components, change these values BEFORE instantiating any components.
 *
 * Copyright (c) 2011 Keith Peters
 *
 * 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.bit101.components
{

	public class Style
	{
		//All those privately declared static variables.
		private static var _textBackground:uint = 0xFFFFFF;
		private static var _background:uint = 0xCCCCCC;
		private static var _buttonFace:uint = 0xFFFFFF;
		private static var _buttonDown:uint = 0xEEEEEE;
		private static var _inputText:uint = 0x333333;
		private static var _labelText:uint = 0x666666;
		private static var _dropShadow:uint = 0x000000;
		private static var _panel:uint = 0xF3F3F3;
		private static var _progressBar:uint = 0xFFFFFF;
		private static var _listDefault:uint = 0xFFFFFF;
		private static var _listAlternate:uint = 0xF3F3F3;
		private static var _listSelected:uint = 0xCCCCCC;
		private static var _listRollover:uint = 0XDDDDDD;

		private static var _embedFonts:Boolean = true;
		private static var _fontName:String = "PF Ronda Seven";
		private static var _fontSize:Number = 10;

		public static const DARK:String = "dark";
		public static const LIGHT:String = "light";

		//Getter and setter functions.
		public static function set TEXT_BACKGROUND(newColor:uint):void { _textBackground = newColor; }
		public static function get TEXT_BACKGROUND():uint { return _textBackground; }

		public static function set BACKGROUND(newColor:uint):void { _background = newColor; }
		public static function get BACKGROUND():uint { return _background; }

		public static function set BUTTON_FACE(newColor:uint):void { _buttonFace = newColor; }
		public static function get BUTTON_FACE():uint { return _buttonFace; }

		public static function set BUTTON_DOWN(newColor:uint):void { _buttonDown = newColor; }
		public static function get BUTTON_DOWN():uint { return _buttonDown; }

		public static function set INPUT_TEXT(newColor:uint):void { _inputText = newColor; }
		public static function get INPUT_TEXT():uint { return _inputText; }

		public static function set LABEL_TEXT(newColor:uint):void { _labelText = newColor; }
		public static function get LABEL_TEXT():uint { return _labelText; }

		public static function set DROPSHADOW(newColor:uint):void { _dropShadow = newColor; }
		public static function get DROPSHADOW():uint { return _dropShadow; }

		public static function set PANEL(newColor:uint):void { _panel = newColor; }
		public static function get PANEL():uint { return _panel; }

		public static function set PROGRESS_BAR(newColor:uint):void { _progressBar = newColor; }
		public static function get PROGRESS_BAR():uint { return _progressBar; }

		public static function set LIST_DEFAULT(newColor:uint):void { _listDefault = newColor; }
		public static function get LIST_DEFAULT():uint { return _listDefault; }

		public static function set LIST_ALTERNATE(newColor:uint):void { _listAlternate = newColor; }
		public static function get LIST_ALTERNATE():uint { return _listAlternate; }

		public static function set LIST_SELECTED(newColor:uint):void { _listSelected = newColor; }
		public static function get LIST_SELECTED():uint { return _listSelected; }

		public static function set LIST_ROLLOVER(newColor:uint):void { _listRollover = newColor; }
		public static function get LIST_ROLLOVER():uint { return _listRollover; }

		public static function set embedFonts(newValue:Boolean):void { _embedFonts = newValue; }
		public static function get embedFonts():Boolean { return _embedFonts; }

		public static function set fontName(newValue:String):void { _fontName = newValue; }
		public static function get fontName():String { return _fontName; }

		public static function set fontSize(newValue:Number):void { _fontSize = newValue; }
		public static function get fontSize():Number { return _fontSize; }

		/**
		 * Applies a preset style as a list of color values. Should be called before creating any components.
		 */
		public static function setStyle(style:String):void
		{
			switch(style)
			{
				case DARK:
					Style.BACKGROUND = 0x444444;
					Style.BUTTON_FACE = 0x666666;
					Style.BUTTON_DOWN = 0x222222;
					Style.INPUT_TEXT = 0xBBBBBB;
					Style.LABEL_TEXT = 0xCCCCCC;
					Style.PANEL = 0x666666;
					Style.PROGRESS_BAR = 0x666666;
					Style.TEXT_BACKGROUND = 0x555555;
					Style.LIST_DEFAULT = 0x444444;
					Style.LIST_ALTERNATE = 0x393939;
					Style.LIST_SELECTED = 0x666666;
					Style.LIST_ROLLOVER = 0x777777;
					break;
				case LIGHT:
				default:
					Style.BACKGROUND = 0xCCCCCC;
					Style.BUTTON_FACE = 0xFFFFFF;
					Style.BUTTON_DOWN = 0xEEEEEE;
					Style.INPUT_TEXT = 0x333333;
					Style.LABEL_TEXT = 0x666666;
					Style.PANEL = 0xF3F3F3;
					Style.PROGRESS_BAR = 0xFFFFFF;
					Style.TEXT_BACKGROUND = 0xFFFFFF;
					Style.LIST_DEFAULT = 0xFFFFFF;
					Style.LIST_ALTERNATE = 0xF3F3F3;
					Style.LIST_SELECTED = 0xCCCCCC;
					Style.LIST_ROLLOVER = 0xDDDDDD;
					break;
			}
		}
	}
}


code:
/**
 * Text.as
 * Keith Peters
 * version 0.9.10
 *
 * A Text component for displaying multiple lines of text.
 *
 * Copyright (c) 2011 Keith Peters
 *
 * 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.bit101.components
{
	import flash.display.DisplayObjectContainer;
	import flash.events.Event;
	import flash.text.TextField;
	import flash.text.TextFieldType;
	import flash.text.TextFormat;

	[Event(name="change", type="flash.events.Event")]
	public class Text extends Component
	{
		protected var _tf:TextField;
		protected var _text:String = "";
		protected var _editable:Boolean = true;
		protected var _panel:Panel;
		protected var _selectable:Boolean = true;
		protected var _html:Boolean = false;
		protected var _format:TextFormat;

		/**
		 * Constructor
		 * @param parent The parent DisplayObjectContainer on which to add this Label.
		 * @param xpos The x position to place this component.
		 * @param ypos The y position to place this component.
		 * @param text The initial text to display in this component.
		 */
		public function Text(parent:DisplayObjectContainer = null, xpos:Number = 0, ypos:Number =  0, text:String = "")
		{
			this.text = text;
			super(parent, xpos, ypos);
			setSize(200, 100);
		}

		/**
		 * Initializes the component.
		 */
		override protected function init():void
		{
			super.init();
		}

		/**
		 * Creates and adds the child display objects of this component.
		 */
		override protected function addChildren():void
		{
			_panel = new Panel(this);
			_panel.color = Style.TEXT_BACKGROUND;

			_format = new TextFormat(Style.fontName, Style.fontSize, Style.LABEL_TEXT);

			_tf = new TextField();
			_tf.x = 2;
			_tf.y = 2;
			_tf.height = _height;
			_tf.embedFonts = Style.embedFonts;
			_tf.multiline = true;
			_tf.wordWrap = true;
			_tf.selectable = true;
			_tf.type = TextFieldType.INPUT;
			_tf.defaultTextFormat = _format;
			_tf.addEventListener(Event.CHANGE, onChange);
			addChild(_tf);
		}

		///////////////////////////////////
		// public methods
		///////////////////////////////////

		/**
		 * Draws the visual ui of the component.
		 */
		override public function draw():void
		{
			super.draw();

			_panel.setSize(_width, _height);
			_panel.draw();

			_tf.width = _width - 4;
			_tf.height = _height - 4;
			if(_html)
			{
				_tf.htmlText = _text;
			}
			else
			{
				_tf.text = _text;
			}
			if(_editable)
			{
				_tf.mouseEnabled = true;
				_tf.selectable = true;
				_tf.type = TextFieldType.INPUT;
			}
			else
			{
				_tf.mouseEnabled = _selectable;
				_tf.selectable = _selectable;
				_tf.type = TextFieldType.DYNAMIC;
			}
			_tf.setTextFormat(_format);
		}

		///////////////////////////////////
		// event handlers
		///////////////////////////////////

		/**
		 * Called when the text in the text field is manually changed.
		 */
		protected function onChange(event:Event):void
		{
			_text = _tf.text;
			dispatchEvent(event);
		}

		///////////////////////////////////
		// getter/setters
		///////////////////////////////////

		/**
		 * Gets / sets the text of this Label.
		 */
		public function set text(t:String):void
		{
			_text = t;
			if(_text == null) _text = "";
			invalidate();
		}
		public function get text():String
		{
			return _text;
		}

		/**
		 * Returns a reference to the internal text field in the component.
		 */
		public function get textField():TextField
		{
			return _tf;
		}

		/**
		 * Gets / sets whether or not this text component will be editable.
		 */
		public function set editable(b:Boolean):void
		{
			_editable = b;
			invalidate();
		}
		public function get editable():Boolean
		{
			return _editable;
		}

		/**
		 * Gets / sets whether or not this text component will be selectable. Only meaningful if editable is false.
		 */
		public function set selectable(b:Boolean):void
		{
			_selectable = b;
			invalidate();
		}
		public function get selectable():Boolean
		{
			return _selectable;
		}

		/**
		 * Gets / sets whether or not text will be rendered as HTML or plain text.
		 */
		public function set html(b:Boolean):void
		{
			_html = b;
			invalidate();
		}
		public function get html():Boolean
		{
			return _html;
		}

        /**
         * Sets/gets whether this component is enabled or not.
         */
        public override function set enabled(value:Boolean):void
        {
            super.enabled = value;
            _tf.tabEnabled = value;
        }

	}
}


code:
/**
 * TextArea.as
 * Keith Peters
 * version 0.9.10
 *
 * A Text component for displaying multiple lines of text with a scrollbar.
 *
 * Copyright (c) 2011 Keith Peters
 *
 * 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.bit101.components
{
	import flash.display.DisplayObjectContainer;
	import flash.events.Event;
	import flash.events.MouseEvent;

	public class TextArea extends Text
	{
		protected var _scrollbar:VScrollBar;

		/**
		 * Constructor
		 * @param parent The parent DisplayObjectContainer on which to add this Label.
		 * @param xpos The x position to place this component.
		 * @param ypos The y position to place this component.
		 * @param text The initial text to display in this component.
		 */
		public function TextArea(parent:DisplayObjectContainer=null, xpos:Number=0, ypos:Number=0, text:String="")
		{
			super(parent, xpos, ypos, text);
		}

		/**
		 * Initilizes the component.
		 */
		protected override function init() : void
		{
			super.init();
			addEventListener(MouseEvent.MOUSE_WHEEL, onMouseWheel);
		}
		/**
		 * Creates and adds the child display objects of this component.
		 */
		override protected function addChildren():void
		{
			super.addChildren();
			_scrollbar = new VScrollBar(this, 0, 0, onScrollbarScroll);
			_tf.addEventListener(Event.SCROLL, onTextScroll);
		}

		/**
		 * Changes the thumb percent of the scrollbar based on how much text is shown in the text area.
		 */
		protected function updateScrollbar():void
		{
			var visibleLines:int = _tf.numLines - _tf.maxScrollV + 1;
			var percent:Number = visibleLines / _tf.numLines;
			_scrollbar.setSliderParams(1, _tf.maxScrollV, _tf.scrollV);
			_scrollbar.setThumbPercent(percent);
			_scrollbar.pageSize = visibleLines;
		}

		///////////////////////////////////
		// public methods
		///////////////////////////////////

		/**
		 * Draws the visual ui of the component.
		 */
		override public function draw():void
		{
			super.draw();

			_tf.width = _width - _scrollbar.width - 4;
			_scrollbar.x = _width - _scrollbar.width;
			_scrollbar.height = _height;
			_scrollbar.draw();
			addEventListener(Event.ENTER_FRAME, onTextScrollDelay);
		}

		///////////////////////////////////
		// event handlers
		///////////////////////////////////

		/**
		 * Waits one more frame before updating scroll bar.
		 * It seems that numLines and maxScrollV are not valid immediately after changing a TextField's size.
		 */
		protected function onTextScrollDelay(event:Event):void
		{
			removeEventListener(Event.ENTER_FRAME, onTextScrollDelay);
			updateScrollbar();
		}

		/**
		 * Called when the text in the text field is manually changed.
		 */
		protected override function onChange(event:Event):void
		{
			super.onChange(event);
			updateScrollbar();
		}

		/**
		 * Called when the scroll bar is moved. Scrolls text accordingly.
		 */
		protected function onScrollbarScroll(event:Event):void
		{
			_tf.scrollV = Math.round(_scrollbar.value);
		}

		/**
		 * Called when the text is scrolled manually. Updates the position of the scroll bar.
		 */
		protected function onTextScroll(event:Event):void
		{
			_scrollbar.value = _tf.scrollV;
			updateScrollbar();
		}

		/**
		 * Called when the mouse wheel is scrolled over the component.
		 */
		protected function onMouseWheel(event:MouseEvent):void
		{
			_scrollbar.value -= event.delta;
			_tf.scrollV = Math.round(_scrollbar.value);
		}

        /**
         * Sets/gets whether this component is enabled or not.
         */
        public override function set enabled(value:Boolean):void
        {
            super.enabled = value;
            _tf.tabEnabled = value;
        }

        /**
         * Sets / gets whether the scrollbar will auto hide when there is nothing to scroll.
         */
        public function set autoHideScrollBar(value:Boolean):void
        {
            _scrollbar.autoHide = value;
        }
        public function get autoHideScrollBar():Boolean
        {
            return _scrollbar.autoHide;
        }

	}
}


code:
package com.bit101.components {
    import flash.display.DisplayObjectContainer;
    import flash.events.Event;
    import flash.events.MouseEvent;
    import flash.text.TextField;

    public class TextFieldVScroll extends VScrollBar {
        protected var scrollTarget:TextField;

        public function TextFieldVScroll(_scrollTarget:TextField = null, parent:DisplayObjectContainer = null, xpos:Number = 0, ypos:Number = 0) {
            scrollTarget = _scrollTarget;
            super(parent, xpos, ypos, onScrollbarScroll);
            this.autoHide = true;
        }

        /**
         * Initilizes the component.
         */
        protected override function init():void {
            super.init();
            addEventListener(MouseEvent.MOUSE_WHEEL, onMouseWheel);
            scrollTarget.width = scrollTarget.width - this.width;
        }

        /**
         * Creates and adds the child display objects of this component.
         */
        override protected function addChildren():void {
            super.addChildren();
            scrollTarget.addEventListener(Event.SCROLL, onTextScroll);
        }

        /**
         * Changes the thumb percent of the scrollbar based on how much text is shown in the text area.
         */
        protected function updateScrollbar():void {
            var visibleLines:int = scrollTarget.numLines - scrollTarget.maxScrollV + 1;
            var percent:Number = visibleLines / scrollTarget.numLines;
            this.setSliderParams(1, scrollTarget.maxScrollV, scrollTarget.scrollV);
            this.setThumbPercent(percent);
            this.pageSize = visibleLines;
        }

        ///////////////////////////////////
        // public methods
        ///////////////////////////////////

        /**
         * Draws the visual ui of the component.
         */
        override public function draw():void {
            super.draw();
            this.x = (scrollTarget.x + scrollTarget.width) + 10;
            this.height = scrollTarget.height;
            addEventListener(Event.ENTER_FRAME, onTextScrollDelay);
        }

        ///////////////////////////////////
        // event handlers
        ///////////////////////////////////

        /**
         * Waits one more frame before updating scroll bar.
         * It seems that numLines and maxScrollV are not valid immediately after changing a TextField's size.
         */
        protected function onTextScrollDelay(event:Event):void {
            removeEventListener(Event.ENTER_FRAME, onTextScrollDelay);
            updateScrollbar();
        }

        /**
         * Called when the scroll bar is moved. Scrolls text accordingly.
         */
        protected function onScrollbarScroll(event:Event):void {
            scrollTarget.scrollV = Math.round(this.value);
        }

        /**
         * Called when the text is scrolled manually. Updates the position of the scroll bar.
         */
        protected function onTextScroll(event:Event):void {
            this.value = scrollTarget.scrollV;
            updateScrollbar();
        }

        /**
         * Called when the mouse wheel is scrolled over the component.
         */
        protected function onMouseWheel(event:MouseEvent):void {
            this.value -= event.delta;
            scrollTarget.scrollV = Math.round(this.value);
        }

        /**
         * Sets/gets whether this component is enabled or not.
         */
        public override function set enabled(value:Boolean):void {
            super.enabled = value;
            scrollTarget.tabEnabled = value;
        }
    }
}


code:
/**
 * UISlider.as
 * Keith Peters
 * version 0.9.10
 *
 * A Slider with a label and value label. Abstract base class for VUISlider and HUISlider
 *
 * Copyright (c) 2011 Keith Peters
 *
 * 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.bit101.components
{
	import flash.display.DisplayObjectContainer;
	import flash.events.Event;

	[Event(name="change", type="flash.events.Event")]
	public class UISlider extends Component
	{
		protected var _label:Label;
		protected var _valueLabel:Label;
		protected var _slider:Slider;
		protected var _precision:int = 1;
		protected var _sliderClass:Class;
		protected var _labelText:String;
		protected var _tick:Number = 1;

		/**
		 * Constructor
		 * @param parent The parent DisplayObjectContainer on which to add this UISlider.
		 * @param xpos The x position to place this component.
		 * @param ypos The y position to place this component.
		 * @param label The initial string to display as this component's label.
		 * @param defaultHandler The event handling function to handle the default event for this component (change in this case).
		 */
		public function UISlider(parent:DisplayObjectContainer = null, xpos:Number = 0, ypos:Number = 0, label:String = "", defaultHandler:Function = null)
		{
			_labelText = label;
			super(parent, xpos, ypos);
			if(defaultHandler != null)
			{
				addEventListener(Event.CHANGE, defaultHandler);
			}
			formatValueLabel();
		}

		/**
		 * Creates and adds the child display objects of this component.
		 */
		override protected function addChildren():void
		{
			_label = new Label(this, 0, 0);
			_slider = new _sliderClass(this, 0, 0, onSliderChange);
			_valueLabel = new Label(this);
		}

		/**
		 * Formats the value of the slider to a string based on the current level of precision.
		 */
		protected function formatValueLabel():void
		{
			if(isNaN(_slider.value))
			{
				_valueLabel.text = "NaN";
				return;
			}
			var mult:Number = Math.pow(10, _precision);
			var val:String = (Math.round(_slider.value * mult) / mult).toString();
			var parts:Array = val.split(".");
			if(parts[1] == null)
			{
				if(_precision > 0)
				{
					val += ".";
				}
				for(var i:uint = 0; i < _precision; i++)
				{
					val += "0";
				}
			}
			else if(parts[1].length < _precision)
			{
				for(i = 0; i < _precision - parts[1].length; i++)
				{
					val += "0";
				}
			}
			_valueLabel.text = val;
			positionLabel();
		}

		/**
		 * Positions the label when it has changed. Implemented in child classes.
		 */
		protected function positionLabel():void
		{

		}

		///////////////////////////////////
		// public methods
		///////////////////////////////////

		/**
		 * Draws the visual ui of this component.
		 */
		override public function draw():void
		{
			super.draw();
			_label.text = _labelText;
			_label.draw();
			formatValueLabel();
		}

		/**
		 * Convenience method to set the three main parameters in one shot.
		 * @param min The minimum value of the slider.
		 * @param max The maximum value of the slider.
		 * @param value The value of the slider.
		 */
		public function setSliderParams(min:Number, max:Number, value:Number):void
		{
			_slider.setSliderParams(min, max, value);
		}

		///////////////////////////////////
		// event handlers
		///////////////////////////////////

		/**
		 * Handler called when the slider's value changes.
		 * @param event The Event passed by the slider.
		 */
		protected function onSliderChange(event:Event):void
		{
			formatValueLabel();
			dispatchEvent(new Event(Event.CHANGE));
		}

		///////////////////////////////////
		// getter/setters
		///////////////////////////////////

		/**
		 * Sets / gets the current value of this slider.
		 */
		public function set value(v:Number):void
		{
			_slider.value = v;
			formatValueLabel();
		}
		public function get value():Number
		{
			return _slider.value;
		}

		/**
		 * Gets / sets the maximum value of this slider.
		 */
		public function set maximum(m:Number):void
		{
			_slider.maximum = m;
		}
		public function get maximum():Number
		{
			return _slider.maximum;
		}

		/**
		 * Gets / sets the minimum value of this slider.
		 */
		public function set minimum(m:Number):void
		{
			_slider.minimum = m;
		}
		public function get minimum():Number
		{
			return _slider.minimum;
		}

		/**
		 * Gets / sets the number of decimals to format the value label. Does not affect the actual value of the slider, just the number shown.
		 */
		public function set labelPrecision(decimals:int):void
		{
			_precision = decimals;
		}
		public function get labelPrecision():int
		{
			return _precision;
		}

		/**
		 * Gets / sets the text shown in this component's label.
		 */
		public function set label(str:String):void
		{
			_labelText = str;
			draw();
		}
		public function get label():String
		{
			return _labelText;
		}

		/**
		 * Gets / sets the tick value of this slider. This round the value to the nearest multiple of this number.
		 */
		public function set tick(t:Number):void
		{
			_tick = t;
			_slider.tick = _tick;
		}
		public function get tick():Number
		{
			return _tick;
		}

	}
}


code:
/**
 * VBox.as
 * Keith Peters
 * version 0.9.10
 *
 * A layout container for vertically aligning other components.
 *
 * Copyright (c) 2011 Keith Peters
 *
 * 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.bit101.components
{
    import flash.display.DisplayObject;
    import flash.display.DisplayObjectContainer;
    import flash.events.Event;

	[Event(name="resize", type="flash.events.Event")]
	public class VBox extends Component
	{
		protected var _spacing:Number = 5;
		private var _alignment:String = NONE;

		public static const LEFT:String = "left";
		public static const RIGHT:String = "right";
		public static const CENTER:String = "center";
		public static const NONE:String = "none";

		/**
		 * Constructor
		 * @param parent The parent DisplayObjectContainer on which to add this PushButton.
		 * @param xpos The x position to place this component.
		 * @param ypos The y position to place this component.
		 */
		public function VBox(parent:DisplayObjectContainer = null, xpos:Number = 0, ypos:Number =  0)
		{
			super(parent, xpos, ypos);
		}

		/**
		 * Override of addChild to force layout;
		 */
		override public function addChild(child:DisplayObject) : DisplayObject
		{
			super.addChild(child);
			child.addEventListener(Event.RESIZE, onResize);
			draw();
			return child;
		}

		/**
		 * Override of addChildAt to force layout;
		 */
		override public function addChildAt(child:DisplayObject, index:int) : DisplayObject
		{
			super.addChildAt(child, index);
			child.addEventListener(Event.RESIZE, onResize);
			draw();
			return child;
		}

        /**
         * Override of removeChild to force layout;
         */
        override public function removeChild(child:DisplayObject):DisplayObject
        {
            super.removeChild(child);
            child.removeEventListener(Event.RESIZE, onResize);
            draw();
            return child;
        }

        /**
         * Override of removeChild to force layout;
         */
        override public function removeChildAt(index:int):DisplayObject
        {
            var child:DisplayObject = super.removeChildAt(index);
            child.removeEventListener(Event.RESIZE, onResize);
            draw();
            return child;
        }

		/**
		 * Internal handler for resize event of any attached component. Will redo the layout based on new size.
		 */
		protected function onResize(event:Event):void
		{
			invalidate();
		}

		/**
		 * Sets element's x positions based on alignment value.
		 */
		protected function doAlignment():void
		{
			if(_alignment != NONE)
			{
				for(var i:int = 0; i < numChildren; i++)
				{
					var child:DisplayObject = getChildAt(i);
					if(_alignment == LEFT)
					{
						child.x = 0;
					}
					else if(_alignment == RIGHT)
					{
						child.x = _width - child.width;
					}
					else if(_alignment == CENTER)
					{
						child.x = (_width - child.width) / 2;
					}
				}
			}
		}

		/**
		 * Draws the visual ui of the component, in this case, laying out the sub components.
		 */
		override public function draw() : void
		{
			_width = 0;
			_height = 0;
			var ypos:Number = 0;
			for(var i:int = 0; i < numChildren; i++)
			{
				var child:DisplayObject = getChildAt(i);
				child.y = ypos;
				ypos += child.height;
				ypos += _spacing;
				_height += child.height;
				_width = Math.max(_width, child.width);
			}

			doAlignment();
			_height += _spacing * (numChildren - 1);
		}

		/**
		 * Gets / sets the spacing between each sub component.
		 */
		public function set spacing(s:Number):void
		{
			_spacing = s;
			invalidate();
		}
		public function get spacing():Number
		{
			return _spacing;
		}

		/**
		 * Gets / sets the horizontal alignment of components in the box.
		 */
		public function set alignment(value:String):void
		{
			_alignment = value;
			invalidate();
		}
		public function get alignment():String
		{
			return _alignment;
		}

	}
}


code:
/**
 * VRangeSlider.as
 * Keith Peters
 * version 0.9.10
 *
 * A vertical slider with two handles for selecting a range of values.
 *
 * Copyright (c) 2011 Keith Peters
 *
 * 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.bit101.components
{
	import flash.display.DisplayObjectContainer;

	public class VRangeSlider extends RangeSlider
	{
		public function VRangeSlider(parent:DisplayObjectContainer=null, xpos:Number=0, ypos:Number=0, defaultHandler:Function = null)
		{
			super(VERTICAL, parent, xpos, ypos, defaultHandler);
		}
	}
}


code:
/**
 * VScrollBar.as
 * Keith Peters
 * version 0.9.10
 *
 * A vertical scroll bar for use in other components.
 *
 * Copyright (c) 2011 Keith Peters
 *
 * 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.bit101.components
{
	import flash.display.DisplayObjectContainer;

	public class VScrollBar extends ScrollBar
	{
		/**
		 * Constructor
		 * @param parent The parent DisplayObjectContainer on which to add this ScrollBar.
		 * @param xpos The x position to place this component.
		 * @param ypos The y position to place this component.
		 * @param defaultHandler The event handling function to handle the default event for this component (change in this case).
		 */
		public function VScrollBar(parent:DisplayObjectContainer=null, xpos:Number=0, ypos:Number=0, defaultHandler:Function=null)
		{
			super(Slider.VERTICAL, parent, xpos, ypos, defaultHandler);
		}
	}
}


code:
/**
 * VSlider.as
 * Keith Peters
 * version 0.9.10
 *
 * A Vertical Slider component for choosing values.
 *
 * Copyright (c) 2011 Keith Peters
 *
 * 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.bit101.components
{
	import flash.display.DisplayObjectContainer;

	public class VSlider extends Slider
	{
		/**
		 * Constructor
		 * @param parent The parent DisplayObjectContainer on which to add this Slider.
		 * @param xpos The x position to place this component.
		 * @param ypos The y position to place this component.
		 * @param defaultHandler The event handling function to handle the default event for this component.
		 */
		public function VSlider(parent:DisplayObjectContainer=null, xpos:Number=0, ypos:Number=0, defaultHandler:Function = null)
		{
			super(Slider.VERTICAL, parent, xpos, ypos, defaultHandler);
		}
	}
}


code:
/**
 * VUISlider.as
 * Keith Peters
 * version 0.9.10
 *
 * A vertical Slider with a label and value label.
 *
 * Copyright (c) 2011 Keith Peters
 *
 * 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.bit101.components
{
	import flash.display.DisplayObjectContainer;

	public class VUISlider extends UISlider
	{

		/**
		 * Constructor
		 * @param parent The parent DisplayObjectContainer on which to add this VUISlider.
		 * @param x The x position to place this component.
		 * @param y The y position to place this component.
		 * @param label The string to use as the label for this component.
		 * @param defaultHandler The event handling function to handle the default event for this component.
		 */
		public function VUISlider(parent:DisplayObjectContainer = null, xpos:Number = 0, ypos:Number = 0, label:String = "", defaultHandler:Function = null)
		{
			_sliderClass = VSlider;
			super(parent, xpos, ypos, label, defaultHandler);
		}

		/**
		 * Initializes this component.
		 */
		protected override function init():void
		{
			super.init();
			setSize(20, 146);
		}

		///////////////////////////////////
		// public methods
		///////////////////////////////////

		override public function draw():void
		{
			super.draw();
			_label.x = width / 2 - _label.width / 2;

			_slider.x = width / 2 - _slider.width / 2;
			_slider.y = _label.height + 5;
			_slider.height = height - _label.height - _valueLabel.height - 10;

			_valueLabel.x = width / 2 - _valueLabel.width / 2;
			_valueLabel.y = _slider.y + _slider.height + 5;
		}

		override protected function positionLabel():void
		{
			_valueLabel.x = width / 2 - _valueLabel.width / 2;
		}

		///////////////////////////////////
		// event handlers
		///////////////////////////////////

		///////////////////////////////////
		// getter/setters
		///////////////////////////////////

		override public function get width():Number
		{
			if(_label == null) return _width;
			return Math.max(_width, _label.width);
		}

	}
}


code:
/**
 * WheelMenu.as
 * Keith Peters
 * version 0.9.10
 *
 * A radial menu that pops up around the mouse.
 *
 * Copyright (c) 2011 Keith Peters
 *
 * 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.
 *
 *
 *
 * Components with text make use of the font PF Ronda Seven by Yuusuke Kamiyamane
 * This is a free font obtained from http://www.dafont.com/pf-ronda-seven.font
 */

package com.bit101.components
{
	import flash.display.DisplayObjectContainer;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.filters.DropShadowFilter;

	[Event(name="select", type="flash.events.Event")]
	public class WheelMenu extends Component
	{
		protected var _borderColor:uint = 0xcccccc;
		protected var _buttons:Array;
		protected var _color:uint = 0xffffff;
		protected var _highlightColor:uint = 0xeeeeee;
		protected var _iconRadius:Number;
		protected var _innerRadius:Number;
		protected var _items:Array;
		protected var _numButtons:int;
		protected var _outerRadius:Number;
		protected var _selectedIndex:int = -1;
		protected var _startingAngle:Number = -90;

		/**
		 * Constructor
		 * @param parent The parent DisplayObjectContainer on which to add this component.
		 * @param numButtons The number of segments in the menu
		 * @param outerRadius The radius of the menu as a whole.
		 * @parem innerRadius The radius of the inner circle at the center of the menu.
		 * @param defaultHandler The event handling function to handle the default event for this component (select in this case).
		 */
		public function WheelMenu(parent:DisplayObjectContainer, numButtons:int, outerRadius:Number = 80, iconRadius:Number = 60, innerRadius:Number = 10, defaultHandler:Function = null)
		{
			_numButtons = numButtons;
			_outerRadius = outerRadius;
			_iconRadius = iconRadius;
			_innerRadius = innerRadius;
			addEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
			super(parent);

			if(defaultHandler != null)
			{
				addEventListener(Event.SELECT, defaultHandler);
			}
		}

		///////////////////////////////////
		// protected methods
		///////////////////////////////////

		/**
		 * Initializes the component.
		 */
		override protected function init():void
		{
			super.init();
			_items = new Array();
			makeButtons();

			filters = [new DropShadowFilter(4, 45, 0, 1, 4, 4, .2, 4)];
		}

		/**
		 * Creates the buttons that make up the wheel menu.
		 */
		protected function makeButtons():void
		{
			_buttons = new Array();
			for(var i:int = 0; i < _numButtons; i++)
			{
				var btn:ArcButton = new ArcButton(Math.PI * 2 / _numButtons, _outerRadius, _iconRadius, _innerRadius);
				btn.id = i;
				btn.rotation = _startingAngle + 360 / _numButtons * i;
				btn.addEventListener(Event.SELECT, onSelect);
				addChild(btn);
				_buttons.push(btn);
			}
		}

		///////////////////////////////////
		// public methods
		///////////////////////////////////

		/**
		 * Hides the menu.
		 */
		public function hide():void
		{
			visible = false;
			if(stage != null)
			{
				stage.removeEventListener(MouseEvent.MOUSE_UP, onStageMouseUp);
			}
		}

		/**
		 * Sets the icon / text and data for a specific menu item.
		 * @param index The index of the item to set icon/text and data for.
		 * @iconOrLabel Either a display object instance, a class that extends DisplayObject, or text to show in a label.
		 * @data Any data to associate with the item.
		 */
		public function setItem(index:int, iconOrLabel:Object, data:Object = null):void
		{
			_buttons[index].setIcon(iconOrLabel);
			_items[index] = data;
		}

		/**
		 * Shows the menu - placing it on top level of parent and centering around mouse.
		 */
		public function show():void
		{
			parent.addChild(this);
			x = Math.round(parent.mouseX);
			y = Math.round(parent.mouseY);
			_selectedIndex = -1;
			visible = true;
			stage.addEventListener(MouseEvent.MOUSE_UP, onStageMouseUp, true);
		}

		///////////////////////////////////
		// event handlers
		///////////////////////////////////

		/**
		 * Called when the component is added to the stage. Adds mouse listeners to the stage.
		 */
		protected function onAddedToStage(event:Event):void
		{
			hide();
			addEventListener(Event.REMOVED_FROM_STAGE, onRemovedFromStage);
		}

		/**
		 * Called when the component is removed from the stage. Removes mouse listeners from stage.
		 */
		protected function onRemovedFromStage(event:Event):void
		{
			stage.removeEventListener(MouseEvent.MOUSE_UP, onStageMouseUp);
			removeEventListener(Event.REMOVED_FROM_STAGE, onRemovedFromStage);
		}

		/**
		 * Called when one of the buttons is selected. Sets selected index and dispatches select event.
		 */
		protected function onSelect(event:Event):void
		{
			_selectedIndex = event.target.id;
			dispatchEvent(new Event(Event.SELECT));
		}

		/**
		 * Called when mouse is released. Hides menu.
		 */
		protected function onStageMouseUp(event:MouseEvent):void
		{
			hide();
		}

		///////////////////////////////////
		// getter / setters
		///////////////////////////////////

		/**
		 * Gets / sets the color of the border around buttons.
		 */
		public function set borderColor(value:uint):void
		{
			_borderColor = value;
			for(var i:int = 0; i < _numButtons; i++)
			{
				_buttons[i].borderColor = _borderColor;
			}
		}
		public function get borderColor():uint
		{
			return _borderColor;
		}

		/**
		 * Gets / sets the base color of buttons.
		 */
		public function set color(value:uint):void
		{
			_color = value;
			for(var i:int = 0; i < _numButtons; i++)
			{
				_buttons[i].color = _color;
			}
		}
		public function get color():uint
		{
			return _color;
		}

		/**
		 * Gets / sets the highlighted color of buttons.
		 */
		public function set highlightColor(value:uint):void
		{
			_highlightColor = value;
			for(var i:int = 0; i < _numButtons; i++)
			{
				_buttons[i].highlightColor = _highlightColor;
			}
		}
		public function get highlightColor():uint
		{
			return _highlightColor;
		}

		/**
		 * Gets the selected index.
		 */
		public function get selectedIndex():int
		{
			return _selectedIndex;
		}

		/**
		 * Gets the selected item.
		 */
		public function get selectedItem():Object
		{
			return _items[_selectedIndex];
		}

	}
}

/**
 * ArcButton class. Internal class only used by WheelMenu.
 */
import flash.display.DisplayObject;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.display.Shape;
import com.bit101.components.Label;

class ArcButton extends Sprite
{
	public var id:int;

	protected var _arc:Number;
	protected var _bg:Shape;
	protected var _borderColor:uint = 0xcccccc;
	protected var _color:uint = 0xffffff;
	protected var _highlightColor:uint = 0xeeeeee;
	protected var _icon:DisplayObject;
	protected var _iconHolder:Sprite;
	protected var _iconRadius:Number;
	protected var _innerRadius:Number;
	protected var _outerRadius:Number;

	/**
	 * Constructor.
	 * @param arc The radians of the arc to draw.
	 * @param outerRadius The outer radius of the arc.
	 * @param innerRadius The inner radius of the arc.
	 */
	public function ArcButton(arc:Number, outerRadius:Number, iconRadius:Number, innerRadius:Number)
	{
		_arc = arc;
		_outerRadius = outerRadius;
		_iconRadius = iconRadius;
		_innerRadius = innerRadius;

		_bg = new Shape();
		addChild(_bg);

		_iconHolder = new Sprite();
		addChild(_iconHolder);

		drawArc(0xffffff);
		addEventListener(MouseEvent.MOUSE_OVER, onMouseOver);
		addEventListener(MouseEvent.MOUSE_OUT, onMouseOut);
		addEventListener(MouseEvent.MOUSE_UP, onMouseGoUp);
	}

	///////////////////////////////////
	// protected methods
	///////////////////////////////////

	/**
	 * Draws an arc of the specified color.
	 * @param color The color to draw the arc.
	 */
	protected function drawArc(color:uint):void
	{
		_bg.graphics.clear();
		_bg.graphics.lineStyle(2, _borderColor);
		_bg.graphics.beginFill(color);
		_bg.graphics.moveTo(_innerRadius, 0);
		_bg.graphics.lineTo(_outerRadius, 0);
		for(var i:Number = 0; i < _arc; i += .05)
		{
			_bg.graphics.lineTo(Math.cos(i) * _outerRadius, Math.sin(i) * _outerRadius);
		}
		_bg.graphics.lineTo(Math.cos(_arc) * _outerRadius, Math.sin(_arc) * _outerRadius);
		_bg.graphics.lineTo(Math.cos(_arc) * _innerRadius, Math.sin(_arc) * _innerRadius);
		for(i = _arc; i > 0; i -= .05)
		{
			_bg.graphics.lineTo(Math.cos(i) * _innerRadius, Math.sin(i) * _innerRadius);
		}
		_bg.graphics.lineTo(_innerRadius, 0);

		graphics.endFill();
	}

	///////////////////////////////////
	// public methods
	///////////////////////////////////

	/**
	 * Sets the icon or label of this button.
	 * @param iconOrLabel Either a display object instance, a class that extends DisplayObject, or text to show in a label.
	 */
	public function setIcon(iconOrLabel:Object):void
	{
		if(iconOrLabel == null) return;
		while(_iconHolder.numChildren > 0) _iconHolder.removeChildAt(0);
		if(iconOrLabel is Class)
		{
			_icon = new (iconOrLabel as Class)() as DisplayObject;
		}
		else if(iconOrLabel is DisplayObject)
		{
			_icon = iconOrLabel as DisplayObject;
		}
		else if(iconOrLabel is String)
		{
			_icon = new Label(null, 0, 0, iconOrLabel as String);
			(_icon as Label).draw();
		}
		if(_icon != null)
		{
			var angle:Number = _bg.rotation * Math.PI / 180;
			_icon.x = Math.round(-_icon.width / 2);
			_icon.y = Math.round(-_icon.height / 2);
			_iconHolder.addChild(_icon);
			_iconHolder.x = Math.round(Math.cos(angle + _arc / 2) * _iconRadius);
			_iconHolder.y = Math.round(Math.sin(angle + _arc / 2) * _iconRadius);
		}
	}

	///////////////////////////////////
	// event handlers
	///////////////////////////////////

	/**
	 * Called when mouse moves over this button. Draws highlight.
	 */
	protected function onMouseOver(event:MouseEvent):void
	{
		drawArc(_highlightColor);
	}

	/**
	 * Called when mouse moves out of this button. Draw base color.
	 */
	protected function onMouseOut(event:MouseEvent):void
	{
		drawArc(_color);
	}

	/**
	 * Called when mouse is released over this button. Dispatches select event.
	 */
	protected function onMouseGoUp(event:MouseEvent):void
	{
		dispatchEvent(new Event(Event.SELECT));
	}

	///////////////////////////////////
	// getter / setters
	///////////////////////////////////

	/**
	 * Sets / gets border color.
	 */
	public function set borderColor(value:uint):void
	{
		_borderColor = value;
		drawArc(_color);
	}
	public function get borderColor():uint
	{
		return _borderColor;
	}

	/**
	 * Sets / gets base color.
	 */
	public function set color(value:uint):void
	{
		_color = value;
		drawArc(_color);
	}
	public function get color():uint
	{
		return _color;
	}

	/**
	 * Sets / gets highlight color.
	 */
	public function set highlightColor(value:uint):void
	{
		_highlightColor = value;
	}
	public function get highlightColor():uint
	{
		return _highlightColor;
	}

	/**
	 * Overrides rotation by rotating arc only, allowing label / icon to be unrotated.
	 */
	override public function set rotation(value:Number):void
	{
		_bg.rotation = value;
	}
	override public function get rotation():Number
	{
		return _bg.rotation;
	}

}