Merge branch 'grid-fix-drawing-invalid-cells' of https://github.com/discnl/wxWidgets

Fix drawing of grid cells appearing inside a multicell.

See https://github.com/wxWidgets/wxWidgets/pull/2176
This commit is contained in:
Vadim Zeitlin
2021-01-21 00:50:09 +01:00
2 changed files with 54 additions and 9 deletions

View File

@@ -158,6 +158,24 @@ wxDEFINE_EVENT( wxEVT_GRID_TABBING, wxGridEvent );
// implementation
// ============================================================================
namespace
{
// Helper function for consistent cell span determination based on cell size.
wxGrid::CellSpan GetCellSpan(int numRows, int numCols)
{
if ( numRows == 1 && numCols == 1 )
return wxGrid::CellSpan_None; // just a normal cell
if ( numRows < 0 || numCols < 0 )
return wxGrid::CellSpan_Inside; // covered by a multi-span cell
// this cell spans multiple cells to its right/bottom
return wxGrid::CellSpan_Main;
}
} // anonymous namespace
wxIMPLEMENT_ABSTRACT_CLASS(wxGridCellEditorEvtHandler, wxEvtHandler);
wxBEGIN_EVENT_TABLE( wxGridCellEditorEvtHandler, wxEvtHandler )
@@ -6217,7 +6235,15 @@ void wxGrid::DrawGridCellArea( wxDC& dc, const wxGridCellCoordsArray& cells )
{
if (!m_table->IsEmptyCell(row + l, j))
{
if ( GetCellAttrPtr(row + l, j)->CanOverflow() )
wxGridCellAttrPtr attr = GetCellAttrPtr(row + l, j);
int numRows, numCols;
attr->GetSize(&numRows, &numCols);
if ( GetCellSpan(numRows, numCols)
== wxGrid::CellSpan_Inside )
// As above: don't bother drawing inside cells.
continue;
if ( attr->CanOverflow() )
{
wxGridCellCoords cell(row + l, j);
bool marked = false;
@@ -9120,14 +9146,7 @@ wxGrid::GetCellSize( int row, int col, int *num_rows, int *num_cols ) const
{
GetCellAttrPtr(row, col)->GetSize( num_rows, num_cols );
if ( *num_rows == 1 && *num_cols == 1 )
return CellSpan_None; // just a normal cell
if ( *num_rows < 0 || *num_cols < 0 )
return CellSpan_Inside; // covered by a multi-span cell
// this cell spans multiple cells to its right/bottom
return CellSpan_Main;
return GetCellSpan(*num_rows, *num_cols);
}
wxGridCellRenderer* wxGrid::GetCellRenderer(int row, int col) const

View File

@@ -1423,6 +1423,32 @@ TEST_CASE_METHOD(GridTestCase, "Grid::AutoSizeColumn", "[grid]")
}
}
TEST_CASE_METHOD(GridTestCase, "Grid::DrawInvalidCell", "[grid][multicell]")
{
// Set up a multicell with inside an overflowing cell.
// This is artificial and normally inside cells are probably not expected
// to have a value but this is merely done to check if inside cells are
// drawn, which they shouldn't be.
m_grid->SetCellSize(0, 0, 2, 1);
m_grid->SetCellValue( 1, 0, wxString('W', 42) );
// Update()s, yields and sleep are needed to try to make the test fail with
// macOS, GTK and MSW.
// MSW needs just the yields (or updates), macOS in addition needs to sleep
// (doesn't work with updates) and for GTK it's usually enough to just do
// two updates (not yields). This test does all unconditionally.
m_grid->Update();
wxYield();
wxMilliSleep(20);
// Try to force redrawing of the inside cell: if it still draws there will
// be an infinite recursion.
m_grid->SetColSize(1, m_grid->GetColSize(1) + 1);
m_grid->Update();
wxYield();
}
// Test wxGridBlockCoords here because it'a a part of grid sources.
std::ostream& operator<<(std::ostream& os, const wxGridBlockCoords& block) {