Definitive example of desktop drag and drop

I’m looking for a definitive example of how to drag a file from the Finder and drop it into a desktop Xojo application. The problem I’m having is how to set the mouse cursor. I’d like the cursor to change as the file is dragged into the Xojo application window, and then change back to standard pointer when the file is dropped. The actual DropObject event is triggering fine, but really I’d like better visual confirmation of what’s happening. Here is the code from DropObject:

if obj.FolderItemAvailable then
  msgbox("File: " + obj.FolderItem.NativePath)
end if

This is in winMain.Opening:

me.AcceptFileDrop("special/any")

This is in winMain.DragOver:

winMain.MouseCursor = System.Cursors.HandOpen // only seen after the drop

And this is in winMain.DragEnter:

winMain.MouseCursor = System.Cursors.HandClosed // never seen

The actual cursor choices don’t matter - the above is just for illustration.
I’d really like to see a best practice example of how I should be doing this. All I can find are examples of dragging out of a Xojo application to the Finder and dragging within an application.

Any examples of working code would be gratefully received.

Thanks,

Ian.

Look at the DragEnter and DragMove events. There’s a byref parameter there that lets you control what types of actions your app accepts… move, copy or shortcut. Setting that should automatically change the cursor if the user isn’t holding down a key.

And it’s not byref. Sorry about that, I remembered incorrectly.

But you should be able to set the. Yes or in those events and then reset it in the DropObject and MouseUp events.

If the event is linked to the drop zone, I can imagine a scenario where someone enters the zone changing the mouse cursor and move away without dropping the item, never firing the zone.MouseUp(). DragExit() must participate on the solution.

1 Like

Thanks for the responses. I decided to make my own example to illustrate what seems to work and what doesn’t. I have pasted the code from the main window (wMain.xojo_window) below, but in summary:

  • Mousing over windows and controls changes the cursor as expected
  • Dragging a file in and dropping it works fine (as I have previously found) but the cursor doesn’t change
  • I can detect dragging over a control (DragEnter) by setting a background colour, but the cursor does not change
  • If I have used the DropObject event to apparently set a cursor, that is ignored, but after I have done the drop the cursor will later change on moving the mouse pointer over the control unless (as I have done in my example) I have set the cursor back to StandardPointer in the DropObject event.
    On one level, I now have a way to highlight the drag of a file over a control (using the BackgroundColor) but I’d much rather that setting the mouse cursor worked. If it is of interest, here is the code, and any advice on improving it will be welcome.

Ian.

