flex-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From aha...@apache.org
Subject [17/30] Radii8 code base as accepted by IP Clearance
Date Wed, 03 Sep 2014 00:17:50 GMT
http://git-wip-us.apache.org/repos/asf/flex-radii8/blob/f370bfcf/Radii8Library/src/com/flexcapacitor/utils/DragManagerUtil.as
----------------------------------------------------------------------
diff --git a/Radii8Library/src/com/flexcapacitor/utils/DragManagerUtil.as b/Radii8Library/src/com/flexcapacitor/utils/DragManagerUtil.as
new file mode 100644
index 0000000..09209cd
--- /dev/null
+++ b/Radii8Library/src/com/flexcapacitor/utils/DragManagerUtil.as
@@ -0,0 +1,1794 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  Licensed to the Apache Software Foundation (ASF) under one or more
+//  contributor license agreements.  See the NOTICE file distributed with
+//  this work for additional information regarding copyright ownership.
+//  The ASF licenses this file to You under the Apache License, Version 2.0
+//  (the "License"); you may not use this file except in compliance with
+//  the License.  You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+//  Unless required by applicable law or agreed to in writing, software
+//  distributed under the License is distributed on an "AS IS" BASIS,
+//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//  See the License for the specific language governing permissions and
+//  limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+
+
+package com.flexcapacitor.utils {
+	import com.flexcapacitor.controller.Radiate;
+	import com.flexcapacitor.events.DragDropEvent;
+	import com.flexcapacitor.model.IDocument;
+	import com.flexcapacitor.utils.supportClasses.ComponentDescription;
+	import com.flexcapacitor.utils.supportClasses.DragData;
+	import com.flexcapacitor.utils.supportClasses.TargetSelectionGroup;
+	
+	import flash.display.DisplayObject;
+	import flash.display.DisplayObjectContainer;
+	import flash.display.Sprite;
+	import flash.events.Event;
+	import flash.events.EventDispatcher;
+	import flash.events.MouseEvent;
+	import flash.filters.DropShadowFilter;
+	import flash.geom.Point;
+	import flash.geom.Rectangle;
+	import flash.utils.Dictionary;
+	
+	import mx.collections.ArrayCollection;
+	import mx.core.BitmapAsset;
+	import mx.core.DragSource;
+	import mx.core.FlexGlobals;
+	import mx.core.FlexSprite;
+	import mx.core.IFactory;
+	import mx.core.IFlexDisplayObject;
+	import mx.core.IUIComponent;
+	import mx.core.IVisualElement;
+	import mx.core.IVisualElementContainer;
+	import mx.events.DragEvent;
+	import mx.managers.DragManager;
+	import mx.managers.ISystemManager;
+	import mx.managers.PopUpManager;
+	import mx.utils.NameUtil;
+	
+	import spark.components.Application;
+	import spark.components.Image;
+	import spark.components.SkinnableContainer;
+	import spark.components.supportClasses.GroupBase;
+	import spark.components.supportClasses.ItemRenderer;
+	import spark.components.supportClasses.Skin;
+	import spark.layouts.BasicLayout;
+	import spark.layouts.HorizontalLayout;
+	import spark.layouts.TileLayout;
+	import spark.layouts.VerticalLayout;
+	import spark.layouts.supportClasses.DropLocation;
+	import spark.layouts.supportClasses.LayoutBase;
+	import spark.skins.spark.ApplicationSkin;
+	import spark.skins.spark.ListDropIndicator;
+
+	/**
+	 * Drag over 
+	 * */
+	[Event(name="dragOver", type="com.flexcapacitor.radiate.events.DragDropEvent")]
+
+	/**
+	 * Drop event 
+	 * */
+	[Event(name="dragDrop", type="com.flexcapacitor.radiate.events.DragDropEvent")]
+
+	/**
+	 * Drop complete event 
+	 * */
+	[Event(name="dragDropComplete", type="com.flexcapacitor.radiate.events.DragDropEvent")]
+	
+	/**
+	 * Enables drag and drop of UIComponent. 
+	 * I don't know if this has a drag cancel event. 
+	 * That is, if you don't find a place to drop then what happens? 
+	 * Could listen for stage mouse up or mouse up outside. 
+	 * */
+	public class DragManagerUtil extends EventDispatcher {
+		
+		
+		public function DragManagerUtil():void {
+			
+		}
+		
+		/**
+		 * Used during drag and drop to indicate the target destination for the dragged element
+		 * */
+		public var dropIndicator:IFactory;
+		
+		/**
+		 * The distance of the mouse pointer location from the edge of the dragged element
+		 * */
+		private var offset:Point = new Point;
+		
+		[Bindable] 
+		public var showSelectionBox:Boolean = true;
+		public var showListDropIndicator:Boolean = true;
+		public var showMousePositionLines:Boolean = true;
+		public var showSelectionBoxOnApplication:Boolean;
+		
+		public var swfRoot:DisplayObject;
+		
+		/**
+		 * Reference to the document
+		 * */
+		public var targetApplication:Application;
+		
+		public var selectionGroup:ItemRenderer = new TargetSelectionGroup();
+		public var mouseLocationLines:IFlexDisplayObject = new ListDropIndicator();
+		public var lastTargetCandidate:Object;
+		public var dropTarget:Object;
+		public var groupBase:GroupBase;
+		public var dropLayout:LayoutBase;
+		
+		[Bindable] 
+		public var dropTargetName:String;
+		
+		/**
+		 * X and Y location of dragged object
+		 * */
+		[Bindable] 
+		public var dropTargetLocation:String;
+		
+		public var startingPoint:Point;
+		
+		public var includeSkins:Boolean;
+		public var applicationGroups:Dictionary;
+		
+		/**
+		 * How many pixels the mouse has to move before a drag operation is started
+		 * */
+		public var dragStartTolerance:int = 5;
+		
+		public var dragInitiator:IUIComponent;
+		private var dropLocation:DropLocation;
+		public var dragData:DragData;
+		
+		
+		public var showDropIndicator:Boolean = true;
+		private var systemManager:Object;
+		private var dragListener:DisplayObjectContainer;
+		
+		private var targetsUnderPoint:Array;
+		public var adjustMouseOffset:Boolean = true;
+		public var draggedItem:Object;
+		private var topLevelApplication:Application;
+		
+		
+		/**
+		 * Sets up a target to listen for drag like behavior. 
+		 * There is a little bit of resistance before a drag is started. 
+		 * This can be set in the dragStartTolerance
+		 * @param dragInitiator the component that will be dragged
+		 * @param parentApplication the application of the component being dragged
+		 * @param event Mouse event from the mouse down event
+		 * @param draggedItem The item or data to be dragged. If null then this is the dragInitiator.
+		 * */
+		public function listenForDragBehavior(dragInitiator:IUIComponent, document:IDocument, event:MouseEvent, draggedItem:Object = null):void {
+			startingPoint = new Point();
+			this.dragInitiator = dragInitiator;
+			this.targetApplication = Application(document.instance);
+			systemManager = targetApplication.systemManager;
+			topLevelApplication = Application(FlexGlobals.topLevelApplication);
+			
+			//componentTree = DisplayObjectUtils.getComponentDisplayList(documentApplication);
+			componentTree = document.componentDescription;
+			
+			// either the component to add or the component to move
+			if (arguments[3]) {
+				this.draggedItem = draggedItem;
+			}
+			else {
+				this.draggedItem = dragInitiator;
+			}
+			
+			// if selection is offset then check if using system manager sandbox root or top level root
+			var systemManager:ISystemManager = ISystemManager(topLevelApplication.systemManager);
+			
+			// no types so no dependencies
+			var marshallPlanSystemManager:Object = systemManager.getImplementation("mx.managers.IMarshallPlanSystemManager");
+			var targetCoordinateSpace:DisplayObject;
+			
+			if (marshallPlanSystemManager && marshallPlanSystemManager.useSWFBridge()) {
+				targetCoordinateSpace = Sprite(systemManager.getSandboxRoot());
+			}
+			else {
+				targetCoordinateSpace = Sprite(topLevelApplication);
+			}
+			
+			swfRoot = targetCoordinateSpace;
+			
+			startingPoint.x = event.stageX;
+			startingPoint.y = event.stageY;
+			
+			
+			updateDropTargetLocation(targetApplication, event);
+			
+			dragInitiator.addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
+			swfRoot.addEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler);
+		}
+		
+		/**
+		 * Updates the drop target location property with the x and y values of the dragged item.
+		 * Format is "XxY", so for example, "100x50".
+		 * */
+		private function updateDropTargetLocation(rootDisplayObject:DisplayObject, event:MouseEvent):void {
+			var mousePoint:Point = new Point(event.stageX, event.stageY);
+			var applicationLocationPoint:Point = DisplayObject(rootDisplayObject).localToGlobal(new Point());
+			
+			//var point2:Point = new Point(-event.stageX, -event.stageY);
+			//var newPoint:Point = DisplayObject(rootDisplayObject).localToGlobal(mousePoint);
+			//var newPoint1:Point = DisplayObject(rootDisplayObject).localToGlobal(point2);
+			
+			// this one works 
+			//var newPoint3:Point = DisplayObject(rootDisplayObject).globalToLocal(mousePoint);
+			//var newPoint4:Point = DisplayObject(rootDisplayObject).globalToLocal(point2);
+			
+			var newX:Number = mousePoint.x - applicationLocationPoint.x - offset.x;
+			var newY:Number = mousePoint.y - applicationLocationPoint.y - offset.y;
+			//var newX2:Number = targetApplication.contentMouseX - offset.x;
+			//var newY2:Number = targetApplication.contentMouseY - offset.y;
+			
+			var out:String = newX + "x" + newY;
+			// Find the registration point of the owner
+	        /*var sandboxRoot:DisplayObject = systemManager.getSandboxRoot();
+	        var regPoint:Point = owner.localToGlobal(new Point());
+	        regPoint = sandboxRoot.globalToLocal(regPoint);*/
+	        //var regPoint:Point = rootDisplayObject.localToGlobal(new Point());
+	        //regPoint = rootDisplayObject.globalToLocal(regPoint);
+			
+			if (dropTargetLocation!=out) {
+				dropTargetLocation = out;
+			}
+		}
+		
+		/**
+		 * Mouse move handler that listens to see if the mouse has moved past the drag tolerance amount.
+		 * If the mouse has moved past the drag tolerance then dragging is started.
+		 * */
+		protected function mouseMoveHandler(event:MouseEvent):void {
+			var dragToleranceMet:Boolean;
+			dragToleranceMet = Math.abs(startingPoint.x - event.stageX) >= dragStartTolerance;
+			dragToleranceMet = !dragToleranceMet ? Math.abs(startingPoint.y - event.stageY)  >= dragStartTolerance: true;
+			
+			updateDropTargetLocation(targetApplication, event);
+			
+			if (dragToleranceMet) {
+				dragInitiator.visible = hideDragInitiatorOnDrag ? false : true; // hide from view
+				removeMouseHandlers(dragInitiator);
+				startDrag(dragInitiator, targetApplication, event);
+			}
+			
+		}
+		
+		/**
+		 * Start dragging
+		 * */
+		public function startDrag(dragInitiator:IUIComponent, application:Application, event:MouseEvent):void {
+			var dragSource:DragSource = new DragSource();
+			var snapshot:BitmapAsset;
+
+			this.dragInitiator = dragInitiator;
+			this.targetApplication = application;
+			this.systemManager = application.systemManager;
+			
+			// set the object that will listen for drag events
+			dragListener = DisplayObjectContainer(application);
+			
+			distanceFromLeft = dragInitiator.localToGlobal(new Point).x;
+			distanceFromTop = dragInitiator.localToGlobal(new Point).y;
+			
+			// TODO = READ 
+			// Flex coordinate systems
+			// http://help.adobe.com/en_US/flex/using/WS2db454920e96a9e51e63e3d11c0bf69084-7de0.html
+			var scale:Number = application.scaleX;
+			
+			// store distance of mouse point to top left of display object
+			if (scale!=1 && !isNaN(scale)) {
+				offset.x = event.stageX - distanceFromLeft;// * scale;
+				offset.y = event.stageY - distanceFromTop;// * scale;
+			}
+			else {
+				offset.x = event.stageX - distanceFromLeft;
+				offset.y = event.stageY - distanceFromTop;
+			}
+			
+			updateDropTargetLocation(targetApplication, event);
+			
+			addGroupListeners(application);
+			addDragListeners(dragInitiator, dragListener);
+			
+			// creates an instance of the bounding box that will be shown around the drop target
+			if (!selectionGroup) {
+				selectionGroup = new TargetSelectionGroup();
+				selectionGroup.mouseEnabled = false;
+				selectionGroup.mouseChildren = false;
+			}
+			
+			// show selection / bounding box 
+			if (showSelectionBox) {
+				// RangeError: Error #2006: The supplied index is out of bounds.
+				PopUpManager.addPopUp(selectionGroup, swfRoot);
+				selectionGroup.visible = false;
+				selectionGroup.addEventListener(DragEvent.DRAG_OVER, dragOverHandler);
+			}
+			
+			// show mouse location lines
+			if (showListDropIndicator && mouseLocationLines) {
+				PopUpManager.addPopUp(mouseLocationLines, swfRoot);
+				mouseLocationLines.visible = false;
+			}
+			
+			// SecurityError: Error #2123: Security sandbox violation: 
+			//BitmapData.draw: http://www.radii8.com/debug-build/RadiateExample.swf cannot access http://www.google.com/intl/en_com/images/srpr/logo3w.png. No policy files granted access.
+			if (dragInitiator is Image && !Image(dragInitiator).trustedSource) {
+				snapshot = null;
+			}
+			else {
+				snapshot = DisplayObjectUtils.getBitmapAssetSnapshot2(dragInitiator as DisplayObject);
+				//snapshot = DisplayObjectUtils.getSpriteSnapshot(dragInitiator as DisplayObject);
+			}
+			
+			if (addDropShadow) {
+				snapshot.filters = [dropShadowFilter];
+			}
+			
+			dragSource.addData(draggedItem, "UIComponent");
+			
+			if (setDragManagerOffset) {
+				DragManager.doDrag(dragInitiator, dragSource, event, snapshot, -offset.x, -offset.y, 1);
+			}
+			else {
+				DragManager.doDrag(dragInitiator, dragSource, event, snapshot, 0, 0, 1);
+			}
+			
+			
+		}
+		
+		private function dragEnterHandler(event:DragEvent):void {
+			DragManager.acceptDragDrop(event.target as IUIComponent);
+			//trace("Drag Enter:" + event.target);
+		}
+		
+		protected function dragExitHandler(event:DragEvent):void {
+			//trace("Drag Exit:" + event.target);
+		}
+		
+		/**
+		 * Dispatched during a drag over event. Dispatched multiple times. 
+		 * */
+		protected function dragOverHandler(event:DragEvent):void {
+			var eventTarget:FlexSprite = FlexSprite(event.target);
+			var description:ComponentDescription;
+			var topLeftEdgePoint:Point;
+			var rectangle:Rectangle;
+			var isHorizontal:Boolean;
+			var isApplication:Boolean;
+			var isVertical:Boolean;
+			var isBasic:Boolean;
+			var isTile:Boolean;
+			var target:Object;
+			var length:int;
+			
+			
+			/*
+			// get targets under mouse pointer
+			if (adjustMouseOffset) {
+				topLeftEdgePoint = new Point(event.stageX-offset.x, event.stageY-offset.y);
+			}
+			else {
+				topLeftEdgePoint = new Point(event.stageX, event.stageY);
+			}
+			
+			// get items under point
+			targetsUnderPoint = topLevelApplication.getObjectsUnderPoint(topLeftEdgePoint);
+			length = targetsUnderPoint.length;
+
+			// start from highest component and go back to application
+			targetsUnderPoint = targetsUnderPoint.reverse();
+			
+			// update location properties
+			updateDropTargetLocation(event.stageX, event.stageY);
+			
+			if (target is mx.containers.GridItem) {
+				trace("break");
+			}
+			
+			////////////////////////////////////////////////////////////
+			// find drop target
+			////////////////////////////////////////////////////////////
+			
+			componentTreeLoop:
+			
+			// loop through items under point until we find one on the *component* tree
+			for (var i:int;i<length;i++) {
+				target = targetsUnderPoint[i];
+				
+				if (!parentApplication.contains(DisplayObject(target))) {
+					continue;
+				}
+				
+				// check if target is self
+				if (target==draggedItem) {
+					continue;
+				}
+				
+				// check if target is child of self
+				if ("contains" in draggedItem && draggedItem.contains(target)) {
+					continue;
+				}
+				
+				// as soon as we find a visual element we can find the owner
+				if (target is IVisualElement) {
+					description = DisplayObjectUtils.getVisualElementContainerFromElement(IVisualElement(target), componentTree);
+					
+					if (description) {
+						target = description.instance;
+						break;
+					}
+				}
+			}
+			
+			
+			// check if target is self
+			if (target==draggedItem) {
+				target = parentApplication;
+				Radiate.log.info("Cannot drag onto self");
+				return;
+				//continue;
+			}
+			
+			// check if target is child of self
+			if ("contains" in draggedItem && target && 
+				draggedItem.contains(target)) {
+				Radiate.log.info("Cannot drag into child of self");
+				return;
+			}
+			
+			// this shouldn't be here but if document is not set then we get all sorts of targets
+			if (target && target != parentApplication && !parentApplication.contains(DisplayObject(target))) {
+				return;
+			}
+			
+			// check if target is a group
+			if (target is GroupBase) {
+				targetGroup = target as GroupBase;
+				
+				// skip skins
+				if (target is Skin && !includeSkins) {
+					//throw new Error("target cannot be a skin");
+					target = parentApplication;
+				}
+					
+				// skip skins (for groups in checkbox skin for example)
+				if ("owner" in target && target.owner is Skin && !includeSkins) {
+					//continue;
+					target = parentApplication;
+				}
+				
+				// we found a group
+				dropTarget = target;
+				
+				// check the type
+				if (targetGroup) {
+					targetGroupLayout = targetGroup.layout;
+					
+					// reset group layout values
+					isTile = isVertical = isHorizontal = false;
+					
+					if (targetGroupLayout is HorizontalLayout) {
+						isHorizontal = true;
+					}
+					else if (targetGroupLayout is VerticalLayout) {
+						isVertical = true;
+					}
+					else if (targetGroupLayout is TileLayout) {
+						isTile = true;
+					}
+				}
+			}
+			*/
+			
+			dragData = findDropTarget(event, true, targetApplication.scaleX);
+			
+			if (dragData==null) return;
+			
+			
+			dropTarget = dragData.target;
+			isApplication = dragData.isApplication;
+			isTile = dragData.isTile;
+			isVertical = dragData.isVertical;
+			isBasic = dragData.isBasicLayout;
+			isHorizontal = dragData.isHorizontal;
+			dropLocation = dragData.dropLocation;
+			dropLayout = dragData.layout;
+			
+			////////////////////////////////////////////////////////////
+			// show selection box
+			////////////////////////////////////////////////////////////
+			if (showSelectionBox) {
+				
+				// get bounds
+				if (!dropTarget || 
+					(isApplication && !showSelectionBoxOnApplication)) {
+					
+					// set values to zero
+					if (!rectangle) {
+						rectangle = new Rectangle();
+					}
+					
+					// hide selection group
+					if (selectionGroup.visible) {
+						selectionGroup.visible = false;
+					}
+				}
+				else {
+					
+					// draw the selection rectangle only if it's changed
+					//if (lastTargetCandidate!=dropTarget) {
+						
+						// if selection is offset then check if using system manager sandbox root or top level root
+						var systemManager:ISystemManager = ISystemManager(topLevelApplication.systemManager);
+						
+						// no types so no dependencies
+						var marshallPlanSystemManager:Object = systemManager.getImplementation("mx.managers.IMarshallPlanSystemManager");
+						var targetCoordinateSpace:DisplayObject;
+						
+						if (marshallPlanSystemManager && marshallPlanSystemManager.useSWFBridge()) {
+							targetCoordinateSpace = Sprite(systemManager.getSandboxRoot());
+						}
+						else {
+							targetCoordinateSpace = Sprite(topLevelApplication);
+						}
+						
+						// get target bounds
+						rectangle = DisplayObject(dropTarget).getBounds(targetCoordinateSpace);
+						
+						// size and position fill
+						selectionGroup.width = rectangle.width;
+						selectionGroup.height = rectangle.height;
+						selectionGroup.x = rectangle.x;
+						selectionGroup.y = rectangle.y;
+						
+						// show target selection group
+						if (!selectionGroup.visible) {
+							selectionGroup.visible = true;
+						}
+						
+						selectionGroup.data = dropTarget;
+					//}
+					
+				}
+				
+			}
+			
+			
+			
+			////////////////////////////////////////////////////////////
+			// show drop indicator
+			////////////////////////////////////////////////////////////
+			if (showDropIndicator) {
+				
+				// remove previous drop indicator
+				if (lastTargetCandidate && 
+					lastTargetCandidate!=dropTarget && 
+					lastTargetCandidate is IVisualElementContainer) {
+					
+					// hide drop indicator
+					lastTargetCandidate.layout.hideDropIndicator();
+					
+					// Hide focus
+					//targetGroup.drawFocus(false);
+					//targetGroup.drawFocusAnyway = false;
+					
+					// Destroy the dropIndicator instance
+					destroyDropIndicator();
+				}
+				
+				// if drop indicator is needed
+				if (isHorizontal || isVertical || isTile) {
+					// get drop indicator location
+					//dropLocation = targetGroupLayout.calculateDropLocation(event);
+					
+					if (dropLocation) {
+						//DragManager.acceptDragDrop(parentApplication);
+						DragManager.acceptDragDrop(targetApplication);
+						
+						// Create the dropIndicator instance. The layout will take care of
+						// parenting, sizing, positioning and validating the dropIndicator.
+						dropLayout.dropIndicator = createDropIndicator();
+						
+						// Show focus
+						//drawFocusAnyway = true;
+						//targetGroup.drawFocus(true);
+						
+						// Notify manager we can drop
+						DragManager.showFeedback(event.ctrlKey ? DragManager.COPY : DragManager.MOVE);
+						
+						// Show drop indicator
+						dropLayout.showDropIndicator(dropLocation);
+					}
+					else {
+						// drop location is null
+						// hide drop indicator
+						DragManager.showFeedback(DragManager.NONE);
+						
+						// hide drop indicator
+						dropLayout.hideDropIndicator();
+						
+						// Hide focus
+						//targetGroup.drawFocus(false);
+						//targetGroup.drawFocusAnyway = false;
+						
+						// Destroy the dropIndicator instance
+						destroyDropIndicator();
+					}
+					
+				}
+					// target group is basic layout
+					// does not need drop indicator
+				else if (dropLayout) {
+					if (lastTargetCandidate && "layout" in lastTargetCandidate) {
+						lastTargetCandidate.layout.hideDropIndicator();
+					}
+					
+					// Hide if previously showing
+					dropLayout.hideDropIndicator();
+					
+					// Hide focus
+					//targetGroup.drawFocus(false);
+					//targetGroup.drawFocusAnyway = false;
+					
+					// Destroy the dropIndicator instance
+					destroyDropIndicator();
+				}
+				
+			}
+			
+			// store the last target
+			lastTargetCandidate = dropTarget;
+			
+			dropTargetName = NameUtil.getUnqualifiedClassName(dropTarget);
+			
+			event.updateAfterEvent();
+			
+			
+			if (hasEventListener(DragDropEvent.DRAG_OVER)) {
+				dispatchEvent(new DragDropEvent(DragDropEvent.DRAG_OVER));
+			}
+			
+			
+			return;
+			
+			
+			
+			
+			////////////////////////////////////////////////////////////
+			// show mouse lines
+			////////////////////////////////////////////////////////////
+			/*if (showListDropIndicator) {
+				mouseLocationLines.x = topLeftEdgePoint.x;
+				mouseLocationLines.y = topLeftEdgePoint.y;
+				mouseLocationLines.width = 1;
+				mouseLocationLines.height = parentApplication.height;
+				
+				// show mouse location
+				if (!mouseLocationLines.visible) {
+					mouseLocationLines.visible = true;
+				}
+			}
+			
+			
+			// store the last target
+			lastTargetCandidate = dropTarget;
+			
+			dropTargetName = NameUtil.getUnqualifiedClassName(dropTarget);
+			
+			//trace("target: " + dropTargetName);
+			event.updateAfterEvent();*/
+		}
+		
+		
+		/**
+		 * Find the target under mouse pointer
+		 * */
+		public function findDropTarget(event:DragEvent, draggingOver:Boolean = true, applicationScale:Number = 1):DragData {
+			/*var eventTarget:FlexSprite = FlexSprite(event.target); */
+			var visualElementContainer:IVisualElementContainer;
+			var skinnableContainer:SkinnableContainer;
+			var description:ComponentDescription;
+			var isSkinnableContainer:Boolean;
+			var topLeftEdgePoint:Point;
+			var isApplication:Boolean;
+			var isBasicLayout:Boolean;
+			var isHorizontal:Boolean;
+			var isVertical:Boolean;
+			var isGroup:Boolean;
+			var isBasic:Boolean;
+			var isTile:Boolean;
+			var layout:LayoutBase;
+			var targetsLength:int;
+			var target:Object;
+			var debug:Boolean;
+			var dropIndex:int;
+			var location:DropLocation;
+			var offscreen:Boolean;
+			
+			dragData = new DragData();
+			
+			// get targets under mouse pointer
+			if (adjustMouseOffset) {
+				var adjustedX:Number = event.stageX-(offset.x * applicationScale);
+				var adjustedY:Number = event.stageY-(offset.y * applicationScale);
+				topLeftEdgePoint = new Point(adjustedX, adjustedY);
+			}
+			else {
+				topLeftEdgePoint = new Point(event.stageX, event.stageY);
+			}
+			
+			// get items under point
+			targetsUnderPoint = topLevelApplication.getObjectsUnderPoint(topLeftEdgePoint);
+			targetsLength = targetsUnderPoint.length;
+
+			// start from highest component and go back to application
+			targetsUnderPoint = targetsUnderPoint.reverse();
+			
+			// update location properties
+			updateDropTargetLocation(targetApplication, event);
+			
+			/*if (target is mx.containers.GridItem) {
+				trace("break");
+			}*/
+			
+			////////////////////////////////////////////////////////////
+			// find drop target
+			////////////////////////////////////////////////////////////
+			
+			componentTreeLoop:
+			
+			// loop through items under point until we find one on the *component* tree
+			for (var i:int;i<targetsLength;i++) {
+				target = targetsUnderPoint[i];
+				// if parent application does not contain the target
+				if (!targetApplication.contains(DisplayObject(target))) {
+					continue;
+				}
+				
+				// check if target is self
+				if (target==draggedItem) {
+					continue;
+				}
+				
+				// check if target is child of self
+				if ("contains" in draggedItem && draggedItem.contains(target)) {
+					continue;
+				}
+				
+				// as soon as we find a visual element we can find the owner
+				if (target is IVisualElement) {
+					description = DisplayObjectUtils.getVisualElementContainerFromElement(IVisualElement(target), componentTree);
+					
+					if (description) {
+						target = description.instance;
+						break;
+					}
+				}
+			}
+			
+			
+			// check if target is self
+			if (target==draggedItem) {
+				target = targetApplication;
+				if (debug) Radiate.log.info("Cannot drag onto self");
+				if (draggingOver) return null;
+				//continue;
+			}
+			
+			// check if target is child of self
+			if (target && "contains" in draggedItem && 
+				draggedItem.contains(target)) {
+				if (debug) Radiate.log.info("Cannot drag into child of self");
+				if (draggingOver) return null;
+				//return null;
+			}
+			
+			// this shouldn't be here but if document is not set then we get all sorts of targets
+			if (target && 
+				target != targetApplication && 
+				!targetApplication.contains(DisplayObject(target))) {
+				if (debug) Radiate.log.info("Target application doesn't contain drop target");
+				if (draggingOver) return null;
+				//return null;
+			}
+			
+			// still no target then we are on the application (most likely)
+			if (!target) {
+				target = targetApplication;
+			}
+			
+			if (target==targetApplication) {
+				isApplication = true;
+			}
+			
+			// check if target is a group
+			if (target is IVisualElementContainer) {
+				
+				dropIndex = -1;
+				
+				// skip skins
+				if (target is Skin && !includeSkins) {
+					//throw new Error("target cannot be a skin");
+					target = targetApplication;
+				}
+				
+				// skip skins (for groups in checkbox skin for example)
+				if ("owner" in target && target.owner is Skin && !includeSkins) {
+					target = targetApplication;
+				}
+				
+				visualElementContainer = target as IVisualElementContainer;
+				groupBase = target as GroupBase;
+				skinnableContainer = target as SkinnableContainer;
+				
+				//isGroup = groupBase!=null;
+				//isSkinnableContainer = skinnableContainer!=null;
+				
+				// ReferenceError: Error #1069: Property layout not found on mx.containers.TabNavigator and there is no default value.
+				layout = "layout" in target ? target.layout : null;
+				
+				
+				if (!layout) return null;
+				// we found a group
+				//dropTarget = target;
+		
+				// TypeError: Error #1009: Cannot access a property or method of a null object reference.
+				// get drop indicator location
+				location = layout.calculateDropLocation(event);
+				
+				var stagePoint:Point = new Point(event.stageX, event.stageY);
+				offscreen = location.dropPoint.equals(stagePoint);
+				
+				if (location) {
+					dropIndex = location.dropIndex;
+				}
+				
+				// reset group layout values
+				isBasic = isTile = isVertical = isHorizontal = false;
+				
+				// check the type
+				//if (targetGroup) {
+				//	targetGroupLayout = targetGroup.layout;
+				
+				if (layout is BasicLayout) {
+					isBasic = true;
+				}
+				else if (layout is HorizontalLayout) {
+					isHorizontal = true;
+				}
+				else if (layout is VerticalLayout) {
+					isVertical = true;
+				}
+				else if (layout is TileLayout) {
+					isTile = true;
+				}
+				//}
+			}
+			
+			dragData.target = target;
+			dragData.offscreen = offscreen;
+			dragData.dropLocation = location;
+			dragData.dropIndex = dropIndex;
+			dragData.description = description;
+			dragData.isApplication = isApplication;
+			dragData.isHorizontal = isHorizontal;
+			dragData.isVertical = isVertical;
+			dragData.isTile = isTile;
+			dragData.isBasicLayout = isBasic;
+			dragData.layout = layout;
+			dragData.isGroup = groupBase!=null;
+			dragData.isSkinnableContainer = skinnableContainer!=null;
+			dragData.isVisualElementContainer = visualElementContainer!=null;
+			
+			return dragData;
+		}
+		
+		
+		/**
+		 * Drag drop event
+		 * */
+		protected function dragDropHandler(event:DragEvent):void {
+			var targetSkinnableContainer:SkinnableContainer;
+			var isVisualElementContainer:Boolean;
+			var isSkinnableContainer:Boolean;
+			var targetsUnderPoint:Array;
+			var dragEvent:DragDropEvent;
+			var topLeftEdgePoint:Point;
+			var isApplication:Boolean;
+			var isBasicLayout:Boolean;
+			var isHorizontal:Boolean;
+			var isVertical:Boolean;
+			var isGroup:Boolean;
+			var isTile:Boolean;
+			var offscreen:Boolean;
+			var dropIndex:int;
+			var target:Object;
+			var point:Point;
+			var length:int;
+			
+			/*
+			target = getContainerUnderPoint(event, parentApplication, true, offset);
+			
+			// get point from upper left edge of drag proxy
+			if (adjustMouseOffset) {
+				topLeftEdgePoint = new Point(event.stageX-offset.x, event.stageY-offset.y);
+			}
+			else {
+				topLeftEdgePoint = new Point(event.stageX, event.stageY);
+			}
+			
+			// get items under point
+			targetsUnderPoint = topLevelApplication.getObjectsUnderPoint(topLeftEdgePoint);
+			
+			// start at the top
+			targetsUnderPoint = targetsUnderPoint.reverse();
+			
+			// update location
+			updateDropTargetLocation(event.stageX, event.stageY);
+			
+			// reset drop location
+			dropLocation = null;
+			
+			// get length of targets
+			length = targetsUnderPoint.length;
+			
+			// loop through objects under pointer from the highest to the lowest
+			outerloop: 
+			
+			////////////////////////////////////////////////////////////
+			// find first available group
+			////////////////////////////////////////////////////////////
+			for (var i:int;i<length;i++) {
+				isGroup = false;
+				
+				target = targetsUnderPoint[i];
+				//trace(i + " of " + length+ " target:"+NameUtil.getUnqualifiedClassName(target));
+				
+				if (parentApplication.contains(DisplayObject(target))) {
+					//trace(i + " parent application is " + parentApplication);
+					//trace(i + " parent application contains " + target);
+				}
+				else {
+					//trace(i + " parent application does not contain " + target);
+					continue;
+				}
+				
+				// check if target is self
+				if (target==draggedItem) {
+					continue;
+				}
+				
+				// check if target is child of self
+				if ("contains" in draggedItem && draggedItem.contains(target)) {
+					continue;
+				}
+				
+				
+				
+				// check if target is a group
+				if (target is GroupBase || target is SkinnableContainer) {
+					dropIndex = -1;
+					
+					// skip skins
+					if (target is ApplicationSkin) {
+						target = target.owner;
+					}
+					
+					// skip skins
+					if (target is Skin && !includeSkins) {
+						continue;
+					}
+					
+					// skip skins (for groups in checkbox skin for example)
+					if ("owner" in target && target.owner is Skin && !includeSkins) {
+						continue;
+					}
+					
+					isGroup = target is GroupBase ? true : false;
+					isSkinnableContainer = target is SkinnableContainer ? true : false;
+					targetGroup = target as GroupBase;
+					targetSkinnableContainer = target as SkinnableContainer;
+					
+					// we found a group
+					dropTarget = target;
+					
+					// check the type
+					if (target) { // may not need this check
+						targetGroupLayout = target.layout;
+						
+						// get drop indicator location
+						dropLocation = targetGroupLayout.calculateDropLocation(event);
+						
+						if (dropLocation) {
+							dropIndex = dropLocation.dropIndex;
+						}
+						
+						// reset group layout values
+						isTile = isVertical = isHorizontal = false;
+						
+						if (targetGroupLayout is HorizontalLayout) {
+							isHorizontal = true;
+						}
+						else if (targetGroupLayout is VerticalLayout) {
+							isVertical = true;
+						}
+						else if (targetGroupLayout is TileLayout) {
+							isTile = true;
+						}
+						else if (targetGroupLayout is BasicLayout) {
+							isBasicLayout = true;
+						}
+					}
+					
+					//trace("found target " + targetCandidate);
+					// found a target break
+					break;
+				}
+				
+			}// end loop to find target
+			*/
+			
+			
+			// check document, parentDocument, owner and parent
+			// GROUP in CHECKBOX
+			// document = spark.skins.spark.CheckBoxSkin
+			// isDocument = false;
+			// owner = spark.skins.spark.CheckBoxSkin
+			// parent = spark.skins.spark.CheckBoxSkin
+			// parentDocument = spark.skins.spark.CheckBoxSkin
+			// systemManager = _application_mx_managers_SystemManager (@118f03ba1)
+			
+			// GROUP on Application
+			// document = spark.skins.spark.ApplicationSkin;
+			// isDocument = false;
+			// owner = application
+			// parent = spark.components.Group
+			// parentDocument = spark.skins.spark.ApplicationSkin
+			// systemManager = _application_mx_managers_SystemManager (@118f03ba1)
+			
+			
+			/*if (dropTarget is CheckBox) {
+				//trace("is checkbox");
+			}
+			else {
+				//trace("is group");
+			}*/
+			
+			
+			/*if (!dropTarget) {
+				dropTarget = parentApplication;
+			}*/
+			
+			dragData = findDropTarget(event, false);
+			
+			dropTarget 			= dragData.target;
+			dropIndex 			= dragData.dropIndex;
+			dropLocation		= dragData.dropLocation;
+			dropLayout		 	= dragData.layout;
+			isApplication 		= dragData.isApplication;
+			isTile		 		= dragData.isTile;
+			isVertical 			= dragData.isVertical;
+			isBasicLayout 		= dragData.isBasicLayout;
+			isHorizontal 		= dragData.isHorizontal;
+			isGroup				= dragData.isGroup;
+			isSkinnableContainer= dragData.isSkinnableContainer;
+			isVisualElementContainer= dragData.isVisualElementContainer;
+			offscreen			= dragData.offscreen;
+			
+			removeDragListeners(dragListener);
+			removeDragDisplayObjects();
+			removeGroupListeners(targetApplication);
+			
+			// Hide if previously showing
+			if (dropLayout) {
+				dropLayout.hideDropIndicator();
+			}
+			
+			// Hide if previously showing
+			if (lastTargetCandidate && "layout" in lastTargetCandidate) {
+				lastTargetCandidate.layout.hideDropIndicator();
+			}
+			
+			// hide drop indicator
+			DragManager.showFeedback(DragManager.NONE);
+			
+			// Destroy the dropIndicator instance
+			destroyDropIndicator();
+			
+			// store the last target
+			lastTargetCandidate = dropTarget;
+			
+			dropTargetName = NameUtil.getUnqualifiedClassName(dropTarget);
+			
+			//trace("target: " + dropTargetName);
+			event.updateAfterEvent();
+			
+			dragEvent = new DragDropEvent(DragDropEvent.DRAG_DROP, false, true);
+			dragEvent.offsetPoint 			= offset;
+			dragEvent.dragEvent				= event;
+			dragEvent.dropTarget 			= dropTarget;
+			dragEvent.dragInitiator 		= event.dragInitiator;
+			dragEvent.dragSource 			= event.dragSource;
+			dragEvent.draggedItem 			= draggedItem;
+			dragEvent.dropLocation 			= dropLocation;
+			dragEvent.dropPoint 			= dropLocation ? dropLocation.dropPoint : new Point(event.localX, event.localY);
+			dragEvent.isGroup 				= isGroup;
+			dragEvent.isTile 				= isTile;
+			dragEvent.isVertical 			= isVertical;
+			dragEvent.isHorizontal 			= isHorizontal;
+			dragEvent.isBasicLayout			= isBasicLayout;
+			dragEvent.isSkinnableContainer	= isSkinnableContainer;
+			dragEvent.isDropTargetParent 	= (dropTarget == draggedItem.parent);
+			dragEvent.isDropTargetOwner 	= (dropTarget == draggedItem.owner);
+			
+			dispatchEvent(dragEvent);
+			
+			if (dragEvent.isDefaultPrevented()) return;
+
+			
+			// SHOULD BE MOVED TO SELECTION CLASS?!?!
+			// continue drop
+			var index:int = -1;
+			var dropPoint:Point;
+			var addResult:String;
+			var move:Boolean;
+			var width:int;
+			var height:int;
+			
+			//sm = SystemManagerGlobals.topLevelSystemManagers[0];
+			
+			// THE Following code may be causing this error:
+			// TypeError: Error #1009: Cannot access a property or method of a null object reference.
+			//	at mx.managers.dragClasses::DragProxy/mouseUpHandler()[E:\dev\4.y\frameworks\projects\framework\src\mx\managers\dragClasses\DragProxy.as:640]
+			//  - the parent property is null for some reason
+			//  solution maybe to add a try catch block if possible
+			//  or monkey patch DragProxy and remove animation effect (that causes error)
+			
+			// it seems to happen when dragging and dropping rapidly
+			// stops the drop not accepted animation
+			var dragManagerImplementation:Object = mx.managers.DragManagerImpl.getInstance();
+			var dragProxy:Object = dragManagerImplementation.dragProxy;
+			//var startPoint:Point = new Point(dragProxy.startX, dragProxy.startY);
+			Object(dragManagerImplementation).endDrag(); 
+			//DragManager.endDrag();
+			
+			if (dropLocation) {
+				
+				if (isHorizontal || isVertical || isTile) {
+					index = dropLocation.dropIndex;
+				}
+				else if (isGroup || isSkinnableContainer) {
+					dropPoint = offscreen ? new Point(event.localX, event.localY) : dropLocation.dropPoint;
+				}
+			}
+			
+			var eventDescription:String = "Move";
+			
+			if (draggedItem.parent==null) {
+				eventDescription = "Add";
+			}
+			
+			// attempt to add or move
+			//addResult = Radiate.requestAddDisplayItems(draggedItem, dropTarget, null, eventDescription, null, index);
+			
+			
+			draggedItem.visible = true;
+			
+			// setPositionFromXY(target, startPoint, endPoint);
+			if (isBasicLayout) {
+				var dropX:Number;
+				var dropY:Number;
+				var values:Object = new Object();
+				var properties:Array = [];
+				var styles:Array = [];
+				var verticalCenter:int;
+				var horizontalCenter:int;
+				var setVerticalCenter:Boolean;
+				var setHorizontalCenter:Boolean;
+				var setBottom:Boolean;
+				var setRight:Boolean;
+				var setLeft:Boolean;
+				var setTop:Boolean;
+				var setX:Boolean;
+				var setY:Boolean;
+				var bottom:int;
+				var right:int;
+				var left:int;
+				var top:int;
+				var x:int;
+				var y:int;
+				var scaleX:Number = targetApplication.scaleX;
+				var scaleY:Number = targetApplication.scaleY;
+				
+				
+				var distanceFromLeftEdge:Number = targetApplication.localToGlobal(new Point).x;
+				var distanceFromTopEdge:Number = targetApplication.localToGlobal(new Point).y;
+				
+				// check for scaling
+				if (scaleX!=1 && !isNaN(scaleX)) {
+					//dropX = (dropPoint.x*scaleX) - offset.x; //45.6875
+					//dropY = (dropPoint.y*scaleY) - offset.y;
+					dropX = dropPoint.x - offset.x; //45.6875
+					dropY = dropPoint.y - offset.y;
+				}
+				else {
+					dropX = dropPoint.x - offset.x;
+					dropY = dropPoint.y - offset.y;
+				}
+				
+				
+				////////////////////////////////////////
+				// X and Y
+				////////////////////////////////////////
+				setX = true;
+				x = dropX;
+				values["x"] = x;
+				
+				setY = true;
+				y = dropY;
+				values["y"] = y;
+				
+				
+				////////////////////////////////////////
+				// Top and bottom
+				////////////////////////////////////////
+				if (draggedItem.top!=undefined) {
+					setTop = true;
+					top = dropY;
+					values["top"] = top;
+					delete values["y"];
+				}
+				
+				if (draggedItem.bottom!=undefined) {
+					setBottom = true;
+					bottom = Number(draggedItem.parent.height) - Number(draggedItem.height) - Number(dropY);
+					values["bottom"] = bottom;
+					
+				}
+				
+				////////////////////////////////////////
+				// Left and Right
+				////////////////////////////////////////
+				if (draggedItem.left!=undefined) {
+					setLeft = true;
+					left = dropX;
+					values["left"] = left;
+					delete values["x"];
+				}
+				
+				if (draggedItem.right!=undefined) {
+					setRight = true;
+					right = Number(draggedItem.parent.width) - Number(draggedItem.width) - Number(dropX);
+					values["right"] = right;
+				}
+				
+				////////////////////////////////////////
+				// Vertical and Horizontal Center
+				////////////////////////////////////////
+				if (draggedItem.verticalCenter!=undefined) {
+					setVerticalCenter = true;
+					verticalCenter = dropY - draggedItem.parent.height /2;
+					values["verticalCenter"] = verticalCenter;
+					delete values["y"];
+					//delete values["top"]; need to test
+					//delete values["bottom"];
+				}
+				
+				if (draggedItem.horizontalCenter!=undefined) {
+					setHorizontalCenter = true;
+					horizontalCenter = dropX - draggedItem.parent.width/2;
+					values["horizontalCenter"] = horizontalCenter;
+					delete values["x"];
+					//delete values["left"];
+					//delete values["right"];
+				}
+				
+				// build affected properties array
+				for (var propertyName:String in values) {
+					properties.push(propertyName);
+				}
+				
+				var moveResult:String;
+				
+				if (draggedItem.parent==null) {
+					addResult = Radiate.addElement(draggedItem, dropTarget, properties, styles, values, eventDescription);
+				}
+				else {
+					moveResult = Radiate.moveElement(draggedItem, dropTarget, properties, styles, values, eventDescription);
+				}
+				
+			}
+			// tile, vertical or horizontal layout
+			else {
+				
+				if (draggedItem.parent==null) {
+					addResult = Radiate.addElement(draggedItem, dropTarget, null, null, null, eventDescription, null, null, index);
+				}
+				else {
+					moveResult = Radiate.moveElement(draggedItem, dropTarget, null, null, null, eventDescription, null, null, index);
+				}
+			}
+			
+			
+			var dragCompleteEvent:DragDropEvent = new DragDropEvent(DragDropEvent.DRAG_DROP_COMPLETE, false, true);
+			dragCompleteEvent.offsetPoint 			= offset;
+			dragCompleteEvent.dragEvent				= event;
+			dragCompleteEvent.dropTarget 			= dropTarget;
+			dragCompleteEvent.dragInitiator 		= event.dragInitiator;
+			dragCompleteEvent.dragSource 			= event.dragSource;
+			dragCompleteEvent.draggedItem 			= draggedItem;
+			dragCompleteEvent.dropLocation 			= dropLocation;
+			dragCompleteEvent.dropPoint 			= dropLocation ? dropLocation.dropPoint : new Point(event.localX, event.localY);
+			dragCompleteEvent.isGroup 				= isGroup;
+			dragCompleteEvent.isTile 				= isTile;
+			dragCompleteEvent.isVertical 			= isVertical;
+			dragCompleteEvent.isHorizontal 			= isHorizontal;
+			dragCompleteEvent.isBasicLayout			= isBasicLayout;
+			dragCompleteEvent.isSkinnableContainer	= isSkinnableContainer;
+			dragCompleteEvent.isDropTargetParent 	= (dropTarget == draggedItem.parent);
+			dragCompleteEvent.isDropTargetOwner 	= (dropTarget == draggedItem.owner);
+			
+			dispatchEvent(dragCompleteEvent);
+			
+		}
+		
+		protected function dragCompleteHandler(event:DragEvent):void {
+			removeDragListeners(dragListener);
+			removeDragDisplayObjects();
+			removeGroupListeners(targetApplication);
+			event.currentTarget.removeEventListener(DragEvent.DRAG_COMPLETE, dragCompleteHandler);	
+		}
+		
+		private function addDragListeners(dragInitiator:IUIComponent, dragListener:DisplayObject):void {
+			
+			dragListener.addEventListener(DragEvent.DRAG_ENTER, dragEnterHandler);
+			dragListener.addEventListener(DragEvent.DRAG_EXIT, dragExitHandler);
+			dragListener.addEventListener(DragEvent.DRAG_OVER, dragOverHandler);
+			dragListener.addEventListener(DragEvent.DRAG_DROP, dragDropHandler);
+			
+			dragInitiator.addEventListener(DragEvent.DRAG_COMPLETE, dragCompleteHandler);			
+		}
+		
+		private function removeDragListeners(dragListener:DisplayObject):void {
+			dragListener.removeEventListener(DragEvent.DRAG_ENTER, dragEnterHandler);
+			dragListener.removeEventListener(DragEvent.DRAG_EXIT, dragExitHandler);
+			dragListener.removeEventListener(DragEvent.DRAG_OVER, dragOverHandler);
+			dragListener.removeEventListener(DragEvent.DRAG_DROP, dragDropHandler);
+			
+			dragInitiator.removeEventListener(DragEvent.DRAG_COMPLETE, dragCompleteHandler);	
+		}
+		
+		private function removeDragDisplayObjects():void {
+			destroyDropIndicator();
+			selectionGroup.width = 0;
+			selectionGroup.height = 0;
+			
+			PopUpManager.removePopUp(selectionGroup);
+			
+			PopUpManager.removePopUp(mouseLocationLines);
+			
+			if (mouseLocationLines) {
+				mouseLocationLines.width = 0;
+				mouseLocationLines.height = 0;
+			}
+			
+		}
+		
+		/**
+		 * Remove listeners from selected target
+		 * */
+		protected function mouseUpHandler(event:Event):void {
+			removeMouseHandlers(IUIComponent(event.currentTarget));
+		}
+		
+		/**
+		 * Remove listeners from selected target and swfroot. 
+		 * */
+		protected function removeMouseHandlers(target:IUIComponent):void {
+			
+			target.removeEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
+			swfRoot.removeEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler);
+		}
+		
+		
+		public function createDropIndicator():DisplayObject
+		{
+			// Do we have a drop indicator already?
+			if (dropIndicator)
+				return DisplayObject(dropIndicator);
+			
+			var dropIndicatorInstance:DisplayObject;
+			var dropIndicatorClass:Class;
+			
+			if (dropIndicator) {
+				//dropIndicatorInstance = DisplayObject(parentApplication.createDynamicPartInstance("dropIndicator"));
+				dropIndicatorInstance = DisplayObject(dropIndicator.newInstance());
+			}
+			else {
+				dropIndicatorClass = spark.skins.spark.ListDropIndicator;
+				
+				if (dropIndicatorClass) {
+					dropIndicatorInstance = new dropIndicatorClass();
+				}
+			}
+			
+			if (dropIndicatorInstance is IVisualElement) {
+				IVisualElement(dropIndicatorInstance).owner = targetApplication;
+			}
+			
+			// Set it in the layout
+			//layout.dropIndicator = dropIndicatorInstance;
+			return dropIndicatorInstance;
+		}
+		
+		public function destroyDropIndicator():DisplayObject {
+			var dropIndicatorInstance:DisplayObject = dropIndicator as DisplayObject;
+			
+			if (!dropIndicatorInstance)
+				return null;
+			
+			// Release the reference from the layout
+			dropIndicator = null;
+			
+			// Release it if it's a dynamic skin part
+			/*var count:int = parentApplication.numDynamicParts("dropIndicator");
+			
+			for (var i:int = 0; i < count; i++) {
+			if (dropIndicatorInstance == parentApplication.getDynamicPartAt("dropIndicator", i)) {
+			// This was a dynamic part, remove it now:
+			parentApplication.removeDynamicPartInstance("dropIndicator", dropIndicatorInstance);
+			break;
+			}
+			}*/
+			return dropIndicatorInstance;
+		}
+		
+		
+		/**
+		 * Finds the first visual element container
+		 * */
+		public static function getContainerUnderPoint(event:Object, topLevelContainer:DisplayObjectContainer, adjustMouseOffset:Boolean = true, offset:Point = null):* {
+			var topLevelApplication:Object = FlexGlobals.topLevelApplication;
+			var adjustMouseOffset:Boolean;
+			var targetsUnderPoint:Array;
+			var topLeftEdgePoint:Point;
+			var isHorizontal:Boolean;
+			var rectangle:Rectangle;
+			var isVertical:Boolean;
+			var dropTarget:Object;
+			var isTile:Boolean;
+			var isGroup:Boolean;
+			var isBasicLayout:Boolean;
+			var isVerticalLayout:Boolean;
+			var isHorizontalLayout:Boolean;
+			var includeSkins:Boolean;
+			var dropIndex:int = -1;
+			var target:Object;
+			var length:int;
+			
+			
+			// get targets under point
+			if (adjustMouseOffset) {
+				topLeftEdgePoint = new Point(event.stageX-offset.x, event.stageY-offset.y);
+			}
+			else {
+				topLeftEdgePoint = new Point(event.stageX, event.stageY);
+			}
+			
+			// get items under point
+			//targetsUnderPoint = topLevelApplication.getObjectsUnderPoint(topLeftEdgePoint);
+			targetsUnderPoint = topLevelContainer.getObjectsUnderPoint(topLeftEdgePoint);
+			
+			length = targetsUnderPoint.length;
+			
+			targetsUnderPoint = targetsUnderPoint.reverse();
+			
+			// loop through objects under pointer from the highest to the lowest
+			outerloop: 
+			
+			////////////////////////////////////////////////////////////
+			// find first available group
+			////////////////////////////////////////////////////////////
+			for (var i:int;i<length;i++) {
+				target = targetsUnderPoint[i];
+				
+				if (DisplayObjectContainer(topLevelContainer).contains(DisplayObject(target))) {
+					//trace(i + " parent application is " + parentApplication);
+					//trace(i + " parent application contains " + target);
+				}
+				else {
+					//trace(i + " parent application does not contain " + target);
+					//continue;
+					// if the top level container doesn't contain 
+					break;
+				}
+				
+				
+				// check if target is self
+				/*if (target==draggedItem) {
+					continue;
+				}
+				
+				// check if target is child of self
+				if ("contains" in draggedItem && draggedItem.contains(target)) {
+					continue;
+				}*/
+				
+				isGroup = false;
+				
+				// check if target is a group
+				if (target is GroupBase || target is SkinnableContainer) {
+					dropIndex = -1;
+					
+					
+					// skip skins
+					if (target is ApplicationSkin) {
+						target = target.owner;
+					}
+					
+					// skip skins
+					if (target is Skin && !includeSkins) {
+						continue;
+					}
+					
+					isGroup = target is GroupBase ? true : false;
+					
+					var isSkinnableContainer:Object = target is SkinnableContainer ? true : false;
+					var targetGroup:Object = target as GroupBase;
+					var targetSkinnableContainer:Object = target as SkinnableContainer;
+					
+					// we found a group
+					dropTarget = target;
+					
+					// check the type
+					if (target) { // may not need this check
+						var targetGroupLayout:Object = target.layout;
+						
+						// get drop indicator location
+						var dropLocation:Object = targetGroupLayout.calculateDropLocation(event);
+						
+						if (dropLocation) {
+							dropIndex = dropLocation.dropIndex;
+						}
+						
+						// reset group layout values
+						isTile = isVertical = isHorizontal = false;
+						
+						if (targetGroupLayout is HorizontalLayout) {
+							isHorizontal = true;
+						}
+						else if (targetGroupLayout is VerticalLayout) {
+							isVertical = true;
+						}
+						else if (targetGroupLayout is TileLayout) {
+							isTile = true;
+						}
+						else if (targetGroupLayout is BasicLayout) {
+							isBasicLayout = true;
+						}
+					}
+					
+					//trace("found target " + targetCandidate);
+					// found a target break
+					break;
+				}
+				
+			}
+			
+			// end loop to find target
+			if (!dropTarget) {
+				//trace("Group not found. Setting to application");
+				dropTarget = topLevelContainer;
+			}
+			
+			return dropTarget;
+		}
+
+		/**
+		 * Finds the first visual element under the point
+		 * */
+		public function findTargetUnderPoint(event:MouseEvent):IVisualElement {
+			var topLeftEdgePoint:Point;
+			var rectangle:Rectangle;
+			var isHorizontal:Boolean;
+			var isVertical:Boolean;
+			var isTile:Boolean;
+			var target:Object;
+			var length:int;
+			
+			// get targets under point
+			if (adjustMouseOffset) {
+				topLeftEdgePoint = new Point(event.stageX-offset.x, event.stageY-offset.y);
+			}
+			else {
+				topLeftEdgePoint = new Point(event.stageX, event.stageY);
+			}
+			
+			// get items under point
+			targetsUnderPoint = topLevelApplication.getObjectsUnderPoint(topLeftEdgePoint);
+			
+			length = targetsUnderPoint.length;
+			
+			targetsUnderPoint = targetsUnderPoint.reverse();
+			
+			// loop through objects under pointer from the highest to the lowest
+			outerloop: 
+			
+			////////////////////////////////////////////////////////////
+			// find first available group
+			////////////////////////////////////////////////////////////
+			for (var i:int;i<length;i++) {
+				target = targetsUnderPoint[i];
+				//trace(i + " of " + length+ " target:"+NameUtil.getUnqualifiedClassName(target));
+				
+				if (targetApplication.contains(DisplayObject(target))) {
+					//trace(i + " parent application is " + parentApplication);
+					//trace(i + " parent application contains " + target);
+				}
+				else {
+					//trace(i + " parent application does not contain " + target);
+					continue;
+				}
+				
+				// check if target is a group
+				if (target is GroupBase) {
+					groupBase = target as GroupBase;
+					
+					// skip skins
+					if (target is Skin && !includeSkins) {
+						continue;
+					}
+					
+					// we found a group
+					dropTarget = target;
+					
+					// check the type
+					if (groupBase) {
+						dropLayout = groupBase.layout;
+						
+						// reset group layout values
+						isTile = isVertical = isHorizontal = false;
+						
+						if (dropLayout is HorizontalLayout) {
+							isHorizontal = true;
+						}
+						else if (dropLayout is VerticalLayout) {
+							isVertical = true;
+						}
+						else if (dropLayout is TileLayout) {
+							isTile = true;
+						}
+					}
+					
+					//trace("found target " + targetCandidate);
+					// found a target break
+					break;
+				}
+			}
+			
+			// end loop to find target
+			
+			if (!dropTarget) {
+				//trace("Group not found. Setting to application");
+				dropTarget = targetApplication;
+			}
+			else {
+				//trace("Target found. Target is " + targetCandidate);
+			}
+			
+			return dropTarget as IVisualElement;
+		}
+		
+		private var _displayList:Array;
+		private var setDragManagerOffset:Boolean = false;
+		
+		public var hideDragInitiatorOnDrag:Boolean;
+		public var dropShadowFilter:DropShadowFilter = new DropShadowFilter(4, 45, 0, 1, 2, 2, .3);
+		public var addDropShadow:Boolean = false;
+
+		public var componentTree:ComponentDescription;
+
+		private var distanceFromLeft:int;
+
+		private var distanceFromTop:int;
+
+		
+		/**
+		 * Gets the display list. The parentApplication needs to be set
+		 * or this returns null. 
+		 * */
+		public function get displayList():Array {
+			
+			return _displayList; 
+		}
+		
+		/**
+		 * @private
+		 * */
+		public function set displayList(value:Array):void {
+			if (_displayList == value)
+				return;
+			_displayList = value;
+		}
+		
+		public function addGroupListeners(element:IVisualElement):void {
+			//enableDragBehaviorOnDisplayList(displayObject);
+			applicationGroups = DisplayObjectUtils.enableDragBehaviorOnDisplayList(element, true);
+		}
+		
+		public function removeGroupListeners(element:IVisualElement):void {
+			//enableDragBehaviorOnDisplayList(displayObject, null, 0, false);
+			applicationGroups = DisplayObjectUtils.enableDragBehaviorOnDisplayList(element, false, applicationGroups);
+		}
+				
+		public static function addGroupMouseSupport(group:GroupBase, applicationGroups:Dictionary):void {
+			DisplayObjectUtils.addGroupMouseSupport(group, applicationGroups);
+			//applicationGroups[group] = new GroupOptions(group.mouseEnabledWhereTransparent);
+			//group.mouseEnabledWhereTransparent = true;
+			//group.addEventListener(MouseEvent.MOUSE_OUT, enableGroupMouseHandler, false, 0, true);
+		}
+		
+		public static function removeGroupMouseSupport(group:GroupBase, applicationGroups:Dictionary):void {
+			DisplayObjectUtils.removeGroupMouseSupport(group, applicationGroups);
+			//group.mouseEnabledWhereTransparent = applicationGroups[group].mouseEnabledWhereTransparent;
+			//group.removeEventListener(MouseEvent.MOUSE_OUT, enableGroupMouseHandler);
+			//applicationGroups[group] = null;
+		}
+		
+		public static function enableGroupMouseHandler(event:MouseEvent):void
+		{
+			// this is used to enable mouse events where transparent 
+		}
+		
+		/**
+		 * Gets the display list
+		 * */
+		public function getDisplayList(element:Object, parentItem:Object = null, depth:int = 0):Object {
+			
+			/* 
+			if (displayList.length <= depth) {
+			displayList.push(new ArrayCollection());
+			} */
+			
+			
+			if (!parentItem) {
+				parentItem = {name:"root", element:element.parent, children:new ArrayCollection()};
+			}
+			
+			
+			if ("numElements" in element) {
+				var length:int = element.numElements;
+				
+				for (var i:int; i < length; i++) {
+					var child:Object = element.getElementAt(i);
+					var item:Object = {name:"test", element:child, children:new ArrayCollection()};
+					
+					parentItem.children.addItem(item);
+					
+					if ("numElements" in child) {
+						getDisplayList(child, item, depth + 1);
+					}
+					
+					
+					//displayList[depth].push(object);
+					
+				}
+			}
+			return parentItem;
+		}
+	}
+}


Mime
View raw message