Le Drag and drop sous Flex est vraiment sympa : on peut dragger des éléments d'un composant vers un autre. Mais avec AIR, on peut aussi dragger des éléments depuis ou vers le Bureau, enfin le système de l'utilisateur.

Comme d'habitude, un petit exemple en vidéo :

Texte de remplacement


Voici 4 exemples pour mieux comprendre :

I : Drag depuis le Bureau vers AIR avec NativePath

Dans cet exemple, quand le drag est initialisé (la souris revient dans l'appli AIR), on teste l'extension du fichier draggé, puis on utilise la propriété NativePath pour récupérer le chemin du fichier draggé. On passe ensuite ce chemin à la propriété source du composant image, qui nous affiche donc l'image.

<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" 
layout="absolute"  creationComplete="init()"
width="352" height="270">
<mx:Script>
<![CDATA[
import mx.controls.Alert;
import flash.desktop.DragActions; 
import flash.desktop.Clipboard;
import flash.desktop.ClipboardFormats;
import flash.events.NativeDragEvent; 
import flash.desktop.DragManager; 
		
	public function init():void{
		addEventListener(NativeDragEvent.NATIVE_DRAG_ENTER,onDragIn); 
        	addEventListener(NativeDragEvent.NATIVE_DRAG_DROP,onDrop); 
        	addEventListener(NativeDragEvent.NATIVE_DRAG_EXIT,onDragExit); 
	} 
                          
	public function onDragIn(event:NativeDragEvent):void{ 
		DragManager.acceptDragDrop(this);         
	} 
		
	public function onDragExit(event:NativeDragEvent):void{ 
                //Drag exit;                         
	} 
		
	public function onDrop(event:NativeDragEvent):void{ 
			
                var dropfiles2:Array = event.clipboard.dataForFormat(ClipboardFormats.FILE_LIST_FORMAT) as Array;
                     
                for each (var file:File in dropfiles2){                      
            	    switch (file.extension){                     
                	case "jpg" :  
                    	addImg(file.nativePath); 
                    break; 
                    case "JPG" :  
                    	addImg(file.nativePath); 
                    break;
                    default:  
                    	Alert.show("\nSeuls les formats JPG et jpg sont supportés"); 
			} 
		}          
	}    
		
	private function addImg(nativePath:String):void{ 
    
        	if(Capabilities.os.search("Mac") >= 0){ 
            	        img.source = "file://" + nativePath;                  
		} else { 
    			img.source = nativePath;
		} 
	}
		
]]>
</mx:Script>
<mx:Label text="Glissez votre photo ici" width="128" height="16" 
	horizontalCenter="0" verticalCenter="0"/>
<mx:Image id="img" right="14" top="12" left="16" bottom="16" 
	scaleContent="true"/>
</mx:WindowedApplication>

II : Drag depuis le Bureau vers AIR avec HTTPService();

Dans cet exemple, quand le drag est initialisé (la souris revient dans l'appli AIR), on utilise la propriété url pour récupérer le chemin du fichier draggé. On passe ensuite ce chemin à une fonction qui utilise un HTTPService() pour charger le contenu du fichier texte dans une variable.On peut ensuite afficher le contenu du fichier texte dans un composant TextArea.

<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" 
layout="absolute"  creationComplete="init()"
width="352" height="270">
<mx:Script>
<![CDATA[
import mx.rpc.http.HTTPService;
import mx.controls.Alert;
import flash.desktop.DragActions; 
import flash.desktop.Clipboard;
import flash.desktop.ClipboardFormats;
import flash.events.NativeDragEvent; 
import flash.desktop.DragManager; 
import mx.rpc.events.ResultEvent;
	
	public var itemConn:HTTPService;
		
	public function init():void{
		addEventListener(NativeDragEvent.NATIVE_DRAG_ENTER,onDragIn); 
        	addEventListener(NativeDragEvent.NATIVE_DRAG_DROP,onDrop); 
        	addEventListener(NativeDragEvent.NATIVE_DRAG_EXIT,onDragExit); 
	} 
                          
	public function onDragIn(event:NativeDragEvent):void{ 
		DragManager.acceptDragDrop(this);         
	} 
		
	public function onDragExit(event:NativeDragEvent):void{ 
                //Drag exit;                         
	} 
		
	public function onDrop(event:NativeDragEvent):void{ 
			
		Txt.htmlText = "";
		var dropfiles:Array = event.clipboard.dataForFormat(ClipboardFormats.FILE_LIST_FORMAT) as Array;      
		for each (var file:File in dropfiles){                      
            	        LoadTextFile(file.url);    
		}
	}    
		
	public function LoadTextFile(url:String):void
	{
		itemConn = new HTTPService();
		itemConn.addEventListener(ResultEvent.RESULT,LoadTextFile_resultHandler);
		itemConn.url = url;
		itemConn.send();
	}
	
	private function LoadTextFile_resultHandler(event:ResultEvent):void
        {
		var rows:Array = String(itemConn.lastResult).split("\n");
		  for (var i:int = 0; i < rows.length; i++)
      		  {
        	        Txt.htmlText += rows[i];
      		  }
        }
]]>
</mx:Script>
<mx:Label text="Glissez votre fichier texte ici" width="162" height="16" 
horizontalCenter="0" verticalCenter="0"/>
<mx:TextArea right="10" top="10" left="10" bottom="10" id="Txt"/>
</mx:WindowedApplication>

III : Drag d'une image (un graphique en fait) depuis une appli AIR vers le Bureau;

Dans cet exemple, quand le drag est initialisé (la souris sort de l'appli AIR), on appelle une méthode qui créé une image jpg du graphique puis écris sur le Bureau un fichier jpg contenant cette image.

<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" 
layout="absolute" creationComplete="init()">
<mx:Script>
<![CDATA[
		
import mx.collections.ArrayCollection;
import mx.formatters.DateFormatter;
import com.phiphou.utils.JPGEncoder;
		
private var dateFormatter:DateFormatter;
public var dragIcon:BitmapData;
		
[Embed(source="assets/icon_image.png")]
private var ICON_IMAGE:Class;
		
[Bindable]
public var results:ArrayCollection = new ArrayCollection( [
            { Country: "USA", Gold: 35, Silver:39, Bronze: 29 },
            { Country: "China", Gold: 32, Silver:17, Bronze: 14 },
            { Country: "Russia", Gold: 27, Silver:27, Bronze: 38 } ]);
			
	public function init():void{
        	lc.addEventListener(MouseEvent.MOUSE_MOVE, onDrag);
        	dragIcon = new ICON_IMAGE().bitmapData;
		dateFormatter = new DateFormatter();
		dateFormatter.formatString = "DD-MM-YYYY HH-NN-SS";
	} 
                            
	private function onDrag(event:MouseEvent):void
	{
		if (!event.buttonDown) 
		{
				return;
		}
		var data:Clipboard = new Clipboard
		var bd:BitmapData = new BitmapData(lc.width, lc.height);
		bd.draw(lc);
		data.addData(bd, ClipboardFormats.BITMAP_FORMAT, false);
		data.addData([TempFile()], ClipboardFormats.FILE_LIST_FORMAT);
		DragManager.doDrag(lc, data, dragIcon, null);
	}
		
	private function TempFile():File
	{
		var file:File = File.createTempDirectory().resolvePath("data-"+dateFormatter.format(new Date())+".jpg");
		var fileStream:FileStream = new FileStream();
		fileStream.open(file, FileMode.WRITE);
		fileStream.writeBytes(encodeJPG());
		fileStream.close();
		return file;
	}
 
	private function encodeJPG():ByteArray
	{
		var bd:BitmapData = new BitmapData(lc.width, lc.height);
		bd.draw(lc);
		var jpgEncoder:JPGEncoder = new JPGEncoder();
		var bytes:ByteArray = jpgEncoder.encode(bd);
		return bytes;
	}
		
]]>
</mx:Script>
	
<mx:ColumnChart id="lc" dataProvider="{results}" showDataTips="true" width="100%" height="100%">
	<mx:horizontalAxis>
	<mx:CategoryAxis categoryField="Country"/>
	</mx:horizontalAxis>
	<mx:series>
		<mx:ColumnSeries yField="Gold"/>
		<mx:ColumnSeries yField="Silver"/>
		<mx:ColumnSeries yField="Bronze"/>
	</mx:series>
</mx:ColumnChart>
</mx:WindowedApplication>

III : Drag d'un datagrid depuis une appli AIR vers un fichier texte sur le Bureau;

Dans cet exemple, quand le drag est initialisé (la souris sort de l'appli AIR), on appelle une méthode qui créé une version texte du datagrid puis écris sur le Bureau un fichier texte contenant ces données.

<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" 
layout="absolute" creationComplete="init()">
<mx:Script>
<![CDATA[
		
import mx.collections.ArrayCollection;
import mx.formatters.DateFormatter;
import com.phiphou.utils.JPGEncoder;
		
	private var dateFormatter:DateFormatter;
	public var dragIcon:BitmapData;
		
	[Embed(source="assets/icon_txt.png")]
	private var ICON_TXT:Class;
		
	[Bindable]
        public var results:ArrayCollection = new ArrayCollection( [
            { Country: "USA", Gold: 35, Silver:39, Bronze: 29 },
            { Country: "China", Gold: 32, Silver:17, Bronze: 14 },
            { Country: "Russia", Gold: 27, Silver:27, Bronze: 38 } ]);
			
	public function init():void{
        	DG.addEventListener(MouseEvent.MOUSE_MOVE, onDrag);
        	dragIcon = new ICON_TXT().bitmapData;
		dateFormatter = new DateFormatter();
		dateFormatter.formatString = "DD-MM-YYYY HH-NN-SS";
	} 
                            
	private function onDrag(event:MouseEvent):void
	{
		if (!event.buttonDown) 
		{
			return;
		}
 
		var data:Clipboard = new Clipboard
		data.addData(dgToText(), ClipboardFormats.TEXT_FORMAT);
		data.addData([createXLS()], ClipboardFormats.FILE_LIST_FORMAT);
		DragManager.doDrag(DG, data, dragIcon, null);
	}
		
	private function createXLS():File
	{
		var file:File = File.createTempDirectory().resolvePath("data-"+dateFormatter.format(new Date())+".txt");
		var fileStream:FileStream = new FileStream();
		fileStream.open(file, FileMode.WRITE);
		fileStream.writeUTFBytes(dgToText());
		fileStream.close();
		return file;
	}
 
	private function dgToText():String
	{
		var Text:String = "";
		Text += "";
		for (var i:int = 0; i<DG.columnCount; i++)
			{
				Text += "" + DataGridColumn(DG.columns[i]).headerText + "  ";							
			}
		Text += String.fromCharCode(13);
		for (var j:int = 0; j<DG.dataProvider.length; j++)
			{
				var row:Object = DG.dataProvider.getItemAt(j);
				Text += "";
				for (var k:int = 0; k<DG.columnCount; k++)
				{
					if(k==0){
						Text += "" + row[DataGridColumn(DG.columns[k]).dataField] + "";								
					} else {
						Text += ":" + row[DataGridColumn(DG.columns[k]).dataField] + "";							
					}
				}
				Text += String.fromCharCode(13);;
			}
		Text += "";
		return Text;
	}
]]>
</mx:Script>
<mx:DataGrid id="DG" dataProvider="{results}" right="10" bottom="10" left="10" top="10">
	<mx:columns>
		<mx:DataGridColumn headerText="Pays" dataField="Country"/>
		<mx:DataGridColumn headerText="Or" dataField="Gold"/>
		<mx:DataGridColumn headerText="Argent" dataField="Silver"/>
		<mx:DataGridColumn headerText="Bronze" dataField="Bronze"/>
	</mx:columns>
</mx:DataGrid>
</mx:WindowedApplication>

Voilà... 8-)