diff --git a/include/wx/generic/listctrl.h b/include/wx/generic/listctrl.h index 60e034f1af..bf1c8d6e1a 100644 --- a/include/wx/generic/listctrl.h +++ b/include/wx/generic/listctrl.h @@ -208,6 +208,8 @@ public: wxListHeaderWindow *m_headerWin; wxListMainWindow *m_mainWin; + void SetListRulesAlternateColourOnBlank(bool state, const wxColour& colour); + protected: // Implement base class pure virtual methods. long DoInsertColumn(long col, const wxListItem& info) wxOVERRIDE; diff --git a/include/wx/generic/private/listctrl.h b/include/wx/generic/private/listctrl.h index 4087889098..f5e29fef15 100644 --- a/include/wx/generic/private/listctrl.h +++ b/include/wx/generic/private/listctrl.h @@ -775,6 +775,17 @@ public: selected ? ++m_selCount : --m_selCount; } + void DrawInReportModeOnBlank ( wxDC *dc, + const wxRect& rect, + int lineNumber ); + + void SetListRulesAlternateColourOnBlank( const bool state, + const wxColour& colour) + { + m_listRulesAlternateColourOnBlank = state; + m_alternateColourOnBlank = colour; + } + protected: // the array of all line objects for a non virtual list control (for the // virtual list control we only ever use m_lines[0]) @@ -941,6 +952,13 @@ private: friend class wxGenericListCtrl; friend class wxListCtrlMaxWidthCalculator; + + // tells whether or not to paint empty rows with alternate colour and draw + // rulers on empty rows + bool m_listRulesAlternateColourOnBlank; + + // colour to paint empty rows (zebra effect) + wxColour m_alternateColourOnBlank; }; #endif // wxUSE_LISTCTRL diff --git a/interface/wx/listctrl.h b/interface/wx/listctrl.h index d574a4723d..5abfafb0a1 100644 --- a/interface/wx/listctrl.h +++ b/interface/wx/listctrl.h @@ -1333,6 +1333,30 @@ public: */ void CheckItem(long item, bool check); + /** + When the content of state is true, tells listctrl to draw + horizontal and vertical rulers on blank rows and also to + paint the background of alternate rows on blank rows, using + colour to paint the alternate blank(empty) rows' background. + + As EnableAlternateRowColours(), this method can only be used with + controls having ::wxLC_REPORT and ::wxLC_VIRTUAL styles. + + This method is NOT available on Windows. + + @param state + if @true, draws horizontal rules and vertical rules on empty rows + and uses the colour parameter to paint the background of + alternate rows when those rows are blank, empty, with no data. + @param colour + A valid row background colour to enable alternating rows on + blank rows (rows with no data). + + @since 3.1.5 + @note This method is currently NOT implemented in the Windows version. + */ + void SetListRulesAlternateColourOnBlank(const bool state, const wxColour& colour); + protected: /** diff --git a/samples/listctrl/listtest.cpp b/samples/listctrl/listtest.cpp index 016d297c99..bd522a8c62 100644 --- a/samples/listctrl/listtest.cpp +++ b/samples/listctrl/listtest.cpp @@ -134,6 +134,9 @@ wxBEGIN_EVENT_TABLE(MyFrame, wxFrame) EVT_MENU(LIST_SET_FG_COL, MyFrame::OnSetFgColour) EVT_MENU(LIST_SET_BG_COL, MyFrame::OnSetBgColour) EVT_MENU(LIST_ROW_LINES, MyFrame::OnSetRowLines) +#if !defined(__WXMSW__) + EVT_MENU(LIST_ROW_LINES_ON_BLANK, MyFrame::OnSetRowLinesOnBlank) +#endif EVT_MENU(LIST_CUSTOM_HEADER_ATTR, MyFrame::OnCustomHeaderAttr) EVT_MENU(LIST_TOGGLE_MULTI_SEL, MyFrame::OnToggleMultiSel) EVT_MENU(LIST_SHOW_COL_INFO, MyFrame::OnShowColInfo) @@ -165,6 +168,9 @@ wxBEGIN_EVENT_TABLE(MyFrame, wxFrame) EVT_UPDATE_UI(LIST_TOGGLE_CHECKBOXES, MyFrame::OnUpdateToggleCheckBoxes) EVT_UPDATE_UI(LIST_TOGGLE_HEADER, MyFrame::OnUpdateToggleHeader) EVT_UPDATE_UI(LIST_ROW_LINES, MyFrame::OnUpdateRowLines) +#if !defined(__WXMSW__) + EVT_UPDATE_UI(LIST_ROW_LINES_ON_BLANK, MyFrame::OnUpdateRowLines) +#endif wxEND_EVENT_TABLE() // My frame constructor @@ -277,6 +283,9 @@ MyFrame::MyFrame(const wxString& title) menuCol->Append(LIST_SET_FG_COL, "&Foreground colour..."); menuCol->Append(LIST_SET_BG_COL, "&Background colour..."); menuCol->AppendCheckItem(LIST_ROW_LINES, "Alternating colours"); +#if !defined(__WXMSW__) + menuCol->AppendCheckItem(LIST_ROW_LINES_ON_BLANK, "Alternating colours on Blank"); +#endif menuCol->AppendCheckItem(LIST_CUSTOM_HEADER_ATTR, "&Custom header attributes"); wxMenuBar *menubar = new wxMenuBar; @@ -520,6 +529,9 @@ void MyFrame::RecreateList(long flags, bool withText) } GetMenuBar()->Check(LIST_ROW_LINES, false); +#if !defined(__WXMSW__) + GetMenuBar()->Check(LIST_ROW_LINES_ON_BLANK, false); +#endif m_logWindow->Clear(); } @@ -940,6 +952,20 @@ void MyFrame::OnSetRowLines(wxCommandEvent& event) m_listCtrl->Refresh(); } +#if !defined(__WXMSW__) +void MyFrame::OnSetRowLinesOnBlank(wxCommandEvent& event) +{ + wxColour color = wxGetColourFromUser(this); + m_listCtrl->SetSingleStyle(wxLC_HRULES | wxLC_VRULES, event.IsChecked()); + if (event.IsChecked()) + m_listCtrl->SetAlternateRowColour(color); + else + m_listCtrl->EnableAlternateRowColours(event.IsChecked()); + m_listCtrl->SetListRulesAlternateColourOnBlank(event.IsChecked(), color); + m_listCtrl->Refresh(); +} +#endif + void MyFrame::OnCustomHeaderAttr(wxCommandEvent& event) { wxItemAttr attr; diff --git a/samples/listctrl/listtest.h b/samples/listctrl/listtest.h index 40af8628cb..213870635b 100644 --- a/samples/listctrl/listtest.h +++ b/samples/listctrl/listtest.h @@ -133,6 +133,9 @@ protected: void OnSetFgColour(wxCommandEvent& event); void OnSetBgColour(wxCommandEvent& event); void OnSetRowLines(wxCommandEvent& event); +#if !defined(__WXMSW__) + void OnSetRowLinesOnBlank(wxCommandEvent& event); +#endif void OnCustomHeaderAttr(wxCommandEvent& event); void OnToggleMultiSel(wxCommandEvent& event); void OnShowColInfo(wxCommandEvent& event); @@ -223,6 +226,9 @@ enum LIST_SET_FG_COL, LIST_SET_BG_COL, LIST_ROW_LINES, +#if !defined(__WXMSW__) + LIST_ROW_LINES_ON_BLANK, +#endif LIST_CUSTOM_HEADER_ATTR, LIST_TOGGLE_MULTI_SEL, LIST_TOGGLE_HEADER, diff --git a/src/generic/listctrl.cpp b/src/generic/listctrl.cpp index 1497aaa289..9bf6516959 100644 --- a/src/generic/listctrl.cpp +++ b/src/generic/listctrl.cpp @@ -793,6 +793,22 @@ void wxListLineData::Draw(wxDC *dc, bool current) } } +void wxListMainWindow::DrawInReportModeOnBlank ( wxDC *dc, + const wxRect& rect, + int lineNumber ) +{ + // Checks whether or not lineNumber is due to change on its background + // colour and fills the row from beginning to end with the colour stored + // in the m_alternateColourOnBlank instance variable in affirmative case + if ( lineNumber % 2 ) + { + dc->SetBrush(m_alternateColourOnBlank); + dc->SetPen(*wxTRANSPARENT_PEN); + dc->DrawRectangle(rect); + } + +} + void wxListLineData::DrawInReportMode( wxDC *dc, const wxRect& rect, const wxRect& rectHL, @@ -1601,6 +1617,9 @@ void wxListMainWindow::Init() m_anchor = (size_t)-1; m_hasCheckBoxes = false; + + m_listRulesAlternateColourOnBlank = false; + m_alternateColourOnBlank = wxColour(176, 235, 212, 0xff);; } wxListMainWindow::wxListMainWindow() @@ -2072,8 +2091,13 @@ void wxListMainWindow::OnPaint( wxPaintEvent &WXUNUSED(event) ) int lineHeight = GetLineHeight(); size_t visibleFrom, visibleTo; + size_t visibleEnd; + const size_t linesPerPage = (unsigned int) m_linesPerPage; GetVisibleLinesRange(&visibleFrom, &visibleTo); + visibleEnd = (m_listRulesAlternateColourOnBlank && + linesPerPage > visibleTo ? linesPerPage : visibleTo); + wxRect rectLine; int xOrig = dc.LogicalToDeviceX( 0 ); int yOrig = dc.LogicalToDeviceY( 0 ); @@ -2090,7 +2114,7 @@ void wxListMainWindow::OnPaint( wxPaintEvent &WXUNUSED(event) ) GetParent()->GetEventHandler()->ProcessEvent( evCache ); } - for ( size_t line = visibleFrom; line <= visibleTo; line++ ) + for ( size_t line = visibleFrom; line <= visibleEnd; line++ ) { rectLine = GetLineRect(line); @@ -2102,11 +2126,15 @@ void wxListMainWindow::OnPaint( wxPaintEvent &WXUNUSED(event) ) continue; } - GetLine(line)->DrawInReportMode( &dc, - rectLine, - GetLineHighlightRect(line), - IsHighlighted(line), - line == m_current ); + if ( line <= visibleTo ) { + GetLine(line)->DrawInReportMode( &dc, + rectLine, + GetLineHighlightRect(line), + IsHighlighted(line), + line == m_current ); + } else { + DrawInReportModeOnBlank( &dc, rectLine, line ); + } } if ( HasFlag(wxLC_HRULES) ) @@ -2116,7 +2144,7 @@ void wxListMainWindow::OnPaint( wxPaintEvent &WXUNUSED(event) ) size_t i = visibleFrom; if (i == 0) i = 1; // Don't draw the first one - for ( ; i <= visibleTo; i++ ) + for ( ; i <= visibleEnd; i++ ) { dc.SetPen(pen); dc.SetBrush( *wxTRANSPARENT_BRUSH ); @@ -2125,7 +2153,7 @@ void wxListMainWindow::OnPaint( wxPaintEvent &WXUNUSED(event) ) } // Draw last horizontal rule - if ( visibleTo == GetItemCount() - 1 ) + if ( visibleEnd == GetItemCount() - 1 ) { dc.SetPen( pen ); dc.SetBrush( *wxTRANSPARENT_BRUSH ); @@ -2135,7 +2163,9 @@ void wxListMainWindow::OnPaint( wxPaintEvent &WXUNUSED(event) ) } // Draw vertical rules if required - if ( HasFlag(wxLC_VRULES) && !IsEmpty() ) + if ( HasFlag(wxLC_VRULES) && (m_listRulesAlternateColourOnBlank || + ( ! m_listRulesAlternateColourOnBlank + && !IsEmpty() ) ) ) { wxPen pen(GetRuleColour(), 1, wxPENSTYLE_SOLID); wxRect firstItemRect, lastItemRect; @@ -2146,14 +2176,23 @@ void wxListMainWindow::OnPaint( wxPaintEvent &WXUNUSED(event) ) dc.SetPen(pen); dc.SetBrush(* wxTRANSPARENT_BRUSH); + int clientHeight, clientWidth; + GetSize( &clientWidth, &clientHeight ); + for (int col = 0; col < GetColumnCount(); col++) { int colWidth = GetColumnWidth(col); x += colWidth; int x_pos = x - dev_x; if (col < GetColumnCount()-1) x_pos -= 2; - dc.DrawLine(x_pos, firstItemRect.GetY() - 1 - dev_y, + + if (m_listRulesAlternateColourOnBlank) { + dc.DrawLine(x_pos, firstItemRect.GetY() - 1 - dev_y, + x_pos, clientHeight); + } else { + dc.DrawLine(x_pos, firstItemRect.GetY() - 1 - dev_y, x_pos, lastItemRect.GetBottom() + 1 - dev_y); + } } } } @@ -4947,6 +4986,12 @@ bool wxGenericListCtrl::Create(wxWindow *parent, return true; } +void wxGenericListCtrl::SetListRulesAlternateColourOnBlank(const bool state, const wxColour& colour) +{ + if (m_mainWin) + m_mainWin->SetListRulesAlternateColourOnBlank(state, colour); +} + wxBorder wxGenericListCtrl::GetDefaultBorder() const { return wxBORDER_THEME;