/* * @author Galaburda Oleg a_[w] * http://actualwave.com/ * */ import aw.template.MimeType; import aw.template.event.Broadcaster; import aw.template.element.ddrop.DDropInfo; class aw.template.element.DDrop extends Object{ private static var __asMs = Mouse.addListener(DDrop); private static var _libInst:MovieClip; private static var _iconPaddingX:Number = 0; private static var _iconPaddingY:Number = 0; private static var _init:Boolean = false; private static var _status:Boolean = false; private static var _libInstName:String = 'DDropIconLibrary'; private static var _detectionLimit:Number = 10; private static var _typeContainer:String = 'mimeType'; private static var _dragMethod:String = 'DDropDrag'; private static var _dropMethod:String = 'DDropDrop'; private static var _resultMethod:String = 'DDropReturn'; private static var _dragApplyer:String = 'DDropDragable'; private static var _mimeLimit:Number = 0; private static var _dropData:DDropInfo; private static var _mimeType:MimeType; //---- Set main movieClip public static function set iconLibrary(lib:Object):Void{ if(lib instanceof MovieClip){ _libInst = lib; }else setIconLibrary(lib, _root); } public static function get iconLibrary():Object{ return _libInst; } public static function setIconLibrary(lib:String, pathMc:MovieClip){ if(!pathMc) pathMc = _root; if(_libInst){ _libInst.removeMovieClip(); delete _libInst; } _libInst = pathMc.createEmptyMovieClip(_libInstName, pathMc.getNextHighestDepth()); _libInst.attachMovie(lib, _libInstName, pathMc.getNextHighestDepth(), {_x:_iconPaddingX, _y:_iconPaddingY}); } //---- Set start mouse detection Drag&Drop functions public static function set detectionLimit(lim:Number):Void{ _detectionLimit = Math.abs(Number(lim)); } public static function get detectionLimit():Number{ return _detectionLimit; } //---- Icon padding public static function set iconPaddingX(p:Number):Void{ _iconPaddingX = isNaN(p) ? 0 : p; } public static function get iconPaddingX():Number{ return _iconPaddingX; } public static function set iconPaddingY(p:Number):Void{ _iconPaddingY = isNaN(p) ? 0 : p; } public static function get iconPaddingY():Number{ return _iconPaddingY; } //---- Set mime secondary compare level public static function set mimeSecondaryLimit(lim:Number):Void{ _mimeLimit = Math.abs(Number(lim)); } public static function get mimeSecondaryLimit():Number{ return _mimeLimit; } //---- Set Drag&Drop methods for instances to use it public static function set dragMethod(name:String){ _dragMethod = name; } public static function get dragMethod():String{ return _dragMethod; } public static function set dropMethod(name:String){ _dropMethod = name; } public static function get dropMethod():String{ return _dropMethod; } public static function set resultMethod(name:String){ _resultMethod = name; } public static function get resultMethod():String{ return _resultMethod; } //---- Set name of MimeType container public static function set typeContainer(cont:String){ _typeContainer = cont; } public static function get typeContainer():String{ return _typeContainer; } public static function set dragApplyer(name:String){ _dragApplyer = name; } public static function get dragApplyer():String{ return _dragApplyer; } public static function get dropData():DDropInfo{ return _dropData; } public static function get mimeType():MimeType{ return _mimeType; } //---- Swap depth of main movieclip to highest depth public static function swapDepths(){ if(_libInst.getDepth()!=_libInst._parent.getNextHighestDepth()-1){ _libInst.swapDepths(_libInst._parent.getNextHighestDepth()); } var icon:Object = _libInst._libInstName; if(icon){ icon._x = _iconPaddingX; icon._y = _iconPaddingY; } } //---- Mouse listeners private static function onMouseUp(){ if(!_init || !_status){ clear(); return false; } var path = move(); var arr = getAvailableInstances(path); for(var i=arr.length-1; i>=0; i--){ var type = isTypeSimilar(_dropData.mimeType, arr[i][_typeContainer]); if(type && typeof(arr[i][_dropMethod])=='function') break; else arr.pop(); } var dropMc = null; if(arr.length) dropMc = arr.pop(); else dropMc = false; if(dropMc !== false){ _dropData.setTargetInfo(dropMc, path); _dropData.setResult(dropMc[_dropMethod](_dropData)); broadcastMessage(DROP_EVENT, true, _dropData); if(typeof(_dropData.instance[_resultMethod])=='function'){ _dropData.instance[_resultMethod](dropMc, _dropData); } }else broadcastMessage(DROP_EVENT, false, _dropData); clear(); } private static function onMouseDown(){ var path = move(); var arr = getAvailableInstances(path); if(arr.length){ for(var i=arr.length-1; i>=0; i--){ if(typeof(arr[i][_dragMethod])!='function') arr.pop(); else break; } if(arr.length){ DDrop.startDrag(arr.pop()); } } } public static function startDrag(item:MovieClip, data:Object):Boolean{ _init = true; var info:DDropInfo = accumulateDragInfo(item, data); if(!isDragable(info.instance)){ clear(); return false; }else{ _dropData = info; _mimeType = info.mimeType; if(_libInst){ _libInst._x = _libInst._parent._xmouse; _libInst._y = _libInst._parent._ymouse; } broadcastMessage(START_DRAG_EVENT, info); return true; } } private static function onMouseMove(){ if(_init){ if(!isDragable(_dropData.instance)){ clear(); broadcastMessage(ERROR_EVENT, _dropData); } if(!_status){ if(Math.abs(_libInst._xmouse)>=_detectionLimit || Math.abs(_libInst._ymouse)>=_detectionLimit){ init(); } } } } private static function isDragable(m):Boolean{ if(m[_dragApplyer]===false || (m[_dragApplyer] instanceof Function && m[_dragApplyer]()===false)){ return false; }else return true; } //---- Verify similarity of objects mimeType; public static function isTypeSimilar(dragType/*:String*/, dropType/*:String*/){ return MimeType.compare(dragType, dropType, true, _mimeLimit); } //---- Move main movieclip to mouse location and get _droptarget private static function move(){ _libInst._x = _libInst._parent._xmouse; _libInst._y = _libInst._parent._ymouse; _libInst.startDrag(); _libInst.stopDrag(); return _libInst._droptarget; } //---- Drag init function private static function init(){ _status = true; swapDepths(); _libInst.startDrag(true); broadcastMessage(DRAG_EVENT, _dropData); } //---- Get drag data from drag instance public static function accumulateDragInfo(instance:Object, data:Object):DDropInfo{ if(!data) data = instance[_dragMethod](); return new DDropInfo(instance, new MimeType(instance[_typeContainer]), data); } //---- Get all instances with mimeTypes in DropTarget of MovieClip private static function getAvailableInstances(path){ var arr = path.split('/'); if(!arr.length) return arr; path = _root; var ret = new Array(); for(var i=1; i