Page 1 of 1

How to detect listicongadget column header click

Posted: Thu Jan 30, 2014 4:38 pm
by karu
I dont find this thread anymore where discussed about that?

Karu

Re: How to detect listicongadget column header click

Posted: Thu Jan 30, 2014 6:21 pm
by Tranquil
www.purebasic.fr/english/viewtopic.php?p=25851

old topiy, code maybe needs to be adapted to new version of pb.

Re: How to detect listicongadget column header click

Posted: Thu Jan 30, 2014 7:35 pm
by karu
:) thanks Tranquil, this is what i need.

Re: How to detect listicongadget column header click

Posted: Mon Mar 17, 2014 11:49 am
by CONVERT
Hello,

Freak's code works fine with PB 5.21, but it is Windows specific.

For Linux or Macintosh, I tried to see how to use BindEvent, but I did not find yet how to detect the column. It is not urgent, but I would like to use it in future versions of my application for Linux or Mac.

Thanks if you have any idea.

Jean.

Re: How to detect listicongadget column header click

Posted: Tue Mar 18, 2014 10:18 pm
by Shardik
CONVERT wrote:Freak's code works fine with PB 5.21, but it is Windows specific.

For Linux or Macintosh, I tried to see how to use BindEvent, but I did not find yet how to detect the column. It is not urgent, but I would like to use it in future versions of my application for Linux or Mac.

Thanks if you have any idea.
Please try the cross-platform code example below which detects the clicked header column and the clicked row. I have tested it successfully on these operating systems:
- Debian 7 x86 with Gnome 3
- Fedora 20 x86 with Gnome 3
- Kubuntu 13.10 x86 with KDE
- Linux Mint 16 x86 with Cinnamon
- Lubuntu 13.10 x86 with LXDE
- MacOS X 10.6.8 (Snow Leopard) with PB 5.21 x86 and x64 in ASCII and unicode mode
- MacOS X 10.9.2 (Mavericks)
- OpenSUSE 13.1 with KDE
- PCLinuxOS x86 with KDE
- PearOS 8 x86 with a heavily modified Gnome 3
- Ubuntu 10.04 LTS x86 with Gnome 2
- Ubuntu 12.04 LTS x64 with KDE
- Ubuntu 12.04 LTS x64 with Unity
- Ubuntu 12.04 LTS x64 with Enlightenment
- Windows XP SP3 x86
- Windows 7 SP1 x64
- Xubuntu 13.10 x86 with Xfce

Code: Select all

EnableExplicit

Structure CallbackEntry
  WindowID.I
  ListIconID.I
  DefaultCallback.I
EndStructure

NewList CallbackEntry.CallbackEntry()

