Added wxDataViewCustomCell.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@37716 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Robert Roebling 2006-02-24 18:19:55 +00:00
parent b30b49e993
commit e152afc3d4
4 changed files with 354 additions and 15 deletions

View File

@ -136,13 +136,11 @@ public:
virtual bool BeginEdit() { return true; }
virtual bool EndEdit() { return true; }
virtual bool Render( wxRect cell, wxRect exposed, wxDC *dc, int state ) { return true; }
wxString GetVariantType() { return m_variantType; }
void SetOwner( wxDataViewColumn *owner ) { m_owner = owner; }
wxDataViewColumn* GetOwner() { return m_owner; }
wxString GetVariantType() { return m_variantType; }
protected:
wxDataViewCellMode m_mode;
wxString m_variantType;

View File

@ -75,6 +75,30 @@ protected:
DECLARE_DYNAMIC_CLASS_NO_COPY(wxDataViewToggleCell)
};
// ---------------------------------------------------------
// wxDataViewCustomCell
// ---------------------------------------------------------
class wxDataViewCustomCell: public wxDataViewCell
{
public:
wxDataViewCustomCell( const wxString &varianttype = wxT("string"),
wxDataViewCellMode mode = wxDATAVIEW_CELL_INERT );
~wxDataViewCustomCell();
virtual bool Render( wxRect cell, wxDC *dc, int state ) = 0;
virtual wxSize GetSize() = 0;
// Create DC on request
virtual wxDC *GetDC();
private:
wxDC *m_dc;
protected:
DECLARE_DYNAMIC_CLASS_NO_COPY(wxDataViewCustomCell)
};
// ---------------------------------------------------------
// wxDataViewColumn
// ---------------------------------------------------------

View File

@ -40,12 +40,14 @@ public:
m_list.Add( wxT("Test") );
for (i = 0; i < 500; i++)
{ m_bools.Add( 0 ); m_bools.Add( 1 ); }
for (i = 0; i < 500; i++)
{ m_colours.Add( wxT("red") ); m_colours.Add( wxT("green") ); }
}
virtual size_t GetNumberOfRows()
{ return 1000; }
virtual size_t GetNumberOfCols()
{ return 4; }
{ return 5; }
// as reported by wxVariant
virtual wxString GetColType( size_t col )
@ -61,7 +63,11 @@ public:
if (col == 3)
{
return (bool) m_bools[row];
} else
} else
if (col == 4)
{
return m_colours[row];
}
if (col == 2)
{
return m_list[row];
@ -88,6 +94,45 @@ public:
wxArrayString m_list;
wxArrayInt m_bools;
wxArrayString m_colours;
};
// -------------------------------------
// MyCustomCell
// -------------------------------------
class MyCustomCell: public wxDataViewCustomCell
{
public:
MyCustomCell() :
wxDataViewCustomCell( wxT("string"), wxDATAVIEW_CELL_INERT )
{
m_colour = wxT("black");
}
bool SetValue( const wxVariant &value )
{
m_colour = value.GetString();
return true;
}
bool Render( wxRect rect, wxDC *dc, int state )
{
dc->SetPen( *wxBLACK_PEN );
if (m_colour == wxT("red"))
dc->SetBrush( *wxRED_BRUSH );
else if (m_colour == wxT("green"))
dc->SetBrush( *wxGREEN_BRUSH );
else
dc->SetBrush( *wxBLACK_BRUSH );
dc->DrawRectangle( rect );
return true;
}
wxSize GetSize()
{
return wxSize(20,8);
}
private:
wxString m_colour;
};
// -------------------------------------
@ -176,11 +221,17 @@ MyFrame::MyFrame(wxFrame *frame, wxChar *title, int x, int y, int w, int h):
dataview_left->AppendTextColumn( wxT("first"), 0 );
dataview_left->AppendTextColumn( wxT("second"), 1 );
wxDataViewTextCell *text_cell = new wxDataViewTextCell( wxT("string"), wxDATAVIEW_CELL_EDITABLE );
wxDataViewColumn *column = new wxDataViewColumn( wxT("editable"), text_cell, 2 );
dataview_left->AppendColumn( column );
dataview_left->AppendToggleColumn( wxT("fourth"), 3 );
MyCustomCell *custom_cell = new MyCustomCell;
column = new wxDataViewColumn( wxT("custom"), custom_cell, 4 );
dataview_left->AppendColumn( column );
// Right wxDataViewCtrl using the same model
dataview_right = new wxDataViewCtrl( this, -1 );
dataview_right->AssociateModel( model );

