From 0530737d1e46ff91dec84f7854661799f2efa77b Mon Sep 17 00:00:00 2001
From: Vadim Zeitlin <vadim@wxwidgets.org>
Date: Mon, 6 Dec 1999 10:43:35 +0000
Subject: [PATCH] generic wxListCtrl colour/font setting

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@4835 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
---
 docs/changes.txt              |   1 +
 docs/latex/wx/listctrl.tex    |   8 ++-
 include/wx/generic/listctrl.h |  27 +++++---
 samples/listctrl/listtest.cpp |   2 +-
 src/generic/listctrl.cpp      | 127 ++++++++++++++++++++++------------
 5 files changed, 111 insertions(+), 54 deletions(-)

diff --git a/docs/changes.txt b/docs/changes.txt
index 665dd44386..861a746147 100644
--- a/docs/changes.txt
+++ b/docs/changes.txt
@@ -18,6 +18,7 @@ all (GUI):
 - wxMenu(Bar)::Insert() and Remove() functions for dynamic menu menagament
 - wxToolBar supports arbitrary controls (not only buttons) and can be
   dynamically changed (Delete/Insert functions)
+- wxListCtrl allows setting colour/fonts for individual items
 - wxDC::DrawRotatedText() (contributed by Hans-Joachim Baader, limited to
   +/-90 degrees for now - contributions to improve it are welcome!)
 
