diff --git a/include/wx/generic/grid.h b/include/wx/generic/grid.h index 6ebf09a1d0..948aba4d0b 100644 --- a/include/wx/generic/grid.h +++ b/include/wx/generic/grid.h @@ -212,6 +212,20 @@ public: return GetBestSize(grid, attr, dc, row, col).GetWidth(); } + + // Unlike GetBestSize(), this functions is optional: it is used when + // auto-sizing columns to determine the best width without iterating over + // all cells in this column, if possible. + // + // If it isn't, return wxDefaultSize as the base class version does by + // default. + virtual wxSize GetMaxBestSize(wxGrid& WXUNUSED(grid), + wxGridCellAttr& WXUNUSED(attr), + wxDC& WXUNUSED(dc)) + { + return wxDefaultSize; + } + // create a new object which is the copy of this one virtual wxGridCellRenderer *Clone() const = 0; }; diff --git a/include/wx/generic/gridctrl.h b/include/wx/generic/gridctrl.h index c06937f0b2..68e3f08323 100644 --- a/include/wx/generic/gridctrl.h +++ b/include/wx/generic/gridctrl.h @@ -141,6 +141,10 @@ public: wxDC& dc, int row, int col) wxOVERRIDE; + virtual wxSize GetMaxBestSize(wxGrid& grid, + wxGridCellAttr& attr, + wxDC& dc) wxOVERRIDE; + virtual wxGridCellRenderer *Clone() const wxOVERRIDE { return new wxGridCellBoolRenderer; } }; @@ -175,6 +179,10 @@ public: wxDC& dc, int row, int col) wxOVERRIDE; + virtual wxSize GetMaxBestSize(wxGrid& grid, + wxGridCellAttr& attr, + wxDC& dc) wxOVERRIDE; + virtual wxGridCellRenderer *Clone() const wxOVERRIDE; // output strptime()-like format string @@ -232,6 +240,10 @@ public: wxDC& dc, int row, int col) wxOVERRIDE; + virtual wxSize GetMaxBestSize(wxGrid& grid, + wxGridCellAttr& attr, + wxDC& dc) wxOVERRIDE; + virtual wxGridCellRenderer *Clone() const wxOVERRIDE; // parameters string format is "item1[,item2[...,itemN]]" where itemN will diff --git a/interface/wx/grid.h b/interface/wx/grid.h index c15e466735..24d2dc8e0e 100644 --- a/interface/wx/grid.h +++ b/interface/wx/grid.h @@ -88,6 +88,26 @@ public: virtual int GetBestWidth(wxGrid& grid, wxGridCellAttr& attr, wxDC& dc, int row, int col, int height); + /** + Get the maximum possible size for a cell using this renderer, if + possible. + + This function may be overridden in the derived class if it can return + the maximum size needed for displaying the cells rendered it without + iterating over all cells. The base class version simply returns + ::wxDefaultSize, indicating that this is infeasible and that + GetBestSize() should be called for each cell individually. + + Note that this method will only be used if + wxGridTableBase::CanMeasureColUsingSameAttr() is overriden to return + @true. + + @since 3.1.4 + */ + virtual wxSize GetMaxBestSize(wxGrid& grid, + wxGridCellAttr& attr, + wxDC& dc); + protected: /** The destructor is private because only DecRef() can delete us. diff --git a/src/generic/grid.cpp b/src/generic/grid.cpp index ec102e3f69..cbf2658f7b 100644 --- a/src/generic/grid.cpp +++ b/src/generic/grid.cpp @@ -10017,6 +10017,21 @@ wxGrid::AutoSizeColOrRow(int colOrRow, bool setAsMin, wxGridDirection direction) { attr = GetCellAttrPtr(row, col); renderer = attr->GetRendererPtr(this, row, col); + + if ( canReuseAttr ) + { + // Try to get the best width for the entire column at once, if + // it's supported by the renderer. + extent = renderer->GetMaxBestSize(*this, *attr, dc).x; + + if ( extent != wxDefaultCoord ) + { + extentMax = extent; + + // No need to check all the values. + break; + } + } } if ( renderer ) diff --git a/src/generic/gridctrl.cpp b/src/generic/gridctrl.cpp index f40acbf0fd..bb9e3dd12c 100644 --- a/src/generic/gridctrl.cpp +++ b/src/generic/gridctrl.cpp @@ -165,6 +165,24 @@ wxSize wxGridCellDateRenderer::GetBestSize(wxGrid& grid, return DoGetBestSize(attr, dc, GetString(grid, row, col)); } +wxSize wxGridCellDateRenderer::GetMaxBestSize(wxGrid& WXUNUSED(grid), + wxGridCellAttr& attr, + wxDC& dc) +{ + wxSize size; + + // Try to produce the longest string in the current format: as we don't + // know which month is the longest, we need to try all of them. + for ( int m = wxDateTime::Jan; m <= wxDateTime::Dec; ++m ) + { + const wxDateTime d(28, static_cast(m), 9999); + + size.IncTo(DoGetBestSize(attr, dc, d.Format(m_oformat, m_tz))); + } + + return size; +} + void wxGridCellDateRenderer::SetParameters(const wxString& params) { if (!params.empty()) @@ -260,6 +278,20 @@ wxSize wxGridCellEnumRenderer::GetBestSize(wxGrid& grid, return DoGetBestSize(attr, dc, GetString(grid, row, col)); } +wxSize wxGridCellEnumRenderer::GetMaxBestSize(wxGrid& WXUNUSED(grid), + wxGridCellAttr& attr, + wxDC& dc) +{ + wxSize size; + + for ( size_t n = 0; n < m_choices.size(); ++n ) + { + size.IncTo(DoGetBestSize(attr, dc, m_choices[n])); + } + + return size; +} + void wxGridCellEnumRenderer::SetParameters(const wxString& params) { if ( !params ) @@ -912,10 +944,17 @@ void wxGridCellFloatRenderer::SetParameters(const wxString& params) // ---------------------------------------------------------------------------- wxSize wxGridCellBoolRenderer::GetBestSize(wxGrid& grid, - wxGridCellAttr& WXUNUSED(attr), - wxDC& WXUNUSED(dc), + wxGridCellAttr& attr, + wxDC& dc, int WXUNUSED(row), int WXUNUSED(col)) +{ + return GetMaxBestSize(grid, attr, dc); +} + +wxSize wxGridCellBoolRenderer::GetMaxBestSize(wxGrid& grid, + wxGridCellAttr& WXUNUSED(attr), + wxDC& WXUNUSED(dc)) { static wxPrivate::DpiDependentValue s_sizeCheckMark;