Listicon Gadget bitmap ?

Just starting out? Need help? Post your questions and find answers here.
dontmailme
Enthusiast
Enthusiast
Posts: 537
Joined: Wed Oct 29, 2003 10:35 am

Listicon Gadget bitmap ?

Post by dontmailme »

Does anyone have some code that allows you to paint an image into a cell in a listicon gadget ?

I'm trying to find examples by searching but am either searching for the wrong thing or there no examples.

I think I need to get the dimensions of the cell and then paint a bitmap over the top of it but have not yet found out how to do it.

The image will be the same size as the row, probably 300x14 which will contain coloured text. ( Each Character can be a different colour! )

Unless anyone has an easier way to paint coloured text into a listicon gadget ?

I'm not too good with the API which is why I'm stuck!

Anyone ?
Paid up PB User !
Sparkie
PureBatMan Forever
PureBatMan Forever
Posts: 2307
Joined: Tue Feb 10, 2004 3:07 am
Location: Ohio, USA

Post by Sparkie »

This may be a little overkill for your needs, but feel free to pick this code apart and use what you need. :)

If you'd rather use an image instead, I'll see what I can come up with. ;)

Code written for PB 3.94 but can be easily modified for 4.0b

Code: Select all

; ************************************************************************ 
; Code:   Multicolor Text in ListIconGadget
; Author: Sparkie 
; Date:   February 07, 2006 
; OS:     Windows only 
; PB ver: 3.94
; Notes:  
; ************************************************************************ 
; ########################################
; Window constants
; ########################################
Enumeration
  #WindowMain = 1
EndEnumeration
; ########################################
; Gadget constants
; ########################################
Enumeration
  #ListIcon1 = 1
  #Button1
EndEnumeration

