I'm an arborist and I'm all right...
BlitzMax Forums/Brucey's Modules/I'm an arborist and I'm all right...| 
 | ||
| Interesting things you can do with trees : 
SuperStrict
 
Framework wx.wxApp
Import wx.wxFrame
Import wx.wxTreeCtrl
Import wx.wxTextDropTarget
Import wx.wxTextDataObject
Import wx.wxDropSource
New MyApp.Run()
 
Type MyApp Extends wxApp
	Method OnInit:Int()
	
		Local sz:MyFrame = MyFrame(New MyFrame.Create(Null, wxID_ANY, "Drag Drop Example", -1, -1, 250, 280))
		sz.Show(True)
 
		Return True
	End Method
End Type
Type MyFrame Extends wxFrame
 
	Field treectrl:wxTreeCtrl
	Field dragItem:wxTreeItemId
	
	Method OnInit()
		
		treectrl = New wxTreeCtrl.Create(Self, -1)
		
		Local root:wxTreeItemId = treeCtrl.AddRoot("Root")
		For Local i:Int = 1 To 10
			treectrl.AppendItem(root, "Node Number " + i)
		Next
		
		treeCtrl.ExpandAll()
		
		Centre()
 
		Local target:MyTextDropTarget = New MyTextDropTarget.CreateTarget(Self)
		treeCtrl.SetDropTarget(target)
		treeCtrl.ConnectAny(wxEVT_COMMAND_TREE_BEGIN_DRAG, _OnDrag, Null, Self)
	End Method
	
	Function _OnDrag(event:wxEvent)
		MyFrame(event.sink).OnDrag(wxTreeEvent(event))
	End Function
	
	Method OnDrag(event:wxTreeEvent)
		dragItem = event.GetItem()
		
		If Not dragItem.Equals(treectrl.GetRootItem()) Then
		
			Local tdo:wxTextDataObject = New wxTextDataObject.Create(treectrl.getItemText(dragItem))
			Local tds:wxDropSource = New wxDropSource.Create(tdo, treectrl)
			tds.DoDragDrop(wxDrag_AllowMove)
			
		End If
	End Method
	
End Type
Type MyTextDropTarget Extends wxTextDropTarget
	Field s:MyFrame
	Field ctrl:wxTreeCtrl
	
	Method CreateTarget:MyTextDropTarget(owner:MyFrame)
		s = owner
		ctrl = s.treectrl
		Super.Create()
		Return Self
	End Method
	Method OnDropText:Int(x:Int, y:Int, data:String)
	
		Local flags:Int
		
		' find the item we drop onto
		Local item:wxTreeItemId = ctrl.HitTest(x, y, flags)
		' everything is okay to do the drop?
		'  - source is okay
		'  - target is okay
		'  - target <> source
		'  - target <> root
		If s.dragItem And s.dragItem.isOk() And item.isOk() And Not item.Equals(s.dragItem) And Not item.Equals(ctrl.GetRootItem()) Then
			
			' create a new item
			Local newItem:wxTreeItemId = Ctrl.InsertItem(ctrl.GetItemParent(item), item, data)
			' copy its user data, if any
			ctrl.SetItemData(newItem, ctrl.GetItemData(s.dragItem))
			
			' remove the original item
			ctrl.DeleteItem(s.dragItem)
		
			' select the 'moved' item
			ctrl.SelectItem(newItem)
		End If
		Return False
	End Method
End Type
So much interestingness, so little code :-p | 
| 
 | ||
| Weird.. it works on Windows but not Linux. | 
| 
 | ||
| Works on Mac too... :-) | 
| 
 | ||
| Is it possible to drag an item from one tree to another? Is it possible to drag an item from a tree to a property in a property grid control? | 
| 
 | ||
| I improved your code a bit by selecting the dragged node when dragging.  Is it possible to display a line where the node will be dropped?  It isn't very obvious right now: SuperStrict
 
Framework wx.wxApp
Import wx.wxFrame
Import wx.wxTreeCtrl
Import wx.wxTextDropTarget
Import wx.wxTextDataObject
Import wx.wxDropSource
Import brl.standardio
Import brl.random
New MyApp.Run()
 
Type MyApp Extends wxApp
	Method OnInit:Int()
	
		Local sz:MyFrame = MyFrame(New MyFrame.Create(Null, wxID_ANY, "Drag Drop Example", -1, -1, 250, 280))
		sz.Show(True)
 
		Return True
	End Method
