added wxGridCellRenderer

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@5971 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin 2000-02-11 19:40:56 +00:00
parent 2e9a678817
commit ab79958a7f
4 changed files with 290 additions and 111 deletions

View File

@ -54,12 +54,51 @@
// forward declarations
// ----------------------------------------------------------------------------
class WXDLLEXPORT wxGrid;
class WXDLLEXPORT wxGridCellAttr;
class WXDLLEXPORT wxGridCellAttrProviderData;
class WXDLLEXPORT wxGridRowLabelWindow;
class WXDLLEXPORT wxGridColLabelWindow;
class WXDLLEXPORT wxGridCornerLabelWindow;
class WXDLLEXPORT wxGridRowLabelWindow;
class WXDLLEXPORT wxGridTableBase;
class WXDLLEXPORT wxGridWindow;
class WXDLLEXPORT wxGrid;
// ----------------------------------------------------------------------------
// wxGridCellRenderer: this class is responsible for actually drawing the cell
// in the grid. You may pass it to the wxGridCellAttr (below) to change the
// format of one given cell or to wxGrid::SetDefaultRenderer() to change the
// view of all cells. This is an ABC, you will normally use one of the
// predefined derived classes or derive oyur own class from it.
// ----------------------------------------------------------------------------
class WXDLLEXPORT wxGridCellRenderer
{
public:
// draw the given cell on the provided DC inside the given rectangle
// using the style specified by the attribute and the default or selected
// state corresponding to the isSelected value.
//
// this pure virtual function has a default implementation which will
// prepare the DC using the given attribute: it will draw the rectangle
// with the bg colour from attr and set the text colour and font
virtual void Draw(wxGrid& grid,
wxDC& dc,
const wxRect& rect,
int row, int col,
bool isSelected) = 0;
};
// the default renderer for the cells containing string data
class WXDLLEXPORT wxGridCellStringRenderer : public wxGridCellRenderer
{
public:
// draw the string
virtual void Draw(wxGrid& grid,
wxDC& dc,
const wxRect& rect,
int row, int col,
bool isSelected);
};
// ----------------------------------------------------------------------------
// wxGridCellAttr: this class can be used to alter the cells appearance in
@ -107,6 +146,10 @@ public:
m_vAlign = vAlign;
}
// takes ownership of the pointer
void SetRenderer(wxGridCellRenderer *renderer)
{ delete m_renderer; m_renderer = renderer; }
// accessors
bool HasTextColour() const { return m_colText.Ok(); }
bool HasBackgroundColour() const { return m_colBack.Ok(); }
@ -122,12 +165,14 @@ public:
if ( vAlign ) *vAlign = m_vAlign;
}
wxGridCellRenderer *GetRenderer() const { return m_renderer; }
private:
// the common part of all ctors
void Init() { m_nRef = 1; }
void Init() { m_nRef = 1; m_renderer = (wxGridCellRenderer *)NULL; }
// the dtor is private because only DecRef() can delete us
~wxGridCellAttr() { }
~wxGridCellAttr() { delete m_renderer; }
// the ref count - when it goes to 0, we die
size_t m_nRef;
@ -138,6 +183,8 @@ private:
int m_hAlign,
m_vAlign;
wxGridCellRenderer *m_renderer;
// suppress the stupid gcc warning about the class having private dtor and
// no friends
friend class wxGridCellAttrDummyFriend;
@ -501,8 +548,6 @@ public:
void DrawCellBorder( wxDC& dc, const wxGridCellCoords& );
void DrawAllGridLines( wxDC& dc, const wxRegion & reg );
void DrawCell( wxDC& dc, const wxGridCellCoords& );
void DrawCellBackground( wxDC& dc, const wxGridCellCoords& );
void DrawCellValue( wxDC& dc, const wxGridCellCoords& );
void DrawRowLabels( wxDC& dc );
void DrawRowLabel( wxDC& dc, int row );
@ -617,7 +662,7 @@ public:
wxString GetColLabelValue( int col );
wxColour GetGridLineColour() { return m_gridLineColour; }
void SetRowLabelSize( int width );
void SetRowLabelSize( int width );
void SetColLabelSize( int height );
void SetLabelBackgroundColour( const wxColour& );
void SetLabelTextColour( const wxColour& );
@ -631,7 +676,6 @@ public:
void EnableGridLines( bool enable = TRUE );
bool GridLinesEnabled() { return m_gridLinesEnabled; }
// ------ row and col formatting
//
int GetDefaultRowSize();
@ -662,6 +706,13 @@ public:
void SetDefaultCellAlignment( int horiz, int vert );
void SetCellAlignment( int row, int col, int horiz, int vert );
// takes ownership of the pointer
void SetDefaultRenderer(wxGridCellRenderer *renderer)
{ delete m_defaultRenderer; m_defaultRenderer = renderer; }
wxGridCellRenderer *GetDefaultRenderer() const
{ return m_defaultRenderer; }
void SetCellRenderer(int row, int col, wxGridCellRenderer *renderer);
// ------ cell value accessors
//
@ -957,6 +1008,12 @@ protected:
wxColour m_gridLineColour;
bool m_gridLinesEnabled;
// get the renderer for the given cell - if it has no special one, the
// default one will be returned, never NULL
wxGridCellRenderer *GetCellRenderer(int row, int col);
wxGridCellRenderer *m_defaultRenderer;
// default cell attributes
wxFont m_defaultCellFont;
int m_defaultCellHAlign,

