In case Flash no longer exists; a copy of this site is included in the Flashpoint archive's "ultimate" collection.

Dead Code Preservation :: Archived AS3 works from wonderfl.net

flash on 2010-5-29

Get Adobe Flash player
by lukluk 29 May 2010
    Embed
package  {
	import com.bit101.components.*;
	import flash.display.*;
	import flash.events.*;
	public class FileTree2 extends Sprite {
		private var style:TreeStyle;
		private var rootLimb1:TreeLimb;
		private var rootLimb2:TreeLimb;
		private var sliders:Vector.<HUISlider>;
		private var sliderSpacing:HUISlider;
		private var sliderIndent:HUISlider;
		private var sliderButton:HUISlider;
		private var buttonGroup:VBox;
		private var buttonGroupBottom:VBox;
		public function FileTree2() {
			var loader:IconLoader = new IconLoader();
			loader.create(onDecode);
		}
		private function onDecode(icons:Vector.<BitmapData>):void {
			var win1:TreeWindow = new TreeWindow(this, 10, 80, "Actions");
			var win2:TreeWindow = new TreeWindow(this, 240, 80, "Balance Sheet");
			win1.setWindowSize(215, 350);
			win2.setWindowSize(215, 350);
			win1.hasMinimizeButton = true;
			win2.hasMinimizeButton = true;
			win1.minimized = true;
			win2.minimized = true;
			rootLimb1 = win1.folder;
			rootLimb1.label = "Market";
			rootLimb1.addFolder("EventDispatcher").addFolders(["LoaderInfo", "DisplayObject", "URLLoader", "URLStream", "Sound", "SoundChannel"]);
			rootLimb1.getLimbByLabel("EventDispatcher", true)[0].addFile("etc...", 0);
			rootLimb1.getLimbByLabel("DisplayObject", true)[0].addFolders(["AVM1Movie", "Bitmap", "InteractiveObject", "MorphShape", "Shape", "StaticText", "Video"]);
			rootLimb1.getLimbByLabel("InteractiveObject", true)[0].addFolders(["DisplayObjectContainer", "SimpleButton"])[0].addFolders(["Loader", "Sprite", "Stage", "TextLine"]);
			rootLimb1.getLimbByLabel("Video", true)[0].addFolder("VideoPlayer");
			rootLimb1.getLimbByLabel("Sprite", true)[0].addFolder("MovieClip");
			rootLimb1.addEventListener(TreeEvent.CHANGE_SELECT, onChangeSelect);
			//
			style = new TreeStyle();
			style.closeIcon = icons[0];
			style.openIcon = icons[1];
			style.icons = icons.slice(2, icons.length);
			style.textFormat.size = 12;
			style.lineSpacing = 16;
			rootLimb1.setStyle(style);
			//
			rootLimb2 = win2.folder;
			rootLimb2.label = "Balance Sheet";
			//var sortFolder:TreeLimb = rootLimb2.addFile("sort test", 5);
			//sortFolder.addFiles(["10", "2", "8", "3", "0", "7"]);
			//sortFolder.sortOn("label", Array.NUMERIC);
			rootLimb2.addFolder("Assets");
			rootLimb2.addFolder("Liabilities");
			rootLimb2.getLimbByLabel("Assets", true)[0].addFolders(["Cash", "Accounts Receivable", "Materials", "Intangibles", "Fixed AssetsShape", "StaticText", "Video"]);
			
			
			var style2:TreeStyle = style.clone();
			style2.textFormat.color = 0x57A7D7;
			style2.selectedBoxColor = 0x888888;
			rootLimb2.setStyle(style2);

			buttonGroup = new VBox(this);
			buttonGroup.x = 10;
			buttonGroup.y = 10
			buttonGroup.spacing = 2;

			new PushButton(buttonGroup, 0, 0, "START GAME", onClickMove).width = 80;
			new PushButton(buttonGroup, 0, 0, "TUTORIAL", onClickDelete).width = 80;
			new PushButton(buttonGroup, 0, 0, "SETTINGS", onClickDelete).width = 80;
			new PushButton(buttonGroup, 0, 0, "NEXT TURN", onClickDelete).width = 80;

			buttonGroup.enabled = false;
		

			buttonGroupBottom = new VBox(this);
			buttonGroupBottom.x = 310;
			buttonGroupBottom.y = 310
			buttonGroupBottom.spacing = 2;

			new PushButton(buttonGroupBottom , 0, 0, "NEXT TURN", onClickMove).width = 80;
			new PushButton(buttonGroupBottom , 0, 0, "CHAT", onClickDelete).width = 80;
			new PushButton(buttonGroupBottom , 0, 0, "STATISTICS", onClickDelete).width = 80;
			new PushButton(buttonGroupBottom , 0, 0, "INVITE", onClickDelete).width = 80;

			buttonGroupBottom .enabled = false;
		

			var vox1:VBox = new VBox(this);
			vox1.x = 100;
			vox1.y = 10;
			vox1.spacing = -5;
			sliders = new Vector.<HUISlider>();
			var labels:Array = ["LINE SPACING", "LINE INDENT", "BUTTON SIZE", "FONT-SIZE"];
			var values:Array = [style.lineSpacing, style.lineIndent, style.buttonSize, style.textFormat.size];
			var mins:Array = [0, 0, 5, 1];
			var maxes:Array = [100, 100, 27, 40];
			for (var i:int = 0; i < labels.length; i++) {
				var slider:HUISlider = new HUISlider(vox1, 0, 0, labels[i]);
				slider.minimum = mins[i];
				slider.maximum = maxes[i];
				slider.value = values[i];
				slider.addEventListener(Event.CHANGE, onChangeSlider);
				sliders.push(slider);
			}
		}
		private function onChangeSelect(e:TreeEvent):void {
			buttonGroup.enabled = (!e.targetLimb.isRoot && e.targetLimb.getSelectedLimbs().length > 0);
		}
		private function onClickDelete(...arg):void {
			var selected:Vector.<TreeLimb> = rootLimb1.getSelectedLimbs();
			if (selected.length == 0 || selected[0].isRoot) return;
			selected[0].dispose();
		}
		private function onClickMove(...arg):void {
			var selected:Vector.<TreeLimb> = rootLimb1.getSelectedLimbs();
			if (selected.length == 0 || selected[0].isRoot) return;
			rootLimb2.addLimb(selected[0]);
			selected[0].setSelect(false);
		}
		private function onChangeSlider(...arg):void{
			style.lineSpacing = sliders[0].value;
			style.lineIndent = sliders[1].value;
			style.buttonSize = int(sliders[2].value / 2) * 2 + 1;
			style.textFormat.size = sliders[3].value;
			rootLimb1.updateStyle();
		}
	}
}
import com.bit101.components.*;
import flash.display.*;
import flash.events.*;
import flash.geom.*;
import flash.text.*;
import flash.utils.*;
import mx.utils.*;

