added wxDataViewIndexListModel and sample

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@47630 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Robert Roebling
2007-07-21 23:07:03 +00:00
parent 11f406f91f
commit c534e69669
4 changed files with 333 additions and 33 deletions

View File

@@ -141,13 +141,16 @@ protected:
}; };
// --------------------------------------------------------- // ---------------------------------------------------------
// wxDataViewVirtualListModel // wxDataViewIndexListModel
// --------------------------------------------------------- // ---------------------------------------------------------
// use hash map later
WX_DEFINE_ARRAY_PTR( void*, wxDataViewItemHash );
class wxDataViewIndexListModel: public wxDataViewModel class wxDataViewIndexListModel: public wxDataViewModel
{ {
public: public:
wxDataViewIndexListModel(); wxDataViewIndexListModel( unsigned int initial_size = 0 );
~wxDataViewIndexListModel(); ~wxDataViewIndexListModel();
virtual unsigned int GetRowCount() = 0; virtual unsigned int GetRowCount() = 0;
@@ -158,16 +161,36 @@ public:
virtual bool SetValue( const wxVariant &variant, virtual bool SetValue( const wxVariant &variant,
unsigned int row, unsigned int col ) = 0; unsigned int row, unsigned int col ) = 0;
void ItemPrepended(); void RowPrepended();
void ItemInserted( unsigned int before ); void RowInserted( unsigned int before );
void ItemAppended(); void RowAppended();
void ItemChanged( unsigned int row ); void RowDeleted( unsigned int row );
void ValueChanged( unsigned int row, unsigned int col ); void RowChanged( unsigned int row );
void RowValueChanged( unsigned int row, unsigned int col );
wxDataViewItem GetItem( unsigned int row ); // convert to/from row/wxDataViewItem
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 ); 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;
}; };
// --------------------------------------------------------- // ---------------------------------------------------------

View File

@@ -305,6 +305,83 @@ private:
bool m_classicalMusicIsKnownToControl; 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 // MyApp
// ------------------------------------- // -------------------------------------
@@ -328,13 +405,21 @@ public:
public: public:
void OnQuit(wxCommandEvent& event); void OnQuit(wxCommandEvent& event);
void OnAbout(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: private:
wxDataViewCtrl* m_dataview; wxDataViewCtrl* m_musicCtrl;
wxObjectDataPtr<MyMusicModel> m_music_model;
wxDataViewCtrl* m_listCtrl;
wxObjectDataPtr<MyListModel> m_list_model;
wxTextCtrl * m_log; wxTextCtrl * m_log;
wxObjectDataPtr<MyMusicModel> m_model;
private: private:
DECLARE_EVENT_TABLE() DECLARE_EVENT_TABLE()
@@ -376,15 +461,20 @@ enum
ID_ABOUT = wxID_ABOUT, ID_ABOUT = wxID_ABOUT,
ID_EXIT = wxID_EXIT, ID_EXIT = wxID_EXIT,
ID_ADD = 100, ID_ADD_MOZART = 100,
ID_DELETE = 101, ID_DELETE_MUSIC = 101,
ID_PREPEND_LIST = 200,
ID_DELETE_LIST = 201
}; };
BEGIN_EVENT_TABLE(MyFrame, wxFrame) BEGIN_EVENT_TABLE(MyFrame, wxFrame)
EVT_MENU( ID_ABOUT, MyFrame::OnAbout ) EVT_MENU( ID_ABOUT, MyFrame::OnAbout )
EVT_MENU( ID_EXIT, MyFrame::OnQuit ) EVT_MENU( ID_EXIT, MyFrame::OnQuit )
EVT_BUTTON( ID_ADD, MyFrame::OnAdd ) EVT_BUTTON( ID_ADD_MOZART, MyFrame::OnAddMozart )
EVT_BUTTON( ID_DELETE, MyFrame::OnDelete ) EVT_BUTTON( ID_DELETE_MUSIC, MyFrame::OnDeleteMusic )
EVT_BUTTON( ID_PREPEND_LIST, MyFrame::OnPrependList )
EVT_BUTTON( ID_DELETE_LIST, MyFrame::OnDeleteList )
END_EVENT_TABLE() END_EVENT_TABLE()
MyFrame::MyFrame(wxFrame *frame, wxChar *title, int x, int y, int w, int h): MyFrame::MyFrame(wxFrame *frame, wxChar *title, int x, int y, int w, int h):
@@ -407,27 +497,53 @@ MyFrame::MyFrame(wxFrame *frame, wxChar *title, int x, int y, int w, int h):
wxBoxSizer *main_sizer = new wxBoxSizer( wxVERTICAL ); wxBoxSizer *main_sizer = new wxBoxSizer( wxVERTICAL );
m_dataview = new wxDataViewCtrl( this, wxID_ANY, wxDefaultPosition, wxBoxSizer *data_sizer = new wxBoxSizer( wxHORIZONTAL );
wxDefaultSize );
m_model = new MyMusicModel; // MyMusic
m_dataview->AssociateModel( m_model.get() );
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 ); 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 ); 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 ); 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 ); 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_ADD_MOZART, "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_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 ); m_log = new wxTextCtrl( this, -1, "", wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE );
@@ -441,16 +557,28 @@ void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event) )
Close(true); Close(true);
} }
void MyFrame::OnDelete(wxCommandEvent& WXUNUSED(event) ) void MyFrame::OnAddMozart(wxCommandEvent& WXUNUSED(event) )
{ {
wxDataViewItem item = m_dataview->GetSelection(); m_music_model->AddToClassical( "Kleine Nachtmusik", "Wolfgang Mozart", "1787" );
if (item.IsOk())
m_model->Delete( item );
} }
void MyFrame::OnAdd(wxCommandEvent& WXUNUSED(event) ) void MyFrame::OnDeleteMusic(wxCommandEvent& WXUNUSED(event) )
{ {
m_model->AddToClassical( "Kleine Nachtmusik", "Wolfgang Mozart", "1787" ); wxDataViewItem item = m_musicCtrl->GetSelection();
if (item.IsOk())
m_music_model->Delete( item );
}
void MyFrame::OnPrependList( wxCommandEvent& WXUNUSED(event) )
{
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) ) void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event) )

