// Modified by: Santiago Palacios
// RCS-ID: $Id$
// Copyright: (c) Michael Bedward, Julian Smart, Vadim Zeitlin
-// Licence: wxWindows license
+// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
// ============================================================================
#include "griddemo.h"
-#ifndef __WXMSW__
+#ifndef wxHAS_IMAGES_IN_RESOURCES
#include "../sample.xpm"
#endif
+// Custom renderer that renders column header cells without borders and in
+// italic
+class CustomColumnHeaderRenderer : public wxGridColumnHeaderRenderer
+{
+public:
+ CustomColumnHeaderRenderer(const wxColour& colFg, const wxColour& colBg)
+ : m_colFg(colFg),
+ m_colBg(colBg)
+ {
+ }
+
+ virtual void DrawLabel(const wxGrid& WXUNUSED(grid),
+ wxDC& dc,
+ const wxString& value,
+ const wxRect& rect,
+ int horizAlign,
+ int vertAlign,
+ int WXUNUSED(textOrientation)) const
+ {
+ dc.SetTextForeground(m_colFg);
+ dc.SetFont(wxITALIC_FONT->Bold());
+ dc.DrawLabel(value, rect, horizAlign | vertAlign);
+ }
+
+ virtual void DrawBorder(const wxGrid& WXUNUSED(grid),
+ wxDC& dc,
+ wxRect& rect) const
+ {
+ dc.SetPen(*wxTRANSPARENT_PEN);
+ dc.SetBrush(wxBrush(m_colBg));
+ dc.DrawRectangle(rect);
+ }
+
+private:
+ const wxColour m_colFg, m_colBg;
+
+ wxDECLARE_NO_COPY_CLASS(CustomColumnHeaderRenderer);
+};
+
+// And a custom attributes provider which uses custom column header renderer
+// defined above
+class CustomColumnHeadersProvider : public wxGridCellAttrProvider
+{
+public:
+ // by default custom column renderer is not used, call
+ // UseCustomColHeaders() to enable it
+ CustomColumnHeadersProvider()
+ : m_customOddRenderer(*wxYELLOW, *wxBLUE),
+ m_customEvenRenderer(*wxWHITE, *wxBLACK),
+ m_useCustom(false)
+ {
+ }
+
+ // enable or disable the use of custom renderer for column headers
+ void UseCustomColHeaders(bool use = true) { m_useCustom = use; }
+
+protected:
+ virtual const wxGridColumnHeaderRenderer& GetColumnHeaderRenderer(int col)
+ {
+ // if enabled, use custom renderers
+ if ( m_useCustom )
+ {
+ // and use different ones for odd and even columns -- just to show
+ // that we can
+ return col % 2 ? m_customOddRenderer : m_customEvenRenderer;
+ }
+
+ return wxGridCellAttrProvider::GetColumnHeaderRenderer(col);
+ }
+
+private:
+ CustomColumnHeaderRenderer m_customOddRenderer,
+ m_customEvenRenderer;
+
+ bool m_useCustom;
+
+ wxDECLARE_NO_COPY_CLASS(CustomColumnHeadersProvider);
+};
+
// ----------------------------------------------------------------------------
// wxWin macros
// ----------------------------------------------------------------------------
EVT_MENU( ID_TOGGLECOLMOVING, GridFrame::ToggleColMoving )
EVT_MENU( ID_TOGGLEGRIDSIZING, GridFrame::ToggleGridSizing )
EVT_MENU( ID_TOGGLEGRIDDRAGCELL, GridFrame::ToggleGridDragCell )
- EVT_MENU( ID_TOGGLENATIVEHEADER, GridFrame::ToggleNativeHeader )
+ EVT_MENU( ID_COLNATIVEHEADER, GridFrame::SetNativeColHeader )
+ EVT_MENU( ID_COLDEFAULTHEADER, GridFrame::SetDefaultColHeader )
+ EVT_MENU( ID_COLCUSTOMHEADER, GridFrame::SetCustomColHeader )
EVT_MENU( ID_TOGGLEGRIDLINES, GridFrame::ToggleGridLines )
EVT_MENU( ID_AUTOSIZECOLS, GridFrame::AutoSizeCols )
EVT_MENU( ID_CELLOVERFLOW, GridFrame::CellOverflow )
EVT_MENU( ID_SELECT_ROW, GridFrame::SelectRow)
EVT_MENU( ID_SELECT_ALL, GridFrame::SelectAll)
EVT_MENU( ID_SELECT_UNSELECT, GridFrame::OnAddToSelectToggle)
- EVT_MENU( ID_SHOW_SELECTION, GridFrame::OnShowSelection)
EVT_MENU( ID_SIZE_ROW, GridFrame::AutoSizeRow )
EVT_MENU( ID_SIZE_COL, GridFrame::AutoSizeCol )
EVT_MENU( ID_SET_HIGHLIGHT_WIDTH, GridFrame::OnSetHighlightWidth)
EVT_MENU( ID_SET_RO_HIGHLIGHT_WIDTH, GridFrame::OnSetROHighlightWidth)
+ EVT_MENU( wxID_PRINT, GridFrame::OnGridRender )
+ EVT_MENU( ID_RENDER_COORDS, GridFrame::OnGridRender )
+
EVT_GRID_LABEL_LEFT_CLICK( GridFrame::OnLabelLeftClick )
EVT_GRID_CELL_LEFT_CLICK( GridFrame::OnCellLeftClick )
EVT_GRID_ROW_SIZE( GridFrame::OnRowSize )
fileMenu->Append( ID_VTABLE, wxT("&Virtual table test\tCtrl-V"));
fileMenu->Append( ID_BUGS_TABLE, wxT("&Bugs table test\tCtrl-B"));
fileMenu->Append( ID_TABULAR_TABLE, wxT("&Tabular table test\tCtrl-T"));
+ fileMenu->AppendSeparator();
+
+ wxMenu* setupMenu = new wxMenu;
+ wxMenuItem* item;
+ item = setupMenu->AppendCheckItem( ID_RENDER_ROW_LABEL,
+ "Render row labels" );
+ item->Check();
+ item = setupMenu->AppendCheckItem( ID_RENDER_COL_LABEL,
+ "Render column labels" );
+ item->Check();
+ item = setupMenu->AppendCheckItem( ID_RENDER_GRID_LINES,
+ "Render grid cell lines" );
+ item->Check();
+ item = setupMenu->AppendCheckItem( ID_RENDER_GRID_BORDER,
+ "Render border" );
+ item->Check();
+ item = setupMenu->AppendCheckItem( ID_RENDER_SELECT_HLIGHT,
+ "Render selection highlight" );
+ setupMenu->AppendSeparator();
+ setupMenu->AppendCheckItem( ID_RENDER_LOMETRIC,
+ "Use LOMETRIC mapping mode" );
+ setupMenu->AppendCheckItem( ID_RENDER_DEFAULT_SIZE,
+ "Use wxDefaultSize" );
+ setupMenu->AppendCheckItem( ID_RENDER_MARGIN,
+ "Logical 50 unit margin" );
+ setupMenu->AppendCheckItem( ID_RENDER_ZOOM,
+ "Zoom 125%" );
+
+ fileMenu->AppendSubMenu( setupMenu, "Render setup" );
+ fileMenu->Append( wxID_PRINT, "Render" );
+ fileMenu->Append( ID_RENDER_COORDS, "Render G5:P30" );
+
fileMenu->AppendSeparator();
fileMenu->Append( wxID_EXIT, wxT("E&xit\tAlt-X") );
viewMenu->AppendCheckItem(ID_TOGGLECOLMOVING, "Col drag-&move");
viewMenu->AppendCheckItem(ID_TOGGLEGRIDSIZING, "&Grid drag-resize");
viewMenu->AppendCheckItem(ID_TOGGLEGRIDDRAGCELL, "&Grid drag-cell");
- viewMenu->AppendCheckItem(ID_TOGGLENATIVEHEADER, "&Native column headers");
viewMenu->AppendCheckItem(ID_TOGGLEGRIDLINES, "&Grid Lines");
viewMenu->AppendCheckItem(ID_SET_HIGHLIGHT_WIDTH, "&Set Cell Highlight Width...");
viewMenu->AppendCheckItem(ID_SET_RO_HIGHLIGHT_WIDTH, "&Set Cell RO Highlight Width...");
rowLabelMenu,
wxT("Change alignment of row labels") );
- rowLabelMenu->Append( ID_ROWLABELHORIZALIGN, wxT("&Horizontal") );
- rowLabelMenu->Append( ID_ROWLABELVERTALIGN, wxT("&Vertical") );
+ rowLabelMenu->AppendRadioItem( ID_ROWLABELHORIZALIGN, wxT("&Horizontal") );
+ rowLabelMenu->AppendRadioItem( ID_ROWLABELVERTALIGN, wxT("&Vertical") );
wxMenu *colLabelMenu = new wxMenu;
colLabelMenu,
wxT("Change alignment of col labels") );
- colLabelMenu->Append( ID_COLLABELHORIZALIGN, wxT("&Horizontal") );
- colLabelMenu->Append( ID_COLLABELVERTALIGN, wxT("&Vertical") );
+ colLabelMenu->AppendRadioItem( ID_COLLABELHORIZALIGN, wxT("&Horizontal") );
+ colLabelMenu->AppendRadioItem( ID_COLLABELVERTALIGN, wxT("&Vertical") );
+
+ wxMenu *colHeaderMenu = new wxMenu;
+
+ viewMenu->Append( ID_ROWLABELALIGN, wxT("Col header style"),
+ colHeaderMenu,
+ wxT("Change style of col header") );
+
+ colHeaderMenu->AppendRadioItem( ID_COLDEFAULTHEADER, wxT("&Default") );
+ colHeaderMenu->AppendRadioItem( ID_COLNATIVEHEADER, wxT("&Native") );
+ colHeaderMenu->AppendRadioItem( ID_COLCUSTOMHEADER, wxT("&Custom") );
+
wxMenu *colMenu = new wxMenu;
colMenu->Append( ID_SETLABELCOLOUR, wxT("Set &label colour...") );
selectMenu->Append( ID_SELECT_UNSELECT, wxT("Add new cells to the selection"),
wxT("When off, old selection is deselected before ")
wxT("selecting the new cells"), wxITEM_CHECK );
- selectMenu->Append( ID_SHOW_SELECTION,
- wxT("&Show current selection\tCtrl-Alt-S"));
selectMenu->AppendSeparator();
selectMenu->Append( ID_SELECT_ALL, wxT("Select all"));
selectMenu->Append( ID_SELECT_ROW, wxT("Select row 2"));
wxPoint( 0, 0 ),
wxSize( 400, 300 ) );
+
#if wxUSE_LOG
int gridW = 600, gridH = 300;
int logW = gridW, logH = 100;
// this will create a grid and, by default, an associated grid
// table for strings
grid->CreateGrid( 0, 0 );
+
+ grid->GetTable()->SetAttrProvider(new CustomColumnHeadersProvider());
+
grid->AppendRows(100);
grid->AppendCols(100);
grid->SetCellValue(5, 8, wxT("Bg from row attr\nText col from cell attr"));
grid->SetCellValue(5, 5, wxT("Bg from row attr Text col from col attr and this text is so long that it covers over many many empty cells but is broken by one that isn't"));
+ // Some numeric columns with different formatting.
grid->SetColFormatFloat(6);
- grid->SetCellValue(0, 6, wxString::Format(wxT("%g"), 3.1415));
- grid->SetCellValue(1, 6, wxString::Format(wxT("%g"), 1415.0));
- grid->SetCellValue(2, 6, wxString::Format(wxT("%g"), 12345.67890));
+ grid->SetCellValue(0, 6, "Default\nfloat format");
+ grid->SetCellValue(1, 6, wxString::Format(wxT("%g"), 3.1415));
+ grid->SetCellValue(2, 6, wxString::Format(wxT("%g"), 1415.0));
+ grid->SetCellValue(3, 6, wxString::Format(wxT("%g"), 12345.67890));
grid->SetColFormatFloat(7, 6, 2);
- grid->SetCellValue(0, 7, wxString::Format(wxT("%g"), 3.1415));
- grid->SetCellValue(1, 7, wxString::Format(wxT("%g"), 1415.0));
- grid->SetCellValue(2, 7, wxString::Format(wxT("%g"), 12345.67890));
-
- grid->SetColFormatNumber(8);
- grid->SetCellValue(0, 8, "17");
- grid->SetCellValue(1, 8, "0");
- grid->SetCellValue(2, 8, "-666");
+ grid->SetCellValue(0, 7, "Width 6\nprecision 2");
+ grid->SetCellValue(1, 7, wxString::Format(wxT("%g"), 3.1415));
+ grid->SetCellValue(2, 7, wxString::Format(wxT("%g"), 1415.0));
+ grid->SetCellValue(3, 7, wxString::Format(wxT("%g"), 12345.67890));
+
+ grid->SetColFormatCustom(8,
+ wxString::Format("%s:%i,%i,%s", wxGRID_VALUE_FLOAT, -1, 4, "g"));
+ grid->SetCellValue(0, 8, "Compact\nformat");
+ grid->SetCellValue(1, 8, wxT("31415e-4"));
+ grid->SetCellValue(2, 8, wxT("1415"));
+ grid->SetCellValue(3, 8, wxT("123456789e-4"));
+
+ grid->SetColFormatNumber(9);
+ grid->SetCellValue(0, 9, "Integer\ncolumn");
+ grid->SetCellValue(1, 9, "17");
+ grid->SetCellValue(2, 9, "0");
+ grid->SetCellValue(3, 9, "-666");
+ grid->SetCellAlignment(3, 9, wxALIGN_CENTRE, wxALIGN_TOP);
+ grid->SetCellValue(3, 10, "<- This numeric cell should be centred");
const wxString choices[] =
{
grid->SetCellAlignment(7, 1, wxALIGN_CENTRE, wxALIGN_CENTRE);
grid->SetCellValue(7, 1, wxT("Big box!"));
- // create a separator-like row: it's grey and it's non-resizeable
+ // create a separator-like row: it's grey and it's non-resizable
grid->DisableRowResize(10);
grid->SetRowSize(10, 30);
attr = new wxGridCellAttr;
GetMenuBar()->Check( ID_TOGGLECOLMOVING, false );
GetMenuBar()->Check( ID_TOGGLEGRIDSIZING, true );
GetMenuBar()->Check( ID_TOGGLEGRIDDRAGCELL, false );
- GetMenuBar()->Check( ID_TOGGLENATIVEHEADER, false );
GetMenuBar()->Check( ID_TOGGLEGRIDLINES, true );
GetMenuBar()->Check( ID_CELLOVERFLOW, true );
}
GetMenuBar()->IsChecked( ID_TOGGLEGRIDDRAGCELL ) );
}
-void GridFrame::ToggleNativeHeader( wxCommandEvent& WXUNUSED(ev) )
+void GridFrame::SetNativeColHeader( wxCommandEvent& WXUNUSED(ev) )
{
- grid->SetUseNativeColLabels(
- GetMenuBar()->IsChecked( ID_TOGGLENATIVEHEADER ) );
+ CustomColumnHeadersProvider* provider =
+ static_cast<CustomColumnHeadersProvider*>(grid->GetTable()->GetAttrProvider());
+ provider->UseCustomColHeaders(false);
+ grid->SetUseNativeColLabels(true);
}
+void GridFrame::SetCustomColHeader( wxCommandEvent& WXUNUSED(ev) )
+{
+ CustomColumnHeadersProvider* provider =
+ static_cast<CustomColumnHeadersProvider*>(grid->GetTable()->GetAttrProvider());
+ provider->UseCustomColHeaders(true);
+ grid->SetUseNativeColLabels(false);
+}
+
+void GridFrame::SetDefaultColHeader( wxCommandEvent& WXUNUSED(ev) )
+{
+ CustomColumnHeadersProvider* provider =
+ static_cast<CustomColumnHeadersProvider*>(grid->GetTable()->GetAttrProvider());
+ provider->UseCustomColHeaders(false);
+ grid->SetUseNativeColLabels(false);
+}
+
+
void GridFrame::ToggleGridLines( wxCommandEvent& WXUNUSED(ev) )
{
grid->EnableGridLines(
void GridFrame::SetLabelFont( wxCommandEvent& WXUNUSED(ev) )
{
wxFont font = wxGetFontFromUser(this);
- if ( font.Ok() )
+ if ( font.IsOk() )
{
grid->SetLabelFont(font);
}
void GridFrame::SetCellFgColour( wxCommandEvent& WXUNUSED(ev) )
{
wxColour col = wxGetColourFromUser(this);
- if ( col.Ok() )
+ if ( col.IsOk() )
{
grid->SetDefaultCellTextColour(col);
grid->Refresh();
void GridFrame::SetCellBgColour( wxCommandEvent& WXUNUSED(ev) )
{
wxColour col = wxGetColourFromUser(this);
- if ( col.Ok() )
+ if ( col.IsOk() )
{
// Check the new Refresh function by passing it a rectangle
// which exactly fits the grid.
}
-void GridFrame::OnShowSelection(wxCommandEvent& WXUNUSED(event))
-{
- // max number of elements to dump -- otherwise it can take too much time
- static const size_t countMax = 100;
-
- bool rows = false;
-
- switch ( grid->GetSelectionMode() )
- {
- case wxGrid::wxGridSelectCells:
- {
- const wxGridCellCoordsArray cells(grid->GetSelectedCells());
- size_t count = cells.size();
- wxLogMessage(wxT("%lu cells selected:"), (unsigned long)count);
- if ( count > countMax )
- {
- wxLogMessage(wxT("[too many selected cells, ")
- wxT("showing only the first %lu]"),
- (unsigned long)countMax);
- count = countMax;
- }
-
- for ( size_t n = 0; n < count; n++ )
- {
- const wxGridCellCoords& c = cells[n];
- wxLogMessage(wxT(" selected cell %lu: (%d, %d)"),
- (unsigned long)n, c.GetCol(), c.GetRow());
- }
- }
- break;
-
- case wxGrid::wxGridSelectRows:
- rows = true;
- // fall through
-
- case wxGrid::wxGridSelectColumns:
- {
- const wxChar *plural, *single;
- if ( rows )
- {
- plural = wxT("rows");
- single = wxT("row");
- }
- else // columns
- {
- plural = wxT("columns");
- single = wxT("column");
- }
-
- const wxArrayInt sels((const wxArrayInt)(rows ? grid->GetSelectedRows()
- : grid->GetSelectedCols()));
- size_t count = sels.size();
- wxLogMessage(wxT("%lu %s selected:"),
- (unsigned long)count, plural);
- if ( count > countMax )
- {
- wxLogMessage(wxT("[too many selected %s, ")
- wxT("showing only the first %lu]"),
- plural, (unsigned long)countMax);
- count = countMax;
- }
-
- for ( size_t n = 0; n < count; n++ )
- {
- wxLogMessage(wxT(" selected %s %lu: %d"),
- single, (unsigned long)n, sels[n]);
- }
- }
- break;
-
- default:
- wxFAIL_MSG( wxT("unknown wxGrid selection mode") );
- break;
- }
-}
-
void GridFrame::OnSelectCell( wxGridEvent& ev )
{
wxString logBuf;
{
new TabularGridFrame;
}
+
+// Example using wxGrid::Render
+// Displays a preset selection or, if it exists, a selection block
+// Draws the selection to a wxBitmap and displays the bitmap
+void GridFrame::OnGridRender( wxCommandEvent& event )
+{
+ int styleRender = 0, i;
+ bool useLometric = false, defSize = false;
+ double zoom = 1;
+ wxSize sizeMargin( 0, 0 );
+ wxPoint pointOrigin( 0, 0 );
+
+ wxMenu* menu = GetMenuBar()->GetMenu( 0 );
+ wxMenuItem* menuItem = menu->FindItem( ID_RENDER_ROW_LABEL );
+ menu = menuItem->GetMenu();
+
+ if ( menu->FindItem( ID_RENDER_ROW_LABEL )->IsChecked() )
+ styleRender |= wxGRID_DRAW_ROWS_HEADER;
+ if ( menu->FindItem( ID_RENDER_COL_LABEL )->IsChecked() )
+ styleRender |= wxGRID_DRAW_COLS_HEADER;
+ if ( menu->FindItem( ID_RENDER_GRID_LINES )->IsChecked() )
+ styleRender |= wxGRID_DRAW_CELL_LINES;
+ if ( menu->FindItem( ID_RENDER_GRID_BORDER )->IsChecked() )
+ styleRender |= wxGRID_DRAW_BOX_RECT;
+ if ( menu->FindItem( ID_RENDER_SELECT_HLIGHT )->IsChecked() )
+ styleRender |= wxGRID_DRAW_SELECTION;
+ if ( menu->FindItem( ID_RENDER_LOMETRIC )->IsChecked() )
+ useLometric = true;
+ if ( menu->FindItem( ID_RENDER_MARGIN )->IsChecked() )
+ {
+ pointOrigin.x += 50;
+ pointOrigin.y += 50;
+ sizeMargin.IncBy( 50 );
+ }
+ if ( menu->FindItem( ID_RENDER_ZOOM )->IsChecked() )
+ zoom = 1.25;
+ if ( menu->FindItem( ID_RENDER_DEFAULT_SIZE )->IsChecked() )
+ defSize = true;
+
+ // init render area coords with a default row and col selection
+ wxGridCellCoords topLeft( 0, 0 ), bottomRight( 8, 6 );
+ // check whether we are printing a block selection
+ // other selection types not catered for here
+ if ( event.GetId() == ID_RENDER_COORDS )
+ {
+ topLeft.SetCol( 6 );
+ topLeft.SetRow( 4 );
+ bottomRight.SetCol( 15 );
+ bottomRight.SetRow( 29 );
+ }
+ else if ( grid->IsSelection() && grid->GetSelectionBlockTopLeft().Count() )
+ {
+ wxGridCellCoordsArray cells = grid->GetSelectionBlockTopLeft();
+ if ( grid->GetSelectionBlockBottomRight().Count() )
+ {
+ cells.Add( grid->GetSelectionBlockBottomRight()[ 0 ] );
+ topLeft.Set( cells[ 0 ].GetRow(),
+ cells[ 0 ].GetCol() );
+ bottomRight.Set( cells[ 1 ].GetRow(),
+ cells[ 1 ].GetCol() );
+ }
+ }
+
+ // sum col widths
+ wxSize sizeRender( 0, 0 );
+ wxGridSizesInfo sizeinfo = grid->GetColSizes();
+ for ( i = topLeft.GetCol(); i <= bottomRight.GetCol(); i++ )
+ {
+ sizeRender.x += sizeinfo.GetSize( i );
+ }
+
+ // sum row heights
+ sizeinfo = grid->GetRowSizes();
+ for ( i = topLeft.GetRow(); i <= bottomRight.GetRow(); i++ )
+ {
+ sizeRender.y += sizeinfo.GetSize( i );
+ }
+
+ if ( styleRender & wxGRID_DRAW_ROWS_HEADER )
+ sizeRender.x += grid->GetRowLabelSize();
+ if ( styleRender & wxGRID_DRAW_COLS_HEADER )
+ sizeRender.y += grid->GetColLabelSize();
+
+ sizeRender.x *= zoom;
+ sizeRender.y *= zoom;
+
+ // delete any existing render frame and create new one
+ wxWindow* win = FindWindow( "frameRender" );
+ if ( win )
+ win->Destroy();
+
+ wxFrame* frame = new wxFrame( this, wxID_ANY, "Grid Render" );
+ frame->SetClientSize( 780, 400 );
+ frame->SetName( "frameRender" );
+
+ wxPanel* canvas = new wxPanel( frame, wxID_ANY );
+
+ // make bitmap large enough for margins if any
+ if ( !defSize )
+ sizeRender.IncBy( sizeMargin * 2 );
+ else
+ sizeRender.IncBy( sizeMargin );
+
+ wxBitmap bmp( sizeRender );
+ // don't leave it larger or drawing will be scaled
+ sizeRender.DecBy( sizeMargin * 2 );
+
+ wxMemoryDC memDc(bmp);
+
+ // default row labels have no background colour so set background
+ memDc.SetBackground( wxBrush( canvas->GetBackgroundColour() ) );
+ memDc.Clear();
+
+ // convert sizeRender to mapping mode units if necessary
+ if ( useLometric )
+ {
+ memDc.SetMapMode( wxMM_LOMETRIC );
+ sizeRender.x = memDc.DeviceToLogicalXRel( sizeRender.x );
+ sizeRender.y = memDc.DeviceToLogicalYRel( sizeRender.y );
+ }
+
+ // pass wxDefaultSize if menu item is checked
+ if ( defSize )
+ sizeRender = wxDefaultSize;
+
+ grid->Render( memDc,
+ pointOrigin,
+ sizeRender,
+ topLeft, bottomRight,
+ wxGridRenderStyle( styleRender ) );
+
+ m_gridBitmap = bmp;
+
+ canvas->Connect( wxEVT_PAINT,
+ wxPaintEventHandler(GridFrame::OnRenderPaint),
+ NULL,
+ this );
+
+ frame->Show();
+}
+
+void GridFrame::OnRenderPaint( wxPaintEvent& event )
+{
+ wxPanel* canvas = ( wxPanel* )event.GetEventObject();
+ wxPaintDC dc( canvas );
+ canvas->PrepareDC( dc );
+
+ if ( !m_gridBitmap.IsOk() )
+ return;;
+
+ wxMemoryDC memDc( m_gridBitmap );
+
+ dc.Blit( 0, 0,
+ m_gridBitmap.GetWidth(),
+ m_gridBitmap.GetHeight(),
+ &memDc, 0, 0 );
+}