; ########################################
; ListIconGadget NMLVCUSTOMDRAW constants
; ########################################
#LVM_GETSUBITEMRECT = #LVM_FIRST + 56
#CDDS_ITEM = $10000
#CDDS_POSTERASE = 4
#CDDS_POSTPAINT = 2
#CDDS_PREERASE = 3
#CDDS_PREPAINT = 1
#CDDS_ITEMPOSTERASE = #CDDS_ITEM | #CDDS_POSTERASE
#CDDS_ITEMPOSTPAINT = #CDDS_ITEM | #CDDS_POSTPAINT
#CDDS_ITEMPREERASE = #CDDS_ITEM | #CDDS_PREERASE
#CDDS_ITEMPREPAINT = #CDDS_ITEM | #CDDS_PREPAINT
#CDDS_SUBITEM = $20000
#CDRF_DODEFAULT = 0
#CDRF_NOTIFYITEMDRAW = $20
#CDRF_NOTIFYPOSTERASE = $40
#CDRF_NOTIFYPOSTPAINT = $10
#CDRF_NOTIFYSUBITEMDRAW = $20
#CDRF_SKIPDEFAULT = 4
; //////////////////////////////////////////
; Array to hold character colors
; //////////////////////////////////////////
Dim charColor(255)
; //////////////////////////////////////////
; Global brush for ListIcon background
; //////////////////////////////////////////
Global blackBrush
blackBrush = GetStockObject_(#BLACK_BRUSH)
; //////////////////////////////////////////
; Procedure to create random text colors
; //////////////////////////////////////////
Procedure CreateRandomColors()
  For char = 0 To 255
    ; ..........................................................
    ; I'll keep the RGB values between 100 and 255 for brighness
    ; ..........................................................
    charColor(char) = RGB(Random(155)+100, Random(155)+100, Random(155)+100) 
  Next char
EndProcedure
; //////////////////////////////////////////
; Procedure to get character width
; //////////////////////////////////////////
Procedure GetCharWidth(hListIcon, char$)
  charwidth = SendMessage_(hListIcon, #LVM_GETSTRINGWIDTH, 0, @char$)
  ProcedureReturn charwidth
EndProcedure
; //////////////////////////////////////////
; Procedure for changing text colors
; //////////////////////////////////////////
Procedure ChangeColors()
  CreateRandomColors()
  SendMessage_(GadgetID(#ListIcon1), #LVM_REDRAWITEMS, 0, 11)
EndProcedure
; //////////////////////////////////////////
; Main window callback
; //////////////////////////////////////////
Procedure WinCallback(hwnd, msg, wparam, lparam)
  result = #PB_ProcessPureBasicEvents
  Select msg
    Case #WM_NOTIFY
      *nmhdr.NMHDR = lparam
      If *nmhdr\code = #NM_CUSTOMDRAW And *nmhdr\hwndFrom = GadgetID(#ListIcon1)
        *lvCD.NMLVCUSTOMDRAW = lparam
        ; ...................................................
        ; --> Make sure text background is always transparent
        ; ...................................................
        SetBkMode_(*lvCD\nmcd\hdc, #TRANSPARENT)
        Select *lvCD\nmcd\dwDrawStage
          Case #CDDS_PREPAINT 
            result = #CDRF_NOTIFYITEMDRAW 
          Case #CDDS_ITEMPREPAINT 
            result = #CDRF_NOTIFYSUBITEMDRAW
          Case #CDDS_ITEMPREPAINT | #CDDS_SUBITEM
            result = #CDRF_NOTIFYPOSTPAINT 
          Case #CDDS_ITEMPOSTPAINT | #CDDS_SUBITEM
            If *lvCD\nmcd\dwItemSpec > -1 And  *lvCD\iSubItem > -1
              ; ................................................
              ; --> Get item text
              ; ................................................
              item$ = GetGadgetItemText(#ListIcon1, *lvCD\nmcd\dwItemSpec, *lvCD\iSubItem)
              ; ................................................
              ; --> Get item rect
              ; ................................................
              subItemRc.RECT\left = #LVIR_LABEL
              subItemRc\top = *lvCD\iSubItem
              SendMessage_(*lvCD\nmcd\hdr\hwndFrom, #LVM_GETSUBITEMRECT, *lvCD\nmcd\dwItemSpec, @subItemRc) 
              ; ................................................
              ; --> Fill item rect with our brush color (black)
              ; ................................................
              FillRect_(*lvCD\nmcd\hdc, subItemRc, blackBrush)
              ; ................................................
              ; --> Adjust left margin
              ; ................................................
              If *lvCD\iSubItem = 0
                subItemRc\left + (GetSystemMetrics_(#SM_CXEDGE) * 3) - 2
              Else
                subItemRc\left + GetSystemMetrics_(#SM_CXEDGE) * 3
              EndIf
              ; ................................................
              ; --> Colorize each character and draw it
              ; ................................................
              For char = 1 To Len(item$)
                char$ = Mid(item$, char, 1)
                ; ........................................................
                ; --> I am adding + *lvCD\nmcd\dwItemSpec + *lvCD\iSubItem
                ;     only for variety of colors, so this is optional
                ; ........................................................
                SetTextColor_(*lvCD\nmcd\hdc, charColor(Asc(char$) + *lvCD\nmcd\dwItemSpec + *lvCD\iSubItem))
                DrawText_(*lvCD\nmcd\hdc, char$, 1, subItemRc, #DT_NOCLIP)
                ; ........................................................
                ; --> Get the current character width (pixels) and move
                ;     the drawing rect\left for the next character.
                ;     I am adding + *lvCD\nmcd\dwItemSpec + *lvCD\iSubItem
                ;     only for increased spacing, so this is optional
                ; ........................................................
                subItemRc\left + GetCharWidth(*nmhdr\hwndFrom, char$) + *lvCD\nmcd\dwItemSpec + *lvCD\iSubItem
              Next char
            EndIf
            result = #CDRF_SKIPDEFAULT
        EndSelect
      EndIf
  EndSelect
  ProcedureReturn result
EndProcedure
; //////////////////////////////////////////
; Main Window
; //////////////////////////////////////////
If OpenWindow(#WindowMain, 0, 0, 620, 235,#PB_Window_SystemMenu,"Sparkies Multicolor ListIconGadget") And CreateGadgetList(WindowID(#WindowMain)) 
  SetWindowCallback(@WinCallback())
  ListIconGadget(#ListIcon1, 5, 5, 610, 195, "Column 0", 270, #PB_ListIcon_AlwaysShowSelection | #PB_ListIcon_FullRowSelect)
  ButtonGadget(#Button1, 260, 205, 100, 25, "Change colors")
  ; ................................................
  ; --> Uncomment next line if text shadowing occurs
  ;     that will make text invisible (text color on back color)
  ; ................................................
  ;SendMessage_(GadgetID(0), #LVM_SETTEXTCOLOR, 0, #Black)
  SendMessage_(GadgetID(#ListIcon1), #LVM_SETBKCOLOR, 0, #Black)
  ; ................................................
  ; --> Change font is optional
  ; ................................................
  hCourierNew = LoadFont(0, "Courier New", 10, #PB_Font_Bold)
  SetGadgetFont(0, hCourierNew)
  ; ................................................
  ; --> Add our ListIcon items
  ; ................................................
  AddGadgetColumn(#ListIcon1, 1, "Column 1", 335)
  For i = 0 To 11
    AddGadgetItem(#ListIcon1, -1, "Experience the " + Chr(10) + "Power of PureBasic")
  Next
  ; ................................................
  ; --> Create random text color
  ; ................................................
  CreateRandomColors()
  ; //////////////////////////////////////////
  ; Main window event loop
  ; //////////////////////////////////////////
  Repeat
    event = WaitWindowEvent()
    If event = #PB_EventGadget And EventGadgetID() = #Button1
      ChangeColors()
    EndIf
  Until event = #PB_Event_CloseWindow 
  ; ................................................
  ; Optional for GetStockObject
  ; ................................................
  DeleteObject_(blackBrush)
EndIf 
End
What goes around comes around.

PB 5.21 LTS (x86) - Windows 8.1
User avatar
Fangbeast
PureBasic Protozoa
PureBasic Protozoa
Posts: 4789
Joined: Fri Apr 25, 2003 3:08 pm
Location: Not Sydney!!! (Bad water, no goats)

Post by Fangbeast »

Too much late night coding eh sparkie? "Image" is exactly what he asked for (ROFLMAO).

/me goes hunting the forums, was sure there was an example somewhere
Amateur Radio/VK3HAF, (D-STAR/DMR and more), Arduino, ESP32, Coding, Crochet
dontmailme
Enthusiast
Enthusiast
Posts: 537
Joined: Wed Oct 29, 2003 10:35 am

Post by dontmailme »

Fangbeast wrote:Too much late night coding eh sparkie? "Image" is exactly what he asked for (ROFLMAO).

/me goes hunting the forums, was sure there was an example somewhere
No need to do that Fangie!

Sparkie hit the nail on the head :D

That's exactly what I want !!!!!!! Even though I didn't know it, somehow sparkie did ;)

He's too good, you know :)
Paid up PB User !
User avatar
Fangbeast
PureBasic Protozoa
PureBasic Protozoa
Posts: 4789
Joined: Fri Apr 25, 2003 3:08 pm
Location: Not Sydney!!! (Bad water, no goats)

Post by Fangbeast »

Yes, you are right, Us poor humans have to bathe in his reflected wisdom and glory:(
Amateur Radio/VK3HAF, (D-STAR/DMR and more), Arduino, ESP32, Coding, Crochet
Sparkie
PureBatMan Forever
PureBatMan Forever
Posts: 2307
Joined: Tue Feb 10, 2004 3:07 am
Location: Ohio, USA

Post by Sparkie »

@Fangles:
dontmailme wrote:...Unless anyone has an easier way to paint coloured text into a listicon gadget ?
Seemed easy enough to me. :D

...

...

...

...

Well ok, maybe not as easy as using an image. :P
What goes around comes around.

PB 5.21 LTS (x86) - Windows 8.1
Sparkie
PureBatMan Forever
PureBatMan Forever
Posts: 2307
Joined: Tue Feb 10, 2004 3:07 am
Location: Ohio, USA

Post by Sparkie »

@dontmailme: Glad to hear it's what you were looking for. I was afraid the code was more for me than for you. ;)
What goes around comes around.

PB 5.21 LTS (x86) - Windows 8.1
Sparkie
PureBatMan Forever
PureBatMan Forever
Posts: 2307
Joined: Tue Feb 10, 2004 3:07 am
Location: Ohio, USA

Post by Sparkie »

Fangles wrote:...bathe in his reflected wisdom and glory
Sorry Fangles, but the only other person I bathe is my wife. :D


Side note: Damn I'm slow on this dial-up account. No DSL for me this week :cry: as I'm house sitting for my inlaws. Old wiring = many reconnects. :evil:
Last edited by Sparkie on Wed Feb 08, 2006 2:30 pm, edited 1 time in total.
What goes around comes around.

PB 5.21 LTS (x86) - Windows 8.1
Dare2
Moderator
Moderator
Posts: 3321
Joined: Sat Dec 27, 2003 3:55 am
Location: Great Southern Land

Post by Dare2 »

:D
@}--`--,-- A rose by any other name ..
dontmailme
Enthusiast
Enthusiast
Posts: 537
Joined: Wed Oct 29, 2003 10:35 am

Post by dontmailme »

@Sparkie, or another bright spark!

The example works fine, but there one small issue :(

If you set a different brush colour, say grey ... you can then see that the non text parts of the listicongadget are still black.

It's even more noticable if there are less rows of text than the listicongadget can show.

I would like to remove this 'border', but need some help!

I'm sure it's simple, but I cannot see it :oops:
Paid up PB User !
Sparkie
PureBatMan Forever
PureBatMan Forever
Posts: 2307
Joined: Tue Feb 10, 2004 3:07 am
Location: Ohio, USA

Post by Sparkie »

Try changing the background color to match the brush. Line 160 of my original code is where the background color is set. ;)

Code: Select all

SendMessage_(GadgetID(#ListIcon1), #LVM_SETBKCOLOR, 0, same_color_as_brush)
What goes around comes around.

PB 5.21 LTS (x86) - Windows 8.1
dontmailme
Enthusiast
Enthusiast
Posts: 537
Joined: Wed Oct 29, 2003 10:35 am

Post by dontmailme »

Knew it was simple ;)

But not that simple :roll:

Thanks again :D
Paid up PB User !
PB
PureBasic Expert
PureBasic Expert
Posts: 7581
Joined: Fri Apr 25, 2003 5:24 pm

Post by PB »

Modified by myself for v4.10 B3:

Code: Select all

; ************************************************************************
; Code:   Multicolor Text in ListIconGadget
; Author: Sparkie
; Date:   February 07, 2006
; OS:     Windows only
; PB ver: 3.94
; Notes:  Modified for v4.10 B3 on 13 Oct 2007 by PB.
; ************************************************************************
; ########################################
; Window constants
; ########################################
Enumeration
  #WindowMain = 1
EndEnumeration
; ########################################
; Gadget constants
; ########################################
Enumeration
  #ListIcon1 = 1
  #Button1
EndEnumeration

; ########################################
; ListIconGadget NMLVCUSTOMDRAW constants
; ########################################
#LVM_GETSUBITEMRECT = #LVM_FIRST + 56
#CDDS_ITEM = $10000
#CDDS_POSTERASE = 4
#CDDS_POSTPAINT = 2
#CDDS_PREERASE = 3
#CDDS_PREPAINT = 1
#CDDS_ITEMPOSTERASE = #CDDS_ITEM | #CDDS_POSTERASE
#CDDS_ITEMPOSTPAINT = #CDDS_ITEM | #CDDS_POSTPAINT
#CDDS_ITEMPREERASE = #CDDS_ITEM | #CDDS_PREERASE
#CDDS_ITEMPREPAINT = #CDDS_ITEM | #CDDS_PREPAINT
#CDDS_SUBITEM = $20000
#CDRF_DODEFAULT = 0
#CDRF_NOTIFYITEMDRAW = $20
#CDRF_NOTIFYPOSTERASE = $40
#CDRF_NOTIFYPOSTPAINT = $10
#CDRF_NOTIFYSUBITEMDRAW = $20
#CDRF_SKIPDEFAULT = 4
; //////////////////////////////////////////
; Array to hold character colors
; //////////////////////////////////////////
Global Dim charColor(255)
; //////////////////////////////////////////
; Global brush for ListIcon background
; //////////////////////////////////////////
Global blackBrush
blackBrush = GetStockObject_(#BLACK_BRUSH)
; //////////////////////////////////////////
; Procedure to create random text colors
; //////////////////////////////////////////
Procedure CreateRandomColors()
  For char = 0 To 255
    ; ..........................................................
    ; I'll keep the RGB values between 100 and 255 for brighness
    ; ..........................................................
    charColor(char) = RGB(Random(155)+100, Random(155)+100, Random(155)+100)
  Next char
EndProcedure
; //////////////////////////////////////////
; Procedure to get character width
; //////////////////////////////////////////
Procedure GetCharWidth(hListIcon, char$)
  charwidth = SendMessage_(hListIcon, #LVM_GETSTRINGWIDTH, 0, @char$)
  ProcedureReturn charwidth
EndProcedure
; //////////////////////////////////////////
; Procedure for changing text colors
; //////////////////////////////////////////
Procedure ChangeColors()
  CreateRandomColors()
  SendMessage_(GadgetID(#ListIcon1), #LVM_REDRAWITEMS, 0, 11)
EndProcedure
; //////////////////////////////////////////
; Main window callback
; //////////////////////////////////////////
Procedure WinCallback(hwnd, msg, wparam, lparam)
  result = #PB_ProcessPureBasicEvents
  Select msg
    Case #WM_NOTIFY
      *nmhdr.NMHDR = lparam
      If *nmhdr\code = #NM_CUSTOMDRAW And *nmhdr\hwndFrom = GadgetID(#ListIcon1)
        *lvCD.NMLVCUSTOMDRAW = lparam
        ; ...................................................
        ; --> Make sure text background is always transparent
        ; ...................................................
        SetBkMode_(*lvCD\nmcd\hdc, #TRANSPARENT)
        Select *lvCD\nmcd\dwDrawStage
          Case #CDDS_PREPAINT
            result = #CDRF_NOTIFYITEMDRAW
          Case #CDDS_ITEMPREPAINT
            result = #CDRF_NOTIFYSUBITEMDRAW
          Case #CDDS_ITEMPREPAINT | #CDDS_SUBITEM
            result = #CDRF_NOTIFYPOSTPAINT
          Case #CDDS_ITEMPOSTPAINT | #CDDS_SUBITEM
            If *lvCD\nmcd\dwItemSpec > -1 And  *lvCD\iSubItem > -1
              ; ................................................
              ; --> Get item text
              ; ................................................
              item$ = GetGadgetItemText(#ListIcon1, *lvCD\nmcd\dwItemSpec, *lvCD\iSubItem)
              ; ................................................
              ; --> Get item rect
              ; ................................................
              subItemRc.RECT\left = #LVIR_LABEL
              subItemRc\top = *lvCD\iSubItem
              SendMessage_(*lvCD\nmcd\hdr\hwndFrom, #LVM_GETSUBITEMRECT, *lvCD\nmcd\dwItemSpec, @subItemRc)
              ; ................................................
              ; --> Fill item rect with our brush color (black)
              ; ................................................
              FillRect_(*lvCD\nmcd\hdc, subItemRc, blackBrush)
              ; ................................................
              ; --> Adjust left margin
              ; ................................................
              If *lvCD\iSubItem = 0
                subItemRc\left + (GetSystemMetrics_(#SM_CXEDGE) * 3) - 2
              Else
                subItemRc\left + GetSystemMetrics_(#SM_CXEDGE) * 3
              EndIf
              ; ................................................
              ; --> Colorize each character and draw it
              ; ................................................
              For char = 1 To Len(item$)
                char$ = Mid(item$, char, 1)
                ; ........................................................
                ; --> I am adding + *lvCD\nmcd\dwItemSpec + *lvCD\iSubItem
                ;     only for variety of colors, so this is optional
                ; ........................................................
                SetTextColor_(*lvCD\nmcd\hdc, charColor(Asc(char$) + *lvCD\nmcd\dwItemSpec + *lvCD\iSubItem))
                DrawText_(*lvCD\nmcd\hdc, char$, 1, subItemRc, #DT_NOCLIP)
                ; ........................................................
                ; --> Get the current character width (pixels) and move
                ;     the drawing rect\left for the next character.
                ;     I am adding + *lvCD\nmcd\dwItemSpec + *lvCD\iSubItem
                ;     only for increased spacing, so this is optional
                ; ........................................................
                subItemRc\left + GetCharWidth(*nmhdr\hwndFrom, char$) + *lvCD\nmcd\dwItemSpec + *lvCD\iSubItem
              Next char
            EndIf
            result = #CDRF_SKIPDEFAULT
        EndSelect
      EndIf
  EndSelect
  ProcedureReturn result
EndProcedure
; //////////////////////////////////////////
; Main Window
; //////////////////////////////////////////
If OpenWindow(#WindowMain, 0, 0, 620, 235, "Sparkies Multicolor ListIconGadget", #PB_Window_SystemMenu) And CreateGadgetList(WindowID(#WindowMain))
  SetWindowCallback(@WinCallback())
  ListIconGadget(#ListIcon1, 5, 5, 610, 195, "Column 0", 270, #PB_ListIcon_AlwaysShowSelection | #PB_ListIcon_FullRowSelect)
  ButtonGadget(#Button1, 260, 205, 100, 25, "Change colors")
  ; ................................................
  ; --> Uncomment next line if text shadowing occurs
  ;     that will make text invisible (text color on back color)
  ; ................................................
  ;SendMessage_(GadgetID(0), #LVM_SETTEXTCOLOR, 0, #Black)
  SendMessage_(GadgetID(#ListIcon1), #LVM_SETBKCOLOR, 0, #Black)
  ; ................................................
  ; --> Change font is optional
  ; ................................................
  hCourierNew = LoadFont(0, "Courier New", 10, #PB_Font_Bold)
  SetGadgetFont(0, hCourierNew)
  ; ................................................
  ; --> Add our ListIcon items
  ; ................................................
  AddGadgetColumn(#ListIcon1, 1, "Column 1", 335)
  For i = 0 To 11
    AddGadgetItem(#ListIcon1, -1, "Experience the " + Chr(10) + "Power of PureBasic")
  Next
  ; ................................................
  ; --> Create random text color
  ; ................................................
  CreateRandomColors()
  ; //////////////////////////////////////////
  ; Main window event loop
  ; //////////////////////////////////////////
  Repeat
    event = WaitWindowEvent()
    If event = #PB_Event_Gadget And EventGadget() = #Button1
      ChangeColors()
    EndIf
  Until event = #PB_Event_CloseWindow
  ; ................................................
  ; Optional for GetStockObject
  ; ................................................
  DeleteObject_(blackBrush)
EndIf
Sparkie
PureBatMan Forever
PureBatMan Forever
Posts: 2307
Joined: Tue Feb 10, 2004 3:07 am
Location: Ohio, USA

Post by Sparkie »

Thanks PB :)
What goes around comes around.

PB 5.21 LTS (x86) - Windows 8.1
PB
PureBasic Expert
PureBasic Expert
Posts: 7581
Joined: Fri Apr 25, 2003 5:24 pm

Post by PB »

No problem. I needed it for my own app, but I'm having trouble converting it
for my own app. Below is what I want do to do; I want both "THIS" words to
be in red. Any chance you can help? :)

Code: Select all

If OpenWindow(0,200,200,250,120,"test",#PB_Window_SystemMenu)
  CreateGadgetList(WindowID(0))
  ListIconGadget(0,10,10,200,100,"test",190)
  AddGadgetItem(0,-1,"I'd like THIS and THIS to be red.")
  Repeat : Until WaitWindowEvent()=#PB_Event_CloseWindow
EndIf
Post Reply