End Type
Type MyFrame Extends wxFrame
 
	Field treectrl:wxTreeCtrl
	Field dragItem:wxTreeItemId
	
	Method OnInit()
		
		treectrl = New wxTreeCtrl.Create(Self, -1,0,0,wxTR_HAS_BUTTONS)
		
		Local root:wxTreeItemId = treeCtrl.AddRoot("Root")
		For Local i:Int = 1 To 10
			treectrl.AppendItem(root, "Node Number " + i)
		Next
		
		treeCtrl.ExpandAll()
		
		Centre()
 
		Local target:MyTextDropTarget = New MyTextDropTarget.CreateTarget(Self)
		treeCtrl.SetDropTarget(target)
		treeCtrl.ConnectAny(wxEVT_COMMAND_TREE_BEGIN_DRAG, _OnDrag, Null, Self)
	End Method
	
	Function _OnDrag(event:wxEvent)
		MyFrame(event.sink).OnDrag(wxTreeEvent(event))
	End Function
	
	Method OnDrag(event:wxTreeEvent)
		
		dragItem = event.GetItem()
		
		treectrl.SelectItem(dragitem)
		
		If Not dragItem.Equals(treectrl.GetRootItem()) Then
		
			Local tdo:wxTextDataObject = New wxTextDataObject.Create(treectrl.getItemText(dragItem))
			Local tds:wxDropSource = New wxDropSource.Create(tdo, treectrl)
			tds.DoDragDrop(wxDrag_AllowMove)
			
		End If
	End Method
	
End Type
Type MyTextDropTarget Extends wxTextDropTarget
	Field s:MyFrame
	Field ctrl:wxTreeCtrl
	
	Method CreateTarget:MyTextDropTarget(owner:MyFrame)
		s = owner
		ctrl = s.treectrl
		Super.Create()
		Return Self
	End Method
	Method OnDropText:Int(x:Int, y:Int, data:String)
	
		Local flags:Int
		
		' find the item we drop onto
		Local item:wxTreeItemId = ctrl.HitTest(x, y, flags)
		' everything is okay to do the drop?
		'  - source is okay
		'  - target is okay
		'  - target <> source
		'  - target <> root
		If s.dragItem And s.dragItem.isOk() And item.isOk() And Not item.Equals(s.dragItem) And Not item.Equals(ctrl.GetRootItem()) Then
			
			' create a new item
			Local newItem:wxTreeItemId = Ctrl.InsertItem(ctrl.GetItemParent(item), item, data)
			' copy its user data, if any
			ctrl.SetItemData(newItem, ctrl.GetItemData(s.dragItem))
			
			' remove the original item
			ctrl.DeleteItem(s.dragItem)
		
			' select the 'moved' item
			ctrl.SelectItem(newItem)
		End If
		Return False
	End Method
End Type | 
| 
 | ||
| Is SetItemDropHighlight of any use to you? | 
| 
 | ||
|  Works on Mac too... :-)   I don't know what it is, but trying to compile anything as a multi-threaded app no longer works since the BMX 1.40 update: 
Undefined symbols:
  "_threads_GetThreadData", referenced from:
      _444 in appstub.debug.mt.macos.x86.a(debugger_mt.stdio.bmx.debug.mt.macos.x86.o)
  "_threads_SetThreadData", referenced from:
      _444 in appstub.debug.mt.macos.x86.a(debugger_mt.stdio.bmx.debug.mt.macos.x86.o)
  "_threads_AllocThreadData", referenced from:
      _442 in appstub.debug.mt.macos.x86.a(debugger_mt.stdio.bmx.debug.mt.macos.x86.o)
ld: symbol(s) not found
collect2: ld returned 1 exit status
Single-threaded compilation works fine. | 
| 
 | ||
| try rebuilding all your modules, single and multi-threaded. I dunno why but I get similar glitches some times and I have to rebuild both to get MT building working again... I blame gremlins personally. | 
| 
 | ||
|  Is SetItemDropHighlight of any use to you?  Looking at the docs, I don't think so, unless you can tell me why. Is there any way to give better visualization of the tree drag and drop operation? You can only drag a node onto another node, and there is no visual feedback for where it will be inserted. | 
| 
 | ||
|  try rebuilding all your modules, single and multi-threaded.  That's what I usually do after an upgrade. But 1.40 really seems to have some gremlins aboard, at least for multi-threaded builds. The funny thing is that in most cases it helps to build first a single-threaded version and then it's also possible to create a multi-threaded build. |