View File

@ -8,9 +8,17 @@
// Licence: wxWindows license
/////////////////////////////////////////////////////////////////////////////
// ============================================================================
// declarations
// ============================================================================
// ----------------------------------------------------------------------------
// headers
// ----------------------------------------------------------------------------
#ifdef __GNUG__
#pragma implementation
#pragma interface
#pragma implementation
#pragma interface
#endif
// For compilers that support precompilation, includes "wx/wx.h".
@ -30,9 +38,19 @@
#include "griddemo.h"
// ----------------------------------------------------------------------------
// wxWin macros
// ----------------------------------------------------------------------------
IMPLEMENT_APP( GridApp )
// ============================================================================
// implementation
// ============================================================================
// ----------------------------------------------------------------------------
// GridApp
// ----------------------------------------------------------------------------
bool GridApp::OnInit()
{
@ -42,7 +60,9 @@ bool GridApp::OnInit()
return TRUE;
}
// ----------------------------------------------------------------------------
// GridFrame
// ----------------------------------------------------------------------------
BEGIN_EVENT_TABLE( GridFrame, wxFrame )
EVT_MENU( ID_TOGGLEROWLABELS, GridFrame::ToggleRowLabels )
@ -61,6 +81,9 @@ BEGIN_EVENT_TABLE( GridFrame, wxFrame )
EVT_MENU( ID_DELETECOL, GridFrame::DeleteSelectedCols )
EVT_MENU( ID_CLEARGRID, GridFrame::ClearGrid )
EVT_MENU( ID_SET_CELL_FG_COLOUR, GridFrame::SetCellFgColour )
EVT_MENU( ID_SET_CELL_BG_COLOUR, GridFrame::SetCellBgColour )
EVT_MENU( ID_ABOUT, GridFrame::About )
EVT_MENU( wxID_EXIT, GridFrame::OnQuit )
@ -90,8 +113,6 @@ GridFrame::GridFrame()
viewMenu->Append( ID_TOGGLEROWLABELS, "&Row labels", "", TRUE );
viewMenu->Append( ID_TOGGLECOLLABELS, "&Col labels", "", TRUE );
viewMenu->Append( ID_TOGGLEEDIT, "&Editable", "", TRUE );
viewMenu->Append( ID_SETLABELCOLOUR, "Set &label colour" );
viewMenu->Append( ID_SETLABELTEXTCOLOUR, "Set label &text colour" );
wxMenu *rowLabelMenu = new wxMenu;
@ -111,7 +132,12 @@ GridFrame::GridFrame()
colLabelMenu->Append( ID_COLLABELHORIZALIGN, "&Horizontal" );
colLabelMenu->Append( ID_COLLABELVERTALIGN, "&Vertical" );
viewMenu->Append( ID_GRIDLINECOLOUR, "&Grid line colour" );
wxMenu *colMenu = new wxMenu;
colMenu->Append( ID_SETLABELCOLOUR, "Set &label colour" );
colMenu->Append( ID_SETLABELTEXTCOLOUR, "Set label &text colour" );
colMenu->Append( ID_GRIDLINECOLOUR, "&Grid line colour" );
colMenu->Append( ID_SET_CELL_FG_COLOUR, "Set cell &foreground colour" );
colMenu->Append( ID_SET_CELL_BG_COLOUR, "Set cell &background colour" );
wxMenu *editMenu = new wxMenu;
editMenu->Append( ID_INSERTROW, "Insert &row" );
@ -126,6 +152,7 @@ GridFrame::GridFrame()
wxMenuBar *menuBar = new wxMenuBar;
menuBar->Append( fileMenu, "&File" );
menuBar->Append( viewMenu, "&View" );
menuBar->Append( colMenu, "&Colours" );
menuBar->Append( editMenu, "&Edit" );
menuBar->Append( helpMenu, "&Help" );
@ -164,11 +191,16 @@ GridFrame::GridFrame()
grid->SetCellValue( 99, 99, "Ctrl+End\nwill go to\nthis cell" );
grid->SetCellValue(2, 2, "red");
grid->SetCellTextColour(2, 2, *wxRED);
grid->SetCellValue(3, 3, "green on grey");
grid->SetCellTextColour(3, 3, *wxGREEN);
grid->SetCellBackgroundColour(3, 3, *wxLIGHT_GREY);
grid->SetCellValue(4, 4, "a weird looking cell");
grid->SetCellAlignment(4, 4, wxCENTRE, wxCENTRE);
grid->SetCellRenderer(4, 4, new MyGridCellRenderer);
wxBoxSizer *topSizer = new wxBoxSizer( wxVERTICAL );
topSizer->Add( grid,
1,
@ -411,6 +443,19 @@ void GridFrame::ClearGrid( wxCommandEvent& WXUNUSED(ev) )
grid->ClearGrid();
}
void GridFrame::SetCellFgColour( wxCommandEvent& WXUNUSED(ev) )
{
wxColour col = wxGetColourFromUser(this);
if ( col.Ok() )
grid->SetDefaultCellTextColour(col);
}
void GridFrame::SetCellBgColour( wxCommandEvent& WXUNUSED(ev) )
{
wxColour col = wxGetColourFromUser(this);
if ( col.Ok() )
grid->SetDefaultCellBackgroundColour(col);
}
void GridFrame::OnLabelLeftClick( wxGridEvent& ev )
{
@ -524,3 +569,19 @@ void GridFrame::OnQuit( wxCommandEvent& WXUNUSED(ev) )
Close( TRUE );
}
// ----------------------------------------------------------------------------
// MyGridCellRenderer
// ----------------------------------------------------------------------------
void MyGridCellRenderer::Draw(wxGrid& grid,
wxDC& dc,
const wxRect& rect,
int row, int col,
bool isSelected)
{
wxGridCellStringRenderer::Draw(grid, dc, rect, row, col, isSelected);
dc.SetPen(*wxGREEN_PEN);
dc.SetBrush(*wxTRANSPARENT_BRUSH);
dc.DrawEllipse(rect);
}