class TreeWindow extends Window {
	private var _workSpace:Rectangle;
	private var _container:Sprite;
	private var _bg:Sprite;
	private var _folder:TreeLimb;
	private var _vscroll:VScrollBar;
	private var _hscroll:VScrollBar;
	private var _padding:Number = 10;
	private var _bgcolor:uint = 0xF9F9F9;
	public function get folder():TreeLimb { return _folder; }
	public function get bgcolor():uint { return _bgcolor; }
	public function set bgcolor(value:uint):void {
		_bgcolor = value;
		var ct:ColorTransform = new ColorTransform();
		ct.color = _bgcolor;
		_bg.transform.colorTransform = ct;
	}
	public function TreeWindow(parent:DisplayObjectContainer = null, xpos:Number = 0, ypos:Number = 0, title:String = "Window") {
		super(parent, xpos, ypos, title);
		_workSpace = new Rectangle();
		_bg = content.addChild(new Sprite()) as Sprite;
		_bg.graphics.clear();
		_bg.graphics.beginFill(0xFFFFFF);
		_bg.graphics.drawRect(0, 0, 100, 100);
		_bg.graphics.endFill();
		_bg.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDownBg);
		addEventListener(MouseEvent.MOUSE_WHEEL, onMouseWheel);
		_container = content.addChild(new Sprite()) as Sprite;
		_folder = _container.addChild(new TreeLimb()) as TreeLimb;
		_folder.addEventListener(TreeEvent.RESIZE, onResize);
		_vscroll = new VScrollBar(content, 0, 0, onVScroll);
		_hscroll = new VScrollBar(content, 0, 0, onHScroll);
		_hscroll.rotation = -90;
		setWindowSize(width, height);
		var rect:Rectangle = _folder.getVisibleRect();
		rect.inflate(_padding, _padding);
		var px:int = int(rect.left), py:int = int(rect.top);
		_hscroll.setSliderParams(px, px + 100, px);
		_vscroll.setSliderParams(py, py + 100, py);
		bgcolor = _bgcolor;
	}
	private function onMouseWheel(e:MouseEvent):void {
		var vec:int = e.delta / Math.abs(e.delta);
		if (!_vscroll.enabled) return;
		_vscroll.value += vec * -30;
	}
	private function onMouseDownBg(e:MouseEvent):void {
		_folder.resetSelect();
	}
	private function onHScroll(...arg):void{
		_folder.x = int(_workSpace.x - _hscroll.value);
	}
	private function onVScroll(...arg):void {
		_folder.y = int(_workSpace.y - _vscroll.value);
	}
	private function onResize(e:TreeEvent):void {
		e.bounds.inflate(_padding, _padding);
		var perV:Number = Math.min(2, _workSpace.height / e.bounds.height);
		var perH:Number = Math.min(2, _workSpace.width / e.bounds.width);
		_vscroll.enabled = (perV < 1);
		_hscroll.enabled = (perH < 1);
		if (perV < 0.1 || isNaN(perV)) perV = 0.1;
		if (perH < 0.1 || isNaN(perH)) perH = 0.1;
		_vscroll.setThumbPercent(perV);
		_hscroll.setThumbPercent(perH);
		if (!_vscroll.enabled) _vscroll.value = e.bounds.top;
		if (!_hscroll.enabled) _hscroll.value = e.bounds.left;
		_vscroll.setSliderParams(e.bounds.top, e.bounds.height - _workSpace.height - _padding, _vscroll.value);
		_hscroll.setSliderParams(e.bounds.left, e.bounds.width - _workSpace.width - _padding, _hscroll.value);
	}
	public function setWindowSize(w:Number, h:Number):void {
		setSize(w, h);
		_workSpace = new Rectangle(0, 0, width - _vscroll.width, height - _titleBar.height - _hscroll.width);
		_hscroll.x = _workSpace.left;
		_hscroll.y = _workSpace.bottom + 10;
		_vscroll.x = _workSpace.right;
		_vscroll.y = _workSpace.top;
		_hscroll.height = _workSpace.width;
		_vscroll.height = _workSpace.height;
		_container.scrollRect = _workSpace;
		_bg.width = _workSpace.width;
		_bg.height = _workSpace.height;
	}
	public function dispose():void {
		_folder.dispose();
		removeEventListener(MouseEvent.MOUSE_WHEEL, onMouseWheel);
		_bg.removeEventListener(MouseEvent.MOUSE_DOWN, onMouseDownBg);
		_folder.removeEventListener(TreeEvent.RESIZE, onResize);
	}
}

