Page 1 of 2

Color Individual ListIconGadget Rows

Posted: Tue May 06, 2003 11:12 pm
by ebs
Code updated for 5.20+

Thanks to Denis for the pointer (pun intended :wink:) to the C code that I converted to PureBasic. The code below lets you set the text and background colors for each row individually. I haven't been able to make it work for each "cell" yet, but I'm going to keep trying!

Code: Select all

Global ListGadget

; window callback routine to color listview rows
Declare NotifyCallback(WindowID, Message, wParam, lParam)

hWnd = OpenWindow(0, 0, 0, 356, 197, "Color List View Rows", #PB_Window_ScreenCentered | #PB_Window_SystemMenu)

; create list with seven columns
ListGadget = ListIconGadget(1, 10, 10, 336, 177,"", 70, #PB_ListIcon_GridLines)
AddGadgetColumn(1, 1, "Sun", 35)
AddGadgetColumn(1, 2, "Mon", 35)
AddGadgetColumn(1, 3, "Tue", 35)
AddGadgetColumn(1, 4, "Wed", 35)
AddGadgetColumn(1, 5, "Thu", 35)
AddGadgetColumn(1, 6, " Fri", 35)
AddGadgetColumn(1, 7, "Sat", 35)

; add some rows
AddGadgetItem(1, -1, "  9:00 am")
AddGadgetItem(1, -1, "  9:30 am")
AddGadgetItem(1, -1, "10:00 am")
AddGadgetItem(1, -1, "10:30 am")
AddGadgetItem(1, -1, "11:00 am")
AddGadgetItem(1, -1, "11:30 am")
AddGadgetItem(1, -1, "12:00 pm")
AddGadgetItem(1, -1, "12:30 pm")
AddGadgetItem(1, -1, "  1:00 pm")
AddGadgetItem(1, -1, "  1:30 pm")
AddGadgetItem(1, -1, "  2:00 pm")
AddGadgetItem(1, -1, "  2:30 pm")
AddGadgetItem(1, -1, "  3:00 pm")
AddGadgetItem(1, -1, "  3:30 pm")
AddGadgetItem(1, -1, "  4:00 pm")
AddGadgetItem(1, -1, "  4:30 pm")
AddGadgetItem(1, -1, "  5:00 pm")

; set callback routine
SetWindowCallback(@NotifyCallback())

Repeat
Until WaitWindowEvent()=#PB_Event_CloseWindow

End

; window callback routine to color listview rows
Procedure NotifyCallback(WindowID, Message, wParam, lParam)
  ; process NOTIFY message only
  If Message = #WM_NOTIFY
    ; set stucture pointer
    *LVCDHeader.NMLVCUSTOMDRAW = lParam
    ; CUSTOMDRAW message from desired gadget?
    If *LVCDHeader\nmcd\hdr\hWndFrom = ListGadget And *LVCDHeader\nmcd\hdr\code = #NM_CUSTOMDRAW
      Select *LVCDHeader\nmcd\dwDrawStage
        Case #CDDS_PREPAINT
          ProcedureReturn #CDRF_NOTIFYITEMDRAW
        Case #CDDS_ITEMPREPAINT
          ; simple example - change text and background colors every other row
          Row = *LVCDHeader\nmcd\dwItemSpec
          If (Row/2) * 2 = Row
            *LVCDHeader\clrText = RGB(255, 0, 0)
            *LVCDHeader\clrTextBk = RGB(255, 255, 223)
          Else
            *LVCDHeader\clrText = RGB(0, 0, 255)
            *LVCDHeader\clrTextBk = RGB(208, 208, 176)
          EndIf
          ProcedureReturn #CDRF_DODEFAULT
      EndSelect
    EndIf
  Else
    ProcedureReturn #PB_ProcessPureBasicEvents
  EndIf
EndProcedure

Posted: Wed May 07, 2003 4:33 pm
by ebs
Code updated for 5.20+

Here's my latest revision. It shows how to set the text/background colors and font for each "cell" in a ListIconGadget (ListView control). It's almost ready to be used as a grid control replacement. Now all I need is a way to put row headers down the left side - Denis??? :wink:

Code: Select all

Global ListGadget

; window callback routine to color listview rows
Declare NotifyCallback(WindowID, Message, wParam, lParam)

; load fonts
Global FontReg, FontBold
FontReg = LoadFont(1, "Tahoma", 9)
FontBold = LoadFont(2, "Tahoma", 9, #PB_Font_Bold)

hWnd = OpenWindow(0, 0, 0, 356, 197, "Color List View Rows", #PB_Window_ScreenCentered | #PB_Window_SystemMenu)

; create list with seven columns
ListGadget = ListIconGadget(1, 10, 10, 336, 177,"", 70, #PB_ListIcon_GridLines | #LVS_NOSORTHEADER)
AddGadgetColumn(1, 1, "Sun", 35)
AddGadgetColumn(1, 2, "Mon", 35)
AddGadgetColumn(1, 3, "Tue", 35)
AddGadgetColumn(1, 4, "Wed", 35)
AddGadgetColumn(1, 5, "Thu", 35)
AddGadgetColumn(1, 6, " Fri", 35)
AddGadgetColumn(1, 7, "Sat", 35)

; add some rows
AddGadgetItem(1, -1, "  9:00 am" + Chr(10) + "XXX" + Chr(10) + Chr(10) + "XXX" + Chr(10) + Chr(10) + "XXX")
AddGadgetItem(1, -1, "  9:30 am" + Chr(10) + "XXX" + Chr(10) + Chr(10) + "XXX" + Chr(10) + Chr(10) + "XXX")
AddGadgetItem(1, -1, "10:00 am" + Chr(10) + "XXX" + Chr(10) + Chr(10) + "XXX" + Chr(10) + Chr(10) + "XXX")
AddGadgetItem(1, -1, "10:30 am" + Chr(10) + "XXX" + Chr(10) + Chr(10) + "XXX" + Chr(10) + Chr(10) + "XXX")
AddGadgetItem(1, -1, "11:00 am" + Chr(10) + "XXX" + Chr(10) + Chr(10) + "XXX" + Chr(10) + Chr(10) + "XXX")
AddGadgetItem(1, -1, "11:30 am" + Chr(10) + "XXX" + Chr(10) + Chr(10) + "XXX" + Chr(10) + Chr(10) + "XXX")
AddGadgetItem(1, -1, "12:00 pm" + Chr(10) + "XXX" + Chr(10) + Chr(10) + "XXX" + Chr(10) + Chr(10) + "XXX")
AddGadgetItem(1, -1, "12:30 pm" + Chr(10) + "XXX" + Chr(10) + Chr(10) + "XXX" + Chr(10) + Chr(10) + "XXX")
AddGadgetItem(1, -1, "  1:00 pm" + Chr(10) + "XXX" + Chr(10) + Chr(10) + "XXX" + Chr(10) + Chr(10) + "XXX")
AddGadgetItem(1, -1, "  1:30 pm" + Chr(10) + "XXX" + Chr(10) + Chr(10) + "XXX" + Chr(10) + Chr(10) + "XXX")
AddGadgetItem(1, -1, "  2:00 pm" + Chr(10) + "XXX" + Chr(10) + Chr(10) + "XXX" + Chr(10) + Chr(10) + "XXX")
AddGadgetItem(1, -1, "  2:30 pm" + Chr(10) + "XXX" + Chr(10) + Chr(10) + "XXX" + Chr(10) + Chr(10) + "XXX")
AddGadgetItem(1, -1, "  3:00 pm" + Chr(10) + "XXX" + Chr(10) + Chr(10) + "XXX" + Chr(10) + Chr(10) + "XXX")
AddGadgetItem(1, -1, "  3:30 pm" + Chr(10) + "XXX" + Chr(10) + Chr(10) + "XXX" + Chr(10) + Chr(10) + "XXX")
AddGadgetItem(1, -1, "  4:00 pm" + Chr(10) + "XXX" + Chr(10) + Chr(10) + "XXX" + Chr(10) + Chr(10) + "XXX")
AddGadgetItem(1, -1, "  4:30 pm" + Chr(10) + "XXX" + Chr(10) + Chr(10) + "XXX" + Chr(10) + Chr(10) + "XXX")
AddGadgetItem(1, -1, "  5:00 pm" + Chr(10) + "XXX" + Chr(10) + Chr(10) + "XXX" + Chr(10) + Chr(10) + "XXX")

; set callback routine
SetWindowCallback(@NotifyCallback())

Repeat
Until WaitWindowEvent()=#PB_Event_CloseWindow

End

; window callback routine to color listview rows
Procedure NotifyCallback(WindowID, Message, wParam, lParam)
  ; process NOTIFY message only
  If Message = #WM_NOTIFY
    ; set stucture pointer
    *LVCDHeader.NMLVCUSTOMDRAW = lParam
    ; CUSTOMDRAW message from desired gadget?
    If *LVCDHeader\nmcd\hdr\hWndFrom = ListGadget And *LVCDHeader\nmcd\hdr\code = #NM_CUSTOMDRAW
      Select *LVCDHeader\nmcd\dwDrawStage
        Case #CDDS_PREPAINT
          ProcedureReturn #CDRF_NOTIFYITEMDRAW
        Case #CDDS_ITEMPREPAINT
          ProcedureReturn #CDRF_NOTIFYSUBITEMDRAW
        Case #CDDS_SUBITEMPREPAINT
          ; simple example - change background colors every other row
          ;                  change text colors every other row, only in column 3
          ;                  text in first column is bold
          Row = *LVCDHeader\nmcd\dwItemSpec
          Col = *LVCDHeader\iSubItem
          If Col = 0
            SelectObject_(*LVCDHeader\nmcd\hDC, FontBold)
          Else
            SelectObject_(*LVCDHeader\nmcd\hDC, FontReg)
          EndIf
          If (Row/2) * 2 = Row
            *LVCDHeader\clrTextBk = RGB(255, 255, 223)
            If Col = 3
              *LVCDHeader\clrText = RGB(255, 0, 0)
            EndIf
          Else
            *LVCDHeader\clrTextBk = RGB(208, 208, 176)
            If Col = 3
              *LVCDHeader\clrText = RGB(0, 0, 255)
            EndIf
          EndIf
          ProcedureReturn #CDRF_NEWFONT
      EndSelect
    EndIf
  Else
    ProcedureReturn #PB_ProcessPureBasicEvents
  EndIf
EndProcedure

Nice!

Posted: Wed May 07, 2003 6:57 pm
by Hi-Toro
Good stuff -- thanks for sharing that :)

Posted: Sat Jun 14, 2003 2:05 am
by Karbon
Very cool idea, I'm unable to get it to work in PB 3.7.

I got "structure already defined" errors trying to compile it the first time - I commented out the top two structure definitions and got it to compile but it shows a standard ListIcon gadget, no colors..

I'd been looking for a way to do just this, hopefully you can give me a smack in the right direction! Thanks!

Posted: Sat Jun 14, 2003 2:11 am
by El_Choni
Why don't you take profit of the work already done? Search the form by 'grid' or similar. If you come with something better, maybe we can put it all togheter into a 3rd lib. Have a nice day,

Posted: Sat Jun 14, 2003 2:20 am
by Karbon
Don't know if that was intended as a reply for me or not but if it was then I don't know what you're suggesting.. If it wasn't then no worries :-)

Posted: Sat Jun 14, 2003 2:58 am
by freak
The reason, why the above code doesn't work is very simple:
It's all my fault :oops: :oops:

I recently added all these NM... Structures to the .res files of PB, that's
why they are allready defined now. The problem is, that i made a mistake
with the NMCUSTOMDRAW Structure. It is wrong defined now.

You have 2 choises now:
You can get the new File at http://cvs.purebasic.com/ (in the
Resident/Windows folder) as a *.pb, and compile it yourself with the /RESIDENT switch of the compiler, to get this fixed, or you
make a Search&Replace on this Sourcecode, and change all
"NMCUSTOMDRAW" to "NMCUSTOMDRAW_", uncomment the Structure
again, and name it like that. (You must do this also for the other
Structure, as it contains the first one.

It should work then.

Sorry for the trouble.

Timo

Posted: Sat Jun 14, 2003 3:04 am
by Karbon
*kicks you in the heaD*

Just kidding :-)

I'll probably grab a copy of the CVS version and compile it.

Thanks!!!

Posted: Sat Jun 14, 2003 2:51 pm
by Denis
>>> Now all I need is a way to put row headers down the left side - Denis???

Hi Ebs,
i spend time to find an answer but without succes.



Denis

Posted: Sat Jun 14, 2003 4:27 pm
by Karbon
Hmm, neither .pb files in that directory compile..

For Windows.pb I get
Line 6487 : This structure is already declared.

For Windows.pb I get
Line 564 : This structure is already declared.


PBCompiler.exe \RESIDENT Windows.pb

-- If I'm not doing that right just smack me with a clue stick...

Thanks!

Hello Karbon

Posted: Sat Jun 14, 2003 4:54 pm
by DominiqueB
Here is what i did to compile easily the updates to .res files:

a) create a new dir and put in it windows and purebasic .pb
b) create a .bat named Win.bat that contain:
@ECHO OFF
d:\purebasic\Compilers\PBCompiler Windows.pb /RESIDENT Windows. res /QUIET
PAUSE

c) This is the real path to pb compilers, modify it for your case.
d) Create a new one called Pure.bat
Basicly the same text but with Purebasic.pb

Then it will create windows.res and purebasic.res in the created dir.
Just take them to residents dir of pb.

All works well for me.

Posted: Sat Jun 14, 2003 5:13 pm
by Karbon
Worked great! Thanks!

Posted: Sat Jun 14, 2003 5:25 pm
by Cor
Works great here on win98 se. :D

Recompiled the res files

Posted: Sat Jun 14, 2003 5:26 pm
by Karbon
Hmm, side note.. If I grab and compile PreBasic.pb to PureBasic.res and replace the one in the Res directory I get an error loading every source file "Constant #Byte already declared"?

Went back to the old PureBasic res file and just updated Windows.res and everything seems to be working great!

Re: Color Individual ListIconGadget Rows

Posted: Sat Jun 14, 2003 7:53 pm
by idStefke
Hi

This code doesn't compile with the PureBASIC Compiler v3.70
Error : This structure is already declared

Kind regards
Stephane