The cursor changes in windows but not in linux (no idea about MacOS)!By returning #False, the callback denies the action (the cursor will be changed to a "forbidden" cursor by the drag source)
Next problem is, we need quite some API calls to be able to check the drop items "on-the-fly" with nothing but x and y coordinates.
I'm still not sure if below is correct in any cases, wouldn't it be possible that GetGadgetState() would return the item below the cursor while dragging, instead of always returning the item which gets dragged?
Code: Select all
CompilerIf #PB_Compiler_OS = #PB_OS_Linux
ImportC ""
gtk_widget_style_get(*Widget.GtkWidget, PropertyName.P-UTF8, *Value, Null)
gtk_tree_view_convert_bin_window_to_tree_coords(*tree_view.GtkTreeView, bx.I, by.I, *wx, *wy)
EndImport
CompilerEndIf
Global DragFrom.i
Procedure DropCallback(TargetHandle, State, Format, Action, x, y)
Protected Count, TreeItemHandle, i, H, Result = #True
Count = CountGadgetItems(0)
CompilerSelect #PB_Compiler_OS
CompilerCase #PB_OS_Windows
Protected TreeHandle
TreeItemHandle = SendMessage_(GadgetID(0), #TVM_GETNEXTITEM, #TVGN_FIRSTVISIBLE, #Null)
For i = 0 To Count - 1
If GadgetItemID(0, i) = TreeItemHandle
Break
EndIf
Next i
H = SendMessage_(GadgetID(0), 4380, 0, 0) ;#TVM_GETITEMHEIGHT = 4380
i + Int(y / H)
CompilerCase #PB_OS_Linux ;Thanks to Shardik: http://www.purebasic.fr/german/viewtopic.php?p=345109#p345109
Protected Add, wx, wy
gtk_tree_view_column_cell_get_size_(gtk_tree_view_get_column_(GadgetID(0), 0), #Null, #Null, #Null, #Null, @H)
gtk_widget_style_get(GadgetID(0), "vertical-separator", @Add, 0)
gtk_tree_view_convert_bin_window_to_tree_coords(GadgetID(0), x, y, @wx, @wy)
y = wy
H + Add
i = Int(y / H)
CompilerCase #PB_OS_MacOS ;Thanks to Shardik: http://www.purebasic.fr/german/viewtopic.php?p=345137#p345137
CocoaMessage(@Frame, GadgetID(0), "frameOfOutlineCellAtRow:", 0)
H = Frame\size\height
i = Int(y / H)
CompilerEndSelect
If i = 25
Result = #False
EndIf
ProcedureReturn Result
EndProcedure
Procedure OnDragStart()
DragFrom = GetGadgetState(0)
DragPrivate(1, #PB_Drag_Move)
EndProcedure
Procedure OnDropped()
;do nithing
Debug "Dropped pos " + Str(DragFrom) + " to pos " + Str(GetGadgetState(0))
EndProcedure
OpenWindow(0, 0, 0, 300, 300, "tree drag&drop")
TreeGadget(0, 5, 5, 290, 290)
For i = 1 To 25
AddGadgetItem(0, -1, "drop here")
Next i
AddGadgetItem(0, -1, "don't drop here!")
For i = 1 To 25
AddGadgetItem(0, -1, "drop here")
Next i
SetDropCallback(@DropCallBack())
EnableGadgetDrop(0, #PB_Drop_Private, #PB_Drag_Move, 1)
BindGadgetEvent(0, @OnDragStart(), #PB_EventType_DragStart)
BindEvent(#PB_Event_GadgetDrop, @OnDropped())
While WaitWindowEvent() <> #PB_Event_CloseWindow : Wend