class TreeStyle {
	public var openIcon:BitmapData;	
	public var closeIcon:BitmapData;	
	public var noIcon:BitmapData;	
	public var icons:Vector.<BitmapData> = new Vector.<BitmapData>();	
	public var textFormat:TextFormat = new TextFormat("_sans", 14, 0x000000);	
	public var selectedBoxColor:uint = 0x4CA4D8;	
	public var selectedLabelColor:uint = 0xFFFFFF;	
	public var dotV:BitmapData;	
	public var dotH:BitmapData;	
	public var buttonSize:Number = 11;	
	public var lineSpacing:Number = 20;	
	public var lineIndent:Number = 14;	
	public var labelOffset:Point = new Point(10, 0);	
	public var treeOffset:Point = new Point(8, 8);
	public function TreeStyle():void {
		dotV = new BitmapData(1, 2, true, 0);
		dotV.setPixel32(0, 0, 0xFF000000);
		dotH = new BitmapData(2, 1, true, 0);
		dotH.setPixel32(0, 0, 0xFF000000);
		noIcon = new BitmapData(3, 3, false, 0xFF000000);
		openIcon = new BitmapData(7, 7, false, 0xFF000000);
		openIcon.fillRect(new Rectangle(1, 1, 5, 5), 0xFFFFFFFF);
		closeIcon = openIcon.clone();
		closeIcon.fillRect(new Rectangle(2, 2, 3, 3), 0xFF000000);
	}
	public function clone():TreeStyle {
		var newStyle:TreeStyle = new TreeStyle();
		for each(var v:XML in describeType(this).variable) {
			if (v.@type.indexOf("Vector") != -1) for each(var bd:BitmapData in this[v.@name]) newStyle.icons.push(bd.clone());
			else if (v.@type.indexOf("BitmapData") != -1) newStyle[v.@name] = this[v.@name].clone();
			else if (v.@type.indexOf("TextFormat") == -1) newStyle[v.@name] = this[v.@name];
		}
		var ba:ByteArray = new ByteArray();
		ba.writeObject(textFormat);
		ba.position = 0;
		var obj:Object = ba.readObject();
		for (var k:String in obj) newStyle.textFormat[k] = obj[k];
		return newStyle;
	}
}


class TreeLimb extends Sprite {
	private var _icon:int;
	private var _isFolder:Boolean;
	private var _label:String;
	private var _extra:*;
	private var _isOpen:Boolean = true;
	private var _selected:Boolean = false;
	private var _parentLimb:TreeLimb;
	private var _rootLimb:TreeLimb;
	private var _isRoot:Boolean = true;
	private var _style:TreeStyle = new TreeStyle();
	private var _isDirtyStyle:Boolean = true;
	private var _lastParent:DisplayObjectContainer;
	private var _lastLineVisible:Boolean = true;
	private var _lastBounds:Rectangle;
	private var _itemContainer:Sprite;
	private var _switchContainer:Sprite;
	private var _openSprite:Sprite;
	private var _closeSprite:Sprite;
	private var _iconSprite:Sprite;
	private var _openIcon:Bitmap;
	private var _closeIcon:Bitmap;
	private var _labelText:TextField;
	private var _limbs:Sprite;
	private var _lineV:Sprite;
	private var _lineH:Sprite;
	private var _selectBox:Sprite;
	private var _selectedItems:Vector.<TreeLimb>;
	private var _onStage:Boolean = false;	
	private var _isAdding:Boolean = false;	
	private var _beforeMoveParent:TreeLimb;	
	private var _isGhost:Boolean = false;	
	private var _isDirtyChild:Boolean = true;	
	private var _lastVisibleCount:int = 1;	
	private var _isDirtyVisibleCount:Boolean = true;	
	
	public function get extra():* { return _extra; }
	public function set extra(value:*):void { _extra = value; }

