- Reorder Columns
- Column header icon
- Column sort arrows
- Options to disable column resizing and dragging
- Group view
- Auto sort on click column header
- Sort groups & items (customizable via function)
- Collapsible group (not fully supported by winXP)
- New event types: header left/right click, reorderColumns...

Code: Select all
EnableExplicit
Enumeration
;add missing Windows platform constants if necessary...
CompilerIf Not Defined(HDF_BITMAP_ON_RIGHT, #PB_Constant)
#HDF_BITMAP_ON_RIGHT=$1000
#LVGS_COLLAPSED=$1
#LVGS_COLLAPSIBLE=$8
#LVGS_HIDDEN = $2
#LVM_GETGROUPCOUNT = #LVM_FIRST + 152
CompilerEndIf
;ListIcon new event types
#PB_EventType_HeaderLeftClick = #PB_EventType_FirstCustomValue+1111
#PB_EventType_HeaderRightClick
#PB_EventType_ReorderColumns
;ListIcon Attributes
#ListIconAttribute_GroupView=1
#ListIconAttribute_SortAuto
#ListIconAttribute_SortMultiColumn
#ListIconAttribute_AvailableColumnWidth
;ListIcon Header Flags
#ListIconHeader_None=0
#ListIconHeader_SortArrow_Down =%1
#ListIconHeader_SortArrow_Up =%10
#ListIconHeader_SortArrow_Changing =%100
#ListIconHeader_LeftIcon =%1000
#ListIconHeader_RightIcon =%10000
#ListIconHeader_NoDrag =%100000
#ListIconHeader_NoManualResize =%1000000
#ListIconHeader_NoAutoResize =%10000000
;(internal use only)
#ListIconHeader_AnySortArrow =#ListIconHeader_SortArrow_Down | #ListIconHeader_SortArrow_Up
#ListIconHeader_AnyIcon =#ListIconHeader_LeftIcon | #ListIconHeader_RightIcon
;ListIcon GroupID max value
#ListIconGroupID_MaxValue=%1<<16-1
;ListIcon Group Flags (conbinaison allowed)
#ListIconGroups_Collapsed=%1<<16
#ListIconGroups_Collapsible=%10<<16 ;not supported by winXP
#ListIconGroups_Hidden=%100<<16
EndEnumeration
Structure LISTICON_PARAMS
Map GroupName$()
Map GroupIDs.i()
List HeaderFlags.i()
Gadget.i
*GadgetID
*OriginalCallback
*ColHeader
*CustomData
IsSortingItems.b
IsSortAuto.b
IsSortMulti.b
IsGroupViewEnabled.b
EndStructure
Structure LVGROUP1 Align #PB_Structure_AlignC
cbSize.l
mask.l
*pszHeader
cchHeader.l
*pszFooter
cchFooter.l
iGroupId.l
stateMask.l
state.l
uAlign.l
EndStructure
Procedure.i InternalListIconParams(Gadget)
Protected *params.LISTICON_PARAMS=GetProp_(GadgetID(Gadget), "LISTICON_INTERNAL_PARAMS")
With *params
If Not *params
*params=AllocateMemory(SizeOf(LISTICON_PARAMS))
InitializeStructure(*params, LISTICON_PARAMS)
\Gadget=Gadget
\GadgetID=GadgetID(Gadget)
\ColHeader=SendMessage_(\GadgetID, #LVM_GETHEADER, 0, 0)
Protected *newCallback=GetRuntimeInteger("InternalListIconCallback()")
\OriginalCallback=SetWindowLongPtr_(\GadgetID, #GWL_WNDPROC, *newCallback)
Protected colCount=SendMessage_(*params\ColHeader, #HDM_GETITEMCOUNT, 0, 0)
Protected colIndex
For colIndex=1 To colCount : AddElement(\HeaderFlags()) : Next
SetProp_(\GadgetID, "LISTICON_INTERNAL_PARAMS", *params)
EndIf
ProcedureReturn *params
EndWith
EndProcedure
Procedure.i CountListIconColumns(Gadget)
Protected *params.LISTICON_PARAMS=InternalListIconParams(Gadget)
Protected colCount = SendMessage_(*params\ColHeader, #HDM_GETITEMCOUNT, 0, 0)
ProcedureReturn colCount
EndProcedure
Procedure.i CountListIconGroups(Gadget)
Protected *params.LISTICON_PARAMS=InternalListIconParams(Gadget)
Protected groupCount = SendMessage_(*params\GadgetID, #LVM_GETGROUPCOUNT, 0, 0)
ProcedureReturn groupCount
EndProcedure
Procedure.i GetListIconAttribute(Gadget, Attribute)
Protected *params.LISTICON_PARAMS=InternalListIconParams(Gadget)
With *params
Select Attribute
Case #ListIconAttribute_GroupView
ProcedureReturn SendMessage_(\GadgetID, #LVM_ISGROUPVIEWENABLED, 0, 0)
Case #ListIconAttribute_SortAuto
ProcedureReturn \IsSortAuto
Case #ListIconAttribute_SortMultiColumn
ProcedureReturn \IsSortMulti
Case #ListIconAttribute_AvailableColumnWidth
Protected column, colCount=CountListIconColumns(Gadget)
Protected columnWidth=GadgetWidth(Gadget)-4
For column=0 To colCount-1
columnWidth-GetGadgetItemAttribute(Gadget, -1, #PB_ListIcon_ColumnWidth, column)
Next
If GetWindowLongPtr_(\GadgetID, #GWL_STYLE)& #WS_VSCROLL
columnWidth-GetSystemMetrics_(#SM_CXVSCROLL)
EndIf
ProcedureReturn columnWidth
EndSelect
EndWith
EndProcedure
Procedure.i SetListIconAttribute(Gadget, Attribute, Value)
Protected *params.LISTICON_PARAMS=InternalListIconParams(Gadget)
Protected result
With *params
Select Attribute
Case #ListIconAttribute_GroupView
\IsGroupViewEnabled=Bool(Value)
result=Bool(SendMessage_(\GadgetID, #LVM_ENABLEGROUPVIEW, Bool(Value), 0)<>-1)
Case #ListIconAttribute_SortAuto
\IsSortAuto=Bool(Value)
result=#True
Case #ListIconAttribute_SortMultiColumn
\IsSortMulti=Bool(Value)
result=#True
Case #ListIconAttribute_AvailableColumnWidth
Protected column, columnsToResize, columnWidth, columnWidthToAdd, lastToResize=-1
Protected availableWidth=GetListIconAttribute(Gadget, #ListIconAttribute_AvailableColumnWidth)-Value
PushListPosition(\HeaderFlags())
ForEach \HeaderFlags()
If Not (\HeaderFlags()& #ListIconHeader_NoAutoResize)
columnsToResize+1
lastToResize=ListIndex(\HeaderFlags())
EndIf
Next
If columnsToResize
columnWidthToAdd=Round(availableWidth/columnsToResize, #PB_Round_Down)
ForEach \HeaderFlags()
column=ListIndex(\HeaderFlags())
If Not (\HeaderFlags()& #ListIconHeader_NoAutoResize)
columnWidth=GetGadgetItemAttribute(Gadget, -1, #PB_ListIcon_ColumnWidth, column)
If column=lastToResize
columnWidth+availableWidth
Else
columnWidth+columnWidthToAdd
availableWidth-columnWidthToAdd
EndIf
SetGadgetItemAttribute(Gadget, -1, #PB_ListIcon_ColumnWidth, columnWidth, column)
EndIf
Next
EndIf
PopListPosition(\HeaderFlags())
result=#True
EndSelect
EndWith
;returns TRUE if successful
ProcedureReturn result
EndProcedure
Procedure SetListIconHeader(Gadget, Column, Flags=0, *ImageID=0)
Protected *params.LISTICON_PARAMS=InternalListIconParams(Gadget)
Protected *colHeader=*params\ColHeader
Protected item.HD_ITEM, result
With item
\mask=#HDI_FORMAT|#HDI_BITMAP
If Not SendMessage_(*colHeader, #HDM_GETITEM, Column, item) : ProcedureReturn : EndIf
\fmt & ~#HDF_SORTDOWN & ~#HDF_SORTUP & ~#HDF_BITMAP & ~#HDF_BITMAP_ON_RIGHT
\fmt | #HDF_STRING
;change sort arrow (shift between bits)
If Flags & #ListIconHeader_SortArrow_Changing
If Not (Flags & #ListIconHeader_AnyIcon)
Protected newFlags=(Flags & %11)
If (newFlags=0) : newFlags=1 : Else : newFlags<<1 : EndIf
If (newFlags & %100) : newFlags=0 : EndIf
EndIf
Flags & ~%111 | newFlags
EndIf
If Flags & #ListIconHeader_AnySortArrow
;show/hide arrow (=> remove icon)
\hbm=0
\iImage=-1
If Flags & #ListIconHeader_SortArrow_Down : \fmt |#HDF_SORTDOWN : EndIf
If Flags & #ListIconHeader_SortArrow_Up : \fmt | #HDF_SORTUP : EndIf
ElseIf Flags & #ListIconHeader_AnyIcon
;show/hide icon (=> remove arrow)
\fmt |(#HDF_BITMAP *Bool(*ImageID))
\fmt |(#HDF_BITMAP_ON_RIGHT *Bool(*ImageID And Flags & #ListIconHeader_RightIcon))
\hbm=*ImageID
Else
;hide icon and arrow
\hbm=0
\iImage=-1
EndIf
EndWith
With *params
PushListPosition(\HeaderFlags())
If Not \IsSortMulti And Flags & #ListIconHeader_AnySortArrow
;keep only one sort arrow (=> single column sorting)
ForEach \HeaderFlags()
Protected col=ListIndex(\HeaderFlags())
If col<>Column And \HeaderFlags()& #ListIconHeader_AnySortArrow
\HeaderFlags()& ~#ListIconHeader_AnySortArrow
SetListIconHeader(\Gadget, col, \HeaderFlags())
EndIf
Next
EndIf
If SelectElement(\HeaderFlags(), Column)
;save and apply header flags
\HeaderFlags()=Flags
result=SendMessage_(*colHeader, #HDM_SETITEM, Column, item)
EndIf
PopListPosition(\HeaderFlags())
;returns TRUE if successful
ProcedureReturn result
EndWith
EndProcedure
Procedure.i GetListIconHeader(Gadget, Column, *ImageID=0)
Protected *params.LISTICON_PARAMS=InternalListIconParams(Gadget)
Protected item.HD_ITEM, Flags=0
With *params
PushListPosition(\HeaderFlags())
SelectElement(\HeaderFlags(), Column)
Flags=\HeaderFlags()
item\mask=#HDI_FORMAT|#HDI_BITMAP
If *ImageID And Flags & #ListIconHeader_AnyIcon And SendMessage_(\ColHeader, #HDM_GETITEM, Column, item)
PokeI(*ImageID, item\hbm)
EndIf
PopListPosition(\HeaderFlags())
;returns header Flags and Image if possible
ProcedureReturn Flags
EndWith
EndProcedure
Procedure.i GetListIconColumnOrder(Gadget, Array ColumnOrders(1))
Protected *params.LISTICON_PARAMS=InternalListIconParams(Gadget)
Protected *colHeader=*params\ColHeader
Protected colCount = CountListIconColumns(Gadget), i
If colCount
ReDim ColumnOrders(colCount-1)
Dim order.Long(colCount-1)
If SendMessage_(*colHeader, #HDM_GETORDERARRAY, colCount, order())
For i=0 To colCount-1 : ColumnOrders(i)=order(i)\l : Next
;retrieves count of columnOrders
ProcedureReturn colCount
EndIf
EndIf
EndProcedure
Procedure SetListIconColumnOrder(Gadget, Array ColumnOrders(1))
Protected *params.LISTICON_PARAMS=InternalListIconParams(Gadget)
Protected *colHeader=*params\ColHeader
Protected colCount = CountListIconColumns(Gadget), i
If ArraySize(ColumnOrders())=colCount-1
Protected Dim order.Long(colCount-1)
For i=0 To colCount-1 : order(i)\l=ColumnOrders(i) : Next
If SendMessage_(*colHeader, #HDM_SETORDERARRAY, colCount, order())
PostEvent(#PB_Event_Gadget, #PB_All, Gadget, #PB_EventType_ReorderColumns, #PB_All)
;returns TRUE if successful
ProcedureReturn #True
EndIf
EndIf
EndProcedure
Procedure SetListIconGroups(Gadget, Map GroupIDs(), Flags=#PB_Ignore)
Protected *params.LISTICON_PARAMS=InternalListIconParams(Gadget)
Protected *gadgetID=*params\GadgetID
Protected groupName$, groupID, groupState, group.LVGROUP1
With *params
ClearMap(\GroupIDs())
ClearMap(\GroupName$())
EndWith
If Flags<>#PB_Ignore
If Flags & #ListIconGroups_Collapsible : groupState | #LVGS_COLLAPSIBLE : EndIf
If Flags & #ListIconGroups_Collapsed : groupState | #LVGS_COLLAPSED : EndIf
If Flags & #ListIconGroups_Hidden : groupState | #LVGS_HIDDEN : EndIf
EndIf
PushMapPosition(GroupIDs())
ForEach GroupIDs()
With group
groupName$=MapKey(GroupIDs())
groupID=GroupIDs()& #ListIconGroupID_MaxValue
*params\GroupName$(""+groupID)=groupName$
*params\GroupIDs(groupName$)=groupID
\cbSize = SizeOf(LVGROUP1)
\mask = #LVGF_GROUPID | #LVGF_ALIGN | #LVGF_STATE | #LVGF_HEADER
\iGroupId = groupID
\state = groupState
\uAlign = #LVGA_HEADER_LEFT
\pszHeader=0
\cchHeader=0
If GroupIDs()& #ListIconGroups_Collapsible : \state | #LVGS_COLLAPSIBLE : EndIf
If GroupIDs()& #ListIconGroups_Collapsed : \state | #LVGS_COLLAPSED : EndIf
If GroupIDs()& #ListIconGroups_Hidden : \state | #LVGS_HIDDEN : EndIf
CompilerIf #PB_Compiler_Unicode = 0
Protected groupNameUNICODE$ = Space(260*2+2)
PokeS(@groupNameUNICODE$, groupName$, 260, #PB_Unicode)
\pszHeader = @groupNameUNICODE$
\cchHeader = Len(groupName$)
CompilerElse
\pszHeader = @groupName$
\cchHeader = Len(groupName$)
CompilerEndIf
If SendMessage_(*gadgetID, #LVM_HASGROUP, groupID, 0)
;\mask=#LVGF_GROUPID | #LVGF_STATE| #LVGF_ALIGN | #LVGF_HEADER
;\stateMask=#LVGS_COLLAPSIBLE|#LVGS_COLLAPSED|#LVGS_HIDDEN
;If SendMessage_(*gadgetID, #LVM_GETGROUPINFO, groupID, group)
; \mask=#LVGF_GROUPID | #LVGF_STATE| #LVGF_ALIGN | #LVGF_HEADER
; \stateMask=#LVGS_COLLAPSIBLE|#LVGS_COLLAPSED|#LVGS_HIDDEN
; \state=#LVGS_COLLAPSED
; Debug "x"+\pszHeader+" "+\cchHeader
; Debug SendMessage_(*gadgetID, #LVM_SETGROUPINFO, groupID, @group)
;EndIf
Else
SendMessage_(*gadgetID, #LVM_INSERTGROUP, -1, group)
EndIf
EndWith
Next
PopMapPosition(GroupIDs())
;returns TRUE if successful
ProcedureReturn #True
EndProcedure
Procedure.i GetListIconGroups(Gadget, Map GroupIDs(), Flags=#PB_Ignore)
Protected *params.LISTICON_PARAMS=InternalListIconParams(Gadget)
Protected *gadgetID=*params\GadgetID
Protected groupState, groupName$, groupID, group.LVGROUP1
If Flags<>#PB_Ignore
If Flags & #ListIconGroups_Collapsible : groupState | #LVGS_COLLAPSIBLE : EndIf
If Flags & #ListIconGroups_Collapsed : groupState | #LVGS_COLLAPSED : EndIf
If Flags & #ListIconGroups_Hidden : groupState | #LVGS_HIDDEN : EndIf
EndIf
ClearMap(GroupIDs())
PushMapPosition(*params\GroupIDs())
ForEach *params\GroupIDs()
With group
groupID=*params\GroupIDs()
\cbSize = SizeOf(LVGROUP1)
\mask = #LVGF_GROUPID | #LVGF_ALIGN | #LVGF_STATE | #LVGF_HEADER
\stateMask = #LVGS_COLLAPSIBLE|#LVGS_COLLAPSED|#LVGS_HIDDEN
\pszHeader=0
If SendMessage_(*gadgetID, #LVM_GETGROUPINFO, groupID, group)
If Flags=#PB_Ignore Or (\state & groupState)=groupState
CompilerIf #PB_Compiler_Unicode = 0
groupName$=PeekS(\pszHeader, 260, #PB_Unicode)
CompilerElse
groupName$=PeekS(\pszHeader)
CompilerEndIf
GroupIDs(groupName$)=groupID
If \state & #LVGS_COLLAPSIBLE : GroupIDs()| #ListIconGroups_Collapsible : EndIf
If \state & #LVGS_COLLAPSED : GroupIDs()| #ListIconGroups_Collapsed : EndIf
If \state & #LVGS_HIDDEN : GroupIDs()| #ListIconGroups_Hidden : EndIf
;Debug \uAlign
;Debug \state
EndIf
EndIf
EndWith
Next
PopMapPosition(*params\GroupIDs())
;returns GroupIDs according to state Flags (element map & count)
ProcedureReturn MapSize(GroupIDs())
EndProcedure
Procedure.i GetListIconGroupItems(Gadget, Array GroupItems(1), GroupID=#PB_All)
Protected *params.LISTICON_PARAMS=InternalListIconParams(Gadget)
Protected *gadgetID=*params\GadgetID
Protected itemPos, itemLast=CountGadgetItems(Gadget)-1, itemCount, item.LVITEM
If GroupID=#PB_All
itemCount=itemLast+1
ReDim GroupItems(itemLast)
For itemPos=0 To itemLast
With item
\mask=#LVIF_GROUPID
\iItem=itemPos
\iSubItem=0
If SendMessage_(*gadgetID, #LVM_GETITEM, 0, item)
GroupItems(itemPos)=\iGroupID
EndIf
EndWith
Next
;returns collection of GroupID per item position (element array & count)
ProcedureReturn itemCount
Else
GroupID & #ListIconGroupID_MaxValue
For itemPos=0 To itemLast
With item
\mask=#LVIF_GROUPID
\iItem=itemPos
\iSubItem=0
If SendMessage_(*gadgetID, #LVM_GETITEM, 0, item) And \iGroupID=GroupID
ReDim GroupItems(itemCount)
GroupItems(itemCount)=itemPos
itemCount+1
EndIf
EndWith
Next
;returns collection of Item Positions linked to GroupID (element array & count)
ProcedureReturn itemCount
EndIf
EndProcedure
Procedure SetListIconGroupItems(Gadget, Array GroupItems(1), GroupID=#PB_All)
Protected *params.LISTICON_PARAMS=InternalListIconParams(Gadget)
Protected *gadgetID=*params\GadgetID
Protected itemPos, itemIndex, itemLast=ArraySize(GroupItems()), item.LVITEM
If GroupID=#PB_All
For itemPos=0 To itemLast
With item
\mask=#LVIF_GROUPID | #LVIF_STATE
\iItem=itemPos
\iSubItem=0
If Not SendMessage_(*gadgetID, #LVM_GETITEM, 0, item)
ProcedureReturn #False
EndIf
\iGroupID=GroupItems(itemPos)& #ListIconGroupID_MaxValue
If Not SendMessage_(*gadgetID, #LVM_SETITEM, 0, item)
ProcedureReturn #False
EndIf
EndWith
Next
Else
GroupID & #ListIconGroupID_MaxValue
For itemIndex=0 To itemLast
With item
itemPos=GroupItems(itemIndex)
\mask=#LVIF_GROUPID | #LVIF_STATE
\iItem=itemPos
\iSubItem=0
If Not SendMessage_(*gadgetID, #LVM_GETITEM, 0, item)
ProcedureReturn #False
EndIf
\iGroupID=GroupID
If Not SendMessage_(*gadgetID, #LVM_SETITEM, 0, item)
ProcedureReturn #False
EndIf
EndWith
Next
EndIf
;returns TRUE if successful
ProcedureReturn #True
EndProcedure
Procedure.i SortListIconElements(ID1, ID2, *params.LISTICON_PARAMS)
With *params
If \IsSortingItems
;default method to sort items
ProcedureReturn 1
Else
;default method to sort groups
Protected name1$=\GroupName$(""+ID1)
Protected name2$=\GroupName$(""+ID2)
ProcedureReturn CompareMemoryString(@name1$, @name2$, #PB_String_NoCase)
EndIf
EndWith
EndProcedure
Procedure.i SortListIconGroups(Gadget, *SortFunction=0, *CustomData=0)
Protected *params.LISTICON_PARAMS=InternalListIconParams(Gadget)
With *params
\CustomData=*CustomData
\Gadget=Gadget
\IsSortingItems=#False
If *SortFunction=0 : *SortFunction=@SortListIconElements() : EndIf
ProcedureReturn SendMessage_(\gadgetID, #LVM_SORTGROUPS, *SortFunction, *params)
EndWith
EndProcedure
Procedure.i SortListIconGroupItems(Gadget, *SortFunction=0, *CustomData=0)
Protected *params.LISTICON_PARAMS=InternalListIconParams(Gadget)
With *params
\CustomData=*CustomData
\Gadget=Gadget
\IsSortingItems=#True
If *SortFunction=0 : *SortFunction=@SortListIconElements() : EndIf
ProcedureReturn SendMessage_(\gadgetID, #LVM_SORTITEMS, *params, *SortFunction)
EndWith
EndProcedure
Runtime Procedure InternalListIconCallback(Window, Message, wParam, lParam)
Protected *params.LISTICON_PARAMS=InternalListIconParams(GetDlgCtrlID_(Window))
With *params
Protected column, headerFlags, headerImageID, mouseButton
Protected code, *notify.NMHDR, *hdnotify.HD_NOTIFY, *column.LVCOLUMN
Select Message
;Case #LVM_ARRANGE
;Case #LVM_UPDATE
;Case #LVM_REDRAWITEMS
;Case #LVM_SETCOLUMNWIDTH, #LVM_SETCOLUMNWIDTHA, #LVM_SETCOLUMNWIDTHW
;Case #LVM_SETCOLUMN, #LVM_SETCOLUMNA, #LVM_SETCOLUMNW
Case #WM_NCDESTROY
SetWindowLongPtr_(\GadgetID, #GWL_WNDPROC, \OriginalCallback)
FreeMemory(*params)
Case #LVM_DELETECOLUMN
column=wParam
PushListPosition(\HeaderFlags())
SelectElement(\HeaderFlags(), column)
DeleteElement(\HeaderFlags())
PopListPosition(\HeaderFlags())
Case #LVM_INSERTCOLUMN, #LVM_INSERTCOLUMNA, #LVM_INSERTCOLUMNW
column=wParam
PushListPosition(\HeaderFlags())
SelectElement(\HeaderFlags(), column)
InsertElement(\HeaderFlags())
PopListPosition(\HeaderFlags())
Case #WM_PARENTNOTIFY
If wParam =#WM_RBUTTONDOWN
EndIf
Case #WM_NOTIFY
*notify=lParam
code=*notify\code
If *notify\hwndFrom=\ColHeader
*hdnotify=lParam
column=*hdnotify\Iitem
mouseButton=*hdnotify\iButton
Select code
Case #NM_RCLICK
Protected TestHit.HD_HITTESTINFO
TestHit\pt\x=DesktopMouseX()
TestHit\pt\y=DesktopMouseY()
ScreenToClient_(\ColHeader, TestHit\pt)
column = SendMessage_(\ColHeader, #HDM_HITTEST, 0, TestHit)
If column>=0
PostEvent(#PB_Event_Gadget, #PB_All, \Gadget, #PB_EventType_HeaderRightClick, column)
EndIf
Case #HDN_ITEMCHANGED, #HDN_ITEMCHANGEDW, #HDN_ITEMCHANGEDA
Case #HDN_BEGINDRAG
If column>=0 And GetListIconHeader(\Gadget, column)& #ListIconHeader_NoDrag
SetCapture_(0)
ProcedureReturn 1
EndIf
Case #HDN_BEGINTRACK, #HDN_BEGINTRACKA, #HDN_BEGINTRACKW
If column>=0 And GetListIconHeader(\Gadget, column)& #ListIconHeader_NoManualResize
ProcedureReturn 1
EndIf
Case #HDN_ENDDRAG
PostEvent(#PB_Event_Gadget, #PB_All, \Gadget, #PB_EventType_ReorderColumns, column)
Case #HDN_ITEMCLICK, #HDN_ITEMCLICKW, #HDN_ITEMCLICKA
PostEvent(#PB_Event_Gadget, #PB_All, \Gadget, #PB_EventType_HeaderLeftClick, column)
If \IsSortAuto
headerFlags=GetListIconHeader(\Gadget, column, @headerImageID)|#ListIconHeader_SortArrow_Changing
SetListIconHeader(\Gadget, column, headerFlags, headerImageID)
EndIf
EndSelect
EndIf
EndSelect
ProcedureReturn CallWindowProc_(\OriginalCallback, Window, Message, wParam, lParam)
EndWith
EndProcedure
; ********************************
; LISTICON FEATURES
; ********************************
DisableExplicit
CompilerIf #PB_Compiler_IsMainFile
If OpenWindow(100, 0, 0, 450, 400, "ListIcon Plus", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
headerIcon=CreateImage(#PB_Any, 16, 16, 32, $34F011)
itemIcon=CreateImage(#PB_Any, 16, 16, 32, $FE1110)
ButtonGadget(30, 10, 360, 100, 20, "Report")
ButtonGadget(31, 120, 360, 100, 20, "Large Icon")
ButtonGadget(32, 230, 360, 100, 20, "Small Icon")
CheckBoxGadget(33, 350, 360, 90, 20, "Group View")
SetGadgetState(33, #True)
If ListIconGadget(20, 5, 5, 440, 350, "No.", 60, PB_ListIcon_GridLines|
#PB_ListIcon_CheckBoxes|
#PB_ListIcon_HeaderDragDrop|
#PB_ListIcon_FullRowSelect|
#PB_ListIcon_AlwaysShowSelection)
AddGadgetColumn(20, 1, "item", 100)
AddGadgetColumn(20, 2, "price", 70)
AddGadgetColumn(20, 3, "count", 70)
AddGadgetItem(20, -1, "1."+#LF$+"coffee"+#LF$+"100$"+#LF$+"1"+#LF$)
AddGadgetItem(20, -1, "2."+#LF$+"sugar"+#LF$+"200$"+#LF$+"100"+#LF$)
AddGadgetItem(20, -1, "3."+#LF$+"banana"+#LF$+"200$"+#LF$+"2"+#LF$)
AddGadgetItem(20, -1, "4."+#LF$+"choco"+#LF$+"20$"+#LF$+"2"+#LF$)
AddGadgetItem(20, -1, "5."+#LF$+"big box"+#LF$+"NA"+#LF$+"NA"+#LF$, ImageID(itemIcon))
AddGadgetItem(20, -1, "6."+#LF$+"big box"+#LF$+"NA"+#LF$+"NA"+#LF$, ImageID(itemIcon))
AddGadgetItem(20, -1, "7."+#LF$+"big box"+#LF$+"NA"+#LF$+"NA"+#LF$, ImageID(itemIcon))
AddGadgetItem(20, -1, "8."+#LF$+"big box"+#LF$+"NA"+#LF$+"NA"+#LF$, ImageID(itemIcon))
SetGadgetItemColor(20, 1, #PB_Gadget_BackColor, RGB(241, 211, 72))
SetGadgetItemState(20, 0, #True)
;set listicon header options
SetListIconHeader(20, 0, #ListIconHeader_RightIcon, ImageID(headerIcon))
SetListIconHeader(20, 1, #ListIconHeader_SortArrow_Down)
SetListIconHeader(20, 2, #ListIconHeader_LeftIcon, ImageID(headerIcon))
SetListIconHeader(20, 3, #ListIconHeader_SortArrow_Up)
;get listicon header options
headerFlags=GetListIconHeader(20, 2, @headerImageID)
If headerFlags=#ListIconHeader_LeftIcon
Debug "Retrieve header Flags: OK"
EndIf
If headerImageID=ImageID(headerIcon)
Debug "Retrieve header ImageID: OK"
EndIf
StartDrawing(ImageOutput(headerIcon))
Box(2, 2, 11, 11, RGB(11, 111, 78))
DrawImage(headerImageID, 3, 3)
StopDrawing()
;get column order
Debug "Columns="+CountListIconColumns(20)
Dim columnOrder(0)
GetListIconColumnOrder(20, columnOrder())
;set column order
Swap columnOrder(2), columnOrder(3)
SetListIconColumnOrder(20, columnOrder())
;enable group view mode
Debug "GroupView is enabled="+GetListIconAttribute(20, #ListIconAttribute_GroupView)
Debug "GroupView is enabled="+SetListIconAttribute(20, #ListIconAttribute_GroupView, #True)
;define all groups and sort all groups
NewMap groups()
groups("Other")=200 | #ListIconGroups_Collapsed
groups("Food")=100
groups("Unknown")=80
groups("B")=10
groups("C")=11
groups("Z")=5
SetListIconGroups(20, groups(), #ListIconGroups_Collapsible)
NewMap findGroups()
Debug "Collapsed Groups="+GetListIconGroups(20, findGroups(), #ListIconGroups_Collapsed)+" / "+CountListIconGroups(20)
;assign items to FOOD groups
Dim itemsToAssign(2)
itemsToAssign(0)=0
itemsToAssign(1)=1
itemsToAssign(2)=2
SetListIconGroupItems(20, itemsToAssign(), groups("Food"))
Debug "Items assigned To FOOD group="+GetListIconGroupItems(20, itemsToAssign(), groups("Food"))
;assign items to OTHER groups
ReDim itemsToAssign(0)
itemsToAssign(0)=4
SetListIconGroupItems(20, itemsToAssign(), groups("Other"))
Debug "Items assigned To OTHER group="+GetListIconGroupItems(20, itemsToAssign(), groups("Other"))
ReDim itemsToAssign(0)
itemsToAssign(0)=5
SetListIconGroupItems(20, itemsToAssign(), groups("B"))
ReDim itemsToAssign(0)
itemsToAssign(0)=6
SetListIconGroupItems(20, itemsToAssign(), groups("C"))
ReDim itemsToAssign(0)
itemsToAssign(0)=7
SetListIconGroupItems(20, itemsToAssign(), groups("Z"))
;sort all groups and items
SortListIconGroups(20)
SortListIconGroupItems(20)
Debug "AutoSort is enabled="+GetListIconAttribute(20, #ListIconAttribute_SortAuto)
Debug "AutoSort is enabled="+SetListIconAttribute(20, #ListIconAttribute_SortAuto, #True)
EndIf
Repeat
e=WaitWindowEvent()
g=EventGadget()
t=EventType()
w=EventWindow()
pos=GetGadgetState(20)
info=EventData()
If e=#PB_Event_Gadget
If g=30 : SetGadgetAttribute(20, #PB_ListIcon_DisplayMode, #PB_ListIcon_Report) : EndIf
If g=31 : SetGadgetAttribute(20, #PB_ListIcon_DisplayMode, #PB_ListIcon_LargeIcon) : EndIf
If g=32 : SetGadgetAttribute(20, #PB_ListIcon_DisplayMode, #PB_ListIcon_SmallIcon) : EndIf
If g=33 And t=#PB_EventType_LeftClick
Debug "GroupView is enabled="+SetListIconAttribute(20, #ListIconAttribute_GroupView, GetGadgetState(33))
EndIf
If g=20
If t=#PB_EventType_Change
Debug "Selected item="+pos+" => "+GetGadgetItemText(20, pos, 0)+" "+GetGadgetItemText(20, pos, 1)
ElseIf t=#PB_EventType_LeftClick
Debug "Collapsed Groups="+GetListIconGroups(20, findGroups(), #ListIconGroups_Collapsed)+" / "+CountListIconGroups(20)
ElseIf t=#PB_EventType_HeaderLeftClick
Debug "Selected column="+info+" => "+GetGadgetItemText(20, -1, info)
ElseIf t=#PB_EventType_ReorderColumns
If EventData()=#PB_All
GetListIconColumnOrder(20, columnOrder())
For i=0 To ArraySize(columnOrder()) : order$+columnOrder(i)+", " : Next
Debug "Reordered column=ALL => order: "+order$
Else
Debug "Reordered column="+info+" => "+GetGadgetItemText(20, -1, info)
EndIf
EndIf
EndIf
EndIf
Until e=#PB_Event_CloseWindow
EndIf
CompilerEndIf