]> git.saurik.com Git - wxWidgets.git/commitdiff
Add event based Drop API
authorRobert Roebling <robert@roebling.de>
Tue, 20 Jan 2009 13:46:21 +0000 (13:46 +0000)
committerRobert Roebling <robert@roebling.de>
Tue, 20 Jan 2009 13:46:21 +0000 (13:46 +0000)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@58240 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

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

index 17d6f3e092ec29f5fda0131457f51a0e17409026..2437dac42756cfbac5ea0431b8082c0f8f6c262b 100644 (file)
@@ -715,6 +715,7 @@ public:
     virtual wxRect GetItemRect( const wxDataViewItem & item, const wxDataViewColumn *column = NULL ) const = 0;
     
     virtual bool EnableDragSource( const wxDataFormat &format );
+    virtual bool EnableDropTarget( const wxDataFormat &format );
 
 protected:
     virtual void DoSetExpanderColumn() = 0 ;
@@ -744,7 +745,9 @@ public:
         m_value(wxNullVariant),
         m_column(NULL),
         m_pos(-1,-1),
-        m_dataObject(NULL)
+        m_dataObject(NULL),
+        m_dataBuffer(NULL),
+        m_dataSize(0)
         { }
 
     wxDataViewEvent(const wxDataViewEvent& event)
@@ -755,7 +758,10 @@ public:
         m_value(event.m_value),
         m_column(event.m_column),
         m_pos(m_pos),
-        m_dataObject(event.m_dataObject)
+        m_dataObject(event.m_dataObject),
+        m_dataFormat(event.m_dataFormat),
+        m_dataBuffer(event.m_dataBuffer),
+        m_dataSize(event.m_dataSize)
         { }
 
     wxDataViewItem GetItem() const { return m_item; }
@@ -778,9 +784,17 @@ public:
     wxPoint GetPosition() const { return m_pos; }
     void SetPosition( int x, int y ) { m_pos.x = x; m_pos.y = y; }
 
-    // For DnD operations
+    // For drag operations
     void SetDataObject( wxDataObject *obj ) { m_dataObject = obj; }
-    wxDataObject *GetDataObject() { return m_dataObject; }
+    wxDataObject *GetDataObject() const { return m_dataObject; }
+    
+    // For drop operations
+    void SetDataFormat( const wxDataFormat &format ) { m_dataFormat = format; }
+    wxDataFormat GetDataFormat() const { return m_dataFormat; }
+    void SetDataSize( size_t size ) { m_dataSize = size; }
+    size_t GetDataSize() const { return m_dataSize; }
+    void SetDataBuffer( void* buf ) { m_dataBuffer = buf;}
+    void *GetDataBuffer() const { return m_dataBuffer; }
 
     virtual wxEvent *Clone() const { return new wxDataViewEvent(*this); }
 
@@ -791,7 +805,12 @@ protected:
     wxVariant           m_value;
     wxDataViewColumn   *m_column;
     wxPoint             m_pos;
+    
     wxDataObject       *m_dataObject;
+    
+    wxDataFormat        m_dataFormat;
+    void*               m_dataBuffer;
+    size_t              m_dataSize;
 
 private:
     DECLARE_DYNAMIC_CLASS_NO_ASSIGN(wxDataViewEvent)
@@ -816,6 +835,8 @@ wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_ADV, wxEVT_COMMAND_DATAVIEW_COLUMN_SORTED,
 wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_ADV, wxEVT_COMMAND_DATAVIEW_COLUMN_REORDERED, wxDataViewEvent )
 
 wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_ADV, wxEVT_COMMAND_DATAVIEW_ITEM_BEGIN_DRAG, wxDataViewEvent )
+wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_ADV, wxEVT_COMMAND_DATAVIEW_ITEM_DROP_POSSIBLE, wxDataViewEvent )
+wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_ADV, wxEVT_COMMAND_DATAVIEW_ITEM_DROP, wxDataViewEvent )
 
 typedef void (wxEvtHandler::*wxDataViewEventFunction)(wxDataViewEvent&);
 
@@ -844,6 +865,8 @@ typedef void (wxEvtHandler::*wxDataViewEventFunction)(wxDataViewEvent&);
 #define EVT_DATAVIEW_COLUMN_REORDERED(id, fn) wx__DECLARE_DATAVIEWEVT(COLUMN_REORDERED, id, fn)
 
 #define EVT_DATAVIEW_ITEM_BEGIN_DRAG(id, fn) wx__DECLARE_DATAVIEWEVT(ITEM_BEGIN_DRAG, id, fn)
