]> git.saurik.com Git - wxWidgets.git/commitdiff
New eventb based Drag interface for wxDataViewCtrl
authorRobert Roebling <robert@roebling.de>
Mon, 19 Jan 2009 22:27:06 +0000 (22:27 +0000)
committerRobert Roebling <robert@roebling.de>
Mon, 19 Jan 2009 22:27:06 +0000 (22:27 +0000)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@58236 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

include/wx/dataview.h
include/wx/gtk/dataview.h
samples/dataview/dataview.cpp
src/common/datavcmn.cpp
src/gtk/dataview.cpp

index 547ffce878237d208dcb59b6ec8f26eab700da9d..29a658f66b0d7924b21ad69585e0c3c454bf0345 100644 (file)
@@ -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
index 6580aee732c0561c671ed688614f63cd44e855be..1418915ef33a8ba2061cc6994e1cb415502d1f1f 100644 (file)
@@ -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);
 
index 0a3647ba0d67acd1c860cec0b5cfc453b4d789ab..ae42ee83377c94a84178919446666a24f4870753 100644 (file)
@@ -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();
+}
index 79ed168564485e47c1add4d2fd0ebd650694a392..5f59a20fcf377550a32d7540df0bcd155b36286e 100644 (file)
@@ -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
index af854e9045b6fc8159785fc7fdd225cd3dd87e4a..8fd5e3793256030c076ccca687570e53de0d2931 100644 (file)
@@ -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<guint>(-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<char *>("UTF8_STRING");
-    gs_target.flags = 0;
-    gs_target.info = static_cast<guint>(-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))