Add wxGridCellRenderer::GetBest{Height,Width}() and use them in wxGrid.
Allow the renderer to specify the best height at the given width (or vice versa) instead of the best size in both direction which is not defined for e.g. wxGridCellAutoWrapStringRenderer. Closes #15943. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@76451 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
parent
02f5b809bd
commit
2e8988c3d6
@ -46,6 +46,7 @@ All (GUI):
|
||||
- Add wxFont::GetBaseFont() (Melroy Tellis).
|
||||
- Update included Scintilla to version 3.3.9 (Christian Walther).
|
||||
- Add support for loading old V1 BMP files to wxImage (Artur Wieczorek).
|
||||
- Improve auto sizing of wrapped cells in wxGrid (iwbnwif).
|
||||
|
||||
wxGTK:
|
||||
|
||||
|
@ -174,6 +174,30 @@ public:
|
||||
wxDC& dc,
|
||||
int row, int col) = 0;
|
||||
|
||||
// Get the preferred height for a given width. Override this method if the
|
||||
// renderer computes height as function of its width, as is the case of the
|
||||
// standard wxGridCellAutoWrapStringRenderer, for example.
|
||||
// and vice versa
|
||||
virtual int GetBestHeight(wxGrid& grid,
|
||||
wxGridCellAttr& attr,
|
||||
wxDC& dc,
|
||||
int row, int col,
|
||||
int WXUNUSED(width))
|
||||
{
|
||||
return GetBestSize(grid, attr, dc, row, col).GetHeight();
|
||||
}
|
||||
|
||||
// Get the preferred width for a given height, this is the symmetric
|
||||
// version of GetBestHeight().
|
||||
virtual int GetBestWidth(wxGrid& grid,
|
||||
wxGridCellAttr& attr,
|
||||
wxDC& dc,
|
||||
int row, int col,
|
||||
int WXUNUSED(height))
|
||||
{
|
||||
return GetBestSize(grid, attr, dc, row, col).GetWidth();
|
||||
}
|
||||
|
||||
// create a new object which is the copy of this one
|
||||
virtual wxGridCellRenderer *Clone() const = 0;
|
||||
};
|
||||
|
@ -238,6 +238,18 @@ public:
|
||||
wxDC& dc,
|
||||
int row, int col) wxOVERRIDE;
|
||||
|
||||
virtual int GetBestHeight(wxGrid& grid,
|
||||
wxGridCellAttr& attr,
|
||||
wxDC& dc,
|
||||
int row, int col,
|
||||
int width) wxOVERRIDE;
|
||||
|
||||
virtual int GetBestWidth(wxGrid& grid,
|
||||
wxGridCellAttr& attr,
|
||||
wxDC& dc,
|
||||
int row, int col,
|
||||
int height) wxOVERRIDE;
|
||||
|
||||
virtual wxGridCellRenderer *Clone() const wxOVERRIDE
|
||||
{ return new wxGridCellAutoWrapStringRenderer; }
|
||||
|
||||
|
@ -48,10 +48,40 @@ public:
|
||||
|
||||
/**
|
||||
Get the preferred size of the cell for its contents.
|
||||
|
||||
This method must be overridden in the derived classes to return the
|
||||
minimal fitting size for displaying the content of the given grid cell.
|
||||
|
||||
@see GetBestHeight(), GetBestWidth()
|
||||
*/
|
||||
virtual wxSize GetBestSize(wxGrid& grid, wxGridCellAttr& attr, wxDC& dc,
|
||||
int row, int col) = 0;
|
||||
|
||||
/**
|
||||
Get the preferred height of the cell at the given width.
|
||||
|
||||
Some renderers may not have a well-defined best size, but only be able
|
||||
to provide the best height at the given width, e.g. this is the case of
|
||||
the standard wxGridCellAutoWrapStringRenderer. In this case, they
|
||||
should override this method, in addition to GetBestSize().
|
||||
|
||||
@see GetBestWidth()
|
||||
|
||||
@since 3.1.0
|
||||
*/
|
||||
virtual wxSize GetBestHeight(wxGrid& grid, wxGridCellAttr& attr, wxDC& dc,
|
||||
int row, int col, int width);
|
||||
|
||||
/**
|
||||
Get the preferred width of the cell at the given height.
|
||||
|
||||
See GetBestHeight(), this method is symmetric to it.
|
||||
|
||||
@since 3.1.0
|
||||
*/
|
||||
virtual wxSize GetBestWidth(wxGrid& grid, wxGridCellAttr& attr, wxDC& dc,
|
||||
int row, int col, int height);
|
||||
|
||||
protected:
|
||||
/**
|
||||
The destructor is private because only DecRef() can delete us.
|
||||
|
@ -8407,8 +8407,11 @@ wxGrid::AutoSizeColOrRow(int colOrRow, bool setAsMin, wxGridDirection direction)
|
||||
wxGridCellRenderer *renderer = attr->GetRenderer(this, row, col);
|
||||
if ( renderer )
|
||||
{
|
||||
wxSize size = renderer->GetBestSize(*this, *attr, dc, row, col);
|
||||
extent = column ? size.x : size.y;
|
||||
extent = column
|
||||
? renderer->GetBestWidth(*this, *attr, dc, row, col,
|
||||
GetRowHeight(row))
|
||||
: renderer->GetBestHeight(*this, *attr, dc, row, col,
|
||||
GetColWidth(col));
|
||||
|
||||
if ( span != CellSpan_None )
|
||||
{
|
||||
|
@ -436,20 +436,57 @@ wxGridCellAutoWrapStringRenderer::GetBestSize(wxGrid& grid,
|
||||
wxDC& dc,
|
||||
int row, int col)
|
||||
{
|
||||
const int lineHeight = dc.GetCharHeight();
|
||||
// We have to make a choice here and fix either width or height because we
|
||||
// don't have any naturally best size. This choice is mostly arbitrary, but
|
||||
// we need to be consistent about it, otherwise wxGrid auto-sizing code
|
||||
// would get confused. For now we decide to use a single line of text and
|
||||
// compute the width needed to fully display everything.
|
||||
const int height = dc.GetCharHeight();
|
||||
|
||||
// Search for a shape no taller than the golden ratio.
|
||||
wxSize size;
|
||||
for ( size.x = 10; ; size.x += 10 )
|
||||
{
|
||||
const size_t
|
||||
numLines = GetTextLines(grid, dc, attr, size, row, col).size();
|
||||
size.y = numLines * lineHeight;
|
||||
if ( size.x >= size.y*1.68 )
|
||||
break;
|
||||
return wxSize(GetBestWidth(grid, attr, dc, row, col, height), height);
|
||||
}
|
||||
|
||||
return size;
|
||||
static const int AUTOWRAP_Y_MARGIN = 4;
|
||||
|
||||
int
|
||||
wxGridCellAutoWrapStringRenderer::GetBestHeight(wxGrid& grid,
|
||||
wxGridCellAttr& attr,
|
||||
wxDC& dc,
|
||||
int row, int col,
|
||||
int width)
|
||||
{
|
||||
const int lineHeight = dc.GetCharHeight();
|
||||
|
||||
// Use as many lines as we need for this width and add a small border to
|
||||
// improve the appearance.
|
||||
return GetTextLines(grid, dc, attr, wxSize(width, lineHeight),
|
||||
row, col).size() * lineHeight + AUTOWRAP_Y_MARGIN;
|
||||
}
|
||||
|
||||
int
|
||||
wxGridCellAutoWrapStringRenderer::GetBestWidth(wxGrid& grid,
|
||||
wxGridCellAttr& attr,
|
||||
wxDC& dc,
|
||||
int row, int col,
|
||||
int height)
|
||||
{
|
||||
const int lineHeight = dc.GetCharHeight();
|
||||
|
||||
// Maximal number of lines that fully fit but at least 1.
|
||||
const size_t maxLines = height - AUTOWRAP_Y_MARGIN < lineHeight
|
||||
? 1
|
||||
: (height - AUTOWRAP_Y_MARGIN)/lineHeight;
|
||||
|
||||
// Increase width until all the text fits.
|
||||
//
|
||||
// TODO: this is not the most efficient to do it for the long strings.
|
||||
const int charWidth = dc.GetCharWidth();
|
||||
int width = 2*charWidth;
|
||||
while ( GetTextLines(grid, dc, attr, wxSize(width, height),
|
||||
row, col).size() > maxLines )
|
||||
width += charWidth;
|
||||
|
||||
return width;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
Loading…
Reference in New Issue
Block a user