Implement icon text column using native GTK renderers in wxDVC.
[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", 0, wxDATAVIEW_CELL_EDITABLE);
549 m_ctrl[1]->AppendIconTextColumn("icon", 1, wxDATAVIEW_CELL_EDITABLE);
550 m_ctrl[1]->AppendColumn(
551 new wxDataViewColumn("attributes", new wxDataViewTextRenderer, 2 ));
552 }
553 break;
554
555 case 2:
556 {
557 wxASSERT(!m_ctrl[2]);
558 wxDataViewListCtrl* lc =
559 new wxDataViewListCtrl( parent, wxID_ANY, wxDefaultPosition,
560 wxDefaultSize, style );
561 m_ctrl[2] = lc;
562
563 lc->AppendToggleColumn( "Toggle" );
564 lc->AppendTextColumn( "Text" );
565 lc->AppendProgressColumn( "Progress" );
566
567 wxVector<wxVariant> data;
568 for (unsigned int i=0; i<10; i++)
569 {
570 data.clear();
571 data.push_back( (i%3) == 0 );
572 data.push_back( wxString::Format("row %d", i) );
573 data.push_back( long(5*i) );
574
575 lc->AppendItem( data );
576 }
577 }
578 break;
579
580 case 3:
581 {
582 wxASSERT(!m_ctrl[3]);
583 wxDataViewTreeCtrl* tc =
584 new wxDataViewTreeCtrl( parent, wxID_ANY, wxDefaultPosition,
585 wxDefaultSize, style );
586 m_ctrl[3] = tc;
587
588 wxImageList *ilist = new wxImageList( 16, 16 );
589 ilist->Add( wxIcon(wx_small_xpm) );
590 tc->SetImageList( ilist );
591
592 wxDataViewItem parent =
593 tc->AppendContainer( wxDataViewItem(0), "The Root", 0 );
594 tc->AppendItem( parent, "Child 1", 0 );
595 tc->AppendItem( parent, "Child 2", 0 );
596 tc->AppendItem( parent, "Child 3, very long, long, long, long", 0 );
597
598 wxDataViewItem cont =
599 tc->AppendContainer( parent, "Container child", 0 );
600 tc->AppendItem( cont, "Child 4", 0 );
601 tc->AppendItem( cont, "Child 5", 0 );
602
603 tc->Expand(cont);
604 }
605 break;
606 }
607 }
608
609
610 // ----------------------------------------------------------------------------
611 // MyFrame - generic event handlers
612 // ----------------------------------------------------------------------------
613
614 void MyFrame::OnClearLog( wxCommandEvent& WXUNUSED(event) )
615 {
616 m_log->Clear();
617 }
618
619 void MyFrame::OnSetForegroundColour(wxCommandEvent& WXUNUSED(event))
620 {
621 wxDataViewCtrl * const dvc = m_ctrl[m_notebook->GetSelection()];
622 wxColour col = wxGetColourFromUser(this, dvc->GetForegroundColour());
623 if ( col.IsOk() )
624 {
625 dvc->SetForegroundColour(col);
626 Refresh();
627 }
628 }
629
630 void MyFrame::OnSetBackgroundColour(wxCommandEvent& WXUNUSED(event))
631 {
632 wxDataViewCtrl * const dvc = m_ctrl[m_notebook->GetSelection()];
633 wxColour col = wxGetColourFromUser(this, dvc->GetBackgroundColour());
634 if ( col.IsOk() )
635 {
636 dvc->SetBackgroundColour(col);
637 Refresh();
638 }
639 }
640
641 void MyFrame::OnPageChanged( wxBookCtrlEvent& WXUNUSED(event) )
642 {
643 unsigned int nPanel = m_notebook->GetSelection();
644
645 GetMenuBar()->FindItem(ID_STYLE_MENU)->SetItemLabel(
646 wxString::Format("Style of panel #%d", nPanel+1));
647
648 for (unsigned int id = ID_MULTIPLE; id <= ID_VERT_RULES; id++)
649 {
650 unsigned long style = 0;
651 switch (id)
652 {
653 /*case ID_SINGLE:
654 style = wxDV_SINGLE;
655 break;*/
656 case ID_MULTIPLE:
657 style = wxDV_MULTIPLE;
658 break;
659 case ID_ROW_LINES:
660 style = wxDV_ROW_LINES;
661 break;
662 case ID_HORIZ_RULES:
663 style = wxDV_HORIZ_RULES;
664 break;
665 case ID_VERT_RULES:
666 style = wxDV_VERT_RULES;
667 break;
668 default:
669 wxFAIL;
670 }
671
672 GetMenuBar()->FindItem(id)->Check( m_ctrl[nPanel]->HasFlag(style) );
673 }
674 }
675
676 void MyFrame::OnStyleChange( wxCommandEvent& WXUNUSED(event) )
677 {
678 unsigned int nPanel = m_notebook->GetSelection();
679
680 // build the style
681 unsigned long style = 0;
682 /*if (GetMenuBar()->FindItem(ID_SINGLE)->IsChecked())
683 style |= wxDV_SINGLE;*/
684 if (GetMenuBar()->FindItem(ID_MULTIPLE)->IsChecked())
685 style |= wxDV_MULTIPLE;
686 if (GetMenuBar()->FindItem(ID_ROW_LINES)->IsChecked())
687 style |= wxDV_ROW_LINES;
688 if (GetMenuBar()->FindItem(ID_HORIZ_RULES)->IsChecked())
689 style |= wxDV_HORIZ_RULES;
690 if (GetMenuBar()->FindItem(ID_VERT_RULES)->IsChecked())
691 style |= wxDV_VERT_RULES;
692
693 wxSizer* sz = m_ctrl[nPanel]->GetContainingSizer();
694 wxASSERT(sz);
695
696 sz->Detach(m_ctrl[nPanel]);
697 wxDELETE(m_ctrl[nPanel]);
698 m_ctrl[nPanel] = NULL;
699
700 if (nPanel == 0)
701 m_music_model.reset(NULL);
702 else if (nPanel == 1)
703 m_list_model.reset(NULL);
704
705 // rebuild the DVC for the selected panel:
706 BuildDataViewCtrl((wxPanel*)m_notebook->GetPage(nPanel), nPanel, style);
707
708 sz->Prepend(m_ctrl[nPanel], 1, wxGROW|wxALL, 5);
709 sz->Layout();
710 }
711
712 void MyFrame::OnQuit( wxCommandEvent& WXUNUSED(event) )
713 {
714 Close(true);
715 }
716
717 void MyFrame::OnAbout( wxCommandEvent& WXUNUSED(event) )
718 {
719 wxAboutDialogInfo info;
720 info.SetName(_("DataView sample"));
721 info.SetDescription(_("This sample demonstrates wxDataViewCtrl"));
722 info.SetCopyright(wxT("(C) 2007-2009 Robert Roebling"));
723 info.AddDeveloper("Robert Roebling");
724 info.AddDeveloper("Francesco Montorsi");
725
726 wxAboutBox(info);
727 }
728
729
730 // ----------------------------------------------------------------------------
731 // MyFrame - event handlers for the first page
732 // ----------------------------------------------------------------------------
733
734 void MyFrame::OnBeginDrag( wxDataViewEvent &event )
735 {
736 wxDataViewItem item( event.GetItem() );
737
738 // only allow drags for item, not containers
739 if (m_music_model->IsContainer( item ) )
740 {
741 event.Veto();
742 return;
743 }
744
745 MyMusicTreeModelNode *node = (MyMusicTreeModelNode*) item.GetID();
746 wxTextDataObject *obj = new wxTextDataObject;
747 obj->SetText( node->m_title );
748 event.SetDataObject( obj );
749 }
750
751 void MyFrame::OnDropPossible( wxDataViewEvent &event )
752 {
753 wxDataViewItem item( event.GetItem() );
754
755 // only allow drags for item, not containers
756 if (m_music_model->IsContainer( item ) )
757 event.Veto();
758
759 if (event.GetDataFormat() != wxDF_UNICODETEXT)
760 event.Veto();
761 }
762
763 void MyFrame::OnDrop( wxDataViewEvent &event )
764 {
765 wxDataViewItem item( event.GetItem() );
766
767 // only allow drops for item, not containers
768 if (m_music_model->IsContainer( item ) )
769 {
770 event.Veto();
771 return;
772 }
773
774 if (event.GetDataFormat() != wxDF_UNICODETEXT)
775 {
776 event.Veto();
777 return;
778 }
779
780 wxTextDataObject obj;
781 obj.SetData( wxDF_UNICODETEXT, event.GetDataSize(), event.GetDataBuffer() );
782
783 wxLogMessage( "Text dropped: %s", obj.GetText() );
784 }
785
786 void MyFrame::OnAddMozart( wxCommandEvent& WXUNUSED(event) )
787 {
788 m_music_model->AddToClassical( "Kleine Nachtmusik", "Wolfgang Mozart", 1787 );
789 }
790
791 void MyFrame::OnDeleteMusic( wxCommandEvent& WXUNUSED(event) )
792 {
793 wxDataViewItemArray items;
794 int len = m_ctrl[0]->GetSelections( items );
795 for( int i = 0; i < len; i ++ )
796 if (items[i].IsOk())
797 m_music_model->Delete( items[i] );
798 }
799
800 void MyFrame::OnDeleteYear( wxCommandEvent& WXUNUSED(event) )
801 {
802 m_ctrl[0]->DeleteColumn( m_ctrl[0]->GetColumn( 2 ) );
803 FindWindow( ID_DELETE_YEAR )->Disable();
804 }
805
806 void MyFrame::OnSelectNinth( wxCommandEvent& WXUNUSED(event) )
807 {
808 if (!m_music_model->GetNinthItem().IsOk())
809 {
810 wxLogError( "Cannot select the ninth symphony: it was removed!" );
811 return;
812 }
813
814 m_ctrl[0]->Select( m_music_model->GetNinthItem() );
815 }
816
817 void MyFrame::OnCollapse( wxCommandEvent& WXUNUSED(event) )
818 {
819 wxDataViewItem item = m_ctrl[0]->GetSelection();
820 if (item.IsOk())
821 m_ctrl[0]->Collapse( item );
822 }
823
824 void MyFrame::OnExpand( wxCommandEvent& WXUNUSED(event) )
825 {
826 wxDataViewItem item = m_ctrl[0]->GetSelection();
827 if (item.IsOk())
828 m_ctrl[0]->Expand( item );
829 }
830
831 void MyFrame::OnValueChanged( wxDataViewEvent &event )
832 {
833 if (!m_log)
834 return;
835
836 wxLogMessage( "wxEVT_DATAVIEW_ITEM_VALUE_CHANGED, Item Id: %d; Column: %d",
837 event.GetItem().GetID(), event.GetColumn() );
838 }
839
840 void MyFrame::OnActivated( wxDataViewEvent &event )
841 {
842 if(!m_log)
843 return;
844
845 wxString title = m_music_model->GetTitle( event.GetItem() );
846 wxLogMessage( "wxEVT_COMMAND_DATAVIEW_ITEM_ACTIVATED, Item: %s", title );
847
848 if (m_ctrl[0]->IsExpanded( event.GetItem() ))
849 {
850 wxLogMessage( "Item: %s is expanded", title );
851 }
852 }
853
854 void MyFrame::OnSelectionChanged( wxDataViewEvent &event )
855 {
856 if(!m_log)
857 return;
858
859 wxString title = m_music_model->GetTitle( event.GetItem() );
860 if (title.empty())
861 title = "None";
862
863 wxLogMessage( "wxEVT_COMMAND_DATAVIEW_SELECTION_CHANGED, First selected Item: %s", title );
864 }
865
866 void MyFrame::OnExpanding( wxDataViewEvent &event )
867 {
868 if (!m_log)
869 return;
870
871 wxString title = m_music_model->GetTitle( event.GetItem() );
872 wxLogMessage( "wxEVT_COMMAND_DATAVIEW_ITEM_EXPANDING, Item: %s", title );
873 }
874
875
876 void MyFrame::OnStartEditing( wxDataViewEvent &event )
877 {
878 wxString artist = m_music_model->GetArtist( event.GetItem() );
879 if (artist == "Ludwig van Beethoven")
880 {
881 event.Veto();
882
883 if (!m_log)
884 return;
885
886 wxLogMessage( "wxEVT_COMMAND_DATAVIEW_ITEM_START_EDITING vetoed. Artist: %s", artist );
887 }
888 else
889 wxLogMessage( "wxEVT_COMMAND_DATAVIEW_ITEM_START_EDITING not vetoed. Artist: %s", artist );
890
891 }
892
893 void MyFrame::OnEditingStarted( wxDataViewEvent &event )
894 {
895 if (!m_log)
896 return;
897
898 wxString title = m_music_model->GetTitle( event.GetItem() );
899 wxLogMessage( "wxEVT_COMMAND_DATAVIEW_ITEM_EDITING_STARTED, Item: %s", title );
900 }
901
902 void MyFrame::OnEditingDone( wxDataViewEvent &event )
903 {
904 if (!m_log)
905 return;
906
907 wxString title = m_music_model->GetTitle( event.GetItem() );
908 wxLogMessage( "wxEVT_COMMAND_DATAVIEW_ITEM_EDITING_DONE, Item: %s", title );
909 }
910
911 void MyFrame::OnExpanded( wxDataViewEvent &event )
912 {
913 if (!m_log)
914 return;
915
916 wxString title = m_music_model->GetTitle( event.GetItem() );
917 wxLogMessage( "wxEVT_COMMAND_DATAVIEW_ITEM_EXPANDED, Item: %s", title );
918 }
919
920 void MyFrame::OnCollapsing( wxDataViewEvent &event )
921 {
922 if (!m_log)
923 return;
924
925 wxString title = m_music_model->GetTitle( event.GetItem() );
926 wxLogMessage( "wxEVT_COMMAND_DATAVIEW_ITEM_COLLAPSING, Item: %s", title );
927 }
928
929 void MyFrame::OnCollapsed( wxDataViewEvent &event )
930 {
931 if (!m_log)
932 return;
933
934 wxString title = m_music_model->GetTitle( event.GetItem() );
935 wxLogMessage( "wxEVT_COMMAND_DATAVIEW_ITEM_COLLAPSED, Item: %s", title );
936 }
937
938 void MyFrame::OnContextMenu( wxDataViewEvent &event )
939 {
940 if (!m_log)
941 return;
942
943 wxString title = m_music_model->GetTitle( event.GetItem() );
944 wxLogMessage( "wxEVT_COMMAND_DATAVIEW_ITEM_CONTEXT_MENU, Item: %s", title );
945
946 wxMenu menu;
947 menu.Append( 1, "menuitem 1" );
948 menu.Append( 2, "menuitem 2" );
949 menu.Append( 3, "menuitem 3" );
950
951 m_ctrl[0]->PopupMenu(&menu);
952 }
953
954 void MyFrame::OnHeaderClick( wxDataViewEvent &event )
955 {
956 // we need to skip the event to let the default behaviour of sorting by
957 // this column when it is clicked to take place
958 event.Skip();
959
960 if (!m_log)
961 return;
962
963 int pos = m_ctrl[0]->GetColumnPosition( event.GetDataViewColumn() );
964
965 wxLogMessage( "wxEVT_COMMAND_DATAVIEW_COLUMN_HEADER_CLICK, Column position: %d", pos );
966 wxLogMessage( "Column width: %d", event.GetDataViewColumn()->GetWidth() );
967 }
968
969 void MyFrame::OnHeaderRightClick( wxDataViewEvent &event )
970 {
971 if(!m_log)
972 return;
973
974 int pos = m_ctrl[0]->GetColumnPosition( event.GetDataViewColumn() );
975
976 wxLogMessage( "wxEVT_COMMAND_DATAVIEW_COLUMN_HEADER_RIGHT_CLICK, Column position: %d", pos );
977 }
978
979 void MyFrame::OnSorted( wxDataViewEvent &event )
980 {
981 if(!m_log)
982 return;
983
984 int pos = m_ctrl[0]->GetColumnPosition( event.GetDataViewColumn() );
985
986 wxLogMessage( "wxEVT_COMMAND_DATAVIEW_COLUMN_SORTED, Column position: %d", pos );
987 }
988
989 void MyFrame::OnRightClick( wxMouseEvent &event )
990 {
991 if(!m_log)
992 return;
993
994 wxLogMessage( "wxEVT_MOUSE_RIGHT_UP, Click Point is X: %d, Y: %d",
995 event.GetX(), event.GetY() );
996 }
997
998
999 // ----------------------------------------------------------------------------
1000 // MyFrame - event handlers for the second page
1001 // ----------------------------------------------------------------------------
1002
1003 void MyFrame::OnPrependList( wxCommandEvent& WXUNUSED(event) )
1004 {
1005 m_list_model->Prepend("Test");
1006 }
1007
1008 void MyFrame::OnDeleteList( wxCommandEvent& WXUNUSED(event) )
1009 {
1010 wxDataViewItemArray items;
1011 int len = m_ctrl[1]->GetSelections( items );
1012 if (len > 0)
1013 m_list_model->DeleteItems( items );
1014 }
1015
1016 void MyFrame::OnGoto(wxCommandEvent& WXUNUSED(event))
1017 {
1018 wxDataViewItem item = m_list_model->GetItem( 50 );
1019 m_ctrl[1]->EnsureVisible(item,m_col);
1020 }
1021
1022 void MyFrame::OnAddMany(wxCommandEvent& WXUNUSED(event))
1023 {
1024 m_list_model->AddMany();
1025 }
1026