CompilerSelect #PB_Compiler_OS
  CompilerCase #PB_OS_Linux ; ------------------------------------------------
    ProcedureC ColumnHeaderClickCallback(*Column, ListIconData.I)
      Shared CallbackEntry()

      ForEach CallbackEntry()
        If ListIconData >> 16 = CallbackEntry()\ListIconID
          Break
        EndIf
      Next

      PostEvent(#PB_Event_Gadget, CallbackEntry()\WindowID,
        CallbackEntry()\ListIconID, #PB_EventType_LeftClick,
        (ListIconData & $FFFF) + 1)
    EndProcedure

    Procedure SetGadgetCallback(WindowID.I, ListIconID.I)
      Shared CallbackEntry()

      Protected Column.I
      Protected ColumnCount.I
      Protected ColumnIndex.I
      Protected *ListStore.GtkListStore

      AddElement(CallbackEntry())
      CallbackEntry()\WindowID = WindowID
      CallbackEntry()\ListIconID = ListIconID
      gtk_tree_view_set_headers_clickable_(GadgetID(ListIconID), #True)
      *ListStore = gtk_tree_view_get_model_(GadgetID(ListIconID))
      ColumnCount = (*ListStore\n_columns - 3) / 3

      For ColumnIndex = 0 To ColumnCount - 1
        Column = gtk_tree_view_get_column_(GadgetID(CallbackEntry()\ListIconID),
          ColumnIndex)

        If Column
          g_signal_connect_data_(Column, "clicked",
            @ColumnHeaderClickCallback(), ListIconID << 16 | ColumnIndex, 0, 0)
        EndIf
      Next ColumnIndex
    EndProcedure
  CompilerCase #PB_OS_MacOS ; ------------------------------------------------
    ImportC ""
      sel_registerName(MethodName.S)
      class_addMethod(Class.I, Selector.I, Implementation.I, Types.S)
    EndImport

    Procedure.S ConvertToUTF8(String.S)
      Protected UTF8String.S = Space(StringByteLength(String))
      PokeS(@UTF8String, String, -1, #PB_UTF8)
      ProcedureReturn UTF8String
    EndProcedure
   
    ProcedureC ColumnHeaderClickCallback(Object.I, Selector.I, TableView.I,
      TableColumn.I)
      Shared CallbackEntry()

      Protected ClickedHeaderColumn.I
 
      ForEach CallbackEntry()
        If TableView = GadgetID(CallbackEntry()\ListIconID)
          Break
        EndIf
      Next
    
      ClickedHeaderColumn = Val(PeekS(CocoaMessage(0,
        CocoaMessage(0, TableColumn, "identifier"),
        "UTF8String"), -1, #PB_UTF8))
      PostEvent(#PB_Event_Gadget, CallbackEntry()\WindowID,
        CallbackEntry()\ListIconID, #PB_EventType_LeftClick,
        ClickedHeaderColumn + 1)
    EndProcedure
   
    Procedure SetGadgetCallback(WindowID.I, ListIconID.I)
      Shared CallbackEntry()
     
      Protected AppDelegate.I
      Protected DelegateClass.I
      Protected Selector.I = sel_registerName(ConvertToUTF8("tableView:didClickTableColumn:"))
      Protected Types.S = ConvertToUTF8("v@:@@")

      AddElement(CallbackEntry())
      CallbackEntry()\WindowID = WindowID
      CallbackEntry()\ListIconID = ListIconID
      AppDelegate = CocoaMessage(0,
        CocoaMessage(0, 0, "NSApplication sharedApplication"), "delegate")
      DelegateClass = CocoaMessage(0, AppDelegate, "class")
      class_addMethod(DelegateClass, Selector, @ColumnHeaderClickCallback(),
        Types)
      CocoaMessage(0, GadgetID(CallbackEntry()\ListIconID),
        "setDelegate:", AppDelegate)
    EndProcedure
  CompilerCase #PB_OS_Windows ; ----------------------------------------------
    Procedure ColumnHeaderClickCallback(WindowHandle.I, Msg.I, WParam.I,
      LParam.I)
      Shared CallbackEntry()

      Protected Result.I
      Protected *Header.HD_NOTIFY

      ForEach CallbackEntry()
        If WindowHandle = GadgetID(CallbackEntry()\ListIconID)
          Break
        EndIf
      Next

      Result = CallWindowProc_(CallbackEntry()\DefaultCallback, WindowHandle,
        Msg, WParam, LParam)

      If Msg = #WM_NOTIFY
        *Header = LParam

        If *Header\hdr\code = #HDN_ITEMCLICK
          PostEvent(#PB_Event_Gadget, CallbackEntry()\WindowID,
            CallbackEntry()\ListIconID, #PB_EventType_LeftClick,
            *Header\iItem + 1)
        EndIf
      EndIf

      ProcedureReturn Result
    EndProcedure

    Procedure SetGadgetCallback(WindowID.I, ListIconID.I)
      Shared CallbackEntry()

      AddElement(CallbackEntry())
      CallbackEntry()\WindowID = WindowID
      CallbackEntry()\ListIconID = ListIconID
      CallbackEntry()\DefaultCallback = SetWindowLongPtr_(GadgetID(CallbackEntry()\ListIconID),
        #GWL_WNDPROC, @ColumnHeaderClickCallback())
    EndProcedure ; -----------------------------------------------------------
CompilerEndSelect

OpenWindow(0, 200, 100, 450, 150, "Detect left click on header cell")
ListIconGadget(0, 10, 10, WindowWidth(0) - 20, WindowHeight(0) - 20, "Name",
  110, #PB_ListIcon_FullRowSelect)
AddGadgetColumn(0, 1, "Address", 300)
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")

SetGadgetCallback(0, 0)

Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      Break
    Case #PB_Event_Gadget
      If EventGadget() = 0 And EventType() = #PB_EventType_LeftClick
        If EventData()
          Debug "Left click on header of column " + Str(EventData() - 1)
        Else
          Debug "Left click on row " + Str(GetGadgetState(0))
        EndIf
      EndIf
  EndSelect
ForEver
Update: CONVERT found out that my code didn't work properly with more that one ListIconGadget. I therefore modified the above code to also work reliable with multiple windows and ListIconGadgets.

Re: How to detect listicongadget column header click

Posted: Tue Mar 18, 2014 10:37 pm
by CONVERT
Whoaooh! Great!

It already works on W7 32. I'll integrate it in my application (provided for GNU L3), with your name, of course.

Thanks, Shardik.

Jean.

Re: several ListIconGadgets in a same window

Posted: Sun Mar 23, 2014 2:40 pm
by CONVERT
Hello Shardik,

Your code works fine (Windows 7 Home 32), but not in case of several ListIcon Gadgets in a same window, with eventually several panels.

I added a second ListIconGadgets in your code to test.
(I also replaced
"DefaultListIconCallback = SetWindowLong_(GadgetID(0)," by
"DefaultListIconCallback = SetWindowLong_(GadgetID(ListIconID),"
in the Procedure SetGadgetCallback(WindowID.I, ListIconID.I)
I hope I did not make a mistake).

The problem is: how to manage the SetGadgetCallback() before the Repeat /Select WaitWindowEvent()?

I tried to put the SetGadgetCallback() in the repeat loop with a test of the last used ListIconGadget, but I got a stack overflow.

The version 7 below does only the 2 SetGadgetCallback() (one for every ListIconGadget) before the repeat, but, of course, it gives the column header only on the last ListIconGadget.

May be I can solve this problem by replacing DefaultListIconCallback.I by a map M_DefaultListIconCallback.I (str(ListIconID.I)) and also others variables.

Also, the SetWindowLong_ as to be replaced by SetWindowLongPtr_ for 64 compatibility.

Well, for the moment, I use Freak's code (only for Window), and I'll see later for Linux etc.

Code: Select all


; VERSION 7

;How To detect listicongadget column header click
;by Shardik ยป Tue Mar 18, 2014 23:18

EnableExplicit

Define CallbackListIconID.I
Define CallbackWindowID.I

CompilerSelect #PB_Compiler_OS
  CompilerCase #PB_OS_Linux ; ------------------------------------------------
    ProcedureC ColumnHeaderClickCallback(*Column, ClickedHeaderColumn.I)
      Shared CallbackListIconID.I
      Shared CallbackWindowID.I

      PostEvent(#PB_Event_Gadget, CallbackWindowID, CallbackListIconID,
        #PB_EventType_LeftClick, ClickedHeaderColumn + 1)
    EndProcedure

    Procedure SetGadgetCallback(WindowID.I, ListIconID.I)
      Shared CallbackWindowID.I
      Shared CallbackListIconID.I

      Protected Column.I
      Protected ColumnCount.I
      Protected ColumnIndex.I
      Protected *ListStore.GtkListStore

      CallbackWindowID = WindowID
      CallbackListIconID = ListIconID
      gtk_tree_view_set_headers_clickable_(GadgetID(CallbackListIconID), #True)
      *ListStore = gtk_tree_view_get_model_(GadgetID(CallbackListIconID))
      ColumnCount = (*ListStore\n_columns - 3) / 3

      For ColumnIndex = 0 To ColumnCount - 1
        Column = gtk_tree_view_get_column_(GadgetID(CallbackListIconID),
          ColumnIndex)

        If Column
          g_signal_connect_data_(Column, "clicked",
            @ColumnHeaderClickCallback(), ColumnIndex, 0, 0)
        EndIf
      Next ColumnIndex
    EndProcedure
  CompilerCase #PB_OS_MacOS ; ------------------------------------------------
    ImportC ""
      sel_registerName(MethodName.S)
      class_addMethod(Class.I, Selector.I, Implementation.I, Types.S)
    EndImport

    Procedure.S ConvertToUTF8(String.S)
      Protected UTF8String.S = Space(StringByteLength(String))
      PokeS(@UTF8String, String, -1, #PB_UTF8)
      ProcedureReturn UTF8String
    EndProcedure
    
    ProcedureC ColumnHeaderClickCallback(Object.I, Selector.I, TableView.I,
      TableColumn.I)
      Shared CallbackListIconID.I
      Shared CallbackWindowID.I

      Protected ClickedHeaderColumn.I
      
      ClickedHeaderColumn = Val(PeekS(CocoaMessage(0,
        CocoaMessage(0, TableColumn, "identifier"),
        "UTF8String"), -1, #PB_UTF8))
      PostEvent(#PB_Event_Gadget, CallbackWindowID, CallbackListIconID,
        #PB_EventType_LeftClick, ClickedHeaderColumn + 1)
    EndProcedure
    
    Procedure SetGadgetCallback(WindowID.I, ListIconID.I)
      Shared CallbackListIconID.I
      Shared CallbackWindowID.I
      
      Protected AppDelegate.I
      Protected DelegateClass.I
      Protected Selector.I = sel_registerName(ConvertToUTF8("tableView:didClickTableColumn:"))
      Protected Types.S = ConvertToUTF8("v@:@@")
      
      CallbackListIconID = ListIconID
      CallbackWindowID = WindowID
      AppDelegate = CocoaMessage(0,
        CocoaMessage(0, 0, "NSApplication sharedApplication"), "delegate")
      DelegateClass = CocoaMessage(0, AppDelegate, "class")
      class_addMethod(DelegateClass, Selector, @ColumnHeaderClickCallback(),
        Types)
      CocoaMessage(0, GadgetID(CallbackListIconID), "setDelegate:", AppDelegate)
    EndProcedure
  CompilerCase #PB_OS_Windows ; ----------------------------------------------
    Define DefaultListIconCallback.I

    Procedure ColumnHeaderClickCallback(WindowHandle.I, Msg.I, WParam.I,
      LParam.I)
      Shared DefaultListIconCallback.I
      Shared CallbackListIconID.I
      Shared CallbackWindowID.I

      Protected Result.I
      Protected *Header.HD_NOTIFY

      Result = CallWindowProc_(DefaultListIconCallback, WindowHandle, Msg,
        WParam, LParam)

      If Msg = #WM_NOTIFY
        *Header = LParam

        If *Header\hdr\code = #HDN_ITEMCLICK
          PostEvent(#PB_Event_Gadget, CallbackWindowID, CallbackListIconID,
            #PB_EventType_LeftClick, *Header\iItem + 1)
        EndIf
      EndIf

      ProcedureReturn Result
    EndProcedure

    Procedure SetGadgetCallback(WindowID.I, ListIconID.I)
      Shared DefaultListIconCallback.I
      Shared CallbackListIconID.I
      Shared CallbackWindowID.I

      CallbackListIconID = ListIconID
      CallbackWindowID = WindowID
      DefaultListIconCallback = SetWindowLong_(GadgetID(ListIconID), #GWL_WNDPROC,
        @ColumnHeaderClickCallback()) 
    EndProcedure ; -----------------------------------------------------------
CompilerEndSelect

; ========================================== SPECIFIC CODE FOR TESTING

Enumeration
  #zero
  #windows_nb
  #list1_nb
  #list2_nb
EndEnumeration

#Title_column1$ = "Name"
#Title_column2$ = "Address"

OpenWindow(#windows_nb, 0, 0, 950, 150, "Detect left click on header cell",#PB_Window_SystemMenu | #PB_Window_ScreenCentered)
ListIconGadget(#list1_nb, 10, 10, 430, WindowHeight(#windows_nb) - 20, #Title_column1$,
  110, #PB_ListIcon_FullRowSelect)
AddGadgetColumn(#list1_nb, 1, #Title_column2$, 300)
AddGadgetItem(#list1_nb, -1, "Harry Rannit" + #LF$ +
  "12 Parliament Way, Battle Street, By the Bay")
AddGadgetItem(#list1_nb, -1, "Ginger Brokeit"+ #LF$ +
  "130 PureBasic Road, BigTown, CodeCity")
AddGadgetItem(#list1_nb, -1, "Didi Foundit"+ #LF$ +
  "321 Logo Drive, Mouse House, Downtown")

ListIconGadget(#list2_nb, 460, 10, 430, WindowHeight(#windows_nb) - 20, #Title_column1$,
  110, #PB_ListIcon_FullRowSelect)
AddGadgetColumn(#list2_nb, 1, #Title_column2$, 300)
AddGadgetItem(#list2_nb, -1, "Harry Rannit" + #LF$ +
  "12 Parliament Way, Battle Street, By the Bay")
AddGadgetItem(#list2_nb, -1, "Ginger Brokeit"+ #LF$ +
  "130 PureBasic Road, BigTown, CodeCity")
AddGadgetItem(#list2_nb, -1, "Didi Foundit"+ #LF$ +
  "321 Logo Drive, Mouse House, Downtown")

SetGadgetCallback(#windows_nb, #list1_nb)
SetGadgetCallback(#windows_nb, #list2_nb)

Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      Break
    Case #PB_Event_Gadget
      Select EventGadget()
        Case #list1_nb, #list2_nb
          If EventType() = #PB_EventType_LeftClick
            If EventData()
              Debug "Left click on header of column " + Str(EventData() - 1) + " gadget=" + Str(EventGadget())
            Else
              Debug "Left click on row " + Str(GetGadgetState(EventGadget())) + " gadget=" + Str(EventGadget())
            EndIf
          EndIf
      EndSelect
  EndSelect
ForEver

Re: How to detect listicongadget column header click

Posted: Sun Mar 23, 2014 8:10 pm
by Shardik
Jean,

thank you for testing my example code with 2 different ListIconGadgets, for reporting the error and notifing me that I should replace SetWindowLong_() by SetWindowLongPtr_(). Unfortunately I never tested with 2 ListIconGadgets and so didn't discover the error. The problem is that you need to keep track of the WindowID and ListIconID for each ListIcon callback defined. I therefore modified my code to use the new linked list CallbackEntry() which is declared as Shared in the ColumnHeaderClickCallback() and SetGadgetCallback() and contains the WindowID and ListIconID (and DefaultCallback address on Windows) for each entry.

I also corrected a small error in your code:

Code: Select all

    Case #PB_Event_Gadget
      Select EventGadget()
        Case #list1_nb, #list2_nb
          If EventType() = #PB_EventType_LeftClick
            If EventData()
              Debug "Left click on header of column " + Str(EventData() - 1) + " gadget=" + Str(EventGadget())
You shouldn't use EventGadget() twice in succession because the second call may obtain a different result as the first one! Therefore you should assign the result of EventGadget() to a variable and work with this variable afterwards:

Code: Select all

    Case #PB_Event_Gadget
      GadgetID = EventGadget()

      Select GadgetID
        Case #list1_nb, #list2_nb
          If EventType() = #PB_EventType_LeftClick
            If EventData()
              Debug "Left click on header of column " + Str(EventData() - 1) + " gadget=" + Str(GadgetID)
I have modified your code and tested it successfully on Windows 7 x64, Ubuntu 12.04 x64 with KDE and MacOS X 10.6.8 (Snow Leopard). On Linux I had to implement a trick because the old callback only received the clicked header column but didn't know the ListIconID and was not able to find the correct ListIcon callback. Therefore I logically ORed the clicked header column with the ListIconID shifted left by 16 bits so that the callback now also knows the ListIconID in which the header click occurred.

Code: Select all

EnableExplicit

Structure CallbackEntry
  WindowID.I
  ListIconID.I
  DefaultCallback.I
EndStructure

NewList CallbackEntry.CallbackEntry()

CompilerSelect #PB_Compiler_OS
  CompilerCase #PB_OS_Linux ; ------------------------------------------------
    ProcedureC ColumnHeaderClickCallback(*Column, ListIconData.I)
      Shared CallbackEntry()

      ForEach CallbackEntry()
        If ListIconData >> 16 = CallbackEntry()\ListIconID
          Break
        EndIf
      Next

      PostEvent(#PB_Event_Gadget, CallbackEntry()\WindowID,
        CallbackEntry()\ListIconID, #PB_EventType_LeftClick,
        (ListIconData & $FFFF) + 1)
    EndProcedure

    Procedure SetGadgetCallback(WindowID.I, ListIconID.I)
      Shared CallbackEntry()

      Protected Column.I
      Protected ColumnCount.I
      Protected ColumnIndex.I
      Protected *ListStore.GtkListStore

      AddElement(CallbackEntry())
      CallbackEntry()\WindowID = WindowID
      CallbackEntry()\ListIconID = ListIconID
      gtk_tree_view_set_headers_clickable_(GadgetID(ListIconID), #True)
      *ListStore = gtk_tree_view_get_model_(GadgetID(ListIconID))
      ColumnCount = (*ListStore\n_columns - 3) / 3

      For ColumnIndex = 0 To ColumnCount - 1
        Column = gtk_tree_view_get_column_(GadgetID(CallbackEntry()\ListIconID),
          ColumnIndex)

        If Column
          g_signal_connect_data_(Column, "clicked",
            @ColumnHeaderClickCallback(), ListIconID << 16 | ColumnIndex, 0, 0)
        EndIf
      Next ColumnIndex
    EndProcedure
  CompilerCase #PB_OS_MacOS ; ------------------------------------------------
    ImportC ""
      sel_registerName(MethodName.S)
      class_addMethod(Class.I, Selector.I, Implementation.I, Types.S)
    EndImport

    Procedure.S ConvertToUTF8(String.S)
      Protected UTF8String.S = Space(StringByteLength(String))
      PokeS(@UTF8String, String, -1, #PB_UTF8)
      ProcedureReturn UTF8String
    EndProcedure
   
    ProcedureC ColumnHeaderClickCallback(Object.I, Selector.I, TableView.I,
      TableColumn.I)
      Shared CallbackEntry()

      Protected ClickedHeaderColumn.I
 
      ForEach CallbackEntry()
        If TableView = GadgetID(CallbackEntry()\ListIconID)
          Break
        EndIf
      Next
    
      ClickedHeaderColumn = Val(PeekS(CocoaMessage(0,
        CocoaMessage(0, TableColumn, "identifier"),
        "UTF8String"), -1, #PB_UTF8))
      PostEvent(#PB_Event_Gadget, CallbackEntry()\WindowID,
        CallbackEntry()\ListIconID, #PB_EventType_LeftClick,
        ClickedHeaderColumn + 1)
    EndProcedure
   
    Procedure SetGadgetCallback(WindowID.I, ListIconID.I)
      Shared CallbackEntry()
     
      Protected AppDelegate.I
      Protected DelegateClass.I
      Protected Selector.I = sel_registerName(ConvertToUTF8("tableView:didClickTableColumn:"))
      Protected Types.S = ConvertToUTF8("v@:@@")

      AddElement(CallbackEntry())
      CallbackEntry()\WindowID = WindowID
      CallbackEntry()\ListIconID = ListIconID
      AppDelegate = CocoaMessage(0,
        CocoaMessage(0, 0, "NSApplication sharedApplication"), "delegate")
      DelegateClass = CocoaMessage(0, AppDelegate, "class")
      class_addMethod(DelegateClass, Selector, @ColumnHeaderClickCallback(),
        Types)
      CocoaMessage(0, GadgetID(CallbackEntry()\ListIconID),
        "setDelegate:", AppDelegate)
    EndProcedure
  CompilerCase #PB_OS_Windows ; ----------------------------------------------
    Procedure ColumnHeaderClickCallback(WindowHandle.I, Msg.I, WParam.I,
      LParam.I)
      Shared CallbackEntry()

      Protected Result.I
      Protected *Header.HD_NOTIFY

      ForEach CallbackEntry()
        If WindowHandle = GadgetID(CallbackEntry()\ListIconID)
          Break
        EndIf
      Next

      Result = CallWindowProc_(CallbackEntry()\DefaultCallback, WindowHandle,
        Msg, WParam, LParam)

      If Msg = #WM_NOTIFY
        *Header = LParam

        If *Header\hdr\code = #HDN_ITEMCLICK
          PostEvent(#PB_Event_Gadget, CallbackEntry()\WindowID,
            CallbackEntry()\ListIconID, #PB_EventType_LeftClick,
            *Header\iItem + 1)
        EndIf
      EndIf

      ProcedureReturn Result
    EndProcedure

    Procedure SetGadgetCallback(WindowID.I, ListIconID.I)
      Shared CallbackEntry()

      AddElement(CallbackEntry())
      CallbackEntry()\WindowID = WindowID
      CallbackEntry()\ListIconID = ListIconID
      CallbackEntry()\DefaultCallback = SetWindowLongPtr_(GadgetID(CallbackEntry()\ListIconID),
        #GWL_WNDPROC, @ColumnHeaderClickCallback())
    EndProcedure ; -----------------------------------------------------------
CompilerEndSelect

; ========================================== SPECIFIC CODE FOR TESTING

Enumeration
  #zero
  #windows_nb
  #list1_nb
  #list2_nb
EndEnumeration

#Title_column1$ = "Name"
#Title_column2$ = "Address"

Define GadgetID.I

OpenWindow(#windows_nb, 0, 0, 950, 150, "Detect left click on header cell",#PB_Window_SystemMenu | #PB_Window_ScreenCentered)
ListIconGadget(#list1_nb, 10, 10, 430, WindowHeight(#windows_nb) - 20, #Title_column1$,
  110, #PB_ListIcon_FullRowSelect)
AddGadgetColumn(#list1_nb, 1, #Title_column2$, 300)
AddGadgetItem(#list1_nb, -1, "Harry Rannit" + #LF$ +
  "12 Parliament Way, Battle Street, By the Bay")
AddGadgetItem(#list1_nb, -1, "Ginger Brokeit"+ #LF$ +
  "130 PureBasic Road, BigTown, CodeCity")
AddGadgetItem(#list1_nb, -1, "Didi Foundit"+ #LF$ +
  "321 Logo Drive, Mouse House, Downtown")

ListIconGadget(#list2_nb, 460, 10, 430, WindowHeight(#windows_nb) - 20, #Title_column1$,
  110, #PB_ListIcon_FullRowSelect)
AddGadgetColumn(#list2_nb, 1, #Title_column2$, 300)
AddGadgetItem(#list2_nb, -1, "Harry Rannit" + #LF$ +
  "12 Parliament Way, Battle Street, By the Bay")
AddGadgetItem(#list2_nb, -1, "Ginger Brokeit"+ #LF$ +
  "130 PureBasic Road, BigTown, CodeCity")
AddGadgetItem(#list2_nb, -1, "Didi Foundit"+ #LF$ +
  "321 Logo Drive, Mouse House, Downtown")

SetGadgetCallback(#windows_nb, #list1_nb)
SetGadgetCallback(#windows_nb, #list2_nb)

Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      CompilerIf #PB_Compiler_OS = #PB_OS_Windows
        ForEach CallbackEntry()
          SetWindowLongPtr_(GadgetID(CallbackEntry()\ListIconID),
            #GWL_WNDPROC, CallbackEntry()\DefaultCallback)
        Next
      CompilerEndIf

      Break
    Case #PB_Event_Gadget
      GadgetID = EventGadget()

      Select GadgetID
        Case #list1_nb, #list2_nb
          If EventType() = #PB_EventType_LeftClick
            If EventData()
              Debug "Left click on header of column " + Str(EventData() - 1) + " gadget=" + Str(GadgetID)
            Else
              Debug "Left click on row " + Str(GetGadgetState(GadgetID)) + " gadget=" + Str(GadgetID)
            EndIf
          EndIf
      EndSelect
  EndSelect
ForEver
I will also implemented the above changes in my first example.
Thank you again, Jean.

Re: How to detect listicongadget column header click

Posted: Sun Mar 23, 2014 9:45 pm
by CONVERT
Thanks a lot to you, Shardik!!!

What's a very great job!

Re: How to detect listicongadget column header click

Posted: Sat Jun 25, 2016 10:22 am
by Lebostein
There seems a bug in the Mac OS version. This code deactivates the #PB_EventType_Change event!! Take the code above and replace the last lines (see below). If you click (or select a new entry with arrow keys) in the left list, then no #PB_EventType_Change event is triggered. If you click (or select a new entry with arrow keys) in the right list, then a #PB_EventType_Change event is triggered:

Code: Select all

SetGadgetCallback(#windows_nb, #list1_nb)
;SetGadgetCallback(#windows_nb, #list2_nb) ; -> gadget 2 without that callback

Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      CompilerIf #PB_Compiler_OS = #PB_OS_Windows
        ForEach CallbackEntry()
          SetWindowLongPtr_(GadgetID(CallbackEntry()\ListIconID),
            #GWL_WNDPROC, CallbackEntry()\DefaultCallback)
        Next
      CompilerEndIf

      Break
    Case #PB_Event_Gadget
      GadgetID = EventGadget()

      Select GadgetID
        Case #list1_nb, #list2_nb
          Select EventType()
          Case #PB_EventType_LeftClick
            If EventData()
              Debug "Left click on header of column " + Str(EventData() - 1) + " gadget=" + Str(GadgetID)
            Else
              Debug "Left click on row " + Str(GetGadgetState(GadgetID)) + " gadget=" + Str(GadgetID)
            EndIf
          Case #PB_EventType_Change
            Debug "changed"
          EndSelect
      EndSelect
  EndSelect
ForEver

Re: How to detect listicongadget column header click

Posted: Sun Aug 07, 2016 8:16 am
by Shardik
Lebostein wrote:There seems a bug in the Mac OS version. This code deactivates the #PB_EventType_Change event!!
I have posted a modified version for MacOS here which also generates #PB_EventType_Change events.

Re: How to detect listicongadget column header click

Posted: Sun Aug 07, 2016 11:00 am
by CONVERT
Thanks Shardik.

Re: How to detect listicongadget column header click

Posted: Mon Aug 08, 2016 7:31 am
by Kukulkan

Re: How to detect listicongadget column header click

Posted: Thu Nov 01, 2018 2:22 pm
by Rinzwind
Can someone explain me why common needed functionality like this is (still) not included in the gadget library itself?