Drag and Drop
Feathers UI provides a DragDropManager
to support drag-and-drop of children and data between UI components.
Built-in drag and drop
The ListView
and GridView
data containers can enable drag-and-drop gestures by setting certain properties. The user can pick up an item or row with the pointer (either on mouse down or touch start), drag it, and then drop by releasing the pointer (on mouse up or touch end).
Set the
dragEnabled
property totrue
to enable an item or row to be picked up by the user's pointer on mouse down or touch start.Set the
dropEnabled
property totrue
to allow the user to drop an item on the container and add it to the data provider.Set the
removeOnDragDropComplete
totrue
to remove the dragged item from its original data provider when it is successfully dropped elsewhere.
var listView = new ListView();
listView.dragEnabled = true;
listView.dropEnabled = true;
listView.removeOnDragDropComplete = true;
See the
list-view-drag-and-drop
sample for a demonstration of how to enable drag-and-drop in aListView
component.
Custom drag and drop
If a UI component implements the IDragSource
, it may call DragDropManager.startDrag()
to begin a drag-and-drop action in response to a user gesture (such as MouseEvent.MOUSE_DOWN
or MouseEvent.MOUSE_MOVE
).
If a UI component implements the IDropTarget
interface, it may call DragDropManager.acceptDrag()
to allow the user to drop an object on mouse up or touch end.
Drag data
Data passed in a drag-and-drop gesture is stored in a DragData
instance. This class works similarly to a map, allowing it to store multiple items with string keys. The values may be any Haxe object or class instance, similarly to items that might be added to a data collection.
var item = {a: 123, b: true};
var dragData = new DragData();
dragData.set("my-custom-drag-format", item);
DragDropManager.startDrag(this, dragData);
Drag and drop events
After a drag is started, and the user moves the pointer around, each IDropTarget
will automatically dispatch certain events that they can listen for by adding listeners to themselves.
DragDropEvent.DRAG_ENTER
is dispatched when the pointer move over theIDropTarget
.addEventListener(DragDropEvent.DRAG_ENTER, event -> { if (!event.dragData.exists("my-custom-drag-format")) { return; } event.acceptDrag(this); });
DragDropEvent.DRAG_MOVE
is dispatched when the pointer that is over theIDropTarget
moves to a new location.DragDropEvent.DRAG_EXIT
is dispatched when the pointer is no longer over theIDropTarget
.DragDropEvent.DRAG_DROP
is dispatched on mouse up or touch end, the pointer is over theIDropTarget
, and theIDropTarget
has calledDragDropManager.acceptDrag()
.
The IDragSource
will also dispatch some events.
DragDropEvent.DRAG_START
is dispatched when the drag gesture starts in response to a call toDragDropManager.startDrag()
.DragDropEvent.DRAG_COMPLETE
is dispatched either when the data is dropped, or when the drag gesture is cancelled without being accepted.
See the
drag-and-drop
sample for a demonstration of how to enable drag-and-drop in a custom UI component.
Layout support for drag and drop
If a layout implements the IDragDropLayout
interface, the container can pass the position of a drop to the layout to calculate the drop index of the item. This interface has two methods.
getDragDropIndex()
calculates the index of the dropped item from the drop position.getDragDropRegion()
returns the region where the container can position an indicator to show the user where the drop will occur.