Page 3 of 3

Re: ComboBoxGadget in Editable ListIconGadget [Windows]

Posted: Sat Oct 12, 2024 10:02 pm
by minimy
wow! thanks RASHAD! Very nice work as allways! :wink:
Thanks for share! +1

Re: ComboBoxGadget in Editable ListIconGadget [Windows]

Posted: Sun Oct 13, 2024 6:42 am
by PBJim
minimy wrote: Sat Oct 12, 2024 10:02 pm wow! thanks RASHAD! Very nice work as allways! :wink: Thanks for share! +1
Indeed, thanks likewise Rashad. It works well and is more robust now.

Incidentally, it's necessary to check for row - 1 within Case #WM_LBUTTONDBLCLK because we need to check if the user double-clicks an empty line. It edits the column heading otherwise :

Code: Select all

      If  row = -1                      ; <----- Check for empty line
        editflag = 0
      Else
        editflag = 1
        MoveWindow_(GadgetID(2),r\left+GadgetX(0)+2,r\top+GadgetY(0)+2,r\right-r\left,r\bottom-r\top,1)
        SetGadgetText(2,GetGadgetItemText(0,row,col))
        SetFocus_(GadgetID(2))
      EndIf

Re: ComboBoxGadget in Editable ListIconGadget [Windows]

Posted: Sun Oct 13, 2024 8:31 am
by RASHAD
@minimy ,PBJim
You are welcome
Previous post updated

Re: ComboBoxGadget in Editable ListIconGadget [Windows]

Posted: Sun Nov 03, 2024 4:54 pm
by PBJim
Hi Rashad,
Hope you might be able to help. I added a new function to the editable ListIconGadget, to create a new empty item in the list. I implemented this as a double-click on the blank line below the last item in the list :

Code: Select all

  If row = -1    ; <------------------   Double-click empty row to create new line
    AddGadgetItem(ListIcon, -1, "")
    editflag = 0
I'm not sure how to get StringGadget to automatically appear at the new line (in column 0 only), to allow the user to input the value. It needs to be calculated at the correct row to make the StringGadget input appear at the right place. I was never really sure how struct 'r' is calculated. Could you possibly help me with it? Many thanks. Jim

Code: Select all

; **
; **  Grid input test routine
; **  Removed ComboBoxGadget
; **
; **  https://www.purebasic.fr/english/viewtopic.php?t=55781
; **

EnableExplicit

Global oldCallback,ListIcon,LIColor,Oldr,Oldc,editflag

Define Quit


