SetGadgetItemColor doesn't work after windowcallback code

Just starting out? Need help? Post your questions and find answers here.
User avatar
mk-soft
Always Here
Always Here
Posts: 6249
Joined: Fri May 12, 2006 6:51 pm
Location: Germany

Re: SetGadgetItemColor doesn't work after windowcallback cod

Post by mk-soft »

Here first a huge thanks to RASHAD for the API code for the callback.

So I changed the structure so that you can define your own color for each column.

Don't forget to use 'RemoveListIconGadgetItem(Gadget, Item) for remove items.
Otherwise there will be a memory leak.

Update v1.02
- Now as new Functions
- Added Selection Color

Code: Select all

;EnableExplicit

#LVM_GETHEADER = #LVM_FIRST + 31

#Gadget_MyInfo_Titles = 0

Enumeration fonts
  #FontStrikeoutYes
  #FontStrikeoutNo
  #FontItalic
EndEnumeration

Structure udtColumn
  Font.i
  TextColor.i
  BackColor.i
EndStructure

Structure udtItemData
  Ident.i
  UserData.i
  Array Column.udtColumn(0)
EndStructure

LoadFont(#FontStrikeoutYes, "", 10, #PB_Font_StrikeOut)
LoadFont(#FontStrikeoutNo, "", 10)
LoadFont(#FontItalic, "", 10, #PB_Font_Italic | #PB_Font_Bold)

Procedure.i BlendColor(Color1.i, Color2.i, Scale.i = 50) ; Thanks to Thorsten
  Protected.i R1, G1, B1, R2, G2, B2
  Protected.f Blend = Scale / 100
  R1 = Red(Color1): G1 = Green(Color1): B1 = Blue(Color1)
  R2 = Red(Color2): G2 = Green(Color2): B2 = Blue(Color2)
  ProcedureReturn RGB((R1*Blend) + (R2 * (1 - Blend)), (G1*Blend) + (G2 * (1 - Blend)), (B1*Blend) + (B2 * (1 - Blend)))
EndProcedure
  
Procedure SetListIconGadgetData(Gadget, Item, Font = #PB_Ignore, TextColor = #Black, BackColor = #White, Column = 0)
  Protected *ItemData.udtItemData
  *ItemData = GetGadgetItemData(Gadget, Item)
  If *ItemData = 0
    *ItemData = AllocateStructure(udtItemData)
    *ItemData\Ident = $AA2019EE
    SetGadgetItemData(Gadget, Item, *ItemData)
  EndIf
  With *ItemData
    If Column > ArraySize(\Column())
      ReDim \Column(Column)
    EndIf
    If Font = #PB_Ignore And \Column(Column)\Font = 0
      \Column(Column)\Font = #PB_Default
    Else
      \Column(Column)\Font = Font
    EndIf
    \Column(Column)\TextColor = TextColor
    \Column(Column)\BackColor = BackColor
  EndWith
EndProcedure

Procedure RemoveListIconGadgetItem(Gadget, Item)
  Protected *ItemData.udtItemData, index, count
  If Item = #PB_All
    count = CountGadgetItems(Gadget) - 1
    For index = 0 To count
      *ItemData = GetGadgetItemData(Gadget, Index)
      If *ItemData And *ItemData\Ident = $AA2019EE
        FreeStructure(*ItemData)
      EndIf
    Next
    ClearGadgetItems(Gadget)
  Else
    *ItemData = GetGadgetItemData(Gadget, Item)
    If *ItemData And *ItemData\Ident = $AA2019EE
      FreeStructure(*ItemData)
    EndIf
    RemoveGadgetItem(Gadget, Item)
  EndIf
EndProcedure

Procedure DrawListIconGadgetItem(*lvCD.NMLVCUSTOMDRAW, *ItemData.udtItemData)
  Protected thisRow, thisCol, thisText.s, hBrush, TextColor, BackColor
  
  If *ItemData
    If *ItemData\Ident <> $AA2019EE
      ProcedureReturn 0
    EndIf
    With *ItemData
      thisRow = *lvCD\nmcd\dwItemSpec
      thisCol = *lvCD\iSubItem
      ; Get text from ListIcon
      thisText = GetGadgetItemText(0, thisRow ,thisCol)
      ; Limit thisCol to the available column data
      If thisCol > ArraySize(\Column())
        thisCol = ArraySize(\Column())
      EndIf
      ; Draw Background
      If *lvCD\nmcd\uItemState & #CDIS_SELECTED
        ;TextColor = BlendColor(\Column(thisCol)\TextColor, $000000, 70)
        ;BackColor = BlendColor(\Column(thisCol)\BackColor, $000000, 70)
        TextColor = #Black
        BackColor = $FF901E
      Else
        TextColor = \Column(thisCol)\TextColor
        BackColor = \Column(thisCol)\BackColor
      EndIf  
      hBrush = CreateSolidBrush_(BackColor)
      FillRect_(*lvCD\nmcd\hdc, *lvCD\nmcd\rc, hBrush)
      ; Use Font
      SelectObject_(*lvCD\nmcd\hdc, FontID(\Column(thisCol)\Font))
      ; Write Text
      SetBkMode_(*lvCD\nmcd\hdc,#TRANSPARENT)
      SetTextColor_(*lvCD\nmcd\hdc, TextColor)
      DrawText_(*lvCD\nmcd\hdc, @thisText, Len(thisText), *lvCD\nmcd\rc, #DT_CENTER|#DT_VCENTER|#DT_SINGLELINE|#DT_END_ELLIPSIS)
      ; Free resourcees
      DeleteObject_(hBrush)
    EndWith
  EndIf
EndProcedure



Procedure MainWindowCallback(hWnd, uMsg, wParam, lParam)
  Protected Result = #PB_ProcessPureBasicEvents
  Protected *nmhdr.NMHDR, *lvCD.NMLVCUSTOMDRAW, *ItemData.udtItemData
  
  ; Draw a line through an item to indicate its deleted state
  Select uMsg
      
    Case #WM_NOTIFY
      
      *nmhdr.NMHDR = lParam
      
      *lvCD.NMLVCUSTOMDRAW = lParam
      
      If IsGadget(#Gadget_MyInfo_Titles)
        If *lvCD\nmcd\hdr\hwndFrom = GadgetID(#Gadget_MyInfo_Titles) And *lvCD\nmcd\hdr\code = #NM_CUSTOMDRAW
          Select *lvCD\nmcd\dwDrawStage
            Case #CDDS_PREPAINT
              result = #CDRF_NOTIFYITEMDRAW
            Case #CDDS_ITEMPREPAINT
              result = #CDRF_NOTIFYSUBITEMDRAW;
            Case #CDDS_ITEMPREPAINT | #CDDS_SUBITEM
              *ItemData = GetGadgetItemData(#Gadget_MyInfo_Titles, *lvCD\nmcd\dwItemSpec)
              If *ItemData
                DrawListIconGadgetItem(*lvCD, *ItemData)
                result = #CDRF_SKIPDEFAULT
              Else
                result = #CDRF_DODEFAULT   
              EndIf
          EndSelect
        EndIf
      EndIf
  EndSelect ; uMsg
  
  ProcedureReturn Result
  
EndProcedure

OpenWindow(0, 200, 100, 400, 100, "ListIconGadget with colored header text")
ListIconGadget(0, 10, 10, WindowWidth(0) - 20, WindowHeight(0) - 20,
               "Name", 110, #PB_ListIcon_FullRowSelect)
AddGadgetColumn(0, 1, "Address", GadgetWidth(0) - GetGadgetItemAttribute(0, 0,
                                                                         #PB_ListIcon_ColumnWidth) - 4)
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")

SetListIconGadgetData(0, 0, #FontStrikeoutNo, #White, #Gray)
SetListIconGadgetData(0, 1, #FontStrikeoutYes, #Red, #Yellow)
SetListIconGadgetData(0, 2, #FontItalic, #Green, #Black)
SetListIconGadgetData(0, 2, #FontStrikeoutYes, #Black, #Green, 1)

SetWindowCallback(@MainWindowCallback())

Repeat
Until WaitWindowEvent() = #PB_Event_CloseWindow
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
User avatar
Fangbeast
PureBasic Protozoa
PureBasic Protozoa
Posts: 4790
Joined: Fri Apr 25, 2003 3:08 pm
Location: Not Sydney!!! (Bad water, no goats)

Re: SetGadgetItemColor doesn't work after windowcallback cod

Post by Fangbeast »

That's some seriously great code there. Now do I have the brain to use it?? (shaddap srod)
It was 3 degrees when I read this post and I could barely read. Now that my eyeballs have thawed out, I am going over it.

Thanks mk-soft, RASHAD et al.

Woohoo!! Looks like you blokes made it simple for me to incorporate everything. (BTW, blokes is Ozzie for 'Guys' in case you are wondering) :):):)
Amateur Radio/VK3HAF, (D-STAR/DMR and more), Arduino, ESP32, Coding, Crochet
User avatar
mk-soft
Always Here
Always Here
Posts: 6249
Joined: Fri May 12, 2006 6:51 pm
Location: Germany

Re: SetGadgetItemColor doesn't work after windowcallback cod

Post by mk-soft »

Update...

Show Link :wink:
viewtopic.php?f=12&t=73305
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
Post Reply