Okay, here's a pretty simple way to do this, based on the last example in this Flex Quick Starts article. This should probably be improved by using the "proper" drop indicators (the lines between items) instead of just selecting the item under the mouse when dragging.
The most relevant part is the onDragOver()
method, where we restrict where items can be dropped.
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:Script>
<![CDATA[
import mx.events.DragEvent;
import mx.managers.DragManager;
import mx.core.DragSource;
import mx.core.UIComponent;
import mx.controls.Tree;
private var _draggedItem:XML = null;
private function onDragEnter( event:DragEvent ) : void
{
event.preventDefault();
event.currentTarget.hideDropFeedback(event);
var ds:DragSource = event.dragSource;
var items:Array = ds.dataForFormat("treeItems") as Array;
if (items != null && items.length > 0 && (items[0] is XML))
_draggedItem = items[0];
DragManager.acceptDragDrop(UIComponent(event.currentTarget));
}
private function onDragOver( event:DragEvent ) : void
{
event.preventDefault();
event.currentTarget.hideDropFeedback(event);
tree.selectedIndex = tree.calculateDropIndex(event);
var node:XML = tree.selectedItem as XML;
// restrict drag & drop to nodes within same parent
if (_draggedItem.parent() != node.parent())
{
DragManager.showFeedback(DragManager.NONE);
return;
}
DragManager.showFeedback(DragManager.MOVE);
}
private function onDragDrop( event:DragEvent ) : void
{
event.preventDefault();
event.currentTarget.hideDropFeedback(event);
tree.selectedIndex = tree.calculateDropIndex(event);
var node:XML = tree.selectedItem as XML;
var addToIndex:int = node.childIndex();
if ((_draggedItem.parent() == node.parent()) && (addToIndex != _draggedItem.childIndex()))
{
tree.dataDescriptor.removeChildAt(node.parent(), _draggedItem, _draggedItem.childIndex());
tree.dataDescriptor.addChildAt(node.parent(), _draggedItem, addToIndex);
}
}
private function onDragComplete( event:DragEvent ) : void
{
tree.selectedIndex = -1;
}
]]>
</mx:Script>
<mx:XML id="treeData" xmlns="">
<root>
<node label="Massachusetts" type="state" data="MA">
<node label="Boston" type="city" >
<node label="Smoke House Grill" type="restaurant" />
<node label="Equator" type="restaurant" />
<node label="Aquataine" type="restaurant" />
<node label="Grill 23" type="restaurant" />
</node>
<node label="Provincetown" type="city" >
<node label="Lobster Pot" type="restaurant" />
<node label="The Mews" type="restaurant" />
</node>
</node>
<node label="California" type="state" data="CA">
<node label="San Francisco" type="city" >
<node label="Frog Lane" type="restaurant" />
</node>
</node>
</root>
</mx:XML>
<mx:Tree width="100%" height="100%" id="tree"
labelField="@label"
dataProvider="{treeData.node}"
allowMultipleSelection="false"
dragEnabled="true"
dropEnabled="true"
dragMoveEnabled="false"
dragEnter="onDragEnter(event)"
dragOver="onDragOver(event)"
dragDrop="onDragDrop(event)"
dragComplete="onDragComplete(event)">
</mx:Tree>
</mx:Application>