Next | Prev | Up | Top | Contents | Index

Drag and Drop

A drag and drop facility was introduced into Motif 1.2. On the drop side, a widget must first register itself as a drop site, so that it can handle any attempts to drop something on it. Registration is done by means of the dropSiteRegister widget method. The registration must include a Tcl procedure to be executed whenever a drop is attempted, specified using the -dropProc resource.

Since drag and drop involves two different applications attempting to communicate, a protocol is needed so that applications can share a common language. Consequently, registration must specify what types of protocol are used, and how many there are. This is done using X atoms. The major X atoms are COMPOUND_TEXT, TEXT, and STRING. This example shows drop site registration:

.l dropSiteRegister \ 
    -dropProc {startDrop %dragContext} \
    -numImportTargets 1 \
    -importTargets COMPOUND_TEXT
This allows widget .l to be used as a drop site, accepting COMPOUND_TEXT only. Multiple types are allowed, using the Motif list structure of comma-separated elements as in "COMPOUND_TEXT, TEXT, STRING," for example.

When a drop occurs, the procedure startDrop is called, with one substituted parameter: dragContext, which is a widget created by Motif to handle the drag overhead. You must include this parameter, or the next stage will fail.

When a drag occurs, Motif creates a dragContext widget. A drag is started by holding down the left moust button in a drag source. The dragContext widget contains information about the drag source, which is matched up against the drop destination.

When the drop is triggered by releasing the left mouse button, Tcl code registered as dropProc is executed. This procedure takes the dragContext widget as a parameter.

The dropProc code may try to determine if the drop should proceed, but usually it just acts as a channel for the actual information transfer. The dragProc does not actually transfer the information, it just determines whether it is possible, and if so, what protocols to employ.

The drop recipient may decide that it wants something encoded as TEXT, followed by COMPOUND_TEXT. It signals what it wants by specifying a Tcl list of dropTransfer pairs. The list pairs consist of the protocol (as an X atom name) and the recipient widget. Why the recipient widget? Because when a drop takes place, the dragContext widget actually deals with it, and is about to hand the transfer over to a transferWidget. This is essentially a triple indirection.

This is an example of a dragProc:

proc startDrop dragContext {
    $dragContext dropTransferStart \
    -dropTransfers {{COMPOUND_TEXT .l}} \
    -numDropTransfers 1 \
    -transferProc {doTransfer %closure {%value}}
}
The dragContext widget uses the command dropTransferStart to signal the beginning of information transfer. (It could also signal termination with no information transfer).

The dragContext widget accepts one chunk of information in COMPOUND_TEXT format, and passes this on to the .l widget. The information transfer is actually carried on by a Tcl procedure in the transferProc resource.

The only formats currently accepted (because they are hard-coded into Tcl Motif) are COMPOUND_TEXT, TEXT, and STRING.

The transferProc resource is a function that is called when the drop recipient actually gets the information dropped on it. This function takes at least two parameters: %value is substituted for the actual information dropped on it, and %closure is the second element in the dropTransfer list that should be the widget where the drop is happening. (Tcl Motif should be able to determine this, but unfortunately does not.) The dropped-on widget takes suitable action.

This function resets the label to the text dropped on it:

proc doTransfer {destination value} {
    $destination setValues -labelString $value
}
Here, destination is substituted with %closure and value with %value.



Next | Prev | Up | Top | Contents | Index