⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dragtile.as

📁 QS我也没用过
💻 AS
字号:
package qs.controls
{
	import mx.core.UIComponent;
	import mx.core.IUIComponent;
	import mx.core.IFactory;
	import flash.display.Sprite;
	import flash.display.DisplayObject;
	import flash.events.MouseEvent;
	import flash.geom.Point;
	import flash.events.Event;
	import mx.core.ClassFactory;
	import mx.core.IDataRenderer;
	import mx.managers.DragManager;
	import mx.core.DragSource;
	import mx.core.BitmapAsset;
	import flash.display.PixelSnapping;
	import mx.events.DragEvent;
	import mx.states.RemoveChild;
	import mx.containers.Tile;
	import mx.core.Container;
	import mx.core.ScrollPolicy;

	/** the amount of space, in pixels, between invidual items */
	[Style(name="spacing", type="Number", inherit="no")]
	[Style(name="padding", type="Number", inherit="no")]
		
	[Event("change")]

	public class DragTile extends Container
	{
		private var _items:Array = [];
		private var _pendingItems:Array;
		protected var itemsChanged:Boolean = false;
		/** true if the renderers need to be regenerated */
		protected var renderersDirty:Boolean = true;
		/** the renderers representing the data items, one for each item */
		protected var renderers:Array = [];		
		/** the factory that generates item renderers
		 */
		private var _itemRendererFactory:IFactory;
		/** 
		 * the object that manages animating the children layout
		 */
		private var _rowLength:int = 16;
		private var _colLength:int;
		private var _tileWidth:int;
		private var _tileHeight:int;
		private var _dragTargetIdx:Number;
		private var _dragMouseStart:Point;
		private var _dragMousePos:Point;
		private var _dragPosStart:Point;
				
		private var animator:LayoutAnimator;
		
		
		public function DragTile()
		{
			super();
			_itemRendererFactory= new ClassFactory(CachedLabel);
			animator = new LayoutAnimator();
			animator.autoPrioritize = false;
			animator.animationSpeed = .2;
			animator.layoutFunction = generateLayout;
			animator.updateFunction = layoutUpdated;
			
			horizontalScrollPolicy = ScrollPolicy.OFF;
			clipContent = true;
			
			addEventListener(MouseEvent.MOUSE_DOWN,startReorder);
			addEventListener(DragEvent.DRAG_ENTER,dragEnter);
			addEventListener(DragEvent.DRAG_OVER,dragOver);
			addEventListener(DragEvent.DRAG_EXIT,dragOut);
			addEventListener(DragEvent.DRAG_DROP,dragDrop);
			addEventListener(DragEvent.DRAG_COMPLETE,dragComplete);
						
		}
		//-----------------------------------------------------------------
		
		/** the data source
		 */
		public function set dataProvider(value:Array):void
		{
			_pendingItems= value;

			renderersDirty = true;
			itemsChanged = true;
			invalidateProperties();			
		}
		public function get dataProvider():Array
		{
			return _items;

		}
		//-----------------------------------------------------------------

		/**
		 * by making the itemRenderer be of type IFactory, 
		 * developers can define it inline using the <Component> tag
		 */
		public function get itemRenderer():IFactory
		{
			return _itemRendererFactory;
		}
		public function set itemRenderer(value:IFactory):void
		{
			_itemRendererFactory = value;
			renderersDirty = true;
			invalidateProperties();						
		}
		//-----------------------------------------------------------------

		
		override protected function commitProperties():void
		{
			// its now safe to switch over new dataProviders.
			if(_pendingItems != null)
			{
				_items = _pendingItems;
				_pendingItems = null;
			}
			
			itemsChanged = false;
			
			if(renderersDirty)
			{
				// something has forced us to reallocate our renderers. start by throwing out the old ones.
				renderersDirty = false;
				for(var i:int=numChildren-1;i>= 0;i--)
					removeChildAt(i);
				
				renderers = [];

				// allocate new renderers, assign the data.
				for(var i:int = 0;i<_items.length;i++)
				{
					var renderer:IUIComponent = _itemRendererFactory.newInstance();
					IDataRenderer(renderer).data = _items[i];
					renderers[i] = renderer;
					addChild(DisplayObject(renderer));
				}
				animator.items = renderers;

			}
			invalidateSize();
		}
		
		private function get spacingWidthDefault():Number
		{
			var result:Number = getStyle("spacing");
			if(isNaN(result))
				result = 20;
			return result;
		}
		private function get paddingWidthDefault():Number
		{
			var result:Number = getStyle("padding");
			if(isNaN(result))
				result = 40;
			return result;
		}
		
		override protected function measure():void
		{
			_tileWidth = 0;
			_tileHeight = 0;
			
			// first, calculate the largest width/height of all the items, since we'll have to make all of the items
			// that size

			for(var i:int=0;i<renderers.length;i++)
			{
				var itemRenderer:IUIComponent = renderers[i];
				_tileWidth = Math.max(_tileWidth,itemRenderer.getExplicitOrMeasuredWidth());
				_tileHeight = Math.max(_tileHeight,itemRenderer.getExplicitOrMeasuredHeight());
			}
			// square them off
			_tileWidth = Math.max(_tileWidth,_tileHeight);
			//_tileHeight = _tileWidth;
						
			var itemsInRow:Number = Math.min(renderers.length,_rowLength);
			
			var spacing:Number = spacingWidthDefault;
			measuredWidth = itemsInRow * _tileWidth + (itemsInRow - 1) * spacing;
			var defaultColumnCount:Number = Math.ceil(renderers.length / _rowLength);
			measuredHeight = defaultColumnCount*_tileHeight + (defaultColumnCount-1)*spacing;
	
			animator.invalidateLayout();		
							
		}
		
		private function findItemAt(px:Number,py:Number,seamAligned:Boolean):Number
		{
			var gPt:Point = localToGlobal(new Point(px,py));
						
			px += horizontalScrollPosition;
			py += verticalScrollPosition;
			
			var spacing:Number = spacingWidthDefault;
			var padding:Number = paddingWidthDefault;
			
			var targetWidth:Number = unscaledWidth -2*padding + spacing;
			var rowLength:Number = Math.min(renderers.length,Math.floor(targetWidth/(_tileWidth+spacing)) );
			var colLength:Number = (rowLength == 0)? 0:(Math.ceil(renderers.length / rowLength));
			var leftSide:Number = (unscaledWidth - (rowLength * _tileWidth + (rowLength-1) * spacing + 2*padding))/2;
			
									
			var rowPos:Number = (px-padding - leftSide) / (_tileWidth + spacing);
			var colPos:Number = (py-spacing/2) / (_tileHeight + spacing);
			rowPos = (seamAligned)? Math.round(rowPos):Math.floor(rowPos);
			colPos = Math.floor(colPos);
						
			if(seamAligned)
			{
				rowPos = Math.max(0,Math.min(rowPos,rowLength));
				colPos = Math.max(0,Math.min(colPos,colLength));
				var result:Number = colPos * rowLength + rowPos;						
				return Math.min(_items.length,result);
								
			}
			else
			{
				if(rowPos >= rowLength || rowPos < 0)
					return NaN;
				if(colPos >= colLength || colPos < 0)
					return NaN;
				var result:Number = colPos * rowLength + rowPos;																	
				if(result > _items.length)
					return NaN;
				var r:DisplayObject = renderers[result];
				if(r.hitTestPoint(gPt.x,gPt.y,true) == false)
					return NaN;					
				return result;
			}
		}
				
						
		private function startReorder(e:MouseEvent):void
		{
			var dragIdx:Number = findItemAt(mouseX,mouseY,false);
			if(isNaN(dragIdx))
				return;

			var dragItem:IUIComponent = renderers[dragIdx];
			
			var dragImage:UIBitmap = new UIBitmap(dragItem,PixelSnapping.NEVER);			

			var dragSrc:DragSource = new DragSource();
			dragSrc.addData([dataProvider[dragIdx]],"items");
			dragSrc.addData(dragIdx,"index");
			
			var pt:Point = DisplayObject(dragItem).localToGlobal(new Point(0,0));
			pt = globalToLocal(pt);
			DragManager.doDrag(this,dragSrc,e,dragImage,-pt.x - 4 ,-pt.y - 4,.6);
		}
		private function dragEnter(e:DragEvent):void
		{
			if(e.dragInitiator == this)
			{
		    	DragManager.acceptDragDrop(this);
				e.action = DragManager.MOVE;
				DragManager.showFeedback(DragManager.MOVE);
			}
			else
			{
		    	DragManager.acceptDragDrop(this);								
				if(e.shiftKey)
					DragManager.showFeedback(DragManager.COPY);
				else
					DragManager.showFeedback(DragManager.MOVE);				
			}
			animator.animationSpeed = .1;
		}
		private function dragOver(e:DragEvent):void
		{
			if(e.shiftKey)
				DragManager.showFeedback(DragManager.COPY);
			else
				DragManager.showFeedback(DragManager.MOVE);				
			_dragTargetIdx = findItemAt(mouseX,mouseY,true);
			_dragMousePos = new Point(mouseX,mouseY);
			animator.invalidateLayout(true);						
		}
		private function dragDrop(e:DragEvent):void
		{
			_dragTargetIdx = findItemAt(mouseX,mouseY,true);
			if(e.dragInitiator == this && e.action == DragManager.MOVE)
			{
				DragManager.showFeedback(DragManager.LINK);
				var dragFromIndex:Number = Number(e.dragSource.dataForFormat("index"));
				if(_dragTargetIdx > dragFromIndex)
				{
					_items.splice(_dragTargetIdx,0,_items[dragFromIndex]);
					_items.splice(dragFromIndex,1);
					setChildIndex(renderers[dragFromIndex],numChildren-1);
					renderers.splice(_dragTargetIdx,0,renderers[dragFromIndex]);
					renderers.splice(dragFromIndex,1);
				
				}
				else
				{
					var tmp:* = _items[dragFromIndex];
					_items.splice(dragFromIndex,1);
					_items.splice(_dragTargetIdx,0,tmp);
					tmp = renderers[dragFromIndex];
					setChildIndex(tmp,numChildren-1);
					renderers.splice(dragFromIndex,1);
					renderers.splice(_dragTargetIdx,0,tmp);												
				}
				dispatchEvent(new Event("change"));
			}
			else
			{
				var newItems:Array = (e.dragSource.dataForFormat("items") as Array).concat();
				var newRenderers:Array = [];
				for(var i:int =0;i<newItems.length;i++)
				{
					var r:IUIComponent = newRenderers[i] = _itemRendererFactory.newInstance();
					IDataRenderer(r).data = newItems[i];
					addChild(DisplayObject(r));
					_items.splice(_dragTargetIdx,0,newItems[i]);
					renderers.splice(_dragTargetIdx+i,0,r);
																				
				}
			}
			_dragTargetIdx = NaN;
			animator.animationSpeed = .2;
			animator.invalidateLayout(true);
		}
		private function dragComplete(e:DragEvent):void
		{
			if(e.action == DragManager.MOVE)
			{
				var dragFromIndex:Number = Number(e.dragSource.dataForFormat("index"));
				_items.splice(dragFromIndex,1);
				var r:IUIComponent = renderers.splice(dragFromIndex,1)[0];
				removeChild(DisplayObject(r));
				animator.invalidateLayout();
			}
		}
		private function dragOut(e:DragEvent):void
		{
			_dragTargetIdx = NaN;
			animator.animationSpeed = .2;						
			animator.invalidateLayout(true);
		}
		
		
		private function layoutUpdated():void
		{
			validateDisplayList();
		}
		private function generateLayout():void
		{
			var spacing:Number = spacingWidthDefault;
			var padding:Number = paddingWidthDefault;
			var targetWidth:Number = unscaledWidth - 2*padding + spacing;
			var rowLength:Number = Math.min(renderers.length,Math.floor(targetWidth/(spacing + _tileWidth)) );
			var colLength:Number = Math.ceil(renderers.length / rowLength);
			
			var leftSide:Number = (unscaledWidth - (rowLength * _tileWidth + (rowLength-1) * spacing + 2*padding))/2;
			
			var positionFunc:Function = function(r:int,c:int,offset:Number):void
			{			
				var idx:int = c*rowLength + r;
				if(idx >= renderers.length)
					return;								
				var renderer:IUIComponent = renderers[idx];
				var target:LayoutTarget = animator.targetFor(renderer);//targets[idx];
				target.scaleX = target.scaleY = 1;
				target.item = renderer;
				target.unscaledWidth = renderer.getExplicitOrMeasuredWidth();
				target.unscaledHeight = renderer.getExplicitOrMeasuredHeight();
				target.x = offset + r * (_tileWidth + spacing) + _tileWidth/2 - target.unscaledWidth/2;
				target.y = spacing + c * (_tileHeight + spacing)+ _tileHeight/2 - target.unscaledHeight/2;
				target.animate = true;					
			}

			var insertRowPos:Number = _dragTargetIdx % rowLength;
			var insertColPos:Number = Math.floor(_dragTargetIdx / rowLength);
			
			for(var c:int = 0;c<colLength;c++)			
			{
				if(c == insertColPos)
				{
					for(var r:int = 0;r<insertRowPos;r++)
					{
						positionFunc(r,c,leftSide);
					}
					for(var r:int = insertRowPos;r<rowLength;r++)
					{
						positionFunc(r,c,leftSide + 2*padding);
					}
				}
				else
				{
					for(var r:int = 0;r<rowLength;r++)
					{
						positionFunc(r,c,leftSide + padding);
					}
				}
			}
		}

		override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void
		{
			graphics.clear();
			graphics.moveTo(0,0);
			graphics.beginFill(0,0);
			graphics.drawRect(0,0,unscaledWidth,unscaledHeight);
			
			
			animator.invalidateLayout();			
			
			super.updateDisplayList(unscaledWidth,unscaledHeight);
		}
		override public function styleChanged(styleProp:String):void
		{
			invalidateSize();
			invalidateDisplayList();
			animator.invalidateLayout();
		}

	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -