PureLVSORT library : sorting ListIconGadgets (and more)

All PureFORM, JaPBe, Libs and useful code maintained by gnozal

Moderator: gnozal

User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8451
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Post by netmaestro »

timeSetEvent_() is ideal for this. Are you calling it with fuEvent set to #TIME_PERIODIC? It won't continue to pulse otherwise.
mskuma
Enthusiast
Enthusiast
Posts: 573
Joined: Sat Dec 03, 2005 1:31 am
Location: Australia

Post by mskuma »

netmaestro wrote:timeSetEvent_() is ideal for this. Are you calling it with fuEvent set to #TIME_PERIODIC? It won't continue to pulse otherwise.
Yes I was. I could get it to animate in the program by setting up some dummy buttons to turn it on/off, but couldn't get it to animate beyond the first frame during a sort.
gnozal
PureBasic Expert
PureBasic Expert
Posts: 4229
Joined: Sat Apr 26, 2003 8:27 am
Location: Strasbourg / France
Contact:

Post by gnozal »

Update (both versions)

Changes :
- new function PureLVSORT_DefineFilterCallback() : define user filtering callback for #HDN_FILTERCHANGE or #HDN_FILTERBTNCLICK events.
For free libraries and tools, visit my web site (also home of jaPBe V3 and PureFORM).
User avatar
Flype
Addict
Addict
Posts: 1542
Joined: Tue Jul 22, 2003 5:02 pm
Location: In a long distant galaxy

Post by Flype »

gnozal wrote:Update (both versions)

Changes :
- new function PureLVSORT_DefineFilterCallback() : define user filtering callback for #HDN_FILTERCHANGE or #HDN_FILTERBTNCLICK events.
yeah, exactely when i need it for a project.
i was yesterday wondering on how to enhanced this because the previous PureLVSORT_SetFilter(#Gadget) is limited (very often).

i test your update right now :wink:
No programming language is perfect. There is not even a single best language.
There are only languages well suited or perhaps poorly suited for particular purposes. Herbert Mayer
User avatar
Flype
Addict
Addict
Posts: 1542
Joined: Tue Jul 22, 2003 5:02 pm
Location: In a long distant galaxy

Post by Flype »

gnozal wrote:Update (both versions)

Changes :
- new function PureLVSORT_DefineFilterCallback() : define user filtering callback for #HDN_FILTERCHANGE or #HDN_FILTERBTNCLICK events.
humm, how to use it ?
what are the callback arguments ?



[EDIT]

1/
ah ok, i found the documentation in the PB3.94 archive.
so i found a bug :D : the documentation of the PB4 lib isn't updated.

2/
maybe, it's normal but i receive each time 2 events in the callback.
one with an empty string, another which is ok :
======= filter callback ========
GadgetNumber:0
FilterString:
ListIconColumn: 0
======= filter callback ========
GadgetNumber:3
FilterString: teststring
ListIconColumn: 0
======= filter callback ========
GadgetNumber:0
FilterString:
ListIconColumn: 0
======= filter callback ========
GadgetNumber:3
FilterString: teststring
ListIconColumn: 0
======= filter callback ========
GadgetNumber:0
FilterString:
ListIconColumn: 0
======= filter callback ========
GadgetNumber:3
FilterString: teststring
ListIconColumn: 0
======= filter callback ========
GadgetNumber:0
FilterString:
ListIconColumn: 0
======= filter callback ========
GadgetNumber:3
FilterString: teststring
ListIconColumn: 0

3/
i think it could be useful to receive - as a fourth argument - the type of the event.

like in this (not working) example :

Code: Select all

Procedure.l MyFilterCallBack(GadgetNumber.l, FilterString.s, ListIconColumn.l, EventType.l)
  
  Select EventType
    
    Case #PureLVSORT_FilterChange
      
    Case #PureLVSORT_FilterButtonClick
      
  EndSelect
  
EndProcedure

4/
thank you gnozal for all.
No programming language is perfect. There is not even a single best language.
There are only languages well suited or perhaps poorly suited for particular purposes. Herbert Mayer
User avatar
Flype
Addict
Addict
Posts: 1542
Joined: Tue Jul 22, 2003 5:02 pm
Location: In a long distant galaxy

Post by Flype »

/5

another request ( sorry :oops: gnozal )
but i know you love to enhance your libs
:wink:

Code: Select all

PureLVSORT_SetFilter(GadgetNumber.l, [FilterTimeOut.l]) 
a FilterTimeOut.l argument would be nice for the PureLVSORT_SetFilter() function.

this timeout should be easy to implement because the WinAPI has such an option for the filter stuff.


here is my example to show you how to implement the TimeOut.l option and the EventType (4th argument in the callback).
[EDIT]

Code: Select all

;#################################
;##### LISTICONGADGET FILTER #####
;#################################

#LVM_GETHEADER = (#LVM_FIRST+31)
#HDI_FILTER = $0100
#HDFT_ISSTRING = $0000
#HDS_FILTERBAR = $0100
#HDM_SETFILTERCHANGETIMEOUT = #HDM_FIRST+22
#HDM_EDITFILTER = #HDM_FIRST+23
#HDM_CLEARFILTER = #HDM_FIRST+24
#HDN_FILTERCHANGE = #HDN_FIRST-12
#HDN_FILTERBTNCLICK = #HDN_FIRST-13

Structure HDITEM
  mask.l
  cxy.l
  pszText.l
  hbm.l
  cchTextMax.l
  fmt.l
  lParam.l
  iImage.l
  iOrder.l
  type.l
  pvFilter.l
EndStructure
Structure HDTEXTFILTER
  pszText.s
  cchTextMax.l
EndStructure

Procedure.l ListIconGadget_CallBack(hwnd.l, msg.l, wParam.l, *lParam.NMHDFILTERBTNCLICK)
  
  Protected result.l, item.HDITEM, filter.HDTEXTFILTER
  
  result = CallWindowProc_(GetProp_(hwnd, "USER_OLDPROC"), hwnd, msg, wParam, *lParam)
  
  If msg = #WM_NOTIFY
    Select *lParam\hdr\code
      Case #HDN_FILTERCHANGE, #HDN_FILTERBTNCLICK
        filter\pszText = Space(256)
        filter\cchTextMax = 256
        item\mask = #HDI_FILTER
        item\type = #HDFT_ISSTRING
        item\pvFilter = @filter
        SendMessage_(GetProp_(hwnd, "USER_HEADER"), #HDM_GETITEM, *lParam\iItem, @item)
        If GetProp_(hwnd, "USER_HPROC")
          CallFunctionFast(GetProp_(hwnd, "USER_HPROC"), GetProp_(hwnd, "USER_GADGET"), filter\pszText, *lParam\iItem, *lParam\hdr\code)
        EndIf
    EndSelect
  EndIf
  
  ProcedureReturn result
  
EndProcedure
Procedure.l ListIconGadget_Filter(gadget.l, *window, *hproc, timeOut.l = 50)
  
  Protected *header, hdItem.HDITEM
  
  *header = SendMessage_(GadgetID(gadget), #LVM_GETHEADER, #Null, #Null)
  
  If *header
    hdItem\mask = #HDI_FILTER
    hdItem\type = #HDFT_ISSTRING
    SendMessage_(*header, #HDM_SETFILTERCHANGETIMEOUT, 0, timeOut)
    SetWindowLong_(*header, #GWL_STYLE, GetWindowLong_(*header, #GWL_STYLE) | #HDS_FILTERBAR )
    SetProp_(*window, "USER_OLDPROC", SetWindowLong_(*window, #GWL_WNDPROC, @ListIconGadget_CallBack()))
    SetProp_(*window, "USER_HEADER", *header)
    SetProp_(*window, "USER_GADGET", gadget)
    SetProp_(*window, "USER_HPROC", *hproc)
  EndIf
  
EndProcedure

;#################################
;##### EXAMPLE D'UTILISATION #####
;#################################

Procedure.l recherche(gadget.l, text.s = "", column.l = 0, ev.l = 0)
  
  Debug "Gadget: " + Str(gadget)
  
  Select ev
    Case #HDN_FILTERCHANGE:   Debug "Filter Cchange."
    Case #HDN_FILTERBTNCLICK: Debug "Filter Button Click."
  EndSelect
  
  If ExamineEnvironmentVariables()
    
    ClearGadgetItemList(gadget)
    
    While NextEnvironmentVariable()
      Select column
        Case 0: EnvironmentVariable$ = EnvironmentVariableName()
        Case 1: EnvironmentVariable$ = EnvironmentVariableValue()
      EndSelect
      If text = #Null$ Or FindString(LCase(EnvironmentVariable$), LCase(text), 1)
        AddGadgetItem(gadget, -1, EnvironmentVariableName() + #LF$ + EnvironmentVariableValue())
      EndIf
    Wend
    
  EndIf
  
  StatusBarText(0, 0, "La recherche de '" + text + "' a retournée " + Str(CountGadgetItems(1)) + " résultat(s).")
  
EndProcedure

If OpenWindow(0, 0, 0, 640, 400, "Variables d'environnement", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)
  
  If CreateStatusBar(0, WindowID(0))
    AddStatusBarField(800)
  EndIf
  
  If CreateGadgetList(WindowID(0))
    ListIconGadget(1, 5, 5, WindowWidth(0)-10, 370, "Nom", 180, #PB_ListIcon_FullRowSelect)
    AddGadgetColumn(1, 1, "Valeur", WindowWidth(0)-215)
    ListIconGadget_Filter(1, WindowID(0), @recherche())
  EndIf
  
  recherche(1)
  
  Repeat
  Until WaitWindowEvent() = #PB_Event_CloseWindow
  
EndIf
No programming language is perfect. There is not even a single best language.
There are only languages well suited or perhaps poorly suited for particular purposes. Herbert Mayer
gnozal
PureBasic Expert
PureBasic Expert
Posts: 4229
Joined: Sat Apr 26, 2003 8:27 am
Location: Strasbourg / France
Contact:

Post by gnozal »

Update (both libs)

Changes :
- new argument for filtering callback : EventID
Help wrote:The callback is a procedure called when a listicon header filter changes (#HDN_FILTERCHANGE) or a header button is pressed (#HDN_FILTERBTNCLICK).
The filter mode is activated with the PureLVSORT_SetFilter() function.

The callback procedure is like this :

Procedure MyFilterCallback(GadgetNumber.l, FilterString.s, ListIconColumn.l, EventID.l)
; ...
EndProcedure

declared like that :

PureLVSORT_DefineFilterCallback(@MyFilterCallback())

where :

GadgetNumber is the purebasic gadget ID
FilterString is the header filter text
ListIconColumn is the header column
EventID is the trigger event (#PureLVSORT_FilterBtnClick or #PureLVSORT_FilterChange)
- new function PureLVSORT_SetFilterTimeOut() ; allows to change the default library timeout (1000 ms).
For free libraries and tools, visit my web site (also home of jaPBe V3 and PureFORM).
gnozal
PureBasic Expert
PureBasic Expert
Posts: 4229
Joined: Sat Apr 26, 2003 8:27 am
Location: Strasbourg / France
Contact:

Post by gnozal »

Update (both libs) (yes again !)

Changes :
- fixed new constants in resident
- new function PureLVSORT_SaveListIconToMem()
- new function PureLVSORT_LoadListIconFromMem()
These two new functions make the filtering very easy :

Code: Select all

Procedure MyFilterCallback(GadgetNumber.l, FilterString.s, ListIconColumn.l, EventCode.l) ; simple filter example
  Shared *ListBuffer
  If EventCode = #PureLVSORT_FilterChange
    If *ListBuffer
      PureLVSORT_LoadListIconFromMem(GadgetNumber, *ListBuffer, FilterString, ListIconColumn, #True)
    EndIf
  EndIf
EndProcedure
;
#Window_0 = 0 
#ListIcon_0 = 0 
;
Procedure Open_Window_0() 
  If OpenWindow(#Window_0, 216, 0, 602, 302, "PureLVSORT Test",  #PB_Window_SystemMenu | #PB_Window_TitleBar | #PB_Window_ScreenCentered) 
    If CreateGadgetList(WindowID(#Window_0)) 
      ListIconGadget(#ListIcon_0, 5, 5, 590, 285, "String", 110) 
      AddGadgetColumn(#ListIcon_0, 1, "Numeric", 110) 
      AddGadgetColumn(#ListIcon_0, 2, "Float", 110) 
      AddGadgetColumn(#ListIcon_0, 3, "DateDDMMYYYY", 120) 
      AddGadgetColumn(#ListIcon_0, 4, "DateMMDDYYYY", 120) 
      AddGadgetItem(#ListIcon_0, -1, "ABCDE" + Chr(10) + "514" + Chr(10) + "0.9" + Chr(10) + "31/12/2004" + Chr(10) + "12/31/2004") 
      AddGadgetItem(#ListIcon_0, -1, "ACDEF" + Chr(10) + "118" + Chr(10) + "1.9" + Chr(10) + "11/12/2004" + Chr(10) + "12/11/2004") 
      AddGadgetItem(#ListIcon_0, -1, "ZABCD" + Chr(10) + "-414" + Chr(10) + "7.0" + Chr(10) + "21/01/2003" + Chr(10) + "01/21/2003") 
      AddGadgetItem(#ListIcon_0, -1, "DEFGH" + Chr(10) + "524" + Chr(10) + "900" + Chr(10) + "10/06/2001" + Chr(10) + "06/10/2001") 
      AddGadgetItem(#ListIcon_0, -1, "AFFGH" + Chr(10) + "352" + Chr(10) + "911" + Chr(10) + "10/06/2004" + Chr(10) + "06/10/2003") 
      AddGadgetItem(#ListIcon_0, -1, "ZSFZI" + Chr(10) + "574" + Chr(10) + "921" + Chr(10) + "10/06/2002" + Chr(10) + "06/10/2004") 
      AddGadgetItem(#ListIcon_0, -1, "ZEKZH" + Chr(10) + "521" + Chr(10) + "931" + Chr(10) + "10/06/2011" + Chr(10) + "06/10/2005") 
      AddGadgetItem(#ListIcon_0, -1, "ZFFGH" + Chr(10) + "523" + Chr(10) + "913" + Chr(10) + "10/06/2011" + Chr(10) + "06/10/2001") 
      AddGadgetItem(#ListIcon_0, -1, "AZFHI" + Chr(10) + "522" + Chr(10) + "923" + Chr(10) + "10/06/2006" + Chr(10) + "06/10/2001") 
      AddGadgetItem(#ListIcon_0, -1, "AEZGH" + Chr(10) + "529" + Chr(10) + "933" + Chr(10) + "10/06/2000" + Chr(10) + "06/11/2001") 
      AddGadgetItem(#ListIcon_0, -1, "DZFKH" + Chr(10) + "624" + Chr(10) + "900" + Chr(10) + "10/07/2001" + Chr(10) + "06/11/2001") 
      AddGadgetItem(#ListIcon_0, -1, "DEFGI" + Chr(10) + "625" + Chr(10) + "900" + Chr(10) + "10/08/2001" + Chr(10) + "06/11/2001") 
      AddGadgetItem(#ListIcon_0, -1, "DSFKH" + Chr(10) + "623" + Chr(10) + "900" + Chr(10) + "10/09/2001" + Chr(10) + "06/11/2001") 
    EndIf 
  EndIf 
EndProcedure 
;
Open_Window_0() 
;
If PureLVSORT_SelectGadgetToSort(#ListIcon_0, #PureLVSORT_ShowClickedHeader_IconLeft) = #PureLVSORT_Ok 
  PureLVSORT_SetColumnType(#ListIcon_0, 0, #PureLVSORT_String) ; default, not necessary 
  PureLVSORT_SetColumnType(#ListIcon_0, 1, #PureLVSORT_Numeric) 
  PureLVSORT_SetColumnType(#ListIcon_0, 2, #PureLVSORT_Float) 
  PureLVSORT_SetColumnType(#ListIcon_0, 3, #PureLVSORT_DateDDMMYYYY) 
  PureLVSORT_SetColumnType(#ListIcon_0, 4, #PureLVSORT_DateMMDDYYYY) 
  PureLVSORT_SortListIconNow(#ListIcon_0, 3, 1)
  *ListBuffer = PureLVSORT_SaveListIconToMem(#ListIcon_0)
  PureLVSORT_DefineFilterCallback(@MyFilterCallback())
  PureLVSORT_SetFilterTimeOut(100)
  PureLVSORT_SetFilter(#ListIcon_0)
EndIf 
; 
Repeat 
  Event = WaitWindowEvent() 
Until Event = #PB_Event_CloseWindow 
If *ListBuffer
  FreeMemory(*ListBuffer)
EndIf
End
For free libraries and tools, visit my web site (also home of jaPBe V3 and PureFORM).
User avatar
Flype
Addict
Addict
Posts: 1542
Joined: Tue Jul 22, 2003 5:02 pm
Location: In a long distant galaxy

Post by Flype »

looks good - thank you. i can't test now. i will test tonight.

but i would have prefered PureLVSORT_SetFilterTimeOut(#Gadget, Timeout.l)

in order to specify a different timeout for each gadget :idea: .

or just this way PureLVSORT_SetFilter(#Gadget [, Timeout.l])
No programming language is perfect. There is not even a single best language.
There are only languages well suited or perhaps poorly suited for particular purposes. Herbert Mayer
gnozal
PureBasic Expert
PureBasic Expert
Posts: 4229
Joined: Sat Apr 26, 2003 8:27 am
Location: Strasbourg / France
Contact:

Post by gnozal »

Flype wrote:looks good - thank you. i can't test now. i will test tonight.
but i would have prefered PureLVSORT_SetFilterTimeOut(#Gadget, Timeout.l)
in order to specify a different timeout for each gadget :idea: .
or just this way PureLVSORT_SetFilter(#Gadget [, Timeout.l])
It should work this way :

Code: Select all

PureLVSORT_SetFilterTimeOut(500)
PureLVSORT_SetFilter(#ListIcon_0)
PureLVSORT_SetFilterTimeOut(10)
PureLVSORT_SetFilter(#ListIcon_1)
PureLVSORT_SetFilterTimeOut(5000)
PureLVSORT_SetFilter(#ListIcon_2)
It's pretty much the same.

EDIT: I have just updated the libs (fixed a possible memory leak). Should be the last one today ...
For free libraries and tools, visit my web site (also home of jaPBe V3 and PureFORM).
AND51
Addict
Addict
Posts: 1040
Joined: Sun Oct 15, 2006 8:56 pm
Location: Germany
Contact:

Post by AND51 »

Hi gnozal!

I'm using your Libs for a long period of time - they are GREAT!

Suggestion: I just saw that there is an update for the libs by accident.
Wouldn't it be better, if you create an automatically Updater, which can be directly embedded in the PB IDE? YOu know, there is a menu called Tools. There you can add your own tools. Would be great, if you create an EXE, which can be started, when the IDE starts. Then it searches in the background for Updates while programming.

So we don't have to care for updates ourself anymore. :D
PB 4.30

Code: Select all

onErrorGoto(?Fred)
User avatar
Flype
Addict
Addict
Posts: 1542
Joined: Tue Jul 22, 2003 5:02 pm
Location: In a long distant galaxy

Post by Flype »

@AND51

Yes - i wanted to suggest the same idea for jaPBe. It would be handy.
No programming language is perfect. There is not even a single best language.
There are only languages well suited or perhaps poorly suited for particular purposes. Herbert Mayer
AND51
Addict
Addict
Posts: 1040
Joined: Sun Oct 15, 2006 8:56 pm
Location: Germany
Contact:

Post by AND51 »

Unfortunately, I don't use jaPBe, but then the auto-updater should work for both IDE's.

Well, the updater should also install the Libs, if the user confirms it! So I don't have to do this on my own.
PB 4.30

Code: Select all

onErrorGoto(?Fred)
User avatar
Flype
Addict
Addict
Posts: 1542
Joined: Tue Jul 22, 2003 5:02 pm
Location: In a long distant galaxy

Post by Flype »

just like Mozilla Firefox :D

with firefox, every extensions, plugins, themes, languages installed can be updated automatically. very handy.


OK for tomorrow morning gnozal :?: :D


i'm joking of course.
No programming language is perfect. There is not even a single best language.
There are only languages well suited or perhaps poorly suited for particular purposes. Herbert Mayer
gnozal
PureBasic Expert
PureBasic Expert
Posts: 4229
Joined: Sat Apr 26, 2003 8:27 am
Location: Strasbourg / France
Contact:

Post by gnozal »

About automatic update notification / download

I am behind a firewall, and I need code to connect through a proxy with authentication. None of the codes I found actually works correctly.
And more, the purebasic smart updater doesn't work for me (no proxy option).

As for update notification, what's better than to post in the 'Announcement' forum ?
For free libraries and tools, visit my web site (also home of jaPBe V3 and PureFORM).
Post Reply