Allow showing rules and background on entire wxListCtrl window

Previously they were both limited to the part occupied by the items
only, add a new method allowing to extend them to the whole client
window area.

See https://github.com/wxWidgets/wxWidgets/pull/2106
This commit is contained in:
Marcos
2020-10-30 14:27:42 -03:00
committed by Vadim Zeitlin
parent 1cf7c47934
commit 584d1ae47d
6 changed files with 131 additions and 10 deletions

View File

@@ -208,6 +208,8 @@ public:
wxListHeaderWindow *m_headerWin; wxListHeaderWindow *m_headerWin;
wxListMainWindow *m_mainWin; wxListMainWindow *m_mainWin;
void SetListRulesAlternateColourOnBlank(bool state, const wxColour& colour);
protected: protected:
// Implement base class pure virtual methods. // Implement base class pure virtual methods.
long DoInsertColumn(long col, const wxListItem& info) wxOVERRIDE; long DoInsertColumn(long col, const wxListItem& info) wxOVERRIDE;

View File

@@ -775,6 +775,17 @@ public:
selected ? ++m_selCount : --m_selCount; 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: protected:
// the array of all line objects for a non virtual list control (for the // the array of all line objects for a non virtual list control (for the
// virtual list control we only ever use m_lines[0]) // virtual list control we only ever use m_lines[0])
@@ -941,6 +952,13 @@ private:
friend class wxGenericListCtrl; friend class wxGenericListCtrl;
friend class wxListCtrlMaxWidthCalculator; 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 #endif // wxUSE_LISTCTRL

View File