+#define EVT_DATAVIEW_ITEM_DROP_POSSIBLE(id, fn) wx__DECLARE_DATAVIEWEVT(ITEM_DROP_POSSIBLE, id, fn)
+#define EVT_DATAVIEW_ITEM_DROP(id, fn) wx__DECLARE_DATAVIEWEVT(ITEM_DROP, id, fn)
 
 #ifdef wxHAS_GENERIC_DATAVIEWCTRL
     // this symbol doesn't follow the convention for wxUSE_XXX symbols which
index 550edd0a8936a1037e94d20cc0608a9e7b1245b4..c4ac26a10b3385d9e618a8027ec756d284bb3da4 100644 (file)
@@ -556,6 +556,10 @@ public:
            Process a wxEVT_COMMAND_DATAVIEW_COLUMN_REORDERED event.
     @event{EVT_DATAVIEW_ITEM_BEGIN_DRAG(id, func)}
            Process a wxEVT_COMMAND_DATAVIEW_ITEM_BEGIN_DRAG event.
+    @event{EVT_DATAVIEW_ITEM_DROP_POSSIBLE(id, func)}
+           Process a wxEVT_COMMAND_DATAVIEW_ITEM_DROP_POSSIBLE event.
+    @event{EVT_DATAVIEW_ITEM_DROP(id, func)}
+           Process a wxEVT_COMMAND_DATAVIEW_ITEM_DROP event.
     @endEventTable
 
     @library{wxadv}
@@ -765,6 +769,16 @@ public:
     */
     virtual bool DeleteColumn(wxDataViewColumn* column);
 
+    /**
+       Enable drag operations using the given @a format.
+    */
+    virtual bool EnableDragSource( const wxDataFormat &format );
+    
+    /**
+       Enable drop operations using the given @a format.
+    */
+    virtual bool EnableDropTarget( const wxDataFormat &format );
+    
     /**
         Call this to ensure that the given item is visible.
     */
@@ -2253,13 +2267,44 @@ public:
     void SetValue(const wxVariant& value);
     
     /**
-        Set wxDataObject for Drag'n'drop data transfer.
+        Set wxDataObject for data transfer within a drag operation.
     */
     void SetDataObject( wxDataObject *obj );
             
     /**
-        Gets associated wxDataObject for Drag'n'drop data transfer.
+        Used internally. Gets associated wxDataObject for data transfer
+        within a drag operation.
+    */
+    wxDataObject *GetDataObject() const;
+    
+    /**
+        Used internally. Sets the wxDataFormat during a drop operation.
+    */
+    void SetDataFormat( const wxDataFormat &format );
+    
+    /**
+        Gets the wxDataFormat during a drop operation.
+    */
+    wxDataFormat GetDataFormat() const;
+    
+    /**
+        Used internally. Sets the data size for a drop data transfer.
+    */
+    void SetDataSize( size_t size );
+    
+    /**
+        Gets the data size for a drop data transfer.
+    */
+    size_t GetDataSize() const;
+    
+    /**
+        Used internally. Sets the data buffer for a drop data transfer.
+    */
+    void SetDataBuffer( void* buf );
+    
+    /**
+        Gets the data buffer for a drop data transfer.
     */
-    wxDataObject *GetDataObject();
+    void *GetDataBuffer() const;
 };
 
index b533b57bdb141103e0765da9bfe30cdefce304eb..0df4c89a4b85f823065bbe536eab22c6ff0fa81d 100644 (file)
@@ -670,6 +670,8 @@ public:
     void OnAddMany( wxCommandEvent &event);
     
     void OnBeginDrag( wxDataViewEvent &event );
+    void OnDropPossible( wxDataViewEvent &event );
+    void OnDrop( wxDataViewEvent &event );
 
 private:
     wxDataViewCtrl* m_musicCtrl;
@@ -767,6 +769,8 @@ BEGIN_EVENT_TABLE(MyFrame, wxFrame)
     EVT_DATAVIEW_ITEM_CONTEXT_MENU(ID_MUSIC_CTRL, MyFrame::OnContextMenu)
     
     EVT_DATAVIEW_ITEM_BEGIN_DRAG( ID_MUSIC_CTRL, MyFrame::OnBeginDrag )
+    EVT_DATAVIEW_ITEM_DROP_POSSIBLE( ID_MUSIC_CTRL, MyFrame::OnDropPossible )
+    EVT_DATAVIEW_ITEM_DROP( ID_MUSIC_CTRL, MyFrame::OnDrop )
 
     EVT_RIGHT_UP(MyFrame::OnRightClick)
 END_EVENT_TABLE()