View File

@ -20,7 +20,7 @@ class wxGrid;
class GridApp : public wxApp
{
public:
public:
bool OnInit();
};
@ -45,6 +45,9 @@ class GridFrame : public wxFrame
void SetColLabelVertAlignment( wxCommandEvent& );
void SetGridLineColour( wxCommandEvent& );
void SetCellFgColour(wxCommandEvent &);
void SetCellBgColour(wxCommandEvent &);
void InsertRow( wxCommandEvent& );
void InsertCol( wxCommandEvent& );
void DeleteSelectedRows( wxCommandEvent& );
@ -59,37 +62,51 @@ class GridFrame : public wxFrame
void OnRangeSelected( wxGridRangeSelectEvent& );
void OnCellValueChanged( wxGridEvent& );
public:
public:
GridFrame();
~GridFrame();
void OnQuit( wxCommandEvent& );
void About( wxCommandEvent& );
enum { ID_TOGGLEROWLABELS = 100,
ID_TOGGLECOLLABELS,
ID_TOGGLEEDIT,
ID_SETLABELCOLOUR,
ID_SETLABELTEXTCOLOUR,
ID_ROWLABELALIGN,
ID_ROWLABELHORIZALIGN,
ID_ROWLABELVERTALIGN,
ID_COLLABELALIGN,
ID_COLLABELHORIZALIGN,
ID_COLLABELVERTALIGN,
ID_GRIDLINECOLOUR,
ID_INSERTROW,
ID_INSERTCOL,
ID_DELETEROW,
ID_DELETECOL,
ID_CLEARGRID,
ID_ABOUT,
enum
{
ID_TOGGLEROWLABELS = 100,
ID_TOGGLECOLLABELS,
ID_TOGGLEEDIT,
ID_SETLABELCOLOUR,
ID_SETLABELTEXTCOLOUR,
ID_ROWLABELALIGN,
ID_ROWLABELHORIZALIGN,
ID_ROWLABELVERTALIGN,
ID_COLLABELALIGN,
ID_COLLABELHORIZALIGN,
ID_COLLABELVERTALIGN,
ID_GRIDLINECOLOUR,
ID_INSERTROW,
ID_INSERTCOL,
ID_DELETEROW,
ID_DELETECOL,
ID_CLEARGRID,
ID_SET_CELL_FG_COLOUR,
ID_SET_CELL_BG_COLOUR,
ID_ABOUT,
ID_TESTFUNC };
ID_TESTFUNC
};
DECLARE_EVENT_TABLE()
};
class MyGridCellRenderer : public wxGridCellStringRenderer
{
public:
virtual void Draw(wxGrid& grid,
wxDC& dc,
const wxRect& rect,
int row, int col,
bool isSelected);
};
#endif

