How to detect listicongadget column header click
Posted: Thu Jan 30, 2014 4:38 pm
I dont find this thread anymore where discussed about that?
Karu
Karu
http://www.purebasic.com
https://www.purebasic.fr/english/
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: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.
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
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
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())
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)
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
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
I have posted a modified version for MacOS here which also generates #PB_EventType_Change events.Lebostein wrote:There seems a bug in the Mac OS version. This code deactivates the #PB_EventType_Change event!!