From: Vadim Zeitlin Date: Sun, 5 Dec 1999 00:20:58 +0000 (+0000) Subject: wxListCtrl custom drawing seems to work X-Git-Url: https://git.saurik.com/wxWidgets.git/commitdiff_plain/d62228a6450c566434fbcbcff00fa571fdbbdb2a wxListCtrl custom drawing seems to work git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@4824 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- diff --git a/include/wx/listctrl.h b/include/wx/listctrl.h index d5817da5bd..31b86aac5a 100644 --- a/include/wx/listctrl.h +++ b/include/wx/listctrl.h @@ -124,6 +124,10 @@ public: void SetFont(const wxFont& font) { m_font = font; } // accessors + bool HasTextColour() const { return m_colText.Ok(); } + bool HasBackgroundColour() const { return m_colBack.Ok(); } + bool HasFont() const { return m_font.Ok(); } + const wxColour& GetTextColour() const { return m_colText; } const wxColour& GetBackgroundColour() const { return m_colBack; } const wxFont& GetFont() const { return m_font; } @@ -142,6 +146,7 @@ class WXDLLEXPORT wxListItem : public wxObject { public: wxListItem(); + ~wxListItem() { delete m_attr; } // setters void SetMask(long mask) { m_mask = mask; } diff --git a/include/wx/msw/listctrl.h b/include/wx/msw/listctrl.h index 3fb236e0c2..47c81afaf4 100644 --- a/include/wx/msw/listctrl.h +++ b/include/wx/msw/listctrl.h @@ -19,6 +19,7 @@ #include "wx/control.h" #include "wx/event.h" #include "wx/imaglist.h" +#include "wx/hash.h" /* The wxListCtrl can show lists of items in four different modes: @@ -340,7 +341,10 @@ protected: int m_colCount; // Windows doesn't have GetColumnCount so must // keep track of inserted/deleted columns - // TRUE fi we have any items with custom attributes + // the hash table we use for storing pointers to the items attributes + wxHashTable m_attrs; + + // TRUE if we have any items with custom attributes bool m_hasAnyAttr; private: diff --git a/samples/listctrl/listtest.cpp b/samples/listctrl/listtest.cpp index ee96736492..345bc83be2 100644 --- a/samples/listctrl/listtest.cpp +++ b/samples/listctrl/listtest.cpp @@ -279,7 +279,7 @@ void MyFrame::OnReportView(wxCommandEvent& WXUNUSED(event)) wxChar buf[50]; wxSprintf(buf, _T("This is item %d"), i); long tmp = m_listCtrl->InsertItem(i, buf, 0); - //m_listCtrl->SetItemData(tmp, i); + m_listCtrl->SetItemData(tmp, i); wxSprintf(buf, _T("Col 1, item %d"), i); tmp = m_listCtrl->SetItem(i, 1, buf); @@ -295,12 +295,17 @@ void MyFrame::OnReportView(wxCommandEvent& WXUNUSED(event)) m_listCtrl->SetItem( item ); item.m_itemId = 2; - item.SetTextColour(*wxLIGHT_GREY); + item.SetTextColour(*wxGREEN); m_listCtrl->SetItem( item ); - item.m_itemId = 3; + item.m_itemId = 4; item.SetTextColour(*wxLIGHT_GREY); + item.SetFont(*wxITALIC_FONT); + item.SetBackgroundColour(*wxRED); m_listCtrl->SetItem( item ); + m_listCtrl->SetTextColour(*wxBLUE); + m_listCtrl->SetBackgroundColour(*wxLIGHT_GREY); + m_listCtrl->SetColumnWidth( 0, wxLIST_AUTOSIZE ); m_listCtrl->SetColumnWidth( 1, wxLIST_AUTOSIZE ); m_listCtrl->SetColumnWidth( 2, wxLIST_AUTOSIZE ); diff --git a/src/msw/listctrl.cpp b/src/msw/listctrl.cpp index 5bb0d8f862..3d4eb964bb 100644 --- a/src/msw/listctrl.cpp +++ b/src/msw/listctrl.cpp @@ -204,7 +204,15 @@ void wxListCtrl::UpdateStyle() wxListCtrl::~wxListCtrl() { - if (m_textCtrl) + if ( m_hasAnyAttr ) + { + for ( wxNode *node = m_attrs.Next(); node; node = m_attrs.Next() ) + { + delete (wxListItemAttr *)node->Data(); + } + } + + if ( m_textCtrl ) { m_textCtrl->UnsubclassWin(); m_textCtrl->SetHWND(0); @@ -549,20 +557,10 @@ bool wxListCtrl::SetItem(wxListItem& info) // check whether it has any custom attributes if ( info.HasAttributes() ) { - // FIXME it should be... - wxASSERT_MSG( !info.GetData(), - _T("can't have custom attributes and client data") ); - - item.mask |= LVIF_PARAM; - item.lParam = (long)info.GetAttributes(); + m_attrs.Put(item.iItem, (wxObject *)new wxListItemAttr(*info.GetAttributes())); m_hasAnyAttr = TRUE; } - else if ( m_hasAnyAttr ) - { - item.mask |= LVIF_PARAM; - item.lParam = 0; - } item.cchTextMax = 0; bool ok = ListView_SetItem(GetHwnd(), &item) != 0; @@ -1048,20 +1046,10 @@ long wxListCtrl::InsertItem(wxListItem& info) // check whether it has any custom attributes if ( info.HasAttributes() ) { - // FIXME it should be... - wxASSERT_MSG( !info.GetData(), - _T("can't have custom attributes and client data") ); - - item.mask |= LVIF_PARAM; - item.lParam = (long)info.GetAttributes(); + m_attrs.Put(item.iItem, (wxObject *)new wxListItemAttr(*info.GetAttributes())); m_hasAnyAttr = TRUE; } - else if ( m_hasAnyAttr ) - { - item.mask |= LVIF_PARAM; - item.lParam = 0; - } return (long) ListView_InsertItem(GetHwnd(), & item); } @@ -1279,16 +1267,10 @@ bool wxListCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result) // return TRUE to suppress all additional LVN_DELETEITEM // notifications - this makes deleting all items from a list ctrl - // much faster (but we can't do it if we have any custom drawn - // items because we need to delete their attributes in - // LVN_DELETEITEM below) - if ( !m_hasAnyAttr ) - { - *result = TRUE; + // much faster + *result = TRUE; - return TRUE; - } - break; + return TRUE; case LVN_DELETEITEM: { @@ -1298,8 +1280,7 @@ bool wxListCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result) if ( m_hasAnyAttr ) { - wxListItemAttr *attr = (wxListItemAttr *)hdr->lParam; - delete attr; + delete m_attrs.Delete(hdr->iItem); } } break; @@ -1464,7 +1445,7 @@ bool wxListCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result) NMCUSTOMDRAW& nmcd = lplvcd->nmcd; switch( nmcd.dwDrawStage ) { - case CDDS_PREPAINT : + case CDDS_PREPAINT: // if we've got any items with non standard attributes, // notify us before painting each item *result = m_hasAnyAttr ? CDRF_NOTIFYITEMDRAW @@ -1473,30 +1454,68 @@ bool wxListCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result) case CDDS_ITEMPREPAINT: { - if ( !nmcd.lItemlParam ) + wxListItemAttr *attr = + (wxListItemAttr *)m_attrs.Get(nmcd.dwItemSpec); + + if ( !attr ) { // nothing to do for this item return CDRF_DODEFAULT; } - wxListItemAttr *attr = - (wxListItemAttr *)nmcd.lItemlParam; + HFONT hFont; + wxColour colText, colBack; + if ( attr->HasFont() ) + { + wxFont font = attr->GetFont(); + hFont = (HFONT)font.GetResourceHandle(); + } + else + { + hFont = 0; + } + + if ( attr->HasTextColour() ) + { + colText = attr->GetTextColour(); + } + else + { + colText = GetTextColour(); + } + + if ( attr->HasBackgroundColour() ) + { + colBack = attr->GetBackgroundColour(); + } + else + { + colBack = GetBackgroundColour(); + } + + // note that if we wanted to set colours for + // individual columns (subitems), we would have + // returned CDRF_NOTIFYSUBITEMREDRAW from here + if ( hFont ) + { + ::SelectObject(nmcd.hdc, hFont); - ::SelectObject(nmcd.hdc, - (HFONT)((wxFont &)attr->GetFont()). - GetResourceHandle()); - lplvcd->clrText = - wxColourToRGB(attr->GetTextColour()); - lplvcd->clrTextBk = - wxColourToRGB(attr->GetBackgroundColour()); + *result = CDRF_NEWFONT; + } + else + { + *result = CDRF_DODEFAULT; + } - // if we wanted to set colours for individual - // columns (subitems), we would have returned - // CDRF_NOTIFYSUBITEMREDRAW from here - *result = CDRF_NEWFONT; + lplvcd->clrText = wxColourToRGB(colText); + lplvcd->clrTextBk = wxColourToRGB(colBack); return TRUE; } + + default: + *result = CDRF_DODEFAULT; + return TRUE; } } break;