[Gtk-sharp-list] custom cell renderer

Mikkel Kruse Johnsen mikkel@linet.dk
Fri, 07 Jan 2005 08:43:13 +0100


--=-m8rvZc2bNUU/DWpBZ42h
Content-Type: multipart/alternative; boundary="=-qCpVEmNf2zyOcC2PkIXW"


--=-qCpVEmNf2zyOcC2PkIXW
Content-Type: text/plain
Content-Transfer-Encoding: 7bit

Hi

I don't know if all you want is a pixbuf and some text displayed beside
each other. If that is the case you don't need to make a custom
CellRendere, you can just pack the two renderes toghter like this:

---

               public enum Column :int {
                        Title,
                        Pixbuf,
                };


                        GType[] types = {   GType.String,
Gdk.Pixbuf.GType };

                       TreeStore store = new TreeStore (types);
                        treeview.Model = store;

                        TreeViewColumn column = new TreeViewColumn ();
                        column.Title = "Pack Test";

                        CellRendererPixbuf pixbufRenderer = new
CellRendererPixbuf ();
                        column.PackStart (pixbufRenderer, false);
                        column.AddAttribute (pixbufRenderer, "pixbuf",
(int)Column.Pixbuf);

                        CellRendererText textRenderer = new
CellRendererText ();
                        column.PackStart (textRenderer, false);
                        column.AddAttribute (textRenderer, "text",
(int)Column.Title);

                        treeview.AppendColumn (column);
---

Remember that the "Store" doesn't have any relation to the CellRenderer
and CellRenderer only use the Store to get data. The Store has nothing
to do with how the data is presented. So you don't need a CellRederer
for every column in the Store, think of the Store as a database with
columns and the CellRederer is how to display that data.

Hope it helps, sorry if you already now that and really needed a custom
CellRenderer :)

/Mikkel


On Thu, 2005-01-06 at 12:10 -0500, Michael Quinn wrote:

