]> git.saurik.com Git - wxWidgets.git/commitdiff
Added wxDataViewCustomCell.
authorRobert Roebling <robert@roebling.de>
Fri, 24 Feb 2006 18:19:55 +0000 (18:19 +0000)
committerRobert Roebling <robert@roebling.de>
Fri, 24 Feb 2006 18:19:55 +0000 (18:19 +0000)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@37716 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

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

index b4844dcc573f62738a1fc59b97faff30793c466d..f28eb943e98587b16984f9539b98748fa51eadb0 100644 (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;
index a86ebe1ed253587f4fa06752ee03054bf25800a4..1e398fe662d925181614906c4b62d0132a28152f 100644 (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
 // --------------------------------------------------------- 
index 8662b913ce726f76c0011fe72df297d27f0fd435..3fb311897b8f631bacb7910ef2036473bc42fa29 100644 (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 );
index 7f9c9376972a8e8756251e2cea473c93f8b2f97d..8edf067ec940e43897df0c89116f0b261c5741fa 100644 (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
 // ---------------------------------------------------------