@@ -807,6 +811,7 @@ MyFrame::MyFrame(wxFrame *frame, const wxString &title, int x, int y, int w, int
     m_musicCtrl->AssociateModel( m_music_model.get() );
     
     m_musicCtrl->EnableDragSource( wxDF_TEXT );
+    m_musicCtrl->EnableDropTarget( wxDF_TEXT );
 
     wxDataViewTextRenderer *tr = new wxDataViewTextRenderer( wxT("string"), wxDATAVIEW_CELL_INERT );
     wxDataViewColumn *column0 = new wxDataViewColumn( wxT("title"), tr, 0, 200, wxALIGN_LEFT,
@@ -1171,3 +1176,33 @@ void MyFrame::OnBeginDrag( wxDataViewEvent &event )
     obj->SetText( node->m_title );
     event.SetDataObject( obj );
 }
+
+void MyFrame::OnDropPossible( wxDataViewEvent &event )
+{
+    wxDataViewItem item( event.GetItem() );
+        
+    // only allow drags for item, not containers
+    if (m_music_model->IsContainer( item ) )
+        event.Veto();
+    
+    if (event.GetDataFormat() != wxDF_TEXT)
+        event.Veto();
+}
+
+void MyFrame::OnDrop( wxDataViewEvent &event )
+{
+    wxDataViewItem item( event.GetItem() );
+        
+    // only allow drags for item, not containers
+    if (m_music_model->IsContainer( item ) )
+        event.Veto();
+    
+    if (event.GetDataFormat() != wxDF_TEXT)
+        event.Veto();
+        
+    wxTextDataObject obj;
+    obj.SetData( wxDF_TEXT, event.GetDataSize(), event.GetDataBuffer() );
+    
+    wxLogMessage(wxT("Text dropped: %s"), obj.GetText() );
+}
+
index 2bc6102f0f0c612226d67435cc3b99020376b7b3..39d6ba8b8e23b02977c6550d5ee57715f96054c2 100644 (file)
@@ -901,6 +901,11 @@ bool wxDataViewCtrlBase::EnableDragSource( const wxDataFormat &WXUNUSED(format)
     return false;
 }
 
+bool wxDataViewCtrlBase::EnableDropTarget( const wxDataFormat &WXUNUSED(format) )
+{
+    return false;
+}
+
 void wxDataViewCtrlBase::ExpandAncestors( const wxDataViewItem & item )
 {
     if (!m_model) return;
@@ -1236,6 +1241,8 @@ wxDEFINE_EVENT( wxEVT_COMMAND_DATAVIEW_COLUMN_SORTED, wxDataViewEvent )
 wxDEFINE_EVENT( wxEVT_COMMAND_DATAVIEW_COLUMN_REORDERED, wxDataViewEvent )
 
 wxDEFINE_EVENT( wxEVT_COMMAND_DATAVIEW_ITEM_BEGIN_DRAG, wxDataViewEvent )
+wxDEFINE_EVENT( wxEVT_COMMAND_DATAVIEW_ITEM_DROP_POSSIBLE, wxDataViewEvent )
+wxDEFINE_EVENT( wxEVT_COMMAND_DATAVIEW_ITEM_DROP, wxDataViewEvent )
 
 // -------------------------------------
 // wxDataViewSpinRenderer
index 62eb070d42cbc7b838f73c8ea127e28883776e8e..5c9c64c115d03c54315c1c5699034d3320bd4e33 100644 (file)
@@ -76,6 +76,7 @@ public:
     // dnd iface
    
     bool EnableDragSource( const wxDataFormat &format );
+    bool EnableDropTarget( const wxDataFormat &format );
     
     gboolean row_draggable( GtkTreeDragSource *drag_source, GtkTreePath *path );
     gboolean drag_data_delete( GtkTreeDragSource *drag_source, GtkTreePath* path );
@@ -127,9 +128,13 @@ private:
     GtkSortType           m_sort_order;
     wxDataViewColumn     *m_dataview_sort_column;
     int                   m_sort_column;
+    
     GtkTargetEntry        m_dragSourceTargetEntry;
     wxCharBuffer          m_dragSourceTargetEntryTarget;
     wxDataObject         *m_dragDataObject;
+    
+    GtkTargetEntry        m_dropTargetTargetEntry;
+    wxCharBuffer          m_dropTargetTargetEntryTarget;
     wxDataObject         *m_dropDataObject;
 };
 
@@ -2941,6 +2946,21 @@ bool wxDataViewCtrlInternal::EnableDragSource( const wxDataFormat &format )
     return true;
 }
 