#tag DesktopWindow
Begin DesktopWindow winMain
   Backdrop        =   0
   BackgroundColor =   &cFFFFFF
   Composite       =   False
   DefaultLocation =   2
   FullScreen      =   False
   HasBackgroundColor=   False
   HasCloseButton  =   True
   HasFullScreenButton=   False
   HasMaximizeButton=   True
   HasMinimizeButton=   True
   HasTitleBar     =   True
   Height          =   400
   ImplicitInstance=   True
   MacProcID       =   0
   MaximumHeight   =   32000
   MaximumWidth    =   32000
   MenuBar         =   566888447
   MenuBarVisible  =   False
   MinimumHeight   =   64
   MinimumWidth    =   64
   Resizeable      =   True
   Title           =   "Testing mouse cursor and file drag and drop"
   Type            =   0
   Visible         =   True
   Width           =   703
   Begin DesktopLabel lblMPOnWindow
      AllowAutoDeactivate=   True
      Bold            =   False
      Enabled         =   True
      FontName        =   "System"
      FontSize        =   0.0
      FontUnit        =   0
      Height          =   20
      Index           =   -2147483648
      Italic          =   False
      Left            =   20
      LockBottom      =   False
      LockedInPosition=   False
      LockLeft        =   True
      LockRight       =   False
      LockTop         =   True
      Multiline       =   False
      Scope           =   0
      Selectable      =   False
      TabIndex        =   0
      TabPanelIndex   =   0
      TabStop         =   True
      Text            =   "Mouse pointer (timer) moving on window"
      TextAlignment   =   0
      TextColor       =   &c000000
      Tooltip         =   ""
      Top             =   52
      Transparent     =   False
      Underline       =   False
      Visible         =   False
      Width           =   264
   End
   Begin DesktopLabel lblMPOffWindow
      AllowAutoDeactivate=   True
      Bold            =   False
      Enabled         =   True
      FontName        =   "System"
      FontSize        =   0.0
      FontUnit        =   0
      Height          =   20
      Index           =   -2147483648
      Italic          =   False
      Left            =   20
      LockBottom      =   False
      LockedInPosition=   False
      LockLeft        =   True
      LockRight       =   False
      LockTop         =   True
      Multiline       =   False
      Scope           =   0
      Selectable      =   False
      TabIndex        =   1
      TabPanelIndex   =   0
      TabStop         =   True
      Text            =   "Mouse pointer (standard) outside window"
      TextAlignment   =   0
      TextColor       =   &c000000
      Tooltip         =   ""
      Top             =   84
      Transparent     =   False
      Underline       =   False
      Visible         =   True
      Width           =   264
   End
   Begin DesktopTextField txtMPOntxt
      AllowAutoDeactivate=   True
      AllowFocusRing  =   True
      AllowSpellChecking=   False
      AllowTabs       =   False
      BackgroundColor =   &cFFFFFF
      Bold            =   False
      Enabled         =   True
      FontName        =   "System"
      FontSize        =   0.0
      FontUnit        =   0
      Format          =   ""
      HasBorder       =   True
      Height          =   22
      Hint            =   ""
      Index           =   -2147483648
      Italic          =   False
      Left            =   20
      LockBottom      =   False
      LockedInPosition=   False
      LockLeft        =   True
      LockRight       =   False
      LockTop         =   True
      MaximumCharactersAllowed=   0
      Password        =   False
      ReadOnly        =   False
      Scope           =   0
      TabIndex        =   2
      TabPanelIndex   =   0
      TabStop         =   True
      Text            =   ""
      TextAlignment   =   0
      TextColor       =   &c000000
      Tooltip         =   ""
      Top             =   155
      Transparent     =   False
      Underline       =   False
      ValidationMask  =   ""
      Visible         =   True
      Width           =   264
   End
   Begin DesktopLabel lblDetectingtTitle
      AllowAutoDeactivate=   True
      Bold            =   True
      Enabled         =   True
      FontName        =   "System"
      FontSize        =   16.0
      FontUnit        =   0
      Height          =   20
      Index           =   -2147483648
      Italic          =   False
      Left            =   20
      LockBottom      =   False
      LockedInPosition=   False
      LockLeft        =   True
      LockRight       =   False
      LockTop         =   True
      Multiline       =   False
      Scope           =   0
      Selectable      =   False
      TabIndex        =   3
      TabPanelIndex   =   0
      TabStop         =   True
      Text            =   "Detecting mouse movement"
      TextAlignment   =   0
      TextColor       =   &c000000
      Tooltip         =   ""
      Top             =   20
      Transparent     =   False
      Underline       =   False
      Visible         =   True
      Width           =   264
   End
   Begin DesktopLabel lblDragAndDropTitle
      AllowAutoDeactivate=   True
      Bold            =   True
      Enabled         =   True
      FontName        =   "System"
      FontSize        =   16.0
      FontUnit        =   0
      Height          =   20
      Index           =   -2147483648
      Italic          =   False
      Left            =   326
      LockBottom      =   False
      LockedInPosition=   False
      LockLeft        =   True
      LockRight       =   False
      LockTop         =   True
      Multiline       =   False
      Scope           =   0
      Selectable      =   False
      TabIndex        =   4
      TabPanelIndex   =   0
      TabStop         =   True
      Text            =   "Detecting file drag and drop"
      TextAlignment   =   0
      TextColor       =   &c000000
      Tooltip         =   ""
      Top             =   20
      Transparent     =   False
      Underline       =   False
      Visible         =   True
      Width           =   254
   End
   Begin DesktopLabel lblMoveeMPTitle
      AllowAutoDeactivate=   True
      Bold            =   True
      Enabled         =   True
      FontName        =   "System"
      FontSize        =   0.0
      FontUnit        =   0
      Height          =   20
      Index           =   -2147483648
      Italic          =   False
      Left            =   20
      LockBottom      =   False
      LockedInPosition=   False
      LockLeft        =   True
      LockRight       =   False
      LockTop         =   True
      Multiline       =   False
      Scope           =   0
      Selectable      =   False
      TabIndex        =   5
      TabPanelIndex   =   0
      TabStop         =   True
      Text            =   "Move the mouse over the textfield below"
      TextAlignment   =   0
      TextColor       =   &c000000
      Tooltip         =   ""
      Top             =   123
      Transparent     =   False
      Underline       =   False
      Visible         =   True
      Width           =   264
   End
   Begin DesktopTextField txtDragFileOver
      AllowAutoDeactivate=   True
      AllowFocusRing  =   True
      AllowSpellChecking=   False
      AllowTabs       =   False
      BackgroundColor =   &cFFFFFF00
      Bold            =   False
      Enabled         =   True
      FontName        =   "System"
      FontSize        =   0.0
      FontUnit        =   0
      Format          =   ""
      HasBorder       =   True
      Height          =   22
      Hint            =   ""
      Index           =   -2147483648
      Italic          =   False
      Left            =   326
      LockBottom      =   False
      LockedInPosition=   False
      LockLeft        =   True
      LockRight       =   False
      LockTop         =   True
      MaximumCharactersAllowed=   0
      Password        =   False
      ReadOnly        =   False
      Scope           =   0
      TabIndex        =   6
      TabPanelIndex   =   0
      TabStop         =   True
      Text            =   "Drag a file into this textfield. Don't drop it!"
      TextAlignment   =   0
      TextColor       =   &c000000
      Tooltip         =   ""
      Top             =   82
      Transparent     =   False
      Underline       =   False
      ValidationMask  =   ""
      Visible         =   True
      Width           =   357
   End
   Begin DesktopLabel lblDragOverTitle
      AllowAutoDeactivate=   True
      Bold            =   True
      Enabled         =   True
      FontName        =   "System"
      FontSize        =   0.0
      FontUnit        =   0
      Height          =   20
      Index           =   -2147483648
      Italic          =   False
      Left            =   326
      LockBottom      =   False
      LockedInPosition=   False
      LockLeft        =   True
      LockRight       =   False
      LockTop         =   True
      Multiline       =   False
      Scope           =   0
      Selectable      =   False
      TabIndex        =   7
      TabPanelIndex   =   0
      TabStop         =   True
      Text            =   "Drag an incoming file over the textfield below"
      TextAlignment   =   0
      TextColor       =   &c000000
      Tooltip         =   ""
      Top             =   52
      Transparent     =   False
      Underline       =   False
      Visible         =   True
      Width           =   311
   End
   Begin DesktopLabel lblDropObjectTitle
      AllowAutoDeactivate=   True
      Bold            =   True
      Enabled         =   True
      FontName        =   "System"
      FontSize        =   0.0
      FontUnit        =   0
      Height          =   20
      Index           =   -2147483648
      Italic          =   False
      Left            =   326
      LockBottom      =   False
      LockedInPosition=   False
      LockLeft        =   True
      LockRight       =   False
      LockTop         =   True
      Multiline       =   False
      Scope           =   0
      Selectable      =   False
      TabIndex        =   8
      TabPanelIndex   =   0
      TabStop         =   True
      Text            =   "Drag and drop an incoming file over the textfield below"
      TextAlignment   =   0
      TextColor       =   &c000000
      Tooltip         =   ""
      Top             =   123
      Transparent     =   False
      Underline       =   False
      Visible         =   True
      Width           =   357
   End
   Begin DesktopTextField txtDragDropFile
      AllowAutoDeactivate=   True
      AllowFocusRing  =   True
      AllowSpellChecking=   False
      AllowTabs       =   False
      BackgroundColor =   &cFFFFFF
      Bold            =   False
      Enabled         =   True
      FontName        =   "System"
      FontSize        =   0.0
      FontUnit        =   0
      Format          =   ""
      HasBorder       =   True
      Height          =   22
      Hint            =   ""
      Index           =   -2147483648
      Italic          =   False
      Left            =   326
      LockBottom      =   False
      LockedInPosition=   False
      LockLeft        =   True
      LockRight       =   False
      LockTop         =   True
      MaximumCharactersAllowed=   0
      Password        =   False
      ReadOnly        =   False
      Scope           =   0
      TabIndex        =   9
      TabPanelIndex   =   0
      TabStop         =   True
      Text            =   "Drag a file and drop it on this textfield"
      TextAlignment   =   0
      TextColor       =   &c000000
      Tooltip         =   ""
      Top             =   155
      Transparent     =   False
      Underline       =   False
      ValidationMask  =   ""
      Visible         =   True
      Width           =   357
   End