Procedure LIcallback(hwnd, msg, wparam, lparam) 
  
  Define result.i
  Define *NMHDR.NMHDR
  Define *phdn.NMHEADER
  Define r.RECT
  Define pInfo.LVHITTESTINFO
  Define col, row
  
  result = CallWindowProc_(oldCallback, hwnd, msg, wparam, lparam)
  Select msg
    Case #WM_NOTIFY 
      *NMHDR.NMHDR = lParam
      If *nmhdr\code = #HDN_ITEMCHANGING And *NMHDR\code = #HDN_FIRST
        *phdn.NMHEADER = lParam                 
        If  editflag = 1
          r.RECT\top = Oldc
          r.RECT\left = #LVIR_BOUNDS
          SendMessage_(GadgetID(ListIcon), #LVM_GETSUBITEMRECT, Oldr, r)
          If Oldc = 0
            r\right = r\left+SendMessage_(GadgetID(ListIcon), #LVM_GETCOLUMNWIDTH, 0, 0)
          EndIf
          MoveWindow_(GadgetID(2),r\left+GadgetX(ListIcon)+2,r\top+GadgetY(ListIcon)+2,r\right-r\left,r\bottom-r\top,1)  
          SetFocus_(GadgetID(2))
        EndIf
      EndIf
      
    Case #WM_LBUTTONDOWN
      SetGadgetState(ListIcon,-1)
      MoveWindow_(GadgetID(2),0,0,0,0,1)
      If editflag = 1 And GetGadgetText(2) <> ""
        SetGadgetItemText(ListIcon, Oldr,GetGadgetText(2),Oldc)
      EndIf
      pInfo.LVHITTESTINFO
      pInfo\pt\x = (lParam & $FFFF) 
      pInfo\pt\y = (lParam>> 16 & $FFFF)                    
      
      SendMessage_(GadgetID(ListIcon),#LVM_SUBITEMHITTEST,0,@pInfo)
      SetGadgetItemColor(ListIcon,OLdr,#PB_Gadget_FrontColor,#Black ,Oldc)
      SetGadgetItemColor(ListIcon,Oldr, #PB_Gadget_BackColor, LIColor,Oldc)
      SetGadgetItemColor(ListIcon,pInfo\iItem,#PB_Gadget_FrontColor,#White ,pInfo\iSubItem)
      SetGadgetItemColor(ListIcon,pInfo\iItem, #PB_Gadget_BackColor,GetSysColor_(#COLOR_HIGHLIGHT),pInfo\iSubItem)

      Oldr = pInfo\iItem
      Oldc = pInfo\iSubItem
      editflag = 0

    Case #WM_LBUTTONDBLCLK      
      r.RECT\top = Oldc
      r.RECT\left = #LVIR_BOUNDS
      SendMessage_(GadgetID(ListIcon), #LVM_GETSUBITEMRECT, Oldr, r)
      SendMessage_(GadgetID(ListIcon), #LVM_GETHOTITEM, 0,0)
      If Oldc = 0
        r\right = r\left+SendMessage_(GadgetID(ListIcon), #LVM_GETCOLUMNWIDTH, 0, 0)
      EndIf        
      pInfo.LVHITTESTINFO
      pInfo\pt\x = (lParam & $FFFF) 
      pInfo\pt\y = (lParam>> 16 & $FFFF)                    
      SendMessage_(GadgetID(ListIcon),#LVM_SUBITEMHITTEST,0,@pInfo)
      row = pInfo\iItem
      col = pinfo\iSubItem

      If row = -1
        AddGadgetItem(ListIcon, -1, "")  ; <------------------   Double-click empty row to create new line
        editflag = 0
      Else
        editflag = 1
        MoveWindow_(GadgetID(2),r\left+GadgetX(ListIcon)+2,r\top+GadgetY(ListIcon)+2,r\right-r\left,r\bottom-r\top,1)
        SetGadgetText(2,GetGadgetItemText(ListIcon,row,col))
        SetFocus_(GadgetID(2))
      EndIf
      
    Case #WM_VSCROLL,#WM_HSCROLL
      MoveWindow_(GadgetID(2),0,0,0,0,1)

      SetGadgetItemColor(ListIcon,OLdr,#PB_Gadget_FrontColor,#Black ,Oldc)
      SetGadgetItemColor(ListIcon,Oldr, #PB_Gadget_BackColor, LIColor,Oldc)

      
  EndSelect
  ProcedureReturn result
EndProcedure

LoadFont(0,"Tahoma",10) 

OpenWindow(0,0,0,840,480,"Test",#PB_Window_SystemMenu| #PB_Window_ScreenCentered| #PB_Window_SizeGadget)
ListIcon = ListIconGadget(#PB_Any,10,10,821,470,"Column 1",200,#PB_ListIcon_GridLines|#WS_CLIPSIBLINGS )
AddGadgetColumn(ListIcon,1,"Column 2",200) 
AddGadgetColumn(ListIcon,2,"Column 3",200) 
AddGadgetColumn(ListIcon,3,"Column 4",200)

AddGadgetItem(ListIcon, -1, "Row 1, Col 1" + Chr(10) +
                         "Row 1, Col 2" + Chr(10) +
                         "Row 1, Col 3" + Chr(10) +
                         "Row 1, Col 4" + Chr(10))

; **
; **  Set colour of grid
; **
SetGadgetColor(ListIcon, #PB_Gadget_BackColor, $F7F7F7)

; **
; **  Grid input string
; **
StringGadget(2,0,0,0,0,"",#ES_MULTILINE|#WS_CLIPSIBLINGS)
SendMessage_(GadgetID(2), #EM_SETMARGINS, #EC_LEFTMARGIN, 3)
BringWindowToTop_(GadgetID(2))
oldCallback = SetWindowLongPtr_(GadgetID(ListIcon), #GWL_WNDPROC, @LIcallback())

SetGadgetFont(ListIcon,FontID(0))
SetGadgetFont(2,FontID(0))
If GetGadgetColor(ListIcon, #PB_Gadget_BackColor) < 0 
  LIColor = #White
Else
  LIColor =  GetGadgetColor(ListIcon, #PB_Gadget_BackColor)
EndIf

AddKeyboardShortcut(0, #PB_Shortcut_Return, 15)
AddKeyboardShortcut(0, #PB_Shortcut_Escape, 20)

Repeat
  Select WaitWindowEvent()
      
    Case #PB_Event_CloseWindow
      Quit = 1
      
    Case #PB_Event_Menu    
      Select EventMenu()
        Case 15
          If GetActiveGadget() = 2
            SetGadgetItemText(ListIcon, Oldr,GetGadgetText(2),Oldc)
            MoveWindow_(GadgetID(2),0,0,0,0,1)
            editflag = 0
          EndIf
        Case 20
          If GetActiveGadget() = 2
            MoveWindow_(GadgetID(2),0,0,0,0,1)
            editflag = 0
          EndIf               
      EndSelect
      
    Case #WM_KEYDOWN
      If GetActiveGadget() = 2 And  EventwParam() = 27
        MoveWindow_(GadgetID(2),0,0,0,0,1)
        editflag = 0
      ElseIf GetActiveGadget() = 2 And  EventwParam() = 13
        SetGadgetItemText(ListIcon, Oldr,GetGadgetText(2),Oldc)
        MoveWindow_(GadgetID(2),0,0,0,0,1)
        editflag = 0
      EndIf      
      
    Case #PB_Event_Gadget
      
  EndSelect 
  
Until Quit = 1
End

Re: ComboBoxGadget in Editable ListIconGadget [Windows]

Posted: Sun Mar 09, 2025 6:45 pm
by Michael Vogel
Hi Rashad, very nice code.
But when using the mouse (select a cell) and the keyboard arrow keys then (cursor down, etc.) two cells seem to be active (blue background).

Re: ComboBoxGadget in Editable ListIconGadget [Windows]

Posted: Sun Mar 09, 2025 8:18 pm
by RASHAD
Hi MV :)
Time to enhance the snippet

Code: Select all

Global oldCallback,ListIcon,LIColor,Oldr,Oldc,editflag

Procedure LIcallback(hwnd, msg, wparam, lparam) 
  result = CallWindowProc_(oldCallback, hwnd, msg, wparam, lparam)
  Select msg
    Case #WM_NOTIFY 
      *NMHDR.NMHDR = lParam
      If *nmhdr\code = #HDN_ITEMCHANGING And *NMHDR\code = #HDN_FIRST
        *phdn.NMHEADER = lParam                 
        If  editflag = 1
          r.RECT\top = Oldc
          r.RECT\left = #LVIR_BOUNDS
          SendMessage_(GadgetID(0), #LVM_GETSUBITEMRECT, Oldr, r)
          If Oldc = 0
            r\right = r\left+SendMessage_(GadgetID(0), #LVM_GETCOLUMNWIDTH, 0, 0)
          EndIf
          MoveWindow_(GadgetID(2),r\left+GadgetX(0)+2,r\top+GadgetY(0)+2,r\right-r\left,r\bottom-r\top,1)  
          SetFocus_(GadgetID(2))
        EndIf
      EndIf
      
    Case #WM_LBUTTONDOWN
      SetGadgetState(0,-1)
      MoveWindow_(GadgetID(2),0,0,0,0,1)
      If editflag = 1 And GetGadgetText(2) <> ""
        SetGadgetItemText(0, Oldr,GetGadgetText(2),Oldc)
        SetGadgetState(0,-1) 
      EndIf
      pInfo.LVHITTESTINFO
      pInfo\pt\x = (lParam & $FFFF) 
      pInfo\pt\y = (lParam>> 16 & $FFFF)                    
      SendMessage_(ListIcon,#LVM_SUBITEMHITTEST,0,@pInfo)
      If  pInfo\iSubItem = 4 And Run =0              
        SendMessage_(GadgetID(0),#WM_HSCROLL,#SB_PAGERIGHT,0)
        Run = 1
        r.RECT 
        r\top  = pInfo\iSubItem 
        r\left = #LVIR_BOUNDS 
        SendMessage_(GadgetID(0), #LVM_GETSUBITEMRECT, pInfo\iItem, r)
        MoveWindow_(GadgetID(5),r\left+GadgetX(0)+2,r\top+GadgetY(0)+2,r\right-r\left,r\bottom-r\top,1)
      Else
        Run =0  
        MoveWindow_(GadgetID(5),0,0,0,0,1)
        SetGadgetItemState(0,pInfo\iItem,#PB_ListIcon_Selected )
      EndIf          
      editflag = 0
      Oldr = pInfo\iItem
      Oldc = pInfo\iSubItem      
      
    Case #WM_LBUTTONDBLCLK
      SetGadgetState(0,-1)
      editflag = 1
      r.RECT\top = Oldc
      r.RECT\left = #LVIR_BOUNDS
      SendMessage_(GadgetID(0), #LVM_GETSUBITEMRECT, Oldr, r)
      SendMessage_(GadgetID(0), #LVM_GETHOTITEM, 0,0)
      If Oldc = 0
        r\right = r\left+SendMessage_(GadgetID(0), #LVM_GETCOLUMNWIDTH, 0, 0)
      EndIf
      SetGadgetText(2,"")
      MoveWindow_(GadgetID(2),r\left+GadgetX(0)+2,r\top+GadgetY(0)+2,r\right-r\left,r\bottom-r\top,1)
      SetFocus_(GadgetID(2))
      
    Case #WM_VSCROLL,#WM_HSCROLL
      MoveWindow_(GadgetID(2),0,0,0,0,1)
      MoveWindow_(GadgetID(5),0,0,0,0,1)      
      
  EndSelect
  ProcedureReturn result
EndProcedure

Procedure sizeCB()
  ResizeGadget(1,10,WindowHeight(0)-30,#PB_Ignore,#PB_Ignore)
  ResizeGadget(0,10,10,WindowWidth(0)-20,WindowHeight(0)-60)
EndProcedure

LoadFont(0,"Tahoma",10) 

OpenWindow(0,0,0,640,480,"Test",#PB_Window_SystemMenu| #PB_Window_ScreenCentered| #PB_Window_SizeGadget)
ListIcon = ListIconGadget(0,10,10,620,450,"Column 0",200,#PB_ListIcon_FullRowSelect |#PB_ListIcon_AlwaysShowSelection|#PB_ListIcon_GridLines|#WS_CLIPSIBLINGS );|#LVS_EDITLABELS) 
AddGadgetColumn(0,1,"Column 1",210) 
AddGadgetColumn(0,2,"Column 2",200) 
AddGadgetColumn(0,3,"Column 3",200)
AddGadgetColumn(0,4,"Column 4",200)
AddGadgetColumn(0,5,"Column 5",100) 

For i = 0 To 16 
  linestr.s = LSet(Str(i),3," ") 
  AddGadgetItem(0, -1, "Text on Line "+linestr+" in Column 1"+Chr(10)+"Text on Line "+linestr+" in Column 2" + Chr(10)+"Text on Line "+linestr+" in Column 3" + Chr(10)+"Text on Line "+linestr+" in Column 3"+ Chr(10)+"") 
Next
SetGadgetColor(0, #PB_Gadget_BackColor,$DFFEFD)
ButtonGadget(1,10,450,150,24,"Add new ROW")
StringGadget(2,0,0,0,0,"",#ES_MULTILINE|#WS_CLIPSIBLINGS);|#PB_String_BorderLess)
SendMessage_(GadgetID(2), #EM_SETMARGINS, #EC_LEFTMARGIN, 3)
BringWindowToTop_(GadgetID(2))
oldCallback = SetWindowLongPtr_(ListIcon, #GWL_WNDPROC, @LIcallback())

SetGadgetFont(0,FontID(0))
SetGadgetFont(2,FontID(0))
If GetGadgetColor(0, #PB_Gadget_BackColor) < 0 
  LIColor = #White
Else
  LIColor =  GetGadgetColor(0, #PB_Gadget_BackColor)
EndIf

ComboBoxGadget(5,0,0,0,0,#WS_CLIPSIBLINGS)
For a = 1 To 5
  AddGadgetItem(5, -1,"ComboBox item " + Str(a))
Next
BringWindowToTop_(GadgetID(5))
BindEvent(#PB_Event_SizeWindow,@sizeCB())
Repeat
  Select WaitWindowEvent()
      
    Case #PB_Event_CloseWindow
      Quit = 1
      
    Case #WM_KEYDOWN
      If GetActiveGadget() = 2 And  EventwParam() = 27
        MoveWindow_(GadgetID(2),0,0,0,0,1)
        editflag = 0
      ElseIf GetActiveGadget() = 2 And  EventwParam() = 13
        SetGadgetItemText(0, Oldr,GetGadgetText(2),Oldc)
        MoveWindow_(GadgetID(2),0,0,0,0,1)
        SetGadgetState(0,-1) 
        editflag = 0
      EndIf
      
    Case #PB_Event_Menu
      Select EventMenu()
        Case 1            
      EndSelect
      
    Case #PB_Event_Gadget
      Select EventGadget()
        Case 1
          sel = GetGadgetState(0)
          linestr.s = LSet(Str(CountGadgetItems(0)),3," ")
          AddGadgetItem(0, -1, "Text on Line "+linestr+" in Column 1"+Chr(10)+"Text on Line "+linestr+" in Column 2" + Chr(10)+"Text on Line "+linestr+" in Column 3" + Chr(10)+"Text on Line "+linestr+" in Column 3"+ Chr(10)+"")
          SetGadgetItemState(0,sel,#PB_ListIcon_Selected)
          SetActiveGadget(0)
        Case 5
          MoveWindow_(GadgetID(5),0,0,0,0,1)
          SetGadgetItemText(0, Oldr,GetGadgetText(5),Oldc)
      EndSelect
      
      
    Case #WM_SIZE
      ResizeGadget(0,10,10,WindowWidth(0)-20,WindowHeight(0)-60)
      
  EndSelect 
  
Until Quit = 1
End

Re: ComboBoxGadget in Editable ListIconGadget [Windows]

Posted: Sun Mar 09, 2025 11:39 pm
by BarryG
That's so good, Rashad! Thanks.

Re: ComboBoxGadget in Editable ListIconGadget [Windows]

Posted: Mon Mar 10, 2025 12:59 am
by RASHAD
Thanks BarryG
Much appreciated

Re: ComboBoxGadget in Editable ListIconGadget [Windows]

Posted: Mon Mar 10, 2025 1:23 am
by BarryG
Definitely has that Excel feeling (posted this comment for future searches). ;)

Re: ComboBoxGadget in Editable ListIconGadget [Windows]

Posted: Tue Mar 11, 2025 10:23 am
by PBJim
Thanks to Rashad for continuing to update this code. Incidentally, I don't think the latest changes were applied to what was actually the latest version from October 2024, as it does not allow editing of existing cell values — the last refinement made at this link : https://www.purebasic.fr/english/viewto ... 8a#p628938

That version sets the input with the below line :

Code: Select all

SetGadgetText(2,GetGadgetItemText(0,row,col))
For the record, I've been working with this code since last year and refined it further, also removing the combobox function, as it wasn't needed and added unwanted complexity to the code. On the whole it works well, if a little buggy in places, but even so it still offers a great basis for providing a grid input. It wasn't easy to refine — it would benefit from some comments.

But I'd love to see this be developed further and made more robust as it looks quite professional and is suited to business applications — which the 'Said' version is far from suited. A cross-hairs cell pointer in a business application, definitely will not go down well with users. :D

Re: ComboBoxGadget in Editable ListIconGadget [Windows]

Posted: Sun Jun 08, 2025 8:04 am
by a_carignan
Hello, I would like an example with an editable combobox on column 5 and why not a dategadget and thus have a complete example of editing a listgadget with all the compatible editing gadgets. Thank you in advance.