	public function get label():String { return _label; }
	public function set label(value:String):void { _labelText.text = _label = value; refreshLabel(); }

	public function get isFolder():Boolean { return _isFolder; }
	public function set isFolder(value:Boolean):void { _isFolder = value; refresh(false); }
	/**[g/s]ファイルアイコンの種類(isFolder=trueで無効。-1でアイコン無し。)*/
	public function get icon():int { return _icon; }
	public function set icon(value:int):void { _icon = value; refreshStyle(); }
	/**[g/s]自分が選択されているか*/
	public function get selected():Boolean { return _selected; }
	public function set selected(value:Boolean):void { setSelect(value, true); }
	
	public function get isOpen():Boolean { return _isOpen; }
	public function set isOpen(value:Boolean):void { setOpen(value); }
	public function get rootLimb():TreeLimb { return _rootLimb; }
	
	public function get isRoot():Boolean { return _isRoot; }
	

	public function get style():TreeStyle { return _style; }
	
	public function get numLimb():int { return _limbs.numChildren; }
	
	public function TreeLimb(label:String = "New Item", isFolder:Boolean = true, icon:int = 0, extra:* = null) {
		_selectedItems = new Vector.<TreeLimb>();
		_lineV = addChild(new Sprite()) as Sprite;
		_lineH = addChild(new Sprite()) as Sprite;
		_itemContainer = addChild(new Sprite()) as Sprite;
		_selectBox = _itemContainer.addChild(new Sprite()) as Sprite;
		_selectBox.graphics.beginFill(0xBE9852, 1);
		_selectBox.graphics.drawRect(0, 0, 100, 10);
		_switchContainer = _itemContainer.addChild(new Sprite()) as Sprite;
		_openSprite = _switchContainer.addChild(new Sprite()) as Sprite;
		_closeSprite = _switchContainer.addChild(new Sprite()) as Sprite;
		_closeSprite.mouseEnabled = false;
		_openSprite.addEventListener(MouseEvent.CLICK, onClickOpen);
		_openSprite.buttonMode = true;
		_iconSprite = _itemContainer.addChild(new Sprite()) as Sprite;
		_labelText = _itemContainer.addChild(new TextField()) as TextField;
		_labelText.autoSize = TextFieldAutoSize.LEFT;
		_labelText.selectable = false;
		_limbs = addChild(new Sprite()) as Sprite;
		_iconSprite.buttonMode = _selectBox.buttonMode = true;
		_iconSprite.doubleClickEnabled = _selectBox.doubleClickEnabled = true;
		_iconSprite.addEventListener(MouseEvent.CLICK, onClickIcon);
		_iconSprite.addEventListener(MouseEvent.DOUBLE_CLICK, onWclickIcon);
		_selectBox.addEventListener(MouseEvent.CLICK, onClickIcon);
		_selectBox.addEventListener(MouseEvent.DOUBLE_CLICK, onWclickIcon);
		_label = label;
		_labelText.text = _label;
		_labelText.mouseEnabled = false;
		_isFolder = isFolder;
		_icon = icon;
		_extra = extra;
		checkRoot(true);
		addEventListener(Event.ADDED, onAdded);
		addEventListener(Event.ADDED_TO_STAGE, onAddedStage);
		addEventListener(Event.REMOVED_FROM_STAGE, onRemoveStage);
		refresh();
	}
	private function onRemoveStage(e:Event):void {
		_onStage = false;
		if (_isAdding) _beforeMoveParent = _parentLimb;
	}
	private function onAddedStage(e:Event):void {
		_onStage = true;
	}
	private function onAdded(e:Event):void { checkRoot(); }
	private function onClickOpen(e:MouseEvent):void { setOpen(!_isOpen); }
	private function onClickIcon(e:MouseEvent):void {
		setSelect(true);
		_rootLimb.dispatchEvent(new TreeEvent(TreeEvent.CLICK_ITEM, this));
	}
	private function onWclickIcon(e:MouseEvent):void {
		setOpen(!_isOpen);
		_rootLimb.dispatchEvent(new TreeEvent(TreeEvent.WCLICK_ITEM, this));
	}
	private function getRoot():TreeLimb { return (_parentLimb == null)? this : _parentLimb.getRoot(); }
	private function checkRoot(exe:Boolean = false):void {
		if (parent === _lastParent && !exe) return;
		_lastParent = parent;
		_parentLimb = (parent == null || parent.parent == null)? null : parent.parent as TreeLimb;
		_rootLimb = getRoot();
		_isRoot = _rootLimb === this;
		for each(var l:TreeLimb in getLimbs()) l.checkRoot(true);
	}
	/**選択されている全てのアイテムを取得*/
	public function getSelectedLimbs():Vector.<TreeLimb> {
		return _rootLimb._selectedItems.concat();
	}
	/**全ての選択を解除*/
	public function resetSelect(dispatch:Boolean = true):void {
		for each(var l:TreeLimb in _rootLimb._selectedItems) l.setSelect(false, false, false);
		if (dispatch) _rootLimb.dispatchEvent(new TreeEvent(TreeEvent.CHANGE_SELECT, this));
	}
	/**自分を選択or解除*/
	public function setSelect(selected:Boolean = true, multiSelect:Boolean = false, dispatch:Boolean = true):void {
		_selected = selected;
		if (_selected && !multiSelect) for each(var l:TreeLimb in _rootLimb._selectedItems) if(l !== this) l.setSelect(false, multiSelect, false);
		var index:int = _rootLimb._selectedItems.indexOf(this);
		if (_selected && index == -1) _rootLimb._selectedItems.push(this);
		if (!_selected && index != -1) _rootLimb._selectedItems.splice(index, 1);
		refreshSelect();
		if (dispatch) _rootLimb.dispatchEvent(new TreeEvent(TreeEvent.CHANGE_SELECT, this));
	}
	/**フォルダの開閉*/
	public function setOpen(isOpen:Boolean = true, subLimbs:Boolean = false):void {
		_isOpen = isOpen;
		if (subLimbs) for each(var l:TreeLimb in getLimbs(true)) l.setOpen(isOpen, subLimbs);
		refreshDirty();
	}
	/**自分のインデックス位置を取得*/
	public function getIndex():int {
		return (!parent)? 0 : parent.getChildIndex(this);
	}
	private function getParentLimbs():Vector.<TreeLimb> {
		var result:Vector.<TreeLimb> = new Vector.<TreeLimb>();
		if (!isRoot) {
			result.push(_parentLimb);
			result = result.concat(_parentLimb.getParentLimbs());
		}
		return result;
	}
	private function getUpdateLimbs():Vector.<TreeLimb> {
		var result:Vector.<TreeLimb> = new Vector.<TreeLimb>();
		if (isRoot) {
			result.push(this);
		} else if (_parentLimb) {
			for (var i:int = getIndex(); i < _parentLimb.numLimb; i++) result.push(_parentLimb.getLimbAt(i) as TreeLimb);
			result = result.concat(_parentLimb.getUpdateLimbs());
		}
		return result;
	}
	/**自分の子をまとめて取得*/
	public function getLimbs(subLimbs:Boolean = false, addMe:Boolean = false):Vector.<TreeLimb> {
		var result:Vector.<TreeLimb> = new Vector.<TreeLimb>();
		for (var i:int = 0; i < numLimb; i++) {
			var limb:TreeLimb = getLimbAt(i);
			result.push(limb);
			if (subLimbs) result = result.concat(limb.getLimbs(subLimbs));
		}
		if (addMe) result.push(this);
		return result;
	}
	/**ユーザーデータが一致する全ての子を取得*/
	public function getLimbByExtra(extra:*, subLimbs:Boolean = true):Vector.<TreeLimb> {
		var result:Vector.<TreeLimb> = new Vector.<TreeLimb>();
		for each(var limb:TreeLimb in getLimbs(subLimbs)) if (limb.extra === extra) result.push(limb);
		return result;
	}
	/**ラベル名が一致する全ての子を取得*/
	public function getLimbByLabel(label:String, subLimbs:Boolean = true):Vector.<TreeLimb> {
		var result:Vector.<TreeLimb> = new Vector.<TreeLimb>();
		for each(var limb:TreeLimb in getLimbs(subLimbs)) if (limb._label == label) result.push(limb);
		return result;
	}
	/**指定インデックスの子を取得*/
	public function getLimbAt(index:int):TreeLimb {
		return (index < 0 || index >= numLimb)? null : _limbs.getChildAt(index) as TreeLimb;
	}
	/**TreeLimbオブジェクトを子に追加*/
	public function addLimb(limb:TreeLimb):TreeLimb {
		return addLimbAt(limb, numLimb);
	}
	/**複数のTreeLimbオブジェクトを子に追加*/
	public function addLimbs(limbs:Vector.<TreeLimb>):Vector.<TreeLimb> {
		for each(var l:TreeLimb in limbs) addLimb(l);
		return limbs;
	}
	/**TreeLimbオブジェクトを指定インデックスに追加*/
	public function addLimbAt(limb:TreeLimb, index:int = -1):TreeLimb {
		for each(var l:TreeLimb in limb.getLimbs(true, true)) if(l.selected) l.setSelect(false);
		limb._isAdding = true;
		if (limb._parentLimb === this) limb.parent.removeChild(limb);
		if (index > numLimb || index < 0) index = numLimb;
		if (limb.parent != null) limb.parent.removeChild(limb);
		_limbs.addChildAt(limb, index);
		limb.newStyle(_style, true);
		limb.refreshDirty();
		if (limb._beforeMoveParent) {
			limb._beforeMoveParent.refreshDirty();
		}
		_beforeMoveParent = null;
		limb.refresh();
		limb._isAdding = false;
		return limb;
	}
	/**ファイルを子に追加*/
	public function addFile(label:String = "", icon:int = 0, extra:* = null):TreeLimb {
		return addLimb(new TreeLimb(label, false, icon, extra));
	}
	/**複数のファイルを子に追加*/
	public function addFiles(labels:Array, icons:Array = null, extras:Array = null):Vector.<TreeLimb> {
		if (icons == null) icons = new Array();
		if (extras == null) extras = new Array();
		while (icons.length < labels.length) icons.push(0);
		while (extras.length < labels.length) extras.push(null);
		var result:Vector.<TreeLimb> = new Vector.<TreeLimb>();
		for (var i:int = 0; i < labels.length; i++) result.push(addFile(labels[i], icons[i], extras[i]));
		return result;
	}
	/**フォルダを子に追加*/
	public function addFolder(label:String = "", extra:* = null):TreeLimb {
		return addLimb(new TreeLimb(label, true, 0, extra));
	}
	/**複数のフォルダを子に追加*/
	public function addFolders(labels:Array, extras:Array = null):Vector.<TreeLimb> {
		if (extras == null) extras = new Array();
		while (extras.length < labels.length) extras.push(null);
		var result:Vector.<TreeLimb> = new Vector.<TreeLimb>();
		for (var i:int = 0; i < labels.length; i++) result.push(addFolder(labels[i], extras[i]));
		return result;
	}
	/**TreeLimbオブジェクトを子から切り離す*/
	public function removeLimb(limb:TreeLimb):Boolean {
		for each(var l:TreeLimb in getLimbs(true, true)) if (l === limb) { l.remove(); return true; }
		return false;
	}
	/**複数のTreeLimbオブジェクトを子から切り離す*/
	public function removeLimbs(limbs:Vector.<TreeLimb>):int {
		var count:int = 0;
		for each(var l:TreeLimb in limbs) count += int(l.removeLimb(l));
		return count;
	}
	private function destroyData(subLimbs:Boolean = true):void {
		removeAllListeners();
		_extra = null;
		_selected = false;
		_isGhost = true;
		_selectedItems.length = 0;
		if(subLimbs) for each(var l:TreeLimb in getLimbs()) l.destroyData(true);
	}
	/**自分を破棄する*/
	public function dispose(subLimbs:Boolean = true):void {
		remove();
		destroyData(subLimbs);
	}
	/**自分を親から切り離す*/
	public function remove():Boolean {
		for each(var l:TreeLimb in getLimbs(true, true)) if(l.selected) l.setSelect(false);
		if (parent == null) return false;
		parent.removeChild(this);
		if (!isRoot && !_rootLimb._isGhost) refreshDirty();
		checkRoot(true);
		return true;
	}
	/**内部イベントリスナを全て削除*/
	public function removeAllListeners():void {
		removeEventListener(Event.ADDED, onAdded);
		removeEventListener(Event.ADDED_TO_STAGE, onAddedStage);
		removeEventListener(Event.REMOVED_FROM_STAGE, onRemoveStage);
		_iconSprite.removeEventListener(MouseEvent.CLICK, onClickIcon);
		_iconSprite.removeEventListener(MouseEvent.DOUBLE_CLICK, onWclickIcon);
		_selectBox.removeEventListener(MouseEvent.CLICK, onClickIcon);
		_selectBox.removeEventListener(MouseEvent.DOUBLE_CLICK, onWclickIcon);
		_openSprite.removeEventListener(MouseEvent.CLICK, onClickOpen);
	}
	/**自分の子をソートして再配置*/
	public function sortOn(names:String, options:Object = null):void {
		var list:Array = new Array();
		for each(var l:TreeLimb in getLimbs()) list.push(l);
		list.sortOn(names, options);
		var sortedLimbs:Vector.<TreeLimb> = new Vector.<TreeLimb>();
		for each(var limb:TreeLimb in list) sortedLimbs.push(limb);
		addLimbs(sortedLimbs);
	}
	/**繋がった全てのアイテムのスタイルを更新*/
	public function updateStyle():void {
		setStyle(_style);
	}
	/**繋がった全てのアイテムにスタイルを適用*/
	public function setStyle(style:TreeStyle):void {
		_rootLimb.newStyle(style, true);
	}
	private function newStyle(style:TreeStyle, subLimbs:Boolean = true):void {
		_style = style;
		refreshStyle();
		refreshSelect();
		if (subLimbs) for each(var l:TreeLimb in getLimbs()) l.newStyle(_style, subLimbs);
		refresh();
	}
	private function refreshSelect():void {
		_labelText.textColor = (_selected)? _style.selectedLabelColor : uint(_style.textFormat.color);
		_selectBox.alpha = int(_selected);
	}
	private function refreshDirty():void {
		_isDirtyVisibleCount = true;
		for each(var tl1:TreeLimb in getParentLimbs()) tl1._isDirtyVisibleCount = true;
		for each(var tl2:TreeLimb in getUpdateLimbs()) {
			tl2._isDirtyChild = false;
			tl2.refresh(true);
		}
	}
	private function refresh(subLimbs:Boolean = true):void {
		var showLine:Boolean = !(_isRoot && numLimb == 0);
		if (showLine != _lastLineVisible) refreshStyle();
		var lineHeight:Number = 0;
		var heightList:Array = new Array();
		if (_isOpen && subLimbs) {
			var nextY:Number = 0;
			for (var i:int = 0; i < numLimb; i++ ) {
				var limb:TreeLimb = _limbs.getChildAt(i) as TreeLimb;
				limb.x = 0;
				limb.y = nextY;
				if (_isDirtyChild) limb.refresh(subLimbs);
				nextY += heightList[heightList.push(limb.getVisibleCount() * _style.lineSpacing) - 1];
			}
			heightList.forEach(function(...arg):void { lineHeight += (arg[1] == heightList.length - 1)? _style.lineSpacing : arg[0]; } );
		}
		if (_isFolder) _closeIcon.visible = !(_openIcon.visible = (_isOpen && numLimb));
		_limbs.visible = _isOpen;
		_openSprite.visible = (numLimb > 0);
		_closeSprite.visible = _openSprite.visible && !_isOpen;
		_lineV.graphics.clear();
		_lineV.graphics.beginBitmapFill(_style.dotV);
		_lineV.graphics.drawRect(0, 0, 1, lineHeight);
		_lineV.graphics.endFill();
		if (_isRoot) {
			var rect:Rectangle = getVisibleRect();
			if (_lastBounds == null || !rect.equals(_lastBounds)) {
				var event:TreeEvent = new TreeEvent(TreeEvent.RESIZE, this);
				event.bounds = rect.clone();
				dispatchEvent(event);
				_lastBounds = rect;
			}
		}
		_isDirtyChild = false;
		_lastLineVisible = showLine;
	}
	private function refreshLabel():void {
		_labelText.setTextFormat(_style.textFormat);
		_selectBox.width = _labelText.textWidth + 4;
		_selectBox.height = _labelText.textHeight;
		refreshSelect();
	}
	private function refreshStyle():void {
		refreshLabel();
		var showLine:Boolean = !(_isRoot && numLimb == 0);
		var cornerX:int = _style.treeOffset.x + (int(_style.buttonSize / 2) + _style.lineIndent) * int(showLine);
		while (_iconSprite.numChildren) _iconSprite.removeChildAt(0);
		var icons:Vector.<Bitmap> = new Vector.<Bitmap>();
		if (_isFolder) {
			_openIcon = new Bitmap(_style.openIcon);
			_closeIcon = new Bitmap(_style.closeIcon);
			icons.push(_openIcon, _closeIcon);
		} else if (_style.icons.length > _icon && _icon >= 0) icons.push(new Bitmap(_style.icons[_icon]));
		else icons.push(new Bitmap(_style.noIcon));
		for each(var ico:Bitmap in icons){
			_iconSprite.addChild(ico);
			ico.x = cornerX - int(ico.width / 2);
			ico.y = _style.treeOffset.y - int(ico.height / 2);
		}
		_lineV.x = cornerX;
		_lineH.x = _style.treeOffset.x;
		_lineV.y = _lineH.y = _style.treeOffset.y;
		_lineH.graphics.clear();
		if (showLine) {
			_lineH.graphics.beginBitmapFill(_style.dotH);
			_lineH.graphics.drawRect(0, 0, int(_style.buttonSize / 2) + _style.lineIndent, 1);
		}
		var boxw:Number = _style.buttonSize, thick:Number = 1, linew:Number = Math.max(3, boxw - thick * 2 - 4), lineh:Number = 1;
		_openSprite.graphics.clear();
		for each(var draw:Array in [[0, 0, 0, boxw, boxw], [1, thick, thick, boxw - thick * 2, boxw - thick * 2], [0, (boxw - linew) / 2, (boxw - lineh) / 2, linew, lineh]]) {
			_openSprite.graphics.beginFill(draw.shift() * 0xFFFFFF);
			_openSprite.graphics.drawRect.apply(null, draw);
		}
		_closeSprite.graphics.clear();
		_closeSprite.graphics.beginFill(0);
		_closeSprite.graphics.drawRect((boxw - lineh) / 2, (boxw - linew) / 2, lineh, linew);
		_switchContainer.x = _style.treeOffset.x - (_style.buttonSize-1) / 2;
		_switchContainer.y = _style.treeOffset.y - (_style.buttonSize-1) / 2;
		_labelText.x = cornerX + _style.labelOffset.x;
		_labelText.y = _style.treeOffset.y - _labelText.textHeight / 2 - 2  + _style.labelOffset.y;
		_selectBox.x = _labelText.x;
		_selectBox.y = _labelText.y + 3;
		var ct:ColorTransform = new ColorTransform();
		ct.color = _style.selectedBoxColor;
		ct.alphaMultiplier = _selectBox.alpha;
		_selectBox.transform.colorTransform = ct;
		_limbs.x = cornerX - _style.treeOffset.x;
		_limbs.y = _style.lineSpacing;
	}
	/**自分より下の階層の矩形サイズを取得する*/
	public function getVisibleRect():Rectangle {
		var rect:Rectangle = _itemContainer.getBounds(rootLimb);
		if (_isOpen) for each(var l:TreeLimb in getLimbs()) rect = rect.union(l.getVisibleRect());
		return rect;
	}
	private function getVisibleCount():int {
		var count:int = 1;
		if (!_isDirtyVisibleCount) {
			count = _lastVisibleCount;
		} else {
			if (_isOpen) for each(var l:TreeLimb in getLimbs()) count += l.getVisibleCount();
			_isDirtyVisibleCount = false;
			_lastVisibleCount = count;
		}
		return count;
	}
	/**複製*/
	public function clone(subLimbs:Boolean = true):TreeLimb {
		var newLimb:TreeLimb = new TreeLimb();
		for each(var x:XML in describeType(this).accessor.(@declaredBy.split("::").pop() == "TreeLimb" && @access == "readwrite")) newLimb[x.@name] = this[x.@name];
		newLimb._style = _style;
		if(subLimbs) for each(var l:TreeLimb in getLimbs()) newLimb.addLimb(l.clone());
		return newLimb;
	}
}
class TreeEvent extends Event {
	public var extra:*;
	public var targetLimb:TreeLimb;
	public var bounds:Rectangle;
	static public const CHANGE_SELECT:String = "onChangeSelect";
	static public const CLICK_ITEM:String = "onClickItem";
	static public const WCLICK_ITEM:String = "onWclickItem";
	static public const RESIZE:String = "onResize";
	public function TreeEvent(type:String, target:TreeLimb = null, extra:* = null, bubbles:Boolean = false, cancelable:Boolean = false) {
		this.extra = extra;
		targetLimb = target;
		super(type, bubbles, cancelable);
	}
}

