package com.ericfeminella.desktop
{
import flash.desktop.ClipboardFormats;
import flash.desktop.NativeDragActions;
import flash.desktop.NativeDragManager;
import flash.display.DisplayObjectContainer;
import flash.events.NativeDragEvent;
import flash.filesystem.File;
/**
*
* Provides an API from which multiple clients of interest can receive
* notification when a <code>NativeDragEvent</code> occurs as a result
* of a specific user gesture which triggers a Drag and Drop operation
*
* <p>
* The following example demonstrates a <code>NativeDragOperation</code>
* implemntation whereas a view defines an instance of NativeDragOperation
* and passes a reference to itself as both an IDropOperationClient instance
* and DisplayObjectContainer. In addition the specific allowed files types
* are passed in as a String Array
* </p>
*
* @example
* <listing version="3.0">
*
* var dm:NativeDragOperation = new NativeDragOperation( [this], this, ["swf", "swc"]);
*
* </listing>
*
*/
public class NativeDragOperation
{
/**
*
* Defines a reference to the specific DisplayObjectContainer
* which is to listen for Drag operations which occur on it
*
*/
protected var container:DisplayObjectContainer;
/**
*
* Defines an Array of type IDropOperationClient which contains
* concrete implementations of IDropOperationClient
*
* <p>
* Each instance of IDropOperationClient will have it's corresponding
* <code>handleValidDrop</code> implementation invoked when a valid
* File type has been dropped
* </p>
*
* <p>
* Additionally, each instance of IDropOperationClient will have it's
* corresponding <code>handleInvalidDrop</code> implementation invoked
* when an invalid File type has been dropped
* </p>
*
*/
protected var clients:Array;
/**
*
* Defines an array of type String which represents each valid file type
* associated to the <code>AIRDragOperation</code> instance
*
*/
protected var allowedFileTypes:Array;
/**
*
* Contains a reference to all valid files which have been selected in a
* Drag Operation
*
* @see #validFileTypes
*
*/
protected var selectedFiles:Array;
/**
*
* Determines if the NativeDragOperation instance is to ignore case for valid
* File types
*
* @see #validFileTypes
*
*/
protected var ignoreCase:Boolean;
/**
*
* Creates a new instance of AIRDragOperation which will be responsible
* for managing all Drag Operations whih occur on a DisplayObjectContainer
*
* @example
* <listing version="3.0">
*
* var dm:NativeDragOperation = new NativeDragOperation( [this], this, ["swf", "swc"] );
*
* </listing>
*
* @param Array of INativeDragOperationClient clients
* @param container which NativeDrag Events are to be monitored
* @param String Array of valid File types
* @param instructs the NativeDragOperation instance to ignore case for valid File types
*
*/
public function NativeDragOperation(clients:Array, container:DisplayObjectContainer, allowedFileTypes:Array = null, ignoreCase:Boolean = true)
{
this.clients = clients;
this.container = container;
this.container.addEventListener( NativeDragEvent.NATIVE_DRAG_ENTER, dragInitialize );
this.container.addEventListener( NativeDragEvent.NATIVE_DRAG_DROP, dragDrop );
this.allowedFileTypes = validFileTypes;
this.ignoreCase = ignoreCase;
}
/**
*
* Sets the valid file types associated with the AIRDragOperation
* instance
*
* @example
* <listing version="3.0">
*
* var dop:AIRDragOperation = new AIRDragOperation( [this], container );
* dop.validFileTypes = ["jpg", "png", "gif"];
*
* </listing>
*
* @param String Array specifying all valid file extensions
*
*/
public function set validFileTypes(types:Array) : void
{
this.allowedFileTypes = types;
}
/**
*
* Retrieves the valid file types associated with the AIRDragOperation
* instance
*
* @example
* <listing version="3.0">
*
* var dop:AIRDragOperation = new AIRDragOperation( [this], container );
* dop.validFileTypes = ["jpg", "png", "gif"];
*
* trace( operation.validFileTypes ); //jpg, png, gif
*
* </listing>
*
* @return String Array specifying all valid file extensions
*
*/
public function get validFileTypes() : Array
{
return allowedFileTypes;
}
/**
*
* Sets the IDropOperationClient instances for the AIRDragOperation
* instance
*
* @param Array of IDropOperationClient instances
*
*/
public function set dropOperationClients(clients:Array) : void
{
this.clients = clients;
}
/**
*
* Retrieves the IDropOperationClient instances specified for the
* AIRDragOperation instance
*
* @return Array of IDropOperationClient instances
*
*/
public function get dropOperationClients() : Array
{
return clients;
}
/**
*
* Handles a <code>NativeDragEvent.NATIVE_DRAG_ENTER</code> event and
* determines if any valid file types have been selected by the user,
* if so the file is forwarded to <code></code>
*
* @param NativeDragEvent which has occurred
* @see flash.events.NativeDragEvent#NATIVE_DRAG_ENTER
*
*/
protected final function dragInitialize(event:NativeDragEvent) : void
{
this.selectedFiles = new Array();
var currentFileSelections:Array;
currentFileSelections = event.clipboard.dataForFormat( ClipboardFormats.FILE_LIST_FORMAT ) as Array;
var n:int = allowedFileTypes.length;
for each (var file:File in currentFileSelections)
{
var i:int = 0;
var extension:String = file.extension;
while ( i < n )
{
var fileType:String = allowedFileTypes[i];
if ( ignoreCase )
{
if ( fileType.toUpperCase() == extension || fileType.toLowerCase() == extension )
{
selectedFiles.push( file );
}
}
else if ( fileType == extension )
{
selectedFiles.push( file );
}
i++;
}
}
if ( selectedFiles.length > 0 )
{
NativeDragManager.acceptDragDrop( container );
}
}
/**
*
* Handles a <code>NativeDragEvent.NATIVE_DRAG_DROP</code> event
* and determines if any valid file types have been selected by
* the user, if so the file is forwarded to notifyDropOperationClients
*
* @param NativeDragEvent which has occurred
* @see flash.events.NativeDragEvent#NATIVE_DRAG_ENTER
* @see #notifyDropOperationClients
*
*/
protected function dragDrop(event:NativeDragEvent) : void
{
NativeDragManager.dropAction = NativeDragActions.COPY;
var n:int = selectedFiles.length;
for (var i:int = 0; i < n; i++)
{
notifyDrapOperationClients( selectedFiles[i] as File )
}
}
/**
*
* @private
*
* Invokes all registered <code>INativeDragOperationClient</code>
* objects.
*
* <p>
* The <code>File</code> object which has been selected is passed
* to each <code>INativeDragOperationClient</code> instance via
* <code>handleValidDrop()</code>
* </p>
*
*/
private function notifyDrapOperationClients(file:File) : void
{
var n:int = clients.length;
for (var i:int = 0; i < n; i++)
{
var client:INativeDragOperationClient = clients[i] as INativeDragOperationClient;
client.handleValidDrop( file );
}
}
}
}