- Drag and Drop in an Application (DragManager Class)
- Drag and Drop Between the OS and the Application (NativeDragManager)
- Drag and Drop Items into an AIR Application from the OS
- Drag Items into the dpTimeTracker Application
- Drag Items from an AIR Application to the OS
- Drag Items into the OS
- Next Steps
Drag Items from an AIR Application to the OS
When initiating a doDrag() using NativeDragManager, you must pass the method a dragInitiator and a clipboard object. You can also optionally pass a BitmapData object for the proxy, an offset for the proxy from the cursor position, and finally a NativeDragOptions object.
The dragInitiator serves the same role it did in the DragManager class, which is a reference to the component that is beginning the drag action. The second argument is the clipboard (DragManager uses dragSource instead) to store the data along with format information for translation to the OS, another control, or another application.
The optional arguments vary more significantly from the DragManager class. The first is the dragImage, which accepts a BitmapData instead of an IFlexDisplayObject. The second is the offset, which is a Point object that contains an x- and y-coordinate, instead of passing these as discrete properties. Finally, there is the NativeDragOptions object, which is made up of three properties (allowCopy:Boolean, allowLink:Boolean, and allowMove:Boolean) that determine which actions can be performed on a drop. If NativeDragOptions is null, then by default all actions are allowed.
Next, you will see how to drag items from your application to the desktop. This example allows you to drag an image from the AIR application to the desktop.
Listing 8.
<?xml version="1.0" encoding="utf-8"?> <mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" > <mx:Label text="Drag this image to your desktop"/> <mx:Script> <![CDATA[ import mx.controls.Alert; protected function handleDragBegin( event : MouseEvent ):void { var imageFile:File = new File(); imageFile.nativePath = img1.source.toString(); var fileArray : Array = new Array(); fileArray.push( imageFile ); var clip : Clipboard = new Clipboard(); clip.setData(ClipboardFormats.FILE_LIST_FORMAT,fileArray); var dragOptions : NativeDragOptions = new NativeDragOptions(); dragOptions.allowCopy = true; dragOptions.allowLink = true; dragOptions.allowMove = false; NativeDragManager.doDrag( event.currentTarget as InteractiveObject, clip, null, null, dragOptions ); } protected function handleDragComplete(event:NativeDragEvent):void { var x : String = event.dropAction; Alert.show("The Drop Action was " + x ); } ]]> </mx:Script> <mx:HBox backgroundColor="red" width="300" height="300"> <mx:Image id="img1" source="c:\images\mypic.jpg" mouseDown="handleDragBegin( event )" nativeDragComplete="handleDragComplete( event )"/> </mx:HBox> </mx:WindowedApplication>
You will notice two event handlers on img1: one for the mouseDown event and the other for nativeDragComplete. Similar to the DragManager examples earlier in this chapter, a native drag operation often begins with a mouseDown event. In this case, the handleDragBegin() is called, starting the drag process. The following handleDragBegin() method is from Listing 8.
protected function handleDragBegin( event : MouseEvent ):void { var imageFile:File = new File(); imageFile.nativePath = img1.source.toString(); var fileArray : Array = new Array(); fileArray.push( imageFile ); var clip : Clipboard = new Clipboard(); clip.setData(ClipboardFormats.FILE_LIST_FORMAT,fileArray); var dragOptions : NativeDragOptions = new NativeDragOptions(); dragOptions.allowCopy = true; dragOptions.allowLink = true; dragOptions.allowMove = false; NativeDragManager.doDrag( event.currentTarget as InteractiveObject, clip, null, null, dragOptions ); }
As you learned earlier, moving files between the OS and your AIR application is usually accomplished using a format named ClipboardFormats.FILE_LIST_FORMAT, which is an array of File objects. In handleDragBegin(), you create an imageFile of type File and set its path to the source path of the image instance in your application. Next, you create an array and push the File instance into the array.
var fileArray : Array = new Array(); fileArray.push( imageFile );
A Clipboard object is instantiated, which is used in place of DragSource in native drag-and-drop operations. Using the setData() function, you set the ClipboardFormat and the data that you wish to drag. ClipboardFormat.FILE_LIST_FORMAT is the format for a group of Files.
You may also choose to use setDataHandler() instead of setData(). When using the setData() method, the actual data is passed into the method. With setDataHandler(), you can specify a function that will produce the requisite data for the given format when the drag-and-drop operation is complete. You will see a further demonstration on this in the dpTimeTracker application in the next section.
clip.setData( ClipboardFormats.FILE_LIST_FORMAT, fileArray );
Next, the NativeDragOptions are set. This step is optional, as AIR provides defaults, but it is suggested for more granular control over the allowable drag actions. If you choose to specify the options, you will set the allowCopy, allowLink, and allowMove properties to either true or false.
var dragOptions : NativeDragOptions = new NativeDragOptions(); dragOptions.allowCopy = true; dragOptions.allowLink = true; dragOptions.allowMove = false;
Setting these drag options does not actually prevent you from moving, copying, or linking, but enables or disables the feedback indicators on your mouse and prevents the incorrect dropAction from being set when the drag is completed. We cover this in more detail later in the section.
Next, you call the NativeDragManager.doDrag() function to start the drag operation providing the required arguments.
NativeDragManager.doDrag( event.currentTarget as InteractiveObject, clip, null, null, dragOptions );
The NativeDragManager.doDrag() function consists of five arguments. The first argument is the drag initiator and in this case is img1 (the Image component). Next is the clipboard object containing the data to be transported during the drag.
The next two arguments deal with the appearance of the item as it is being dragged. First is the dragImage, which must be of type BitmapData, and second is the offset from the cursor, which is of type Point. Those two arguments are left null in this example and are only required if you wish to display an image proxy and change its alignment on the cursor.
The last argument is the NativeDragOptions object. The user is now free to drag the image outside of the application and drop it in the native file system.
When the drop operation is complete, a nativeDragComplete event dispatches from the dragInitiator (the image).
<mx:Image id="img1" height="100" width="100" mouseDown="handleMouseDown( event )" nativeDragComplete="handleDragComplete( event )"/> protected function handleDragComplete( event : NativeDragEvent ) : void { var x : String = event.dropAction; Alert.show("The Drop Action was " + x ); }
Using information provided in event.dropAction, you will be able to identify the exact action that took place when the drag was released. The dropAction will indicate whether or not the drop was successful. If the dropAction is equal to NativeDragActions.NONE, then the drop was either not accepted by the OS or the drop was released over something that was not prepared to accept it.
This is where setting the NativeDragOptions also becomes important. It provides a suggestion on the type of drop operation your code can handle. Then, depending on the dropAction, you will need to determine the appropriate action to take with the source data. In other words, if the dropAction is equal to “move”, then the original source data should be removed, whereas if it was equal to “copy”, then the source data will likely remain. If you are not prepared, or cannot delete that piece of source data, then you should also not allow move as a possibility in the drag options.