]> git.saurik.com Git - wxWidgets.git/blob - samples/newgrid/griddemo.cpp
Committing menubar changes again after CVS trashed them.
[wxWidgets.git] / samples / newgrid / griddemo.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: griddemo.cpp
3 // Purpose: Grid control wxWindows sample
4 // Author: Michael Bedward
5 // Modified by:
6 // RCS-ID: $Id$
7 // Copyright: (c) Michael Bedward, Julian Smart
8 // Licence: wxWindows license
9 /////////////////////////////////////////////////////////////////////////////
10
11 // ============================================================================
12 // declarations
13 // ============================================================================
14
15 // ----------------------------------------------------------------------------
16 // headers
17 // ----------------------------------------------------------------------------
18
19 #ifdef __GNUG__
20 #pragma implementation
21 #pragma interface
22 #endif
23
24 // For compilers that support precompilation, includes "wx/wx.h".
25 #include "wx/wxprec.h"
26
27 #ifdef __BORLANDC__
28 #pragma hdrstop
29 #endif
30
31 #ifndef WX_PRECOMP
32 #include "wx/wx.h"
33 #endif
34
35 #include "wx/colordlg.h"
36
37 #include "wx/grid.h"
38
39 #include "griddemo.h"
40
41 // ----------------------------------------------------------------------------
42 // wxWin macros
43 // ----------------------------------------------------------------------------
44
45 IMPLEMENT_APP( GridApp )
46
47 // ============================================================================
48 // implementation
49 // ============================================================================
50
51 // ----------------------------------------------------------------------------
52 // GridApp
53 // ----------------------------------------------------------------------------
54
55 bool GridApp::OnInit()
56 {
57 GridFrame *frame = new GridFrame;
58 frame->Show( TRUE );
59
60 return TRUE;
61 }
62
63 // ----------------------------------------------------------------------------
64 // GridFrame
65 // ----------------------------------------------------------------------------
66
67 BEGIN_EVENT_TABLE( GridFrame, wxFrame )
68 EVT_MENU( ID_TOGGLEROWLABELS, GridFrame::ToggleRowLabels )
69 EVT_MENU( ID_TOGGLECOLLABELS, GridFrame::ToggleColLabels )
70 EVT_MENU( ID_TOGGLEEDIT, GridFrame::ToggleEditing )
71 EVT_MENU( ID_TOGGLEROWSIZING, GridFrame::ToggleRowSizing )
72 EVT_MENU( ID_TOGGLECOLSIZING, GridFrame::ToggleColSizing )
73 EVT_MENU( ID_TOGGLEGRIDSIZING, GridFrame::ToggleGridSizing )
74 EVT_MENU( ID_SETLABELCOLOUR, GridFrame::SetLabelColour )
75 EVT_MENU( ID_SETLABELTEXTCOLOUR, GridFrame::SetLabelTextColour )
76 EVT_MENU( ID_ROWLABELHORIZALIGN, GridFrame::SetRowLabelHorizAlignment )
77 EVT_MENU( ID_ROWLABELVERTALIGN, GridFrame::SetRowLabelVertAlignment )
78 EVT_MENU( ID_COLLABELHORIZALIGN, GridFrame::SetColLabelHorizAlignment )
79 EVT_MENU( ID_COLLABELVERTALIGN, GridFrame::SetColLabelVertAlignment )
80 EVT_MENU( ID_GRIDLINECOLOUR, GridFrame::SetGridLineColour )
81 EVT_MENU( ID_INSERTROW, GridFrame::InsertRow )
82 EVT_MENU( ID_INSERTCOL, GridFrame::InsertCol )
83 EVT_MENU( ID_DELETEROW, GridFrame::DeleteSelectedRows )
84 EVT_MENU( ID_DELETECOL, GridFrame::DeleteSelectedCols )
85 EVT_MENU( ID_CLEARGRID, GridFrame::ClearGrid )
86 EVT_MENU( ID_SELCELLS, GridFrame::SelectCells )
87 EVT_MENU( ID_SELROWS, GridFrame::SelectRows )
88 EVT_MENU( ID_SELCOLS, GridFrame::SelectCols )
89
90 EVT_MENU( ID_SET_CELL_FG_COLOUR, GridFrame::SetCellFgColour )
91 EVT_MENU( ID_SET_CELL_BG_COLOUR, GridFrame::SetCellBgColour )
92
93 EVT_MENU( ID_ABOUT, GridFrame::About )
94 EVT_MENU( wxID_EXIT, GridFrame::OnQuit )
95 EVT_MENU( ID_VTABLE, GridFrame::OnVTable)
96 EVT_MENU( ID_BUGS_TABLE, GridFrame::OnBugsTable)
97
98 EVT_GRID_LABEL_LEFT_CLICK( GridFrame::OnLabelLeftClick )
99 EVT_GRID_CELL_LEFT_CLICK( GridFrame::OnCellLeftClick )
100 EVT_GRID_ROW_SIZE( GridFrame::OnRowSize )
101 EVT_GRID_COL_SIZE( GridFrame::OnColSize )
102 EVT_GRID_SELECT_CELL( GridFrame::OnSelectCell )
103 EVT_GRID_RANGE_SELECT( GridFrame::OnRangeSelected )
104 EVT_GRID_CELL_CHANGE( GridFrame::OnCellValueChanged )
105
106 EVT_GRID_EDITOR_SHOWN( GridFrame::OnEditorShown )
107 EVT_GRID_EDITOR_HIDDEN( GridFrame::OnEditorHidden )
108 END_EVENT_TABLE()
109
110
111 GridFrame::GridFrame()
112 : wxFrame( (wxFrame *)NULL, -1, "wxWindows grid class demo",
113 wxDefaultPosition,
114 wxDefaultSize )
115 {
116 int gridW = 600, gridH = 300;
117 int logW = gridW, logH = 100;
118
119 wxMenu *fileMenu = new wxMenu;
120 fileMenu->Append( ID_VTABLE, "&Virtual table test\tCtrl-V");
121 fileMenu->Append( ID_BUGS_TABLE, "&Bugs table test\tCtrl-B");
122 fileMenu->AppendSeparator();
123 fileMenu->Append( wxID_EXIT, "E&xit\tAlt-X" );
124
125 wxMenu *viewMenu = new wxMenu;
126 viewMenu->Append( ID_TOGGLEROWLABELS, "&Row labels", "", TRUE );
127 viewMenu->Append( ID_TOGGLECOLLABELS, "&Col labels", "", TRUE );
128 viewMenu->Append( ID_TOGGLEEDIT, "&Editable", "", TRUE );
129 viewMenu->Append( ID_TOGGLEROWSIZING, "Ro&w drag-resize", "", TRUE );
130 viewMenu->Append( ID_TOGGLECOLSIZING, "C&ol drag-resize", "", TRUE );
131 viewMenu->Append( ID_TOGGLEGRIDSIZING, "&Grid drag-resize", "", TRUE );
132
133 wxMenu *rowLabelMenu = new wxMenu;
134
135 viewMenu->Append( ID_ROWLABELALIGN, "R&ow label alignment",
136 rowLabelMenu,
137 "Change alignment of row labels" );
138
139 rowLabelMenu->Append( ID_ROWLABELHORIZALIGN, "&Horizontal" );
140 rowLabelMenu->Append( ID_ROWLABELVERTALIGN, "&Vertical" );
141
142 wxMenu *colLabelMenu = new wxMenu;
143
144 viewMenu->Append( ID_COLLABELALIGN, "Col l&abel alignment",
145 colLabelMenu,
146 "Change alignment of col labels" );
147
148 colLabelMenu->Append( ID_COLLABELHORIZALIGN, "&Horizontal" );
149 colLabelMenu->Append( ID_COLLABELVERTALIGN, "&Vertical" );
150
151 wxMenu *colMenu = new wxMenu;
152 colMenu->Append( ID_SETLABELCOLOUR, "Set &label colour" );
153 colMenu->Append( ID_SETLABELTEXTCOLOUR, "Set label &text colour" );
154 colMenu->Append( ID_GRIDLINECOLOUR, "&Grid line colour" );
155 colMenu->Append( ID_SET_CELL_FG_COLOUR, "Set cell &foreground colour" );
156 colMenu->Append( ID_SET_CELL_BG_COLOUR, "Set cell &background colour" );
157
158 wxMenu *editMenu = new wxMenu;
159 editMenu->Append( ID_INSERTROW, "Insert &row" );
160 editMenu->Append( ID_INSERTCOL, "Insert &column" );
161 editMenu->Append( ID_DELETEROW, "Delete selected ro&ws" );
162 editMenu->Append( ID_DELETECOL, "Delete selected co&ls" );
163 editMenu->Append( ID_CLEARGRID, "Cl&ear grid cell contents" );
164
165 wxMenu *selectionMenu = new wxMenu;
166
167 editMenu->Append( ID_CHANGESEL, "Change &selection mode",
168 selectionMenu,
169 "Change selection mode" );
170
171 selectionMenu->Append( ID_SELCELLS, "Select &Cells" );
172 selectionMenu->Append( ID_SELROWS, "Select &Rows" );
173 selectionMenu->Append( ID_SELCOLS, "Select C&ols" );
174
175 wxMenu *helpMenu = new wxMenu;
176 helpMenu->Append( ID_ABOUT, "&About wxGrid demo" );
177
178 wxMenuBar *menuBar = new wxMenuBar;
179 menuBar->Append( fileMenu, "&File" );
180 menuBar->Append( viewMenu, "&View" );
181 menuBar->Append( colMenu, "&Colours" );
182 menuBar->Append( editMenu, "&Edit" );
183 menuBar->Append( helpMenu, "&Help" );
184
185 SetMenuBar( menuBar );
186
187 grid = new wxGrid( this,
188 -1,
189 wxPoint( 0, 0 ),
190 wxSize( 400, 300 ) );
191
192 logWin = new wxTextCtrl( this,
193 -1,
194 wxEmptyString,
195 wxPoint( 0, gridH + 20 ),
196 wxSize( logW, logH ),
197 wxTE_MULTILINE );
198
199 logger = new wxLogTextCtrl( logWin );
200 m_logOld = logger->SetActiveTarget( logger );
201 logger->SetTimestamp( NULL );
202
203 // this will create a grid and, by default, an associated grid
204 // table for strings
205 grid->CreateGrid( 100, 100 );
206
207 grid->SetRowSize( 0, 60 );
208 grid->SetCellValue( 0, 0, "Ctrl+Home\nwill go to\nthis cell" );
209
210 grid->SetCellValue( 0, 1, "Blah" );
211 grid->SetCellValue( 0, 2, "Blah" );
212 grid->SetCellValue( 0, 3, "Read only" );
213 grid->SetReadOnly( 0, 3 );
214
215 grid->SetCellValue( 0, 5, "Press\nCtrl+arrow\nto skip over\ncells" );
216
217 grid->SetRowSize( 99, 60 );
218 grid->SetCellValue( 99, 99, "Ctrl+End\nwill go to\nthis cell" );
219
220 grid->SetCellValue(2, 2, "red");
221
222 grid->SetCellTextColour(2, 2, *wxRED);
223 grid->SetCellValue(3, 3, "green on grey");
224 grid->SetCellTextColour(3, 3, *wxGREEN);
225 grid->SetCellBackgroundColour(3, 3, *wxLIGHT_GREY);
226
227 grid->SetCellValue(4, 4, "a weird looking cell");
228 grid->SetCellAlignment(4, 4, wxCENTRE, wxCENTRE);
229 grid->SetCellRenderer(4, 4, new MyGridCellRenderer);
230
231 grid->SetCellValue(3, 0, "1");
232 grid->SetCellRenderer(3, 0, new wxGridCellBoolRenderer);
233 grid->SetCellEditor(3, 0, new wxGridCellBoolEditor);
234
235 wxGridCellAttr *attr;
236 attr = new wxGridCellAttr;
237 attr->SetTextColour(*wxBLUE);
238 grid->SetColAttr(5, attr);
239 attr = new wxGridCellAttr;
240 attr->SetBackgroundColour(*wxBLUE);
241 grid->SetRowAttr(5, attr);
242
243 grid->SetCellValue(2, 4, "a wider column");
244 grid->SetColSize(4, 120);
245 grid->SetColMinimalWidth(4, 120);
246
247 grid->SetColFormatFloat(5);
248 grid->SetCellValue(0, 5, "3.1415");
249 grid->SetCellValue(1, 5, "1415");
250 grid->SetCellValue(2, 5, "12345.67890");
251
252 grid->SetColFormatFloat(6, 6, 2);
253 grid->SetCellValue(0, 6, "3.1415");
254 grid->SetCellValue(1, 6, "1415");
255 grid->SetCellValue(2, 6, "12345.67890");
256
257 wxBoxSizer *topSizer = new wxBoxSizer( wxVERTICAL );
258 topSizer->Add( grid,
259 1,
260 wxEXPAND );
261
262 topSizer->Add( logWin,
263 0,
264 wxEXPAND );
265
266 SetAutoLayout( TRUE );
267 SetSizer( topSizer );
268
269 topSizer->Fit( this );
270 topSizer->SetSizeHints( this );
271
272 Centre();
273 SetDefaults();
274 }
275
276
277 GridFrame::~GridFrame()
278 {
279 delete wxLog::SetActiveTarget(m_logOld);
280 }
281
282
283 void GridFrame::SetDefaults()
284 {
285 GetMenuBar()->Check( ID_TOGGLEROWLABELS, TRUE );
286 GetMenuBar()->Check( ID_TOGGLECOLLABELS, TRUE );
287 GetMenuBar()->Check( ID_TOGGLEEDIT, TRUE );
288 GetMenuBar()->Check( ID_TOGGLEROWSIZING, TRUE );
289 GetMenuBar()->Check( ID_TOGGLECOLSIZING, TRUE );
290 GetMenuBar()->Check( ID_TOGGLEGRIDSIZING, TRUE );
291 }
292
293
294 void GridFrame::ToggleRowLabels( wxCommandEvent& WXUNUSED(ev) )
295 {
296 if ( GetMenuBar()->IsChecked( ID_TOGGLEROWLABELS ) )
297 {
298 grid->SetRowLabelSize( grid->GetDefaultRowLabelSize() );
299 }
300 else
301 {
302 grid->SetRowLabelSize( 0 );
303 }
304 }
305
306
307 void GridFrame::ToggleColLabels( wxCommandEvent& WXUNUSED(ev) )
308 {
309 if ( GetMenuBar()->IsChecked( ID_TOGGLECOLLABELS ) )
310 {
311 grid->SetColLabelSize( grid->GetDefaultColLabelSize() );
312 }
313 else
314 {
315 grid->SetColLabelSize( 0 );
316 }
317 }
318
319
320 void GridFrame::ToggleEditing( wxCommandEvent& WXUNUSED(ev) )
321 {
322 grid->EnableEditing(
323 GetMenuBar()->IsChecked( ID_TOGGLEEDIT ) );
324 }
325
326
327 void GridFrame::ToggleRowSizing( wxCommandEvent& WXUNUSED(ev) )
328 {
329 grid->EnableDragRowSize(
330 GetMenuBar()->IsChecked( ID_TOGGLEROWSIZING ) );
331 }
332
333
334 void GridFrame::ToggleColSizing( wxCommandEvent& WXUNUSED(ev) )
335 {
336 grid->EnableDragColSize(
337 GetMenuBar()->IsChecked( ID_TOGGLECOLSIZING ) );
338 }
339
340 void GridFrame::ToggleGridSizing( wxCommandEvent& WXUNUSED(ev) )
341 {
342 grid->EnableDragGridSize(
343 GetMenuBar()->IsChecked( ID_TOGGLEGRIDSIZING ) );
344 }
345
346
347 void GridFrame::SetLabelColour( wxCommandEvent& WXUNUSED(ev) )
348 {
349 wxColourDialog dlg( NULL );
350 if ( dlg.ShowModal() == wxID_OK )
351 {
352 wxColourData retData;
353 retData = dlg.GetColourData();
354 wxColour colour = retData.GetColour();
355
356 grid->SetLabelBackgroundColour( colour );
357 }
358 }
359
360
361 void GridFrame::SetLabelTextColour( wxCommandEvent& WXUNUSED(ev) )
362 {
363 wxColourDialog dlg( NULL );
364 if ( dlg.ShowModal() == wxID_OK )
365 {
366 wxColourData retData;
367 retData = dlg.GetColourData();
368 wxColour colour = retData.GetColour();
369
370 grid->SetLabelTextColour( colour );
371 }
372 }
373
374
375 void GridFrame::SetRowLabelHorizAlignment( wxCommandEvent& WXUNUSED(ev) )
376 {
377 int horiz, vert;
378 grid->GetRowLabelAlignment( &horiz, &vert );
379
380 switch ( horiz )
381 {
382 case wxLEFT:
383 horiz = wxCENTRE;
384 break;
385
386 case wxCENTRE:
387 horiz = wxRIGHT;
388 break;
389
390 case wxRIGHT:
391 horiz = wxLEFT;
392 break;
393 }
394
395 grid->SetRowLabelAlignment( horiz, -1 );
396 }
397
398 void GridFrame::SetRowLabelVertAlignment( wxCommandEvent& WXUNUSED(ev) )
399 {
400 int horiz, vert;
401 grid->GetRowLabelAlignment( &horiz, &vert );
402
403 switch ( vert )
404 {
405 case wxTOP:
406 vert = wxCENTRE;
407 break;
408
409 case wxCENTRE:
410 vert = wxBOTTOM;
411 break;
412
413 case wxBOTTOM:
414 vert = wxTOP;
415 break;
416 }
417
418 grid->SetRowLabelAlignment( -1, vert );
419 }
420
421
422 void GridFrame::SetColLabelHorizAlignment( wxCommandEvent& WXUNUSED(ev) )
423 {
424 int horiz, vert;
425 grid->GetColLabelAlignment( &horiz, &vert );
426
427 switch ( horiz )
428 {
429 case wxLEFT:
430 horiz = wxCENTRE;
431 break;
432
433 case wxCENTRE:
434 horiz = wxRIGHT;
435 break;
436
437 case wxRIGHT:
438 horiz = wxLEFT;
439 break;
440 }
441
442 grid->SetColLabelAlignment( horiz, -1 );
443 }
444
445
446 void GridFrame::SetColLabelVertAlignment( wxCommandEvent& WXUNUSED(ev) )
447 {
448 int horiz, vert;
449 grid->GetColLabelAlignment( &horiz, &vert );
450
451 switch ( vert )
452 {
453 case wxTOP:
454 vert = wxCENTRE;
455 break;
456
457 case wxCENTRE:
458 vert = wxBOTTOM;
459 break;
460
461 case wxBOTTOM:
462 vert = wxTOP;
463 break;
464 }
465
466 grid->SetColLabelAlignment( -1, vert );
467 }
468
469
470 void GridFrame::SetGridLineColour( wxCommandEvent& WXUNUSED(ev) )
471 {
472 wxColourDialog dlg( NULL );
473 if ( dlg.ShowModal() == wxID_OK )
474 {
475 wxColourData retData;
476 retData = dlg.GetColourData();
477 wxColour colour = retData.GetColour();
478
479 grid->SetGridLineColour( colour );
480 }
481 }
482
483
484 void GridFrame::InsertRow( wxCommandEvent& WXUNUSED(ev) )
485 {
486 grid->InsertRows( grid->GetGridCursorRow(), 1 );
487 }
488
489
490 void GridFrame::InsertCol( wxCommandEvent& WXUNUSED(ev) )
491 {
492 grid->InsertCols( grid->GetGridCursorCol(), 1 );
493 }
494
495
496 void GridFrame::DeleteSelectedRows( wxCommandEvent& WXUNUSED(ev) )
497 {
498 if ( grid->IsSelection() )
499 {
500 for ( int n = 0; n < grid->GetNumberRows(); n++ )
501 if ( grid->IsInSelection( n , 0 ) )
502 grid->DeleteRows( n, 1 );
503 }
504 }
505
506
507 void GridFrame::DeleteSelectedCols( wxCommandEvent& WXUNUSED(ev) )
508 {
509 if ( grid->IsSelection() )
510 {
511 for ( int n = 0; n < grid->GetNumberCols(); n++ )
512 if ( grid->IsInSelection( 0 , n ) )
513 grid->DeleteCols( n, 1 );
514 }
515 }
516
517
518 void GridFrame::ClearGrid( wxCommandEvent& WXUNUSED(ev) )
519 {
520 grid->ClearGrid();
521 }
522
523 void GridFrame::SelectCells( wxCommandEvent& WXUNUSED(ev) )
524 {
525 grid->SetSelectionMode( wxGrid::wxGridSelectCells );
526 }
527
528 void GridFrame::SelectRows( wxCommandEvent& WXUNUSED(ev) )
529 {
530 grid->SetSelectionMode( wxGrid::wxGridSelectRows );
531 }
532
533 void GridFrame::SelectCols( wxCommandEvent& WXUNUSED(ev) )
534 {
535 grid->SetSelectionMode( wxGrid::wxGridSelectColumns );
536 }
537
538 void GridFrame::SetCellFgColour( wxCommandEvent& WXUNUSED(ev) )
539 {
540 wxColour col = wxGetColourFromUser(this);
541 if ( col.Ok() )
542 {
543 grid->SetDefaultCellTextColour(col);
544 grid->Refresh();
545 }
546 }
547
548 void GridFrame::SetCellBgColour( wxCommandEvent& WXUNUSED(ev) )
549 {
550 wxColour col = wxGetColourFromUser(this);
551 if ( col.Ok() )
552 {
553 grid->SetDefaultCellBackgroundColour(col);
554 grid->Refresh();
555 }
556 }
557
558 void GridFrame::OnLabelLeftClick( wxGridEvent& ev )
559 {
560 logBuf = "";
561 if ( ev.GetRow() != -1 )
562 {
563 logBuf << "Left click on row label " << ev.GetRow();
564 }
565 else if ( ev.GetCol() != -1 )
566 {
567 logBuf << "Left click on col label " << ev.GetCol();
568 }
569 else
570 {
571 logBuf << "Left click on corner label";
572 }
573
574 if ( ev.ShiftDown() ) logBuf << " (shift down)";
575 if ( ev.ControlDown() ) logBuf << " (control down)";
576 wxLogMessage( "%s", logBuf.c_str() );
577
578 // you must call event skip if you want default grid processing
579 //
580 ev.Skip();
581 }
582
583
584 void GridFrame::OnCellLeftClick( wxGridEvent& ev )
585 {
586 logBuf = "";
587 logBuf << "Left click at row " << ev.GetRow()
588 << " col " << ev.GetCol();
589 wxLogMessage( "%s", logBuf.c_str() );
590
591 // you must call event skip if you want default grid processing
592 // (cell highlighting etc.)
593 //
594 ev.Skip();
595 }
596
597
598 void GridFrame::OnRowSize( wxGridSizeEvent& ev )
599 {
600 logBuf = "";
601 logBuf << "Resized row " << ev.GetRowOrCol();
602 wxLogMessage( "%s", logBuf.c_str() );
603
604 ev.Skip();
605 }
606
607
608 void GridFrame::OnColSize( wxGridSizeEvent& ev )
609 {
610 logBuf = "";
611 logBuf << "Resized col " << ev.GetRowOrCol();
612 wxLogMessage( "%s", logBuf.c_str() );
613
614 ev.Skip();
615 }
616
617
618 void GridFrame::OnSelectCell( wxGridEvent& ev )
619 {
620 logBuf = "";
621 if ( ev.Selecting() )
622 logBuf << "Selected ";
623 else
624 logBuf << "Deselected ";
625 logBuf << "cell at row " << ev.GetRow()
626 << " col " << ev.GetCol()
627 << " ( ControlDown: "<< (ev.ControlDown() ? 'T':'F')
628 << ", ShiftDown: "<< (ev.ShiftDown() ? 'T':'F')
629 << ", AltDown: "<< (ev.AltDown() ? 'T':'F')
630 << ", MetaDown: "<< (ev.MetaDown() ? 'T':'F') << " )";
631 wxLogMessage( "%s", logBuf.c_str() );
632
633 // you must call Skip() if you want the default processing
634 // to occur in wxGrid
635 ev.Skip();
636 }
637
638 void GridFrame::OnRangeSelected( wxGridRangeSelectEvent& ev )
639 {
640 logBuf = "";
641 if ( ev.Selecting() )
642 logBuf << "Selected ";
643 else
644 logBuf << "Deselected ";
645 logBuf << "cells from row " << ev.GetTopRow()
646 << " col " << ev.GetLeftCol()
647 << " to row " << ev.GetBottomRow()
648 << " col " << ev.GetRightCol()
649 << " ( ControlDown: "<< (ev.ControlDown() ? 'T':'F')
650 << ", ShiftDown: "<< (ev.ShiftDown() ? 'T':'F')
651 << ", AltDown: "<< (ev.AltDown() ? 'T':'F')
652 << ", MetaDown: "<< (ev.MetaDown() ? 'T':'F') << " )";
653 wxLogMessage( "%s", logBuf.c_str() );
654
655 ev.Skip();
656 }
657
658 void GridFrame::OnCellValueChanged( wxGridEvent& ev )
659 {
660 logBuf = "";
661 logBuf << "Value changed for cell at"
662 << " row " << ev.GetRow()
663 << " col " << ev.GetCol();
664
665 wxLogMessage( "%s", logBuf.c_str() );
666
667 ev.Skip();
668 }
669
670 void GridFrame::OnEditorShown( wxGridEvent& ev )
671 {
672 wxLogMessage( "Cell editor shown." );
673
674 ev.Skip();
675 }
676
677 void GridFrame::OnEditorHidden( wxGridEvent& ev )
678 {
679 wxLogMessage( "Cell editor hidden." );
680
681 ev.Skip();
682 }
683
684 void GridFrame::About( wxCommandEvent& WXUNUSED(ev) )
685 {
686 (void)wxMessageBox( "\n\nwxGrid demo \n\n"
687 "Michael Bedward \n"
688 "mbedward@ozemail.com.au \n\n",
689 "About",
690 wxOK );
691 }
692
693
694 void GridFrame::OnQuit( wxCommandEvent& WXUNUSED(ev) )
695 {
696 Close( TRUE );
697 }
698
699 void GridFrame::OnBugsTable(wxCommandEvent& )
700 {
701 BugsGridFrame *frame = new BugsGridFrame;
702 frame->Show(TRUE);
703 }
704
705 void GridFrame::OnVTable(wxCommandEvent& )
706 {
707 static long s_sizeGrid = 10000;
708
709 #ifdef __WXMOTIF__
710 // MB: wxGetNumberFromUser doesn't work properly for wxMotif
711 wxString s;
712 s << s_sizeGrid;
713 s = wxGetTextFromUser( "Size of the table to create",
714 "Size:",
715 s );
716
717 s.ToLong( &s_sizeGrid );
718
719 #else
720 s_sizeGrid = wxGetNumberFromUser("Size of the table to create",
721 "Size: ",
722 "wxGridDemo question",
723 s_sizeGrid,
724 0, 32000, this);
725 #endif
726
727 if ( s_sizeGrid != -1 )
728 {
729 BigGridFrame* win = new BigGridFrame(s_sizeGrid);
730 win->Show(TRUE);
731 }
732 }
733
734 // ----------------------------------------------------------------------------
735 // MyGridCellRenderer
736 // ----------------------------------------------------------------------------
737
738 // do something that the default renderer doesn't here just to show that it is
739 // possible to alter the appearance of the cell beyond what the attributes
740 // allow
741 void MyGridCellRenderer::Draw(wxGrid& grid,
742 wxGridCellAttr& attr,
743 wxDC& dc,
744 const wxRect& rect,
745 int row, int col,
746 bool isSelected)
747 {
748 wxGridCellStringRenderer::Draw(grid, attr, dc, rect, row, col, isSelected);
749
750 dc.SetPen(*wxGREEN_PEN);
751 dc.SetBrush(*wxTRANSPARENT_BRUSH);
752 dc.DrawEllipse(rect);
753 }
754
755 // ----------------------------------------------------------------------------
756 // MyGridCellAttrProvider
757 // ----------------------------------------------------------------------------
758
759 MyGridCellAttrProvider::MyGridCellAttrProvider()
760 {
761 m_attrForOddRows = new wxGridCellAttr;
762 m_attrForOddRows->SetBackgroundColour(*wxLIGHT_GREY);
763 }
764
765 MyGridCellAttrProvider::~MyGridCellAttrProvider()
766 {
767 m_attrForOddRows->DecRef();
768 }
769
770 wxGridCellAttr *MyGridCellAttrProvider::GetAttr(int row, int col) const
771 {
772 wxGridCellAttr *attr = wxGridCellAttrProvider::GetAttr(row, col);
773
774 if ( row % 2 )
775 {
776 if ( !attr )
777 {
778 attr = m_attrForOddRows;
779 attr->IncRef();
780 }
781 else
782 {
783 if ( !attr->HasBackgroundColour() )
784 {
785 wxGridCellAttr *attrNew = attr->Clone();
786 attr->DecRef();
787 attr = attrNew;
788 attr->SetBackgroundColour(*wxLIGHT_GREY);
789 }
790 }
791 }
792
793 return attr;
794 }
795
796 // ============================================================================
797 // BigGridFrame and BigGridTable: Sample of a non-standard table
798 // ============================================================================
799
800 BigGridFrame::BigGridFrame(long sizeGrid)
801 : wxFrame(NULL, -1, "Plugin Virtual Table",
802 wxDefaultPosition, wxSize(500, 450))
803 {
804 m_grid = new wxGrid(this, -1, wxDefaultPosition, wxDefaultSize);
805 m_table = new BigGridTable(sizeGrid);
806
807 // VZ: I don't understand why this slows down the display that much,
808 // must profile it...
809 //m_table->SetAttrProvider(new MyGridCellAttrProvider);
810
811 m_grid->SetTable(m_table, TRUE);
812
813 #if defined __WXMOTIF__
814 // MB: the grid isn't getting a sensible default size under wxMotif
815 int cw, ch;
816 GetClientSize( &cw, &ch );
817 m_grid->SetSize( cw, ch );
818 #endif
819 }
820
821 // ============================================================================
822 // BugsGridFrame: a "realistic" table
823 // ============================================================================
824
825 // ----------------------------------------------------------------------------
826 // bugs table data
827 // ----------------------------------------------------------------------------
828
829 enum Columns
830 {
831 Col_Id,
832 Col_Summary,
833 Col_Severity,
834 Col_Priority,
835 Col_Platform,
836 Col_Opened,
837 Col_Max
838 };
839
840 enum Severity
841 {
842 Sev_Wish,
843 Sev_Minor,
844 Sev_Normal,
845 Sev_Major,
846 Sev_Critical,
847 Sev_Max
848 };
849
850 static const wxChar* severities[] =
851 {
852 _T("wishlist"),
853 _T("minor"),
854 _T("normal"),
855 _T("major"),
856 _T("critical"),
857 };
858
859 static struct BugsGridData
860 {
861 int id;
862 wxChar summary[80];
863 Severity severity;
864 int prio;
865 wxChar platform[12];
866 bool opened;
867 } gs_dataBugsGrid [] =
868 {
869 { 18, _T("foo doesn't work"), Sev_Major, 1, _T("wxMSW"), TRUE },
870 { 27, _T("bar crashes"), Sev_Critical, 1, _T("all"), FALSE },
871 { 45, _T("printing is slow"), Sev_Minor, 3, _T("wxMSW"), TRUE },
872 { 68, _T("Rectangle() fails"), Sev_Normal, 1, _T("wxMSW"), FALSE },
873 };
874
875 static const wxChar *headers[Col_Max] =
876 {
877 _T("Id"),
878 _T("Summary"),
879 _T("Severity"),
880 _T("Priority"),
881 _T("Platform"),
882 _T("Opened?"),
883 };
884
885 // ----------------------------------------------------------------------------
886 // BugsGridTable
887 // ----------------------------------------------------------------------------
888
889 wxString BugsGridTable::GetTypeName(int WXUNUSED(row), int col)
890 {
891 switch ( col )
892 {
893 case Col_Id:
894 case Col_Priority:
895 return wxGRID_VALUE_NUMBER;;
896
897 case Col_Severity:
898 // fall thorugh (TODO should be a list)
899
900 case Col_Summary:
901 return wxString::Format(_T("%s:80"), wxGRID_VALUE_STRING);
902
903 case Col_Platform:
904 return wxString::Format(_T("%s:all,MSW,GTK,other"), wxGRID_VALUE_CHOICE);
905
906 case Col_Opened:
907 return wxGRID_VALUE_BOOL;
908 }
909
910 wxFAIL_MSG(_T("unknown column"));
911
912 return wxEmptyString;
913 }
914
915 int BugsGridTable::GetNumberRows()
916 {
917 return WXSIZEOF(gs_dataBugsGrid);
918 }
919
920 int BugsGridTable::GetNumberCols()
921 {
922 return Col_Max;
923 }
924
925 bool BugsGridTable::IsEmptyCell( int row, int col )
926 {
927 return FALSE;
928 }
929
930 wxString BugsGridTable::GetValue( int row, int col )
931 {
932 const BugsGridData& gd = gs_dataBugsGrid[row];
933
934 switch ( col )
935 {
936 case Col_Id:
937 case Col_Priority:
938 case Col_Opened:
939 wxFAIL_MSG(_T("unexpected column"));
940 break;
941
942 case Col_Severity:
943 return severities[gd.severity];
944
945 case Col_Summary:
946 return gd.summary;
947
948 case Col_Platform:
949 return gd.platform;
950 }
951
952 return wxEmptyString;
953 }
954
955 void BugsGridTable::SetValue( int row, int col, const wxString& value )
956 {
957 BugsGridData& gd = gs_dataBugsGrid[row];
958
959 switch ( col )
960 {
961 case Col_Id:
962 case Col_Priority:
963 case Col_Opened:
964 wxFAIL_MSG(_T("unexpected column"));
965 break;
966
967 case Col_Severity:
968 {
969 size_t n;
970 for ( n = 0; n < WXSIZEOF(severities); n++ )
971 {
972 if ( severities[n] == value )
973 {
974 gd.severity = (Severity)n;
975 break;
976 }
977 }
978
979 if ( n == WXSIZEOF(severities) )
980 {
981 wxLogWarning(_T("Invalid severity value '%s'."),
982 value.c_str());
983 gd.severity = Sev_Normal;
984 }
985 }
986 break;
987
988 case Col_Summary:
989 wxStrncpy(gd.summary, value, WXSIZEOF(gd.summary));
990 break;
991
992 case Col_Platform:
993 wxStrncpy(gd.platform, value, WXSIZEOF(gd.platform));
994 break;
995 }
996 }
997
998 bool BugsGridTable::CanGetValueAs( int WXUNUSED(row), int col, const wxString& typeName )
999 {
1000 if ( typeName == wxGRID_VALUE_STRING )
1001 {
1002 return TRUE;
1003 }
1004 else if ( typeName == wxGRID_VALUE_BOOL )
1005 {
1006 return col == Col_Opened;
1007 }
1008 else if ( typeName == wxGRID_VALUE_NUMBER )
1009 {
1010 return col == Col_Id || col == Col_Priority || col == Col_Severity;
1011 }
1012 else
1013 {
1014 return FALSE;
1015 }
1016 }
1017
1018 bool BugsGridTable::CanSetValueAs( int row, int col, const wxString& typeName )
1019 {
1020 return CanGetValueAs(row, col, typeName);
1021 }
1022
1023 long BugsGridTable::GetValueAsLong( int row, int col )
1024 {
1025 const BugsGridData& gd = gs_dataBugsGrid[row];
1026
1027 switch ( col )
1028 {
1029 case Col_Id:
1030 return gd.id;
1031
1032 case Col_Priority:
1033 return gd.prio;
1034
1035 case Col_Severity:
1036 return gd.severity;
1037
1038 default:
1039 wxFAIL_MSG(_T("unexpected column"));
1040 return -1;
1041 }
1042 }
1043
1044 bool BugsGridTable::GetValueAsBool( int row, int col )
1045 {
1046 if ( col == Col_Opened )
1047 {
1048 return gs_dataBugsGrid[row].opened;
1049 }
1050 else
1051 {
1052 wxFAIL_MSG(_T("unexpected column"));
1053
1054 return FALSE;
1055 }
1056 }
1057
1058 void BugsGridTable::SetValueAsLong( int row, int col, long value )
1059 {
1060 BugsGridData& gd = gs_dataBugsGrid[row];
1061
1062 switch ( col )
1063 {
1064 case Col_Priority:
1065 gd.prio = value;
1066 break;
1067
1068 default:
1069 wxFAIL_MSG(_T("unexpected column"));
1070 }
1071 }
1072
1073 void BugsGridTable::SetValueAsBool( int row, int col, bool value )
1074 {
1075 if ( col == Col_Opened )
1076 {
1077 gs_dataBugsGrid[row].opened = value;
1078 }
1079 else
1080 {
1081 wxFAIL_MSG(_T("unexpected column"));
1082 }
1083 }
1084
1085 wxString BugsGridTable::GetColLabelValue( int col )
1086 {
1087 return headers[col];
1088 }
1089
1090 BugsGridTable::BugsGridTable()
1091 {
1092 }
1093
1094 // ----------------------------------------------------------------------------
1095 // BugsGridFrame
1096 // ----------------------------------------------------------------------------
1097
1098 BugsGridFrame::BugsGridFrame()
1099 : wxFrame(NULL, -1, "Bugs table",
1100 wxDefaultPosition, wxSize(500, 300))
1101 {
1102 wxGrid *grid = new wxGrid(this, -1, wxDefaultPosition);
1103 wxGridTableBase *table = new BugsGridTable();
1104 table->SetAttrProvider(new MyGridCellAttrProvider);
1105 grid->SetTable(table, TRUE);
1106
1107 wxGridCellAttr *attrRO = new wxGridCellAttr,
1108 *attrRangeEditor = new wxGridCellAttr,
1109 *attrCombo = new wxGridCellAttr;
1110
1111 attrRO->SetReadOnly();
1112 attrRangeEditor->SetEditor(new wxGridCellNumberEditor(1, 5));
1113 attrCombo->SetEditor(new wxGridCellChoiceEditor(WXSIZEOF(severities),
1114 severities));
1115
1116 grid->SetColAttr(Col_Id, attrRO);
1117 grid->SetColAttr(Col_Priority, attrRangeEditor);
1118 grid->SetColAttr(Col_Severity, attrCombo);
1119
1120 grid->SetMargins(0, 0);
1121
1122 grid->Fit();
1123 wxSize size = grid->GetSize();
1124 size.x += 10;
1125 size.y += 10;
1126 SetClientSize(size);
1127 }