Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I "unaccept" a drag in Flex?

Once I've called DragManager.acceptDrag is there any way to "unaccept" the drag? Say that I have a view which can accept drag and drop, but only in certain areas. Once the user drags over one of these areas I call DragManager.acceptDrag(this) (from a DragEvent.DRAG_OVER handler), but if the user then moves out of this area I'd like to change the status of the drag to not accepted and show the DragManager.NONE feedback. However, neither calling DragManager.acceptDrag(null) nor DragManager.showFeedback(DragManager.NONE) seems to have any effect. Once I've accepted the drag an set the feedback type I can't seem to change it.

Just to make it clear: the areas where the user should be able to drop are not components or even display objects, in fact they are just ranges in the text of a text field (like the selection). Had they been components of their own I could have solved it by making each of them accept drag events individually. I guess I could create proxy components that float over the text to emulate it, but I'd rather not if it isn't necessary.


I've managed to get it working in both AIR and the browser now, but only by putting proxy components on top of the ranges of text where you should be able to drop things. That way I get the right feedback and drops are automatically unaccepted on drag exit.

This is the oddest thing about D&D in AIR:

DragManager.doDrag(initiator, source, event, dragImage, offsetX, offsetY);

In browser-based Flex, offsetX and offsetY should be negative (so says the documentation, and it works fine). However, when running exactly the same code in AIR you have to make the offsets positive. The same numbers, but positive. That is very, very weird.


I've tested some more and what @maclema works, but not if you run in AIR. It seems like drag and drop in AIR is different. It's really, really weird because not only is the feedback not showing correctly, and it's not possible to unaccept, but the coordinates are also completely off. I just tried my application in a browser instead of AIR and dragging and dropping is completely broken.

Also, skipping the dragEnter handler works fine in AIR, but breaks everything when running in a browser.

like image 579
Theo Avatar asked Aug 14 '08 10:08

Theo


1 Answers

Are you using only the dragEnter method? If you are trying to reject the drag while still dragging over the same component you need to use both the dragEnter and dragOver methods.

Check out this example:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
    <mx:Script>
        <![CDATA[
            import mx.core.DragSource;
            import mx.managers.DragManager;
            import mx.events.DragEvent;

            private function onDragEnter(e:DragEvent):void {
                if ( e.target == lbl ) {

                    if ( e.localX < lbl.width/2 ) {
                        trace("accept");
                        DragManager.acceptDragDrop(this);
                    }
                    else {
                        DragManager.acceptDragDrop(null);
                    }
                }
            }

            private function doStartDrag(e:MouseEvent):void {
                if ( e.buttonDown ) {
                    var ds:DragSource = new DragSource();
                    ds.addData("test", "text");

                    DragManager.doDrag(btn, ds, e);
                }
            }
        ]]>
    </mx:Script>
    <mx:Label id="lbl" text="hello world!" left="10" top="10" dragEnter="onDragEnter(event)" dragOver="onDragEnter(event)" />
    <mx:Button id="btn" x="47" y="255" label="Button" mouseMove="doStartDrag(event)"/>
</mx:Application>
like image 116
Matt MacLean Avatar answered Sep 22 '22 17:09

Matt MacLean