+bool wxDataViewCtrlInternal::EnableDropTarget( const wxDataFormat &format )
+{
+    wxGtkString atom_str( gdk_atom_name( format  ) );
+    m_dropTargetTargetEntryTarget = wxCharBuffer( atom_str );
+    
+    m_dropTargetTargetEntry.target =  m_dragSourceTargetEntryTarget.data();
+    m_dropTargetTargetEntry.flags = 0;
+    m_dropTargetTargetEntry.info = static_cast<guint>(-1);
+    
+    gtk_tree_view_enable_model_drag_dest( GTK_TREE_VIEW(m_owner->GtkGetTreeView() ),
+       &m_dropTargetTargetEntry, 1, (GdkDragAction) GDK_ACTION_COPY );
+       
+    return true;
+}
+
 gboolean wxDataViewCtrlInternal::row_draggable( GtkTreeDragSource *WXUNUSED(drag_source),
     GtkTreePath *path )
 {
@@ -2951,6 +2971,7 @@ gboolean wxDataViewCtrlInternal::row_draggable( GtkTreeDragSource *WXUNUSED(drag
     wxDataViewItem item( (void*) iter.user_data );
 
     wxDataViewEvent event( wxEVT_COMMAND_DATAVIEW_ITEM_BEGIN_DRAG, m_owner->GetId() );
+    event.SetEventObject( m_owner );
     event.SetItem( item );
     event.SetModel( m_wx_model );
     if (!m_owner->HandleWindowEvent( event ))
@@ -3007,18 +3028,50 @@ gboolean wxDataViewCtrlInternal::drag_data_get( GtkTreeDragSource *WXUNUSED(drag
 
 gboolean
 wxDataViewCtrlInternal::drag_data_received(GtkTreeDragDest *WXUNUSED(drag_dest),
-                                           GtkTreePath *WXUNUSED(dest),
-                                           GtkSelectionData *WXUNUSED(selection_data))
+                                           GtkTreePath *path,
+                                           GtkSelectionData *selection_data)
 {
-    return FALSE;
+    GtkTreeIter iter;
+    if (!get_iter( &iter, path )) return FALSE;
+    wxDataViewItem item( (void*) iter.user_data );
+    
+    wxDataViewEvent event( wxEVT_COMMAND_DATAVIEW_ITEM_DROP, m_owner->GetId() );
+    event.SetEventObject( m_owner );
+    event.SetItem( item );
+    event.SetModel( m_wx_model );
+    event.SetDataFormat( selection_data->target );
+    event.SetDataSize( selection_data->length );
+    event.SetDataBuffer( selection_data->data );
+    if (!m_owner->HandleWindowEvent( event ))
+        return FALSE;
+        
+    if (!event.IsAllowed())
+        return FALSE;
+
+    return TRUE;
 }
 
 gboolean
 wxDataViewCtrlInternal::row_drop_possible(GtkTreeDragDest *WXUNUSED(drag_dest),
-                                          GtkTreePath *WXUNUSED(dest_path),
-                                          GtkSelectionData *WXUNUSED(selection_data))
+                                          GtkTreePath *path,
+                                          GtkSelectionData *selection_data)
 {
-    return FALSE;
+    GtkTreeIter iter;
+    if (!get_iter( &iter, path )) return FALSE;
+    wxDataViewItem item( (void*) iter.user_data );
+    
+    wxDataViewEvent event( wxEVT_COMMAND_DATAVIEW_ITEM_DROP_POSSIBLE, m_owner->GetId() );
+    event.SetEventObject( m_owner );
+    event.SetItem( item );
+    event.SetModel( m_wx_model );
+    event.SetDataFormat( selection_data->target );
+    if (!m_owner->HandleWindowEvent( event ))
+        return FALSE;
+        
+    if (!event.IsAllowed())
+        return FALSE;
+    
+    return TRUE;
 }
 
 // notifications from wxDataViewModel
@@ -3910,6 +3963,11 @@ bool wxDataViewCtrl::EnableDragSource( const wxDataFormat &format )
     return m_internal->EnableDragSource( format );
 }
 
+bool wxDataViewCtrl::EnableDropTarget( const wxDataFormat &format )
+{
+    return m_internal->EnableDropTarget( format );
+}
+
 bool wxDataViewCtrl::AppendColumn( wxDataViewColumn *col )
 {
     if (!wxDataViewCtrlBase::AppendColumn(col))