Use symbolic constants for list model columns in dataview sample.
[wxWidgets.git] / samples / dataview / dataview.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: dataview.cpp
3 // Purpose: wxDataViewCtrl wxWidgets sample
4 // Author: Robert Roebling
5 // Modified by: Francesco Montorsi, Bo Yang
6 // Created: 06/01/06
7 // RCS-ID: $Id$
8 // Copyright: (c) Robert Roebling
9 // Licence: wxWindows license
10 /////////////////////////////////////////////////////////////////////////////
11
12 // ============================================================================
13 // declarations
14 // ============================================================================
15
16 // For compilers that support precompilation, includes "wx/wx.h".
17 #include "wx/wxprec.h"
18
19 #ifdef __BORLANDC__
20 #pragma hdrstop
21 #endif
22
23 #ifndef WX_PRECOMP
24 #include "wx/wx.h"
25 #endif
26
27 #include "wx/dataview.h"
28 #include "wx/datetime.h"
29 #include "wx/splitter.h"
30 #include "wx/aboutdlg.h"
31 #include "wx/colordlg.h"
32 #include "wx/choicdlg.h"
33 #include "wx/numdlg.h"
34 #include "wx/spinctrl.h"
35 #include "wx/imaglist.h"
36 #include "wx/notebook.h"
37
38 #include "mymodels.h"
39
40 // ----------------------------------------------------------------------------
41 // resources
42 // ----------------------------------------------------------------------------
43
44 #ifndef __WXMSW__
45 #include "../sample.xpm"
46 #endif
47
48 #include "wx_small.xpm"
49
50 // ----------------------------------------------------------------------------
51 // MyApp
52 // ----------------------------------------------------------------------------
53
54 class MyApp: public wxApp
55 {
56 public:
57 virtual bool OnInit();
58 };
59
60 // ----------------------------------------------------------------------------
61 // MyFrame
62 // ----------------------------------------------------------------------------
63
64 class MyFrame : public wxFrame
65 {
66 public:
67 MyFrame(wxFrame *frame, const wxString &title, int x, int y, int w, int h);
68 ~MyFrame();
69
70 void BuildDataViewCtrl(wxPanel* parent,
71 unsigned int nPanel,
72 unsigned long style = 0);
73
74 public: // event handlers
75
76 void OnStyleChange(wxCommandEvent& event);
77 void OnSetBackgroundColour(wxCommandEvent& event);
78 void OnSetForegroundColour(wxCommandEvent& event);
79 void OnQuit(wxCommandEvent& event);
80 void OnAbout(wxCommandEvent& event);
81
82 void OnClearLog(wxCommandEvent& event);
83 void OnPageChanged(wxBookCtrlEvent& event);
84
85 void OnAddMozart(wxCommandEvent& event);
86 void OnDeleteMusic(wxCommandEvent& event);
87 void OnDeleteYear(wxCommandEvent& event);
88 void OnSelectNinth(wxCommandEvent& event);
89 void OnCollapse(wxCommandEvent& event);
90 void OnExpand(wxCommandEvent& event);
91
92 void OnPrependList(wxCommandEvent& event);
93 void OnDeleteList(wxCommandEvent& event);
94
95 void OnValueChanged( wxDataViewEvent &event );
96
97 void OnActivated( wxDataViewEvent &event );
98 void OnExpanding( wxDataViewEvent &event );
99 void OnExpanded( wxDataViewEvent &event );
100 void OnCollapsing( wxDataViewEvent &event );
101 void OnCollapsed( wxDataViewEvent &event );
102 void OnSelectionChanged( wxDataViewEvent &event );
103
104 void OnStartEditing( wxDataViewEvent &event );
105 void OnEditingStarted( wxDataViewEvent &event );
106 void OnEditingDone( wxDataViewEvent &event );
107
108 void OnHeaderClick( wxDataViewEvent &event );
109 void OnHeaderRightClick( wxDataViewEvent &event );
110 void OnSorted( wxDataViewEvent &event );
111
112 void OnContextMenu( wxDataViewEvent &event );
113
114 void OnRightClick( wxMouseEvent &event );
115 void OnGoto( wxCommandEvent &event);
116 void OnAddMany( wxCommandEvent &event);
117
118 void OnBeginDrag( wxDataViewEvent &event );
119 void OnDropPossible( wxDataViewEvent &event );
120 void OnDrop( wxDataViewEvent &event );
121
122 private:
123 wxNotebook* m_notebook;
124
125 // the controls stored in the various tabs of the main notebook:
126
127 wxDataViewCtrl* m_ctrl[4];
128
129 // the models associated with the first two DVC:
130
131 wxObjectDataPtr<MyMusicTreeModel> m_music_model;
132 wxObjectDataPtr<MyListModel> m_list_model;
133
134 // other data:
135
136 wxDataViewColumn* m_col;
137
138 wxTextCtrl* m_log;
139 wxLog *m_logOld;
140
141 private:
142 DECLARE_EVENT_TABLE()
143 };
144
145
146 // ----------------------------------------------------------------------------
147 // MyCustomRenderer
148 // ----------------------------------------------------------------------------
149
150 class MyCustomRenderer: public wxDataViewCustomRenderer
151 {
152 public:
153 MyCustomRenderer( wxDataViewCellMode mode, int alignment ) :
154 wxDataViewCustomRenderer( wxString("long"), mode, alignment )
155 { m_height = 25; }
156
157 virtual bool Render( wxRect rect, wxDC *dc, int WXUNUSED(state) )
158 {
159 dc->SetBrush( *wxRED_BRUSH );
160 dc->SetPen( *wxTRANSPARENT_PEN );
161 dc->DrawRectangle( rect.Deflate(2) );
162 return true;
163 }
164
165 virtual bool Activate( wxRect WXUNUSED(cell),
166 wxDataViewModel *WXUNUSED(model),
167 const wxDataViewItem &WXUNUSED(item),
168 unsigned int WXUNUSED(col) )
169 {
170 wxLogMessage( "MyCustomRenderer Activate()" );
171 return false;
172 }
173
174 virtual bool LeftClick( wxPoint cursor, wxRect WXUNUSED(cell),
175 wxDataViewModel *WXUNUSED(model),
176 const wxDataViewItem &WXUNUSED(item),
177 unsigned int WXUNUSED(col) )
178 {
179 wxLogMessage( "MyCustomRenderer LeftClick( %d, %d )", cursor.x, cursor.y );
180 return false;
181 }
182
183 virtual wxSize GetSize() const
184 {
185 //return wxSize(60,m_height);
186 return wxSize(60,20);
187 }
188
189 virtual bool SetValue( const wxVariant &value )
190 {
191 m_height = value;
192 return true;
193 }
194
195 virtual bool GetValue( wxVariant &WXUNUSED(value) ) const { return true; }
196
197 private:
198 long m_height;
199 };
200
201
202 // ============================================================================
203 // implementation
204 // ============================================================================
205
206 // ----------------------------------------------------------------------------
207 // MyApp
208 // ----------------------------------------------------------------------------
209
210 IMPLEMENT_APP(MyApp)
211
212 bool MyApp::OnInit()
213 {
214 if ( !wxApp::OnInit() )
215 return false;
216
217 MyFrame *frame =
218 new MyFrame(NULL, "wxDataViewCtrl sample", 40, 40, 1000, 540);
219 SetTopWindow(frame);
220
221 frame->Show(true);
222 return true;
223 }
224
225
226 // ----------------------------------------------------------------------------
227 // MyFrame
228 // ----------------------------------------------------------------------------
229
230 enum
231 {
232 ID_CLEARLOG = wxID_HIGHEST+1,
233 ID_BACKGROUND_COLOUR,
234 ID_FOREGROUND_COLOUR,
235 ID_STYLE_MENU,
236
237 // file menu
238 //ID_SINGLE, wxDV_SINGLE==0 so it's always present
239 ID_MULTIPLE,
240 ID_ROW_LINES,
241 ID_HORIZ_RULES,
242 ID_VERT_RULES,
243
244 ID_EXIT = wxID_EXIT,
245
246 // about menu
247 ID_ABOUT = wxID_ABOUT,
248
249
250 // control IDs
251
252 ID_MUSIC_CTRL = 50,
253
254 ID_ADD_MOZART = 100,
255 ID_DELETE_MUSIC = 101,
256 ID_DELETE_YEAR = 102,
257 ID_SELECT_NINTH = 103,
258 ID_COLLAPSE = 104,
259 ID_EXPAND = 105,
260
261 ID_PREPEND_LIST = 200,
262 ID_DELETE_LIST = 201,
263 ID_GOTO = 202,
264 ID_ADD_MANY = 203
265 };
266
267 BEGIN_EVENT_TABLE(MyFrame, wxFrame)
268 EVT_MENU_RANGE( ID_MULTIPLE, ID_VERT_RULES, MyFrame::OnStyleChange )
269 EVT_MENU( ID_EXIT, MyFrame::OnQuit )
270 EVT_MENU( ID_ABOUT, MyFrame::OnAbout )
271 EVT_MENU( ID_CLEARLOG, MyFrame::OnClearLog )
272
273 EVT_MENU( ID_FOREGROUND_COLOUR, MyFrame::OnSetForegroundColour )
274 EVT_MENU( ID_BACKGROUND_COLOUR, MyFrame::OnSetBackgroundColour )
275
276 EVT_NOTEBOOK_PAGE_CHANGED( wxID_ANY, MyFrame::OnPageChanged )
277
278 EVT_BUTTON( ID_ADD_MOZART, MyFrame::OnAddMozart )
279 EVT_BUTTON( ID_DELETE_MUSIC, MyFrame::OnDeleteMusic )
280 EVT_BUTTON( ID_DELETE_YEAR, MyFrame::OnDeleteYear )
281 EVT_BUTTON( ID_SELECT_NINTH, MyFrame::OnSelectNinth )
282 EVT_BUTTON( ID_COLLAPSE, MyFrame::OnCollapse )
283 EVT_BUTTON( ID_EXPAND, MyFrame::OnExpand )
284
285 EVT_BUTTON( ID_PREPEND_LIST, MyFrame::OnPrependList )
286 EVT_BUTTON( ID_DELETE_LIST, MyFrame::OnDeleteList )
287 EVT_BUTTON( ID_GOTO, MyFrame::OnGoto)
288 EVT_BUTTON( ID_ADD_MANY, MyFrame::OnAddMany)
289
290 EVT_DATAVIEW_ITEM_VALUE_CHANGED( ID_MUSIC_CTRL, MyFrame::OnValueChanged )
291
292 EVT_DATAVIEW_ITEM_ACTIVATED(ID_MUSIC_CTRL, MyFrame::OnActivated )
293 EVT_DATAVIEW_ITEM_EXPANDING(ID_MUSIC_CTRL, MyFrame::OnExpanding)
294 EVT_DATAVIEW_ITEM_EXPANDED(ID_MUSIC_CTRL, MyFrame::OnExpanded)
295 EVT_DATAVIEW_ITEM_COLLAPSING(ID_MUSIC_CTRL, MyFrame::OnCollapsing)
296 EVT_DATAVIEW_ITEM_COLLAPSED(ID_MUSIC_CTRL, MyFrame::OnCollapsed)
297 EVT_DATAVIEW_SELECTION_CHANGED(ID_MUSIC_CTRL, MyFrame::OnSelectionChanged)
298
299 EVT_DATAVIEW_ITEM_START_EDITING(ID_MUSIC_CTRL, MyFrame::OnStartEditing)
300 EVT_DATAVIEW_ITEM_EDITING_STARTED(ID_MUSIC_CTRL, MyFrame::OnEditingStarted)
301 EVT_DATAVIEW_ITEM_EDITING_DONE(ID_MUSIC_CTRL, MyFrame::OnEditingDone)
302
303 EVT_DATAVIEW_COLUMN_HEADER_CLICK(ID_MUSIC_CTRL, MyFrame::OnHeaderClick)
304 EVT_DATAVIEW_COLUMN_HEADER_RIGHT_CLICKED(ID_MUSIC_CTRL, MyFrame::OnHeaderRightClick)
305 EVT_DATAVIEW_COLUMN_SORTED(ID_MUSIC_CTRL, MyFrame::OnSorted)
306
307 EVT_DATAVIEW_ITEM_CONTEXT_MENU(ID_MUSIC_CTRL, MyFrame::OnContextMenu)
308
309 EVT_DATAVIEW_ITEM_BEGIN_DRAG( ID_MUSIC_CTRL, MyFrame::OnBeginDrag )
310 EVT_DATAVIEW_ITEM_DROP_POSSIBLE( ID_MUSIC_CTRL, MyFrame::OnDropPossible )
311 EVT_DATAVIEW_ITEM_DROP( ID_MUSIC_CTRL, MyFrame::OnDrop )
312
313 EVT_RIGHT_UP(MyFrame::OnRightClick)
314 END_EVENT_TABLE()
315
316 MyFrame::MyFrame(wxFrame *frame, const wxString &title, int x, int y, int w, int h):
317 wxFrame(frame, wxID_ANY, title, wxPoint(x, y), wxSize(w, h))
318 {
319 m_log = NULL;
320 m_col = NULL;
321
322 m_ctrl[0] = NULL;
323 m_ctrl[1] = NULL;
324 m_ctrl[2] = NULL;
325 m_ctrl[3] = NULL;
326
327 SetIcon(wxICON(sample));
328
329
330 // build the menus
331 // ----------------
332
333 wxMenu *style_menu = new wxMenu;
334 //style_menu->AppendCheckItem(ID_SINGLE, "Single selection"));
335 style_menu->AppendCheckItem(ID_MULTIPLE, "Multiple selection");
336 style_menu->AppendCheckItem(ID_ROW_LINES, "Alternating colours");
337 style_menu->AppendCheckItem(ID_HORIZ_RULES, "Display horizontal rules");
338 style_menu->AppendCheckItem(ID_VERT_RULES, "Display vertical rules");
339
340 wxMenu *file_menu = new wxMenu;
341 file_menu->Append(ID_CLEARLOG, "&Clear log\tCtrl-L");
342 file_menu->Append(ID_FOREGROUND_COLOUR, "Set &foreground colour...\tCtrl-F");
343 file_menu->Append(ID_BACKGROUND_COLOUR, "Set &background colour...\tCtrl-B");
344 file_menu->Append(ID_STYLE_MENU, "&Style", style_menu);
345 file_menu->AppendSeparator();
346 file_menu->Append(ID_EXIT, "E&xit");
347
348 wxMenu *about_menu = new wxMenu;
349 about_menu->Append(ID_ABOUT, "&About");
350
351 wxMenuBar *menu_bar = new wxMenuBar;
352 menu_bar->Append(file_menu, "&File");
353 menu_bar->Append(about_menu, "&About");
354
355 SetMenuBar(menu_bar);
356 CreateStatusBar();
357
358
359 // first page of the notebook
360 // --------------------------
361
362 m_notebook = new wxNotebook( this, wxID_ANY );
363
364 wxPanel *firstPanel = new wxPanel( m_notebook, wxID_ANY );
365
366 BuildDataViewCtrl(firstPanel, 0); // sets m_ctrl[0]
367
368 wxBoxSizer *button_sizer = new wxBoxSizer( wxHORIZONTAL );
369 button_sizer->Add( new wxButton( firstPanel, ID_ADD_MOZART, "Add Mozart"), 0, wxALL, 10 );
370 button_sizer->Add( new wxButton( firstPanel, ID_DELETE_MUSIC,"Delete selected"), 0, wxALL, 10 );
371 button_sizer->Add( new wxButton( firstPanel, ID_DELETE_YEAR, "Delete \"Year\" column"), 0, wxALL, 10 );
372 button_sizer->Add( new wxButton( firstPanel, ID_SELECT_NINTH,"Select ninth symphony"), 0, wxALL, 10 );
373 button_sizer->Add( new wxButton( firstPanel, ID_COLLAPSE, "Collapse"), 0, wxALL, 10 );
374 button_sizer->Add( new wxButton( firstPanel, ID_EXPAND, "Expand"), 0, wxALL, 10 );
375
376 wxSizer *firstPanelSz = new wxBoxSizer( wxVERTICAL );
377 m_ctrl[0]->SetMinSize(wxSize(-1, 200));
378 firstPanelSz->Add(m_ctrl[0], 1, wxGROW|wxALL, 5);
379 firstPanelSz->Add(
380 new wxStaticText(firstPanel, wxID_ANY, "Most of the cells above are editable!"),
381 0, wxGROW|wxALL, 5);
382 firstPanelSz->Add(button_sizer);
383 firstPanel->SetSizerAndFit(firstPanelSz);
384
385
386 // second page of the notebook
387 // ---------------------------
388
389 wxPanel *secondPanel = new wxPanel( m_notebook, wxID_ANY );
390
391 BuildDataViewCtrl(secondPanel, 1); // sets m_ctrl[1]
392
393 wxBoxSizer *button_sizer2 = new wxBoxSizer( wxHORIZONTAL );
394 button_sizer2->Add( new wxButton( secondPanel, ID_PREPEND_LIST,"Prepend"), 0, wxALL, 10 );
395 button_sizer2->Add( new wxButton( secondPanel, ID_DELETE_LIST, "Delete selected"), 0, wxALL, 10 );
396 button_sizer2->Add( new wxButton( secondPanel, ID_GOTO, "Goto 50"), 0, wxALL, 10 );
397 button_sizer2->Add( new wxButton( secondPanel, ID_ADD_MANY, "Add 1000"), 0, wxALL, 10 );
398
399 wxSizer *secondPanelSz = new wxBoxSizer( wxVERTICAL );
400 secondPanelSz->Add(m_ctrl[1], 1, wxGROW|wxALL, 5);
401 secondPanelSz->Add(button_sizer2);
402 secondPanel->SetSizerAndFit(secondPanelSz);
403
404
405 // third page of the notebook
406 // ---------------------------
407
408 wxPanel *thirdPanel = new wxPanel( m_notebook, wxID_ANY );
409
410 BuildDataViewCtrl(thirdPanel, 2); // sets m_ctrl[2]
411
412 wxSizer *thirdPanelSz = new wxBoxSizer( wxVERTICAL );
413 thirdPanelSz->Add(m_ctrl[2], 1, wxGROW|wxALL, 5);
414 thirdPanel->SetSizerAndFit(thirdPanelSz);
415
416
417 // fourth page of the notebook
418 // ---------------------------
419
420 wxPanel *fourthPanel = new wxPanel( m_notebook, wxID_ANY );
421
422 BuildDataViewCtrl(fourthPanel, 3); // sets m_ctrl[3]
423
424 wxSizer *fourthPanelSz = new wxBoxSizer( wxVERTICAL );
425 fourthPanelSz->Add(m_ctrl[3], 1, wxGROW|wxALL, 5);
426 fourthPanel->SetSizerAndFit(fourthPanelSz);
427
428
429
430 // complete GUI
431 // ------------
432
433 m_notebook->AddPage(firstPanel, "MyMusicTreeModel");
434 m_notebook->AddPage(secondPanel, "MyListModel");
435 m_notebook->AddPage(thirdPanel, "wxDataViewListCtrl");
436 m_notebook->AddPage(fourthPanel, "wxDataViewTreeCtrl");
437
438 wxSizer* mainSizer = new wxBoxSizer(wxVERTICAL);
439
440 m_log = new wxTextCtrl( this, wxID_ANY, wxString(), wxDefaultPosition,
441 wxDefaultSize, wxTE_MULTILINE );
442 m_log->SetMinSize(wxSize(-1, 100));
443 m_logOld = wxLog::SetActiveTarget(new wxLogTextCtrl(m_log));
444 wxLogMessage( "This is the log window" );
445
446 mainSizer->Add( m_notebook, 1, wxGROW );
447 mainSizer->Add( m_log, 0, wxGROW );
448
449 SetSizerAndFit(mainSizer);
450 }
451
452 MyFrame::~MyFrame()
453 {
454 delete wxLog::SetActiveTarget(m_logOld);
455 }
456
457 void MyFrame::BuildDataViewCtrl(wxPanel* parent, unsigned int nPanel, unsigned long style)
458 {
459 switch (nPanel)
460 {
461 case 0:
462 {
463 wxASSERT(!m_ctrl[0] && !m_music_model);
464 m_ctrl[0] =
465 new wxDataViewCtrl( parent, ID_MUSIC_CTRL, wxDefaultPosition,
466 wxDefaultSize, style );
467
468 m_music_model = new MyMusicTreeModel;
469 m_ctrl[0]->AssociateModel( m_music_model.get() );
470
471 m_ctrl[0]->EnableDragSource( wxDF_UNICODETEXT );
472 m_ctrl[0]->EnableDropTarget( wxDF_UNICODETEXT );
473
474 // column 0 of the view control:
475
476 wxDataViewTextRenderer *tr =
477 new wxDataViewTextRenderer( "string", wxDATAVIEW_CELL_INERT );
478 wxDataViewColumn *column0 =
479 new wxDataViewColumn( "title", tr, 0, 200, wxALIGN_LEFT,
480 wxDATAVIEW_COL_SORTABLE | wxDATAVIEW_COL_RESIZABLE );
481 m_ctrl[0]->AppendColumn( column0 );
482 #if 0
483 // Call this and sorting is enabled
484 // immediatly upon start up.
485 column0->SetAsSortKey();
486 #endif
487
488 // column 1 of the view control:
489
490 tr = new wxDataViewTextRenderer( "string", wxDATAVIEW_CELL_EDITABLE );
491 wxDataViewColumn *column1 =
492 new wxDataViewColumn( "artist", tr, 1, 150, wxALIGN_LEFT,
493 wxDATAVIEW_COL_SORTABLE | wxDATAVIEW_COL_REORDERABLE |
494 wxDATAVIEW_COL_RESIZABLE );
495 column1->SetMinWidth(150); // this column can't be resized to be smaller
496 m_ctrl[0]->AppendColumn( column1 );
497
498 // column 2 of the view control:
499
500 wxDataViewSpinRenderer *sr =
501 new wxDataViewSpinRenderer( 0, 2010, wxDATAVIEW_CELL_EDITABLE, wxALIGN_RIGHT );
502 wxDataViewColumn *column2 =
503 new wxDataViewColumn( "year", sr, 2, 60, wxALIGN_LEFT,
504 wxDATAVIEW_COL_SORTABLE | wxDATAVIEW_COL_REORDERABLE );
505 m_ctrl[0]->AppendColumn( column2 );
506
507 // column 3 of the view control:
508
509 wxArrayString choices;
510 choices.Add( "good" );
511 choices.Add( "bad" );
512 choices.Add( "lousy" );
513 wxDataViewChoiceRenderer *c =
514 new wxDataViewChoiceRenderer( choices, wxDATAVIEW_CELL_EDITABLE, wxALIGN_RIGHT );
515 wxDataViewColumn *column3 =
516 new wxDataViewColumn( "rating", c, 3, 100, wxALIGN_LEFT,
517 wxDATAVIEW_COL_REORDERABLE | wxDATAVIEW_COL_RESIZABLE );
518 m_ctrl[0]->AppendColumn( column3 );
519
520 // column 4 of the view control:
521
522 m_ctrl[0]->AppendProgressColumn( "popularity", 4, wxDATAVIEW_CELL_INERT, 80 );
523
524 // column 5 of the view control:
525
526 MyCustomRenderer *cr = new MyCustomRenderer( wxDATAVIEW_CELL_ACTIVATABLE, wxALIGN_RIGHT );
527 wxDataViewColumn *column5 =
528 new wxDataViewColumn( "custom", cr, 5, -1, wxALIGN_LEFT,
529 wxDATAVIEW_COL_RESIZABLE );
530 m_ctrl[0]->AppendColumn( column5 );
531
532
533 // select initially the ninth symphony:
534 m_ctrl[0]->Select(m_music_model->GetNinthItem());
535 }
536 break;
537
538 case 1:
539 {
540 wxASSERT(!m_ctrl[1] && !m_list_model);
541 m_ctrl[1] = new wxDataViewCtrl( parent, wxID_ANY, wxDefaultPosition,
542 wxDefaultSize, style );
543
544 m_list_model = new MyListModel;
545 m_ctrl[1]->AssociateModel( m_list_model.get() );
546
547 // the various columns
548 m_ctrl[1]->AppendTextColumn("editable string",
549 MyListModel::Col_EditableText,
550 wxDATAVIEW_CELL_EDITABLE);
551 m_ctrl[1]->AppendIconTextColumn("icon",
552 MyListModel::Col_IconText,
553 wxDATAVIEW_CELL_EDITABLE);
554 m_ctrl[1]->AppendColumn(
555 new wxDataViewColumn("attributes",
556 new wxDataViewTextRenderer,
557 MyListModel::Col_TextWithAttr)
558 );
559 }
560 break;
561
562 case 2:
563 {
564 wxASSERT(!m_ctrl[2]);
565 wxDataViewListCtrl* lc =
566 new wxDataViewListCtrl( parent, wxID_ANY, wxDefaultPosition,
567 wxDefaultSize, style );
568 m_ctrl[2] = lc;
569
570 lc->AppendToggleColumn( "Toggle" );
571 lc->AppendTextColumn( "Text" );
572 lc->AppendProgressColumn( "Progress" );
573
574 wxVector<wxVariant> data;
575 for (unsigned int i=0; i<10; i++)
576 {
577 data.clear();
578 data.push_back( (i%3) == 0 );
579 data.push_back( wxString::Format("row %d", i) );
580 data.push_back( long(5*i) );
581
582 lc->AppendItem( data );
583 }
584 }
585 break;
586
587 case 3:
588 {
589 wxASSERT(!m_ctrl[3]);
590 wxDataViewTreeCtrl* tc =
591 new wxDataViewTreeCtrl( parent, wxID_ANY, wxDefaultPosition,
592 wxDefaultSize, style );
593 m_ctrl[3] = tc;
594
595 wxImageList *ilist = new wxImageList( 16, 16 );
596 ilist->Add( wxIcon(wx_small_xpm) );
597 tc->SetImageList( ilist );
598
599 wxDataViewItem parent =
600 tc->AppendContainer( wxDataViewItem(0), "The Root", 0 );
601 tc->AppendItem( parent, "Child 1", 0 );
602 tc->AppendItem( parent, "Child 2", 0 );
603 tc->AppendItem( parent, "Child 3, very long, long, long, long", 0 );
604
605 wxDataViewItem cont =
606 tc->AppendContainer( parent, "Container child", 0 );
607 tc->AppendItem( cont, "Child 4", 0 );
608 tc->AppendItem( cont, "Child 5", 0 );
609
610 tc->Expand(cont);
611 }
612 break;
613 }
614 }
615
616
617 // ----------------------------------------------------------------------------
618 // MyFrame - generic event handlers
619 // ----------------------------------------------------------------------------
620
621 void MyFrame::OnClearLog( wxCommandEvent& WXUNUSED(event) )
622 {
623 m_log->Clear();
624 }
625
626 void MyFrame::OnSetForegroundColour(wxCommandEvent& WXUNUSED(event))
627 {
628 wxDataViewCtrl * const dvc = m_ctrl[m_notebook->GetSelection()];
629 wxColour col = wxGetColourFromUser(this, dvc->GetForegroundColour());
630 if ( col.IsOk() )
631 {
632 dvc->SetForegroundColour(col);
633 Refresh();
634 }
635 }
636
637 void MyFrame::OnSetBackgroundColour(wxCommandEvent& WXUNUSED(event))
638 {
639 wxDataViewCtrl * const dvc = m_ctrl[m_notebook->GetSelection()];
640 wxColour col = wxGetColourFromUser(this, dvc->GetBackgroundColour());
641 if ( col.IsOk() )
642 {
643 dvc->SetBackgroundColour(col);
644 Refresh();
645 }
646 }
647
648 void MyFrame::OnPageChanged( wxBookCtrlEvent& WXUNUSED(event) )
649 {
650 unsigned int nPanel = m_notebook->GetSelection();
651
652 GetMenuBar()->FindItem(ID_STYLE_MENU)->SetItemLabel(
653 wxString::Format("Style of panel #%d", nPanel+1));
654
655 for (unsigned int id = ID_MULTIPLE; id <= ID_VERT_RULES; id++)
656 {
657 unsigned long style = 0;
658 switch (id)
659 {
660 /*case ID_SINGLE:
661 style = wxDV_SINGLE;
662 break;*/
663 case ID_MULTIPLE:
664 style = wxDV_MULTIPLE;
665 break;
666 case ID_ROW_LINES:
667 style = wxDV_ROW_LINES;
668 break;
669 case ID_HORIZ_RULES:
670 style = wxDV_HORIZ_RULES;
671 break;
672 case ID_VERT_RULES:
673 style = wxDV_VERT_RULES;
674 break;
675 default:
676 wxFAIL;
677 }
678
679 GetMenuBar()->FindItem(id)->Check( m_ctrl[nPanel]->HasFlag(style) );
680 }
681 }
682
683 void MyFrame::OnStyleChange( wxCommandEvent& WXUNUSED(event) )
684 {
685 unsigned int nPanel = m_notebook->GetSelection();
686
687 // build the style
688 unsigned long style = 0;
689 /*if (GetMenuBar()->FindItem(ID_SINGLE)->IsChecked())
690 style |= wxDV_SINGLE;*/
691 if (GetMenuBar()->FindItem(ID_MULTIPLE)->IsChecked())
692 style |= wxDV_MULTIPLE;
693 if (GetMenuBar()->FindItem(ID_ROW_LINES)->IsChecked())
694 style |= wxDV_ROW_LINES;
695 if (GetMenuBar()->FindItem(ID_HORIZ_RULES)->IsChecked())
696 style |= wxDV_HORIZ_RULES;
697 if (GetMenuBar()->FindItem(ID_VERT_RULES)->IsChecked())
698 style |= wxDV_VERT_RULES;
699
700 wxSizer* sz = m_ctrl[nPanel]->GetContainingSizer();
701 wxASSERT(sz);
702
703 sz->Detach(m_ctrl[nPanel]);
704 wxDELETE(m_ctrl[nPanel]);
705 m_ctrl[nPanel] = NULL;
706
707 if (nPanel == 0)
708 m_music_model.reset(NULL);
709 else if (nPanel == 1)
710 m_list_model.reset(NULL);
711
712 // rebuild the DVC for the selected panel:
713 BuildDataViewCtrl((wxPanel*)m_notebook->GetPage(nPanel), nPanel, style);
714
715 sz->Prepend(m_ctrl[nPanel], 1, wxGROW|wxALL, 5);
716 sz->Layout();
717 }
718
719 void MyFrame::OnQuit( wxCommandEvent& WXUNUSED(event) )
720 {
721 Close(true);
722 }
723
724 void MyFrame::OnAbout( wxCommandEvent& WXUNUSED(event) )
725 {
726 wxAboutDialogInfo info;
727 info.SetName(_("DataView sample"));
728 info.SetDescription(_("This sample demonstrates wxDataViewCtrl"));
729 info.SetCopyright(wxT("(C) 2007-2009 Robert Roebling"));
730 info.AddDeveloper("Robert Roebling");
731 info.AddDeveloper("Francesco Montorsi");
732
733 wxAboutBox(info);
734 }
735
736
737 // ----------------------------------------------------------------------------
738 // MyFrame - event handlers for the first page
739 // ----------------------------------------------------------------------------
740
741 void MyFrame::OnBeginDrag( wxDataViewEvent &event )
742 {
743 wxDataViewItem item( event.GetItem() );
744
745 // only allow drags for item, not containers
746 if (m_music_model->IsContainer( item ) )
747 {
748 event.Veto();
749 return;
750 }
751
752 MyMusicTreeModelNode *node = (MyMusicTreeModelNode*) item.GetID();
753 wxTextDataObject *obj = new wxTextDataObject;
754 obj->SetText( node->m_title );
755 event.SetDataObject( obj );
756 }
757
758 void MyFrame::OnDropPossible( wxDataViewEvent &event )
759 {
760 wxDataViewItem item( event.GetItem() );
761
762 // only allow drags for item, not containers
763 if (m_music_model->IsContainer( item ) )
764 event.Veto();
765
766 if (event.GetDataFormat() != wxDF_UNICODETEXT)
767 event.Veto();
768 }
769
770 void MyFrame::OnDrop( wxDataViewEvent &event )
771 {
772 wxDataViewItem item( event.GetItem() );
773
774 // only allow drops for item, not containers
775 if (m_music_model->IsContainer( item ) )
776 {
777 event.Veto();
778 return;
779 }
780
781 if (event.GetDataFormat() != wxDF_UNICODETEXT)
782 {
783 event.Veto();
784 return;
785 }
786
787 wxTextDataObject obj;
788 obj.SetData( wxDF_UNICODETEXT, event.GetDataSize(), event.GetDataBuffer() );
789
790 wxLogMessage( "Text dropped: %s", obj.GetText() );
791 }
792
793 void MyFrame::OnAddMozart( wxCommandEvent& WXUNUSED(event) )
794 {
795 m_music_model->AddToClassical( "Kleine Nachtmusik", "Wolfgang Mozart", 1787 );
796 }
797
798 void MyFrame::OnDeleteMusic( wxCommandEvent& WXUNUSED(event) )
799 {
800 wxDataViewItemArray items;
801 int len = m_ctrl[0]->GetSelections( items );
802 for( int i = 0; i < len; i ++ )
803 if (items[i].IsOk())
804 m_music_model->Delete( items[i] );
805 }
806
807 void MyFrame::OnDeleteYear( wxCommandEvent& WXUNUSED(event) )
808 {
809 m_ctrl[0]->DeleteColumn( m_ctrl[0]->GetColumn( 2 ) );
810 FindWindow( ID_DELETE_YEAR )->Disable();
811 }
812
813 void MyFrame::OnSelectNinth( wxCommandEvent& WXUNUSED(event) )
814 {
815 if (!m_music_model->GetNinthItem().IsOk())
816 {
817 wxLogError( "Cannot select the ninth symphony: it was removed!" );
818 return;
819 }
820
821 m_ctrl[0]->Select( m_music_model->GetNinthItem() );
822 }
823
824 void MyFrame::OnCollapse( wxCommandEvent& WXUNUSED(event) )
825 {
826 wxDataViewItem item = m_ctrl[0]->GetSelection();
827 if (item.IsOk())
828 m_ctrl[0]->Collapse( item );
829 }
830
831 void MyFrame::OnExpand( wxCommandEvent& WXUNUSED(event) )
832 {
833 wxDataViewItem item = m_ctrl[0]->GetSelection();
834 if (item.IsOk())
835 m_ctrl[0]->Expand( item );
836 }
837
838 void MyFrame::OnValueChanged( wxDataViewEvent &event )
839 {
840 if (!m_log)
841 return;
842
843 wxLogMessage( "wxEVT_DATAVIEW_ITEM_VALUE_CHANGED, Item Id: %d; Column: %d",
844 event.GetItem().GetID(), event.GetColumn() );
845 }
846
847 void MyFrame::OnActivated( wxDataViewEvent &event )
848 {
849 if(!m_log)
850 return;
851
852 wxString title = m_music_model->GetTitle( event.GetItem() );
853 wxLogMessage( "wxEVT_COMMAND_DATAVIEW_ITEM_ACTIVATED, Item: %s", title );
854
855 if (m_ctrl[0]->IsExpanded( event.GetItem() ))
856 {
857 wxLogMessage( "Item: %s is expanded", title );
858 }
859 }
860
861 void MyFrame::OnSelectionChanged( wxDataViewEvent &event )
862 {
863 if(!m_log)
864 return;
865
866 wxString title = m_music_model->GetTitle( event.GetItem() );
867 if (title.empty())
868 title = "None";
869
870 wxLogMessage( "wxEVT_COMMAND_DATAVIEW_SELECTION_CHANGED, First selected Item: %s", title );
871 }
872
873 void MyFrame::OnExpanding( wxDataViewEvent &event )
874 {
875 if (!m_log)
876 return;
877
878 wxString title = m_music_model->GetTitle( event.GetItem() );
879 wxLogMessage( "wxEVT_COMMAND_DATAVIEW_ITEM_EXPANDING, Item: %s", title );
880 }
881
882
883 void MyFrame::OnStartEditing( wxDataViewEvent &event )
884 {
885 wxString artist = m_music_model->GetArtist( event.GetItem() );
886 if (artist == "Ludwig van Beethoven")
887 {
888 event.Veto();
889
890 if (!m_log)
891 return;
892
893 wxLogMessage( "wxEVT_COMMAND_DATAVIEW_ITEM_START_EDITING vetoed. Artist: %s", artist );
894 }
895 else
896 wxLogMessage( "wxEVT_COMMAND_DATAVIEW_ITEM_START_EDITING not vetoed. Artist: %s", artist );
897
898 }
899
900 void MyFrame::OnEditingStarted( wxDataViewEvent &event )
901 {
902 if (!m_log)
903 return;
904
905 wxString title = m_music_model->GetTitle( event.GetItem() );
906 wxLogMessage( "wxEVT_COMMAND_DATAVIEW_ITEM_EDITING_STARTED, Item: %s", title );
907 }
908
909 void MyFrame::OnEditingDone( wxDataViewEvent &event )
910 {
911 if (!m_log)
912 return;
913
914 wxString title = m_music_model->GetTitle( event.GetItem() );
915 wxLogMessage( "wxEVT_COMMAND_DATAVIEW_ITEM_EDITING_DONE, Item: %s", title );
916 }
917
918 void MyFrame::OnExpanded( wxDataViewEvent &event )
919 {
920 if (!m_log)
921 return;
922
923 wxString title = m_music_model->GetTitle( event.GetItem() );
924 wxLogMessage( "wxEVT_COMMAND_DATAVIEW_ITEM_EXPANDED, Item: %s", title );
925 }
926
927 void MyFrame::OnCollapsing( wxDataViewEvent &event )
928 {
929 if (!m_log)
930 return;
931
932 wxString title = m_music_model->GetTitle( event.GetItem() );
933 wxLogMessage( "wxEVT_COMMAND_DATAVIEW_ITEM_COLLAPSING, Item: %s", title );
934 }
935
936 void MyFrame::OnCollapsed( wxDataViewEvent &event )
937 {
938 if (!m_log)
939 return;
940
941 wxString title = m_music_model->GetTitle( event.GetItem() );
942 wxLogMessage( "wxEVT_COMMAND_DATAVIEW_ITEM_COLLAPSED, Item: %s", title );
943 }
944
945 void MyFrame::OnContextMenu( wxDataViewEvent &event )
946 {
947 if (!m_log)
948 return;
949
950 wxString title = m_music_model->GetTitle( event.GetItem() );
951 wxLogMessage( "wxEVT_COMMAND_DATAVIEW_ITEM_CONTEXT_MENU, Item: %s", title );
952
953 wxMenu menu;
954 menu.Append( 1, "menuitem 1" );
955 menu.Append( 2, "menuitem 2" );
956 menu.Append( 3, "menuitem 3" );
957
958 m_ctrl[0]->PopupMenu(&menu);
959 }
960
961 void MyFrame::OnHeaderClick( wxDataViewEvent &event )
962 {
963 // we need to skip the event to let the default behaviour of sorting by
964 // this column when it is clicked to take place
965 event.Skip();
966
967 if (!m_log)
968 return;
969
970 int pos = m_ctrl[0]->GetColumnPosition( event.GetDataViewColumn() );
971
972 wxLogMessage( "wxEVT_COMMAND_DATAVIEW_COLUMN_HEADER_CLICK, Column position: %d", pos );
973 wxLogMessage( "Column width: %d", event.GetDataViewColumn()->GetWidth() );
974 }
975
976 void MyFrame::OnHeaderRightClick( wxDataViewEvent &event )
977 {
978 if(!m_log)
979 return;
980
981 int pos = m_ctrl[0]->GetColumnPosition( event.GetDataViewColumn() );
982
983 wxLogMessage( "wxEVT_COMMAND_DATAVIEW_COLUMN_HEADER_RIGHT_CLICK, Column position: %d", pos );
984 }
985
986 void MyFrame::OnSorted( wxDataViewEvent &event )
987 {
988 if(!m_log)
989 return;
990
991 int pos = m_ctrl[0]->GetColumnPosition( event.GetDataViewColumn() );
992
993 wxLogMessage( "wxEVT_COMMAND_DATAVIEW_COLUMN_SORTED, Column position: %d", pos );
994 }
995
996 void MyFrame::OnRightClick( wxMouseEvent &event )
997 {
998 if(!m_log)
999 return;
1000
1001 wxLogMessage( "wxEVT_MOUSE_RIGHT_UP, Click Point is X: %d, Y: %d",
1002 event.GetX(), event.GetY() );
1003 }
1004
1005
1006 // ----------------------------------------------------------------------------
1007 // MyFrame - event handlers for the second page
1008 // ----------------------------------------------------------------------------
1009
1010 void MyFrame::OnPrependList( wxCommandEvent& WXUNUSED(event) )
1011 {
1012 m_list_model->Prepend("Test");
1013 }
1014
1015 void MyFrame::OnDeleteList( wxCommandEvent& WXUNUSED(event) )
1016 {
1017 wxDataViewItemArray items;
1018 int len = m_ctrl[1]->GetSelections( items );
1019 if (len > 0)
1020 m_list_model->DeleteItems( items );
1021 }
1022
1023 void MyFrame::OnGoto(wxCommandEvent& WXUNUSED(event))
1024 {
1025 wxDataViewItem item = m_list_model->GetItem( 50 );
1026 m_ctrl[1]->EnsureVisible(item,m_col);
1027 }
1028
1029 void MyFrame::OnAddMany(wxCommandEvent& WXUNUSED(event))
1030 {
1031 m_list_model->AddMany();
1032 }
1033