3
votes

When you start a Flex drag action, you pass in a proxy image to be displayed when you drag across the screen. When the drop occurs, I want to be able to grab this proxy but I can't find a way to from the DragEvent object.

Is it possible? What I want is to actually drop the dragged image when the mouse button is released... Flex automatically does a nice shrinking animation on the proxy but I don't want that.

The Flex examples show what I don't want - the proxy is removed and a new image added but not in exactly the right place...

More info: I tried adding my Proxy Image as a data item to the DragSource. I was able to access this when the drop occurred and saw there is a class mx.managers.dragClasses.DragProxy which seems to have all the info I need... but this class is not documented?

So there's two questions really... how to get the proxy and find out the position of the mouse cursor within the proxy, and how to disable the Flex drop animation.

9

9 Answers

2
votes

The dragProxy is a static getter on the DragManager and is scoped to mx_internal. So to reference it, you'd have to do something like this:

import mx_internal;

And in a drag event handler:

var p:* = DragManager.mx_internal::dragProxy;

I'm not sure how you could prevent the animation. If I find out, I'll let you know.

2
votes

For disabling the animation in the s:List, in a dragCompleteHandler override, you can 'hack' into the DragManager to get the dragProxy and hide it.

override protected function dragCompleteHandler(e:DragEvent):void
{
  DragManager.mx_internal::dragProxy.visible = false; // <- MAGIC!
  super.dragCompleteHandler(e);
}

Probably applicable in other situations.

1
votes

Only way to prevent the animation:

-You have to monkey patch the DragProxy class (i.e. create a new class with identical name, code, and package structure), and remove the effects code from the mouseUpHandler().

No other way to override it as far as I know, though the issue was been submitted as a bug to Adobe over a year ago.

1
votes

As far as getting the mouse coords for the proxy to drop it in the correct location try this:

assuming you are initiating the drag on mouseDown get the coords using e.currentTarget.contentMouseX and e.currentTarget.contentMouseY in your handler. then add these to the dragSource ( I did it as an object ) like:

var drgSrc:DragSource = new DragSource();
drgSrc.addData( { x:e.currentTarget.contentMouseX, y:e.currentTarget.contentMouseY }, 'drgXY' );

then in your drop handler ( assuming you are dropping it into a Canvas named drpCvs ):

var newImg:Image = new Image();
newImg.x = drpCvs.contentMouseX - e.dragSource.dataForFormat( 'drgXY' ).x;
newImg.y = drpCvs.contentMouseY - e.dragSource.dataForFormat( 'drgXY' ).y;

I found this while looking for a way to get rid of the shrink animation, so thanks for that. Thought I'd RTF.

0
votes

If you just want to prevent the animation, the easiest (hackiest) way is this: create you're own proxy and add a MOUSE_UP handler to the stage that when triggered sets the visible property of your proxy to false. It won't actually stop the animation, it will just hide the proxy while the animation is happening. Something like this:

var proxy:UIComponent = new UIComponent();
proxy.graphics.lineStyle(1);
proxy.graphics.beginFill(0xccddff);
proxy.graphics.drawRect(0, 0, main.width, main.height);
stage.addEventListener(MouseEvent.MOUSE_UP, function (e:MouseEvent):void {
  proxy.visible = false;
});
0
votes

@ykessler: Thank you, the monkey patch worked like a charm. SDK: DragProxy.as

@Alvaro: I believe this approach results in a race condition. I tried it, and it only worked sometimes.

0
votes

Setting

event.dragInitiator.visible = false;

in the drag drop handler works for me!

0
votes

My solution to turn off the animation, was to set visible=0 onMouseUp in my custom ListItemDragProxy component.

0
votes

My solution is to remove the MouseUp-Handler on SandboxRoot and attach an own MouseUp-Handler in dragEnterHandler of the target like this:

protected function dragEnterHandler(event:DragEvent):void{

        DragManager.acceptDragDrop(this);

        this.dragProxy = DragManager.mx_internal::dragProxy;// get drag proxy

        var sm:ISystemManager = event.dragInitiator.systemManager.topLevelSystemManager as ISystemManager;
        var ed:IEventDispatcher = sm.getSandboxRoot();
        this.sandboxRoot = sm.getSandboxRoot();
        //remove
        ed.removeEventListener(MouseEvent.MOUSE_UP, dragProxy.mouseUpHandler, true);

        //attach own
        ed.addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler, true);
        ed.addEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler);

        this.dragInitiator = event.dragInitiator;}

In mouseUpHandler I've implemented the copy of function mouseUpHandler from original DragProxy.as and removed the Drop-Effect.