+ // redirect logs from our event handlers to text control
+ m_log = new wxTextCtrl( this, wxID_ANY, wxString(), wxDefaultPosition,
+ wxDefaultSize, wxTE_MULTILINE );
+ m_log->SetMinSize(wxSize(-1, 100));
+ m_logOld = wxLog::SetActiveTarget(new wxLogTextCtrl(m_log));
+ wxLogMessage( "This is the log window" );
+
+
+ // first page of the notebook
+ // --------------------------
+
+ m_notebook = new wxNotebook( this, wxID_ANY );
+
+ wxPanel *firstPanel = new wxPanel( m_notebook, wxID_ANY );
+
+ BuildDataViewCtrl(firstPanel, 0); // sets m_ctrl[0]
+
+ const wxSizerFlags border = wxSizerFlags().DoubleBorder();
+
+ wxBoxSizer *button_sizer = new wxBoxSizer( wxHORIZONTAL );
+ button_sizer->Add( new wxButton( firstPanel, ID_ADD_MOZART, "Add Mozart"), border );
+ button_sizer->Add( new wxButton( firstPanel, ID_DELETE_SEL, "Delete selected"), border );
+ button_sizer->Add( new wxButton( firstPanel, ID_DELETE_YEAR, "Delete \"Year\" column"), border );
+ button_sizer->Add( new wxButton( firstPanel, ID_SELECT_NINTH,"Select ninth symphony"), border );
+ button_sizer->Add( new wxButton( firstPanel, ID_COLLAPSE, "Collapse"), border );
+ button_sizer->Add( new wxButton( firstPanel, ID_EXPAND, "Expand"), border );
+
+ wxBoxSizer *sizerCurrent = new wxBoxSizer(wxHORIZONTAL);
+ sizerCurrent->Add(new wxButton(firstPanel, ID_SHOW_CURRENT,
+ "&Show current"), border);
+ sizerCurrent->Add(new wxButton(firstPanel, ID_SET_NINTH_CURRENT,
+ "Make &ninth symphony current"), border);
+
+ wxSizer *firstPanelSz = new wxBoxSizer( wxVERTICAL );
+ m_ctrl[0]->SetMinSize(wxSize(-1, 200));
+ firstPanelSz->Add(m_ctrl[0], 1, wxGROW|wxALL, 5);
+ firstPanelSz->Add(
+ new wxStaticText(firstPanel, wxID_ANY, "Most of the cells above are editable!"),
+ 0, wxGROW|wxALL, 5);
+ firstPanelSz->Add(button_sizer);
+ firstPanelSz->Add(sizerCurrent);
+ firstPanel->SetSizerAndFit(firstPanelSz);
+
+
+ // second page of the notebook
+ // ---------------------------
+
+ wxPanel *secondPanel = new wxPanel( m_notebook, wxID_ANY );
+
+ BuildDataViewCtrl(secondPanel, 1); // sets m_ctrl[1]
+
+ wxBoxSizer *button_sizer2 = new wxBoxSizer( wxHORIZONTAL );
+ button_sizer2->Add( new wxButton( secondPanel, ID_PREPEND_LIST,"Prepend"), 0, wxALL, 10 );
+ button_sizer2->Add( new wxButton( secondPanel, ID_DELETE_LIST, "Delete selected"), 0, wxALL, 10 );
+ button_sizer2->Add( new wxButton( secondPanel, ID_GOTO, "Goto 50"), 0, wxALL, 10 );
+ button_sizer2->Add( new wxButton( secondPanel, ID_ADD_MANY, "Add 1000"), 0, wxALL, 10 );
+ button_sizer2->Add( new wxButton( secondPanel, ID_HIDE_ATTRIBUTES, "Hide attributes"), 0, wxALL, 10 );
+ button_sizer2->Add( new wxButton( secondPanel, ID_SHOW_ATTRIBUTES, "Show attributes"), 0, wxALL, 10 );
+
+ wxSizer *secondPanelSz = new wxBoxSizer( wxVERTICAL );
+ secondPanelSz->Add(m_ctrl[1], 1, wxGROW|wxALL, 5);
+ secondPanelSz->Add(button_sizer2);
+ secondPanel->SetSizerAndFit(secondPanelSz);
+
+
+ // third page of the notebook
+ // ---------------------------
+
+ wxPanel *thirdPanel = new wxPanel( m_notebook, wxID_ANY );
+
+ BuildDataViewCtrl(thirdPanel, 2); // sets m_ctrl[2]
+
+ wxSizer *thirdPanelSz = new wxBoxSizer( wxVERTICAL );
+ thirdPanelSz->Add(m_ctrl[2], 1, wxGROW|wxALL, 5);
+ thirdPanel->SetSizerAndFit(thirdPanelSz);
+
+
+ // fourth page of the notebook
+ // ---------------------------
+
+ wxPanel *fourthPanel = new wxPanel( m_notebook, wxID_ANY );
+
+ BuildDataViewCtrl(fourthPanel, 3); // sets m_ctrl[3]
+ // Buttons
+ wxBoxSizer *button_sizer4 = new wxBoxSizer( wxHORIZONTAL );
+ button_sizer4->Add( new wxButton( fourthPanel, ID_DELETE_TREE_ITEM, "Delete Selected"), 0, wxALL, 10 );
+ button_sizer4->Add( new wxButton( fourthPanel, ID_DELETE_ALL_TREE_ITEMS, "Delete All"), 0, wxALL, 10 );
+ button_sizer4->Add( new wxButton( fourthPanel, ID_ADD_TREE_ITEM, "Add Item"), 0, wxALL, 10 );
+ button_sizer4->Add( new wxButton( fourthPanel, ID_ADD_TREE_CONTAINER_ITEM, "Add Container"), 0, wxALL, 10 );
+
+ wxSizer *fourthPanelSz = new wxBoxSizer( wxVERTICAL );
+ fourthPanelSz->Add(m_ctrl[3], 1, wxGROW|wxALL, 5);
+ fourthPanelSz->Add(button_sizer4);
+ fourthPanel->SetSizerAndFit(fourthPanelSz);
+
+
+
+ // complete GUI
+ // ------------
+
+ m_notebook->AddPage(firstPanel, "MyMusicTreeModel");
+ m_notebook->AddPage(secondPanel, "MyListModel");
+ m_notebook->AddPage(thirdPanel, "wxDataViewListCtrl");
+ m_notebook->AddPage(fourthPanel, "wxDataViewTreeCtrl");
+
+ wxSizer* mainSizer = new wxBoxSizer(wxVERTICAL);
+
+ mainSizer->Add( m_notebook, 1, wxGROW );
+ mainSizer->Add( m_log, 0, wxGROW );
+
+ SetSizerAndFit(mainSizer);
+}
+
+MyFrame::~MyFrame()
+{
+ delete wxLog::SetActiveTarget(m_logOld);
+}
+
+void MyFrame::BuildDataViewCtrl(wxPanel* parent, unsigned int nPanel, unsigned long style)
+{
+ switch (nPanel)
+ {
+ case 0:
+ {
+ wxASSERT(!m_ctrl[0] && !m_music_model);
+ m_ctrl[0] =
+ new wxDataViewCtrl( parent, ID_MUSIC_CTRL, wxDefaultPosition,
+ wxDefaultSize, style );
+ m_ctrl[0]->Connect(wxEVT_CHAR,
+ wxKeyEventHandler(MyFrame::OnDataViewChar),
+ NULL, this);
+
+ m_music_model = new MyMusicTreeModel;
+ m_ctrl[0]->AssociateModel( m_music_model.get() );
+
+#if wxUSE_DRAG_AND_DROP && wxUSE_UNICODE
+ m_ctrl[0]->EnableDragSource( wxDF_UNICODETEXT );
+ m_ctrl[0]->EnableDropTarget( wxDF_UNICODETEXT );
+#endif // wxUSE_DRAG_AND_DROP && wxUSE_UNICODE
+
+ // column 0 of the view control:
+
+ wxDataViewTextRenderer *tr =
+ new wxDataViewTextRenderer( "string", wxDATAVIEW_CELL_INERT );
+ wxDataViewColumn *column0 =
+ new wxDataViewColumn( "title", tr, 0, 200, wxALIGN_LEFT,
+ wxDATAVIEW_COL_SORTABLE | wxDATAVIEW_COL_RESIZABLE );
+ m_ctrl[0]->AppendColumn( column0 );
+#if 0
+ // Call this and sorting is enabled
+ // immediatly upon start up.
+ column0->SetAsSortKey();
+#endif
+
+ // column 1 of the view control:
+
+ tr = new wxDataViewTextRenderer( "string", wxDATAVIEW_CELL_EDITABLE );
+ wxDataViewColumn *column1 =
+ new wxDataViewColumn( "artist", tr, 1, 150, wxALIGN_LEFT,
+ wxDATAVIEW_COL_SORTABLE | wxDATAVIEW_COL_REORDERABLE |
+ wxDATAVIEW_COL_RESIZABLE );
+ column1->SetMinWidth(150); // this column can't be resized to be smaller
+ m_ctrl[0]->AppendColumn( column1 );
+
+ // column 2 of the view control:
+
+ wxDataViewSpinRenderer *sr =
+ new wxDataViewSpinRenderer( 0, 2010, wxDATAVIEW_CELL_EDITABLE, wxALIGN_RIGHT );
+ wxDataViewColumn *column2 =
+ new wxDataViewColumn( "year", sr, 2, 60, wxALIGN_LEFT,
+ wxDATAVIEW_COL_SORTABLE | wxDATAVIEW_COL_REORDERABLE );
+ m_ctrl[0]->AppendColumn( column2 );
+
+ // column 3 of the view control:
+
+ wxArrayString choices;
+ choices.Add( "good" );
+ choices.Add( "bad" );
+ choices.Add( "lousy" );
+ wxDataViewChoiceRenderer *c =
+ new wxDataViewChoiceRenderer( choices, wxDATAVIEW_CELL_EDITABLE, wxALIGN_RIGHT );
+ wxDataViewColumn *column3 =
+ new wxDataViewColumn( "rating", c, 3, 100, wxALIGN_LEFT,
+ wxDATAVIEW_COL_REORDERABLE | wxDATAVIEW_COL_RESIZABLE );
+ m_ctrl[0]->AppendColumn( column3 );
+
+ // column 4 of the view control:
+
+ m_ctrl[0]->AppendProgressColumn( "popularity", 4, wxDATAVIEW_CELL_INERT, 80 );
+
+ // column 5 of the view control:
+
+ MyCustomRenderer *cr = new MyCustomRenderer;
+ wxDataViewColumn *column5 =
+ new wxDataViewColumn( "custom", cr, 5, -1, wxALIGN_LEFT,
+ wxDATAVIEW_COL_RESIZABLE );
+ m_ctrl[0]->AppendColumn( column5 );
+
+
+ // select initially the ninth symphony:
+ m_ctrl[0]->Select(m_music_model->GetNinthItem());
+ }
+ break;
+
+ case 1:
+ {
+ wxASSERT(!m_ctrl[1] && !m_list_model);
+ m_ctrl[1] = new wxDataViewCtrl( parent, ID_ATTR_CTRL, wxDefaultPosition,
+ wxDefaultSize, style );
+
+ m_list_model = new MyListModel;
+ m_ctrl[1]->AssociateModel( m_list_model.get() );
+
+ // the various columns
+ m_ctrl[1]->AppendTextColumn("editable string",
+ MyListModel::Col_EditableText,
+ wxDATAVIEW_CELL_EDITABLE,
+ wxCOL_WIDTH_AUTOSIZE);
+ m_ctrl[1]->AppendIconTextColumn("icon",
+ MyListModel::Col_IconText,
+ wxDATAVIEW_CELL_EDITABLE,
+ wxCOL_WIDTH_AUTOSIZE);
+
+ m_attributes =
+ new wxDataViewColumn("attributes",
+ new wxDataViewTextRenderer,
+ MyListModel::Col_TextWithAttr,
+ wxCOL_WIDTH_AUTOSIZE,
+ wxALIGN_RIGHT,
+ wxDATAVIEW_COL_REORDERABLE | wxDATAVIEW_COL_RESIZABLE );
+ m_ctrl[1]->AppendColumn( m_attributes );
+
+ m_ctrl[1]->AppendColumn(
+ new wxDataViewColumn("custom renderer",
+ new MyCustomRenderer,
+ MyListModel::Col_Custom)
+ );
+ }
+ break;
+
+ case 2:
+ {
+ wxASSERT(!m_ctrl[2]);
+ wxDataViewListCtrl* lc =
+ new wxDataViewListCtrl( parent, wxID_ANY, wxDefaultPosition,
+ wxDefaultSize, style );
+ m_ctrl[2] = lc;
+
+ MyListStoreDerivedModel* page2_model = new MyListStoreDerivedModel();
+ lc->AssociateModel(page2_model);
+ page2_model->DecRef();
+
+ lc->AppendToggleColumn( "Toggle" );
+ lc->AppendTextColumn( "Text" );
+ lc->AppendProgressColumn( "Progress" );
+
+ wxVector<wxVariant> data;
+ for (unsigned int i=0; i<10; i++)
+ {
+ data.clear();
+ data.push_back( (i%3) == 0 );
+ data.push_back( wxString::Format("row %d", i) );
+ data.push_back( long(5*i) );
+
+ lc->AppendItem( data );
+ }
+ }
+ break;
+
+ case 3:
+ {
+ wxASSERT(!m_ctrl[3]);
+ wxDataViewTreeCtrl* tc =
+ new wxDataViewTreeCtrl( parent, wxID_ANY, wxDefaultPosition,
+ wxDefaultSize, style | wxDV_NO_HEADER );
+ m_ctrl[3] = tc;
+
+ wxImageList *ilist = new wxImageList( 16, 16 );
+ ilist->Add( wxIcon(wx_small_xpm) );
+ tc->AssignImageList( ilist );
+
+ wxDataViewItem parent =
+ tc->AppendContainer( wxDataViewItem(0), "The Root", 0 );
+ tc->AppendItem( parent, "Child 1", 0 );
+ tc->AppendItem( parent, "Child 2", 0 );
+ tc->AppendItem( parent, "Child 3, very long, long, long, long", 0 );
+
+ wxDataViewItem cont =
+ tc->AppendContainer( parent, "Container child", 0 );
+ tc->AppendItem( cont, "Child 4", 0 );
+ tc->AppendItem( cont, "Child 5", 0 );
+
+ tc->Expand(cont);
+ }
+ break;
+ }
+}
+
+
+// ----------------------------------------------------------------------------
+// MyFrame - generic event handlers
+// ----------------------------------------------------------------------------
+
+void MyFrame::OnClearLog( wxCommandEvent& WXUNUSED(event) )
+{
+ m_log->Clear();
+}
+
+void MyFrame::OnSetForegroundColour(wxCommandEvent& WXUNUSED(event))
+{
+ wxDataViewCtrl * const dvc = m_ctrl[m_notebook->GetSelection()];
+ wxColour col = wxGetColourFromUser(this, dvc->GetForegroundColour());
+ if ( col.IsOk() )
+ {
+ dvc->SetForegroundColour(col);
+ Refresh();
+ }
+}
+
+void MyFrame::OnSetBackgroundColour(wxCommandEvent& WXUNUSED(event))
+{
+ wxDataViewCtrl * const dvc = m_ctrl[m_notebook->GetSelection()];
+ wxColour col = wxGetColourFromUser(this, dvc->GetBackgroundColour());
+ if ( col.IsOk() )
+ {
+ dvc->SetBackgroundColour(col);
+ Refresh();
+ }
+}
+
+void MyFrame::OnPageChanged( wxBookCtrlEvent& WXUNUSED(event) )
+{
+ unsigned int nPanel = m_notebook->GetSelection();
+
+ GetMenuBar()->FindItem(ID_STYLE_MENU)->SetItemLabel(
+ wxString::Format("Style of panel #%d", nPanel+1));
+
+ for (unsigned int id = ID_MULTIPLE; id <= ID_VERT_RULES; id++)
+ {
+ unsigned long style = 0;
+ switch (id)
+ {
+ /*case ID_SINGLE:
+ style = wxDV_SINGLE;
+ break;*/
+ case ID_MULTIPLE:
+ style = wxDV_MULTIPLE;
+ break;
+ case ID_ROW_LINES:
+ style = wxDV_ROW_LINES;
+ break;
+ case ID_HORIZ_RULES:
+ style = wxDV_HORIZ_RULES;
+ break;
+ case ID_VERT_RULES:
+ style = wxDV_VERT_RULES;
+ break;
+ default:
+ wxFAIL;
+ }
+
+ GetMenuBar()->FindItem(id)->Check( m_ctrl[nPanel]->HasFlag(style) );
+ }
+}
+
+void MyFrame::OnStyleChange( wxCommandEvent& WXUNUSED(event) )
+{
+ unsigned int nPanel = m_notebook->GetSelection();
+
+ // build the style
+ unsigned long style = 0;
+ /*if (GetMenuBar()->FindItem(ID_SINGLE)->IsChecked())
+ style |= wxDV_SINGLE;*/
+ if (GetMenuBar()->FindItem(ID_MULTIPLE)->IsChecked())
+ style |= wxDV_MULTIPLE;
+ if (GetMenuBar()->FindItem(ID_ROW_LINES)->IsChecked())
+ style |= wxDV_ROW_LINES;
+ if (GetMenuBar()->FindItem(ID_HORIZ_RULES)->IsChecked())
+ style |= wxDV_HORIZ_RULES;
+ if (GetMenuBar()->FindItem(ID_VERT_RULES)->IsChecked())
+ style |= wxDV_VERT_RULES;
+
+ wxSizer* sz = m_ctrl[nPanel]->GetContainingSizer();
+ wxASSERT(sz);
+
+ sz->Detach(m_ctrl[nPanel]);
+ wxDELETE(m_ctrl[nPanel]);
+ m_ctrl[nPanel] = NULL;
+
+ if (nPanel == 0)
+ m_music_model.reset(NULL);
+ else if (nPanel == 1)
+ m_list_model.reset(NULL);
+
+ // rebuild the DVC for the selected panel:
+ BuildDataViewCtrl((wxPanel*)m_notebook->GetPage(nPanel), nPanel, style);
+
+ sz->Prepend(m_ctrl[nPanel], 1, wxGROW|wxALL, 5);
+ sz->Layout();
+}
+
+void MyFrame::OnQuit( wxCommandEvent& WXUNUSED(event) )