From 15cac64f7564d48c274c6490774a77bd8c09f808 Mon Sep 17 00:00:00 2001 From: Robert Roebling Date: Mon, 19 Jan 2009 22:27:06 +0000 Subject: [PATCH] New eventb based Drag interface for wxDataViewCtrl git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@58236 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- include/wx/dataview.h | 41 ++++++++++++----- include/wx/gtk/dataview.h | 3 +- samples/dataview/dataview.cpp | 85 +++++++++++++++++++++-------------- src/common/datavcmn.cpp | 8 ++++ src/gtk/dataview.cpp | 70 ++++++++++++++++++++--------- 5 files changed, 141 insertions(+), 66 deletions(-) diff --git a/include/wx/dataview.h b/include/wx/dataview.h index 547ffce878..29a658f66b 100644 --- a/include/wx/dataview.h +++ b/include/wx/dataview.h @@ -193,15 +193,6 @@ 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 ); @@ -722,6 +713,8 @@ public: const wxDataViewColumn *column = NULL ) = 0; virtual void HitTest( const wxPoint & point, wxDataViewItem &item, wxDataViewColumn* &column ) const = 0; virtual wxRect GetItemRect( const wxDataViewItem & item, const wxDataViewColumn *column = NULL ) const = 0; + + virtual bool EnableDragSource( const wxDataFormat &format ); protected: virtual void DoSetExpanderColumn() = 0 ; @@ -750,7 +743,9 @@ public: m_model(NULL), m_value(wxNullVariant), m_column(NULL), - m_pos(-1,-1) + m_pos(-1,-1), + m_isDraggable(false), + m_dragDataSize(-1) { } wxDataViewEvent(const wxDataViewEvent& event) @@ -760,7 +755,9 @@ public: m_model(event.m_model), m_value(event.m_value), m_column(event.m_column), - m_pos(m_pos) + m_pos(m_pos), + m_isDraggable(event.m_isDraggable), + m_dragDataSize(event.m_dragDataSize) { } wxDataViewItem GetItem() const { return m_item; } @@ -783,6 +780,16 @@ public: wxPoint GetPosition() const { return m_pos; } void SetPosition( int x, int y ) { m_pos.x = x; m_pos.y = y; } + // For Drag operations + bool IsDraggable() const { return m_isDraggable; } + void SetDraggable( bool can_drag = true ) { m_isDraggable = can_drag; } + int GetDragDataSize() const { return m_dragDataSize; } + void SetDragDataSize( int size ) { m_dragDataSize = size; } + void* GetDragDataBuffer() const { return m_dragDataBuffer; } + void SetDragDataBuffer( void *buffer ) { m_dragDataBuffer = buffer; } + wxDataFormat GetDataFormat() const { return m_dataFormat; } + void SetDataFormat( const wxDataFormat &format ) { m_dataFormat = format; } + virtual wxEvent *Clone() const { return new wxDataViewEvent(*this); } protected: @@ -792,6 +799,11 @@ protected: wxVariant m_value; wxDataViewColumn *m_column; wxPoint m_pos; + + bool m_isDraggable; + int m_dragDataSize; + void *m_dragDataBuffer; + wxDataFormat m_dataFormat; private: DECLARE_DYNAMIC_CLASS_NO_ASSIGN(wxDataViewEvent) @@ -815,6 +827,10 @@ wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_ADV, wxEVT_COMMAND_DATAVIEW_COLUMN_HEADER_ wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_ADV, wxEVT_COMMAND_DATAVIEW_COLUMN_SORTED, wxDataViewEvent ) wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_ADV, wxEVT_COMMAND_DATAVIEW_COLUMN_REORDERED, wxDataViewEvent ) +wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_ADV, wxEVT_COMMAND_DATAVIEW_ITEM_DRAGGABLE, wxDataViewEvent ) +wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_ADV, wxEVT_COMMAND_DATAVIEW_ITEM_GET_DRAG_DATA_SIZE, wxDataViewEvent ) +wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_ADV, wxEVT_COMMAND_DATAVIEW_ITEM_GET_DRAG_DATA, wxDataViewEvent ) + typedef void (wxEvtHandler::*wxDataViewEventFunction)(wxDataViewEvent&); #define wxDataViewEventHandler(func) \ @@ -841,6 +857,9 @@ typedef void (wxEvtHandler::*wxDataViewEventFunction)(wxDataViewEvent&); #define EVT_DATAVIEW_COLUMN_SORTED(id, fn) wx__DECLARE_DATAVIEWEVT(COLUMN_SORTED, id, fn) #define EVT_DATAVIEW_COLUMN_REORDERED(id, fn) wx__DECLARE_DATAVIEWEVT(COLUMN_REORDERED, id, fn) +#define EVT_DATAVIEW_ITEM_DRAGGABLE(id, fn) wx__DECLARE_DATAVIEWEVT(ITEM_DRAGGABLE, id, fn) +#define EVT_DATAVIEW_ITEM_GET_DRAG_DATA_SIZE(id, fn) wx__DECLARE_DATAVIEWEVT(ITEM_GET_DRAG_DATA_SIZE, id, fn) +#define EVT_DATAVIEW_ITEM_GET_DRAG_DATA(id, fn) wx__DECLARE_DATAVIEWEVT(ITEM_GET_DRAG_DATA, id, fn) #ifdef wxHAS_GENERIC_DATAVIEWCTRL // this symbol doesn't follow the convention for wxUSE_XXX symbols which diff --git a/include/wx/gtk/dataview.h b/include/wx/gtk/dataview.h index 6580aee732..1418915ef3 100644 --- a/include/wx/gtk/dataview.h +++ b/include/wx/gtk/dataview.h @@ -428,9 +428,10 @@ public: virtual void Expand( const wxDataViewItem & item ); virtual void Collapse( const wxDataViewItem & item ); - virtual bool IsExpanded( const wxDataViewItem & item ) const; + virtual bool EnableDragSource( const wxDataFormat &format ); + static wxVisualAttributes GetClassDefaultAttributes(wxWindowVariant variant = wxWINDOW_VARIANT_NORMAL); diff --git a/samples/dataview/dataview.cpp b/samples/dataview/dataview.cpp index 0a3647ba0d..ae42ee8337 100644 --- a/samples/dataview/dataview.cpp +++ b/samples/dataview/dataview.cpp @@ -378,38 +378,6 @@ 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; - } - wxDataViewItem GetNinthItem() { return wxDataViewItem( m_ninth ); @@ -700,6 +668,11 @@ public: void OnRightClick( wxMouseEvent &event ); void OnGoto( wxCommandEvent &event); void OnAddMany( wxCommandEvent &event); + + // DnD + void OnDraggable( wxDataViewEvent &event ); + void OnGetDragDataSize( wxDataViewEvent &event ); + void OnGetDragData( wxDataViewEvent &event ); private: wxDataViewCtrl* m_musicCtrl; @@ -795,6 +768,10 @@ BEGIN_EVENT_TABLE(MyFrame, wxFrame) EVT_DATAVIEW_COLUMN_SORTED(ID_MUSIC_CTRL, MyFrame::OnSorted) EVT_DATAVIEW_ITEM_CONTEXT_MENU(ID_MUSIC_CTRL, MyFrame::OnContextMenu) + + EVT_DATAVIEW_ITEM_DRAGGABLE( ID_MUSIC_CTRL, MyFrame::OnDraggable ) + EVT_DATAVIEW_ITEM_GET_DRAG_DATA_SIZE( ID_MUSIC_CTRL, MyFrame::OnGetDragDataSize ) + EVT_DATAVIEW_ITEM_GET_DRAG_DATA( ID_MUSIC_CTRL, MyFrame::OnGetDragData ) EVT_RIGHT_UP(MyFrame::OnRightClick) END_EVENT_TABLE() @@ -833,6 +810,8 @@ MyFrame::MyFrame(wxFrame *frame, const wxString &title, int x, int y, int w, int m_music_model = new MyMusicModel; m_musicCtrl->AssociateModel( m_music_model.get() ); + + m_musicCtrl->EnableDragSource( wxDF_TEXT ); wxDataViewTextRenderer *tr = new wxDataViewTextRenderer( wxT("string"), wxDATAVIEW_CELL_INERT ); wxDataViewColumn *column0 = new wxDataViewColumn( wxT("title"), tr, 0, 200, wxALIGN_LEFT, @@ -1175,9 +1154,47 @@ void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event) ) { wxAboutDialogInfo info; info.SetName(_("DataView sample")); - info.SetDescription(_("This sample demonstrates the dataview control handling")); - info.SetCopyright(_T("(C) 2007 Robert Roebling")); + info.SetDescription(_("This sample demonstrates wxDataViewCtrl")); + info.SetCopyright(_T("(C) 2007-2009 Robert Roebling")); wxAboutBox(info); } +void MyFrame::OnDraggable( wxDataViewEvent &event ) +{ + // only allow drags for item, not containers + event.SetDraggable( !m_music_model->IsContainer( event.GetItem() ) ); +} + +void MyFrame::OnGetDragDataSize( wxDataViewEvent &event ) +{ + if (event.GetDataFormat() == wxDF_TEXT) + { + wxDataViewItem item( event.GetItem() ); + MyMusicModelNode *node = (MyMusicModelNode*) item.GetID(); + + wxTextDataObject obj; + obj.SetText( node->m_artist ); + size_t size = obj.GetDataSize( wxDF_TEXT ); + event.SetDragDataSize( size ); + return; + } + + event.Skip(); +} + +void MyFrame::OnGetDragData( wxDataViewEvent &event ) +{ + if (event.GetDataFormat() == wxDF_TEXT) + { + wxDataViewItem item( event.GetItem() ); + MyMusicModelNode *node = (MyMusicModelNode*) item.GetID(); + + wxTextDataObject obj; + obj.SetText( node->m_artist ); + obj.GetDataHere( wxDF_TEXT, event.GetDragDataBuffer() ); + return; + } + + event.Skip(); +} diff --git a/src/common/datavcmn.cpp b/src/common/datavcmn.cpp index 79ed168564..5f59a20fcf 100644 --- a/src/common/datavcmn.cpp +++ b/src/common/datavcmn.cpp @@ -896,6 +896,11 @@ const wxDataViewModel* wxDataViewCtrlBase::GetModel() const return m_model; } +bool wxDataViewCtrlBase::EnableDragSource( const wxDataFormat &WXUNUSED(format) ) +{ + return false; +} + void wxDataViewCtrlBase::ExpandAncestors( const wxDataViewItem & item ) { if (!m_model) return; @@ -1230,6 +1235,9 @@ wxDEFINE_EVENT( wxEVT_COMMAND_DATAVIEW_COLUMN_HEADER_RIGHT_CLICK, wxDataViewEven wxDEFINE_EVENT( wxEVT_COMMAND_DATAVIEW_COLUMN_SORTED, wxDataViewEvent ) wxDEFINE_EVENT( wxEVT_COMMAND_DATAVIEW_COLUMN_REORDERED, wxDataViewEvent ) +wxDEFINE_EVENT( wxEVT_COMMAND_DATAVIEW_ITEM_DRAGGABLE, wxDataViewEvent ) +wxDEFINE_EVENT( wxEVT_COMMAND_DATAVIEW_ITEM_GET_DRAG_DATA_SIZE, wxDataViewEvent ) +wxDEFINE_EVENT( wxEVT_COMMAND_DATAVIEW_ITEM_GET_DRAG_DATA, wxDataViewEvent ) // ------------------------------------- // wxDataViewSpinRenderer diff --git a/src/gtk/dataview.cpp b/src/gtk/dataview.cpp index af854e9045..8fd5e37932 100644 --- a/src/gtk/dataview.cpp +++ b/src/gtk/dataview.cpp @@ -74,6 +74,9 @@ public: gboolean iter_parent( GtkTreeIter *iter, GtkTreeIter *child ); // dnd iface + + bool EnableDragSource( const wxDataFormat &format ); + 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, @@ -124,6 +127,8 @@ private: GtkSortType m_sort_order; wxDataViewColumn *m_dataview_sort_column; int m_sort_column; + GtkTargetEntry m_dragSourceTargetEntry; + wxCharBuffer m_dragSourceTargetEntryTarget; }; @@ -527,6 +532,8 @@ wxgtk_tree_model_get_column_type (GtkTreeModel *tree_model, wxString wxtype = wxtree_model->internal->GetDataViewModel()->GetColumnType( (unsigned int) index ); + wxPrintf( "get_column_type %s\n", wxtype ); + if (wxtype == wxT("string")) gtype = G_TYPE_STRING; else @@ -2911,15 +2918,34 @@ void wxDataViewCtrlInternal::BuildBranch( wxGtkTreeModelNode *node ) // GTK+ dnd iface +bool wxDataViewCtrlInternal::EnableDragSource( const wxDataFormat &format ) +{ + wxGtkString atom_str( gdk_atom_name( format ) ); + m_dragSourceTargetEntryTarget = wxCharBuffer( atom_str ); + + m_dragSourceTargetEntry.target = m_dragSourceTargetEntryTarget.data(); + m_dragSourceTargetEntry.flags = 0; + m_dragSourceTargetEntry.info = static_cast(-1); + + gtk_tree_view_enable_model_drag_source( GTK_TREE_VIEW(m_owner->GtkGetTreeView() ), + GDK_BUTTON1_MASK, &m_dragSourceTargetEntry, 1, (GdkDragAction) GDK_ACTION_COPY ); + + return true; +} + 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 ); + wxDataViewEvent event( wxEVT_COMMAND_DATAVIEW_ITEM_DRAGGABLE, m_owner->GetId() ); + event.SetItem( item ); + event.SetModel( m_wx_model ); + m_owner->HandleWindowEvent( event ); + + return event.IsDraggable(); } gboolean @@ -2934,24 +2960,31 @@ gboolean wxDataViewCtrlInternal::drag_data_get( GtkTreeDragSource *WXUNUSED(drag { 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; + wxDataViewEvent event( wxEVT_COMMAND_DATAVIEW_ITEM_GET_DRAG_DATA_SIZE, m_owner->GetId() ); + event.SetItem( item ); + event.SetModel( m_wx_model ); + event.SetDataFormat( selection_data->target ); + m_owner->HandleWindowEvent( event ); + if (event.GetDragDataSize() < 1) return FALSE; + size_t size = (size_t) event.GetDragDataSize(); 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 ); + event.SetEventType( wxEVT_COMMAND_DATAVIEW_ITEM_GET_DRAG_DATA ); + event.SetDragDataBuffer( data ); + gboolean res = FALSE; + if (m_owner->HandleWindowEvent( event )) + { + gtk_selection_data_set( selection_data, selection_data->target, + 8, (const guchar*) data, size ); + res = TRUE; + } free( data ); - return TRUE; + return res; } gboolean @@ -3709,8 +3742,6 @@ void wxDataViewCtrl::Init() m_cols.DeleteContents( true ); } -static GtkTargetEntry gs_target; - bool wxDataViewCtrl::Create(wxWindow *parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style, const wxValidator& validator ) @@ -3735,12 +3766,6 @@ bool wxDataViewCtrl::Create(wxWindow *parent, wxWindowID id, g_signal_connect (m_treeview, "size_allocate", G_CALLBACK (gtk_dataviewctrl_size_callback), this); - gs_target.target = const_cast("UTF8_STRING"); - gs_target.flags = 0; - gs_target.info = static_cast(-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)) { @@ -3862,6 +3887,11 @@ bool wxDataViewCtrl::AssociateModel( wxDataViewModel *model ) return true; } +bool wxDataViewCtrl::EnableDragSource( const wxDataFormat &format ) +{ + return m_internal->EnableDragSource( format ); +} + bool wxDataViewCtrl::AppendColumn( wxDataViewColumn *col ) { if (!wxDataViewCtrlBase::AppendColumn(col)) -- 2.47.2