View File

@ -16,6 +16,7 @@
#include "wx/dataview.h"
#include "wx/stockitem.h"
#include "wx/dcclient.h"
#include "wx/gtk/private.h"
#include "wx/gtk/win_gtk.h"
@ -72,11 +73,11 @@ struct _GtkWxListStore
struct _GtkWxListStoreClass
{
GObjectClass parent_class;
GObjectClass list_parent_class;
};
static GtkWxListStore *wxgtk_list_store_new ();
static GtkWxListStore *wxgtk_list_store_new (void);
static void wxgtk_list_store_init (GtkWxListStore *list_store);
static void wxgtk_list_store_class_init (GtkWxListStoreClass *klass);
static void wxgtk_list_store_tree_model_init (GtkTreeModelIface *iface);
@ -111,7 +112,7 @@ static gboolean wxgtk_list_store_iter_parent (GtkTreeModel *tree_mo
GtkTreeIter *iter,
GtkTreeIter *child);
static GObjectClass *parent_class = NULL;
static GObjectClass *list_parent_class = NULL;
GType
gtk_wx_list_store_get_type (void)
@ -152,18 +153,17 @@ gtk_wx_list_store_get_type (void)
}
static GtkWxListStore *
wxgtk_list_store_new()
wxgtk_list_store_new(void)
{
GtkWxListStore *retval = (GtkWxListStore *) g_object_new (GTK_TYPE_WX_LIST_STORE, NULL);
return retval;
GtkWxListStore *retval = (GtkWxListStore *) g_object_new (GTK_TYPE_WX_LIST_STORE, NULL);
return retval;
}
static void
wxgtk_list_store_class_init (GtkWxListStoreClass *klass)
{
GObjectClass *object_class;
parent_class = (GObjectClass*) g_type_class_peek_parent (klass);
object_class = (GObjectClass*) klass;
list_parent_class = (GObjectClass*) g_type_class_peek_parent (klass);
GObjectClass *object_class = (GObjectClass*) klass;
object_class->finalize = wxgtk_list_store_finalize;
}
@ -200,7 +200,7 @@ wxgtk_list_store_finalize (GObject *object)
/* delete list_store->model; */
/* must chain up */
(* parent_class->finalize) (object);
(* list_parent_class->finalize) (object);
}
} // extern "C"
@ -423,6 +423,215 @@ wxgtk_list_store_iter_parent (GtkTreeModel *tree_model,
return FALSE;
}
//-----------------------------------------------------------------------------
// define new GTK+ class wxGtkCellRenderer
//-----------------------------------------------------------------------------
extern "C" {
#define GTK_TYPE_WX_CELL_RENDERER (gtk_wx_cell_renderer_get_type ())
#define GTK_WX_CELL_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_WX_CELL_RENDERER, GtkWxCellRenderer))
#define GTK_WX_CELL_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_WX_CELL_RENDERER, GtkWxCellRendererClass))
#define GTK_IS_WX_CELL_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_WX_CELL_RENDERER))
#define GTK_IS_WX_CELL_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_WX_CELL_RENDERER))
#define GTK_WX_CELL_RENDERER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_WX_CELL_RENDERER, GtkWxCellRendererClass))
GType gtk_wx_cell_renderer_get_type (void);
typedef struct _GtkWxCellRenderer GtkWxCellRenderer;
typedef struct _GtkWxCellRendererClass GtkWxCellRendererClass;
struct _GtkWxCellRenderer
{
GtkCellRenderer parent;
/*< private >*/
wxDataViewCustomCell *cell;
};
struct _GtkWxCellRendererClass
{
GtkCellRendererClass cell_parent_class;
};
static GtkCellRenderer *gtk_wx_cell_renderer_new (void);
static void gtk_wx_cell_renderer_init (GtkWxCellRenderer *cell);
static void gtk_wx_cell_renderer_class_init (GtkWxCellRendererClass *klass);
static void gtk_wx_cell_renderer_finalize (GObject *object);
static void gtk_wx_cell_renderer_get_size (GtkCellRenderer *cell,
GtkWidget *widget,
GdkRectangle *rectangle,
gint *x_offset,
gint *y_offset,
gint *width,
gint *height);
static void gtk_wx_cell_renderer_render (GtkCellRenderer *cell,
GdkWindow *window,
GtkWidget *widget,
GdkRectangle *background_area,
GdkRectangle *cell_area,
GdkRectangle *expose_area,
GtkCellRendererState flags);
static GObjectClass *cell_parent_class = NULL;
} // extern "C"
GType
gtk_wx_cell_renderer_get_type (void)
{
static GType cell_wx_type = 0;
if (!cell_wx_type)
{
static const GTypeInfo cell_wx_info =
{
sizeof (GtkWxCellRendererClass),
NULL, /* base_init */
NULL, /* base_finalize */
(GClassInitFunc) gtk_wx_cell_renderer_class_init,
NULL, /* class_finalize */
NULL, /* class_data */
sizeof (GtkWxCellRenderer),
0, /* n_preallocs */
(GInstanceInitFunc) gtk_wx_cell_renderer_init,
};
cell_wx_type =
g_type_register_static (GTK_TYPE_CELL_RENDERER, "GtkWxCellRenderer",
&cell_wx_info, (GTypeFlags)0);
}
return cell_wx_type;
}
static void
gtk_wx_cell_renderer_init (GtkWxCellRenderer *cell)
{
cell->cell = NULL;
}
static void
gtk_wx_cell_renderer_class_init (GtkWxCellRendererClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GtkCellRendererClass *cell_class = GTK_CELL_RENDERER_CLASS (klass);
cell_parent_class = (GObjectClass*) g_type_class_peek_parent (klass);
object_class->finalize = gtk_wx_cell_renderer_finalize;
cell_class->get_size = gtk_wx_cell_renderer_get_size;
cell_class->render = gtk_wx_cell_renderer_render;
}
static void
gtk_wx_cell_renderer_finalize (GObject *object)
{
/* must chain up */
(* G_OBJECT_CLASS (cell_parent_class)->finalize) (object);
}
GtkCellRenderer*
gtk_wx_cell_renderer_new (void)
{
return (GtkCellRenderer*) g_object_new (GTK_TYPE_WX_CELL_RENDERER, NULL);
}
static void
gtk_wx_cell_renderer_get_size (GtkCellRenderer *renderer,
GtkWidget *widget,
GdkRectangle *cell_area,
gint *x_offset,
gint *y_offset,
gint *width,
gint *height)
{
GtkWxCellRenderer *wxrenderer = (GtkWxCellRenderer *) renderer;
wxDataViewCustomCell *cell = wxrenderer->cell;
wxSize size = cell->GetSize();
gint calc_width = (gint) renderer->xpad * 2 + size.x;
gint calc_height = (gint) renderer->ypad * 2 + size.y;
if (x_offset)
*x_offset = 0;
if (y_offset)
*y_offset = 0;
if (cell_area && size.x > 0 && size.y > 0)
{
if (x_offset)
{
*x_offset = (gint)((renderer->xalign *
(cell_area->width - calc_width - 2 * renderer->xpad)));
*x_offset = MAX (*x_offset, 0) + renderer->xpad;
}
if (y_offset)
{
*y_offset = (gint)((renderer->yalign *
(cell_area->height - calc_height - 2 * renderer->ypad)));
*y_offset = MAX (*y_offset, 0) + renderer->ypad;
}
}
if (width)
*width = calc_width;
if (height)
*height = calc_height;
}
static void
gtk_wx_cell_renderer_render (GtkCellRenderer *renderer,
GdkWindow *window,
GtkWidget *widget,
GdkRectangle *background_area,
GdkRectangle *cell_area,
GdkRectangle *expose_area,
GtkCellRendererState flags)
{
GtkWxCellRenderer *wxrenderer = (GtkWxCellRenderer *) renderer;
wxDataViewCustomCell *cell = wxrenderer->cell;
GdkRectangle rect;
gtk_wx_cell_renderer_get_size (renderer, widget, cell_area,
&rect.x,
&rect.y,
&rect.width,
&rect.height);
rect.x += cell_area->x;
rect.y += cell_area->y;
rect.width -= renderer->xpad * 2;
rect.height -= renderer->ypad * 2;
GdkRectangle dummy;
if (gdk_rectangle_intersect (expose_area, &rect, &dummy))
{
wxRect renderrect( rect.x, rect.y, rect.width, rect.height );
wxWindowDC* dc = (wxWindowDC*) cell->GetDC();
dc->m_window = window;
int state = 0;
if (flags & GTK_CELL_RENDERER_SELECTED)
state |= wxDATAVIEW_CELL_SELECTED;
if (flags & GTK_CELL_RENDERER_PRELIT)
state |= wxDATAVIEW_CELL_PRELIT;
if (flags & GTK_CELL_RENDERER_INSENSITIVE)
state |= wxDATAVIEW_CELL_INSENSITIVE;
if (flags & GTK_CELL_RENDERER_INSENSITIVE)
state |= wxDATAVIEW_CELL_INSENSITIVE;
if (flags & GTK_CELL_RENDERER_FOCUSED)
state |= wxDATAVIEW_CELL_FOCUSED;
cell->Render( renderrect, dc, state );
}
}
// ---------------------------------------------------------
// wxGtkDataViewListModelNotifier
// ---------------------------------------------------------
@ -690,6 +899,63 @@ bool wxDataViewToggleCell::GetValue( wxVariant &value )
return true;
}
// ---------------------------------------------------------
// wxDataViewCustomCell
// ---------------------------------------------------------
class wxDataViewCtrlDC: public wxWindowDC
{
public:
wxDataViewCtrlDC( wxDataViewCtrl *window )
{
GtkWidget *widget = window->GetHandle();
// Set later
m_window = NULL;
m_context = window->GtkGetPangoDefaultContext();
m_layout = pango_layout_new( m_context );
m_fontdesc = pango_font_description_copy( widget->style->font_desc );
m_cmap = gtk_widget_get_colormap( widget ? widget : window->m_widget );
SetUpDC();
m_owner = window;
}
};
// ---------------------------------------------------------
// wxDataViewCustomCell
// ---------------------------------------------------------
IMPLEMENT_ABSTRACT_CLASS(wxDataViewCustomCell, wxDataViewCell)
wxDataViewCustomCell::wxDataViewCustomCell( const wxString &varianttype,
wxDataViewCellMode mode ) :
wxDataViewCell( varianttype, mode )
{
m_dc = NULL;
GtkWxCellRenderer *renderer = (GtkWxCellRenderer *) gtk_wx_cell_renderer_new();
renderer->cell = this;
m_renderer = (void*) renderer;
}
wxDataViewCustomCell::~wxDataViewCustomCell()
{
if (m_dc)
delete m_dc;
}
wxDC *wxDataViewCustomCell::GetDC()
{
if (m_dc == NULL)
m_dc = new wxDataViewCtrlDC( GetOwner()->GetOwner() );
return m_dc;
}
// ---------------------------------------------------------
// wxDataViewColumn
// ---------------------------------------------------------