Drag and drop
Like the clipboard, drag and drop is a way to transfer data between different applications.
Most operating systems implement the drag and drop system in the same way with
clipboard, and in Yue dragged data are represented as instances of the
Clipboard::Data
.
For code examples on handling drag and drop, please see the sample app in
yue-sample-apps/drag_source
.
Drag destination
A View
can be made a drag destination by using the
View.RegisterDraggedTypes
API,
which gives the view abilities to accept dropped data.
view.registerDraggedTypes(['image'])
When users drag data with registered types to the view, drag related events will be emitted in sequence:
- The
handle_drag_enter
andon_drag_leave
will be called when the cursor enters or leaves the view while dragging. - The
handle_drag_update
will be called while cursor moves in the view while dragging. - The
handle_drop
will be called user releases cursor and drops the data on the view.
To accept dropped data, the handle_drag_enter
should be
implemented first to decide which DragOperation
to perform when cursor is dropped. Depending on the returned drag operation,
the cursor may have different icons.
view.handleDragEnter = (self, info, point) => {
isDragging = true
return gui.DraggingInfo.dragOperationCopy
}
If you are implementing some visual effects when there are data being dragged to
the view, you may want to do some cleanup in on_drag_leave
,
which is called when cursor moves out of the view and before users drops the
data on the view.
view.onDragLeave = (self) => {
isDragging = true
}
If the view supports different drag operations depending on the cursor position,
you may want to implement handle_drag_update
, and return
the drag operation according to the cursor position in the view.
If you don't implement handle_drag_update
, the return
value of previous handle_drag_enter
call will be used.
view.handledragUpdate = (self, info, point) => {
if (pointInDragArea(point))
return gui.DraggingInfo.dragOperationCopy
else
return gui.DraggingInfo.dragOperationNone
}
Finally, by implementing handle_drop
, you can read the dragged
data from the passed DraggingInfo
instance.
view.handleDrop = (self, info, point) => {
if (info.isDataAvailable('image')) {
displayImage(info.getData('image').value)
return true
}
return false
}
Drag source
To make it possible for users to drag some data from current applications to
other destinations, you can listen to mouse down events and use the
View.DoDrag
API.
source.setMouseDownCanMoveWindow(false)
source.onMouseDown = (self) => {
const ret = self.doDrag([{type: 'file-paths', value: [filePath]}],
gui.DraggingInfo.dragOperationCopy | gui.DraggingInfo.dragOperationLink)
if (ret == gui.DraggingInfo.dragOperationCopy)
copyData()
else if (ret == gui.DraggingInfo.dragOperationLink)
linkData()
return true
}
The API should be called with the data to provide, and the supported drag operations. The call will be blocked until the user cancels the dragging or drops the data, and it will return the drag operation used by the destination.