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;
+ }
+ }
+}