View File

@@ -205,6 +205,131 @@ int wxDataViewModel::Compare( const wxDataViewItem &item1, const wxDataViewItem
return litem1-litem2; 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 // wxDataViewRendererBase
// --------------------------------------------------------- // ---------------------------------------------------------

View File

@@ -118,6 +118,7 @@ public:
~wxGtkTreeModelNode() ~wxGtkTreeModelNode()
{ {
g_model = m_internal->GetDataViewModel();
size_t count = m_children->GetCount(); size_t count = m_children->GetCount();
size_t i; size_t i;
for (i = 0; i < count; i++) for (i = 0; i < count; i++)
@@ -130,17 +131,20 @@ public:
unsigned int AddNode( wxGtkTreeModelNode* child ) unsigned int AddNode( wxGtkTreeModelNode* child )
{ {
g_model = m_internal->GetDataViewModel();
m_nodes.Add( child ); m_nodes.Add( child );
return m_children->Add( child->GetItem().GetID() ); return m_children->Add( child->GetItem().GetID() );
} }
unsigned int AddLeave( void* id ) unsigned int AddLeave( void* id )
{ {
g_model = m_internal->GetDataViewModel();
return m_children->Add( id ); return m_children->Add( id );
} }
void DeleteChild( void* id ) void DeleteChild( void* id )
{ {
g_model = m_internal->GetDataViewModel();
size_t pos; size_t pos;
size_t count = m_children->GetCount(); size_t count = m_children->GetCount();
for (pos = 0; pos < count; pos++) for (pos = 0; pos < count; pos++)
@@ -2131,6 +2135,8 @@ void wxDataViewColumn::SetWidth( int width )
void wxGtkTreeModelNode::Resort() void wxGtkTreeModelNode::Resort()
{ {
g_model = m_internal->GetDataViewModel();
size_t child_count = GetChildCount(); size_t child_count = GetChildCount();
if (child_count == 0) if (child_count == 0)
return; return;
@@ -2272,6 +2278,8 @@ bool wxDataViewCtrlInternal::ItemDeleted( const wxDataViewItem &item )
gboolean wxDataViewCtrlInternal::get_iter( GtkTreeIter *iter, GtkTreePath *path ) gboolean wxDataViewCtrlInternal::get_iter( GtkTreeIter *iter, GtkTreePath *path )
{ {
g_model = m_wx_model;
int depth = gtk_tree_path_get_depth( path ); int depth = gtk_tree_path_get_depth( path );
wxGtkTreeModelNode *node = m_root; wxGtkTreeModelNode *node = m_root;
@@ -2312,6 +2320,8 @@ gboolean wxDataViewCtrlInternal::get_iter( GtkTreeIter *iter, GtkTreePath *path
GtkTreePath *wxDataViewCtrlInternal::get_path( GtkTreeIter *iter ) GtkTreePath *wxDataViewCtrlInternal::get_path( GtkTreeIter *iter )
{ {
g_model = m_wx_model;
GtkTreePath *retval = gtk_tree_path_new (); GtkTreePath *retval = gtk_tree_path_new ();
void *id = iter->user_data; void *id = iter->user_data;
@@ -2330,6 +2340,8 @@ GtkTreePath *wxDataViewCtrlInternal::get_path( GtkTreeIter *iter )
GtkTreePath *wxDataViewCtrlInternal::get_path_safe( GtkTreeIter *iter ) GtkTreePath *wxDataViewCtrlInternal::get_path_safe( GtkTreeIter *iter )
{ {
g_model = m_wx_model;
GtkTreePath *retval = gtk_tree_path_new (); GtkTreePath *retval = gtk_tree_path_new ();
void *id = iter->user_data; void *id = iter->user_data;
@@ -2355,6 +2367,8 @@ GtkTreePath *wxDataViewCtrlInternal::get_path_safe( GtkTreeIter *iter )
gboolean wxDataViewCtrlInternal::iter_next( GtkTreeIter *iter ) gboolean wxDataViewCtrlInternal::iter_next( GtkTreeIter *iter )
{ {
g_model = m_wx_model;
wxGtkTreeModelNode *parent = FindParentNode( iter ); wxGtkTreeModelNode *parent = FindParentNode( iter );
unsigned int pos = parent->GetChildren().Index( iter->user_data ); unsigned int pos = parent->GetChildren().Index( iter->user_data );
@@ -2369,6 +2383,8 @@ gboolean wxDataViewCtrlInternal::iter_next( GtkTreeIter *iter )
gboolean wxDataViewCtrlInternal::iter_children( GtkTreeIter *iter, GtkTreeIter *parent ) gboolean wxDataViewCtrlInternal::iter_children( GtkTreeIter *iter, GtkTreeIter *parent )
{ {
g_model = m_wx_model;
wxDataViewItem item( (void*) parent->user_data ); wxDataViewItem item( (void*) parent->user_data );
if (!m_wx_model->IsContainer( item )) if (!m_wx_model->IsContainer( item ))
@@ -2388,6 +2404,8 @@ gboolean wxDataViewCtrlInternal::iter_children( GtkTreeIter *iter, GtkTreeIter *
gboolean wxDataViewCtrlInternal::iter_has_child( GtkTreeIter *iter ) gboolean wxDataViewCtrlInternal::iter_has_child( GtkTreeIter *iter )
{ {
g_model = m_wx_model;
wxDataViewItem item( (void*) iter->user_data ); wxDataViewItem item( (void*) iter->user_data );
bool is_container = m_wx_model->IsContainer( item ); bool is_container = m_wx_model->IsContainer( item );
@@ -2402,6 +2420,8 @@ gboolean wxDataViewCtrlInternal::iter_has_child( GtkTreeIter *iter )
gint wxDataViewCtrlInternal::iter_n_children( GtkTreeIter *iter ) gint wxDataViewCtrlInternal::iter_n_children( GtkTreeIter *iter )
{ {
g_model = m_wx_model;
wxDataViewItem item( (void*) iter->user_data ); wxDataViewItem item( (void*) iter->user_data );
if (!m_wx_model->IsContainer( item )) if (!m_wx_model->IsContainer( item ))
@@ -2417,6 +2437,8 @@ gint wxDataViewCtrlInternal::iter_n_children( GtkTreeIter *iter )
gboolean wxDataViewCtrlInternal::iter_nth_child( GtkTreeIter *iter, GtkTreeIter *parent, gint n ) gboolean wxDataViewCtrlInternal::iter_nth_child( GtkTreeIter *iter, GtkTreeIter *parent, gint n )
{ {
g_model = m_wx_model;
void* id = NULL; void* id = NULL;
if (parent) id = (void*) parent->user_data; if (parent) id = (void*) parent->user_data;
wxDataViewItem item( id ); wxDataViewItem item( id );
@@ -2437,6 +2459,8 @@ gboolean wxDataViewCtrlInternal::iter_nth_child( GtkTreeIter *iter, GtkTreeIter
gboolean wxDataViewCtrlInternal::iter_parent( GtkTreeIter *iter, GtkTreeIter *child ) gboolean wxDataViewCtrlInternal::iter_parent( GtkTreeIter *iter, GtkTreeIter *child )
{ {
g_model = m_wx_model;
wxGtkTreeModelNode *node = FindParentNode( child ); wxGtkTreeModelNode *node = FindParentNode( child );
if (!node) if (!node)
return FALSE; return FALSE;