> I'm trying to write just a simple custom CellRenderer that displays both
> an icon and some text.  I've extended a CellRendererText, and within
> that class it holds a CellRendererPixbuf object.  Then I override the
> GetSize and Render methods so that the two render right next to each
> other in a row.  Here's the relevant code:
> 
> public override void GetSize (Widget widget, ref Rectangle cell_area,
> out int x_offset, out int y_offset, out int width, out int height)
> {		
>    int text_x, text_y, text_w, text_h;
>    base.GetSize(widget, ref cell_area, out text_x, out text_y, out
> text_w, out text_h);
> 				
>    int pix_x, pix_y, pix_w, pix_h;
>    pixCell.GetSize(widget, ref cell_area, out pix_x, out pix_y, out
> pix_w, out pix_h);
> 
>    if(text_w != 0 && pix_w != 0)
>       pix_w += (int)this.Xpad;
> 
>    x_offset = 0;
>    y_offset = 0;
>    width = text_w + pix_w;
>    height = Math.Max(text_h, pix_h);
> }
> 
> protected override void Render (Drawable window, Widget widget,
> Rectangle background_area, Rectangle cell_area, Rectangle expose_area,
> CellRendererState flags)
> {
>    Gdk.Window gdkWindow = (Gdk.Window)window;
> 		
>    int pix_x, pix_y, pix_w, pix_h;
>    pixCell.GetSize(widget, ref cell_area, out pix_x, out pix_y, out
> pix_w, out pix_h);
> 		
>    Rectangle pixCellArea = cell_area;
>    pixCellArea.Width = pix_w;
> 
>    pixCell.Render(gdkWindow, widget, background_area, pixCellArea,
> expose_area, flags);
> 
>    Rectangle textCellArea = cell_area;
> 
>    if (pix_w != 0)
>    {
>       textCellArea.X = textCellArea.X + pix_w + (int)this.Xpad;
>       textCellArea.Width = textCellArea.Width - pix_w - (int)this.Xpad;
>    }
> 		
>    base.Render(window, widget, background_area, textCellArea,
> expose_area, flags);
> }
> 
> pixCell is the CellRendererPixbuf contained inside my custom renderer.
> This code has been ported almost line by line from a custom cell
> renderer used in Coaster.  Some problems I'm having are:
> 
> the final base.Render call always throws a NullReferenceException (even
> though neither window nor widget is null).  If I comment out this line,
> though, the renderer still wont render the PixBuf.
> 
> Also, in the GetSize method, when I call pixCell.GetSize, pix_* are
> always set to zero (which explains why it later won't render).
> 
> So, is there anybody who could offer any help? Or, is there a custom
> cell renderer already out there that I could use that does this already?
> Any help is greatly appreciated.  Oh, and yes, I'm sure that the
> CellRendererPixbuf has its Pixbuf property properly assigned to a valid
> Pixbuf.
> 

--=-qCpVEmNf2zyOcC2PkIXW
Content-Type: text/html; charset=utf-8
Content-Transfer-Encoding: 7bit

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 TRANSITIONAL//EN">
<HTML>
<HEAD>
  <META HTTP-EQUIV="Content-Type" CONTENT="text/html; CHARSET=UTF-8">
  <META NAME="GENERATOR" CONTENT="GtkHTML/3.3.2">
</HEAD>
<BODY>
Hi<BR>
<BR>
I don't know if all you want is a pixbuf and some text displayed beside each other. If that is the case you don't need to make a custom CellRendere, you can just pack the two renderes toghter like this:<BR>
<BR>
---<BR>
<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public enum Column :int {<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Title,<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Pixbuf,<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; };<BR>
<BR>
<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; GType[] types = {&nbsp;&nbsp; GType.String, Gdk.Pixbuf.GType };<BR>
<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; TreeStore store = new TreeStore (types);<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; treeview.Model = store;<BR>
<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; TreeViewColumn column = new TreeViewColumn ();<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; column.Title = &quot;Pack Test&quot;;<BR>
<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CellRendererPixbuf pixbufRenderer = new CellRendererPixbuf ();<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; column.PackStart (pixbufRenderer, false);<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; column.AddAttribute (pixbufRenderer, &quot;pixbuf&quot;, (int)Column.Pixbuf);<BR>
<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CellRendererText textRenderer = new CellRendererText ();<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; column.PackStart (textRenderer, false);<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; column.AddAttribute (textRenderer, &quot;text&quot;, (int)Column.Title);<BR>
<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; treeview.AppendColumn (column);<BR>
---<BR>
<BR>
Remember that the &quot;Store&quot; doesn't have any relation to the CellRenderer and CellRenderer only use the Store to get data. The Store has nothing to do with how the data is presented. So you don't need a CellRederer for every column in the Store, think of the Store as a database with columns and the CellRederer is how to display that data.<BR>
<BR>
Hope it helps, sorry if you already now that and really needed a custom CellRenderer <IMG SRC="cid:1105083744.3167.9.camel@tibook.orholm.dk" ALIGN="middle" ALT=":)" BORDER="0"><BR>
<BR>
/Mikkel<BR>
<BR>
<BR>
On Thu, 2005-01-06 at 12:10 -0500, Michael Quinn wrote:
<BLOCKQUOTE TYPE=CITE>
<PRE>
<FONT COLOR="#000000">I'm trying to write just a simple custom CellRenderer that displays both</FONT>
<FONT COLOR="#000000">an icon and some text.  I've extended a CellRendererText, and within</FONT>
<FONT COLOR="#000000">that class it holds a CellRendererPixbuf object.  Then I override the</FONT>
<FONT COLOR="#000000">GetSize and Render methods so that the two render right next to each</FONT>
<FONT COLOR="#000000">other in a row.  Here's the relevant code:</FONT>

<FONT COLOR="#000000">public override void GetSize (Widget widget, ref Rectangle cell_area,</FONT>
<FONT COLOR="#000000">out int x_offset, out int y_offset, out int width, out int height)</FONT>
<FONT COLOR="#000000">{		</FONT>
<FONT COLOR="#000000">   int text_x, text_y, text_w, text_h;</FONT>
<FONT COLOR="#000000">   base.GetSize(widget, ref cell_area, out text_x, out text_y, out</FONT>
<FONT COLOR="#000000">text_w, out text_h);</FONT>
<FONT COLOR="#000000">				</FONT>
<FONT COLOR="#000000">   int pix_x, pix_y, pix_w, pix_h;</FONT>
<FONT COLOR="#000000">   pixCell.GetSize(widget, ref cell_area, out pix_x, out pix_y, out</FONT>
<FONT COLOR="#000000">pix_w, out pix_h);</FONT>

<FONT COLOR="#000000">   if(text_w != 0 &amp;&amp; pix_w != 0)</FONT>
<FONT COLOR="#000000">      pix_w += (int)this.Xpad;</FONT>

<FONT COLOR="#000000">   x_offset = 0;</FONT>
<FONT COLOR="#000000">   y_offset = 0;</FONT>
<FONT COLOR="#000000">   width = text_w + pix_w;</FONT>
<FONT COLOR="#000000">   height = Math.Max(text_h, pix_h);</FONT>
<FONT COLOR="#000000">}</FONT>

<FONT COLOR="#000000">protected override void Render (Drawable window, Widget widget,</FONT>
<FONT COLOR="#000000">Rectangle background_area, Rectangle cell_area, Rectangle expose_area,</FONT>
<FONT COLOR="#000000">CellRendererState flags)</FONT>
<FONT COLOR="#000000">{</FONT>
<FONT COLOR="#000000">   Gdk.Window gdkWindow = (Gdk.Window)window;</FONT>
<FONT COLOR="#000000">		</FONT>
<FONT COLOR="#000000">   int pix_x, pix_y, pix_w, pix_h;</FONT>
<FONT COLOR="#000000">   pixCell.GetSize(widget, ref cell_area, out pix_x, out pix_y, out</FONT>
<FONT COLOR="#000000">pix_w, out pix_h);</FONT>
<FONT COLOR="#000000">		</FONT>
<FONT COLOR="#000000">   Rectangle pixCellArea = cell_area;</FONT>
<FONT COLOR="#000000">   pixCellArea.Width = pix_w;</FONT>

<FONT COLOR="#000000">   pixCell.Render(gdkWindow, widget, background_area, pixCellArea,</FONT>
<FONT COLOR="#000000">expose_area, flags);</FONT>

<FONT COLOR="#000000">   Rectangle textCellArea = cell_area;</FONT>

<FONT COLOR="#000000">   if (pix_w != 0)</FONT>
<FONT COLOR="#000000">   {</FONT>
<FONT COLOR="#000000">      textCellArea.X = textCellArea.X + pix_w + (int)this.Xpad;</FONT>
<FONT COLOR="#000000">      textCellArea.Width = textCellArea.Width - pix_w - (int)this.Xpad;</FONT>
<FONT COLOR="#000000">   }</FONT>
<FONT COLOR="#000000">		</FONT>
<FONT COLOR="#000000">   base.Render(window, widget, background_area, textCellArea,</FONT>
<FONT COLOR="#000000">expose_area, flags);</FONT>
<FONT COLOR="#000000">}</FONT>

<FONT COLOR="#000000">pixCell is the CellRendererPixbuf contained inside my custom renderer.</FONT>
<FONT COLOR="#000000">This code has been ported almost line by line from a custom cell</FONT>
<FONT COLOR="#000000">renderer used in Coaster.  Some problems I'm having are:</FONT>

<FONT COLOR="#000000">the final base.Render call always throws a NullReferenceException (even</FONT>
<FONT COLOR="#000000">though neither window nor widget is null).  If I comment out this line,</FONT>
<FONT COLOR="#000000">though, the renderer still wont render the PixBuf.</FONT>

<FONT COLOR="#000000">Also, in the GetSize method, when I call pixCell.GetSize, pix_* are</FONT>
<FONT COLOR="#000000">always set to zero (which explains why it later won't render).</FONT>

<FONT COLOR="#000000">So, is there anybody who could offer any help? Or, is there a custom</FONT>
<FONT COLOR="#000000">cell renderer already out there that I could use that does this already?</FONT>
<FONT COLOR="#000000">Any help is greatly appreciated.  Oh, and yes, I'm sure that the</FONT>
<FONT COLOR="#000000">CellRendererPixbuf has its Pixbuf property properly assigned to a valid</FONT>
<FONT COLOR="#000000">Pixbuf.</FONT>

</PRE>
</BLOCKQUOTE>
</BODY>
</HTML>

--=-qCpVEmNf2zyOcC2PkIXW--

--=-m8rvZc2bNUU/DWpBZ42h
Content-ID: <1105083744.3167.9.camel@tibook.orholm.dk>
Content-Disposition: attachment; filename=smiley-3.png
Content-Type: image/png; name=smiley-3.png
Content-Transfer-Encoding: base64

iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAC+klEQVR42n2TbUjVdxTHP/+H69Xd
a2VWlFe69rzthZJUoxeNOWoFGxEhYRRFmZSVW2u9ab2KejWE1qDNBkEQhS82VoiaZkVPmoWaKNM5
mA+opbd771//997//T/+epHBarEPHA6Hc84XDnwP/JcwcBS4AVgzcR04ONN7C+md+pcPCz44dPLA
arZs/gg1UABuGkvvp7X1Iad+itE/YtUAle8TuH26sujzqq/LkJQsnOQQVmIASVJQMhehZORiJwc5
d76FH2pf3gY2Aigzy7+eObqmtOqbXbjGGHZqCM+eQpJ9AHhWFCc5CAjWf1KAkppc+qg3vRCol4Fw
0aqcisOVW3HTE7hmBElSKD/5GFkNMhH1KDvegST78CwNSfZxeM88VuYrh4CwAuxqvxL6MnPuWiy9
H1kNUPH9fZofDKPpHn8/z+Z6Yw8JK5stX5VhRO6h+OfiV3WaHxtPVKAwmF+KqXUDMkgqZ0+UoKcE
P57/GXOqh46ODqrPXUQfufb6YOGxJOQD2CaHQnnlAJ4zDXggHBYvK6ap6Rau+RIz1k7djd+YHrqM
pXUC4KQnWTRPAdiuRqNRkFQG/omRNJOsKVQw408xtS4QDsI10AaqEY6O8Fzq70fJy3XI8gsA5HTa
rBdOkvwFKj39EWrr/sJzEnj29OvsphGugfBsLlwbZnjcYN36LxiLuADtMtCUetFAcE4ee8s+pbHV
YtOemwhHx3MSaPEY3X9OUnqsk5a2OMeP7KC3t4u+3gRALUC4cEW2eN62Q4ze3SAiz74TDxvOiI+X
BcTsoCoyfJKYn6OKmrMbxGRnlXhyJSSqv80Vq0KSAFa+ceKl0wcK9lfsW42TGsE/pxhfcDmKfz6e
FUPg4iRH6Ov6g9EJh1t341xusWuAyn9b+c7BrbklJ8oDZGTOQpL9ePY08SmDpCEwbcHwuE370yku
Nlj3gM/e90yXliyU9+8sCVJYlEUgU8IwBZruMThm83uzxsAYV4Hd/A9h4BjQBthAFOgDLgDF7w6/
ArI6YJ0eTQeGAAAAAElFTkSuQmCC


--=-m8rvZc2bNUU/DWpBZ42h--