New eventb based Drag interface for wxDataViewCtrl

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@58236 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Robert Roebling
2009-01-19 22:27:06 +00:00
parent 304a807af9
commit 15cac64f75
5 changed files with 141 additions and 66 deletions

View File

@@ -193,15 +193,6 @@ public:
{ return false; } { return false; }
virtual unsigned int GetChildren( const wxDataViewItem &item, wxDataViewItemArray &children ) const = 0; 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 // delegated notifiers
virtual bool ItemAdded( const wxDataViewItem &parent, const wxDataViewItem &item ); virtual bool ItemAdded( const wxDataViewItem &parent, const wxDataViewItem &item );
virtual bool ItemsAdded( const wxDataViewItem &parent, const wxDataViewItemArray &items ); virtual bool ItemsAdded( const wxDataViewItem &parent, const wxDataViewItemArray &items );
@@ -723,6 +714,8 @@ public:
virtual void HitTest( const wxPoint & point, wxDataViewItem &item, wxDataViewColumn* &column ) const = 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 wxRect GetItemRect( const wxDataViewItem & item, const wxDataViewColumn *column = NULL ) const = 0;
virtual bool EnableDragSource( const wxDataFormat &format );
protected: protected:
virtual void DoSetExpanderColumn() = 0 ; virtual void DoSetExpanderColumn() = 0 ;
virtual void DoSetIndent() = 0; virtual void DoSetIndent() = 0;
@@ -750,7 +743,9 @@ public:
m_model(NULL), m_model(NULL),
m_value(wxNullVariant), m_value(wxNullVariant),
m_column(NULL), m_column(NULL),
m_pos(-1,-1) m_pos(-1,-1),
m_isDraggable(false),
m_dragDataSize(-1)
{ } { }
wxDataViewEvent(const wxDataViewEvent& event) wxDataViewEvent(const wxDataViewEvent& event)
@@ -760,7 +755,9 @@ public:
m_model(event.m_model), m_model(event.m_model),
m_value(event.m_value), m_value(event.m_value),
m_column(event.m_column), 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; } wxDataViewItem GetItem() const { return m_item; }
@@ -783,6 +780,16 @@ public:
wxPoint GetPosition() const { return m_pos; } wxPoint GetPosition() const { return m_pos; }
void SetPosition( int x, int y ) { m_pos.x = x; m_pos.y = y; } 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); } virtual wxEvent *Clone() const { return new wxDataViewEvent(*this); }
protected: protected:
@@ -793,6 +800,11 @@ protected:
wxDataViewColumn *m_column; wxDataViewColumn *m_column;
wxPoint m_pos; wxPoint m_pos;
bool m_isDraggable;
int m_dragDataSize;
void *m_dragDataBuffer;
wxDataFormat m_dataFormat;
private: private:
DECLARE_DYNAMIC_CLASS_NO_ASSIGN(wxDataViewEvent) 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_SORTED, wxDataViewEvent )
wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_ADV, wxEVT_COMMAND_DATAVIEW_COLUMN_REORDERED, 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&); typedef void (wxEvtHandler::*wxDataViewEventFunction)(wxDataViewEvent&);
#define wxDataViewEventHandler(func) \ #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_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_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 #ifdef wxHAS_GENERIC_DATAVIEWCTRL
// this symbol doesn't follow the convention for wxUSE_XXX symbols which // this symbol doesn't follow the convention for wxUSE_XXX symbols which

View File

@@ -428,9 +428,10 @@ public:
virtual void Expand( const wxDataViewItem & item ); virtual void Expand( const wxDataViewItem & item );
virtual void Collapse( const wxDataViewItem & item ); virtual void Collapse( const wxDataViewItem & item );
virtual bool IsExpanded( const wxDataViewItem & item ) const; virtual bool IsExpanded( const wxDataViewItem & item ) const;
virtual bool EnableDragSource( const wxDataFormat &format );
static wxVisualAttributes static wxVisualAttributes
GetClassDefaultAttributes(wxWindowVariant variant = wxWINDOW_VARIANT_NORMAL); GetClassDefaultAttributes(wxWindowVariant variant = wxWINDOW_VARIANT_NORMAL);

View File

