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

forked from: treeui

...
@author lizhi http://matrix3d.github.io/
Get Adobe Flash player
by lizhi 01 Sep 2014
/**
 * Copyright lizhi ( http://wonderfl.net/user/lizhi )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/n1yR
 */

// forked from lizhi's treeui
package  
{
	import com.bit101.components.ScrollPane;
	import com.bit101.components.TextArea;
	import flash.display.Sprite;
	import flash.events.Event;
	/**
	 * ...
	 * @author lizhi http://matrix3d.github.io/
	 */
	public class TestTreeUI extends Sprite
	{
		public var sp:ScrollPane;
		public var tree:TreeUI;
		public var testData:Object = { arr1:[1,2,3,4],a1:"testa1",vec1:Vector.<Number>([1.1,2.2,1.2])};
		public var ta:TextArea;
		public function TestTreeUI() 
		{
			sp = new ScrollPane(this);
			sp.setSize(400, 480);
			tree = new TreeUI();
			tree.addEventListener(Event.CHANGE, tree_change);
			sp.addChild(tree);
			tree.treeModel = new ObjectTreeModel;
			tree.data = this;
			tree.addEventListener(TreeUI.TREE_CLICK, tree_treeClick);
			
			ta = new TextArea(this, 400);
			ta.editable = false;
			ta.setSize(400, 480);
		}
		
		private function tree_treeClick(e:Event):void 
		{
			var tnode:TreeNodeUI = e.target as TreeNodeUI;
			try{
			ta.text = JSON.stringify(tnode.node.data, null, 4);
			}catch (err:Error) {
				ta.text = err + "";
			}
		}
		
		private function tree_change(e:Event):void 
		{
			sp.draw();
		}
	}

}

	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.CapsStyle;
	import flash.display.GradientType;
	import flash.display.Graphics;
	import flash.display.SpreadMethod;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.events.MouseEvent;
	import flash.geom.Matrix;
	import flash.text.TextField;
	import flash.text.TextFormat;
	import flash.utils.describeType;
	import flash.utils.getQualifiedClassName;
    /**
     * ...
     * @author lizhi http://matrix3d.github.io/
     */
    class TreeUI extends Sprite
    {
		public static const TREE_CLICK:String="treeclick"
        private var rootTree:TreeNode=new TreeNode;
        private var treeUI:Sprite = new Sprite;
        private var pen:GradientLinesPen = new GradientLinesPen(treeUI.graphics, [0x999999, 0], [1, 0], [1.5, 1.5], 0);
		private var _treeModel:TreeModel;
		private var lastSelectTreeNodeUI:TreeNodeUI;
		private var _data:Object;
		public function TreeUI() 
        {
            addChild(treeUI);
			treeModel = new TreeModel;
            rootTree.closed = false;
			treeUI.addEventListener(TREE_CLICK, treeUI_treeClick);
            render();
        }
		
		private function treeUI_treeClick(e:Event):void 
		{
			var tnode:TreeNodeUI = e.target as TreeNodeUI;
			if (lastSelectTreeNodeUI != tnode) {
				if(lastSelectTreeNodeUI)
				lastSelectTreeNodeUI.select(false);
				lastSelectTreeNodeUI = tnode;
				lastSelectTreeNodeUI.select(true);
			}
		}
        
        public function render():void {
            treeUI.graphics.clear();
            treeUI.removeChildren();
			treeUI.graphics.lineStyle(0, 0xff0000);
            renderCell(rootTree, 0, 0);
			dispatchEvent(new Event(Event.CHANGE));
        }
        
        private function renderCell(tree:TreeNode, x:Number, y:Number):Number {
            var sy:Number = y;
			var tui:TreeNodeUI=new TreeNodeUI(tree, x, y,this)
            treeUI.addChild(tui);
            y += 20;
            if (!tree.closed) {
                var vx:Number = x + 28;
                var vy:Number = y;
                for each(var child:TreeNode in tree.children) {
                    pen.moveTo(vx, y+8);
                    pen.lineTo(vx+12, y + 8);
                    vy = y;
                    y = renderCell(child, x + 20, y);
                }
				
				if(tree.children.length){
					pen.moveTo(vx, sy+20);
					pen.lineTo(vx, vy + 8);
				}
            }
			tui.update();
            return y;
        }
		
		public function update():void {
			rootTree._children = null;
			render();
		}
		
		public function get treeModel():TreeModel 
		{
			return _treeModel;
		}
		
		public function set treeModel(value:TreeModel):void 
		{
			if (_treeModel) {
				_treeModel.removeEventListener(Event.CHANGE, treeModel_change);
			}
			_treeModel = value;
			rootTree.treeModel = value;
			if(_treeModel)_treeModel.addEventListener(Event.CHANGE, treeModel_change);
			update();
		}
		
		public function get data():Object 
		{
			return _data;
		}
		
		public function set data(value:Object):void 
		{
			_data = value;
			rootTree.data = value;
			update();
		}
		
		private function treeModel_change(e:Event):void 
		{
			update();
		}
    }
	
	/**
	 * 树形节点
	 * @author lizhi http://matrix3d.github.io/
	 */
	class TreeNode {
		public static var ID:int = 0;
		public var treeModel:TreeModel;
		public var parent:TreeNode;
		public var closed:Boolean = true;
		public var name:String;
		public var _children:Vector.<TreeNode>;
		public var data:Object
		public function get children():Vector.<TreeNode> 
		{
			return treeModel.children(this);
		}
		
		public function get numChildren():int {
			return treeModel.numChildren(this);
		}
		
		public function get label():String 
		{
			return treeModel.label(this);
		}
	}
	
	/**
	 * 树节点ui
	 * @author lizhi http://matrix3d.github.io/
	 */
	class TreeNodeUI extends flash.display.Sprite {
		public var tf:TextField;
		public var node:TreeNode;
		public var treeUI:TreeUI;
		public var openBtn:TreeOpenBtn;
		private static var DEFICON:BitmapData;
		public function TreeNodeUI(node:TreeNode,x:Number,y:Number,main:TreeUI) {
			this.node = node;
			this.treeUI = main;
			
			//icon
			if (DEFICON==null) {
				DEFICON = new BitmapData(16, 16, true, 0);
				var pen:Sprite = new Sprite;
				pen.graphics.beginFill(0xd7a438);
				pen.graphics.drawCircle(8, 8, 7);
				DEFICON.draw(pen);
			}
			
			var wrapper:Sprite = new Sprite;
			addChild(wrapper);
			
			var icon:Bitmap = new Bitmap(DEFICON);
			wrapper.addChild(icon);
			icon.x = 20;
			
			tf = new TextField();
			tf.defaultTextFormat = new TextFormat("微软雅黑");
			tf.autoSize = "left";
			tf.selectable = tf.mouseWheelEnabled = false;
			buttonMode = true;
			wrapper.addChild(tf);
			tf.x = 40;
			tf.y = -3;
			tf.backgroundColor = 0x3399ff;
			this.x = x;
			this.y = y;
			
			openBtn = new TreeOpenBtn();
			addChild(openBtn);
			openBtn.addEventListener(MouseEvent.CLICK, click);
			
			wrapper.addEventListener(MouseEvent.CLICK, tf_click);
			
		}
		
		private function tf_click(e:MouseEvent):void 
		{
			var e2:MouseEvent = new MouseEvent(TreeUI.TREE_CLICK);
			dispatchEvent(e2);
		}
		
		public function update():void 
		{
			tf.text = node.label;
			openBtn.closed = node.closed;
			openBtn.visible = node.numChildren != 0;
		}
		
		public function select(boolean:Boolean):void 
		{
			tf.background = boolean;
		}
		
		private function click(e:MouseEvent):void 
		{
			node.closed = !node.closed;
			treeUI.render();
		}
	}
	
	class TreeOpenBtn extends Sprite
	{
		private static var addBmd:BitmapData;
		private static var plusBmd:BitmapData;
		private var image:Bitmap = new Bitmap;
		public function TreeOpenBtn() 
		{
			addChild(image);
			if (addBmd==null) {
				addBmd = new BitmapData(16, 16, true, 0);
				plusBmd = new BitmapData(16, 16, true, 0);
				var pen:Sprite = new Sprite;
				var openBtn:TextField;
				openBtn = new TextField();
				openBtn.autoSize = "left";
				openBtn.defaultTextFormat = new TextFormat("宋体");
				openBtn.textColor=0x4b63a7;
				addChild(openBtn);
				openBtn.selectable = openBtn.mouseWheelEnabled = false;
				openBtn.x = 4;
				openBtn.y = 1;
				pen.addChild(openBtn);
				
				pen.graphics.lineStyle(0,0x919191);
				pen.graphics.beginFill(0xededed);
				var o:Number = 4;
				pen.graphics.drawRect(0 + o, 0 + o, 16 - o * 2, 16 - o * 2);
				openBtn.text="+"
				addBmd.draw(pen);
				openBtn.text = "-";
				plusBmd.draw(pen);
			}
			closed = true;
		}
		
		public function set closed(v:Boolean):void {
			image.bitmapData = v?addBmd:plusBmd;
		} 
		
	}
	
	class TreeModel extends EventDispatcher
	{
		public function numChildren(node:TreeNode):int {
			return node._children?node._children.length:-1;
		}
		
		public function children(node:TreeNode):Vector.<TreeNode> {
			return Vector.<TreeNode>([]);
		}
		
		public function label(node:TreeNode):String {
			return node.data+"";
		}
	}
	
	class ObjectTreeModel extends TreeModel
	{
		override public function numChildren(node:TreeNode):int {
			if(node._children==null){
				var i:int = 0;
				var xml:XML = describeType(node.data);
				if (xml.variable.length()!=0) {
					 for each(var x:XML in xml.variable) {
						i++;
					}
				}else {
					for (var name:String in node.data) {
						i++;
					}
				}
				return i;
			}
			return node._children.length;
		}
		
		override public function children(node:TreeNode):Vector.<TreeNode> {
			if(node._children==null){
				node._children = new Vector.<TreeNode>;
				var xml:XML = describeType(node.data);
				if (xml.variable.length()!=0) {
					 for each(var x:XML in xml.variable) {
						var c:TreeNode = new TreeNode;
						c.treeModel = node.treeModel;
						c.data = node.data[x.@name];
						c.name = x.@name;
						node._children.push(c);
					}
				}else {
					for (var name:String in node.data) {
						c = new TreeNode;
						c.treeModel = node.treeModel;
						c.data = node.data[name];
						c.name = name;
						node._children.push(c)
					}
				}
			   
			}
			return node._children;
		}
		
		override public function label(node:TreeNode):String {
			var cname:String=getQualifiedClassName(node.data)
			if (node.data is Array||cname.indexOf("__AS3__.vec::Vector")==0) {
				return node.name+" : ["+cname.replace("__AS3__.vec::","")+"] len:" + node.data.length;
			}
			return node.name+" : "+node.data;
		}
	}

	class GradientLinesPen
    {
        private var g:Graphics;
        private var colors:Array;
        private var alphas:Array;
        private var ratios:Array;
        private var m:Matrix = new Matrix();
        private var thickness:Number;
        private var sx:Number;
        private var sy:Number;
        private var w:Number;
        public function GradientLinesPen(g:Graphics,colors:Array,alphas:Array,widths:Array,thickness:Number) 
        {
            this.g = g;
            setGradientLines(colors, alphas, widths, thickness);
        }
        public function setGradientLines(colors:Array,alphas:Array,widths:Array,thickness:Number):void {
            for (var i:int = colors.length-2; i > 0;i-- ) {
                colors.splice(i, 0, colors[i]);
            }
            this.colors = colors;
            for (i = alphas.length-2; i > 0;i-- ) {
                alphas.splice(i, 0, alphas[i]);
            }
            this.alphas = alphas;
            w = 0;
            for each(var value:Number in widths) {
                w += value;
            }
            ratios = [];
            var cw:Number = 0;
            for (i = 0; i < widths.length - 1; i++ ) {
                cw += 0xff * widths[i] / w;
                ratios.push(cw);
                ratios.push(cw);
            }
            this.thickness = thickness;
        }
        public function moveTo(x:Number, y:Number):void {
            g.moveTo(x, y);
            sx = x;
            sy = y;
        }
        public function lineTo(x:Number, y:Number):void {
            var dx:Number = x - sx;
            var dy:Number = y - sy;
            var a:Number = Math.atan2(dy, dx);
            var m:Matrix = new Matrix();
            m.createGradientBox(w, w, a);
            g.lineStyle(thickness, 0, 0, false, null, CapsStyle.SQUARE);
            g.lineGradientStyle(GradientType.LINEAR, colors, alphas, ratios, m, SpreadMethod.REPEAT);
            g.lineTo(x, y);
            sx = x;
            sy = y;
        }
    }