End
#tag EndDesktopWindow

#tag WindowCode
	#tag Event
		Sub MouseEnter()
		  lblMPOnWindow.visible = true
		  lblMPOffWindow.visible = false
		  
		  winMain.MouseCursor = System.Cursors.wait
		End Sub
	#tag EndEvent

	#tag Event
		Sub MouseExit()
		  lblMPOnWindow.visible = False
		  lblMPOffWindow.Visible = True
		  winMain.MouseCursor = System.Cursors.StandardPointer
		  
		End Sub
	#tag EndEvent


#tag EndWindowCode

#tag Events txtMPOntxt
	#tag Event
		Sub MouseEnter()
		  txtMPOntxt.text = "Mouse pointer (magnify) over text field"
		  txtMPOntxt.MouseCursor = System.Cursors.MagnifyLarger
		End Sub
	#tag EndEvent
	#tag Event
		Sub MouseExit()
		  txtMPOntxt.text = ""
		  txtMPOntxt.MouseCursor = System.Cursors.StandardPointer
		End Sub
	#tag EndEvent
#tag EndEvents
#tag Events txtDragFileOver
	#tag Event
		Sub Opening()
		  txtDragFileOver.AcceptFileDrop("Any")
		End Sub
	#tag EndEvent
	#tag Event
		Function DragEnter(obj As DragItem, action As DragItem.Types) As Boolean
		  action = DragItem.Types(DragItem.DragActionDefault)
		  txtDragFileOver.MouseCursor = system.Cursors.FingerPointer
		  txtDragFileOver.text = "Dragged file is over textfield. Don't drop it!"
		  txtDragFileOver.BackgroundColor = color.HighlightColor
		End Function
	#tag EndEvent
	#tag Event
		Sub DragExit(obj As DragItem, action As DragItem.Types)
		  txtDragFileOver.MouseCursor = system.Cursors.StandardPointer
		  txtDragFileOver.text = "Drag a file into this textfield. Don't drop it!"
		  txtDragFileOver.BackgroundColor = color.White
		End Sub
	#tag EndEvent
	#tag Event
		Sub DropObject(obj As DragItem, action As DragItem.Types)
		  msgbox("I said don't drop it!")
		  // If I don't include the line below, the mouse pointer changes to 
		  // FingerPointer when I later move the mouse over this textfield
		  txtDragFileOver.MouseCursor = System.Cursors.StandardPointer
		  txtDragFileOver.BackgroundColor = Color.White
		  
		End Sub
	#tag EndEvent
