LIGEnhancements - ListIconGadget with Grouping and TileView

Share your advanced PureBasic knowledge/code with the community.
User avatar
jacdelad
Addict
Addict
Posts: 1432
Joined: Wed Feb 03, 2021 12:46 pm
Location: Planet Riesa
Contact:

LIGEnhancements - ListIconGadget with Grouping and TileView

Post by jacdelad »

In case someone needs it:

Code: Select all

;Compile with modern theme enabled!

Procedure ListIconGadget_(ID,x,y,dx,dy,spalte.s,sbreite,flags=0)
  Protected retval = ListIconGadget(ID, x, y, dx, dy, spalte.s, sbreite, flags) 
  If ID = #PB_Any : ID = retval : EndIf
  If flags & #PB_ListIcon_GridLines
    SendMessage_(GadgetID(ID),#LVM_SETEXTENDEDLISTVIEWSTYLE,#LVS_EX_GRIDLINES,#LVS_EX_GRIDLINES)
  EndIf 
  SendMessage_(GadgetID(ID),#LVM_SETEXTENDEDLISTVIEWSTYLE,#LVS_EX_DOUBLEBUFFER,#LVS_EX_DOUBLEBUFFER)
  ProcedureReturn retval
EndProcedure
Macro ListIconGadget(ID,x,y,dx,dy,spalte,sbreite,flags=0)
  ListIconGadget_(ID,x,y,dx,dy,spalte,sbreite,flags)
EndMacro
DeclareModule LIGEnhancements
  #ILC_PERITEMMIRROR    =  $8000
  #ILC_ORIGINALSIZE     = $10000
  #ILC_HIGHQUALITYSCALE = $20000
  
  #LVBKIF_FLAG_ALPHABLEND = $20000000
  #LVBKIF_FLAG_TILEOFFSET =      $100
  #LVBKIF_SOURCE_HBITMAP  =        $1
  #LVBKIF_SOURCE_MASK     =        $3
  #LVBKIF_SOURCE_NONE     =        $0
  #LVBKIF_SOURCE_URL      =        $2
  #LVBKIF_STYLE_NORMAL    =        $0
  #LVBKIF_STYLE_TILE      =       $10
  #LVBKIF_TYPE_WATERMARK  = $10000000
  
  #LVCF_DEFAULTWIDTH =  $80
  #LVCF_IDEALWIDTH   = $100
  #LVCF_MINWIDTH     =  $40
  
  #LVCFMT_FILL               =  $200000
  #LVCFMT_FIXED_WIDTH        =     $100
  #LVCFMT_FIXED_RATIO        =   $80000
  #LVCFMT_LINE_BREAK         =  $100000
  #LVCFMT_NO_DPI_SCALE       =   $40000
  #LVCFMT_NO_TITLE           =  $800000
  #LVCFMT_SPLITBUTTON        = $1000000
  #LVCFMT_TILE_PLACEMENTMASK =  $300000
  #LVCFMT_WRAP               =  $400000
  
  #LVFI_SUBSTRING = $4
  
  #LVFIF_STATE = $2
  #LVFIF_TEXT  = $1
  
  #LVFIS_FOCUSED = $1
  
  #LVGF_DESCRIPTIONBOTTOM =   $800
  #LVGF_DESCRIPTIONTOP    =   $400
  #LVGF_EXTENDEDIMAGE     =  $2000
  #LVGF_ITEMS             =  $4000
  #LVGF_SUBSET            =  $8000
  #LVGF_SUBSETITEMS       = $10000
  #LVGF_SUBTITLE          =   $100
  #LVGF_TASK              =   $200
  #LVGF_TITLEIMAGE        =  $1000
  
  #LVGS_FOCUSED           = $10
  #LVGS_NOHEADER          =  $4
  #LVGS_NORMAL            =  $0
  #LVGS_SELECTED          = $20
  #LVGS_SUBSETED          = $40
  #LVGS_SUBSETLINKFOCUSED = $80
  
  #LVHT_EX_FOOTER           =        $0
  #LVHT_EX_GROUP            = $FF000000
  #LVHT_EX_GROUP_BACKGROUND = $80000000
  #LVHT_EX_GROUP_COLLAPSE   = $40000000
  #LVHT_EX_GROUP_FOOTER     = $20000000
  #LVHT_EX_GROUP_HEADER     = $10000000
  #LVHT_EX_GROUP_STATEICON  =  $1000000
  #LVHT_EX_GROUP_SUBSETLINK =  $2000000
  #LVHT_EX_ONCONTENTS       =  $4000000
  
  #LVIF_COLFMT = $10000
  
  #LVIS_ACTIVATING = $20
  
  #LVS_EX_COLUMNOVERFLOW = $80000000
  
  #LVTVIF_AUTOSIZE    = $0
  #LVTVIF_EXTENDED    = $4
  #LVTVIF_FIXEDHEIGHT = $2
  #LVTVIF_FIXEDSIZE   = $3
  #LVTVIF_FIXEDWIDTH  = $1
  
  #LVTVIM_COLUMNS     = $2
  #LVTVIM_LABELMARGIN = $4
  #LVTVIM_TILESIZE    = $1
  
  Enumeration
    #PB_ListIcon_JustifyColumnLeft
    #PB_ListIcon_JustifyColumnCenter
    #PB_ListIcon_JustifyColumnRight
  EndEnumeration
  
  Enumeration
    #LIG_Title
    #LIG_SubTitle
    #LIG_Footer
  EndEnumeration
  Declare AddGroup(ListIconID.i,GroupID.i,Align.i,GroupText.s,GroupSubText.s,Footer.s,State.i)
  Declare EnableGroups(ListIconID.i,switch.b)
  Declare SetGroupText(ListIconID.i,GroupiID.i,GroupText.s,TextMode.a)
  Declare SetGroup(ListIconID.i,Item.i,GroupID.i)
  Declare GetGroup(ListIconID,Item)
  Declare AddGroupedItem(ListIconID.i,GroupID.i,ItemText.S)
  Declare SetHeaderFont(ListIconID.i,Font.i)
  Declare RemoveGroup(ListIconID.i,GroupID.i)
  Declare RemoveAllGroups(ListIconID.i)
  Declare FindItem(Gadget.i,item.s,flags);Flags:0=nichts,1=anwählen,2=sichtbar machen,3=beides
  Declare SetHeaderAlignment(Gadget.i,item.i,align);#LVCFMT_LEFT/#LVCFMT_CENTER/#LVCFMT_RIGHT
  Declare EnableTileView(Gadget.i,Columns.l,ColumnDefinition.s)
  Declare SetTile(Gadget.i,item.i)
  Declare DisableTileView(Gadget.i)
  Declare SetTileDefinition(Gadget.i,Columns.l,ColumnDefinition.s)
  Declare CreateImageList(Gadget.i,SizeX.l,SizeY.l)
  Declare SetImage(Gadget.i,Item.i,Column.i,ID.l)
  Declare ImageList_AddImage(Gadget.i,Image.i,ImageType.a=#False)
  Declare ImageList_DeleteImage(Gadget.i,ID.l)
  Declare SetListIconColumnJustification(ListIconID.i, Column.i, Alignment.i)
  Declare.s GetHeaderOrder(ListIconID.i)
  Declare SetHeaderOrder(ListIconID.i,Header.s)
  ;Declare ImageList_Destroy(Gadget.i);not needed due to not using the #LVS_SHAREIMAGELISTS-style!
EndDeclareModule

Module LIGEnhancements
  EnableExplicit
  Structure LVGROUPA Align #PB_Structure_AlignC
    cbSize.l
    mask.l
    *pszHeader
    cchHeader.l
    *pszFooter
    cchFooter.l
    iGroupId.l
    stateMask.l
    state.l
    uAlign.l
    *pszSubtitle
    cchSubtitle.l
    *pszTask
    cchTask.l
    *pszDescriptionTop
    cchDescriptionTop.l
    *pszDescriptionBottom
    cchDescriptionBottom.l
    iTitleImag.l
    iExtendedImage.l
    iFirstItem.l
    cItems.l
    *pszSubsetTitle
    cchSubsetTitle.l
  EndStructure
  Structure LVTILEVIEWINFO
    cbSize.l
    dwMask.l
    dwFlags.l
    sizeTile.SIZE
    cLines.l
    rcLabelMargins.RECT
  EndStructure
  Structure LVTILEINFO
    cbSize.l
    iItem.l
    cColumns.i
    puColumns.i
    piColFmt.i
  EndStructure
  Structure TileView
    Gadget.i
    lvti.LVTILEINFO
    lvtvi.LVTILEVIEWINFO
    Tiles.i
  EndStructure
  Structure ImageList
    Handle.i
    X.l
    Y.l
    Size.l
  EndStructure
  Global NewMap TileViewMap.TileView(),NewMap ImageListMap.ImageList()
  Procedure.s GetHeaderOrder(ListIconID.i)
    Protected Counter.l,Col.l=GetGadgetAttribute(ListIconID.i,#PB_ListIcon_ColumnCount),*Header,Result.s
    If Col>0
      *Header=AllocateMemory(Col*4)
      SendMessage_(GadgetID(ListIconID),#LVM_GETCOLUMNORDERARRAY,Col,*Header)
      For Counter=0 To Col-1
        Result+Str(PeekL(*Header+Counter*4))+"|"
      Next
      FreeMemory(*Header)
      Result=Left(Result,Len(Result)-1)
    EndIf
    ProcedureReturn Result
  EndProcedure
  Procedure SetHeaderOrder(ListIconID.i,Header.s)
    Protected Counter.l,Col.l=GetGadgetAttribute(ListIconID.i,#PB_ListIcon_ColumnCount),*Header,Result.l
    If Col>0 And Col=CountString(Header,"|")+1
      *Header=AllocateMemory(Col*4)
      For Counter=0 To Col-1
        PokeL(*Header+Counter*4,Val(StringField(Header,Counter+1,"|")))
      Next
      Result=SendMessage_(GadgetID(ListIconID),#LVM_SETCOLUMNORDERARRAY,Col,*Header)
      FreeMemory(*Header)
    EndIf
    ProcedureReturn Result
  EndProcedure
  Procedure SetHeaderFont(ListIconID.i,Font.i);Font, not FontID!
    ProcedureReturn SendMessage_(SendMessage_(GadgetID(ListIconID),#LVM_GETHEADER,0,0),#WM_SETFONT,FontID(Font),0)
  EndProcedure
  Procedure SetListIconColumnJustification(ListIconID.I, Column.I, Alignment.I)
    CompilerSelect #PB_Compiler_OS
      CompilerCase #PB_OS_Linux
        Protected AlignmentFactor.F
        Protected *CellRenderers
        Protected *Column
        Protected Count.I
        Protected i.I
        
        Select Alignment
          Case #PB_ListIcon_JustifyColumnLeft
            AlignmentFactor = 0.0
          Case #PB_ListIcon_JustifyColumnCenter
            AlignmentFactor = 0.5
          Case #PB_ListIcon_JustifyColumnRight
            AlignmentFactor = 1.0
        EndSelect
        
        *Column = gtk_tree_view_get_column_(GadgetID(ListIconID), Column)
        
        If *Column
          gtk_tree_view_column_set_alignment(*Column, AlignmentFactor)
          *CellRenderers = gtk_cell_layout_get_cells(*Column)
          
          If *CellRenderers
            Count = g_list_length_(*CellRenderers)
            
            For i = 0 To Count - 1
              g_object_set_double(g_list_nth_data_(*CellRenderers, i), "xalign",
                                  AlignmentFactor, #Null)
            Next i         
            
            g_list_free_(*CellRenderers)
          EndIf
        EndIf
      CompilerCase #PB_OS_MacOS
        Protected ColumnHeaderCell.I
        Protected ColumnObject.I
        Protected ColumnObjectArray.I
        
        Select Alignment
          Case #PB_ListIcon_JustifyColumnLeft
            Alignment = #NSLeftTextAlignment
          Case #PB_ListIcon_JustifyColumnCenter
            Alignment = #NSCenterTextAlignment
          Case #PB_ListIcon_JustifyColumnRight
            Alignment = #NSRightTextAlignment
        EndSelect
        
        ; ----- Justify text of column cells
        CocoaMessage(@ColumnObjectArray, GadgetID(ListIconID), "tableColumns")
        CocoaMessage(@ColumnObject, ColumnObjectArray, "objectAtIndex:", Column)
        CocoaMessage(0, CocoaMessage(0, ColumnObject, "dataCell"), "setAlignment:", Alignment)
        
        ; ----- Justify text of column header
        CocoaMessage(@ColumnHeaderCell, ColumnObject, "headerCell")
        CocoaMessage(0, ColumnHeaderCell, "setAlignment:", Alignment)
        
        ; ----- Redraw ListIcon contents to see change
        CocoaMessage(0, GadgetID(ListIconID), "reloadData")
      CompilerCase #PB_OS_Windows
        Protected ListIconColumn.LV_COLUMN
        
        ListIconColumn\mask = #LVCF_FMT
        
        Select Alignment
          Case #PB_ListIcon_JustifyColumnLeft
            ListIconColumn\fmt = #LVCFMT_LEFT
          Case #PB_ListIcon_JustifyColumnCenter
            ListIconColumn\fmt = #LVCFMT_CENTER
          Case #PB_ListIcon_JustifyColumnRight
            ListIconColumn\fmt = #LVCFMT_RIGHT
        EndSelect
        
        SendMessage_(GadgetID(ListIconID), #LVM_SETCOLUMN, Column, @ListIconColumn)
    CompilerEndSelect
  EndProcedure
  Procedure EnableGroups(ListIconID.i,switch.b)
    If switch
      ProcedureReturn SendMessage_(GadgetID(ListIconID),#LVM_ENABLEGROUPVIEW,#True,0)
    Else
      ProcedureReturn SendMessage_(GadgetID(ListIconID),#LVM_ENABLEGROUPVIEW,#False,0)
    EndIf
  EndProcedure
  Procedure AddGroup(ListIconID.i,GroupID.i,Align.i,GroupText.s,GroupSubText.s,Footer.s,State.i)
    Protected Group.LVGROUPA,UnicodeText.S,UnicodeSubtext.S,UnicodeFooter.S,Flags.i
    Group\cbSize = SizeOf(LVGROUPA)
    Flags=#LVGF_GROUPID | #LVGF_ALIGN
    If GroupText
      flags=flags|#LVGF_HEADER
      UnicodeText = Space(255)
      PokeS(@UnicodeText,GroupText,-1,#PB_Unicode)
      Group\pszHeader = @UnicodeText
    EndIf
    If GroupSubText
      flags=flags|#LVGF_SUBTITLE
      UnicodeSubtext = Space(255)
      PokeS(@UnicodesubText,GroupSubText,-1,#PB_Unicode)
      Group\pszSubtitle = @UnicodeSubtext
    EndIf
    If Footer
      flags=flags|#LVGF_FOOTER
      UnicodeFooter = Space(255)
      PokeS(@UnicodeFooter,Footer,-1,#PB_Unicode)
      Group\pszFooter = @UnicodeFooter
    EndIf
    If align
      Group\uAlign = Align;#LVGA_HEADER_CENTER,#LVGA_HEADER_LEFT,#LVGA_HEADER_RIGHT
    Else
      Group\uAlign = #LVGA_HEADER_CENTER
    EndIf
    Group\iGroupId = GroupID
    If state
      Group\stateMask = State
      Group\state = State
      flags=flags | #LVGF_STATE
    EndIf
    Group\mask = Flags
    ProcedureReturn SendMessage_(GadgetID(ListIconID),#LVM_INSERTGROUP,-1,@Group)
  EndProcedure
  Procedure SetGroupText(ListIconID.i,GroupID.i,GroupText.s,TextMode.a);Textmode -> #LIG_Title, #LIG_SubTitle or #LIG_Footer
    Protected Group.LVGROUPA,unicode.s=Space(255)
    Group\cbSize=SizeOf(LVGROUPA)
    Group\iGroupId=groupid
    PokeS(@unicode,grouptext,-1,#PB_Unicode)
    Select TextMode
      Case #LIG_Title
        group\mask=#LVGF_HEADER
        Group\pszHeader = @Unicode
      Case #LIG_SubTitle
        group\mask=#LVGF_SUBTITLE
        Group\pszSubtitle = @Unicode
      Case #LIG_Footer
        group\mask=#LVGF_FOOTER
        Group\pszFooter = @Unicode
    EndSelect
    ProcedureReturn SendMessage_(GadgetID(ListIconID),#LVM_SETGROUPINFO,groupid,@Group)
  EndProcedure
  Procedure SetGroup(ListIconID.i,Item.i,GroupID.i)
    Protected MyItem.LVITEM
    MyItem\iItem=Item
    MyItem\iGroupId=GroupID
    MyItem\mask=#LVIF_GROUPID
    ProcedureReturn SendMessage_(GadgetID(ListIconID),#LVM_SETITEM,0,@MyItem)
  EndProcedure
  Procedure GetGroup(ListIconID,Item.i)
    Protected MyItem.LVITEM
    MyItem\iItem=Item
    MyItem\mask=#LVIF_GROUPID
    SendMessage_(GadgetID(ListIconID),#LVM_GETITEM,0,@MyItem)
    ProcedureReturn MyItem\iGroupId
  EndProcedure
  Procedure AddGroupedItem(ListIconID.i,GroupID.i,ItemText.S)
    Protected Item.LVITEM
    Item\mask = #LVIF_TEXT | #LVIF_GROUPID
    Item\pszText = @ItemText
    Item\iGroupId = GroupID
    SendMessage_(GadgetID(ListIconID),#LVM_INSERTITEM,0,@Item)
  EndProcedure
  Procedure RemoveGroup(ListIconID.i,GroupID.i)
    SendMessage_(GadgetID(ListIconID),#LVM_REMOVEGROUP,GroupID,0)
  EndProcedure
  Procedure RemoveAllGroups(ListIconID.i)
    SendMessage_(GadgetID(ListIconID),#LVM_REMOVEALLGROUPS,0,0)
  EndProcedure
  Procedure FindItem(Gadget.i,item.s,flags);Flags:0=nothing,1=select,2=make visible,3=both
    Protected LIFI.LVFINDINFO,index
    LIFI\flags=#LVFI_STRING
    LIFI\psz=@item
    Index=SendMessage_(GadgetID(Gadget),#LVM_FINDITEM,-1,@LIFI)
    Select flags
      Case 1
        SetGadgetState(Gadget,index)
      Case 2
        SendMessage_(GadgetID(Gadget),#LVM_ENSUREVISIBLE,index,0)
      Case 3
        SetGadgetState(Gadget,index)
        SendMessage_(GadgetID(Gadget),#LVM_ENSUREVISIBLE,index,0)
    EndSelect
  EndProcedure
  Procedure SetHeaderAlignment(Gadget.i,item.i,align)
    Protected ListViewSpalte.LV_COLUMN
    ListViewSpalte\mask = #LVCF_FMT
    ListViewSpalte\fmt = align;#LVCFMT_RIGHT
    SendMessage_(GadgetID(Gadget),#LVM_SETCOLUMN,item,@ListViewSpalte)
  EndProcedure
  Procedure EnableTileView(Gadget.i,Columns.l,ColumnDefinition.s);Columns=visible Extra Columns, ColumnDefinition=Definition for extra columns separated by "," (e.g. "1,3,2")
    If SendMessage_(GadgetID(Gadget),#LVM_SETVIEW,#LV_VIEW_TILE,0)>0
      Protected handle.s=Str(Gadget),count.b
      TileViewMap(handle)\lvtvi\cbSize=SizeOf(LVTILEVIEWINFO)
      TileViewMap(handle)\lvtvi\cLines=Columns;Anzahl Extra-Zeilen
      TileViewMap(handle)\lvtvi\dwMask=#LVTVIM_COLUMNS
      SendMessage_(GadgetID(Gadget),#LVM_SETTILEVIEWINFO,0,@TileViewMap(handle)\lvtvi)
      SendMessage_(GadgetID(Gadget),#LVM_ARRANGE,0,0)
      TileViewMap(handle)\Gadget=Gadget
      TileViewMap(handle)\lvti\cbSize=SizeOf(LVTILEINFO)
      TileViewMap(handle)\Tiles=AllocateMemory(Columns*4,#PB_Memory_NoClear)
      For count=0 To Columns-1
        PokeL(TileViewMap(handle)\Tiles+count*4,Val(StringField(ColumnDefinition,count+1,",")))
      Next
      TileViewMap(handle)\lvti\cColumns=Columns
      TileViewMap(handle)\lvti\puColumns=TileViewMap(handle)\Tiles
      ProcedureReturn 1
    Else
      ProcedureReturn 0
    EndIf
  EndProcedure
  Procedure SetTileDefinition(Gadget.i,Columns.l,ColumnDefinition.s);Columns=visible Extra Columns, ColumnDefinition=Definition for extra columns separated by "," (e.g. "1,3,2")
    Protected handle.s=Str(Gadget),count.b
    TileViewMap(handle)\lvtvi\cLines=Columns;Anzahl Extra-Zeilen
    SendMessage_(GadgetID(Gadget),#LVM_SETTILEVIEWINFO,0,@TileViewMap(handle)\lvtvi)
    SendMessage_(GadgetID(Gadget),#LVM_ARRANGE,0,0)
    FreeMemory(TileViewMap(handle)\Tiles)
    TileViewMap(handle)\Tiles=AllocateMemory(Columns*4,#PB_Memory_NoClear)
    For count=0 To Columns-1
      PokeL(TileViewMap(handle)\Tiles+count*4,Val(StringField(ColumnDefinition,count+1,",")))
    Next
    TileViewMap(handle)\lvti\cColumns=Columns
    TileViewMap(handle)\lvti\puColumns=TileViewMap(handle)\Tiles
  EndProcedure
  Procedure SetTile(Gadget.i,item.i);Apply defined scheme to tile
    Protected handle.s=Str(Gadget)
    TileViewMap(handle)\lvti\iItem=item
    ProcedureReturn SendMessage_(GadgetID(TileViewMap(handle)\Gadget),#LVM_SETTILEINFO,0,@TileViewMap(handle)\lvti)
  EndProcedure
  Procedure DisableTileView(Gadget.i);Call AFTER destroying ListIconGadget or setting other view
    Protected handle.s=Str(Gadget)
    If FindMapElement(TileViewMap(),handle)
      FreeMemory(TileViewMap(handle)\Tiles)
      DeleteMapElement(TileViewMap(),handle)
    EndIf
  EndProcedure
  Procedure CreateImageList(Gadget.i,SizeX.l,SizeY.l)
    Protected handle.s=Str(Gadget)
    ImageListMap(handle)\Handle=ImageList_Create_(SizeX,SizeY,#ILC_COLOR32,0,0)
    ProcedureReturn SendMessage_(GadgetID(Gadget),#LVM_SETIMAGELIST,0,ImageListMap(handle)\Handle)
  EndProcedure
  Procedure ImageList_AddImage(Gadget.i,Image.i,ImageType.a=#False)
    Protected *IL.ImageList=@ImageListMap(Str(Gadget))
    If ImageType
      ProcedureReturn ImageList_Add_(*IL\Handle,Image,0)
    Else
      If ImageWidth(Image)=*IL\X And ImageHeight(Image)=*IL\Y
        ProcedureReturn ImageList_Add_(*IL\Handle,ImageID(Image),0)
      Else
        Protected TempImage.i=CopyImage(Image,#PB_Any),Result.l
        ResizeImage(TempImage,*IL\X,*IL\Y,#PB_Image_Smooth)
        Result=ImageList_Add_(*IL\Handle,ImageID(TempImage),0)
        FreeImage(TempImage)
        ProcedureReturn Result
      EndIf
    EndIf
  EndProcedure
  Procedure ImageList_DeleteImage(Gadget.i,ID.l)
    ProcedureReturn ImageList_Remove_(ImageListMap(Str(Gadget))\Handle,ID)
  EndProcedure
  Procedure ImageList_Destroy(Gadget.i)
    SendMessage_(GadgetID(Gadget),#LVM_SETIMAGELIST,0,0)
    ProcedureReturn ImageList_Destroy_(ImageListMap(Str(Gadget))\Handle)
  EndProcedure
  Procedure SetImage(Gadget.i,Item.i,Column.i,ID.l)
    Protected LVI.LVITEM
    LVI\iItem=Item
    LVI\iSubItem=Column
    LVI\iImage=ID
    LVI\mask=#LVIF_IMAGE
    ProcedureReturn SendMessage_(GadgetID(Gadget),#LVM_SETITEM,0,LVI)
  EndProcedure
EndModule

CompilerIf #PB_Compiler_IsMainFile
  DisableExplicit
  Define tempcounter,icon
  
  ;Window with Grouped items:
  OpenWindow(0,0,200,600,400,"LIGEnhancements",#PB_Window_SystemMenu)
  id=ListIconGadget(#PB_Any,0,0,600,400,"First Column",200,#PB_ListIcon_FullRowSelect|#PB_ListIcon_GridLines)
  AddGadgetColumn(id,1,"Second column",200)
  LIGEnhancements::EnableGroups(id,1)
  For tempcounter=1 To 10
    LIGEnhancements::AddGroup(id,tempcounter,#LVGA_HEADER_CENTER,"Group No. "+Str(tempcounter),"Cool subtext","Footer text",#LVGS_COLLAPSIBLE)
  Next
  For tempcounter=1 To 100
    AddGadgetItem(id,-1,"Item No. "+Chr(10)+Str(tempcounter))
    LIGEnhancements::SetGroup(id,tempcounter-1,1+tempcounter/10)
  Next
  
  ;Window with TileView-ListIconGadget:
  OpenWindow(1,605,200,640,400,"LIGEnhancements",#PB_Window_SystemMenu)
  id=ListIconGadget(#PB_Any,0,0,640,400,"First Column",200,#PB_ListIcon_FullRowSelect)
  AddGadgetColumn(id,1,"Second column",200)
  LIGEnhancements::EnableTileView(id,1,"1")
  LIGEnhancements::CreateImageList(id,25,50)
  icon=LoadIcon_(0,32518)
  LIGEnhancements::ImageList_AddImage(id,icon,#True)
  For tempcounter=1 To 100
    AddGadgetItem(id,-1,"Item No. "+Chr(10)+Str(tempcounter),icon)
    LIGEnhancements::SetImage(id,tempcounter-1,0,0)
    LIGEnhancements::SetTile(id,tempcounter-1)
  Next
  
  Repeat
    Select WaitWindowEvent()
      Case #PB_Event_CloseWindow
        Break
    EndSelect
  ForEver
  FreeGadget(id)
  LIGEnhancements::DisableTileView(0)
CompilerEndIf
  • Grouping
  • TileView
  • "Autofix" for incorrect gridlines
  • Search-and-Select function
Windows Vista+ only, compile with modern themes enabled (or apply appropriate manifest).
Sorry for the crappy demo and bad coding habits...

Update 15.12.2023: Two new functions for getting and setting the column order (useful for #PB_ListIcon_HeaderDragDrop; return/input as string) and some minor improvements.
Update 15.02.2024: Bugfix for a stupid bug reported by Axolotl, Denis and Mindphazer. See thread for more info, if needed.
Last edited by jacdelad on Thu Feb 15, 2024 4:35 pm, edited 3 times in total.
PureBasic 6.04/XProfan X4a/Embarcadero RAD Studio 11/Perl 5.2/Python 3.10
Windows 11/Ryzen 5800X/32GB RAM/Radeon 7770 OC/3TB SSD/11TB HDD
Synology DS1821+/36GB RAM/130TB
Synology DS920+/20GB RAM/54TB
Synology DS916+ii/8GB RAM/12TB
BarryG
Addict
Addict
Posts: 3292
Joined: Thu Apr 18, 2019 8:17 am

Re: LIGEnhancements - ListIconGadget with Grouping and TileView

Post by BarryG »

I like the grouping support! Thanks so much, jacdelad!
dige
Addict
Addict
Posts: 1247
Joined: Wed Apr 30, 2003 8:15 am
Location: Germany
Contact:

Re: LIGEnhancements - ListIconGadget with Grouping and TileView

Post by dige »

Well done und very handy! Thx jacdlad
"Daddy, I'll run faster, then it is not so far..."
User avatar
Kwai chang caine
Always Here
Always Here
Posts: 5342
Joined: Sun Nov 05, 2006 11:42 pm
Location: Lyon - France

Re: LIGEnhancements - ListIconGadget with Grouping and TileView

Post by Kwai chang caine »

Usefull idea, works nice here :wink:
Thanks for sharing 8)
ImageThe happiness is a road...
Not a destination
User avatar
jacdelad
Addict
Addict
Posts: 1432
Joined: Wed Feb 03, 2021 12:46 pm
Location: Planet Riesa
Contact:

Re: LIGEnhancements - ListIconGadget with Grouping and TileView

Post by jacdelad »

Thanks. I'll try to improve it when I have time, there's still plenty of useful APIs out there.
PureBasic 6.04/XProfan X4a/Embarcadero RAD Studio 11/Perl 5.2/Python 3.10
Windows 11/Ryzen 5800X/32GB RAM/Radeon 7770 OC/3TB SSD/11TB HDD
Synology DS1821+/36GB RAM/130TB
Synology DS920+/20GB RAM/54TB
Synology DS916+ii/8GB RAM/12TB
User avatar
jacdelad
Addict
Addict
Posts: 1432
Joined: Wed Feb 03, 2021 12:46 pm
Location: Planet Riesa
Contact:

Re: LIGEnhancements - ListIconGadget with Grouping and TileView

Post by jacdelad »

I have some kind of blackout, maybe someone can help me. I wanted to add the option to change the tilesize. This isn't hard or anything, but I can't successfully set the tilesize in the LVTILEVIEWINFO structure. Can someone help me? I have to put it into the LVTILEVIEWINFO.sizeTile-field which is defined as "SIZE". Now, I tried with poking the value to it and its address+4 and also with an extra array (but I can't set the address of the array, because "SIZE" is structured).
PureBasic 6.04/XProfan X4a/Embarcadero RAD Studio 11/Perl 5.2/Python 3.10
Windows 11/Ryzen 5800X/32GB RAM/Radeon 7770 OC/3TB SSD/11TB HDD
Synology DS1821+/36GB RAM/130TB
Synology DS920+/20GB RAM/54TB
Synology DS916+ii/8GB RAM/12TB
User avatar
spikey
Enthusiast
Enthusiast
Posts: 581
Joined: Wed Sep 22, 2010 1:17 pm
Location: United Kingdom

Re: LIGEnhancements - ListIconGadget with Grouping and TileView

Post by spikey »

Nice features to add!
jacdelad wrote: Mon Jan 23, 2023 12:15 pm I can't successfully set the tilesize in the LVTILEVIEWINFO structure.
If I've read the documentation correctly, it isn't a one size per tile parameter but a one size fits all parameter.
You need to set #LVTVIM_TILESIZE in dwMask and #LVTVIF_FIXEDSIZE or #LVTVIF_FIXEDWIDTH or #LVTVIF_FIXEDHEIGHT in dwFlags, then you can set the cx and cy members in sizeTile directly. Something like this, which will set a 200 x 200 tile:

Code: Select all

Procedure EnableTileView(Gadget.i,Columns.l,ColumnDefinition.s);Columns=visible Extra Columns, ColumnDefinition=Definition for extra columns separated by "," (e.g. "1,3,2")
  If SendMessage_(GadgetID(Gadget),#LVM_SETVIEW,#LV_VIEW_TILE,0)>0
    Protected handle.s=Str(Gadget),count.b
    TileViewMap(handle)\lvtvi\cbSize=SizeOf(LVTILEVIEWINFO)
    TileViewMap(handle)\lvtvi\dwMask = #LVTVIM_COLUMNS | #LVTVIM_TILESIZE ;*
    TileViewMap(handle)\lvtvi\dwFlags = #LVTVIF_FIXEDSIZE ;*
    TileViewMap(handle)\lvtvi\cLines=Columns;Anzahl Extra-Zeilen
    TileViewMap(Handle)\lvtvi\sizeTile\cx = 200 ;*
    TileViewMap(Handle)\lvtvi\sizeTile\cy = 200 ;*
    SendMessage_(GadgetID(Gadget),#LVM_SETTILEVIEWINFO,0,@TileViewMap(handle)\lvtvi)
    SendMessage_(GadgetID(Gadget),#LVM_ARRANGE,0,0)
    TileViewMap(handle)\Gadget=Gadget
    TileViewMap(handle)\lvti\cbSize=SizeOf(LVTILEINFO)
    TileViewMap(handle)\Tiles=AllocateMemory(Columns*4,#PB_Memory_NoClear)
    For count=0 To Columns-1
      PokeL(TileViewMap(handle)\Tiles+count*4,Val(StringField(ColumnDefinition,count+1,",")))
    Next
    TileViewMap(handle)\lvti\cColumns=Columns
    TileViewMap(handle)\lvti\puColumns=TileViewMap(handle)\Tiles
    ProcedureReturn 1
  Else
    ProcedureReturn 0
  EndIf
EndProcedure
User avatar
jacdelad
Addict
Addict
Posts: 1432
Joined: Wed Feb 03, 2021 12:46 pm
Location: Planet Riesa
Contact:

Re: LIGEnhancements - ListIconGadget with Grouping and TileView

Post by jacdelad »

Ah thanks spikey, now I got it. I just didn't use the members of the TileSize correctly (plus the missing FixedSize). Your code works.
Anyway, that was completely not what I wanted. :oops: My fault, I initally wanted to change the size of the images, not the tiles (and went an absolute wrong way)...
PureBasic 6.04/XProfan X4a/Embarcadero RAD Studio 11/Perl 5.2/Python 3.10
Windows 11/Ryzen 5800X/32GB RAM/Radeon 7770 OC/3TB SSD/11TB HDD
Synology DS1821+/36GB RAM/130TB
Synology DS920+/20GB RAM/54TB
Synology DS916+ii/8GB RAM/12TB
User avatar
spikey
Enthusiast
Enthusiast
Posts: 581
Joined: Wed Sep 22, 2010 1:17 pm
Location: United Kingdom

Re: LIGEnhancements - ListIconGadget with Grouping and TileView

Post by spikey »

jacdelad wrote: Mon Jan 23, 2023 1:21 pm I initally wanted to change the size of the images, not the tiles
:D I think you'd need custom image lists for that.
User avatar
jacdelad
Addict
Addict
Posts: 1432
Joined: Wed Feb 03, 2021 12:46 pm
Location: Planet Riesa
Contact:

Re: LIGEnhancements - ListIconGadget with Grouping and TileView

Post by jacdelad »

Yeah, seems so. I know how to work with them, just need a bit time. Will post it, when it's done.
PureBasic 6.04/XProfan X4a/Embarcadero RAD Studio 11/Perl 5.2/Python 3.10
Windows 11/Ryzen 5800X/32GB RAM/Radeon 7770 OC/3TB SSD/11TB HDD
Synology DS1821+/36GB RAM/130TB
Synology DS920+/20GB RAM/54TB
Synology DS916+ii/8GB RAM/12TB
User avatar
jacdelad
Addict
Addict
Posts: 1432
Joined: Wed Feb 03, 2021 12:46 pm
Location: Planet Riesa
Contact:

Re: LIGEnhancements - ListIconGadget with Grouping and TileView

Post by jacdelad »

Got it to work and will post the updated module when I'm done. Again, thanks spikey!!!
PureBasic 6.04/XProfan X4a/Embarcadero RAD Studio 11/Perl 5.2/Python 3.10
Windows 11/Ryzen 5800X/32GB RAM/Radeon 7770 OC/3TB SSD/11TB HDD
Synology DS1821+/36GB RAM/130TB
Synology DS920+/20GB RAM/54TB
Synology DS916+ii/8GB RAM/12TB
User avatar
idle
Always Here
Always Here
Posts: 5042
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: LIGEnhancements - ListIconGadget with Grouping and TileView

Post by idle »

looks very good thanks Jac
Axolotl
Enthusiast
Enthusiast
Posts: 435
Joined: Wed Dec 31, 2008 3:36 pm

Re: LIGEnhancements - ListIconGadget with Grouping and TileView

Post by Axolotl »

Nice stuff Jacdelad, I could see the beauty after change this function a bit.

Code: Select all

Procedure ListIconGadget_(ID,x,y,dx,dy,spalte.s,sbreite,flags=0)
  Protected retval 

  retval = ListIconGadget(ID, x, y, dx, dy, spalte.s, sbreite, flags) 
  If ID = #PB_Any : ID = retval : EndIf       ; .... now we can use GadgetID(ID) always 

  If flags & #PB_ListIcon_GridLines
;     If ID = #PB_Any 
;       SendMessage_(GadgetID(retval),#LVM_SETEXTENDEDLISTVIEWSTYLE,#LVS_EX_GRIDLINES,#LVS_EX_GRIDLINES)
;     Else 
    SendMessage_(GadgetID(ID),#LVM_SETEXTENDEDLISTVIEWSTYLE,#LVS_EX_GRIDLINES,#LVS_EX_GRIDLINES)
;     EndIf
  EndIf 
  ; without my changes the next function crashed because ID is #PB_Any (-1) 
  SendMessage_(GadgetID(ID),#LVM_SETEXTENDEDLISTVIEWSTYLE,#LVS_EX_DOUBLEBUFFER,#LVS_EX_DOUBLEBUFFER)
  ProcedureReturn retval
EndProcedure
Mostly running PureBasic <latest stable version and current alpha/beta> (x64) on Windows 11 Home
User avatar
jacdelad
Addict
Addict
Posts: 1432
Joined: Wed Feb 03, 2021 12:46 pm
Location: Planet Riesa
Contact:

Re: LIGEnhancements - ListIconGadget with Grouping and TileView

Post by jacdelad »

No problem, everything that makes the code better, is welcome. And there's surely still a lot Windows APIs to add.
PureBasic 6.04/XProfan X4a/Embarcadero RAD Studio 11/Perl 5.2/Python 3.10
Windows 11/Ryzen 5800X/32GB RAM/Radeon 7770 OC/3TB SSD/11TB HDD
Synology DS1821+/36GB RAM/130TB
Synology DS920+/20GB RAM/54TB
Synology DS916+ii/8GB RAM/12TB
Denis
Enthusiast
Enthusiast
Posts: 704
Joined: Fri Apr 25, 2003 5:10 pm
Location: Doubs - France

Re: LIGEnhancements - ListIconGadget with Grouping and TileView

Post by Denis »

Hi jacdelad,

I don't know if I'm the only one with a problem with your first code.

Windows 11 up to date
PB 6.10 beta 10 X64 or x86 ASM or C

It doesn't work, i get an error line 12 (The specified gadget is not initialised) :

Code: Select all

  SendMessage_(GadgetID(ID),#LVM_SETEXTENDEDLISTVIEWSTYLE,#LVS_EX_DOUBLEBUFFER,#LVS_EX_DOUBLEBUFFER)
With or without debugger, it's the same.
A+
Denis
Post Reply