Sorry for the longer delay... yesterday I finished the Drag'n'Drop implementation in my GeoWorld project, using the code shown here with some further enhancements.
The good one is: all is working fine on MS Windows (using several listview gadgets, in which the items can be moved by drag'n'drop), so I'm sure my code is working how it should!
The bad one is: nothing happens on MacOS, there seems any Drag event missing, so no further processing is possible.
The following example with 2 listicons and 2 listviews is hacked together on my MacBook now, based on code from the forum and additions done in my project source (Windows).
It should run as expected on MS Windows (couldn't test it now), but nothing happens on MacOS....
So the question is: Drag'n'Drop not supported for listviews and listicons on MacOS? ... a bug in PB? .... a bug in my code?
Code:
; Code example for moving gadget items inside the "own" listview/listicon by Drag'n'Drop
; works on Windows for both listicon and listviews, on MacOS not.
; by Andre on 6th May 2012
EnableExplicit
Define listview1, listview2, listicon1, listicon2
Define i, Exit
Define Event, EventType, EventGadget
Global DragGadget, DragItem, TargetItem
Enumeration
#Drag_Listview1
#Drag_Listview2
#Drag_Listicon1
#Drag_Listicon2
EndEnumeration
Procedure ListIconGadgetColumns(GadgetNo)
Protected i
i = 0
While GetGadgetItemAttribute(GadgetNo, 0, #PB_ListIcon_ColumnWidth, i) > 0
i + 1
Wend
ProcedureReturn i
EndProcedure
Procedure ListIconGadgetMove(GadgetNo.i, Source.i, Dest.i)
Protected Columns, i, j, Help$, Source$
Columns = ListIconGadgetColumns(GadgetNo) - 1
For j = 0 To Columns
Source$ = GetGadgetItemText(GadgetNo, Source, j)
If Source < Dest
For i = Source To Dest - 1
Help$ = GetGadgetItemText(GadgetNo, i + 1, j)
SetGadgetItemText(GadgetNo, i, Help$, j)
Next i
Else
For i = Source To Dest + 1 Step - 1
Help$ = GetGadgetItemText(GadgetNo, i - 1, j)
SetGadgetItemText(GadgetNo, i, Help$, j)
Next i
EndIf
SetGadgetItemText(GadgetNo, i, Source$, j)
Next j
EndProcedure
Procedure ListViewGadgetMove(gad.i, Source.i, Dest.i)
; This procedure is written by Andre on the base of the ListIconGadgetMove() function found on the PB forum.
; It was enhanced to support also moving of listview item text and data, and to take care when the dropping
; is finished after the current displayed items (then use the last item as destination for the move operation).
Protected i, ItemText$, ItemData, Source$, SourceData
Source$ = GetGadgetItemText(gad, Source)
SourceData = GetGadgetItemData(gad, Source)
;Debug "Dragged item (Source) = " + Str(Source) + ", Dropped at (Dest) = " + Str(Dest)
;If Source = -1 Or Dest = -1
; Debug "Warning: Source = " + Str(Source) + ", Dest = " + Str(Dest)
;EndIf
If Source = -1
; Sometimes it happens, that dragging an item (especially the first one) and dropping
; it at the same place cause a "DragStart" event, but the 'Source' parameter is -1.
; In this case don't make any chances and return to main event loop!
ProcedureReturn
EndIf
If Dest = -1
; The dragged item was dropped after the last item (giving -1 as result of GetGadgetState(),
; so we make the dragged one the last one now...
Dest = CountGadgetItems(gad) - 1
EndIf
If Source < Dest
For i = Source To Dest - 1
ItemText$ = GetGadgetItemText(gad, i + 1)
ItemData = GetGadgetItemData(gad, i + 1)
SetGadgetItemText(gad, i, ItemText$)
SetGadgetItemData(gad, i, ItemData)
Next
Else
For i = Source To Dest + 1 Step - 1
ItemText$ = GetGadgetItemText(gad, i - 1)
ItemData = GetGadgetItemData(gad, i - 1)
SetGadgetItemText(gad, i, ItemText$)
SetGadgetItemData(gad, i, ItemData)
Next
EndIf
SetGadgetItemText(gad, i, Source$)
SetGadgetItemData(gad, i, SourceData)
EndProcedure
OpenWindow(0, 0, 0, 600, 600, "Drag'n drop test", #PB_Window_MinimizeGadget|#PB_Window_ScreenCentered)
; 1st LISTVIEW for testing drag'n'drop:
TextGadget(0, 10, 10, 200, 20, "Listview 1:")
listview1 = ListViewGadget(#PB_Any, 10, 35, 200, 230)
For i = 1 To 10
AddGadgetItem(listview1, -1, "Line " + Str(i))
Next i
EnableGadgetDrop(listview1, #PB_Drop_Private, #PB_Drag_Move, #Drag_Listview1)
; 2nd LISTVIEW for testing drag'n'drop:
TextGadget(1, 10, 280, 200, 20, "Listview 2:")
listview2 = ListViewGadget(#PB_Any, 10, 305, 200, 230)
For i = 1 To 10
AddGadgetItem(listview2, -1, "Line " + Str(i))
Next i
EnableGadgetDrop(listview2, #PB_Drop_Private, #PB_Drag_Move, #Drag_Listview2)
; 1st LISTICON for testing drag'n'drop:
TextGadget(2, 230, 10, 200, 20, "Listicon 1:")
listicon1 = ListIconGadget(#PB_Any, 230, 35, 340, 230, "Column 1", 100, #PB_ListIcon_FullRowSelect)
AddGadgetColumn(listicon1, 1, "Column 2", 100)
AddGadgetColumn(listicon1, 2, "Column 3", 100)
For i = 1 To 10
AddGadgetItem(listicon1, -1, "Line " + Str(i) + Chr(10) + "col. 2 (" + Str(i) + ")" + Chr(10) + "col. 3 (" + Str(i) + ")")
Next i
EnableGadgetDrop(listicon1, #PB_Drop_Private, #PB_Drag_Move, #Drag_Listicon1)
; 2nd LISTICON for testing drag'n'drop:
TextGadget(3, 230, 280, 200, 20, "Listicon 2:")
listicon2 = ListIconGadget(#PB_Any, 230, 305, 340, 230, "Column 1", 100, #PB_ListIcon_FullRowSelect)
AddGadgetColumn(listicon2, 1, "Column 2", 100)
AddGadgetColumn(listicon2, 2, "Column 3", 100)
For i = 1 To 10
AddGadgetItem(listicon2, -1, "Line " + Str(i) + Chr(10) + "col. 2 (" + Str(i) + ")" + Chr(10) + "col. 3 (" + Str(i) + ")")
Next i
EnableGadgetDrop(listicon2, #PB_Drop_Private, #PB_Drag_Move, #Drag_Listicon2)
; Note
TextGadget(4, 10, 550, 580, 20, "Note: Drag'n'Drop is only supported inside the same gadget (move of items only)!")
Exit = #False
DragItem = -1
;- Event loop
Repeat
Event = WaitWindowEvent()
EventType = EventType()
EventGadget = EventGadget()
Select Event
Case #PB_Event_Gadget
Select EventGadget
Case listview1, listview2, listicon1, listicon2
Select EventType
Case #PB_EventType_DragStart
DragGadget = EventGadget ; here we save the GadgetID of the listview, in which the drag operation started
DragItem = GetGadgetState(DragGadget)
;Debug "DragGadget: " + Str(DragGadget)
If DragGadget = listview1
DragPrivate(#Drag_Listview1, #PB_Drag_Move)
ElseIf DragGadget = listview2
DragPrivate(#Drag_Listview2, #PB_Drag_Move)
ElseIf DragGadget = listicon1
DragPrivate(#Drag_Listicon1, #PB_Drag_Move)
ElseIf DragGadget = listicon2
DragPrivate(#Drag_Listicon2, #PB_Drag_Move)
EndIf
EndSelect
EndSelect
Case #PB_Event_GadgetDrop
EventGadget = GetActiveGadget()
TargetItem = GetGadgetState(EventGadget)
;Debug "DropGadget: " + Str(EventGadget) + ", TargetItem: " + Str(TargetItem)
If EventDropPrivate() = #Drag_Listview1 Or EventDropPrivate() = #Drag_Listview2
ListViewGadgetMove(EventGadget, DragItem, TargetItem)
ElseIf EventDropPrivate() = #Drag_Listicon1 Or EventDropPrivate() = #Drag_Listicon2
ListIconGadgetMove(EventGadget, DragItem, TargetItem)
EndIf
Case #PB_Event_CloseWindow
Exit = #True
EndSelect
Until Exit