class IconLoader {
	private var loader:Loader;
	private var iconImages:Vector.<BitmapData> = new Vector.<BitmapData>();
	private var iconSize:Rectangle = new Rectangle(0, 0, 13, 13);
	private var iconNum:int = 8;
	private var iconData:String = "iVBORw0KGgoAAAANSUhEUgAAAGgAAAANCAMAAABy+9t6AAAAA3NCSVQICAjb4U/gAAAAe1BMVEX//////5n//wCZ///x5L7/51Dv3a+97ard3d3/zMzq1Zvo0ZJm/wDMzMzly4Tmy4Sg4G3/zACqyu3tvarcuFh+0SyZzAAzzMyrq6u+qXNts+DIo1S+mFKgkXTgfW3/ZpksmdGFhVCffDxie1h7YlhYaHvROyxtVikAAADVecskAAAACXBIWXMAAArwAAAK8AFCrDSYAAAAFnRFWHRDcmVhdGlvbiBUaW1lADA0LzI4LzEwTP2JvQAAABx0RVh0U29mdHdhcmUAQWRvYmUgRmlyZXdvcmtzIENTNAay06AAAAFWSURBVDiNvdRhV4IwFMbxkRVhMwOGZGqiFTzf/xN2790dd3bqlad29oK/wn4oZzjPA4Cfx7fw10YsJ8fL5TJ9C0zn/XwqXMaiyKPJo8yjtQD6vpdydLydpq1SxEwE7ZWCczyhTsFTo2l4apQlT4225YnE9JFyuCVjpg6TQkSJ47B6cFCnQH1XQJ0Gw2sDdUp0zyXUaTG+tXz5YqFQVYHvWKkQQHEQaEfBd/RC0GoVV8CJoLrW+CRoGDTeCeo6jQ+CxpEv32yEqqrjkaDwyNRTCDv6vzgO550EnUmGQWQYRIZBZBhEhkFMEROhwKvTyvxg8hBIRoJkJEhGgmQkSEaCNjdHg0K4j4/lIv4EWufQ+t8hDxjkAYM8YJAHDPLAz5CX1de6dS7CJ8q23wwpZTFDSsX7VIj3kTStbStnoRSyqPMY8ujyGNPPI0jfDLF/e9fFD66ItNoX84d0b8+P1/QAAAAASUVORK5CYII=";
	private var iconAlpha:uint = 0x66FF00;
	public function IconLoader() {
		loader = new Loader();
		loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, function():void { } );
	}
	public function create(func:Function):void {
		var b64d:Base64Decoder = new Base64Decoder();
		b64d.decode(iconData);
		var ba:ByteArray = b64d.toByteArray();
		loader.contentLoaderInfo.addEventListener(Event.COMPLETE, function():void {
			onDecode.apply();
			func.apply(null, [iconImages]);
		});
		loader.loadBytes(ba);
	}
	private function onDecode():void {
		loader.contentLoaderInfo.removeEventListener(Event.COMPLETE, onDecode);
		var img:BitmapData = Bitmap(loader.content).bitmapData;
		var bmp:BitmapData = new BitmapData(img.width, img.height, true);
		bmp.copyPixels(img, img.rect, new Point());
		bmp.threshold(bmp, bmp.rect, new Point(), "==", 0xFF << 24 | iconAlpha, 0x00000000);//背景色を透明化
		iconImages.length = 0;
		for (var i:int = 0; i < iconNum; i++) {
			iconImages[i] = new BitmapData(iconSize.width, iconSize.height, true);
			iconImages[i].copyPixels(bmp, new Rectangle(iconSize.width * i, 0, iconSize.width, iconSize.height), new Point());
		}
	}
}