diff --git a/docs/changes.txt b/docs/changes.txt index 48bf721253..1f37a94b98 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -595,6 +595,7 @@ All (GUI): - Add wxTL_NO_HEADER style to wxTreeListCtrl (robboto). - Add possibility to delay showing wxRichToolTip (John Roberts). - Add "rect" paramerer to wxRichToolTip::ShowFor() (John Roberts). +- Add wxListCtrl::EnableAlternateRowColours() (troelsk). wxGTK: diff --git a/include/wx/generic/listctrl.h b/include/wx/generic/listctrl.h index 81f9147280..7caa1fc14f 100644 --- a/include/wx/generic/listctrl.h +++ b/include/wx/generic/listctrl.h @@ -229,9 +229,6 @@ protected: // return the icon for the given item and column. virtual int OnGetItemColumnImage(long item, long column) const; - // return the attribute for the item (may return NULL if none) - virtual wxListItemAttr *OnGetItemAttr(long item) const; - // it calls our OnGetXXX() functions friend class WXDLLIMPEXP_FWD_CORE wxListMainWindow; diff --git a/include/wx/listbase.h b/include/wx/listbase.h index 4aa0d5f046..0bbb2bc4a5 100644 --- a/include/wx/listbase.h +++ b/include/wx/listbase.h @@ -446,6 +446,8 @@ public: virtual int GetColumnWidth(int col) const = 0; virtual bool SetColumnWidth(int col, int width) = 0; + // return the attribute for the item (may return NULL if none) + virtual wxListItemAttr *OnGetItemAttr(long item) const; // Other miscellaneous accessors. // ------------------------------ @@ -458,12 +460,19 @@ public: // Only implemented in the generic version currently. virtual void EnableBellOnNoMatch(bool WXUNUSED(on) = true) { } + void EnableAlternateRowColours(bool enable = true); + void SetAlternateRowColour(const wxColour& colour); + protected: // Real implementations methods to which our public forwards. virtual long DoInsertColumn(long col, const wxListItem& info) = 0; // Overridden methods of the base class. virtual wxSize DoGetBestClientSize() const; + +private: + // user defined color to draw row lines, may be invalid + wxListItemAttr m_alternateRowColour; }; // ---------------------------------------------------------------------------- diff --git a/include/wx/msw/listctrl.h b/include/wx/msw/listctrl.h index a873d07546..30080f8784 100644 --- a/include/wx/msw/listctrl.h +++ b/include/wx/msw/listctrl.h @@ -439,9 +439,6 @@ protected: // return the icon for the given item and column. virtual int OnGetItemColumnImage(long item, long column) const; - // return the attribute for the item (may return NULL if none) - virtual wxListItemAttr *OnGetItemAttr(long item) const; - // return the attribute for the given item and column (may return NULL if none) virtual wxListItemAttr *OnGetItemColumnAttr(long item, long WXUNUSED(column)) const { diff --git a/include/wx/osx/listctrl.h b/include/wx/osx/listctrl.h index cd6b2e9fb6..eb6b50b4a9 100644 --- a/include/wx/osx/listctrl.h +++ b/include/wx/osx/listctrl.h @@ -291,9 +291,6 @@ class WXDLLIMPEXP_CORE wxListCtrl: public wxListCtrlBase // return the icon for the given item and column. virtual int OnGetItemColumnImage(long item, long column) const; - // return the attribute for the item (may return NULL if none) - virtual wxListItemAttr *OnGetItemAttr(long item) const; - /* Why should we need this function? Leave for now. * We might need it because item data may have changed, * but the display needs refreshing (in string callback mode) diff --git a/interface/wx/listctrl.h b/interface/wx/listctrl.h index 358bfc4f78..5b955e12c4 100644 --- a/interface/wx/listctrl.h +++ b/interface/wx/listctrl.h @@ -407,6 +407,27 @@ public: wxTextCtrl* EditLabel(long item, wxClassInfo* textControlClass = wxCLASSINFO(wxTextCtrl)); + /** + Enable alternating row background colours (also called zebra striping). + + This method can only be called for the control in virtual report mode, + i.e. having ::wxLC_REPORT and ::wxLC_VIRTUAL styles. + + When enabling alternating colours, the appropriate colour for the even + rows is chosen automatically depending on the default foreground and + background colours which are used for the odd rows. + + @param enable + If @true, enable alternating row background colours, i.e. different + colours for the odd and even rows. If @false, disable this feature + and use the same background colour for all rows. + + @since 2.9.5 + + @see SetAlternateRowColour() + */ + void EnableAlternateRowColours(bool enable = true); + /** Enable or disable a beep if there is no match for the currently entered text when searching for the item from keyboard. @@ -750,6 +771,26 @@ public: */ wxRect GetViewRect() const; + /** + Set the alternative row background colour to a specific colour. + + It is recommended to call EnableAlternateRowColours() instead of using + these methods as native implementations of this control might support + alternating row colours but not setting the exact colour to be used for + them. + + As EnableAlternateRowColours(), this method can only be used with + controls having ::wxLC_REPORT and ::wxLC_VIRTUAL styles. + + @param colour + A valid alternative row background colour to enable alternating + rows or invalid colour to disable them and use the same colour for + all rows. + + @since 2.9.5 + */ + void SetAlternateRowColour(const wxColour& colour); + /** Determines which item (if any) is at the specified point, giving details in @a flags. Returns index of the item or @c wxNOT_FOUND if no item is at diff --git a/samples/listctrl/listtest.cpp b/samples/listctrl/listtest.cpp index e69a82ceb3..eaeb8a9bd7 100644 --- a/samples/listctrl/listtest.cpp +++ b/samples/listctrl/listtest.cpp @@ -137,6 +137,7 @@ BEGIN_EVENT_TABLE(MyFrame, wxFrame) EVT_MENU(LIST_SORT, MyFrame::OnSort) EVT_MENU(LIST_SET_FG_COL, MyFrame::OnSetFgColour) EVT_MENU(LIST_SET_BG_COL, MyFrame::OnSetBgColour) + EVT_MENU(LIST_ROW_LINES, MyFrame::OnSetRowLines) EVT_MENU(LIST_TOGGLE_MULTI_SEL, MyFrame::OnToggleMultiSel) EVT_MENU(LIST_SHOW_COL_INFO, MyFrame::OnShowColInfo) EVT_MENU(LIST_SHOW_SEL_INFO, MyFrame::OnShowSelInfo) @@ -160,6 +161,7 @@ BEGIN_EVENT_TABLE(MyFrame, wxFrame) EVT_UPDATE_UI(LIST_TOGGLE_MULTI_SEL, MyFrame::OnUpdateToggleMultiSel) EVT_UPDATE_UI(LIST_TOGGLE_HEADER, MyFrame::OnUpdateToggleHeader) + EVT_UPDATE_UI(LIST_ROW_LINES, MyFrame::OnUpdateRowLines) END_EVENT_TABLE() // My frame constructor @@ -264,6 +266,7 @@ MyFrame::MyFrame(const wxChar *title) wxMenu *menuCol = new wxMenu; menuCol->Append(LIST_SET_FG_COL, wxT("&Foreground colour...")); menuCol->Append(LIST_SET_BG_COL, wxT("&Background colour...")); + menuCol->AppendCheckItem(LIST_ROW_LINES, wxT("Alternating colours")); wxMenuBar *menubar = new wxMenuBar; menubar->Append(menuFile, wxT("&File")); @@ -483,6 +486,8 @@ void MyFrame::RecreateList(long flags, bool withText) DoSize(); + GetMenuBar()->Check(LIST_ROW_LINES, false); + m_logWindow->Clear(); } @@ -836,6 +841,11 @@ void MyFrame::OnUpdateToggleHeader(wxUpdateUIEvent& event) event.Check(!m_listCtrl->HasFlag(wxLC_NO_HEADER)); } +void MyFrame::OnUpdateRowLines(wxUpdateUIEvent& event) +{ + event.Enable(m_listCtrl->HasFlag(wxLC_VIRTUAL)); +} + void MyFrame::OnSetFgColour(wxCommandEvent& WXUNUSED(event)) { m_listCtrl->SetForegroundColour(wxGetColourFromUser(this)); @@ -848,6 +858,12 @@ void MyFrame::OnSetBgColour(wxCommandEvent& WXUNUSED(event)) m_listCtrl->Refresh(); } +void MyFrame::OnSetRowLines(wxCommandEvent& event) +{ + m_listCtrl->EnableAlternateRowColours(event.IsChecked()); + m_listCtrl->Refresh(); +} + void MyFrame::OnAdd(wxCommandEvent& WXUNUSED(event)) { m_listCtrl->InsertItem(m_listCtrl->GetItemCount(), wxT("Appended item")); @@ -1328,7 +1344,7 @@ wxListItemAttr *MyListCtrl::OnGetItemAttr(long item) const return &s_attrHighlight; } - return item % 2 ? NULL : (wxListItemAttr *)&m_attr; + return wxListCtrl::OnGetItemAttr(item); } void MyListCtrl::InsertItemInReportView(int i) diff --git a/samples/listctrl/listtest.h b/samples/listctrl/listtest.h index dafb92384b..f99c135eb2 100644 --- a/samples/listctrl/listtest.h +++ b/samples/listctrl/listtest.h @@ -37,8 +37,7 @@ public: const wxPoint& pos, const wxSize& size, long style) - : wxListCtrl(parent, id, pos, size, style), - m_attr(*wxBLUE, *wxLIGHT_GREY, wxNullFont) + : wxListCtrl(parent, id, pos, size, style) { m_updated = -1; @@ -88,8 +87,6 @@ private: virtual int OnGetItemColumnImage(long item, long column) const; virtual wxListItemAttr *OnGetItemAttr(long item) const; - wxListItemAttr m_attr; - long m_updated; @@ -135,6 +132,7 @@ protected: void OnSort(wxCommandEvent& event); void OnSetFgColour(wxCommandEvent& event); void OnSetBgColour(wxCommandEvent& event); + void OnSetRowLines(wxCommandEvent& event); void OnToggleMultiSel(wxCommandEvent& event); void OnShowColInfo(wxCommandEvent& event); void OnShowSelInfo(wxCommandEvent& event); @@ -156,6 +154,7 @@ protected: void OnUpdateUIEnableInReport(wxUpdateUIEvent& event); void OnUpdateToggleMultiSel(wxUpdateUIEvent& event); void OnUpdateToggleHeader(wxUpdateUIEvent& event); + void OnUpdateRowLines(wxUpdateUIEvent& event); wxImageList *m_imageListNormal; wxImageList *m_imageListSmall; @@ -218,6 +217,7 @@ enum LIST_FIND, LIST_SET_FG_COL, LIST_SET_BG_COL, + LIST_ROW_LINES, LIST_TOGGLE_MULTI_SEL, LIST_TOGGLE_HEADER, LIST_TOGGLE_BELL, diff --git a/src/common/listctrlcmn.cpp b/src/common/listctrlcmn.cpp index a4cd12f288..4c89a84d26 100644 --- a/src/common/listctrlcmn.cpp +++ b/src/common/listctrlcmn.cpp @@ -216,4 +216,38 @@ wxSize wxListCtrlBase::DoGetBestClientSize() const return wxSize(totalWidth, 10*dc.GetCharHeight()); } +void wxListCtrlBase::SetAlternateRowColour(const wxColour& colour) +{ + wxASSERT(HasFlag(wxLC_VIRTUAL)); + m_alternateRowColour.SetBackgroundColour(colour); +} + +void wxListCtrlBase::EnableAlternateRowColours(bool enable) +{ + if ( enable ) + { + // This code is copied from wxDataViewMainWindow::OnPaint() + + // Determine the alternate rows colour automatically from the + // background colour. + const wxColour bgColour = GetBackgroundColour(); + + // Depending on the background, alternate row color + // will be 3% more dark or 50% brighter. + int alpha = bgColour.GetRGB() > 0x808080 ? 97 : 150; + SetAlternateRowColour(bgColour.ChangeLightness(alpha)); + } + else // Disable striping by setting invalid alternative colour. + { + SetAlternateRowColour(wxColour()); + } +} + +wxListItemAttr *wxListCtrlBase::OnGetItemAttr(long item) const +{ + return (m_alternateRowColour.GetBackgroundColour().IsOk() && (item % 2)) + ? wxConstCast(&m_alternateRowColour, wxListItemAttr) + : NULL; // no attributes by default +} + #endif // wxUSE_LISTCTRL diff --git a/src/generic/listctrl.cpp b/src/generic/listctrl.cpp index 03e299d46a..b311e031ef 100644 --- a/src/generic/listctrl.cpp +++ b/src/generic/listctrl.cpp @@ -5397,16 +5397,6 @@ int wxGenericListCtrl::OnGetItemColumnImage(long item, long column) const return -1; } -wxListItemAttr * -wxGenericListCtrl::OnGetItemAttr(long WXUNUSED_UNLESS_DEBUG(item)) const -{ - wxASSERT_MSG( item >= 0 && item < GetItemCount(), - wxT("invalid item index in OnGetItemAttr()") ); - - // no attributes by default - return NULL; -} - void wxGenericListCtrl::SetItemCount(long count) { wxASSERT_MSG( IsVirtual(), wxT("this is for virtual controls only") ); diff --git a/src/msw/listctrl.cpp b/src/msw/listctrl.cpp index abfdf8db89..941506314e 100644 --- a/src/msw/listctrl.cpp +++ b/src/msw/listctrl.cpp @@ -3089,15 +3089,6 @@ int wxListCtrl::OnGetItemColumnImage(long item, long column) const return -1; } -wxListItemAttr *wxListCtrl::OnGetItemAttr(long WXUNUSED_UNLESS_DEBUG(item)) const -{ - wxASSERT_MSG( item >= 0 && item < GetItemCount(), - wxT("invalid item index in OnGetItemAttr()") ); - - // no attributes by default - return NULL; -} - wxListItemAttr *wxListCtrl::DoGetItemColumnAttr(long item, long column) const { if ( IsVirtual() ) diff --git a/src/os2/listctrl.cpp b/src/os2/listctrl.cpp index cf9a922745..3b4cd843ea 100644 --- a/src/os2/listctrl.cpp +++ b/src/os2/listctrl.cpp @@ -2588,19 +2588,6 @@ int wxListCtrl::OnGetItemColumnImage ( return -1; } // end of wxListCtrl::OnGetItemColumnImage -wxListItemAttr* wxListCtrl::OnGetItemAttr ( - long WXUNUSED_UNLESS_DEBUG(lItem) -) const -{ - wxASSERT_MSG( lItem >= 0 && lItem < GetItemCount(), - wxT("invalid item index in OnGetItemAttr()") ); - - // - // No attributes by default - // - return NULL; -} // end of wxListCtrl::OnGetItemAttr - void wxListCtrl::SetItemCount ( long lCount ) diff --git a/src/osx/carbon/listctrl_mac.cpp b/src/osx/carbon/listctrl_mac.cpp index 7aca51773a..73335f0445 100644 --- a/src/osx/carbon/listctrl_mac.cpp +++ b/src/osx/carbon/listctrl_mac.cpp @@ -2308,15 +2308,6 @@ int wxListCtrl::OnGetItemColumnImage(long item, long column) const return -1; } -wxListItemAttr *wxListCtrl::OnGetItemAttr(long WXUNUSED_UNLESS_DEBUG(item)) const -{ - wxASSERT_MSG( item >= 0 && item < GetItemCount(), - wxT("invalid item index in OnGetItemAttr()") ); - - // no attributes by default - return NULL; -} - void wxListCtrl::SetItemCount(long count) { wxASSERT_MSG( IsVirtual(), wxT("this is for virtual controls only") );