<?xml version="1.0" encoding="utf-8"?>
<s:List xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
itemRenderer="de.dtele.ui.components.ResourceItemRenderer"
allowMultipleSelection="true"
creationComplete="onCreationComplete(event)"
keyDown="onKeyDown(event)"
dragEnabled="true"
dragMoveEnabled="true"
dropEnabled="true"
dragEnter="onDragEnter(event)"
dragOver="onDragOver(event)"
dragDrop="onDragDrop(event)"
dragComplete="onDragComplete(event)">
<fx:Metadata>
/**
* A list of resources
*
* @author Mathias Brodala
*/
/**
* Dispatched when a resource was selected
*/
[Event("resourceSelected", type="de.dtele.ui.components.events.ResourceListEvent")]
</fx:Metadata>
<fx:Declarations>
<mx:Sort id="resourcesSort" compareFunction="compareResources"/>
</fx:Declarations>
<fx:Script>
<![CDATA[
import de.dtele.control.MediaManager;
import de.dtele.data.IResource;
import de.dtele.net.MediaRequest;
import de.dtele.ui.components.events.ResourceListEvent;
import mx.collections.ListCollectionView;
import mx.collections.Sort;
import mx.core.DragSource;
import mx.core.IUIComponent;
import mx.events.DragEvent;
import mx.events.FlexEvent;
import mx.managers.DragManager;
/**
* Tells whether a resource does not belong to the currently selected source
*
* @param resource The resource to check
* @return TRUE if the resource belongs to the currently selected source, FALSE otherwise
*/
protected function isFromOtherSource(resource:IResource, ...a):Boolean {
return resource.source != MediaManager.instance.selectedSource;
}
/**
* Compares numerical indices
*/
protected function compareIndices(a:int, b:int):int {
return a - b;
}
/**
* Compares resources by the current main property
*/
protected function compareResources(a:IResource, b:IResource, fields:Array = null):int {
if (!a || !b) {
return 0;
}
var aTitle:String = a.properties.title.toLowerCase();
var bTitle:String = b.properties.title.toLowerCase();
var result:int = aTitle.localeCompare(bTitle);
return Math.max(-1, Math.min(result, 1));
}
/**
* Retrieves the currently selected resources
*
* @see spark.components.List#copySelectedItemsForDragDrop()
*/
protected function getSelectedResources():Vector.<IResource> {
var draggedIndices:Vector.<int> = selectedIndices.slice(0, this.selectedIndices.length);
var resources:Vector.<IResource> = new Vector.<IResource>(draggedIndices.length);
draggedIndices.sort(compareIndices);
for (var i:int = 0; i < draggedIndices.length; ++i) {
resources[i] = this.dataProvider.getItemAt(draggedIndices[i]) as IResource;
}
return resources;
}
/**
* Overrides the default method called for adding
* drag data and adds a typed list of resources.
*
* By default a similar data format called "itemsByIndex" is added
* but this demonstrates how to set specific data.
*/
public override function addDragData(dragSource:DragSource):void {
dragSource.addHandler(this.getSelectedResources, "resources");
}
/**
* Prepares watching data provider changes
*/
protected function onCreationComplete(event:FlexEvent):void {
this.addEventListener("dataProviderChanged", this.onDataProviderChanged);
this.dispatchEvent(new Event("dataProviderChanged"));
}
/**
* Assigns the sorting and refreshes the data source
*/
protected function onDataProviderChanged(e:Event):void {
if (this.dataProvider) {
var listCollection:ListCollectionView = this.dataProvider as ListCollectionView;
listCollection.sort = this.resourcesSort;
listCollection.refresh();
}
}
/**
* Assigns the sorting and refreshes the data source
*/
protected function onKeyDown(event:KeyboardEvent):void {
if (this.selectedItems.length > 0) {
var resource:IResource = this.selectedItems[this.selectedItems.length - 1] as IResource;
MediaManager.instance.selectedResource = resource;
}
}
/**
* Checks if adding of resources is allowed with the currently selected
* source and whether all resources to add are from a different source.
*
* If true accepts the drop and shows feedback.
*
* @param e The DragEvent object.
*/
protected function onDragEnter(e:DragEvent):void {
e.preventDefault();
if (e.dragSource.hasFormat("resources")) {
var resources:Vector.<IResource> = e.dragSource.dataForFormat("resources") as Vector.<IResource>;
if ((MediaRequest.ADD in MediaManager.instance.selectedSource.allowed) &&
resources.every(isFromOtherSource)) {
DragManager.acceptDragDrop(e.currentTarget as IUIComponent);
DragManager.showFeedback(e.ctrlKey ? DragManager.MOVE : DragManager.COPY);
} else {
DragManager.acceptDragDrop(e.dragInitiator);
DragManager.showFeedback(DragManager.NONE);
}
}
}
/**
* Draws the focus indicator while data is being dragged
* over the list and updates the feedback during drag
*
* @param e The DragEvent object.
*/
protected function onDragOver(e:DragEvent):void {
e.preventDefault();
if (e.dragSource.hasFormat("resources")) {
var resources:Vector.<IResource> = e.dragSource.dataForFormat("resources") as Vector.<IResource>;
if ((MediaRequest.ADD in MediaManager.instance.selectedSource.allowed) &&
resources.every(isFromOtherSource)) {
this.drawFocus(true);
DragManager.acceptDragDrop(e.currentTarget as IUIComponent);
DragManager.showFeedback(e.ctrlKey ? DragManager.MOVE : DragManager.COPY);
} else {
DragManager.acceptDragDrop(e.dragInitiator);
DragManager.showFeedback(DragManager.NONE);
}
}
}
/**
* Prevents the default action which removes items from their
* data sources as this depends on whether moving or copying
* resources actually succeeded
*
* @param e The DragEvent object.
*/
protected function onDragDrop(e:DragEvent):void {
this.drawFocus(false);
e.preventDefault();
}
/**
* Prevents the default action which removes items from their
* data sources as this depends on whether moving or copying
* resources actually succeeded
*
* @param e The DragEvent object.
*/
protected function onDragComplete(e:DragEvent):void {
e.preventDefault();
if (e.dragSource.hasFormat("resources")) {
var resources:Vector.<IResource> = e.dragSource.dataForFormat("resources") as Vector.<IResource>;
switch (e.action) {
case DragManager.COPY:
var resourcesArray:Array = new Array(resources.length);
for (var i:int = 0; i < resources.length; ++i) {
resourcesArray[i] = resources[i];
}
MediaManager.instance.addResources(resourcesArray, MediaManager.instance.selectedSource);
break;
case DragManager.MOVE:
MediaManager.instance.moveResources(resources, MediaManager.instance.selectedSource);
break;
}
}
}
protected function onResourceSelected(e:ResourceListEvent):void {
this.dispatchEvent(e);
}
]]>
</fx:Script>
<s:layout>
<s:TileLayout horizontalGap="6" verticalGap="6"/>
</s:layout>
</s:List>