ListIconGadget - detect a click on the header?

Just starting out? Need help? Post your questions and find answers here.
User avatar
blueznl
PureBasic Expert
PureBasic Expert
Posts: 6166
Joined: Sat May 17, 2003 11:31 am
Contact:

ListIconGadget - detect a click on the header?

Post by blueznl »

I'm fooling around a bit with the ListIconGadget, and I was wondering if there is a way to separate clicks on the top (header) and the first row.

I'm studying the callback based approaches (viewtopic.php?t=80375) but I was wondering if it could be done without a callback.

For now, I use this to detect the cell that was clicked upon:

Code: Select all

Procedure.i x_getlisticonselected(gadget_nr.i,window_nr.i = 0)                                   ; find selected cell in a listicongadget
  Protected gx.i, gy.i, pinfo.LVHITTESTINFO
  ; global x_retval.i, x_retval_x.i, x_retval_y.i
  ;
  ; *** find the cell in a listicongadget under the mouse
  ;
  ; in:     gadget_nr.i       - pb listicongadget nr
  ;         window_nr.i       - pb window number
  ;
  ; retval: n
  ;
  ; out:    x_retval.i        - row
  ;         x_retval_x.i      - column
  ;         x_retval_y.i      - row
  ;
  gx = GadgetX(gadget_nr)
  gy = GadgetY(gadget_nr)
  pinfo\pt\x = WindowMouseX(window_nr)-gx
  pinfo\pt\y = WindowMouseY(window_nr)-gy
  SendMessage_(GadgetID(gadget_nr),#LVM_SUBITEMHITTEST,0,@pinfo)
  ;
  x_retval_x = pInfo\iSubItem
  x_retval_y = pInfo\iItem
  x_retval = x_retval_y
  ;
  ProcedureReturn x_retval
EndProcedure
This works perfectly, however :-) I was thinking about (ab)using this for a header click. The idea was to use a click on the header to sort the column, but... if I abuse :-) the event returned by PB's WaitWindowEvent(), I can't find a way to discern between a click on the header and on the first cell.

(A propos, is there a way to find the clicked cell without relying on WinApi?)

Now, abusing the event mechanism a bit this is what I'm trying to accomplish: a click on a header should trigger a menu event. (In that menu event I do some sorting etc.) The best I could come up with is:

