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