diff --git a/docs/latex/wx/listctrl.tex b/docs/latex/wx/listctrl.tex
index 4fac88641c..a380164b24 100644
--- a/docs/latex/wx/listctrl.tex
+++ b/docs/latex/wx/listctrl.tex
@@ -402,7 +402,7 @@ For list view mode (only), inserts a column. For more details, see \helpref{wxLi
 \pythonnote{In place of a single overloaded method name, wxPython
 implements the following methods:\par
 \indented{2cm}{\begin{twocollist}
-\twocolitem{\bf{InsertColumn(col, heading, format=wxLIST_FORMAT_LEFT,
+\twocolitem{\bf{InsertColumn(col, heading, format=wxLIST\_FORMAT\_LEFT,
 width=-1)}}{Creates a column using a header string only.}
 \twocolitem{\bf{InsertColumnInfo(col, item)}}{Creates a column using a
 wxListInfo.}
@@ -529,6 +529,12 @@ The {\bf m\_mask} member contains a bitlist specifying which of the other fields
 
 The {\bf m\_stateMask} and {\bf m\_state} members take flags from the following:
 
+The wxListItem object can also contain item-specific colour and font
+information: for this you need to call one of SetTextColour(),
+SetBackgroundColour() or SetFont() functions on it passing it the colour/font
+to use. If the colour/font is not specified, the default list control
+colour/font is used.
+
 \twocolwidtha{5cm}
 \begin{twocollist}\itemsep=0pt
 \twocolitem{wxLIST\_STATE\_DONTCARE}{Don't care what the state is. Win32 only. }
diff --git a/include/wx/generic/listctrl.h b/include/wx/generic/listctrl.h
index cd0ced7b50..98b332888d 100644
--- a/include/wx/generic/listctrl.h
+++ b/include/wx/generic/listctrl.h
@@ -63,10 +63,13 @@ public:
     long       m_data;
     int        m_xpos,m_ypos;
     int        m_width,m_height;
-    wxColour   *m_colour;
+
+    wxListItemAttr *m_attr;
 
 public:
     wxListItemData();
+    ~wxListItemData() { delete m_attr; }
+
     wxListItemData( const wxListItem &info );
     void SetItem( const wxListItem &info );
     void SetText( const wxString &s );
@@ -74,18 +77,19 @@ public:
     void SetData( long data );
     void SetPosition( int x, int y );
     void SetSize( int width, int height );
-    void SetColour( wxColour *col );
     bool HasImage() const;
     bool HasText() const;
     bool IsHit( int x, int y ) const;
     void GetText( wxString &s );
+    const wxString& GetText() { return m_text; }
     int GetX( void ) const;
     int GetY( void ) const;
     int GetWidth() const;
     int GetHeight() const;
     int GetImage() const;
-    void GetItem( wxListItem &info );
-    wxColour *GetColour();
+    void GetItem( wxListItem &info ) const;
+
+    wxListItemAttr *GetAttributes() const { return m_attr; }
 
 private:
     DECLARE_DYNAMIC_CLASS(wxListItemData);
@@ -174,6 +178,10 @@ public:
     void AssignRect( wxRect &dest, const wxRect &source );
     
 private:
+    void SetAttributes(wxDC *dc,
+                       const wxListItemAttr *attr,
+                       const wxColour& colText, const wxFont& font);
+
     DECLARE_DYNAMIC_CLASS(wxListLineData);
 };
 
@@ -241,8 +249,9 @@ public:
                     bool *accept, wxString *res, wxListMainWindow *owner,
                     const wxString &value = "",
                     const wxPoint &pos = wxDefaultPosition, const wxSize &size = wxDefaultSize,
+                    int style = 0,
 #if wxUSE_VALIDATORS
-                    int style = 0, const wxValidator& validator = wxDefaultValidator,
+                    const wxValidator& validator = wxDefaultValidator,
 #endif
                     const wxString &name = "wxListTextCtrlText" );
     void OnChar( wxKeyEvent &event );
@@ -313,8 +322,8 @@ public:
     void OnSetFocus( wxFocusEvent &event );
     void OnKillFocus( wxFocusEvent &event );
     void OnSize( wxSizeEvent &event );
-	void OnScroll(wxScrollWinEvent& event) ;
-	
+    void OnScroll(wxScrollWinEvent& event) ;
+    
     void DrawImage( int index, wxDC *dc, int x, int y );
     void GetImageSize( int index, int &width, int &height );
     int GetIndexOfLine( const wxListLineData *line );
@@ -411,8 +420,8 @@ public:
     void SetItemSpacing( int spacing, bool isSmall = FALSE );
     int GetItemSpacing( bool isSmall ) const;
     int GetSelectedItemCount() const;
-//  wxColour GetTextColour() const; // wxGLC has colours for every Item (see wxListItem)
-//  void SetTextColour(const wxColour& col);
+    wxColour GetTextColour() const;
+    void SetTextColour(const wxColour& col);
     long GetTopItem() const;
 
     void SetSingleStyle( long style, bool add = TRUE ) ;
diff --git a/samples/listctrl/listtest.cpp b/samples/listctrl/listtest.cpp
index 345bc83be2..8c4e700899 100644
--- a/samples/listctrl/listtest.cpp
+++ b/samples/listctrl/listtest.cpp
@@ -291,7 +291,7 @@ void MyFrame::OnReportView(wxCommandEvent& WXUNUSED(event))
     // we leave all mask fields to 0 and only change the colour
     wxListItem item;
     item.m_itemId = 0;
-    item.SetTextColour(*wxBLUE);
+    item.SetTextColour(*wxRED);
     m_listCtrl->SetItem( item );
 
     item.m_itemId = 2;
diff --git a/src/generic/listctrl.cpp b/src/generic/listctrl.cpp
index 16db403d0d..bb31a04f6a 100644
--- a/src/generic/listctrl.cpp
+++ b/src/generic/listctrl.cpp
@@ -41,14 +41,15 @@ wxListItemData::wxListItemData()
     m_ypos = 0;
     m_width = 0;
     m_height = 0;
-    m_colour = wxBLACK;
+    m_attr = NULL;
 }
 
 wxListItemData::wxListItemData( const wxListItem &info )
 {
     m_image = -1;
     m_data = 0;
-    m_colour = (wxColour *)&info.GetTextColour();
+    m_attr = NULL;
+
     SetItem( info );
 }
 
@@ -57,7 +58,15 @@ void wxListItemData::SetItem( const wxListItem &info )
     if (info.m_mask & wxLIST_MASK_TEXT) m_text = info.m_text;
     if (info.m_mask & wxLIST_MASK_IMAGE) m_image = info.m_image;
     if (info.m_mask & wxLIST_MASK_DATA) m_data = info.m_data;
-    m_colour = (wxColour *)&info.GetTextColour();
+
+    if ( info.HasAttributes() )
+    {
+        if ( m_attr )
+            *m_attr = *info.GetAttributes();
+        else
+            m_attr = new wxListItemAttr(*info.GetAttributes());
+    }
+
     m_xpos = 0;
     m_ypos = 0;
     m_width = info.m_width;
@@ -91,11 +100,6 @@ void wxListItemData::SetSize( int width, int height )
     if (height != -1) m_height = height;
 }
 
-void wxListItemData::SetColour( wxColour *col )
-{
-    m_colour = col;
-}
-
 bool wxListItemData::HasImage() const
 {
     return (m_image >= 0);
@@ -141,17 +145,21 @@ int wxListItemData::GetImage() const
     return m_image;
 }
 
-void wxListItemData::GetItem( wxListItem &info )
+void wxListItemData::GetItem( wxListItem &info ) const
 {
     info.m_text = m_text;
     info.m_image = m_image;
     info.m_data = m_data;
-    info.SetTextColour(*m_colour);
-}
 
-wxColour *wxListItemData::GetColour()
-{
-    return m_colour;
+    if ( m_attr )
+    {
+        if ( m_attr->HasTextColour() )
+            info.SetTextColour(m_attr->GetTextColour());
+        if ( m_attr->HasBackgroundColour() )
+            info.SetBackgroundColour(m_attr->GetBackgroundColour());
+        if ( m_attr->HasFont() )
+            info.SetFont(m_attr->GetFont());
+    }
 }
 
 //-----------------------------------------------------------------------------
@@ -286,8 +294,7 @@ void wxListLineData::CalculateSize( wxDC *dc, int spacing )
             if (node)
             {
                 wxListItemData *item = (wxListItemData*)node->Data();
-                wxString s;
-                item->GetText( s );
+                wxString s = item->GetText();
                 long lw,lh;
                 dc->GetTextExtent( s, &lw, &lh );
                 if (lw > m_spacing) m_bound_all.width = lw;
@@ -300,8 +307,7 @@ void wxListLineData::CalculateSize( wxDC *dc, int spacing )
             if (node)
             {
                 wxListItemData *item = (wxListItemData*)node->Data();
-                wxString s;
-                item->GetText( s );
+                wxString s = item->GetText();
                 long lw,lh;
                 dc->GetTextExtent( s, &lw, &lh );
                 m_bound_all.width = lw;
@@ -577,6 +583,30 @@ int wxListLineData::GetImage( int index )
     return -1;
 }
 
+void wxListLineData::SetAttributes(wxDC *dc,
+                                   const wxListItemAttr *attr,
+                                   const wxColour& colText,
+                                   const wxFont& font)
+{
+    if ( attr && attr->HasTextColour() )
+    {
+        dc->SetTextForeground(attr->GetTextColour());
+    }
+    else
+    {
+        dc->SetTextForeground(colText);
+    }
+
+    if ( attr && attr->HasFont() )
+    {
+        dc->SetFont(attr->GetFont());
+    }
+    else
+    {
+        dc->SetFont(font);
+    }
+}
+
 void wxListLineData::DoDraw( wxDC *dc, bool hilight, bool paintBG )
 {
     long dev_x = dc->LogicalToDeviceX( m_bound_all.x-2 );
@@ -589,27 +619,51 @@ void wxListLineData::DoDraw( wxDC *dc, bool hilight, bool paintBG )
         return;
     }
 
-    if (paintBG)
+    wxWindow *listctrl = m_owner->GetParent();
+
+    // default foreground colour
+    wxColour colText;
+    if ( hilight )
+    {
+        colText = wxSystemSettings::GetSystemColour( wxSYS_COLOUR_HIGHLIGHTTEXT );
+    }
+    else
+    {
+        colText = listctrl->GetForegroundColour();
+    }
+
+    // default font
+    wxFont font = listctrl->GetFont();
+
+    // VZ: currently we set the colours/fonts only once, but like this (i.e.
+    //     using SetAttributes() inside the loop), it will be trivial to
+    //     customize the subitems (in report mode) too.
+    wxListItemData *item = (wxListItemData*)m_items.First()->Data();
+    wxListItemAttr *attr = item->GetAttributes();
+    SetAttributes(dc, attr, colText, font);
+
+    bool hasBgCol = attr && attr->HasBackgroundColour();
+    if ( paintBG || hasBgCol )
     {
         if (hilight)
         {
             dc->SetBrush( * m_hilightBrush );
-            dc->SetPen( * wxTRANSPARENT_PEN );
         }
         else
         {
-            dc->SetBrush( * wxWHITE_BRUSH );
-            dc->SetPen( * wxTRANSPARENT_PEN );
+            if ( hasBgCol )
+                dc->SetBrush(wxBrush(attr->GetBackgroundColour(), wxSOLID));
+            else
+                dc->SetBrush( * wxWHITE_BRUSH );
         }
+
+        dc->SetPen( * wxTRANSPARENT_PEN );
         dc->DrawRectangle( m_bound_hilight.x, m_bound_hilight.y,
                            m_bound_hilight.width, m_bound_hilight.height );
     }
 
-    dc->SetBackgroundMode(wxTRANSPARENT);
     if (m_mode == wxLC_REPORT)
     {
-        wxString s;
-	wxColour *colour = (wxColour*) NULL;
         wxNode *node = m_items.First();
         while (node)
         {
@@ -623,16 +677,9 @@ void wxListLineData::DoDraw( wxDC *dc, bool hilight, bool paintBG )
                 m_owner->GetImageSize( item->GetImage(), x, y );
                 x += item->GetX() + 5;
             }
-	    if (!colour)
-	        colour = item->GetColour();
             if (item->HasText())
             {
-                item->GetText( s );
-                if (hilight)
-                    dc->SetTextForeground( wxSystemSettings::GetSystemColour( wxSYS_COLOUR_HIGHLIGHTTEXT ) );
-                else
-                    dc->SetTextForeground( *colour );
-                dc->DrawText( s, x, item->GetY() );
+                dc->DrawText( item->GetText(), x, item->GetY() );
             }
             dc->DestroyClippingRegion();
             node = node->Next();
@@ -650,13 +697,7 @@ void wxListLineData::DoDraw( wxDC *dc, bool hilight, bool paintBG )
             }
             if (item->HasText())
             {
-                wxString s;
-                item->GetText( s );
-                if (hilight)
-                    dc->SetTextForeground( wxSystemSettings::GetSystemColour( wxSYS_COLOUR_HIGHLIGHTTEXT ) );
-                else
-                    dc->SetTextForeground( * item->GetColour() );
-                dc->DrawText( s, m_bound_label.x, m_bound_label.y );
+                dc->DrawText( item->GetText(), m_bound_label.x, m_bound_label.y );
             }
         }
     }
@@ -2881,15 +2922,15 @@ int wxListCtrl::GetSelectedItemCount() const
     return m_mainWin->GetSelectedItemCount();
 }
 
-/*
 wxColour wxListCtrl::GetTextColour() const
 {
+    return GetForegroundColour();
 }
 
-void wxListCtrl::SetTextColour(const wxColour& WXUNUSED(col))
+void wxListCtrl::SetTextColour(const wxColour& col)
 {
+    SetForegroundColour(col);
 }
-*/
 
 long wxListCtrl::GetTopItem() const
 {
-- 
2.50.0