@@ -378,38 +378,6 @@ public:
return count; 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() wxDataViewItem GetNinthItem()
{ {
return wxDataViewItem( m_ninth ); return wxDataViewItem( m_ninth );
@@ -701,6 +669,11 @@ public:
void OnGoto( wxCommandEvent &event); void OnGoto( wxCommandEvent &event);
void OnAddMany( wxCommandEvent &event); void OnAddMany( wxCommandEvent &event);
// DnD
void OnDraggable( wxDataViewEvent &event );
void OnGetDragDataSize( wxDataViewEvent &event );
void OnGetDragData( wxDataViewEvent &event );
private: private:
wxDataViewCtrl* m_musicCtrl; wxDataViewCtrl* m_musicCtrl;
wxObjectDataPtr<MyMusicModel> m_music_model; wxObjectDataPtr<MyMusicModel> m_music_model;
@@ -796,6 +769,10 @@ BEGIN_EVENT_TABLE(MyFrame, wxFrame)
EVT_DATAVIEW_ITEM_CONTEXT_MENU(ID_MUSIC_CTRL, MyFrame::OnContextMenu) 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) EVT_RIGHT_UP(MyFrame::OnRightClick)
END_EVENT_TABLE() END_EVENT_TABLE()
@@ -834,6 +811,8 @@ MyFrame::MyFrame(wxFrame *frame, const wxString &title, int x, int y, int w, int
m_music_model = new MyMusicModel; m_music_model = new MyMusicModel;
m_musicCtrl->AssociateModel( m_music_model.get() ); m_musicCtrl->AssociateModel( m_music_model.get() );
m_musicCtrl->EnableDragSource( wxDF_TEXT );
wxDataViewTextRenderer *tr = new wxDataViewTextRenderer( wxT("string"), wxDATAVIEW_CELL_INERT ); wxDataViewTextRenderer *tr = new wxDataViewTextRenderer( wxT("string"), wxDATAVIEW_CELL_INERT );
wxDataViewColumn *column0 = new wxDataViewColumn( wxT("title"), tr, 0, 200, wxALIGN_LEFT, wxDataViewColumn *column0 = new wxDataViewColumn( wxT("title"), tr, 0, 200, wxALIGN_LEFT,
wxDATAVIEW_COL_SORTABLE | wxDATAVIEW_COL_RESIZABLE ); wxDATAVIEW_COL_SORTABLE | wxDATAVIEW_COL_RESIZABLE );
@@ -1175,9 +1154,47 @@ void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event) )
{ {
wxAboutDialogInfo info; wxAboutDialogInfo info;
info.SetName(_("DataView sample")); info.SetName(_("DataView sample"));
info.SetDescription(_("This sample demonstrates the dataview control handling")); info.SetDescription(_("This sample demonstrates wxDataViewCtrl"));
info.SetCopyright(_T("(C) 2007 Robert Roebling")); info.SetCopyright(_T("(C) 2007-2009 Robert Roebling"));
wxAboutBox(info); 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();
}

View File

@@ -896,6 +896,11 @@ const wxDataViewModel* wxDataViewCtrlBase::GetModel() const
return m_model; return m_model;
} }
bool wxDataViewCtrlBase::EnableDragSource( const wxDataFormat &WXUNUSED(format) )
{
return false;
}
void wxDataViewCtrlBase::ExpandAncestors( const wxDataViewItem & item ) void wxDataViewCtrlBase::ExpandAncestors( const wxDataViewItem & item )
{ {
if (!m_model) return; 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_SORTED, wxDataViewEvent )
wxDEFINE_EVENT( wxEVT_COMMAND_DATAVIEW_COLUMN_REORDERED, 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 // wxDataViewSpinRenderer

View File

@@ -74,6 +74,9 @@ public:
gboolean iter_parent( GtkTreeIter *iter, GtkTreeIter *child ); gboolean iter_parent( GtkTreeIter *iter, GtkTreeIter *child );
// dnd iface // dnd iface
bool EnableDragSource( const wxDataFormat &format );
gboolean row_draggable( GtkTreeDragSource *drag_source, GtkTreePath *path ); gboolean row_draggable( GtkTreeDragSource *drag_source, GtkTreePath *path );
gboolean drag_data_delete( GtkTreeDragSource *drag_source, GtkTreePath* path ); gboolean drag_data_delete( GtkTreeDragSource *drag_source, GtkTreePath* path );
gboolean drag_data_get( GtkTreeDragSource *drag_source, GtkTreePath *path, gboolean drag_data_get( GtkTreeDragSource *drag_source, GtkTreePath *path,
@@ -124,6 +127,8 @@ private:
GtkSortType m_sort_order; GtkSortType m_sort_order;
wxDataViewColumn *m_dataview_sort_column; wxDataViewColumn *m_dataview_sort_column;
int m_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 ); wxString wxtype = wxtree_model->internal->GetDataViewModel()->GetColumnType( (unsigned int) index );
wxPrintf( "get_column_type %s\n", wxtype );
if (wxtype == wxT("string")) if (wxtype == wxT("string"))
gtype = G_TYPE_STRING; gtype = G_TYPE_STRING;
else else
@@ -2911,15 +2918,34 @@ void wxDataViewCtrlInternal::BuildBranch( wxGtkTreeModelNode *node )
// GTK+ dnd iface // 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), gboolean wxDataViewCtrlInternal::row_draggable( GtkTreeDragSource *WXUNUSED(drag_source),
GtkTreePath *path ) GtkTreePath *path )
{ {
GtkTreeIter iter; GtkTreeIter iter;
if (!get_iter( &iter, path )) return FALSE; if (!get_iter( &iter, path )) return FALSE;
wxDataViewItem item( (void*) iter.user_data ); 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 gboolean
@@ -2934,24 +2960,31 @@ gboolean wxDataViewCtrlInternal::drag_data_get( GtkTreeDragSource *WXUNUSED(drag
{ {
GtkTreeIter iter; GtkTreeIter iter;
if (!get_iter( &iter, path )) return FALSE; if (!get_iter( &iter, path )) return FALSE;
wxDataViewItem item( (void*) iter.user_data ); wxDataViewItem item( (void*) iter.user_data );
wxDataFormat format( selection_data->target ); wxDataViewEvent event( wxEVT_COMMAND_DATAVIEW_ITEM_GET_DRAG_DATA_SIZE, m_owner->GetId() );
event.SetItem( item );
size_t size = m_wx_model->GetDragDataSize( item, format ); event.SetModel( m_wx_model );
if (size == 0) return FALSE; 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 ); void *data = malloc( size );
m_wx_model->GetDragData( item, format, 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, gtk_selection_data_set( selection_data, selection_data->target,
8, (const guchar*) data, size ); 8, (const guchar*) data, size );
res = TRUE;
}
free( data ); free( data );
return TRUE; return res;
} }
gboolean gboolean
@@ -3709,8 +3742,6 @@ void wxDataViewCtrl::Init()
m_cols.DeleteContents( true ); m_cols.DeleteContents( true );
} }
static GtkTargetEntry gs_target;
bool wxDataViewCtrl::Create(wxWindow *parent, wxWindowID id, bool wxDataViewCtrl::Create(wxWindow *parent, wxWindowID id,
const wxPoint& pos, const wxSize& size, const wxPoint& pos, const wxSize& size,
long style, const wxValidator& validator ) long style, const wxValidator& validator )
@@ -3735,12 +3766,6 @@ bool wxDataViewCtrl::Create(wxWindow *parent, wxWindowID id,
g_signal_connect (m_treeview, "size_allocate", g_signal_connect (m_treeview, "size_allocate",
G_CALLBACK (gtk_dataviewctrl_size_callback), this); 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__ #ifdef __WXGTK26__
if (!gtk_check_version(2,6,0)) if (!gtk_check_version(2,6,0))
{ {
@@ -3862,6 +3887,11 @@ bool wxDataViewCtrl::AssociateModel( wxDataViewModel *model )
return true; return true;
} }
bool wxDataViewCtrl::EnableDragSource( const wxDataFormat &format )
{
return m_internal->EnableDragSource( format );
}
bool wxDataViewCtrl::AppendColumn( wxDataViewColumn *col ) bool wxDataViewCtrl::AppendColumn( wxDataViewColumn *col )
{ {
if (!wxDataViewCtrlBase::AppendColumn(col)) if (!wxDataViewCtrlBase::AppendColumn(col))