ListIcon Sorting

Got an idea for enhancing PureBasic? New command(s) you'd like to see?
Num3
PureBasic Expert
PureBasic Expert
Posts: 2812
Joined: Fri Apr 25, 2003 4:51 pm
Location: Portugal, Lisbon
Contact:

ListIcon Sorting

Post by Num3 »

Would be nice to have some sort of built in procedure to attach a sorting routine when one clicks on the ListIcon Header...

Something like:

If event=#PB_ListIcon_HeaderClick
If EventType()=Column#x
ListIconSortProcedure(#List,@UserSortingProcedure)
endif
endif
User avatar
blueznl
PureBasic Expert
PureBasic Expert
Posts: 6166
Joined: Sat May 17, 2003 11:31 am
Contact:

Post by blueznl »

yep, i could use that...
( PB6.00 LTS Win11 x64 Asrock AB350 Pro4 Ryzen 5 3600 32GB GTX1060 6GB)
( The path to enlightenment and the PureBasic Survival Guide right here... )
Dare2
Moderator
Moderator
Posts: 3321
Joined: Sat Dec 27, 2003 3:55 am
Location: Great Southern Land

Post by Dare2 »

Agree.
@}--`--,-- A rose by any other name ..
naw
Enthusiast
Enthusiast
Posts: 573
Joined: Fri Apr 25, 2003 4:57 pm

Post by naw »

That would be nice for lots of gadgets - ComboBoxes / ListIconGadget / ListViewGadget.

I would like to have Sort(#Gid, PrimaryField, SecondaryField...)

Until then, I found this by Danilo

viewtopic.php?t=9113

I just about got it working with *different* Gadget IDs but I dont really understand the code...
Ta - N
Num3
PureBasic Expert
PureBasic Expert
Posts: 2812
Joined: Fri Apr 25, 2003 4:51 pm
Location: Portugal, Lisbon
Contact:

Post by Num3 »

naw wrote:That would be nice for lots of gadgets - ComboBoxes / ListIconGadget / ListViewGadget.

I would like to have Sort(#Gid, PrimaryField, SecondaryField...)

Until then, I found this by Danilo

viewtopic.php?t=9113

I just about got it working with *different* Gadget IDs but I dont really understand the code...
I've been using this code...

Shame it does not work for numbers :(
naw
Enthusiast
Enthusiast
Posts: 573
Joined: Fri Apr 25, 2003 4:57 pm

Post by naw »

Did you *adapt* it so that it works with other Gadget IDs. I tried, but - well- I just cant get those pesky arrows to display...

:-(
Ta - N
MrMat
Enthusiast
Enthusiast
Posts: 762
Joined: Sun Sep 05, 2004 6:27 am
Location: England

Post by MrMat »

Num3 wrote:Shame it does not work for numbers :(
Do you mean sorting by number instead of by the string? If so change change the two lines

Code: Select all

If A$ > B$
to

Code: Select all

If Val(A$) > Val(B$)
or ValF for floats and it should compare them as you want.

Add my vote for something like this to be built in, including adding the arrows to the column headers :D
Num3
PureBasic Expert
PureBasic Expert
Posts: 2812
Joined: Fri Apr 25, 2003 4:51 pm
Location: Portugal, Lisbon
Contact:

Post by Num3 »

MrMat wrote:
Num3 wrote:Shame it does not work for numbers :(
Do you mean sorting by number instead of by the string? If so change change the two lines

Code: Select all

If A$ > B$
to

Code: Select all

If Val(A$) > Val(B$)
or ValF for floats and it should compare them as you want.

Add my vote for something like this to be built in, including adding the arrows to the column headers :D
Man, you just solved me a 3 week problem!
I was using linked list to sort tables, now i can use the gadget itself for sorting!!!

Thanks!
naw
Enthusiast
Enthusiast
Posts: 573
Joined: Fri Apr 25, 2003 4:57 pm

Re: ListIcon Sorting

Post by naw »

Num3 wrote:Would be nice to have some sort of built in procedure to attach a sorting routine when one clicks on the ListIcon Header...

Something like:

If event=#PB_ListIcon_HeaderClick
If EventType()=Column#x
ListIconSortProcedure(#List,@UserSortingProcedure)
endif
endif
Better still, would be:

Code: Select all

ListIconGadget(0,0,0,500,200,"",0,#PB_Sortable)
Ta - N
RJP Computing
Enthusiast
Enthusiast
Posts: 202
Joined: Sun Apr 27, 2003 4:44 am
Location: Michigan, USA
Contact:

Post by RJP Computing »

Can we get a posting of the updated code. That would be very helpful.

Thanks
-Ryan
RJP Computing

Ubuntu 8.10/WinXP, AMD Athlon 64 3000+, 1000MB RAM, AC 97 Audio, nVidia GeForce 7600GT 512MB
User avatar
blueznl
PureBasic Expert
PureBasic Expert
Posts: 6166
Joined: Sat May 17, 2003 11:31 am
Contact:

Post by blueznl »

naw, yeah, we'd best have both, so programs can do a standard sort after filling the list, but allow the user to change the on screen display (by marking the columns as sortable that's solved :-))

arrows... oh, the little triangles... yes, of course :-)
( PB6.00 LTS Win11 x64 Asrock AB350 Pro4 Ryzen 5 3600 32GB GTX1060 6GB)
( The path to enlightenment and the PureBasic Survival Guide right here... )
MrMat
Enthusiast
Enthusiast
Posts: 762
Joined: Sun Sep 05, 2004 6:27 am
Location: England

Post by MrMat »

I've changed the sorting code so that it works equally well with strings and integers and modified the data in the columns to demonstrate this. It'll also intermix uppercase and lowercase strings so if you don't like that change ucasea.s = UCase(A$) and ucaseb.s = UCase(B$) to ucasea.s = A$ and ucaseb.s = B$. Best way to see is to try it:

Code: Select all

;
; ListIconGagdet column header images
; with image switching
;
; by Danilo, 11.01.2004
;
;
; credits:
;   - sort function from PureArea.net code archive,
;     file  : ListIcon_SortbyColumn.pb
;     writer: unknown
;
Procedure CreateListIconArrows(StartImage)
  ; by Danilo, 11.01.2004
  ;
  ; generate 2 small 16x16 arrows, up & down
  ;
  For img = 0 To 1
    CreateImage(StartImage+img,16,16)
    StartDrawing(ImageOutput())
    background = GetSysColor_(#COLOR_BTNFACE)
    FrontColor(Red(background),Green(background),Blue(background))
    Box(0,0,16,16)
    If img = 0 : Start=7 : Else : Start = 2 : EndIf
    For a = 6 To 10
      Line(Start,a,13-Start*2,0,0)
      Start+1
    Next a
    StopDrawing()
  Next
EndProcedure


Procedure AddListIconColumn(gadget,pos,width,align,text$,hImage)
  ; by Danilo, 11.01.2004
  ;
  ; Add column to ListIconGadget
  ;
  ;   gadget = the PB gadget number
  ;   pos    = position of the new column
  ;   width  = with     of the new column
  ;   align  = align    of the text in the column:
  ;            #LI_CENTERED, #LI_LEFT, #LI_RIGHT
  ;   text$  = column header text
  ;   hImage = image handle __OR__ index of already added image!
  ;
  #LVCF_IMAGE = $10
  #LVCFMT_COL_HAS_IMAGES = $8000
  #LI_CENTERED = #LVCFMT_CENTER
  #LI_LEFT     = #LVCFMT_LEFT
  #LI_RIGHT    = #LVCFMT_RIGHT
  Structure LVCOLUMN
    lv.LV_COLUMN
    iImage.l
    iOrder.l
  EndStructure
  If GetObjectType_(hImage)=#OBJ_BITMAP
    ; Add Image to List
    hImgL = SendMessage_(GadgetID(gadget),#LVM_GETIMAGELIST,#LVSIL_SMALL,0)
    If hImgL=0
      hImgL = ImageList_Create_(16,16,#ILC_COLOR32,1,1)
      SendMessage_(GadgetID(gadget),#LVM_SETIMAGELIST,#LVSIL_SMALL,hImgL)
    EndIf
    idx = ImageList_Add_(hImgL,hImage,0)
  Else
    ; was an index
    idx = hImage
  EndIf
  LVC.LVCOLUMN
  LVC\lv\mask = #LVCF_IMAGE|#LVCF_TEXT|#LVCF_WIDTH|#LVCF_FMT
  LVC\lv\fmt     = align|#LVCFMT_COL_HAS_IMAGES
  LVC\lv\pszText = @text$
  LVC\lv\cchTextMax = Len(text$)
  LVC\lv\iSubItem = pos
  LVC\lv\cx   = width
  LVC\iImage  = idx
  LVC\iOrder  = pos
  SendMessage_(GadgetID(gadget),#LVM_INSERTCOLUMN,pos,@LVC)
EndProcedure


Procedure GetListIconColumnImage(gadget,column)
  ; by Danilo, 11.01.2004
  ;
  ; returns the image_index of the column-header-image
  ;
  LVC.LVCOLUMN
  LVC\lv\mask = #LVCF_IMAGE
  SendMessage_(GadgetID(gadget),#LVM_GETCOLUMN,column,@LVC)
  ProcedureReturn LVC\iImage
EndProcedure


Procedure ChangeListIconColumnImage(gadget,column,Image_Index)
  ; by Danilo, 11.01.2004
  ;
  ; change the image_index of the column-header-image
  ;
  LVC.LVCOLUMN
  LVC\lv\mask = #LVCF_IMAGE
  LVC\iImage  = Image_Index
  ProcedureReturn SendMessage_(GadgetID(gadget),#LVM_SETCOLUMN,column,@LVC)
EndProcedure


Procedure SetListIconColumnText(gadget,index,Text$)
  ; by Danilo, 15.12.2003 - english chat (for 'Karbon')
  ;
  ; change column header text
  ;
  lvc.LV_COLUMN
  lvc\mask    = #LVCF_TEXT
  lvc\pszText = @Text$
  SendMessage_(GadgetID(gadget),#LVM_SETCOLUMN,index,@lvc)
EndProcedure


Procedure SetListIconColumnWidth(gadget,index,new_width)
  ; by Danilo, 15.12.2003 - english chat (for 'Karbon')
  ;
  ; change column header width
  ;
  SendMessage_(GadgetID(gadget),#LVM_SETCOLUMNWIDTH,index,new_width)
EndProcedure


Procedure SetListIconColumnFormat(gadget,index,format)
  ; by Danilo, 15.12.2003 - english chat (for 'Karbon')
  ;
  ; change text alignment for columns
  ;
  lvc.LV_COLUMN
  lvc\mask = #LVCF_FMT
  Select format
  Case 0: lvc\fmt = #LVCFMT_LEFT
  Case 1: lvc\fmt = #LVCFMT_CENTER
  Case 2: lvc\fmt = #LVCFMT_RIGHT
  EndSelect
  SendMessage_(GadgetID(gadget),#LVM_SETCOLUMN,index,@lvc)
EndProcedure




Procedure UpdatelParam(ListIconGadget,columns)
  ;
  ; PureArea.net CodeArchiv, by unknown
  ;
  ; modified by Danilo, 11.01.2004
  ;
  ItemCount = SendMessage_(ListIconGadget, #LVM_GETITEMCOUNT, 0, 0)
  lvi.LV_ITEM
  lvi\mask = #LVIF_PARAM
  lvi\iItem = 0
  While ItemCount>0
    lvi\lParam = lvi\iItem
    For SubItem = 0 To columns-1
      lvi\iSubItem = SubItem
      SendMessage_(ListIconGadget, #LVM_SETITEM, 0, @lvi)
    Next SubItem
    lvi\iItem +1
    ItemCount -1
  Wend
EndProcedure


Procedure ListIconSortFunction(lParam1,lParam2,lParamSort)
  ;
  ; PureArea.net CodeArchiv, by unknown
  ;
  ; modified by Danilo, 11.01.2004
  ;
  A$ = Space(200)
  B$ = Space(200)
  result = 0
  lvi.LV_ITEM
  lvi\iSubItem = lParamSort&$FFFF
  lvi\pszText = @A$
  lvi\cchTextMax = 200
  lvi\mask = #LVIF_TEXT
  SendMessage_(GadgetID(0), #LVM_GETITEMTEXT,lParam1,@lvi)
  lvi\pszText = @B$
  SendMessage_(GadgetID(0), #LVM_GETITEMTEXT,lParam2,@lvi)
  
  If A$ = B$
    ProcedureReturn 0 ; equal
  EndIf
  
  x = (lParamSort>>16)&$FFFF
  ucasea.s = UCase(A$)
  ucaseb.s = UCase(B$)
  vala.l = Val(ucasea)
  valb.l = Val(ucaseb)
  If x
    x = 1
  Else
    x = -1
  Endif
  If (vala = 0 And A$<>"0") Or (valb = 0 And B$<>"0")
    If ucasea > ucaseb
      ProcedureReturn  x
    Else
      ProcedureReturn -x
    EndIf
  Else
    If vala > valb
      ProcedureReturn  x
    Else
      ProcedureReturn -x
    EndIf
  Endif
  ProcedureReturn result
EndProcedure




;
;- Window Callback
;
Procedure WinProc(hWnd,Msg,wParam,lParam)
  result = #PB_ProcessPureBasicEvents
  Select Msg
  Case #WM_NOTIFY
    *NMHDR.NMHDR = lParam
    If *NMHDR\hWndFrom = GadgetID(0) ; comes from our ListIconGadget
      If *NMHDR\code = #LVN_COLUMNCLICK
        *NMLV.NMLISTVIEW = lParam
        column = *NMLV\iSubItem
        ; switch images:
        index  = GetListIconColumnImage(0,column)
        ChangeListIconColumnImage(0,column,index!1)
        ; sort
        SendMessage_(GadgetID(0),#LVM_SORTITEMS,column|((index)<<16),@ListIconSortFunction())
        UpdatelParam(GadgetID(0),5)
      EndIf
    EndIf
  EndSelect
  ProcedureReturn result
EndProcedure


;
;- program start
;
CreateListIconArrows(0)

OpenWindow(0,0,0,500,200,#PB_Window_SystemMenu|#PB_Window_ScreenCentered,"LV")
SetWindowCallback(@WinProc())
CreateGadgetList(WindowID())
ListIconGadget(0,0,0,500,200,"",0,#PB_ListIcon_FullRowSelect|#PB_ListIcon_AlwaysShowSelection)
AddListIconColumn(0,1,150,#LI_LEFT    ,"Column 1",UseImage(0)) ; add Image 0
AddListIconColumn(0,2,120,#LI_CENTERED,"Column 2",UseImage(1)) ; add Image 1
AddListIconColumn(0,3, 90,#LI_CENTERED,"Column 3",0)           ; use Image index 0
AddListIconColumn(0,4,105,#LI_RIGHT   ,"Column 4",1)           ; use Image index 1

For a = 0 To 100
  A$ = "COLUMN 1, Row "+RSet(Str(  a  ),3,"0")
  length.b = 5 + Random(10)
  B$=""
  For loop = 1 To length
    B$ + Chr(65 + Random(60))
  Next
  C$ = Str(Random(10000))
  If a % 2 = 0
    D$ = B$
  Else
    D$ = C$
  EndIf
  AddGadgetItem(0,-1,Chr(10)+A$+Chr(10)+B$+Chr(10)+C$+Chr(10)+D$)
Next

UpdatelParam(GadgetID(0),5)

Repeat:Until WaitWindowEvent()=#PB_Event_CloseWindow
It'll be a tiny bit slower than the original routine but hopefully it isn't noticeable (at least with smallish lists... :roll:)
naw
Enthusiast
Enthusiast
Posts: 573
Joined: Fri Apr 25, 2003 4:57 pm

Post by naw »

MrMat,

Thank you - will be using this a lot....
Ta - N
MrMat
Enthusiast
Enthusiast
Posts: 762
Joined: Sun Sep 05, 2004 6:27 am
Location: England

Post by MrMat »

My pleasure! Danilo did all the hard work though, so thank you Danilo! :-D
Mat
Denis
Enthusiast
Enthusiast
Posts: 778
Joined: Fri Apr 25, 2003 5:10 pm
Location: Doubs - France

Post by Denis »

I send a piece of code on french forum with a listicon (like explorergadget but only with one folder). I explain how to sort the listicon but its in french.

May be it could help you.


http://purebasic.hmt-forum.com/viewtopic.php?t=1652

This code use my Lib MoreListiconGadget
A+
Denis
Post Reply