Merge branch 'grid-autosize'

Optimize wxGrid::AutoSizeColumns() for big grids.

This includes an optimization of wxDC::GetTextExtent() at the price of
slightly reduced precision in wxMSW.

See https://github.com/wxWidgets/wxWidgets/pull/1893
This commit is contained in:
Vadim Zeitlin
2020-06-16 20:37:57 +02:00
9 changed files with 305 additions and 114 deletions

View File

@@ -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;
};
@@ -1065,6 +1079,16 @@ public:
return wxGridCellAttrPtr(GetAttr(row, col, kind));
}
// This is an optimization for a common case when the entire column uses
// roughly the same attribute, which can thus be reused for measuring all
// the cells in this column. Override this to return true (possibly for
// some columns only) to speed up AutoSizeColumns() for the grids using
// this table.
virtual bool CanMeasureColUsingSameAttr(int WXUNUSED(col)) const
{
return false;
}
// these functions take ownership of the pointer
virtual void SetAttr(wxGridCellAttr* attr, int row, int col);
virtual void SetRowAttr(wxGridCellAttr *attr, int row);
@@ -1869,11 +1893,8 @@ public:
{ AutoSizeColOrRow(row, setAsMin, wxGRID_ROW); }
// auto size all columns (very ineffective for big grids!)
void AutoSizeColumns( bool setAsMin = true )
{ (void)SetOrCalcColumnSizes(false, setAsMin); }
void AutoSizeRows( bool setAsMin = true )
{ (void)SetOrCalcRowSizes(false, setAsMin); }
void AutoSizeColumns( bool setAsMin = true );
void AutoSizeRows( bool setAsMin = true );
// auto size the grid, that is make the columns/rows of the "right" size
// and also set the grid size to just fit its contents
@@ -2414,10 +2435,6 @@ protected:
wxColour m_gridFrozenBorderColour;
int m_gridFrozenBorderPenWidth;
// common part of AutoSizeColumn/Row() and GetBestSize()
int SetOrCalcColumnSizes(bool calcOnly, bool setAsMin = true);
int SetOrCalcRowSizes(bool calcOnly, bool setAsMin = true);
// common part of AutoSizeColumn/Row()
void AutoSizeColOrRow(int n, bool setAsMin, wxGridDirection direction);

View File

@@ -57,6 +57,13 @@ protected:
class WXDLLIMPEXP_ADV wxGridCellNumberRenderer : public wxGridCellStringRenderer
{
public:
explicit wxGridCellNumberRenderer(long minValue = LONG_MIN,
long maxValue = LONG_MAX)
: m_minValue(minValue),
m_maxValue(maxValue)
{
}
// draw the string right aligned
virtual void Draw(wxGrid& grid,
wxGridCellAttr& attr,
@@ -70,11 +77,21 @@ public:
wxDC& dc,
int row, int col) wxOVERRIDE;
virtual wxSize GetMaxBestSize(wxGrid& grid,
wxGridCellAttr& attr,
wxDC& dc) wxOVERRIDE;
// Optional parameters for this renderer are "<min>,<max>".
virtual void SetParameters(const wxString& params) wxOVERRIDE;
virtual wxGridCellRenderer *Clone() const wxOVERRIDE
{ return new wxGridCellNumberRenderer; }
{ return new wxGridCellNumberRenderer(m_minValue, m_maxValue); }
protected:
wxString GetString(const wxGrid& grid, int row, int col);
long m_minValue,
m_maxValue;
};
class WXDLLIMPEXP_ADV wxGridCellFloatRenderer : public wxGridCellStringRenderer
@@ -141,6 +158,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 +196,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
@@ -213,8 +238,37 @@ protected:
#endif // wxUSE_DATETIME
// Renderer for fields taking one of a limited set of values: this is the same
// as the renderer for strings, except that it can implement GetMaxBestSize().
class WXDLLIMPEXP_ADV wxGridCellChoiceRenderer : public wxGridCellStringRenderer
{
public:
wxGridCellChoiceRenderer() { }
virtual wxSize GetMaxBestSize(wxGrid& grid,
wxGridCellAttr& attr,
wxDC& dc) wxOVERRIDE;
// Parameters string is a comma-separated list of values.
virtual void SetParameters(const wxString& params) wxOVERRIDE;
virtual wxGridCellRenderer *Clone() const wxOVERRIDE
{
return new wxGridCellChoiceRenderer(*this);
}
protected:
wxGridCellChoiceRenderer(const wxGridCellChoiceRenderer& other)
: m_choices(other.m_choices)
{
}
wxArrayString m_choices;
};
// renders a number using the corresponding text string
class WXDLLIMPEXP_ADV wxGridCellEnumRenderer : public wxGridCellStringRenderer
class WXDLLIMPEXP_ADV wxGridCellEnumRenderer : public wxGridCellChoiceRenderer
{
public:
wxGridCellEnumRenderer( const wxString& choices = wxEmptyString );
@@ -234,14 +288,8 @@ public:
virtual wxGridCellRenderer *Clone() const wxOVERRIDE;
// parameters string format is "item1[,item2[...,itemN]]" where itemN will
// be used if the cell value is N-1
virtual void SetParameters(const wxString& params) wxOVERRIDE;
protected:
wxString GetString(const wxGrid& grid, int row, int col);
wxArrayString m_choices;
};