#tag EndEvents
#tag Events txtDragDropFile
	#tag Event
		Sub Opening()
		  txtDragDropFile.AcceptFileDrop("Any")
		  
		End Sub
	#tag EndEvent
	#tag Event
		Sub DropObject(obj As DragItem, action As DragItem.Types)
		  if obj.FolderItemAvailable then
		    txtDragDropFile.text = obj.FolderItem.NativePath
		    txtDragDropFile.BackgroundColor = Color.White
		    txtDragDropFile.MouseCursor = system.Cursors.StandardPointer
		  end if
		  
		End Sub
	#tag EndEvent
	#tag Event
		Function DragEnter(obj As DragItem, action As DragItem.Types) As Boolean
		  action = DragItem.Types(DragItem.DragActionDefault)
		  txtDragDropFile.MouseCursor = system.Cursors.FingerPointer
		  txtDragDropFile.text = "Dragged file is over textfield. Drop it here"
		  txtDragDropFile.BackgroundColor = color.HighlightColor
		End Function
	#tag EndEvent
	#tag Event
		Sub DragExit(obj As DragItem, action As DragItem.Types)
		  txtDragDropFile.MouseCursor = system.Cursors.StandardPointer
		  txtDragDropFile.text = "Drag a file into this textfield. Don't drop it!"
		  txtDragDropFile.BackgroundColor = color.White
		End Sub
	#tag EndEvent
