DragItem

From Xojo Documentation

Class (inherits from Object)

Used to transfer data being dragged by the user via drag and drop.

Properties
Destination fa-lock-32.png FolderItem PrivateRawData
DragPicture FolderItemAvailable fa-lock-32.png RawData
DropHeight fa-lock-32.png Handle fa-lock-32.png RawDataAvailable fa-lock-32.png
DropLeft fa-lock-32.png MouseCursor Text
DropTop fa-lock-32.png Picture TextAvailable fa-lock-32.png
DropWidth fa-lock-32.png PictureAvailable fa-lock-32.png
Methods
AddItem Drag NextItem
Constructors

Constructor(r as RectControl, x as Integer, y as Integer, width as Integer, height as Integer, DragPicture as Picture)


Constructor(w as Window, x as Integer, y as Integer, width as Integer, height as Integer, DragPicture as Picture)


Class Constants

The following class constants can be used to test the Action parameter of the RectControl and Window classes’ DragEnter, DragExit, and DragOver events.

Class Constant Description
DragActionDefault Default action.
DragActionCopy Copy the dragged item.
DragActionMove Move the dragged item.
DragActionLink Link the dragged item.

Notes

When the user wishes to drag some data from a Window or control, a new DragItem object must be created to hold that data in order to transfer it to the object the data will be dropped on. Xojo supports true drag and drop — which means that the recipient of the data can be anything that supports drag and drop and supports the kind of data being dragged. For example, text can be dragged to the desktop to create a text clipping file or any application that accepts dropped text (like SimpleText or the NotePad). Pictures can be dragged to the Desktop to create picture clipping files. Other types of data can be dragged using the RawData property.

The DragItem supports UTI (Uniform Type Identifiers).

By default, a DragItem can contain only one row containing a single entry for each data type. Using the AddItem method, you can add more rows to the DragItem allowing multiple entries of the same data type. For example, if you wanted a drag item to contain two separate pictures, you would assign one picture to the Picture property then call the AddItem method to add a row and then assign the second picture to the Picture property.

The RawData and PrivateRawData properties allow you to support drag and drop for other data formats. You specify the data format using a four-character Type, corresponding to a Macintosh resource type. RawData and PrivateRawData return the dragged item as a string. It is up to the control or window that receives the DragItem to manage it. Typically, this will mean that you will have to make API calls or use a plug-in that is designed to handle the data format.

You can also use RawData or PrivateRawData to control internal drag and drop. If you make up a four-character Type (not an existing Macintosh resource type), you can prevent a control from receiving dragged text from other sources. See the example of dragging from one ListBox to another.

There is no need to create a DragItem for TextAreas as this is handled automatically.

ListBoxes support the dragging of rows automatically if the EnableDrag property of the ListBox is True (checked). Like TextAreas, the DragItem is created automatically for the ListBox but you must populate the DragItem in the DragRow event handler. See the notes for the ListBox control for more information on dragging from ListBoxes.

Displaying Drag Pictures When There Are Multiple Drag Items

When there are multiple items in the DragItem, You can provide the drag picture in two ways: Using the constructor or by using the DragItem property.

If you use the constructor to provide a single picture, then on MacOS, this picture will be 3D stacked to indicate that there are multiple items. Since the same picture will be stacked in this manner it should be somewhat generic.

Alternatively you can not provide the picture in the constructor and then set the DragPicture property for each DragItem you add with AddItem. On MacOS this results in these separate images being vertically stacked to indicate each item being dragged. This can be more useful if your individual drag items are unique or distinct.

Dragging Promised Files

MacOS supports the concept of dragging a file before it actually exists in the file system. It could be a new document that hasn't been saved yet or a file that exists on a remote server or on the web.

In these cases, the drag and drop gesture serves the purpose of specifying the location at which to save the new file. When the drag and drop operation is complete, it tells the source where it wants the files saved and the dragging source creates the files. This special type of file drag is called a promise because the drag operation contains a promise from the source to the destination that the source will create the specified files if the drag and drop is accepted.

To drag and drop promised files, call the RectControl or Window's AcceptRawDataDrop method with "phfs"; as the data type. When an application that sends file promises is dropped on your application, you will find a FolderItem in the dragged item. Usually this will point to a file in the TemporaryItems folder and you should ordinarily delete it when you are finished with it.

Sample Code

This code shows how to implement dragging the picture in a Canvas control. This example uses the Me keyword to refer to the Canvas control.

Function MouseDown(X As Integer, Y As Integer) As Boolean
Var d As DragItem
d = New DragItem(Self, X, Y, Me.Width, Me.Height)
d.Picture = Me.Backdrop
d.Drag // Allow the drag
End Function

See also the example for ImageWell, which illustrates drag and drop between two ImageWells and jpeg files or clippings on the desktop and the ListBox control, which has an example of drag and drop between two ListBoxes.

The following code implements a "mover" interface in which a user can drag rows from ListBox1 to ListBox2 (and in the reverse direction), but neither ListBox accepts dragged text from other controls or from other apps. It uses PrivateRawData since it also prevents text from being dragged outside the application.

To permit drag and drop in both directions, the two ListBoxes are set up in an identical manner.

Each ListBox has its EnableDrag property set to True. The DragRow event handler is:

Function DragRow (drag As DragItem, row As Integer) As Boolean
Drag.PrivateRawData("text") = Me.List(Row) + EndOfLine //get the text
Me.RemoveRow(Row)
Return True //allow the drag
End Function

To enable each ListBox to accept the dragged text, the following statement appears in its Open event handler:

Me.AcceptRawDataDrop("text")

The DropObject event handler is as follows:

Sub DropObject (obj As DragItem)
If obj.RawDataAvailable("text") Then
Me.AddRow(obj.RawData("text"))
End If
End Sub

The following code allows the user to drag several text files from the desktop to a TextArea. The example places the contents of all the text files in the TextArea, appending each file's contents to the Text property of the TextArea.

To support several files, the NextItem function is used to determine whether there are any more files remaining to be dropped.

Var textStream As TextInputStream
If obj.FolderItemAvailable Then
Do
textStream = TextInputStream.Open(obj.FolderItem)
Me.TextArea1.AddText(textStream.ReadAll)
Loop Until Not obj.NextItem
End If

The TextArea has the line:

Me.AcceptFileDrop(FileTypes1.Text)

in its Open event handler, where FileTypes1 has a common file type of Text.

See Also

Canvas, TextArea, ImageWell, ListBox controls; Picture, FileType, FolderItem classes; UserGuide:Desktop Drag and Drop topic