Implement icon text column using native GTK renderers in wxDVC.

This has a possible advantage of a more native look and feel (although it's
hard to tell the difference between drawing the icon ourselves and how the
default GTK+ renderer does it to be honest) and a very real advantage of
allowing to edit in place cells with icons. It also reduces code duplication
in GTK implementation.

Modify the sample to make the icon-text column in the list model editable to
show that it works. This required storing the values of the second column as
well, so do it in its own array and to avoid calling it "m_array2", rename the
existing m_array to m_textColValues (which accounts for most of the diff in
the sample) and call the new one m_iconColValues.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@62423 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin
2009-10-16 01:29:06 +00:00
parent 7bade612f0
commit 205bdf2069
5 changed files with 220 additions and 149 deletions

View File

@@ -19,6 +19,7 @@
class WXDLLIMPEXP_FWD_ADV wxDataViewCtrl; class WXDLLIMPEXP_FWD_ADV wxDataViewCtrl;
class WXDLLIMPEXP_FWD_ADV wxDataViewCtrlInternal; class WXDLLIMPEXP_FWD_ADV wxDataViewCtrlInternal;
typedef struct _GtkTreeViewColumn GtkTreeViewColumn;
// --------------------------------------------------------- // ---------------------------------------------------------
// wxDataViewRenderer // wxDataViewRenderer
@@ -37,7 +38,22 @@ public:
virtual void SetAlignment( int align ); virtual void SetAlignment( int align );
virtual int GetAlignment() const; virtual int GetAlignment() const;
// implementation
// GTK-specific implementation
// ---------------------------
// pack the GTK cell renderers used by this renderer to the given column
//
// by default only a single m_renderer is used but some renderers use more
// than one GTK cell renderer
virtual void GtkPackIntoColumn(GtkTreeViewColumn *column);
// called when the cell value was edited by user with the new value
//
// it validates the new value and notifies the model about the change by
// calling GtkOnCellChanged() if it was accepted
void GtkOnTextEdited(const gchar *itempath, const wxString& value);
GtkCellRenderer* GetGtkHandle() { return m_renderer; } GtkCellRenderer* GetGtkHandle() { return m_renderer; }
void GtkInitHandlers(); void GtkInitHandlers();
void GtkUpdateAlignment(); void GtkUpdateAlignment();
@@ -46,6 +62,11 @@ public:
void GtkSetUsingDefaultAttrs(bool def) { m_usingDefaultAttrs = def; } void GtkSetUsingDefaultAttrs(bool def) { m_usingDefaultAttrs = def; }
protected: protected:
virtual void GtkOnCellChanged(const wxVariant& value,
const wxDataViewItem& item,
unsigned col);
GtkCellRenderer *m_renderer; GtkCellRenderer *m_renderer;
int m_alignment; int m_alignment;
@@ -68,12 +89,30 @@ public:
wxDataViewCellMode mode = wxDATAVIEW_CELL_INERT, wxDataViewCellMode mode = wxDATAVIEW_CELL_INERT,
int align = wxDVR_DEFAULT_ALIGNMENT ); int align = wxDVR_DEFAULT_ALIGNMENT );
bool SetValue( const wxVariant &value ); virtual bool SetValue( const wxVariant &value )
bool GetValue( wxVariant &value ) const; {
return SetTextValue(value);
}
void SetAlignment( int align ); virtual bool GetValue( wxVariant &value ) const
{
wxString str;
if ( !GetTextValue(str) )
return false;
value = str;
return true;
}
virtual void SetAlignment( int align );
protected: protected:
// implementation of Set/GetValue()
bool SetTextValue(const wxString& str);
bool GetTextValue(wxString& str) const;
DECLARE_DYNAMIC_CLASS_NO_COPY(wxDataViewTextRenderer) DECLARE_DYNAMIC_CLASS_NO_COPY(wxDataViewTextRenderer)
}; };
@@ -156,7 +195,7 @@ private:
wxDC *m_dc; wxDC *m_dc;
public: public:
// Internal, temporay for RenderText. // Internal, temporary for RenderText.
GtkCellRenderer *m_text_renderer; GtkCellRenderer *m_text_renderer;
GdkWindow *window; GdkWindow *window;
GtkWidget *widget; GtkWidget *widget;
@@ -200,7 +239,7 @@ protected:
// wxDataViewIconTextRenderer // wxDataViewIconTextRenderer
// --------------------------------------------------------- // ---------------------------------------------------------
class WXDLLIMPEXP_ADV wxDataViewIconTextRenderer: public wxDataViewCustomRenderer class WXDLLIMPEXP_ADV wxDataViewIconTextRenderer: public wxDataViewTextRenderer
{ {
public: public:
wxDataViewIconTextRenderer( const wxString &varianttype = wxT("wxDataViewIconText"), wxDataViewIconTextRenderer( const wxString &varianttype = wxT("wxDataViewIconText"),
@@ -211,17 +250,19 @@ public:
bool SetValue( const wxVariant &value ); bool SetValue( const wxVariant &value );
bool GetValue( wxVariant &value ) const; bool GetValue( wxVariant &value ) const;
virtual bool Render( wxRect cell, wxDC *dc, int state ); virtual void GtkPackIntoColumn(GtkTreeViewColumn *column);
virtual wxSize GetSize() const;
virtual bool HasEditorCtrl() const { return true; } protected:
virtual wxControl* CreateEditorCtrl( wxWindow *parent, wxRect labelRect, const wxVariant &value ); virtual void GtkOnCellChanged(const wxVariant& value,
virtual bool GetValueFromEditorCtrl( wxControl* editor, wxVariant &value ); const wxDataViewItem& item,
unsigned col);
private: private:
wxDataViewIconText m_value; wxDataViewIconText m_value;
protected: // we use the base class m_renderer for the text and this one for the icon
GtkCellRenderer *m_rendererIcon;
DECLARE_DYNAMIC_CLASS_NO_COPY(wxDataViewIconTextRenderer) DECLARE_DYNAMIC_CLASS_NO_COPY(wxDataViewIconTextRenderer)
}; };

View File

@@ -545,13 +545,8 @@ void MyFrame::BuildDataViewCtrl(wxPanel* parent, unsigned int nPanel, unsigned l
m_ctrl[1]->AssociateModel( m_list_model.get() ); m_ctrl[1]->AssociateModel( m_list_model.get() );
// the various columns // the various columns
#if 1
m_ctrl[1]->AppendTextColumn("editable string", 0, wxDATAVIEW_CELL_EDITABLE, 120);
m_ctrl[1]->AppendIconTextColumn(wxIcon(wx_small_xpm), 1, wxDATAVIEW_CELL_INERT )->SetTitle( "icon");
#else
m_ctrl[1]->AppendTextColumn("editable string", 0, wxDATAVIEW_CELL_EDITABLE); m_ctrl[1]->AppendTextColumn("editable string", 0, wxDATAVIEW_CELL_EDITABLE);
m_ctrl[1]->AppendIconTextColumn("icon", 1, wxDATAVIEW_CELL_INERT); m_ctrl[1]->AppendIconTextColumn("icon", 1, wxDATAVIEW_CELL_EDITABLE);
#endif
m_ctrl[1]->AppendColumn( m_ctrl[1]->AppendColumn(
new wxDataViewColumn("attributes", new wxDataViewTextRenderer, 2 )); new wxDataViewColumn("attributes", new wxDataViewTextRenderer, 2 ));
} }

View File

@@ -334,31 +334,34 @@ MyListModel::MyListModel() :
m_virtualItems = INITIAL_NUMBER_OF_ITEMS; m_virtualItems = INITIAL_NUMBER_OF_ITEMS;
// the first 100 items are really stored in this model; // the first 100 items are really stored in this model;
// all the others are synthetized on request // all the others are synthesized on request
for (unsigned int i = 0; i < 100; i++) static const unsigned NUMBER_REAL_ITEMS = 100;
m_textColValues.reserve(NUMBER_REAL_ITEMS);
for (unsigned int i = 0; i < NUMBER_REAL_ITEMS; i++)
{ {
wxString str; m_textColValues.push_back(wxString::Format("real row %d", i));
str.Printf( "real row %d", i );
m_array.Add( str );
} }
m_iconColValues.assign(NUMBER_REAL_ITEMS, "test");
m_icon[0] = wxIcon( null_xpm ); m_icon[0] = wxIcon( null_xpm );
m_icon[1] = wxIcon( wx_small_xpm ); m_icon[1] = wxIcon( wx_small_xpm );
} }
void MyListModel::Prepend( const wxString &text ) void MyListModel::Prepend( const wxString &text )
{ {
m_array.Insert( text, 0 ); m_textColValues.Insert( text, 0 );
RowPrepended(); RowPrepended();
} }
void MyListModel::DeleteItem( const wxDataViewItem &item ) void MyListModel::DeleteItem( const wxDataViewItem &item )
{ {
unsigned int row = GetRow( item ); unsigned int row = GetRow( item );
if (row >= m_array.GetCount()) if (row >= m_textColValues.GetCount())
return; return;
m_array.RemoveAt( row ); m_textColValues.RemoveAt( row );
RowDeleted( row ); RowDeleted( row );
} }
@@ -369,7 +372,7 @@ void MyListModel::DeleteItems( const wxDataViewItemArray &items )
for (i = 0; i < items.GetCount(); i++) for (i = 0; i < items.GetCount(); i++)
{ {
unsigned int row = GetRow( items[i] ); unsigned int row = GetRow( items[i] );
if (row < m_array.GetCount()) if (row < m_textColValues.GetCount())
rows.Add( row ); rows.Add( row );
} }
@@ -377,7 +380,7 @@ void MyListModel::DeleteItems( const wxDataViewItemArray &items )
{ {
// none of the selected items were in the range of the items // none of the selected items were in the range of the items
// which we store... for simplicity, don't allow removing them // which we store... for simplicity, don't allow removing them
wxLogError( "Cannot remove rows with an index greater than %d", m_array.GetCount() ); wxLogError( "Cannot remove rows with an index greater than %d", m_textColValues.GetCount() );
return; return;
} }
@@ -386,7 +389,7 @@ void MyListModel::DeleteItems( const wxDataViewItemArray &items )
// remaining indeces would all be wrong. // remaining indeces would all be wrong.
rows.Sort( my_sort_reverse ); rows.Sort( my_sort_reverse );
for (i = 0; i < rows.GetCount(); i++) for (i = 0; i < rows.GetCount(); i++)
m_array.RemoveAt( rows[i] ); m_textColValues.RemoveAt( rows[i] );
// This is just to test if wxDataViewCtrl can // This is just to test if wxDataViewCtrl can
// cope with removing rows not sorted in // cope with removing rows not sorted in
@@ -398,7 +401,7 @@ void MyListModel::DeleteItems( const wxDataViewItemArray &items )
void MyListModel::AddMany() void MyListModel::AddMany()
{ {
m_virtualItems += 1000; m_virtualItems += 1000;
Reset( m_array.GetCount() + m_virtualItems ); Reset( m_textColValues.GetCount() + m_virtualItems );
} }
void MyListModel::GetValueByRow( wxVariant &variant, void MyListModel::GetValueByRow( wxVariant &variant,
@@ -406,15 +409,20 @@ void MyListModel::GetValueByRow( wxVariant &variant,
{ {
if (col==0) if (col==0)
{ {
if (row >= m_array.GetCount()) if (row >= m_textColValues.GetCount())
variant = wxString::Format( "virtual row %d", row ); variant = wxString::Format( "virtual row %d", row );
else else
variant = m_array[ row ]; variant = m_textColValues[ row ];
} }
else if (col==1) else if (col==1)
{ {
wxDataViewIconText data( "test", m_icon[ row%2 ] ); wxString text;
variant << data; if ( row >= m_iconColValues.GetCount() )
text = "virtual icon";
else
text = m_iconColValues[row];
variant << wxDataViewIconText(text, m_icon[row % 2]);
} }
else if (col==2) else if (col==2)
{ {
@@ -474,19 +482,35 @@ bool MyListModel::GetAttrByRow( unsigned int row, unsigned int col,
bool MyListModel::SetValueByRow( const wxVariant &variant, bool MyListModel::SetValueByRow( const wxVariant &variant,
unsigned int row, unsigned int col ) unsigned int row, unsigned int col )
{ {
if (col == 0) switch ( col )
{ {
if (row >= m_array.GetCount()) case 0:
case 1:
if (row >= m_textColValues.GetCount())
{ {
// the item is not in the range of the items // the item is not in the range of the items
// which we store... for simplicity, don't allow editing it // which we store... for simplicity, don't allow editing it
wxLogError( "Cannot edit rows with an index greater than %d", m_array.GetCount() ); wxLogError( "Cannot edit rows with an index greater than %d",
m_textColValues.GetCount() );
return false;
}
if ( col == 0 )
{
m_textColValues[row] = variant.GetString();
}
else // col == 1
{
wxDataViewIconText iconText;
iconText << variant;
m_iconColValues[row] = iconText.GetText();
}
break;
default:
wxLogError("Cannot edit the column %d", col);
return false; return false;
} }
m_array[row] = variant.GetString();
return true; return true;
}
return false;
} }

View File

@@ -215,7 +215,7 @@ public:
virtual unsigned int GetRowCount() virtual unsigned int GetRowCount()
{ {
return m_array.GetCount(); return m_textColValues.GetCount();
} }
virtual void GetValueByRow( wxVariant &variant, virtual void GetValueByRow( wxVariant &variant,
@@ -225,7 +225,8 @@ public:
unsigned int row, unsigned int col ); unsigned int row, unsigned int col );
private: private:
wxArrayString m_array; wxArrayString m_textColValues;
wxArrayString m_iconColValues;
wxIcon m_icon[2]; wxIcon m_icon[2];
int m_virtualItems; int m_virtualItems;
}; };

View File

@@ -1560,6 +1560,11 @@ wxDataViewRenderer::wxDataViewRenderer( const wxString &varianttype, wxDataViewC
// after the m_renderer pointer has been initialized // after the m_renderer pointer has been initialized
} }
void wxDataViewRenderer::GtkPackIntoColumn(GtkTreeViewColumn *column)
{
gtk_tree_view_column_pack_end( column, m_renderer, TRUE /* expand */);
}
void wxDataViewRenderer::GtkInitHandlers() void wxDataViewRenderer::GtkInitHandlers()
{ {
if (!gtk_check_version(2,6,0)) if (!gtk_check_version(2,6,0))
@@ -1686,37 +1691,48 @@ int wxDataViewRenderer::GetAlignment() const
return m_alignment; return m_alignment;
} }
void
wxDataViewRenderer::GtkOnTextEdited(const gchar *itempath, const wxString& str)
{
wxVariant value(str);
if (!Validate( value ))
return;
GtkTreePath *path = gtk_tree_path_new_from_string( itempath );
GtkTreeIter iter;
GetOwner()->GetOwner()->GtkGetInternal()->get_iter( &iter, path );
wxDataViewItem item( (void*) iter.user_data );;
gtk_tree_path_free( path );
GtkOnCellChanged(value, item, GetOwner()->GetModelColumn());
}
void
wxDataViewRenderer::GtkOnCellChanged(const wxVariant& value,
const wxDataViewItem& item,
unsigned col)
{
wxDataViewModel *model = GetOwner()->GetOwner()->GetModel();
model->SetValue( value, item, col );
model->ValueChanged( item, col );
}
// --------------------------------------------------------- // ---------------------------------------------------------
// wxDataViewTextRenderer // wxDataViewTextRenderer
// --------------------------------------------------------- // ---------------------------------------------------------
extern "C" { extern "C"
static void wxGtkTextRendererEditedCallback( GtkCellRendererText *renderer, {
gchar *arg1, gchar *arg2, gpointer user_data );
}
static void wxGtkTextRendererEditedCallback( GtkCellRendererText *WXUNUSED(renderer), static void wxGtkTextRendererEditedCallback( GtkCellRendererText *WXUNUSED(renderer),
gchar *arg1, gchar *arg2, gpointer user_data ) gchar *arg1, gchar *arg2, gpointer user_data )
{ {
wxDataViewRenderer *cell = (wxDataViewRenderer*) user_data; wxDataViewRenderer *cell = (wxDataViewRenderer*) user_data;
wxString tmp = wxGTK_CONV_BACK_FONT(arg2, cell->GetOwner()->GetOwner()->GetFont()); cell->GtkOnTextEdited(arg1, wxGTK_CONV_BACK_FONT(
wxVariant value = tmp; arg2, cell->GetOwner()->GetOwner()->GetFont()));
if (!cell->Validate( value )) }
return;
wxDataViewModel *model = cell->GetOwner()->GetOwner()->GetModel();
GtkTreePath *path = gtk_tree_path_new_from_string( arg1 );
GtkTreeIter iter;
cell->GetOwner()->GetOwner()->GtkGetInternal()->get_iter( &iter, path );
wxDataViewItem item( (void*) iter.user_data );;
gtk_tree_path_free( path );
unsigned int model_col = cell->GetOwner()->GetModelColumn();
model->SetValue( value, item, model_col );
model->ValueChanged( item, model_col );
} }
IMPLEMENT_CLASS(wxDataViewTextRenderer, wxDataViewRenderer) IMPLEMENT_CLASS(wxDataViewTextRenderer, wxDataViewRenderer)
@@ -1746,29 +1762,25 @@ wxDataViewTextRenderer::wxDataViewTextRenderer( const wxString &varianttype, wxD
SetAlignment(align); SetAlignment(align);
} }
bool wxDataViewTextRenderer::SetValue( const wxVariant &value ) bool wxDataViewTextRenderer::SetTextValue(const wxString& str)
{ {
wxString tmp = value;
GValue gvalue = { 0, }; GValue gvalue = { 0, };
g_value_init( &gvalue, G_TYPE_STRING ); g_value_init( &gvalue, G_TYPE_STRING );
g_value_set_string( &gvalue, wxGTK_CONV_FONT( tmp, GetOwner()->GetOwner()->GetFont() ) ); g_value_set_string( &gvalue, wxGTK_CONV_FONT( str, GetOwner()->GetOwner()->GetFont() ) );
g_object_set_property( G_OBJECT(m_renderer), "text", &gvalue ); g_object_set_property( G_OBJECT(m_renderer), "text", &gvalue );
g_value_unset( &gvalue ); g_value_unset( &gvalue );
return true; return true;
} }
bool wxDataViewTextRenderer::GetValue( wxVariant &value ) const bool wxDataViewTextRenderer::GetTextValue(wxString& str) const
{ {
GValue gvalue = { 0, }; GValue gvalue = { 0, };
g_value_init( &gvalue, G_TYPE_STRING ); g_value_init( &gvalue, G_TYPE_STRING );
g_object_get_property( G_OBJECT(m_renderer), "text", &gvalue ); g_object_get_property( G_OBJECT(m_renderer), "text", &gvalue );
wxString tmp = wxGTK_CONV_BACK_FONT( g_value_get_string( &gvalue ), const_cast<wxDataViewTextRenderer*>(this)->GetOwner()->GetOwner()->GetFont() ); str = wxGTK_CONV_BACK_FONT( g_value_get_string( &gvalue ), const_cast<wxDataViewTextRenderer*>(this)->GetOwner()->GetOwner()->GetFont() );
g_value_unset( &gvalue ); g_value_unset( &gvalue );
value = tmp;
return true; return true;
} }
@@ -1797,13 +1809,28 @@ void wxDataViewTextRenderer::SetAlignment( int align )
// wxDataViewBitmapRenderer // wxDataViewBitmapRenderer
// --------------------------------------------------------- // ---------------------------------------------------------
namespace
{
// set "pixbuf" property on the given renderer
void SetPixbufProp(GtkCellRenderer *renderer, GdkPixbuf *pixbuf)
{
GValue gvalue = { 0, };
g_value_init( &gvalue, G_TYPE_OBJECT );
g_value_set_object( &gvalue, pixbuf );
g_object_set_property( G_OBJECT(renderer), "pixbuf", &gvalue );
g_value_unset( &gvalue );
}
} // anonymous namespace
IMPLEMENT_CLASS(wxDataViewBitmapRenderer, wxDataViewRenderer) IMPLEMENT_CLASS(wxDataViewBitmapRenderer, wxDataViewRenderer)
wxDataViewBitmapRenderer::wxDataViewBitmapRenderer( const wxString &varianttype, wxDataViewCellMode mode, wxDataViewBitmapRenderer::wxDataViewBitmapRenderer( const wxString &varianttype, wxDataViewCellMode mode,
int align ) : int align ) :
wxDataViewRenderer( varianttype, mode, align ) wxDataViewRenderer( varianttype, mode, align )
{ {
m_renderer = (GtkCellRenderer*) gtk_cell_renderer_pixbuf_new(); m_renderer = gtk_cell_renderer_pixbuf_new();
SetMode(mode); SetMode(mode);
SetAlignment(align); SetAlignment(align);
@@ -1816,38 +1843,23 @@ bool wxDataViewBitmapRenderer::SetValue( const wxVariant &value )
wxBitmap bitmap; wxBitmap bitmap;
bitmap << value; bitmap << value;
// This may create a Pixbuf representation in the // GetPixbuf() may create a Pixbuf representation in the wxBitmap
// wxBitmap object (and it will stay there) // object (and it will stay there and remain owned by wxBitmap)
GdkPixbuf *pixbuf = bitmap.GetPixbuf(); SetPixbufProp(m_renderer, bitmap.GetPixbuf());
GValue gvalue = { 0, };
g_value_init( &gvalue, G_TYPE_OBJECT );
g_value_set_object( &gvalue, pixbuf );
g_object_set_property( G_OBJECT(m_renderer), "pixbuf", &gvalue );
g_value_unset( &gvalue );
return true;
} }
else if (value.GetType() == wxT("wxIcon"))
if (value.GetType() == wxT("wxIcon"))
{ {
wxIcon bitmap; wxIcon icon;
bitmap << value; icon << value;
// This may create a Pixbuf representation in the SetPixbufProp(m_renderer, icon.GetPixbuf());
// wxBitmap object (and it will stay there) }
GdkPixbuf *pixbuf = bitmap.GetPixbuf(); else
{
GValue gvalue = { 0, }; return false;
g_value_init( &gvalue, G_TYPE_OBJECT );
g_value_set_object( &gvalue, pixbuf );
g_object_set_property( G_OBJECT(m_renderer), "pixbuf", &gvalue );
g_value_unset( &gvalue );
return true;
} }
return false; return true;
} }
bool wxDataViewBitmapRenderer::GetValue( wxVariant &WXUNUSED(value) ) const bool wxDataViewBitmapRenderer::GetValue( wxVariant &WXUNUSED(value) ) const
@@ -2399,67 +2411,63 @@ bool wxDataViewDateRenderer::Activate( wxRect WXUNUSED(cell), wxDataViewModel *m
IMPLEMENT_CLASS(wxDataViewIconTextRenderer, wxDataViewCustomRenderer) IMPLEMENT_CLASS(wxDataViewIconTextRenderer, wxDataViewCustomRenderer)
wxDataViewIconTextRenderer::wxDataViewIconTextRenderer( wxDataViewIconTextRenderer::wxDataViewIconTextRenderer
const wxString &varianttype, wxDataViewCellMode mode, int align ) : (
wxDataViewCustomRenderer( varianttype, mode, align ) const wxString &varianttype,
wxDataViewCellMode mode,
int align
)
: wxDataViewTextRenderer(varianttype, mode, align)
{ {
SetMode(mode); m_rendererIcon = gtk_cell_renderer_pixbuf_new();
SetAlignment(align);
} }
wxDataViewIconTextRenderer::~wxDataViewIconTextRenderer() wxDataViewIconTextRenderer::~wxDataViewIconTextRenderer()
{ {
} }
void wxDataViewIconTextRenderer::GtkPackIntoColumn(GtkTreeViewColumn *column)
{
// add the icon renderer first
gtk_tree_view_column_pack_start(column, m_rendererIcon, FALSE /* !expand */);
// add the text renderer too
wxDataViewRenderer::GtkPackIntoColumn(column);
}
bool wxDataViewIconTextRenderer::SetValue( const wxVariant &value ) bool wxDataViewIconTextRenderer::SetValue( const wxVariant &value )
{ {
m_value << value; m_value << value;
return true;
}
bool wxDataViewIconTextRenderer::GetValue( wxVariant &WXUNUSED(value) ) const SetTextValue(m_value.GetText());
{ SetPixbufProp(m_rendererIcon, m_value.GetIcon().GetPixbuf());
return false;
}
bool wxDataViewIconTextRenderer::Render( wxRect cell, wxDC *dc, int state )
{
const wxIcon &icon = m_value.GetIcon();
int offset = 0;
if (icon.IsOk())
{
int yoffset = wxMax( 0, (cell.height - icon.GetHeight()) / 2 );
dc->DrawIcon( icon, cell.x, cell.y + yoffset );
offset = icon.GetWidth() + 4;
}
RenderText( m_value.GetText(), offset, cell, dc, state );
return true; return true;
} }
wxSize wxDataViewIconTextRenderer::GetSize() const bool wxDataViewIconTextRenderer::GetValue(wxVariant& value) const
{
wxSize size;
if (m_value.GetIcon().IsOk())
size.x = 4 + m_value.GetIcon().GetWidth();
wxCoord x,y,d;
GetView()->GetTextExtent( m_value.GetText(), &x, &y, &d );
size.x += x;
size.y = y+d;
return size;
}
wxControl* wxDataViewIconTextRenderer::CreateEditorCtrl(
wxWindow *WXUNUSED(parent), wxRect WXUNUSED(labelRect), const wxVariant &WXUNUSED(value) )
{
return NULL;
}
bool wxDataViewIconTextRenderer::GetValueFromEditorCtrl(
wxControl* WXUNUSED(editor), wxVariant &WXUNUSED(value) )
{ {
wxString str;
if ( !GetTextValue(str) )
return false; return false;
// user doesn't have any way to edit the icon so leave it unchanged
value << wxDataViewIconText(str, m_value.GetIcon());
return true;
}
void
wxDataViewIconTextRenderer::GtkOnCellChanged(const wxVariant& value,
const wxDataViewItem& item,
unsigned col)
{
// we receive just the text part of our value as it's the only one which
// can be edited, but we need the full wxDataViewIconText value for the
// model
wxVariant valueIconText;
valueIconText << wxDataViewIconText(value.GetString(), m_value.GetIcon());
wxDataViewTextRenderer::GtkOnCellChanged(valueIconText, item, col);
} }
// --------------------------------------------------------- // ---------------------------------------------------------
@@ -2679,7 +2687,6 @@ void wxDataViewColumn::Init(wxAlignment align, int flags, int width)
{ {
m_isConnected = false; m_isConnected = false;
GtkCellRenderer *renderer = (GtkCellRenderer *) GetRenderer()->GetGtkHandle();
GtkTreeViewColumn *column = gtk_tree_view_column_new(); GtkTreeViewColumn *column = gtk_tree_view_column_new();
m_column = (GtkWidget*) column; m_column = (GtkWidget*) column;
@@ -2698,10 +2705,13 @@ void wxDataViewColumn::Init(wxAlignment align, int flags, int width)
gtk_box_pack_end( GTK_BOX(box), GTK_WIDGET(m_label), FALSE, FALSE, 1 ); gtk_box_pack_end( GTK_BOX(box), GTK_WIDGET(m_label), FALSE, FALSE, 1 );
gtk_tree_view_column_set_widget( column, box ); gtk_tree_view_column_set_widget( column, box );
gtk_tree_view_column_pack_end( column, renderer, TRUE ); wxDataViewRenderer * const colRenderer = GetRenderer();
GtkCellRenderer * const cellRenderer = colRenderer->GetGtkHandle();
gtk_tree_view_column_set_cell_data_func( column, renderer, colRenderer->GtkPackIntoColumn(column);
wxGtkTreeCellDataFunc, (gpointer) GetRenderer(), NULL );
gtk_tree_view_column_set_cell_data_func( column, cellRenderer,
wxGtkTreeCellDataFunc, (gpointer) colRenderer, NULL );
} }
void wxDataViewColumn::OnInternalIdle() void wxDataViewColumn::OnInternalIdle()