From f6f0ef852ce8a020ad89bec5d67f42780a42230c Mon Sep 17 00:00:00 2001 From: Robert Roebling Date: Sun, 30 Dec 2007 12:41:39 +0000 Subject: [PATCH] initial drag interface for wxDataViewCtrl git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@50946 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- include/wx/dataview.h | 9 +++ samples/dataview/dataview.cpp | 32 ++++++++ src/gtk/dataview.cpp | 148 +++++++++++++++++++++++++++------- 3 files changed, 158 insertions(+), 31 deletions(-) diff --git a/include/wx/dataview.h b/include/wx/dataview.h index 97d9d5b36b..0d07559fd5 100644 --- a/include/wx/dataview.h +++ b/include/wx/dataview.h @@ -191,6 +191,15 @@ public: { return false; } virtual unsigned int GetChildren( const wxDataViewItem &item, wxDataViewItemArray &children ) const = 0; + // define DnD capabilities + virtual bool IsDraggable( const wxDataViewItem &WXUNUSED(item) ) + { return false; } + virtual size_t GetDragDataSize( const wxDataViewItem &WXUNUSED(item), const wxDataFormat &WXUNUSED(format) ) + { return 0; } + virtual bool GetDragData( const wxDataViewItem &WXUNUSED(item), const wxDataFormat &WXUNUSED(format), + void* WXUNUSED(data), size_t WXUNUSED(size) ) + { return FALSE; } + // delegated notifiers virtual bool ItemAdded( const wxDataViewItem &parent, const wxDataViewItem &item ); virtual bool ItemsAdded( const wxDataViewItem &parent, const wxDataViewItemArray &items ); diff --git a/samples/dataview/dataview.cpp b/samples/dataview/dataview.cpp index 4b8f7a5473..96477f0ae4 100644 --- a/samples/dataview/dataview.cpp +++ b/samples/dataview/dataview.cpp @@ -346,6 +346,38 @@ public: return count; } + // DnD + + virtual bool IsDraggable( const wxDataViewItem &item ) + { + // only drag items + return (!IsContainer(item)); + } + + virtual size_t GetDragDataSize( const wxDataViewItem &item, const wxDataFormat &WXUNUSED(format) ) + { + wxPrintf( "GetDragDataSize\n" ); + + MyMusicModelNode *node = (MyMusicModelNode*) item.GetID(); + wxString data; + data += node->m_title; data += wxT(" "); + data += node->m_artist; + return strlen( data.utf8_str() ) + 1; + } + virtual bool GetDragData( const wxDataViewItem &item, const wxDataFormat &WXUNUSED(format), + void* dest, size_t WXUNUSED(size) ) + { + wxPrintf( "GetDragData\n" ); + + MyMusicModelNode *node = (MyMusicModelNode*) item.GetID(); + wxString data; + data += node->m_title; data += wxT(" "); + data += node->m_artist; + wxCharBuffer buffer( data.utf8_str() ); + memcpy( dest, buffer, strlen(buffer)+1 ); + return true; + } + private: MyMusicModelNode* m_root; MyMusicModelNode* m_pop; diff --git a/src/gtk/dataview.cpp b/src/gtk/dataview.cpp index b8cf9ca2a5..2eb7995a8d 100644 --- a/src/gtk/dataview.cpp +++ b/src/gtk/dataview.cpp @@ -61,6 +61,7 @@ public: wxDataViewCtrlInternal( wxDataViewCtrl *owner, wxDataViewModel *wx_model, GtkWxTreeModel *owner ); ~wxDataViewCtrlInternal(); + // model iface GtkTreeModelFlags get_flags(); gboolean get_iter( GtkTreeIter *iter, GtkTreePath *path ); GtkTreePath *get_path( GtkTreeIter *iter); @@ -71,10 +72,17 @@ public: gboolean iter_nth_child( GtkTreeIter *iter, GtkTreeIter *parent, gint n ); gboolean iter_parent( GtkTreeIter *iter, GtkTreeIter *child ); - wxDataViewModel* GetDataViewModel() { return m_wx_model; } - wxDataViewCtrl* GetOwner() { return m_owner; } - GtkWxTreeModel* GetGtkModel() { return m_gtk_model; } - + // dnd iface + gboolean row_draggable( GtkTreeDragSource *drag_source, GtkTreePath *path ); + gboolean drag_data_delete( GtkTreeDragSource *drag_source, GtkTreePath* path ); + gboolean drag_data_get( GtkTreeDragSource *drag_source, GtkTreePath *path, + GtkSelectionData *selection_data ); + gboolean drag_data_received( GtkTreeDragDest *drag_dest, GtkTreePath *dest, + GtkSelectionData *selection_data ); + gboolean row_drop_possible( GtkTreeDragDest *drag_dest, GtkTreePath *dest_path, + GtkSelectionData *selection_data ); + + // notifactions from wxDataViewModel bool ItemAdded( const wxDataViewItem &parent, const wxDataViewItem &item ); bool ItemDeleted( const wxDataViewItem &parent, const wxDataViewItem &item ); bool ItemChanged( const wxDataViewItem &item ); @@ -82,6 +90,7 @@ public: bool Cleared(); void Resort(); + // sorting interface void SetSortOrder( GtkSortType sort_order ) { m_sort_order = sort_order; } GtkSortType GetSortOrder() { return m_sort_order; } @@ -93,6 +102,10 @@ public: bool IsSorted() { return (m_sort_column >= 0); } + // accessors + wxDataViewModel* GetDataViewModel() { return m_wx_model; } + wxDataViewCtrl* GetOwner() { return m_owner; } + GtkWxTreeModel* GetGtkModel() { return m_gtk_model; } protected: void InitTree(); @@ -651,26 +664,20 @@ static gboolean wxgtk_tree_model_row_draggable (GtkTreeDragSource *drag_source, GtkTreePath *path) { - GtkWxTreeModel *tree_model = (GtkWxTreeModel *) drag_source; - - wxPrintf( "draggable 1\n"); - - g_return_val_if_fail (GTK_IS_WX_TREE_MODEL (tree_model), FALSE); - - wxPrintf( "draggable 2\n"); + GtkWxTreeModel *wxtree_model = (GtkWxTreeModel *) drag_source; + g_return_val_if_fail (GTK_IS_WX_TREE_MODEL (wxtree_model), FALSE); - return TRUE; + return wxtree_model->internal->row_draggable( drag_source, path ); } static gboolean wxgtk_tree_model_drag_data_delete (GtkTreeDragSource *drag_source, GtkTreePath *path) { - GtkWxTreeModel *tree_model = (GtkWxTreeModel *) drag_source; - - g_return_val_if_fail (GTK_IS_WX_TREE_MODEL (tree_model), FALSE); + GtkWxTreeModel *wxtree_model = (GtkWxTreeModel *) drag_source; + g_return_val_if_fail (GTK_IS_WX_TREE_MODEL (wxtree_model), FALSE); - return FALSE; + return wxtree_model->internal->drag_data_delete( drag_source, path ); } static gboolean @@ -678,13 +685,25 @@ wxgtk_tree_model_drag_data_get (GtkTreeDragSource *drag_source, GtkTreePath *path, GtkSelectionData *selection_data) { - GtkWxTreeModel *tree_model = (GtkWxTreeModel *) drag_source; + GtkWxTreeModel *wxtree_model = (GtkWxTreeModel *) drag_source; + g_return_val_if_fail (GTK_IS_WX_TREE_MODEL (wxtree_model), FALSE); +#if 0 wxPrintf( "drag_get_data\n"); - g_return_val_if_fail (GTK_IS_WX_TREE_MODEL (tree_model), FALSE); + wxGtkString atom_selection(gdk_atom_name(selection_data->selection)); + wxPrintf( "selection %s\n", wxString::FromAscii(atom_selection) ); - return FALSE; + wxGtkString atom_target(gdk_atom_name(selection_data->target)); + wxPrintf( "target %s\n", wxString::FromAscii(atom_target) ); + + wxGtkString atom_type(gdk_atom_name(selection_data->type)); + wxPrintf( "type %s\n", wxString::FromAscii(atom_type) ); + + wxPrintf( "format %d\n", selection_data->format ); +#endif + + return wxtree_model->internal->drag_data_get( drag_source, path, selection_data ); } static gboolean @@ -692,11 +711,10 @@ wxgtk_tree_model_drag_data_received (GtkTreeDragDest *drag_dest, GtkTreePath *dest, GtkSelectionData *selection_data) { - GtkWxTreeModel *tree_model = (GtkWxTreeModel *) drag_dest; - - g_return_val_if_fail (GTK_IS_WX_TREE_MODEL (tree_model), FALSE); + GtkWxTreeModel *wxtree_model = (GtkWxTreeModel *) drag_dest; + g_return_val_if_fail (GTK_IS_WX_TREE_MODEL (wxtree_model), FALSE); - return FALSE; + return wxtree_model->internal->drag_data_received( drag_dest, dest, selection_data ); } static gboolean @@ -704,11 +722,10 @@ wxgtk_tree_model_row_drop_possible (GtkTreeDragDest *drag_dest, GtkTreePath *dest_path, GtkSelectionData *selection_data) { - GtkWxTreeModel *tree_model = (GtkWxTreeModel *) drag_dest; - - g_return_val_if_fail (GTK_IS_WX_TREE_MODEL (tree_model), FALSE); + GtkWxTreeModel *wxtree_model = (GtkWxTreeModel *) drag_dest; + g_return_val_if_fail (GTK_IS_WX_TREE_MODEL (wxtree_model), FALSE); - return FALSE; + return wxtree_model->internal->row_drop_possible( drag_dest, dest_path, selection_data ); } /* sortable iface */ @@ -717,11 +734,11 @@ wxgtk_tree_model_get_sort_column_id (GtkTreeSortable *sortable, gint *sort_column_id, GtkSortType *order) { - GtkWxTreeModel *tree_model = (GtkWxTreeModel *) sortable; + GtkWxTreeModel *wxtree_model = (GtkWxTreeModel *) sortable; g_return_val_if_fail (GTK_IS_WX_TREE_MODEL (sortable), FALSE); - if (!tree_model->internal->IsSorted()) + if (!wxtree_model->internal->IsSorted()) { if (sort_column_id) *sort_column_id = -1; @@ -731,10 +748,10 @@ wxgtk_tree_model_get_sort_column_id (GtkTreeSortable *sortable, if (sort_column_id) - *sort_column_id = tree_model->internal->GetSortColumn(); + *sort_column_id = wxtree_model->internal->GetSortColumn(); if (order) - *order = tree_model->internal->GetSortOrder(); + *order = wxtree_model->internal->GetSortOrder(); return TRUE; } @@ -2753,6 +2770,64 @@ void wxDataViewCtrlInternal::BuildBranch( wxGtkTreeModelNode *node ) } } +// GTK+ dnd iface + +gboolean wxDataViewCtrlInternal::row_draggable( GtkTreeDragSource *WXUNUSED(drag_source), + GtkTreePath *path ) +{ + GtkTreeIter iter; + if (!get_iter( &iter, path )) return FALSE; + + wxDataViewItem item( (void*) iter.user_data ); + + return m_wx_model->IsDraggable( item ); +} + +gboolean wxDataViewCtrlInternal::drag_data_delete( GtkTreeDragSource *WXUNUSED(drag_source), + GtkTreePath* path ) +{ + return FALSE; +} + +gboolean wxDataViewCtrlInternal::drag_data_get( GtkTreeDragSource *WXUNUSED(drag_source), + GtkTreePath *path, GtkSelectionData *selection_data ) +{ + GtkTreeIter iter; + if (!get_iter( &iter, path )) return FALSE; + + wxDataViewItem item( (void*) iter.user_data ); + + wxDataFormat format( selection_data->target ); + + size_t size = m_wx_model->GetDragDataSize( item, format ); + if (size == 0) return FALSE; + + void *data = malloc( size ); + + m_wx_model->GetDragData( item, format, data, size ); + + gtk_selection_data_set( selection_data, selection_data->target, + 8, (const guchar*) data, size ); + + free( data ); + + return TRUE; +} + +gboolean wxDataViewCtrlInternal::drag_data_received( GtkTreeDragDest *WXUNUSED(drag_dest), + GtkTreePath *dest, GtkSelectionData *selection_data ) +{ + return FALSE; +} + +gboolean wxDataViewCtrlInternal::row_drop_possible( GtkTreeDragDest *WXUNUSED(drag_dest), + GtkTreePath *dest_path, GtkSelectionData *selection_data ) +{ + return FALSE; +} + +// notifications from wxDataViewModel + bool wxDataViewCtrlInternal::Cleared() { if (m_root) @@ -2824,6 +2899,8 @@ bool wxDataViewCtrlInternal::ValueChanged( const wxDataViewItem &item, unsigned return true; } +// GTK+ model iface + GtkTreeModelFlags wxDataViewCtrlInternal::get_flags() { if (m_wx_model->IsIndexListModel()) @@ -3489,6 +3566,8 @@ void wxDataViewCtrl::Init() m_internal = NULL; } +static GtkTargetEntry gs_target; + bool wxDataViewCtrl::Create(wxWindow *parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style, const wxValidator& validator ) @@ -3514,6 +3593,13 @@ bool wxDataViewCtrl::Create(wxWindow *parent, wxWindowID id, g_signal_connect (m_treeview, "size_allocate", G_CALLBACK (gtk_dataviewctrl_size_callback), this); + gs_target.target = "UTF8_STRING"; + gs_target.flags = 0; + gs_target.info = -1; + gtk_tree_view_enable_model_drag_source( GTK_TREE_VIEW(m_treeview), + GDK_BUTTON1_MASK, &gs_target, 1, (GdkDragAction) GDK_ACTION_COPY ); + + #ifdef __WXGTK26__ if (!gtk_check_version(2,6,0)) gtk_tree_view_set_fixed_height_mode( GTK_TREE_VIEW(m_treeview), TRUE ); -- 2.45.2