Merge branch 'listctrl-extend-rules-and-zebra'

Allow extending rules and zebra background in wxListCtrl to the whole
window.

See https://github.com/wxWidgets/wxWidgets/pull/2112
This commit is contained in:
Vadim Zeitlin
2020-11-10 14:08:23 +01:00
7 changed files with 114 additions and 6 deletions

View File

@@ -189,6 +189,8 @@ public:
virtual bool SetFont( const wxFont &font ) wxOVERRIDE;
virtual bool SetCursor( const wxCursor &cursor ) wxOVERRIDE;
virtual void ExtendRulesAndAlternateColour(bool extend = true) wxOVERRIDE;
#if wxUSE_DRAG_AND_DROP
virtual void SetDropTarget( wxDropTarget *dropTarget ) wxOVERRIDE;
virtual wxDropTarget *GetDropTarget() const wxOVERRIDE;

View File

@@ -740,6 +740,12 @@ public:
return true;
}
void ExtendRulesAndAlternateColour(bool extend)
{
m_extendRulesAndAlternateColour = extend;
}
// these are for wxListLineData usage only
// get the backpointer to the list ctrl
@@ -775,6 +781,10 @@ public:
selected ? ++m_selCount : --m_selCount;
}
void DrawInReportModeOnBlank ( wxDC *dc,
const wxRect& rect,
int lineNumber );
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])
@@ -936,6 +946,9 @@ private:
// NULL if no item is being edited
wxListTextCtrlWrapper *m_textctrlWrapper;
// tells whether or not to paint empty rows with alternate colour and draw
// rulers on empty rows
bool m_extendRulesAndAlternateColour;
wxDECLARE_EVENT_TABLE();

View File

@@ -417,6 +417,8 @@ public:
void SetAlternateRowColour(const wxColour& colour);
wxColour GetAlternateRowColour() const { return m_alternateRowColour.GetBackgroundColour(); }
virtual void ExtendRulesAndAlternateColour(bool WXUNUSED(extend) = true) { }
// Header attributes support: only implemented in wxMSW currently.
virtual bool SetHeaderAttr(const wxItemAttr& WXUNUSED(attr)) { return false; }

View File