#tag EndEvents
#tag ViewBehavior
	#tag ViewProperty
		Name="Name"
		Visible=true
		Group="ID"
		InitialValue=""
		Type="String"
		EditorType=""
	#tag EndViewProperty
	#tag ViewProperty
		Name="Interfaces"
		Visible=true
		Group="ID"
		InitialValue=""
		Type="String"
		EditorType=""
	#tag EndViewProperty
	#tag ViewProperty
		Name="Super"
		Visible=true
		Group="ID"
		InitialValue=""
		Type="String"
		EditorType=""
	#tag EndViewProperty
	#tag ViewProperty
		Name="Width"
		Visible=true
		Group="Size"
		InitialValue="600"
		Type="Integer"
		EditorType=""
	#tag EndViewProperty
	#tag ViewProperty
		Name="Height"
		Visible=true
		Group="Size"
		InitialValue="400"
		Type="Integer"
		EditorType=""
	#tag EndViewProperty
	#tag ViewProperty
		Name="MinimumWidth"
		Visible=true
		Group="Size"
		InitialValue="64"
		Type="Integer"
		EditorType=""
	#tag EndViewProperty
	#tag ViewProperty
		Name="MinimumHeight"
		Visible=true
		Group="Size"
		InitialValue="64"
		Type="Integer"
		EditorType=""
	#tag EndViewProperty
	#tag ViewProperty
		Name="MaximumWidth"
		Visible=true
		Group="Size"
		InitialValue="32000"
		Type="Integer"
		EditorType=""
	#tag EndViewProperty
	#tag ViewProperty
		Name="MaximumHeight"
		Visible=true
		Group="Size"
		InitialValue="32000"
		Type="Integer"
		EditorType=""
	#tag EndViewProperty
	#tag ViewProperty
		Name="Type"
		Visible=true
		Group="Frame"
		InitialValue="0"
		Type="Types"
		EditorType="Enum"
		#tag EnumValues
			"0 - Document"
			"1 - Movable Modal"
			"2 - Modal Dialog"
			"3 - Floating Window"
			"4 - Plain Box"
			"5 - Shadowed Box"
			"6 - Rounded Window"
			"7 - Global Floating Window"
			"8 - Sheet Window"
			"9 - Modeless Dialog"
		#tag EndEnumValues
	#tag EndViewProperty
	#tag ViewProperty
		Name="Title"
		Visible=true
		Group="Frame"
		InitialValue="Untitled"
		Type="String"
		EditorType=""
	#tag EndViewProperty
	#tag ViewProperty
		Name="HasCloseButton"
		Visible=true
		Group="Frame"
		InitialValue="True"
		Type="Boolean"
		EditorType=""
	#tag EndViewProperty
	#tag ViewProperty
		Name="HasMaximizeButton"
		Visible=true
		Group="Frame"
		InitialValue="True"
		Type="Boolean"
		EditorType=""
	#tag EndViewProperty
	#tag ViewProperty
		Name="HasMinimizeButton"
		Visible=true
		Group="Frame"
		InitialValue="True"
		Type="Boolean"
		EditorType=""
	#tag EndViewProperty
	#tag ViewProperty
		Name="HasFullScreenButton"
		Visible=true
		Group="Frame"
		InitialValue="False"
		Type="Boolean"
		EditorType=""
	#tag EndViewProperty
	#tag ViewProperty
		Name="HasTitleBar"
		Visible=true
		Group="Frame"
		InitialValue="True"
		Type="Boolean"
		EditorType=""
	#tag EndViewProperty
	#tag ViewProperty
		Name="Resizeable"
		Visible=true
		Group="Frame"
		InitialValue="True"
		Type="Boolean"
		EditorType=""
	#tag EndViewProperty
	#tag ViewProperty
		Name="Composite"
		Visible=false
		Group="OS X (Carbon)"
		InitialValue="False"
		Type="Boolean"
		EditorType=""
	#tag EndViewProperty
	#tag ViewProperty
		Name="MacProcID"
		Visible=false
		Group="OS X (Carbon)"
		InitialValue="0"
		Type="Integer"
		EditorType=""
	#tag EndViewProperty
	#tag ViewProperty
		Name="FullScreen"
		Visible=true
		Group="Behavior"
		InitialValue="False"
		Type="Boolean"
		EditorType=""
	#tag EndViewProperty
	#tag ViewProperty
		Name="DefaultLocation"
		Visible=true
		Group="Behavior"
		InitialValue="2"
		Type="Locations"
		EditorType="Enum"
		#tag EnumValues
			"0 - Default"
			"1 - Parent Window"
			"2 - Main Screen"
			"3 - Parent Window Screen"
			"4 - Stagger"
		#tag EndEnumValues
	#tag EndViewProperty
	#tag ViewProperty
		Name="Visible"
		Visible=true
		Group="Behavior"
		InitialValue="True"
		Type="Boolean"
		EditorType=""
	#tag EndViewProperty
	#tag ViewProperty
		Name="ImplicitInstance"
		Visible=true
		Group="Window Behavior"
		InitialValue="True"
		Type="Boolean"
		EditorType=""
	#tag EndViewProperty
	#tag ViewProperty
		Name="HasBackgroundColor"
		Visible=true
		Group="Background"
		InitialValue="False"
		Type="Boolean"
		EditorType=""
	#tag EndViewProperty
	#tag ViewProperty
		Name="BackgroundColor"
		Visible=true
		Group="Background"
		InitialValue="&cFFFFFF"
		Type="ColorGroup"
		EditorType="ColorGroup"
	#tag EndViewProperty
	#tag ViewProperty
		Name="Backdrop"
		Visible=true
		Group="Background"
		InitialValue=""
		Type="Picture"
		EditorType=""
	#tag EndViewProperty
	#tag ViewProperty
		Name="MenuBar"
		Visible=true
		Group="Menus"
		InitialValue=""
		Type="DesktopMenuBar"
		EditorType=""
	#tag EndViewProperty
	#tag ViewProperty
		Name="MenuBarVisible"
		Visible=true
		Group="Deprecated"
		InitialValue="False"
		Type="Boolean"
		EditorType=""
	#tag EndViewProperty
#tag EndViewBehavior
type or paste code here

Make a sample, save it, zip it, drag the zip to a post here and share with us.

Here you go.
Archive.zip (6.0 KB)

1 Like

Something seems really broken, open an Issue report.

CursorDrop.zip (5.6 KB)

Ian,
The MouseCursor above the window is WaitCursor (clock).

I get the text in TextField (left bottom, but no color).
Drag and drop “works” on the same TextField.
The cursor is a Green +

I said don’t drop it!
You can add the file name. Your Xojo text files are rejected…
As is real (.txt) dropped files (three at once).

HTH

Last MacOS + Last Xojo + MacBook Pro 13" (no beta).