Code: Select all

    event = WaitWindowEvent()
    If event = 514
    ;
      x_getlisticonselected(#g_filelist_nr,#w_main_nr)
      If x_retval_x >= 0 And x_retval_y = 0
        column = x_retval_x
        event = #PB_Event_Menu
        event_menu = #menu_filelist_sort
      EndIf
    EndIf
In more simple words, is there a way to detect a click on the header of a ListIconGadget? (Preferably without callbacks.)
( 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... )
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4946
Joined: Sun Apr 12, 2009 6:27 am

Re: ListIconGadget - detect a click on the header?

Post by RASHAD »

No CallBack
For Windows

Code: Select all


OpenWindow(0,0,0,600,400,"ListIcon Test",#PB_Window_ScreenCentered|#PB_Window_SystemMenu)

ListIconGadget(0,10,10,580,380,"Column 0",90,#PB_ListIcon_GridLines)
SetGadgetColor(0, #PB_Gadget_BackColor, $E8FFFF)
AddGadgetColumn(0,1,"Column 1",90)
AddGadgetColumn(0,2,"Column 2",90)

  For i=0 To 8
    AddGadgetItem(0,-1,"R"+Str(i)+"/C0"+Chr(10)+"R"+Str(i)+"/C1"+Chr(10)+"R"+Str(i)+"/C2")
  Next
hi.LVHITTESTINFO
Repeat
  event = WaitWindowEvent()
    Select event      
    Case #PB_Event_CloseWindow
        Q = 1
        
    Case #WM_LBUTTONUP,#WM_RBUTTONUP
        GetCursorPos_(@p.POINT)
        ScreenToClient_(GadgetID(0), p)
        hi\pt\x = p\x
        hi\pt\y = p\y  
        SendMessage_(GadgetID(0),#LVM_SUBITEMHITTEST,0,@hi)
        *hi.LVHITTESTINFO = @hi
        If event = 514
          Debug "LMB Clicked : "+Str(*hi\iSubItem)
        ElseIf event=517
          Debug "RMB Clicked : "+Str(*hi\iSubItem)
        EndIf
          
  EndSelect
Until Q = 1
Egypt my love
User avatar
blueznl
PureBasic Expert
PureBasic Expert
Posts: 6166
Joined: Sat May 17, 2003 11:31 am
Contact:

Re: ListIconGadget - detect a click on the header?

Post by blueznl »

Ah, not exactly what I meant. Maybe I posed the question wrong.

How to differentiate between header clicks and top line clicks, without a callback?

(Got the callback working, thanks, but I was just wondering if there was another way, which would be easier to integrate with the rest of the code I use).
( 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... )
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4946
Joined: Sun Apr 12, 2009 6:27 am

Re: ListIconGadget - detect a click on the header?

Post by RASHAD »

Modified the last snippet

Code: Select all



OpenWindow(0,0,0,600,400,"ListIcon Test",#PB_Window_ScreenCentered|#PB_Window_SystemMenu)

ListIconGadget(0,10,10,580,380,"Column 0",90,#PB_ListIcon_GridLines)
GetClientRect_(GadgetID(0), @lr.RECT)
Header = SendMessage_(GadgetID(0), #LVM_GETHEADER, 0, 0)
GetClientRect_(Header, @hr.RECT)
SetGadgetColor(0, #PB_Gadget_BackColor, $E8FFFF)
AddGadgetColumn(0,1,"Column 1",90)
AddGadgetColumn(0,2,"Column 2",90)

For i=0 To 8
  AddGadgetItem(0,-1,"R"+Str(i)+"/C0"+Chr(10)+"R"+Str(i)+"/C1"+Chr(10)+"R"+Str(i)+"/C2")
Next
hi.LVHITTESTINFO
Repeat
  event = WaitWindowEvent()
    Select event      
    Case #PB_Event_CloseWindow
        Q = 1
        
    Case #WM_LBUTTONDOWN,#WM_RBUTTONDOWN
        GetCursorPos_(@p.POINT)
        ScreenToClient_(GadgetID(0), p)
        hi\pt\x = p\x
        hi\pt\y = p\y  
        SendMessage_(GadgetID(0),#LVM_SUBITEMHITTEST,0,@hi)
        *hi.LVHITTESTINFO = @hi
        If PtInRect_(@hr, PeekQ(p))
          Debug "Header"
        ElseIf PtInRect_(@lr, PeekQ(p))
          Debug "ListIcon"
        EndIf
        If event = 513
          Debug "LMB Clicked : "+Str(*hi\iSubItem)
        ElseIf event=516
          Debug "RMB Clicked : "+Str(*hi\iSubItem)
        EndIf
          
  EndSelect
Until Q = 1

Edit : Bug fixed

Last edited by RASHAD on Sun Jan 01, 2023 11:05 pm, edited 1 time in total.
Egypt my love
User avatar
blueznl
PureBasic Expert
PureBasic Expert
Posts: 6166
Joined: Sat May 17, 2003 11:31 am
Contact:

Re: ListIconGadget - detect a click on the header?

Post by blueznl »

I've modified my code to use the callback. I noticed that on your last sample the cell 0,0 sometimes doesn't trigger sometimes...

Oh well, it's not that important, it works fine the way it is now using the callback. I typically have my main loop setup like this to handle asynchronous events:

Code: Select all

  ;   1. set up action if a callback procedure has requested one
  ;   2. if there are no actions then process windows events (these can set up further actions as well)
  ;   3. then execute any actions that are set up
  ;   4. rinse and repeat
It all works fine now. Let me post a little clip...
( 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... )
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4946
Joined: Sun Apr 12, 2009 6:27 am

Re: ListIconGadget - detect a click on the header?

Post by RASHAD »

Previous post updated
Column 0 bug fixed
Egypt my love
User avatar
blueznl
PureBasic Expert
PureBasic Expert
Posts: 6166
Joined: Sat May 17, 2003 11:31 am
Contact:

Re: ListIconGadget - detect a click on the header?

Post by blueznl »

Argh! You're too fast :-)
( 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... )
User avatar
blueznl
PureBasic Expert
PureBasic Expert
Posts: 6166
Joined: Sat May 17, 2003 11:31 am
Contact:

Re: ListIconGadget - detect a click on the header?

Post by blueznl »

But... it works. Sorting using RMB, or clicking on the header. Context sensitive pop up menu (hides delete or view when there are no items etc.).

It's all pretty simple, but oh, even simple things can feel good :-)

https://youtu.be/PEYoIvQtbb0
( 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... )
Post Reply