@@ -1333,6 +1333,33 @@ public:
*/
void CheckItem(long item, bool check);
/**
Extend rules and alternate rows background to the entire client area.
Bu default, the rules (when enabled with wxLC_HRULES and wxLC_VRULES)
and alternate row background (when EnableAlternateRowColours() was
called) are only shown in the part of the control occupied by the
items, which can be smaller than the entire window if there are few
items in the control.
Calling this function extends the display of the rules and alternate
background rows to the entire client area.
Similarly to EnableAlternateRowColours(), this method can only be used
with controls having ::wxLC_REPORT and ::wxLC_VIRTUAL styles.
Note that this method is currently not implemented in the native MSW
version and does nothing there.
@param extend
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.
@since 3.1.5
*/
void ExtendRulesAndAlternateColour(bool extend = true);
protected:
/**

View File

@@ -134,6 +134,7 @@ 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)
EVT_MENU(LIST_ROW_LINES_ON_BLANK, MyFrame::OnSetRowLinesOnBlank)
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 +166,7 @@ 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)
EVT_UPDATE_UI(LIST_ROW_LINES_ON_BLANK, MyFrame::OnUpdateUIEnableInReport)
wxEND_EVENT_TABLE()
// My frame constructor
@@ -277,6 +279,7 @@ 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");
menuCol->AppendCheckItem(LIST_ROW_LINES_ON_BLANK, "Extend to whole window");
menuCol->AppendCheckItem(LIST_CUSTOM_HEADER_ATTR, "&Custom header attributes");
wxMenuBar *menubar = new wxMenuBar;
@@ -520,6 +523,7 @@ void MyFrame::RecreateList(long flags, bool withText)
}
GetMenuBar()->Check(LIST_ROW_LINES, false);
GetMenuBar()->Check(LIST_ROW_LINES_ON_BLANK, false);
m_logWindow->Clear();
}
@@ -940,6 +944,11 @@ void MyFrame::OnSetRowLines(wxCommandEvent& event)
m_listCtrl->Refresh();
}
void MyFrame::OnSetRowLinesOnBlank(wxCommandEvent& event)
{
m_listCtrl->ExtendRulesAndAlternateColour(event.IsChecked());
}
void MyFrame::OnCustomHeaderAttr(wxCommandEvent& event)
{
wxItemAttr attr;
@@ -1426,7 +1435,10 @@ void MyListCtrl::OnListKeyDown(wxListEvent& event)
}
else // !virtual
{
InsertItemInReportView(event.GetIndex());
int idx = event.GetIndex();
if ( idx == -1 )
idx = 0;
InsertItemInReportView(idx);
}
break;
}

View File

@@ -133,6 +133,7 @@ protected:
void OnSetFgColour(wxCommandEvent& event);
void OnSetBgColour(wxCommandEvent& event);
void OnSetRowLines(wxCommandEvent& event);
void OnSetRowLinesOnBlank(wxCommandEvent& event);
void OnCustomHeaderAttr(wxCommandEvent& event);
void OnToggleMultiSel(wxCommandEvent& event);
void OnShowColInfo(wxCommandEvent& event);
@@ -223,6 +224,7 @@ enum
LIST_SET_FG_COL,
LIST_SET_BG_COL,
LIST_ROW_LINES,
LIST_ROW_LINES_ON_BLANK,
LIST_CUSTOM_HEADER_ATTR,
LIST_TOGGLE_MULTI_SEL,
LIST_TOGGLE_HEADER,

View File

@@ -1601,6 +1601,7 @@ void wxListMainWindow::Init()
m_anchor = (size_t)-1;
m_hasCheckBoxes = false;
m_extendRulesAndAlternateColour = false;
}
wxListMainWindow::wxListMainWindow()
@@ -2072,8 +2073,23 @@ void wxListMainWindow::OnPaint( wxPaintEvent &WXUNUSED(event) )
int lineHeight = GetLineHeight();
size_t visibleFrom, visibleTo;
const size_t linesPerPage = (unsigned int) m_linesPerPage;
GetVisibleLinesRange(&visibleFrom, &visibleTo);
// We may need to iterate beyond visibleTo if we want to draw striped
// background across the entire window.
size_t visibleEnd;
wxColour colAlt;
if ( m_extendRulesAndAlternateColour )
{
colAlt = GetListCtrl()->GetAlternateRowColour();
visibleEnd = wxMax(linesPerPage, visibleTo);
}
else
{
visibleEnd = visibleTo;
}
wxRect rectLine;
int xOrig = dc.LogicalToDeviceX( 0 );
int yOrig = dc.LogicalToDeviceY( 0 );
@@ -2090,7 +2106,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,6 +2118,21 @@ void wxListMainWindow::OnPaint( wxPaintEvent &WXUNUSED(event) )
continue;
}
if ( line > visibleTo )
{
// We only iterate beyond visibleTo when we have to draw the
// odd rows background, so do this if needed.
if ( line % 2 )
{
dc.SetBrush(colAlt);
dc.SetPen(*wxTRANSPARENT_PEN);
dc.DrawRectangle(rectLine);
}
// But don't do anything else, as there is no valid item.
continue;
}
GetLine(line)->DrawInReportMode( &dc,
rectLine,
GetLineHighlightRect(line),
@@ -2116,7 +2147,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 +2156,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 +2166,8 @@ void wxListMainWindow::OnPaint( wxPaintEvent &WXUNUSED(event) )
}
// Draw vertical rules if required
if ( HasFlag(wxLC_VRULES) && !IsEmpty() )
if ( HasFlag(wxLC_VRULES) &&
(m_extendRulesAndAlternateColour || !IsEmpty()) )
{
wxPen pen(GetRuleColour(), 1, wxPENSTYLE_SOLID);
wxRect firstItemRect, lastItemRect;
@@ -2146,14 +2178,22 @@ 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;
int ruleHeight = m_extendRulesAndAlternateColour
? clientHeight
: lastItemRect.GetBottom() + 1 - dev_y;
dc.DrawLine(x_pos, firstItemRect.GetY() - 1 - dev_y,
x_pos, lastItemRect.GetBottom() + 1 - dev_y);
x_pos, ruleHeight);
}
}
}
@@ -4947,6 +4987,16 @@ bool wxGenericListCtrl::Create(wxWindow *parent,
return true;
}
void wxGenericListCtrl::ExtendRulesAndAlternateColour(bool state)
{
wxCHECK_RET( m_mainWin, "can't be called before creation" );
wxASSERT_MSG( InReportView(), "can only be called in report mode" );
m_mainWin->ExtendRulesAndAlternateColour(state);
m_mainWin->Refresh();
}
wxBorder wxGenericListCtrl::GetDefaultBorder() const
{
return wxBORDER_THEME;