dnd bindsource window
dnd bindsource window type
dnd bindsource window type script ?priority?
dnd clearsource window
dnd drag window ?-actions list ?-descriptions list?? ?-cursorwindow window? ?-callback script?
The dnd command provides a Tcl interface to native, platform specific drag and drop mechanism. Under unix the drag & drop protocol in use is the XDND protocol (also used by the QT toolkit, KDE & GNOME Desktops). Basic interaction (currently drops) with Motif applications is also provided. Under Windows, the OLE drag & drop interfaces are used. The Macindosh platform is not yet supported.
With the dnd command the user is able to register existing Tk widgets as drag sources or drop targets, that are able to send or receive data encoded in specific types. Also through this command drag and drop related information can be retrieved, regarding the drag and drop registered widgets.
The legal forms for the dnd command are:
The events support modifiers as in Tk. You can use a combination of Shift, Alt, Meta, Control, Mod[1-5], Button[1-5] to bind specific scripts when these modifiers are used. As in Tk, the closest matching script will be executed. If there is no exact match, the following algorithm will be applied: find an event without key modifiers but with buttons modifiers, then find an event without buttons modifiers but with the key modifiers, then at last find an event without key modifiers and without buttons (i.e. a raw event as listed above).
The <DragEnter> event will be delivered when the mouse enters the window during a drag operartion. The <Drag> event will be delivered when the mouse moves inside the widget during a drag operartion and the <DragLeave> event will be delivered if the mouse pointer leaves the window during a drag operation. Finally, the <Drop> event will be delivered if a drop over the window occurs.
If there is already a binding script for the same event, this script is replaced by the new one. If the script is an empty string, then any previous binding script is deleted and the specified event is no longer reported to the specified window. The user can optionally specify a priority for this specific type (an integer value ranging from 1 to 100). Priorities have meaning only when more than one types are registered for the same event. During a drag operartion the specified event will be delivered by executing the binding script associated with the type that has the higher priority (or the lower integer value: priority 1 is the highest priority while 100 is the lowest available priority). If priority is ommited, it defaults to 50. If more than one types have the same priority, the actual type that will be used cannot be pre-determined.
If the script is an empty string, then the specified type will be removed from the type list of supported by the drag source types.
Finally, the user can arrange the types that the drag source supports according to priorities. Valid priorities are integers in the range [1,100], with 100 denoting the highest possible priority. If priority is ommited, it defaults to 50. If more than one types have the same priority, only one of them will be used for a drop action. In this case the actual type that will be used cannot be pre-determined.
The user can also specify a Cursor window. A Cursor window is a toplevel window that will appear near the mouse cursor and will follow the cursor, as the mouse cursor moves during the drag operation. This window must exist when the dnd drag command will be executed. If a Cursor window is specified, the user can also register a callback through the -callback option. This callback will be called when the mouse pointer is moved and can be used in order to update the contents of the window. All available substitutions can also be used with this callback. For more information please refer to the BINDING SCRIPTS AND SUBSTITUTIONS section. One difference with the usual substitutions is that in this context, the %A substitution can also take as value the empty string, meaning that the cursor is over a window that cannot accept a drop action. It is advised that this particular callback should be as fast as possible, as it is called very frequently. That is also the reason why the position of the cursor window is managed by the dnd drag command. Also, dnd drag command ensures that the cursor window will always be visible (above all other windows).
Finally, the user can optionally specify a list of actions that will be associated with the current drag and drop operation. Valid actions are the following: copy, move, link and ask. It is up to the drop target to deside which action will be actually used for the drop operartion. It is also responsibility of the drop target to do the required actions implied by the drop action. For example, if the drop action during a file name drop is move, the window that accepts the drop is responsible for deleting the old file and create the new file at the dropped location.
If the ask action is included in the specified action list, then the description list must be also specified. The meaning of the ask action is that when the drop finally occurs, the widget that will accept the drop should display a window that will enable the user to select the action that desires from the available list. The ask action should not be listed and also a way to cancel the drop should provided to the user. The descriptions provided with the description list are the text that should be displayed for the corresponding individual action entries in the presented window. As a result, the description list must contain the same number of items as the action list and the its text elements must describe the corresponding actions specified by the -actions option. For example, a drop that offers all available actions should be defined as follows:
dnd drag .dragSource -actions {ask copy move link} \ -descriptions {{Please Select Action:} {Copy} {Move} {Link} }
In order to declare the format that the data that will encoded during a drag and drop operation, all drag and drop protocols use the notion of types. Unfortunately, each protocol defines its own, usually platform specific, types. The Tk toolkit, trying to maintain its portability among different platforms, offers some predefined types for some basic kinds of data, like text, filenames and images. These types are represented by their MIME types and are available under all platforms that Tk is available. Currently, the following predifined values are available:
Besides the predefined types, the user is free to use the platform specific types. For example under windows the type "FILENAME" can be used in order to receive a single filename from the Explorer or the type "NetscapeURL" can be used in order to receive a bookmark drop from Netscape Navigator. Under Unix, the type "FILE_NAME" can be used in order to receive a filename from a Motif application. The dnd command will make no conversion to types other than the predefined ones. Instead it will place received data into tcl byte-arrays and extract data from tcl after it converts objects into byte-arrays. Also note that the script should make the proper arrangements in order to maintain portability under different platforms. Procceed with platform depended types only if you are absolutely sure that the data you want to excange is not supported by the predefined, platform independed, types.
Any script argument to dnd is a Tcl script, which will be executed in order for the given event to be delivered to the associated window. The script will be executed in the same interpreter that the dnd command was executed in order to specify the binding, and it will run at global level (only global variables will be accessible).
If script contains any % characters, then the script will not be executed directly. Instead, a new script will be generated by replacing each %, and the character following it, with information from the current event. The replacement depends on the character following the %, as defined in the list below. Some of the substitutions are only valid for certain types of events; if they are used for other types of events the value substituted is the empty string.
There are four events that are associated with drop targets and a single event associated with drag sources. The four events that are delivered to drop targets are:
return -code break action
The main use of this feature is the ability to allow drops over specific items of a canvas widget.
It is an error to return the action "ask". If a binding script is not registered for this event, then this functionality will be provided by the Tk core library.
In order to register a data type that can be handled by a target window, the bindtarget option can be used. For example, to handle plain dropped text, the following command can be used:
dnd bindtarget .tgt text/plain <Drop> {puts "Drop-Action=%A, Data=%D"}
When a drop occurs from a source that supports the "text/plain" type, the script associated with the <Drop> event will be executed. In this case, if the dropped data was a sentence such as "The quick brown fox jumped over the moon", the command that will be executed is:
puts {Drop-Action=copy, Data="The quick brown fox jumped over the moon"}
You can specify anything as a data type. The recommended names that can be used as data types are the corresponding MIME types. Internally, the MIME types will be converted to the apropriate types understood by the operating system. For example, if the user requests the type text/plain, the dnd command passes the type "text/plain" to the X server under unix (the XDND protocol defines types by their mime type names). But under windows, the type CF_TEXT will be registered. CF_TEXT is a special type that represents all simple ASCII text that can be dragged and dropped. Creating a handler for CF_TEXT on a window will allow that window to handle text drags and drops from another OLE enabled application that also uses the standard CF_TEXT mechanism. The user can also request explicitly to use the type "CF_TEXT". But such an approach will not be portable.
Some common types the are currently supported by the current version of tkDND are "text/uri-list" for dragging and dropping files, "text/plain;charset=utf-8" for handling utf-8 text and "image/xpm" for transfering images. Please refer to the section "DRAG AND DROP TYPES" for more information. Some other Windows specific common types for dragging and dropping to and from web browsers are "UniformResourceLocator" and "Netscape Bookmark". The type "FileName" is used by Explorer to drag and drop a single file. (Note that this type will transfer a single file. Many files (or just one file) can be transfered with the predefined type "text/uri-list")
You can register more than a single type to be handled by a window. Just run the command again with a different data type. Here is another example for the same window:
dnd bindtarget .tgt TK_COLOR <Drop> {.tgt config -bg %D}
In this case, if a an object gets dropped on window .tgt, .tgt will ask the source if it supports either text/plain or TK_COLOR. If it does, it will run the script for the match. It is possible that more than one type would be matched between the source and target. For this case, you can use the priority option to specify the order in which you want the search for matches to occur. Priorities range from 1 to 100. 1 is the highest priority, 50 is the default priority, and 100 is the lowest priority. If two target data types have the same priority, it is undetermined which one will be checked for first. In the above example, if you want to check for the TK_COLOR datatype before text/plain, give a higher priority to the TK_COLOR datatype:
dnd bindtarget .tgt TK_COLOR <Drop> {.tgt config -bg %D} 1
For drag sources, the data types that can be provided by a window can be registered with the bindsource option. For example, in order to register a window as a drop source for ASCII text, the follwowing command can be used:
dnd bindsource .src text/plain {return "Some text"}
More than one datatype can be registered with a source window. To go along with our example, setup the window as a provider of data of type "TK_COLOR":
dnd bindsource .src TK_COLOR {return red}
Now that both the target window and the source window have been configured, one as a data source and the other as a drop area, we still need to do something to initiate the drag operation. If the application that is being dragged from is not part of Tk, we let it handle the drag & drop operation. If we want to drag something from the ".src" window to the ".tgt" window, we must initiate the drag and drop operation with the drag option. Here, we start the operation on a press of mouse button 1.
bind .src <1> {dnd drag %W}
Once button 1 is pressed on the ".src" window, the drag operation begins. When the button is released, a different button is pressed, or a modifier key is pressed during the operation, then a drop operation occurs. If the drop occurs over a window that has a type that matches the source window, then the script for the source window gets run first. If you do not want the source window to send data, it can do a:
return -code break
If the return value is not an error or a break code, the target window script for the matched datatype is then run. For the example above, the datatype that matched would be "TK_COLOR". First, the script registered for data type "TK_COLOR" on window ".src" would be executed. This is the "return red" statement. The string "red" will now substitute the "%D" token to the command for the datatype "TK_COLOR" on the target window .tgt. The command that will be executed will be:
Unix:
During drops from Motif applications, the only action that is allowed is the
copy action.
If during a drag operation the mouse pointer is over a foreign window and the application that owns the window crashes, we may end with a BadWindow error, as it is very possible messages delivered to that window to exist in the message queue of the X Server.
dnd, drag and drop, shape, update