column autosizing added
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@6213 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -105,6 +105,12 @@ public:
|
|||||||
int row, int col,
|
int row, int col,
|
||||||
bool isSelected) = 0;
|
bool isSelected) = 0;
|
||||||
|
|
||||||
|
// get the preferred size of the cell for its contents
|
||||||
|
virtual wxSize GetBestSize(wxGrid& grid,
|
||||||
|
wxGridCellAttr& attr,
|
||||||
|
wxDC& dc,
|
||||||
|
int row, int col) = 0;
|
||||||
|
|
||||||
// virtual dtor for any base class
|
// virtual dtor for any base class
|
||||||
virtual ~wxGridCellRenderer();
|
virtual ~wxGridCellRenderer();
|
||||||
};
|
};
|
||||||
@@ -121,12 +127,23 @@ public:
|
|||||||
int row, int col,
|
int row, int col,
|
||||||
bool isSelected);
|
bool isSelected);
|
||||||
|
|
||||||
|
// return the string extent
|
||||||
|
virtual wxSize GetBestSize(wxGrid& grid,
|
||||||
|
wxGridCellAttr& attr,
|
||||||
|
wxDC& dc,
|
||||||
|
int row, int col);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// set the text colours before drawing
|
// set the text colours before drawing
|
||||||
void SetTextColoursAndFont(wxGrid& grid,
|
void SetTextColoursAndFont(wxGrid& grid,
|
||||||
wxGridCellAttr& attr,
|
wxGridCellAttr& attr,
|
||||||
wxDC& dc,
|
wxDC& dc,
|
||||||
bool isSelected);
|
bool isSelected);
|
||||||
|
|
||||||
|
// calc the string extent for given string/font
|
||||||
|
wxSize DoGetBestSize(wxGridCellAttr& attr,
|
||||||
|
wxDC& dc,
|
||||||
|
const wxString& text);
|
||||||
};
|
};
|
||||||
|
|
||||||
// the default renderer for the cells containing numeric (long) data
|
// the default renderer for the cells containing numeric (long) data
|
||||||
@@ -140,6 +157,14 @@ public:
|
|||||||
const wxRect& rect,
|
const wxRect& rect,
|
||||||
int row, int col,
|
int row, int col,
|
||||||
bool isSelected);
|
bool isSelected);
|
||||||
|
|
||||||
|
virtual wxSize GetBestSize(wxGrid& grid,
|
||||||
|
wxGridCellAttr& attr,
|
||||||
|
wxDC& dc,
|
||||||
|
int row, int col);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
wxString GetString(wxGrid& grid, int row, int col);
|
||||||
};
|
};
|
||||||
|
|
||||||
class WXDLLEXPORT wxGridCellFloatRenderer : public wxGridCellStringRenderer
|
class WXDLLEXPORT wxGridCellFloatRenderer : public wxGridCellStringRenderer
|
||||||
@@ -161,6 +186,13 @@ public:
|
|||||||
int row, int col,
|
int row, int col,
|
||||||
bool isSelected);
|
bool isSelected);
|
||||||
|
|
||||||
|
virtual wxSize GetBestSize(wxGrid& grid,
|
||||||
|
wxGridCellAttr& attr,
|
||||||
|
wxDC& dc,
|
||||||
|
int row, int col);
|
||||||
|
protected:
|
||||||
|
wxString GetString(wxGrid& grid, int row, int col);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// formatting parameters
|
// formatting parameters
|
||||||
int m_width,
|
int m_width,
|
||||||
@@ -180,6 +212,15 @@ public:
|
|||||||
const wxRect& rect,
|
const wxRect& rect,
|
||||||
int row, int col,
|
int row, int col,
|
||||||
bool isSelected);
|
bool isSelected);
|
||||||
|
|
||||||
|
// return the checkmark size
|
||||||
|
virtual wxSize GetBestSize(wxGrid& grid,
|
||||||
|
wxGridCellAttr& attr,
|
||||||
|
wxDC& dc,
|
||||||
|
int row, int col);
|
||||||
|
|
||||||
|
private:
|
||||||
|
static wxSize ms_sizeCheckMark;
|
||||||
};
|
};
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
@@ -1001,6 +1042,14 @@ public:
|
|||||||
|
|
||||||
void SetColSize( int col, int width );
|
void SetColSize( int col, int width );
|
||||||
|
|
||||||
|
// automatically size the column to fit to its contents, if setAsMin is
|
||||||
|
// TRUE, this optimal width will also be set as minimal width for this
|
||||||
|
// column
|
||||||
|
void AutoSizeColumn( int col, bool setAsMin = TRUE );
|
||||||
|
|
||||||
|
// auto size all columns (very ineffective for big grids!)
|
||||||
|
void AutoSizeColumns( bool setAsMin = TRUE );
|
||||||
|
|
||||||
// column won't be resized to be lesser width - this must be called during
|
// column won't be resized to be lesser width - this must be called during
|
||||||
// the grid creation because it won't resize the column if it's already
|
// the grid creation because it won't resize the column if it's already
|
||||||
// narrower than the minimal width
|
// narrower than the minimal width
|
||||||
@@ -1506,8 +1555,6 @@ protected:
|
|||||||
DECLARE_EVENT_TABLE()
|
DECLARE_EVENT_TABLE()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// Grid event class and event types
|
// Grid event class and event types
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
@@ -959,8 +959,13 @@ BugsGridFrame::BugsGridFrame()
|
|||||||
wxGridTableBase *table = new BugsGridTable();
|
wxGridTableBase *table = new BugsGridTable();
|
||||||
grid->SetTable(table, TRUE);
|
grid->SetTable(table, TRUE);
|
||||||
|
|
||||||
for ( size_t row = 0; row < WXSIZEOF(gs_dataBugsGrid); row++ )
|
wxGridCellAttr *attrRO = new wxGridCellAttr,
|
||||||
{
|
*attrRangeEditor = new wxGridCellAttr;
|
||||||
grid->SetReadOnly(row, Col_Id);
|
attrRO->SetReadOnly();
|
||||||
}
|
attrRangeEditor->SetEditor(new wxGridCellNumberEditor(1, 5));
|
||||||
|
|
||||||
|
grid->SetColAttr(Col_Id, attrRO);
|
||||||
|
grid->SetColAttr(Col_Priority, attrRangeEditor);
|
||||||
|
|
||||||
|
grid->AutoSizeColumns();
|
||||||
}
|
}
|
||||||
|
@@ -961,6 +961,25 @@ void wxGridCellStringRenderer::SetTextColoursAndFont(wxGrid& grid,
|
|||||||
dc.SetFont( attr.GetFont() );
|
dc.SetFont( attr.GetFont() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wxSize wxGridCellStringRenderer::DoGetBestSize(wxGridCellAttr& attr,
|
||||||
|
wxDC& dc,
|
||||||
|
const wxString& text)
|
||||||
|
{
|
||||||
|
wxCoord x, y;
|
||||||
|
dc.SetFont(attr.GetFont());
|
||||||
|
dc.GetTextExtent(text, &x, &y);
|
||||||
|
|
||||||
|
return wxSize(x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
wxSize wxGridCellStringRenderer::GetBestSize(wxGrid& grid,
|
||||||
|
wxGridCellAttr& attr,
|
||||||
|
wxDC& dc,
|
||||||
|
int row, int col)
|
||||||
|
{
|
||||||
|
return DoGetBestSize(attr, dc, grid.GetCellValue(row, col));
|
||||||
|
}
|
||||||
|
|
||||||
void wxGridCellStringRenderer::Draw(wxGrid& grid,
|
void wxGridCellStringRenderer::Draw(wxGrid& grid,
|
||||||
wxGridCellAttr& attr,
|
wxGridCellAttr& attr,
|
||||||
wxDC& dc,
|
wxDC& dc,
|
||||||
@@ -983,6 +1002,23 @@ void wxGridCellStringRenderer::Draw(wxGrid& grid,
|
|||||||
rect, hAlign, vAlign);
|
rect, hAlign, vAlign);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// wxGridCellNumberRenderer
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
wxString wxGridCellNumberRenderer::GetString(wxGrid& grid, int row, int col)
|
||||||
|
{
|
||||||
|
wxGridTableBase *table = grid.GetTable();
|
||||||
|
wxString text;
|
||||||
|
if ( table->CanGetValueAs(row, col, wxGRID_VALUE_NUMBER) )
|
||||||
|
{
|
||||||
|
text.Printf(_T("%ld"), table->GetValueAsLong(row, col));
|
||||||
|
}
|
||||||
|
//else: leave the string empty or put 0 into it?
|
||||||
|
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
|
||||||
void wxGridCellNumberRenderer::Draw(wxGrid& grid,
|
void wxGridCellNumberRenderer::Draw(wxGrid& grid,
|
||||||
wxGridCellAttr& attr,
|
wxGridCellAttr& attr,
|
||||||
wxDC& dc,
|
wxDC& dc,
|
||||||
@@ -1002,15 +1038,15 @@ void wxGridCellNumberRenderer::Draw(wxGrid& grid,
|
|||||||
wxRect rect = rectCell;
|
wxRect rect = rectCell;
|
||||||
rect.Inflate(-1);
|
rect.Inflate(-1);
|
||||||
|
|
||||||
wxGridTableBase *table = grid.GetTable();
|
grid.DrawTextRectangle(dc, GetString(grid, row, col), rect, hAlign, vAlign);
|
||||||
wxString text;
|
}
|
||||||
if ( table->CanGetValueAs(row, col, wxGRID_VALUE_NUMBER) )
|
|
||||||
{
|
|
||||||
text.Printf(_T("%ld"), table->GetValueAsLong(row, col));
|
|
||||||
}
|
|
||||||
//else: leave the string empty or put 0 into it?
|
|
||||||
|
|
||||||
grid.DrawTextRectangle(dc, text, rect, hAlign, vAlign);
|
wxSize wxGridCellNumberRenderer::GetBestSize(wxGrid& grid,
|
||||||
|
wxGridCellAttr& attr,
|
||||||
|
wxDC& dc,
|
||||||
|
int row, int col)
|
||||||
|
{
|
||||||
|
return DoGetBestSize(attr, dc, GetString(grid, row, col));
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
@@ -1023,6 +1059,24 @@ wxGridCellFloatRenderer::wxGridCellFloatRenderer(int width, int precision)
|
|||||||
SetPrecision(precision);
|
SetPrecision(precision);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wxString wxGridCellFloatRenderer::GetString(wxGrid& grid, int row, int col)
|
||||||
|
{
|
||||||
|
wxGridTableBase *table = grid.GetTable();
|
||||||
|
wxString text;
|
||||||
|
if ( table->CanGetValueAs(row, col, wxGRID_VALUE_FLOAT) )
|
||||||
|
{
|
||||||
|
if ( !m_format )
|
||||||
|
{
|
||||||
|
m_format.Printf(_T("%%%d.%d%%f"), m_width, m_precision);
|
||||||
|
}
|
||||||
|
|
||||||
|
text.Printf(m_format, table->GetValueAsDouble(row, col));
|
||||||
|
}
|
||||||
|
//else: leave the string empty or put 0 into it?
|
||||||
|
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
|
||||||
void wxGridCellFloatRenderer::Draw(wxGrid& grid,
|
void wxGridCellFloatRenderer::Draw(wxGrid& grid,
|
||||||
wxGridCellAttr& attr,
|
wxGridCellAttr& attr,
|
||||||
wxDC& dc,
|
wxDC& dc,
|
||||||
@@ -1042,26 +1096,54 @@ void wxGridCellFloatRenderer::Draw(wxGrid& grid,
|
|||||||
wxRect rect = rectCell;
|
wxRect rect = rectCell;
|
||||||
rect.Inflate(-1);
|
rect.Inflate(-1);
|
||||||
|
|
||||||
wxGridTableBase *table = grid.GetTable();
|
grid.DrawTextRectangle(dc, GetString(grid, row, col), rect, hAlign, vAlign);
|
||||||
wxString text;
|
}
|
||||||
if ( table->CanGetValueAs(row, col, wxGRID_VALUE_FLOAT) )
|
|
||||||
{
|
|
||||||
if ( !m_format )
|
|
||||||
{
|
|
||||||
m_format.Printf(_T("%%%d.%d%%f"), m_width, m_precision);
|
|
||||||
}
|
|
||||||
|
|
||||||
text.Printf(m_format, table->GetValueAsDouble(row, col));
|
wxSize wxGridCellFloatRenderer::GetBestSize(wxGrid& grid,
|
||||||
}
|
wxGridCellAttr& attr,
|
||||||
//else: leave the string empty or put 0 into it?
|
wxDC& dc,
|
||||||
|
int row, int col)
|
||||||
grid.DrawTextRectangle(dc, text, rect, hAlign, vAlign);
|
{
|
||||||
|
return DoGetBestSize(attr, dc, GetString(grid, row, col));
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// wxGridCellBoolRenderer
|
// wxGridCellBoolRenderer
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
wxSize wxGridCellBoolRenderer::ms_sizeCheckMark;
|
||||||
|
|
||||||
|
// between checkmark and box
|
||||||
|
static const wxCoord wxGRID_CHECKMARK_MARGIN = 4;
|
||||||
|
|
||||||
|
wxSize wxGridCellBoolRenderer::GetBestSize(wxGrid& grid,
|
||||||
|
wxGridCellAttr& WXUNUSED(attr),
|
||||||
|
wxDC& WXUNUSED(dc),
|
||||||
|
int WXUNUSED(row),
|
||||||
|
int WXUNUSED(col))
|
||||||
|
{
|
||||||
|
// compute it only once (no locks for MT safeness in GUI thread...)
|
||||||
|
if ( !ms_sizeCheckMark.x )
|
||||||
|
{
|
||||||
|
// get checkbox size
|
||||||
|
wxCoord checkSize = 0;
|
||||||
|
wxCheckBox *checkbox = new wxCheckBox(&grid, -1, wxEmptyString);
|
||||||
|
wxSize size = checkbox->GetBestSize();
|
||||||
|
checkSize = size.y + wxGRID_CHECKMARK_MARGIN;
|
||||||
|
|
||||||
|
// FIXME wxGTK::wxCheckBox::GetBestSize() gives "wrong" result
|
||||||
|
#ifdef __WXGTK__
|
||||||
|
checkSize -= size.y / 2;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
delete checkbox;
|
||||||
|
|
||||||
|
ms_sizeCheckMark.x = ms_sizeCheckMark.y = checkSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ms_sizeCheckMark;
|
||||||
|
}
|
||||||
|
|
||||||
void wxGridCellBoolRenderer::Draw(wxGrid& grid,
|
void wxGridCellBoolRenderer::Draw(wxGrid& grid,
|
||||||
wxGridCellAttr& attr,
|
wxGridCellAttr& attr,
|
||||||
wxDC& dc,
|
wxDC& dc,
|
||||||
@@ -1071,37 +1153,19 @@ void wxGridCellBoolRenderer::Draw(wxGrid& grid,
|
|||||||
{
|
{
|
||||||
wxGridCellRenderer::Draw(grid, attr, dc, rect, row, col, isSelected);
|
wxGridCellRenderer::Draw(grid, attr, dc, rect, row, col, isSelected);
|
||||||
|
|
||||||
// between checkmark and box
|
|
||||||
static const wxCoord margin = 4;
|
|
||||||
|
|
||||||
// get checkbox size
|
|
||||||
static wxCoord s_checkSize = 0;
|
|
||||||
if ( s_checkSize == 0 )
|
|
||||||
{
|
|
||||||
// compute it only once (no locks for MT safeness in GUI thread...)
|
|
||||||
wxCheckBox *checkbox = new wxCheckBox(&grid, -1, wxEmptyString);
|
|
||||||
wxSize size = checkbox->GetBestSize();
|
|
||||||
s_checkSize = size.y + margin;
|
|
||||||
|
|
||||||
// FIXME wxGTK::wxCheckBox::GetBestSize() is really weird...
|
|
||||||
#ifdef __WXGTK__
|
|
||||||
s_checkSize -= size.y / 2;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
delete checkbox;
|
|
||||||
}
|
|
||||||
|
|
||||||
// draw a check mark in the centre (ignoring alignment - TODO)
|
// draw a check mark in the centre (ignoring alignment - TODO)
|
||||||
|
wxSize size = GetBestSize(grid, attr, dc, row, col);
|
||||||
wxRect rectMark;
|
wxRect rectMark;
|
||||||
rectMark.x = rect.x + rect.width/2 - s_checkSize/2;
|
rectMark.x = rect.x + rect.width/2 - size.x/2;
|
||||||
rectMark.y = rect.y + rect.height/2 - s_checkSize/2;
|
rectMark.y = rect.y + rect.height/2 - size.y/2;
|
||||||
rectMark.width = rectMark.height = s_checkSize;
|
rectMark.width = size.x;
|
||||||
|
rectMark.height = size.y;
|
||||||
|
|
||||||
dc.SetBrush(*wxTRANSPARENT_BRUSH);
|
dc.SetBrush(*wxTRANSPARENT_BRUSH);
|
||||||
dc.SetPen(wxPen(attr.GetTextColour(), 1, wxSOLID));
|
dc.SetPen(wxPen(attr.GetTextColour(), 1, wxSOLID));
|
||||||
dc.DrawRectangle(rectMark);
|
dc.DrawRectangle(rectMark);
|
||||||
|
|
||||||
rectMark.Inflate(-margin);
|
rectMark.Inflate(-wxGRID_CHECKMARK_MARGIN);
|
||||||
|
|
||||||
bool value;
|
bool value;
|
||||||
if (grid.GetTable()->CanGetValueAs(row, col, wxT("bool")))
|
if (grid.GetTable()->CanGetValueAs(row, col, wxT("bool")))
|
||||||
@@ -6599,6 +6663,62 @@ int wxGrid::GetColMinimalWidth(int col) const
|
|||||||
return obj ? (int)obj : WXGRID_MIN_COL_WIDTH;
|
return obj ? (int)obj : WXGRID_MIN_COL_WIDTH;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void wxGrid::AutoSizeColumn( int col, bool setAsMin )
|
||||||
|
{
|
||||||
|
wxClientDC dc(m_gridWin);
|
||||||
|
|
||||||
|
wxCoord width, widthMax = 0;
|
||||||
|
for ( int row = 0; row < m_numRows; row++ )
|
||||||
|
{
|
||||||
|
wxGridCellAttr* attr = GetCellAttr(row, col);
|
||||||
|
wxGridCellRenderer* renderer = attr->GetRenderer(GetDefaultRendererForCell(row,col));
|
||||||
|
if ( renderer )
|
||||||
|
{
|
||||||
|
width = renderer->GetBestSize(*this, *attr, dc, row, col).x;
|
||||||
|
if ( width > widthMax )
|
||||||
|
{
|
||||||
|
widthMax = width;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
attr->DecRef();
|
||||||
|
}
|
||||||
|
|
||||||
|
// now also compare with the column label width
|
||||||
|
dc.SetFont( GetLabelFont() );
|
||||||
|
dc.GetTextExtent( GetColLabelValue(col), &width, NULL );
|
||||||
|
if ( width > widthMax )
|
||||||
|
{
|
||||||
|
widthMax = width;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( !widthMax )
|
||||||
|
{
|
||||||
|
// empty column - give default width (notice that if widthMax is less
|
||||||
|
// than default width but != 0, it's ok)
|
||||||
|
widthMax = m_defaultColWidth;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// leave some space around text
|
||||||
|
widthMax += 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
SetColSize(col, widthMax);
|
||||||
|
if ( setAsMin )
|
||||||
|
{
|
||||||
|
SetColMinimalWidth(col, widthMax);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxGrid::AutoSizeColumns( bool setAsMin )
|
||||||
|
{
|
||||||
|
for ( int col = 0; col < m_numCols; col++ )
|
||||||
|
{
|
||||||
|
AutoSizeColumn(col, setAsMin);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// ------ cell value accessor functions
|
// ------ cell value accessor functions
|
||||||
//
|
//
|
||||||
|
Reference in New Issue
Block a user