View File

@ -189,6 +189,74 @@ wxRect wxGridNoCellRect( -1, -1, -1, -1 );
// TODO: fixed so far - make configurable later (and also different for x/y)
static const size_t GRID_SCROLL_LINE = 10;
// ============================================================================
// implementation
// ============================================================================
// ----------------------------------------------------------------------------
// wxGridCellRenderer
// ----------------------------------------------------------------------------
void wxGridCellRenderer::Draw(wxGrid& grid,
wxDC& dc,
const wxRect& rect,
int row, int col,
bool isSelected)
{
dc.SetBackgroundMode( wxSOLID );
if ( isSelected )
{
// FIXME customize
dc.SetBrush( *wxBLACK_BRUSH );
}
else
{
dc.SetBrush( wxBrush(grid.GetCellBackgroundColour(row, col), wxSOLID) );
}
dc.SetPen( *wxTRANSPARENT_PEN );
dc.DrawRectangle(rect);
}
void wxGridCellStringRenderer::Draw(wxGrid& grid,
wxDC& dc,
const wxRect& rectCell,
int row, int col,
bool isSelected)
{
wxGridCellRenderer::Draw(grid, dc, rectCell, row, col, isSelected);
// now we only have to draw the text
dc.SetBackgroundMode( wxTRANSPARENT );
if ( isSelected )
{
// FIXME customize
dc.SetTextBackground( wxColour(0, 0, 0) );
dc.SetTextForeground( wxColour(255, 255, 255) );
}
else
{
dc.SetTextBackground( grid.GetCellBackgroundColour(row, col) );
dc.SetTextForeground( grid.GetCellTextColour(row, col) );
}
dc.SetFont( grid.GetCellFont(row, col) );
int hAlign, vAlign;
grid.GetCellAlignment(row, col, &hAlign, &vAlign);
wxRect rect = rectCell;
rect.x++;
rect.y++;
rect.width -= 2;
rect.height -= 2;
grid.DrawTextRectangle(dc, grid.GetCellValue(row, col),
rect, hAlign, vAlign);
}
// ----------------------------------------------------------------------------
// wxGridCellAttrProviderData
// ----------------------------------------------------------------------------
@ -1181,6 +1249,7 @@ wxGrid::wxGrid( wxWindow *parent,
wxGrid::~wxGrid()
{
delete m_defaultRenderer;
delete m_table;
}
@ -1323,6 +1392,8 @@ void wxGrid::Init()
m_defaultCellHAlign = wxLEFT;
m_defaultCellVAlign = wxTOP;
m_defaultRenderer = (wxGridCellRenderer *)NULL;
m_gridLineColour = wxColour( 128, 128, 255 );
m_gridLinesEnabled = TRUE;
@ -3096,23 +3167,30 @@ void wxGrid::DrawGridCellArea( wxDC& dc )
void wxGrid::DrawCell( wxDC& dc, const wxGridCellCoords& coords )
{
if ( m_colWidths[coords.GetCol()] <=0 ||
m_rowHeights[coords.GetRow()] <= 0 ) return;
int row = coords.GetRow();
int col = coords.GetCol();
if ( m_colWidths[col] <= 0 || m_rowHeights[row] <= 0 )
return;
// we draw the cell border ourselves
#if !WXGRID_DRAW_LINES
if ( m_gridLinesEnabled )
DrawCellBorder( dc, coords );
#endif
DrawCellBackground( dc, coords );
// but all the rest is drawn by the cell renderer and hence may be
// customized
wxGridCellRenderer *renderer = GetCellRenderer(row, col);
wxRect rect;
rect.x = m_colRights[col] - m_colWidths[col] + 1;
rect.y = m_rowBottoms[row] - m_rowHeights[row] + 1;
rect.width = m_colWidths[col] - 1;
rect.height = m_rowHeights[row] - 1;
// TODO: separate functions here for different kinds of cells ?
// e.g. text, image
//
DrawCellValue( dc, coords );
renderer->Draw(*this, dc, rect, row, col, IsInSelection(coords));
}
void wxGrid::DrawCellBorder( wxDC& dc, const wxGridCellCoords& coords )
{
if ( m_colWidths[coords.GetCol()] <=0 ||
@ -3134,74 +3212,6 @@ void wxGrid::DrawCellBorder( wxDC& dc, const wxGridCellCoords& coords )
}
void wxGrid::DrawCellBackground( wxDC& dc, const wxGridCellCoords& coords )
{
if ( m_colWidths[coords.GetCol()] <=0 ||
m_rowHeights[coords.GetRow()] <= 0 ) return;
int row = coords.GetRow();
int col = coords.GetCol();
dc.SetBackgroundMode( wxSOLID );
if ( IsInSelection( coords ) )
{
// TODO: improve this
//
dc.SetBrush( *wxBLACK_BRUSH );
}
else
{
dc.SetBrush( wxBrush(GetCellBackgroundColour(row, col), wxSOLID) );
}
dc.SetPen( *wxTRANSPARENT_PEN );
dc.DrawRectangle( m_colRights[col] - m_colWidths[col] + 1,
m_rowBottoms[row] - m_rowHeights[row] + 1,
m_colWidths[col]-1,
m_rowHeights[row]-1 );
}
void wxGrid::DrawCellValue( wxDC& dc, const wxGridCellCoords& coords )
{
if ( m_colWidths[coords.GetCol()] <=0 ||
m_rowHeights[coords.GetRow()] <= 0 ) return;
int row = coords.GetRow();
int col = coords.GetCol();
dc.SetBackgroundMode( wxTRANSPARENT );
if ( IsInSelection( row, col ) )
{
// TODO: improve this
//
dc.SetTextBackground( wxColour(0, 0, 0) );
dc.SetTextForeground( wxColour(255, 255, 255) );
}
else
{
dc.SetTextBackground( GetCellBackgroundColour(row, col) );
dc.SetTextForeground( GetCellTextColour(row, col) );
}
dc.SetFont( GetCellFont(row, col) );
int hAlign, vAlign;
GetCellAlignment( row, col, &hAlign, &vAlign );
wxRect rect;
rect.SetX( m_colRights[col] - m_colWidths[col] + 2 );
rect.SetY( m_rowBottoms[row] - m_rowHeights[row] + 2 );
rect.SetWidth( m_colWidths[col] - 4 );
rect.SetHeight( m_rowHeights[row] - 4 );
DrawTextRectangle( dc, GetCellValue( row, col ), rect, hAlign, vAlign );
}
// TODO: remove this ???
// This is used to redraw all grid lines e.g. when the grid line colour
// has been changed
@ -4627,6 +4637,30 @@ void wxGrid::GetDefaultCellAlignment( int *horiz, int *vert )
*vert = m_defaultCellVAlign;
}
wxGridCellRenderer *wxGrid::GetCellRenderer(int row, int col)
{
wxGridCellRenderer *renderer = (wxGridCellRenderer *)NULL;
wxGridCellAttr *attr = m_table ? m_table->GetAttr(row, col) : NULL;
if ( attr )
{
renderer = attr->GetRenderer();
attr->DecRef();
}
if ( !renderer )
{
if ( !m_defaultRenderer )
{
m_defaultRenderer = new wxGridCellStringRenderer;
}
renderer = m_defaultRenderer;
}
return renderer;
}
// ----------------------------------------------------------------------------
// access to cell attributes
// ----------------------------------------------------------------------------
@ -4768,6 +4802,16 @@ void wxGrid::SetCellAlignment( int row, int col, int horiz, int vert )
}
}
void wxGrid::SetCellRenderer(int row, int col, wxGridCellRenderer *renderer)
{
if ( CanHaveAttributes() )
{
wxGridCellAttr *attr = GetCellAttr(row, col);
attr->SetRenderer(renderer);
attr->DecRef();
}
}
// ----------------------------------------------------------------------------
// row/col size
// ----------------------------------------------------------------------------