};
// ---------------------------------------------------------
-// wxDataViewVirtualListModel
+// wxDataViewIndexListModel
// ---------------------------------------------------------
+// use hash map later
+WX_DEFINE_ARRAY_PTR( void*, wxDataViewItemHash );
+
class wxDataViewIndexListModel: public wxDataViewModel
{
public:
- wxDataViewIndexListModel();
+ wxDataViewIndexListModel( unsigned int initial_size = 0 );
~wxDataViewIndexListModel();
virtual unsigned int GetRowCount() = 0;
virtual bool SetValue( const wxVariant &variant,
unsigned int row, unsigned int col ) = 0;
- void ItemPrepended();
- void ItemInserted( unsigned int before );
- void ItemAppended();
- void ItemChanged( unsigned int row );
- void ValueChanged( unsigned int row, unsigned int col );
+ void RowPrepended();
+ void RowInserted( unsigned int before );
+ void RowAppended();
+ void RowDeleted( unsigned int row );
+ void RowChanged( unsigned int row );
+ void RowValueChanged( unsigned int row, unsigned int col );
+
+ // convert to/from row/wxDataViewItem
- wxDataViewItem GetItem( unsigned int row );
+ unsigned int GetRow( const wxDataViewItem &item ) const;
+ wxDataViewItem GetItem( unsigned int row ) const;
+
+ // compare based on index
virtual int Compare( const wxDataViewItem &item1, const wxDataViewItem &item2 );
+
+ // implement base methods
+
+ virtual void GetValue( wxVariant &variant,
+ const wxDataViewItem &item, unsigned int col ) const;
+ virtual bool SetValue( const wxVariant &variant,
+ const wxDataViewItem &item, unsigned int col );
+ virtual wxDataViewItem GetParent( const wxDataViewItem &item ) const;
+ virtual bool IsContainer( const wxDataViewItem &item ) const;
+ virtual wxDataViewItem GetFirstChild( const wxDataViewItem &parent ) const;
+ virtual wxDataViewItem GetNextSibling( const wxDataViewItem &item ) const;
+private:
+ wxDataViewItemHash m_hash;
+ unsigned int m_lastIndex;
};
// ---------------------------------------------------------
bool m_classicalMusicIsKnownToControl;
};
+class MyListModel: public wxDataViewIndexListModel
+{
+public:
+ MyListModel() :
+ wxDataViewIndexListModel( 100 )
+ {
+ unsigned int i;
+ for (i = 0; i < 100; i++)
+ {
+ wxString str;
+ str.Printf( "row number %d", i );
+ m_array.Add( str );
+ }
+ }
+
+ // helper methods to change the model
+
+ void Prepend( const wxString &text )
+ {
+ m_array.Insert( text, 0 );
+ RowPrepended();
+ }
+
+ void DeleteItem( const wxDataViewItem &item )
+ {
+ unsigned int row = GetRow( item );
+ m_array.RemoveAt( row );
+ RowDeleted( row );
+ }
+
+ // implementation of base class virtuals to define model
+
+ virtual unsigned int GetColumnCount() const
+ {
+ return 2;
+ }
+
+ virtual wxString GetColumnType( unsigned int col ) const
+ {
+ return "string";
+ }
+
+ virtual unsigned int GetRowCount()
+ {
+ return m_array.GetCount();
+ }
+
+ virtual void GetValue( wxVariant &variant,
+ unsigned int row, unsigned int col ) const
+ {
+ if (col==0)
+ {
+ variant = m_array[ row ];
+ }
+ else
+ {
+ wxString str;
+ str.Printf( "row %d col %d", row, col );
+ variant = str;
+ }
+ }
+
+ virtual bool SetValue( const wxVariant &variant,
+ unsigned int row, unsigned int col )
+ {
+ if (col == 0)
+ {
+ m_array[row] = variant.GetString();
+ return true;
+ }
+
+ return false;
+ }
+
+ wxArrayString m_array;
+};
+
// -------------------------------------
// MyApp
// -------------------------------------
public:
void OnQuit(wxCommandEvent& event);
void OnAbout(wxCommandEvent& event);
- void OnAdd(wxCommandEvent& event);
- void OnDelete(wxCommandEvent& event);
+
+ void OnAddMozart(wxCommandEvent& event);
+ void OnDeleteMusic(wxCommandEvent& event);
+
+ void OnPrependList(wxCommandEvent& event);
+ void OnDeleteList(wxCommandEvent& event);
private:
- wxDataViewCtrl* m_dataview;
+ wxDataViewCtrl* m_musicCtrl;
+ wxObjectDataPtr<MyMusicModel> m_music_model;
+
+ wxDataViewCtrl* m_listCtrl;
+ wxObjectDataPtr<MyListModel> m_list_model;
+
wxTextCtrl * m_log;
- wxObjectDataPtr<MyMusicModel> m_model;
private:
DECLARE_EVENT_TABLE()
ID_ABOUT = wxID_ABOUT,
ID_EXIT = wxID_EXIT,
- ID_ADD = 100,
- ID_DELETE = 101,
+ ID_ADD_MOZART = 100,
+ ID_DELETE_MUSIC = 101,
+
+ ID_PREPEND_LIST = 200,
+ ID_DELETE_LIST = 201
};
BEGIN_EVENT_TABLE(MyFrame, wxFrame)
EVT_MENU( ID_ABOUT, MyFrame::OnAbout )
EVT_MENU( ID_EXIT, MyFrame::OnQuit )
- EVT_BUTTON( ID_ADD, MyFrame::OnAdd )
- EVT_BUTTON( ID_DELETE, MyFrame::OnDelete )
+ EVT_BUTTON( ID_ADD_MOZART, MyFrame::OnAddMozart )
+ EVT_BUTTON( ID_DELETE_MUSIC, MyFrame::OnDeleteMusic )
+ EVT_BUTTON( ID_PREPEND_LIST, MyFrame::OnPrependList )
+ EVT_BUTTON( ID_DELETE_LIST, MyFrame::OnDeleteList )
END_EVENT_TABLE()
MyFrame::MyFrame(wxFrame *frame, wxChar *title, int x, int y, int w, int h):
wxBoxSizer *main_sizer = new wxBoxSizer( wxVERTICAL );
- m_dataview = new wxDataViewCtrl( this, wxID_ANY, wxDefaultPosition,
- wxDefaultSize );
+ wxBoxSizer *data_sizer = new wxBoxSizer( wxHORIZONTAL );
- m_model = new MyMusicModel;
- m_dataview->AssociateModel( m_model.get() );
+ // MyMusic
- m_dataview->AppendTextColumn( "Title", 0, wxDATAVIEW_CELL_INERT, 200,
+ m_musicCtrl = new wxDataViewCtrl( this, wxID_ANY, wxDefaultPosition,
+ wxDefaultSize );
+
+ m_music_model = new MyMusicModel;
+ m_musicCtrl->AssociateModel( m_music_model.get() );
+
+ m_musicCtrl->AppendTextColumn( "Title", 0, wxDATAVIEW_CELL_INERT, 200,
DEFAULT_ALIGN, wxDATAVIEW_COL_SORTABLE );
- m_dataview->AppendTextColumn( "Artist", 1, wxDATAVIEW_CELL_EDITABLE, 200,
+ m_musicCtrl->AppendTextColumn( "Artist", 1, wxDATAVIEW_CELL_EDITABLE, 200,
DEFAULT_ALIGN, wxDATAVIEW_COL_SORTABLE );
- m_dataview->AppendTextColumn( "Year", 2, wxDATAVIEW_CELL_INERT, 50,
+ m_musicCtrl->AppendTextColumn( "Year", 2, wxDATAVIEW_CELL_INERT, 50,
DEFAULT_ALIGN );
- main_sizer->Add( m_dataview, 2, wxGROW );
+ data_sizer->Add( m_musicCtrl, 3, wxGROW );
+
+#if 1
+
+ // MyList
+
+ m_listCtrl = new wxDataViewCtrl( this, wxID_ANY, wxDefaultPosition,
+ wxDefaultSize );
+
+ m_list_model = new MyListModel;
+ m_listCtrl->AssociateModel( m_list_model.get() );
+
+ m_listCtrl->AppendTextColumn( "editable string", 0, wxDATAVIEW_CELL_EDITABLE, 120 );
+ m_listCtrl->AppendTextColumn( "index", 1, wxDATAVIEW_CELL_INERT, 120 );
+
+ data_sizer->Add( m_listCtrl, 2, wxGROW );
+
+#endif
+
+ main_sizer->Add( data_sizer, 2, wxGROW );
wxBoxSizer *button_sizer = new wxBoxSizer( wxHORIZONTAL );
- button_sizer->Add( new wxButton( this, ID_ADD, "Add Mozart"), 0, wxALL, 10 );
- button_sizer->Add( new wxButton( this, ID_DELETE, "Delete selected"), 0, wxALL, 10 );
+ button_sizer->Add( new wxButton( this, ID_ADD_MOZART, "Add Mozart"), 0, wxALL, 10 );
+ button_sizer->Add( new wxButton( this, ID_DELETE_MUSIC, "Delete selected"), 0, wxALL, 10 );
+ button_sizer->Add( 10, 10, 1 );
+ button_sizer->Add( new wxButton( this, ID_PREPEND_LIST, "Prepend"), 0, wxALL, 10 );
+ button_sizer->Add( new wxButton( this, ID_DELETE_LIST, "Delete selected"), 0, wxALL, 10 );
- main_sizer->Add( button_sizer, 0, 0, 0 );
+ main_sizer->Add( button_sizer, 0, wxGROW, 0 );
m_log = new wxTextCtrl( this, -1, "", wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE );
Close(true);
}
-void MyFrame::OnDelete(wxCommandEvent& WXUNUSED(event) )
+void MyFrame::OnAddMozart(wxCommandEvent& WXUNUSED(event) )
+{
+ m_music_model->AddToClassical( "Kleine Nachtmusik", "Wolfgang Mozart", "1787" );
+}
+
+void MyFrame::OnDeleteMusic(wxCommandEvent& WXUNUSED(event) )
{
- wxDataViewItem item = m_dataview->GetSelection();
+ wxDataViewItem item = m_musicCtrl->GetSelection();
if (item.IsOk())
- m_model->Delete( item );
+ m_music_model->Delete( item );
}
-void MyFrame::OnAdd(wxCommandEvent& WXUNUSED(event) )
+void MyFrame::OnPrependList( wxCommandEvent& WXUNUSED(event) )
{
- m_model->AddToClassical( "Kleine Nachtmusik", "Wolfgang Mozart", "1787" );
+ m_list_model->Prepend( "Test" );
+}
+
+void MyFrame::OnDeleteList( wxCommandEvent& WXUNUSED(event) )
+{
+ wxDataViewItem item = m_listCtrl->GetSelection();
+ if (item.IsOk())
+ m_list_model->DeleteItem( item );
}
void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event) )
return litem1-litem2;
}
+// ---------------------------------------------------------
+// wxDataViewIndexListModel
+// ---------------------------------------------------------
+
+wxDataViewIndexListModel::wxDataViewIndexListModel( unsigned int initial_size )
+{
+ // build initial index
+ unsigned int i;
+ for (i = 1; i < initial_size+1; i++)
+ m_hash.Add( (void*) i );
+ m_lastIndex = initial_size + 1;
+}
+
+wxDataViewIndexListModel::~wxDataViewIndexListModel()
+{
+}
+
+void wxDataViewIndexListModel::RowPrepended()
+{
+ unsigned int id = m_lastIndex++;
+ m_hash.Insert( (void*) id, 0 );
+ wxDataViewItem item( (void*) id );
+ ItemAdded( wxDataViewItem(0), item );
+}
+
+void wxDataViewIndexListModel::RowInserted( unsigned int before )
+{
+ unsigned int id = m_lastIndex++;
+ m_hash.Insert( (void*) id, before );
+ wxDataViewItem item( (void*) id );
+ ItemAdded( wxDataViewItem(0), item );
+}
+
+void wxDataViewIndexListModel::RowAppended()
+{
+ unsigned int id = m_lastIndex++;
+ m_hash.Add( (void*) id );
+ wxDataViewItem item( (void*) id );
+ ItemAdded( wxDataViewItem(0), item );
+}
+
+void wxDataViewIndexListModel::RowDeleted( unsigned int row )
+{
+ wxDataViewItem item( m_hash[row] );
+ m_hash.RemoveAt( row );
+ wxDataViewModel::ItemDeleted( item );
+}
+
+void wxDataViewIndexListModel::RowChanged( unsigned int row )
+{
+ wxDataViewModel::ItemChanged( GetItem(row) );
+}
+
+void wxDataViewIndexListModel::RowValueChanged( unsigned int row, unsigned int col )
+{
+ wxDataViewModel::ValueChanged( GetItem(row), col );
+}
+
+unsigned int wxDataViewIndexListModel::GetRow( const wxDataViewItem &item ) const
+{
+ // assert for not found
+ return (unsigned int) m_hash.Index( item.GetID() );
+}
+
+wxDataViewItem wxDataViewIndexListModel::GetItem( unsigned int row ) const
+{
+ return wxDataViewItem( m_hash[row] );
+}
+
+int wxDataViewIndexListModel::Compare( const wxDataViewItem &item1, const wxDataViewItem &item2 )
+{
+ return GetRow(item1) - GetRow(item2);
+}
+
+void wxDataViewIndexListModel::GetValue( wxVariant &variant,
+ const wxDataViewItem &item, unsigned int col ) const
+{
+ return GetValue( variant, GetRow(item), col );
+}
+
+bool wxDataViewIndexListModel::SetValue( const wxVariant &variant,
+ const wxDataViewItem &item, unsigned int col )
+{
+ return SetValue( variant, GetRow(item), col );
+}
+
+wxDataViewItem wxDataViewIndexListModel::GetParent( const wxDataViewItem &item ) const
+{
+ return wxDataViewItem(0);
+}
+
+bool wxDataViewIndexListModel::IsContainer( const wxDataViewItem &item ) const
+{
+ // only the invisible root item has children
+ if (!item.IsOk())
+ return true;
+
+ return false;
+}
+
+wxDataViewItem wxDataViewIndexListModel::GetFirstChild( const wxDataViewItem &parent ) const
+{
+ if (!parent.IsOk())
+ {
+ if (m_hash.GetCount() == 0)
+ return wxDataViewItem(0);
+
+ return wxDataViewItem( m_hash[0]);
+ }
+
+ return wxDataViewItem(0);
+}
+
+wxDataViewItem wxDataViewIndexListModel::GetNextSibling( const wxDataViewItem &item ) const
+{
+ if (!item.IsOk())
+ return wxDataViewItem(0);
+
+ int pos = m_hash.Index( item.GetID() );
+ if ((pos == wxNOT_FOUND) || (pos == m_hash.GetCount()-1))
+ return wxDataViewItem(0);
+
+ return wxDataViewItem( m_hash[pos+1] );
+}
+
// ---------------------------------------------------------
// wxDataViewRendererBase
// ---------------------------------------------------------
~wxGtkTreeModelNode()
{
+ g_model = m_internal->GetDataViewModel();
size_t count = m_children->GetCount();
size_t i;
for (i = 0; i < count; i++)
unsigned int AddNode( wxGtkTreeModelNode* child )
{
+ g_model = m_internal->GetDataViewModel();
m_nodes.Add( child );
return m_children->Add( child->GetItem().GetID() );
}
unsigned int AddLeave( void* id )
{
+ g_model = m_internal->GetDataViewModel();
return m_children->Add( id );
}
void DeleteChild( void* id )
{
+ g_model = m_internal->GetDataViewModel();
size_t pos;
size_t count = m_children->GetCount();
for (pos = 0; pos < count; pos++)
void wxGtkTreeModelNode::Resort()
{
+ g_model = m_internal->GetDataViewModel();
+
size_t child_count = GetChildCount();
if (child_count == 0)
return;
gboolean wxDataViewCtrlInternal::get_iter( GtkTreeIter *iter, GtkTreePath *path )
{
+ g_model = m_wx_model;
+
int depth = gtk_tree_path_get_depth( path );
wxGtkTreeModelNode *node = m_root;
GtkTreePath *wxDataViewCtrlInternal::get_path( GtkTreeIter *iter )
{
+ g_model = m_wx_model;
+
GtkTreePath *retval = gtk_tree_path_new ();
void *id = iter->user_data;
GtkTreePath *wxDataViewCtrlInternal::get_path_safe( GtkTreeIter *iter )
{
+ g_model = m_wx_model;
+
GtkTreePath *retval = gtk_tree_path_new ();
void *id = iter->user_data;
gboolean wxDataViewCtrlInternal::iter_next( GtkTreeIter *iter )
{
+ g_model = m_wx_model;
+
wxGtkTreeModelNode *parent = FindParentNode( iter );
unsigned int pos = parent->GetChildren().Index( iter->user_data );
gboolean wxDataViewCtrlInternal::iter_children( GtkTreeIter *iter, GtkTreeIter *parent )
{
+ g_model = m_wx_model;
+
wxDataViewItem item( (void*) parent->user_data );
if (!m_wx_model->IsContainer( item ))
gboolean wxDataViewCtrlInternal::iter_has_child( GtkTreeIter *iter )
{
+ g_model = m_wx_model;
+
wxDataViewItem item( (void*) iter->user_data );
bool is_container = m_wx_model->IsContainer( item );
gint wxDataViewCtrlInternal::iter_n_children( GtkTreeIter *iter )
{
+ g_model = m_wx_model;
+
wxDataViewItem item( (void*) iter->user_data );
if (!m_wx_model->IsContainer( item ))
gboolean wxDataViewCtrlInternal::iter_nth_child( GtkTreeIter *iter, GtkTreeIter *parent, gint n )
{
+ g_model = m_wx_model;
+
void* id = NULL;
if (parent) id = (void*) parent->user_data;
wxDataViewItem item( id );
gboolean wxDataViewCtrlInternal::iter_parent( GtkTreeIter *iter, GtkTreeIter *child )
{
+ g_model = m_wx_model;
+
wxGtkTreeModelNode *node = FindParentNode( child );
if (!node)
return FALSE;