Class
DragItem
Description
Used to transfer data being dragged by the user via drag and drop.
Properties
Name |
Type |
Read-Only |
Shared |
---|---|---|---|
✓ |
|||
✓ |
|||
✓ |
|||
✓ |
|||
✓ |
|||
✓ |
Methods
Name |
Parameters |
Returns |
Shared |
---|---|---|---|
Left As Integer, Top As Integer, Width As Integer, Height As Integer |
|||
ctl As DesktopUIControl, x As Integer, y As Integer, width As Integer, height As Integer, [DragPicture As Picture] |
|||
w As DesktopWindow, x As Integer, y As Integer, width As Integer, height As Integer, [DragPicture As Picture] |
|||
Enumerations
DragItem.Types
Types
Specifies the type of drag the user is making.
Enumeration |
Description |
---|---|
Default |
Default action. |
Copy |
Copy the dragged item. |
Move |
Move the dragged item. |
Link |
Link the dragged item. |
Property descriptions
DragItem.Destination
Destination As Object
The location of the dropped item when you drop it to the desktop or onto an application. The DragItem must contain some content that the Finder accepts.
This property is read-only.
Since Destination is of type Object, it potentially can return any type of Xojo object. Currently, Destination is set up to work only with the macOS Finder and will only return a FolderItem. To ensure that your application is compatible with future versions, check the type of object it returns with IsA before recasting it to a FolderItem.
On Windows and Linux, dragging items to the Desktop is not supported; therefore this property does not work on those platforms.
This code uses the Destination property to report the NativePath of a folder that is created by dragging a label from a window to the Finder:
Var di As DragItem
Var f As FolderItem
Var d As DateTime = DateTime.Now
Var tos As TextOutputStream
f = SpecialFolder.Temporary.Child("test" + Format(d.TotalSeconds, "#"))
If f <> Nil Then
tos = TextOutputStream.Create(f)
tos.Write("Howdy! Created by DragToFinder example.")
tos.Close
di = New DragItem(Self, 0, 0, 100, 100)
di.FolderItem = f
di.Drag
If di.Destination <> Nil Then
If di.Destination IsA FolderItem Then
MessageBox(FolderItem(di.Destination).NativePath)
End If
End If
Else
MessageBox("Unable to get FolderItem for temporary file.")
End If
DragItem.DragPicture
DragPicture As Picture
If you assign an image to this property, the picture will be used for the drag instead of the default rectangle. The image will be placed at the top left of the rectangle passed into the DragItem constructor.
It is only possible to change the DragPicture before calling Drag(), any attempt to do so after that point will fail.
This code sets the DragPicture property just after creating the new DragItem.
In an ImageViewer control, put this code in the MouseDown event:
Return True
You can then set up the drag in the MouseDrag event of the ImageViewer:
Var d As DragItem
d = New DragItem(Self, X, Y, Me.Width, Me.Height)
d.DragPicture = MyPicture ' a picture/image added to the project
d.Picture = Me.Image ' From the ImageViewer control
d.Drag ' Allow the drag
DragItem.DropHeight
DropHeight As Integer
Height of the object being dropped.
The following code displays the values of the DropWidth and DropHeight properties after the drag. The code is in the DropObject event.
If obj.PictureAvailable Then
Me.Image = obj.Picture
ElseIf obj.FolderItemAvailable Then
Me.Image = Picture.Open(obj.FolderItem)
End If
Label1.Text = obj.DropWidth.ToString
Label2.Text = obj.DropHeight.ToString
DragItem.DropLeft
DropLeft As Integer
Distance from the left side of the control where the object was dropped.
The following code displays the values of the DropLeft and DropTop properties after the drag. The code is in the DropObject event.
If obj.PictureAvailable Then
Me.Image = obj.Picture
ElseIf obj.FolderItemAvailable Then
Me.Image = Picture.Open(obj.FolderItem)
End If
Label1.Text = obj.DropLeft.ToString
Label2.Text = obj.DropTop.ToString
DragItem.DropTop
DropTop As Integer
Distance from the top of the control where the object was dropped.
The following code displays the values of the DropLeft and DropTop properties after the drag. The code is in the DropObject event.
If obj.PictureAvailable Then
Me.Image = obj.Picture
ElseIf obj.FolderItemAvailable Then
Me.Image = Picture.Open(obj.FolderItem)
End If
Label1.Text = obj.DropLeft.ToString
Label2.Text = obj.DropTop.ToString
DragItem.DropWidth
DropWidth As Integer
Width of the object being dropped.
The following code displays the values of the DropWidth and DropHeight properties after the drag. The code is in the DropObject event.
If obj.PictureAvailable Then
Me.Image = obj.Picture
ElseIf obj.FolderItemAvailable Then
Me.Image = Picture.Open(obj.FolderItem)
End If
Label1.Text = obj.DropWidth.ToString
Label2.Text = obj.DropHeight.ToString
DragItem.FolderItem
FolderItem As FolderItem
The FolderItem being dragged.
The following DropObject event specifies the passed FolderItem as the object to be dropped.
If obj.PictureAvailable Then
Me.Image = obj.Picture
ElseIf obj.FolderItemAvailable Then
Me.Image = Picture.Open(obj.FolderItem)
End If
DragItem.FolderItemAvailable
FolderItemAvailable As Boolean
If True, the FolderItem property contains a FolderItem.
This property is read-only.
DragItem.Handle
Handle As Integer
Returns the macOS handle to the DragItem. Handle returns 0 on Windows and Linux.
This property is read-only.
The following gets a handle to the DragItem.
d = New DragItem(Self, X, Y, Me.Width, Me.Height)
Var i As Integer = d.Handle
DragItem.MouseCursor
MouseCursor As MouseCursor
The cursor to be displayed during the drag.
The following code displays a custom cursor for the drag. It is in the MouseDown event of the DesktopImageViewer.
Var d As DragItem
d = New DragItem(Self, X, Y, Me.Width, Me.Height)
d.DragPicture = MyPicture
d.MouseCursor = System.Cursors.HandOpen
d.Picture = Me.Image
d.Drag ' Allow the drag
DragItem.Picture
Picture As Picture
The Picture being dragged.
The following code is in the DropObject event handler of an DesktopImageViewer. It assigns the dragged picture to the Image property of the DesktopImageViewer.
If obj.PictureAvailable Then
Me.Image = obj.Picture
ElseIf obj.FolderItemAvailable then
Me.Image = Picture.Open(obj.FolderItem)
End If
DragItem.PictureAvailable
PictureAvailable As Boolean
If True, the Picture property contains a picture.
This property is read-only.
The following code is in the DropObject event handler of an DesktopImageViewer. It tests whether a Picture has been dragged and, if so, assigns the dragged picture to the Image property of the DesktopImageViewer.
If obj.PictureAvailable Then
Me.Image = obj.Picture
ElseIf obj.FolderItemAvailable then
Me.Image = Picture.Open(obj.FolderItem)
End If
DragItem.PrivateRawData
PrivateRawData As String
Contains the raw data being dragged.
The parameter is the file type being dragged. MacType is a four-character resource type or programmer-defined four-character code. This data cannot be dragged to another application.
This code checks for raw data of any type and does the drop.
If obj.RawDataAvailable("????") Then
Me.Text = obj.PrivateRawData("????")
End If
DragItem.RawData
RawData As String
Contains the raw data being dragged.
The DataType parameter supports both the older MacType and newer UTIs. If the DataType parameter is exactly 4 bytes then it is treated as a MacType for backwards compatibility. Otherwise it is treated as a UTI.
Checks if text data is in a a drag item:
If dragObject.RawDataAvailable("public.text") Then
Me.Text = dragObject.RawData("public.text") ' UTI
End If
DragItem.RawDataAvailable
RawDataAvailable As Boolean
If True, the DragItem contains data of the type or UTI specified.
This property is read-only.
The DataType parameter supports both the older MacType and newer UTIs. If the DataType parameter is exactly 4 bytes then it is treated as a MacType for backwards compatibility. Otherwise it is treated as a UTI.
Checks if text data is in a a drag item:
If dragObject.RawDataAvailable("public.text") Then
Me.Text = dragObject.RawData("public.text") ' UTI
End If
DragItem.Text
Text As String
The text being dragged.
The following DropObject event handler of a ListBox determines whether the dragged item has text; if it does, it creates a new row and assigns the dragged item's text property to the new row.
If obj.TextAvailable Then
Me.AddRow(obj.Text)
End If
DragItem.TextAvailable
TextAvailable As Boolean
If True, the Text property contains text.
This property is read-only.
The object that is receiving dragged text needs to be capable of receiving the text. This is enabled by calling AcceptTextDrop in the Opening event. In the DropObject event, you can test the TextAvailable property prior to dropping the text. For example:
Do
If obj.TextAvailable Then
Me.AddRow(obj.Text)
End If
Loop Until Not obj.NextItem
Method descriptions
DragItem.AddItem
AddItem(Left As Integer, Top As Integer, Width As Integer, Height As Integer)
Adds an item to the drag object. The parameters specify the drag rectangle to be displayed.
This allows you do add additional items to the drag. After calling AddItem, you assign new values to all the DragItem properties for the newly added item. When the item is dropped, the NextItem method can be called to iterate through all the items in the DragItem.
Add two pictures to a DragItem:
Var d As DragItem
d = New DragItem(Self, X, Y, Me.Width, Me.Height)
d.DragPicture = MyDragPic
d.MouseCursor = System.Cursors.HandOpen
d.Picture = MyFirstPic
d.AddItem(0, 0, Me.Width, Me.Height)
d.Picture = MySecondPic
d.Drag ' Allow the drag
DragItem.Constructor
Constructor(ctl As DesktopUIControl, x As Integer, y As Integer, width As Integer, height As Integer, [DragPicture As Picture])
Note
Constructors are special methods called when you create an object with the New keyword and pass in the parameters above.
Creates a new DragItem. The parameter ctl is the DesktopUIControl that the drag originates from. The parameters x and y are the coordinates relative to this control. The parameters width and height are the size/bounds of the drag rectangle. If the optional DragPicture parameter is passed, it will be used instead of the default rectangle to indicate the size and shape of the dragged item during the drag.
DragItem.Constructor
Constructor(w As DesktopWindow, x As Integer, y As Integer, width As Integer, height As Integer, [DragPicture As Picture])
Note
Constructors are special methods called when you create an object with the New keyword and pass in the parameters above.
Creates a new DragItem. The parameter w is the window that the drag originates from. The parameters x and y are the coordinates relative to this window. The parameters width and height are the size/bounds of the drag rectangle. If the optional DragPicture parameter is passed, it will be used instead of the default rectangle to indicate the size and shape of the dragged item during the drag.
The following code is from the example project "Custom Drag" in the Examples folder. The main window consists of a DesktopLabel control and a DesktopTextArea. The user can drag the text in the DesktopLabel into the DesktopTextArea. This is not possible by default but the ability to drag the text is enabled by the code in the MouseDown event of the DesktopLabel. It is:
Var d As DragItem
d = New DragItem(Self, Me.Left, Me.Top, Me.Width, Me.Height)
d.Text = Me.Text
d.Drag
This example drags a picture. It uses the optional DragPicture property in the constructor.
Var d As DragItem
d = New DragItem(Self, X, Y, Me.Width, Me.Height, MyPicture)
d.MouseCursor = System.Cursors.HandOpen
d.AddItem(0, 0, Me.Width, Me.Height)
d.Picture = Me.Image
d.Drag ' Allow the drag
DragItem.Drag
Drag
Allows the drag to take place. Note that it is only possible to change the image before calling Drag(), any attempt to do so after that point will fail.
This code drags the picture that is assigned to the Image property of an DesktopImageViewer to another DesktopImageViewer. In the MouseDown event of the first DesktopImageViewer, Drag is used to allow the drag.
Var d As DragItem
d = New DragItem(Self, X, Y, Me.Width, Me.Height)
d.DragPicture = Keaton534
d.MouseCursor = System.Cursors.HandOpen
d.Picture = Me.Image
d.Drag ' Allow the drag
In the second ImageViewer, put this code in its Opening event to allow the picture drop:
Me.AcceptPictureDrop
DragItem.MoveFirst
MoveFirst
If the DragItem contains multiple items, this method makes the first item the active item.
The active item is the item that can be access via the DragItem properties.
DragItem.NextItem
NextItem As Boolean
Returns True if there is another item that has been dragged and assigns the next item's values to the DragItem properties.
Call this method on the dropped item to check if there are additional items you need to process. When called it, assigns the next item's values to the DragItem properties.
Notes
When the user wishes to drag some data from a DesktopWindow 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 UTIs (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 DesktopListBox 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 DesktopListBox 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 DesktopListBox 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 DesktopUIControl or DesktopWindow'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 DesktopCanvas control. This example uses the Me keyword to refer to the DesktopCanvas 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 DesktopImageViewer, which illustrates drag and drop between two ImageViewers and jpeg files or clippings on the desktop and the DesktopListBox 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 DesktopListBox 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 DesktopListBox 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 DesktopListBox to accept the dragged text, the following statement appears in its Opening 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 DesktopTextArea. The example places the contents of all the text files in the DesktopTextArea, appending each file's contents to the Text property of the DesktopTextArea.
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 DesktopTextArea has the line:
Me.AcceptFileDrop(FileTypeGroup1.Text)
Compatibility
All project types on all supported operating systems.
See also
Object parent class; DesktopCanvas, DesktopTextArea, DesktopImageViewer, DesktopListBox controls; Picture, FileType, FolderItem classes; Supporting Drag and Drop topic