Programmer Reference : Common Widgets : Platform-integrated drag and drop : Data transfer and the CwDropTransfer object
Data transfer and the CwDropTransfer object
The data transfer is the final stage in the drag and drop process. Both the source application and the destination application are involved in the data transfer--the source through the convertProc (described previously), and the destination through the transferProc (described below). The destination starts the data transfer from a dropProc by specifying a list of one or more target types it would like the source to provide. Common Widgets drag and drop takes over at this point. For each target type requested, it sends a convertProc to the source to get the data, and then sends a transferProc to the destination, containing the data from the source.
A destination can add target types to the list of requests during the transfer process if necessary, permitting it to change what it requests based on data received. If the operation was a move, the destination must add the special 'DELETE' target to the request list, which the system will send to the convertProc, so that the source knows when it is safe to delete the data.
Starting the data transfer--CwDropTransfer
The data transfer is started from a dropProc handler by sending the dropTransferStart: message, with a CwDropTransfer create argBlock, to the drag context, which is provided in the dropProc's callData.
Sending dropTransferStart: creates a CwDropTransfer which represents the data transfer in progress. There can only be one instance of CwDropTransfer in existence at any time and it ceases to exist when the data transfer is complete. The following drop transfer resources can be set in the create argBlock when the transfer is started:
An OrderedCollection of CwDropTransferEntry objects. There is one entry for each target type requested by the drop site.
The status of the transfer. It can be either success (XmTRANSFERSUCCESS), which is the default, or failure (XmTRANSFERFAILURE). transferStatus can be updated by the destination application.
A proc that is received one or more times after a valid drop, in which the destination application must use the data converted by the source application. The target type and converted value of the data are given in the proc's callData. The transfer proc will be called as many times as the destination requests, each time with a different target that was converted. A destination must be prepared to use any of the target types it requests. If the operation was a move, the transfer proc must add a 'DELETE' target when it has successfully received all of the converted data from the source.
The following example method was called from the dropProc example code in the previous subsection. It creates a collection of CwDropTransferEntry objects using the specified targetTypes and clientData, and starts the data transfer with these.
startTransfer: callData targetTypes: targetTypes clientData: clientData
"Called from a dropProc to start the drop transfer."
| dropTransfers |
dropTransfers := OrderedCollection new.
targetTypes do: [:target |
add: (CwDropTransferEntry
target: target
transferClientData: clientData)].
callData dragContext
dropTransferStart: [:dropTransfer |
dropTransfers: dropTransfers;
transferProc: (CwCallbackRec
receiver: self
selector: #transferProc:clientData:callData:
clientData: callData)].
The convert proc
The source application must supply a convert proc when it creates a drag context. The convert proc is where the source provides the dragged data in the format specified by its callData target type. The parameters to the convertProc are as follows:
The CwDragContext created for the drag
The clientData specified when the convertProc was hooked
An instance of CwConvertProcCallbackData
The following code shows a typical convert proc. Assume that stringFromWidget: answers the selected string in the specified widget, and deleteStringFromWidget: deletes the selected string from the specified widget.
You can use the clientData parameter to find out the drag source widget inside the convert proc.
convertProc: aCwDragContext clientData: dragSource callData: callData
"Handle the convert proc for the receiver."
| target |
(target := callData target) = 'STRING'
ifTrue: [
"Convert to requested type, and set value."
callData value: (self stringFromWidget: dragSource)]
ifFalse: [
target = 'DELETE'
ifTrue: [
"The operation was XmDROPMOVE, and the destination
successfully received the data. Delete the data from the source."
self deleteStringFromWidget: dragSource]].
A convertProc is usually sent to the source application, and then the corresponding transferProc is sent to the destination application. On some platforms, the convertProc is called for all of the dragContext's export targets when the drag starts. Thus, applications should not count on the order of convertProc and transferProc calls.
The transfer proc
The destination application must supply a transfer proc when it creates a drop transfer. The transfer proc is where the destination receives the dragged data from the source in the format specified by the target type in the transfer proc's callData. The parameters to the transferProc are as follows:
The CwDropTransfer created for the data transfer
The clientData specified when the transferProc was hooked
An instance of CwTransferProcCallbackData
The following code shows a typical transfer proc. Assume that stringToWidget:string:x:y:link: writes a string into the drop site widget, given the string, the coordinates of the drop, and a Boolean describing whether the drop operation was XmDROPLINK. (XmDROPLINK is usually more meaningful for data other than 'STRING'). The drop site widget was passed to the proc (by the startTransfer:targetTypes:clientData: example method) in the callData's transferClientData.
You can use the clientData parameter to find the dropProc's callData inside the transfer proc. The callData is usually necessary to know because it contains the operation and the coordinates of the mouse at the drop.
transferProc: aCwDropTransfer clientData: dropProcCallData callData: callData
"Handle the convert proc for the receiver."
callData value isNil ifTrue: [
"Conversion failed. The source did not pass any data."
^self errorMessage: 'Conversion failed.'].
callData target = 'STRING'
ifTrue: [
stringToWidget: callData transferClientData
string: callData value
x: dropProcCallData x
y: dropProcCallData y
link: (dropProcCallData operation = XmDROPLINK)].
"If this was a move operation, and if we have just received the
last dropTransfer, then send a 'DELETE' target to the drag
source's convert proc."
(dropProcCallData operation = XmDROPMOVE
and: [callData target = aCwDropTransfer dropTransfers last target])
ifTrue: [
dropTransferAdd: (CwDropTransferEntry
target: 'DELETE'
transferClientData: callData transferClientData)].
Last modified date: 03/29/2018