@@ -1333,6 +1333,30 @@ public:
*/ */
void CheckItem(long item, bool check); 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: protected:
/** /**

View File

@@ -134,6 +134,9 @@ wxBEGIN_EVENT_TABLE(MyFrame, wxFrame)
EVT_MENU(LIST_SET_FG_COL, MyFrame::OnSetFgColour) EVT_MENU(LIST_SET_FG_COL, MyFrame::OnSetFgColour)
EVT_MENU(LIST_SET_BG_COL, MyFrame::OnSetBgColour) EVT_MENU(LIST_SET_BG_COL, MyFrame::OnSetBgColour)
EVT_MENU(LIST_ROW_LINES, MyFrame::OnSetRowLines) 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_CUSTOM_HEADER_ATTR, MyFrame::OnCustomHeaderAttr)
EVT_MENU(LIST_TOGGLE_MULTI_SEL, MyFrame::OnToggleMultiSel) EVT_MENU(LIST_TOGGLE_MULTI_SEL, MyFrame::OnToggleMultiSel)
EVT_MENU(LIST_SHOW_COL_INFO, MyFrame::OnShowColInfo) 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_CHECKBOXES, MyFrame::OnUpdateToggleCheckBoxes)
EVT_UPDATE_UI(LIST_TOGGLE_HEADER, MyFrame::OnUpdateToggleHeader) EVT_UPDATE_UI(LIST_TOGGLE_HEADER, MyFrame::OnUpdateToggleHeader)
EVT_UPDATE_UI(LIST_ROW_LINES, MyFrame::OnUpdateRowLines) 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() wxEND_EVENT_TABLE()
// My frame constructor // My frame constructor
@@ -277,6 +283,9 @@ MyFrame::MyFrame(const wxString& title)
menuCol->Append(LIST_SET_FG_COL, "&Foreground colour..."); menuCol->Append(LIST_SET_FG_COL, "&Foreground colour...");
menuCol->Append(LIST_SET_BG_COL, "&Background colour..."); menuCol->Append(LIST_SET_BG_COL, "&Background colour...");
menuCol->AppendCheckItem(LIST_ROW_LINES, "Alternating colours"); 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"); menuCol->AppendCheckItem(LIST_CUSTOM_HEADER_ATTR, "&Custom header attributes");
wxMenuBar *menubar = new wxMenuBar; wxMenuBar *menubar = new wxMenuBar;
@@ -520,6 +529,9 @@ void MyFrame::RecreateList(long flags, bool withText)
} }
GetMenuBar()->Check(LIST_ROW_LINES, false); GetMenuBar()->Check(LIST_ROW_LINES, false);
#if !defined(__WXMSW__)
GetMenuBar()->Check(LIST_ROW_LINES_ON_BLANK, false);
#endif
m_logWindow->Clear(); m_logWindow->Clear();
} }
@@ -940,6 +952,20 @@ void MyFrame::OnSetRowLines(wxCommandEvent& event)
m_listCtrl->Refresh(); 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) void MyFrame::OnCustomHeaderAttr(wxCommandEvent& event)
{ {
wxItemAttr attr; wxItemAttr attr;

View File

@@ -133,6 +133,9 @@ protected:
void OnSetFgColour(wxCommandEvent& event); void OnSetFgColour(wxCommandEvent& event);
void OnSetBgColour(wxCommandEvent& event); void OnSetBgColour(wxCommandEvent& event);
void OnSetRowLines(wxCommandEvent& event); void OnSetRowLines(wxCommandEvent& event);
#if !defined(__WXMSW__)
void OnSetRowLinesOnBlank(wxCommandEvent& event);
#endif
void OnCustomHeaderAttr(wxCommandEvent& event); void OnCustomHeaderAttr(wxCommandEvent& event);
void OnToggleMultiSel(wxCommandEvent& event); void OnToggleMultiSel(wxCommandEvent& event);
void OnShowColInfo(wxCommandEvent& event); void OnShowColInfo(wxCommandEvent& event);
@@ -223,6 +226,9 @@ enum
LIST_SET_FG_COL, LIST_SET_FG_COL,
LIST_SET_BG_COL, LIST_SET_BG_COL,
LIST_ROW_LINES, LIST_ROW_LINES,
#if !defined(__WXMSW__)
LIST_ROW_LINES_ON_BLANK,
#endif
LIST_CUSTOM_HEADER_ATTR, LIST_CUSTOM_HEADER_ATTR,
LIST_TOGGLE_MULTI_SEL, LIST_TOGGLE_MULTI_SEL,
LIST_TOGGLE_HEADER, LIST_TOGGLE_HEADER,

View File

@@ -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, void wxListLineData::DrawInReportMode( wxDC *dc,
const wxRect& rect, const wxRect& rect,
const wxRect& rectHL, const wxRect& rectHL,
@@ -1601,6 +1617,9 @@ void wxListMainWindow::Init()
m_anchor = (size_t)-1; m_anchor = (size_t)-1;
m_hasCheckBoxes = false; m_hasCheckBoxes = false;
m_listRulesAlternateColourOnBlank = false;
m_alternateColourOnBlank = wxColour(176, 235, 212, 0xff);;
} }
wxListMainWindow::wxListMainWindow() wxListMainWindow::wxListMainWindow()
@@ -2072,8 +2091,13 @@ void wxListMainWindow::OnPaint( wxPaintEvent &WXUNUSED(event) )
int lineHeight = GetLineHeight(); int lineHeight = GetLineHeight();
size_t visibleFrom, visibleTo; size_t visibleFrom, visibleTo;
size_t visibleEnd;
const size_t linesPerPage = (unsigned int) m_linesPerPage;
GetVisibleLinesRange(&visibleFrom, &visibleTo); GetVisibleLinesRange(&visibleFrom, &visibleTo);
visibleEnd = (m_listRulesAlternateColourOnBlank &&
linesPerPage > visibleTo ? linesPerPage : visibleTo);
wxRect rectLine; wxRect rectLine;
int xOrig = dc.LogicalToDeviceX( 0 ); int xOrig = dc.LogicalToDeviceX( 0 );
int yOrig = dc.LogicalToDeviceY( 0 ); int yOrig = dc.LogicalToDeviceY( 0 );
@@ -2090,7 +2114,7 @@ void wxListMainWindow::OnPaint( wxPaintEvent &WXUNUSED(event) )
GetParent()->GetEventHandler()->ProcessEvent( evCache ); GetParent()->GetEventHandler()->ProcessEvent( evCache );
} }
for ( size_t line = visibleFrom; line <= visibleTo; line++ ) for ( size_t line = visibleFrom; line <= visibleEnd; line++ )
{ {
rectLine = GetLineRect(line); rectLine = GetLineRect(line);
@@ -2102,11 +2126,15 @@ void wxListMainWindow::OnPaint( wxPaintEvent &WXUNUSED(event) )
continue; continue;
} }
if ( line <= visibleTo ) {
GetLine(line)->DrawInReportMode( &dc, GetLine(line)->DrawInReportMode( &dc,
rectLine, rectLine,
GetLineHighlightRect(line), GetLineHighlightRect(line),
IsHighlighted(line), IsHighlighted(line),
line == m_current ); line == m_current );
} else {
DrawInReportModeOnBlank( &dc, rectLine, line );
}
} }
if ( HasFlag(wxLC_HRULES) ) if ( HasFlag(wxLC_HRULES) )
@@ -2116,7 +2144,7 @@ void wxListMainWindow::OnPaint( wxPaintEvent &WXUNUSED(event) )
size_t i = visibleFrom; size_t i = visibleFrom;
if (i == 0) i = 1; // Don't draw the first one if (i == 0) i = 1; // Don't draw the first one
for ( ; i <= visibleTo; i++ ) for ( ; i <= visibleEnd; i++ )
{ {
dc.SetPen(pen); dc.SetPen(pen);
dc.SetBrush( *wxTRANSPARENT_BRUSH ); dc.SetBrush( *wxTRANSPARENT_BRUSH );
@@ -2125,7 +2153,7 @@ void wxListMainWindow::OnPaint( wxPaintEvent &WXUNUSED(event) )
} }
// Draw last horizontal rule // Draw last horizontal rule
if ( visibleTo == GetItemCount() - 1 ) if ( visibleEnd == GetItemCount() - 1 )
{ {
dc.SetPen( pen ); dc.SetPen( pen );
dc.SetBrush( *wxTRANSPARENT_BRUSH ); dc.SetBrush( *wxTRANSPARENT_BRUSH );
@@ -2135,7 +2163,9 @@ void wxListMainWindow::OnPaint( wxPaintEvent &WXUNUSED(event) )
} }
// Draw vertical rules if required // 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); wxPen pen(GetRuleColour(), 1, wxPENSTYLE_SOLID);
wxRect firstItemRect, lastItemRect; wxRect firstItemRect, lastItemRect;
@@ -2146,17 +2176,26 @@ void wxListMainWindow::OnPaint( wxPaintEvent &WXUNUSED(event) )
dc.SetPen(pen); dc.SetPen(pen);
dc.SetBrush(* wxTRANSPARENT_BRUSH); dc.SetBrush(* wxTRANSPARENT_BRUSH);
int clientHeight, clientWidth;
GetSize( &clientWidth, &clientHeight );
for (int col = 0; col < GetColumnCount(); col++) for (int col = 0; col < GetColumnCount(); col++)
{ {
int colWidth = GetColumnWidth(col); int colWidth = GetColumnWidth(col);
x += colWidth; x += colWidth;
int x_pos = x - dev_x; int x_pos = x - dev_x;
if (col < GetColumnCount()-1) x_pos -= 2; if (col < GetColumnCount()-1) x_pos -= 2;
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, dc.DrawLine(x_pos, firstItemRect.GetY() - 1 - dev_y,
x_pos, lastItemRect.GetBottom() + 1 - dev_y); x_pos, lastItemRect.GetBottom() + 1 - dev_y);
} }
} }
} }
}
else // !report else // !report
{ {
size_t count = GetItemCount(); size_t count = GetItemCount();
@@ -4947,6 +4986,12 @@ bool wxGenericListCtrl::Create(wxWindow *parent,
return true; return true;
} }
void wxGenericListCtrl::SetListRulesAlternateColourOnBlank(const bool state, const wxColour& colour)
{
if (m_mainWin)
m_mainWin->SetListRulesAlternateColourOnBlank(state, colour);
}
wxBorder wxGenericListCtrl::GetDefaultBorder() const wxBorder wxGenericListCtrl::GetDefaultBorder() const
{ {
return wxBORDER_THEME; return wxBORDER_THEME;