I'm trying to draw a line to show where the listview row will drop. But I can't get it to work properly (I just focused on the draw part).
Could you help me please ? Here is the code :
EDIT : Here is a working code from Shardik (thank you !)
Code: Select all
Structure LVINSERTMARK
cbSize.L
dwFlags.L
iItem.L
dwReserved.L
EndStructure
Define DraggingIsActive.I
Define HeaderHeight.I
Define Rectangle.RECT
Define RowIndex.I
Define RowHeight.I
Define RowInsertionIndex.I
Procedure WindowCallback(WindowHandle.I, Msg.I, WParam.I, LParam.I)
Shared DraggingIsActive.I
Protected *NMHdr.NMHDR
Select Msg
Case #WM_NOTIFY
*NMHdr = LParam
If *NMHdr\hwndFrom = GadgetID(0)
If *NMHdr\code = #LVN_ITEMCHANGING
If DraggingIsActive And GetGadgetState(0) = -1
; ----- Disable highlighting of item under cursor
ProcedureReturn #True
EndIf
EndIf
EndIf
EndSelect
ProcedureReturn #PB_ProcessPureBasicEvents
EndProcedure
Procedure DragCallback(Action.I)
Shared HeaderHeight.I
Shared RowHeight.I
Shared RowInsertionIndex.I
Protected CursorPositon.POINT
Protected CursorRow.I
Protected InsertMark.LVINSERTMARK
Protected Rectangle.RECT
Protected RowCount.I
InsertMark\cbSize = SizeOf(LVINSERTMARK)
GetCursorPos_(CursorPositon)
GetWindowRect_(GadgetID(0), Rectangle)
If PtInRect_(Rectangle, CursorPositon\x + (CursorPositon\y) << 32)
; ----- Convert x and y from coordinate space to window-relative space
MapWindowPoints_(0, GadgetID(0), CursorPositon, 1)
; ----- Get row index of current cursor position
CursorRow = (CursorPositon\y - HeaderHeight) / RowHeight
RowCount = CountGadgetItems(0)
If CursorRow >= RowCount
; ----- Cursor is in empty row below last item
RowInsertionIndex = RowCount
ElseIf CursorRow = -1
CursorRow = 0
Else
; ----- Get row insertion index
SendMessage_(GadgetID(0), #LVM_INSERTMARKHITTEST, @CursorPositon,
@InsertMark)
; ----- Display insertion line
SendMessage_(GadgetID(0), #LVM_SETINSERTMARK, 0, @InsertMark)
RowInsertionIndex = InsertMark\iItem
; ----- Increase index if cursor is in lower part of row
If (CursorPositon\y - HeaderHeight) % RowHeight > RowHeight * 0.5
RowInsertionIndex + 1
EndIf
EndIf
ProcedureReturn #True
EndIf
EndProcedure
Procedure DropCallback(TargetHandle.I, Status.I, Format.I, Action.I, x.I, y.I)
Shared DraggingIsActive.I
Protected InsertMark.LVINSERTMARK
Protected Result.I = #False
InsertMark\cbSize = SizeOf(LVINSERTMARK)
Select Status
Case #PB_Drag_Move, #PB_Drag_Enter
DraggingIsActive = #True
Case #PB_Drag_Leave, #PB_Drag_Finish
DraggingIsActive = #False
; ----- Remove insertion line
InsertMark\iItem = -1
SendMessage_(GadgetID(0), #LVM_SETINSERTMARK, 0, @InsertMark)
EndSelect
If Status <> #PB_Drag_Leave
Result = #True
EndIf
ProcedureReturn Result
EndProcedure
OpenWindow(0, 100, 100, 370, 150, "Drag 'n drop row inside gadget")
ListIconGadget(0, 10, 10, WindowWidth(0) - 20, WindowHeight(0) - 20,
"Name", 100,
#PB_ListIcon_GridLines | #PB_ListIcon_FullRowSelect)
AddGadgetColumn(0, 1, "Address", GadgetWidth(0) - GetGadgetItemAttribute(0,
0, #PB_ListIcon_ColumnWidth) - 4)
AddGadgetItem(0, -1, "Harry Rannit" + #LF$ +
"12 Parliament Way, Battle Street, By the Bay")
AddGadgetItem(0, -1, "Ginger Brokeit" + #LF$ +
"130 PureBasic Road, BigTown, CodeCity")
AddGadgetItem(0, -1, "Didi Foundit" + #LF$ +
"321 Logo Drive, Mouse House, Downtown")
EnableGadgetDrop(0, #PB_Drop_Text, #PB_Drag_Copy)
SetDragCallback(@DragCallback())
SetDropCallback(@DropCallback())
; ----- Get height of header row
GetClientRect_(SendMessage_(GadgetID(0), #LVM_GETHEADER, 0, 0), @Rectangle)
HeaderHeight = Rectangle\bottom - Rectangle\top
; ----- Get height of single row
RowHeight = SendMessage_(GadgetID(0), #LVM_GETITEMSPACING, #True, 0) >> 16
; ----- Initialize WindowCallback to suppress highlighting
SetWindowCallback(@WindowCallback(), 0)
Repeat
Select WaitWindowEvent()
Case #PB_Event_CloseWindow
Break
Case #PB_Event_Gadget
If EventGadget() = 0 And EventType() = #PB_EventType_DragStart
DraggingIsActive = #True
RowIndex = GetGadgetState(0)
; ----- Deselect any selected entry
SetGadgetState(0, -1)
If RowIndex >= 0
DragText(GetGadgetItemText(0, RowIndex, 0) + #LF$ +
GetGadgetItemText(0, RowIndex, 1), #PB_Drag_Copy)
EndIf
EndIf
Case #PB_Event_GadgetDrop
AddGadgetItem(0, RowInsertionIndex, EventDropText())
; ----- Deselect any selected entry
SetGadgetState(0, -1)
EndSelect
ForEver