Re: Yet more treeview musings



Marc & Others:

Okay there has been a recent development in Gtk+.  As Bill predicted
several days ago, the Gtk folks made a pretty significant change to
how renderers work in GtkTreeView.

Now instead of each column having a single renderer, a column can have
multiple of renderers.  The renderers are stored in a GList of
GtkTreeViewColumnCellInfo structures.

The gtk_tree_view_column_get_cell_renderer() function has been changed
to gtk_tree_view_column_get_cell_renderers().

If you update to today's GTK+ code you will have the new code.  I talked
with Jonathan (see email and xchat attachments) and he says that the only
place where this is going to be used currently is when text and a pixbuf
are displayed in the same column.

I don't think that this really breaks our plans badly.  It just means that
the GailTextCell (and its siblings) also stores a GList of 
GtkTreeViewColumnCellInfo structures not just the Renderer (in addition
to the GtkTreeRowReference and the GtkTreeViewColumn pointer).

Rememember that each renderer is set up when you call the
gtk_tree_view_column_cell_set_cell_data()  function.   Here is the code
(same code I mentioned in my previous email except a from today's CVS head):
Also note that "cell_list" is a GList of GtkTreeViewColumnCellInfo 
structures.

--example code start--

   for (cell_list = tree_column->cell_list; cell_list; cell_list =
        cell_list->next)
     {
	GtkTreeViewColumnCellInfo *info = 
	  (GtkTreeViewColumnCellInfo *) cell_list->data;
	GObject *cell = (GObject *) info->cell;
 
 	list = info->attributes;
 
 	g_object_freeze_notify (cell);
 	while (list && list->next)
 	{
          gtk_tree_model_get_value (tree_model, iter,
                                     GPOINTER_TO_INT (list->next->data),
                                     &value);
 	  g_object_set_property (cell, (gchar *) list->data, &value);
 	  g_value_unset (&value);
 	  list = list->next->next;
 	}

	[...]
     }
     
--example code stop--

So the outer for loop goes over the cells in the column.  The "info"
variable in the for-loop coorisponds to the CellData structure for
the cell.  Note that the renderer corrisponds to "info->cell" and the
attributes for that cell corrispond to "info->attributes".

So it loops over the attributes and sets the values for each attribute
in info->attributes by calling gtk_tree_model_get_value and then
calling g_object_set_property.

So when a cell change notification happens, the cell can call a function
in the interface which just simply converts its cached GtkTreeRowReference
into a GtkTreeIter, then loops over the GtkTreeViewColumnCellInfo
structures exactly like in the example code above, and that will properly
set the values.

Hope this explains things!

Brian
--- Begin Message ---
Brian Cameron <Brian Cameron sun com> writes:

> Jonathan:
> 
> I just noticed that in the latest CVS head for gtk+, that the function
> gtk_tree_view_column_get_cell_renderer() in gtktreeview.c changed
> to gtk_tree_view_column_get_cell_renderers().  It now returns a GList
> of renderers.
> 
> I don't understand why a cell would need to implement multiple renderers.
> Could you explain?

A column can have multiple renderers packed into it.  The idea is to
replace gtk_cell_renderer_text_pixbuf with the capability of having a
text and pixbuf renderer packed into it.

-Jonathan

--- End Message ---
<jrb> sure
<yippi> your right i'm still a little confused
<yippi> you say that the inner loop loops over the attributes for the cell
<yippi> but that is a list that can point to different cells in the model, eh?
<jrb> yeah
<jrb> no
<jrb> it's stored once per cell
<yippi> in other words info->attributes tells which model cells corrispond to the GtkTreeviewColumn
<yippi> and that's what the inner loop is looping over.
<yippi> while (list && list->next) is the inner loop and list is info->attributes
<yippi> isn't info->attributes a list which contains the model column #'s that corrispond to this cell?
<yippi> or are you just saying that this list will only *ever* have one entry in it.
<yippi> or perhaps this is a part of the code that is changing.  :)
<yippi> so there really isn't a need to have an inner "while" loop if there are only ever going to be 2 values in the list.
<jrb> first of all, TextPixbuf isn't going away
<yippi> (list & list->next)
<jrb> no
<jrb> okay
<jrb> lets start at the beginning:
<yippi> okay
<jrb> 1) Now you can have multiple cells per column.
<jrb> though the code isn't fully finished
<jrb> the idea is, you can do something like:
<jrb> gtk_tree_view_column_pack_start_cell_renderer (column, toggle_cell, FALSE, FALSE, 0);
<jrb> gtk_tree_view_column_pack_start_cell_renderer (column, text_cell, TREU, TRUE, 0);
<jrb> and have something more like a toggle button in a column (all under one Column header)
<yippi> but the multiple cells per column share the same renderers or have different renderers?
<yippi> that makes sense so far.
<jrb> each has it's own set of renderers
<jrb> so I can do:
<yippi> so each cell can have multiple renderers.
<jrb> gtk_tree_view_column_cell_set_attributes (column, text_cell, "text", 0, "foreground_color", 1, "visible", 2, NULL);
<jrb> gtk_tree_view_column_cell_set_attributes (column, toggle_cell, "active", 4, NULL);
<jrb> yeah -- basically
<yippi> so do all the renderers in a cell have the same backing GValue data?
<jrb> GValue is just used to transfer values around
<jrb> neither the model nor the cell actually stores a GValue
<yippi> oh, so the call to gtk_model_get_value just gets the value and the call to to set_property_value pumps it into the renderer.
<jrb> yes
* jrb wonders what you thought it did... (-:
<yippi> i thought each cell would have to have one renderer.
<yippi> not multiple renderers.
<yippi> i thought that you put multiple cells in the column and each cell had its own renderer
<yippi> but instead you can have multiple cells per column and each cell can have multiple values/renderers.
<jrb> the whole idea of this is to allow it to have multiple renderers, so that you can have column-spanning headers...
<yippi> that seems like it could get confusing.
<yippi> but I think i understand it.
<yippi> so each cell in a column shares the same renderers though right?
<yippi> so if you have 3 cells in a column and 4 renderers
<yippi> each of the 3 cells would share the same 4 renderers
<yippi> or can each cell have its own unique renderers?
<jrb> huh
<yippi> i think i'm wrong there.  looking at the code the renderer is stored in the cell_info structure...so each cell could have its own set of renderers.  
<jrb> what's a cell, here?
<yippi> that's better, eh?
<yippi> each column has multiple cells.  That's what I'm refering to as a cell.
<yippi> the multiple cells in the column.
<yippi> each of the cells in a column can have its own unique set of renderers.  
<jrb> yes. each column has multiple cell renderers.
<yippi> that's not quite what i was asking.
<yippi> each column has multiple cells.  Does each cell have it's own set of renderers
* jrb is a little lagged -- sorry
<yippi> or does each cell share its renderers with the other cells in the column?
<yippi> no problem.  :)
<jrb> a cell is a renderer
<yippi> so in the outer for loop you are looping over the renderers then?
<jrb> yes
<yippi> then in the inner while loop you are looping over the attributes
<jrb> yes
<yippi> aren't you then setting each renderer to all of the values?
<jrb> b/c it doesn't make sense
<yippi> so if you have a text and a pixbuf in the attributes
<jrb> okay
<jrb> you can't set a "pixbuf" atttribute on a text renderer
<yippi> you loop over the renderers in the outer loop, then you loop over the attributes in the inner loop and call gtk_tree_model_get_value for each attribute, and then g_object_set_property() for each attribute.  This indicates to me that you are setting each attribute value to each renderer.
<jrb> yes, but I store the attributes per cell_renderer
<jrb> new rule.  no more using the word 'cell'
<yippi> okay so now we use the word 'renderer'?
<jrb> there is a column, and a renderer
<jrb> a renderer just draws something.
<yippi> oh i see!
<jrb> I store a list of attribute mappings per renderer
<yippi> what you are saying is that it's pulling out the renderer from info->cell
<yippi> and its pulling out the attributes from info->attributes
<jrb> yes
<yippi> so each cell in "cell_list" has its own renderer and its own list of attributes
<jrb> yes
<yippi> so if a cell in "cell_list" has multiple attributes in info->attributes, then each attribute value would get set on the renderer.
<yippi> would there ever be such a case?
<jrb> sure
<yippi> is this the pixbuf case?
<yippi> :)
<jrb> no -- the text case most likely
<jrb> there are a large number of attributes that can be set
<yippi> oh so having multiple attributes doesn't mean that it is pulling data from different columns in the model.
<jrb>   PROP_BACKGROUND,
<jrb>   PROP_FOREGROUND,
<jrb>   PROP_BACKGROUND_GDK,
<jrb>   PROP_FOREGROUND_GDK,
<jrb>   PROP_FONT,
<jrb>   PROP_FONT_DESC,
<jrb>   PROP_FAMILY,
<jrb>   PROP_STYLE,
<yippi> they also corripsond to properties.
<jrb>   PROP_VARIANT,
<yippi> that it?
<jrb>   PROP_WEIGHT,
<jrb>   PROP_STRETCH,
<jrb>   PROP_SIZE,
<jrb>   PROP_SIZE_POINTS,
<jrb>   PROP_SCALE,
<jrb>   PROP_EDITABLE,
<jrb>   PROP_STRIKETHROUGH,
<jrb>   PROP_UNDERLINE,
<jrb>   PROP_RISE,
<jrb>   
<jrb> (for text)
<jrb> plus XALIGN, YALIGN, VISIBLE, etc.
<yippi> so the attributes would all come from the same column in the model, but would corripond to properties as well as the actual value.
<jrb> no
<jrb> look at the code.
<yippi> the value is a property
<yippi> so it is just setting properties.
<jrb>       while (list && list->next)
<jrb>  {
<jrb>    gtk_tree_model_get_value (tree_model, iter,
<jrb>         GPOINTER_TO_INT (list->next->data),
<jrb>         &value);
<jrb>    g_object_set_property (cell, (gchar *) list->data, &value);
<jrb>    g_value_unset (&value);
<jrb>    list = list->next->next;
<jrb>  }
<yippi> right.
<jrb> list->data is an attribute, and list->next->data is a column model 
<yippi> i understand that the attributes could come from different column models.
<jrb> so an attribute list for a text renderer might look like {"text", 1, "bold", 4 }
<jrb> yeah
<jrb> > oh so having multiple attributes doesn't mean that it is pulling data from different columns in the model.
<jrb> that statement confused me
<yippi> ?
<yippi> in your example "text", 1, "bold", 4.  It is pulling the text from column 1 in the model and the bold attribute from column 4.
<yippi> i guess i don't really understand why you would set up a model where it would grab properties for a single renderer from different columns in the model...but i guess you could if you wanted to.
<yippi> i would think that if there is one text column in the model you would store all of the relevant properties in that column.
<jrb> well, doesn't the case above indicate it?
<yippi> it does.  I understand it is possible to do...I just don't understand why you would set up a model that way.
<yippi> However, I don't really *need* to understand why.
<yippi> That's really the business of the person setting up the model.
<jrb> well, you can only have one type per column
<jrb> "bold" is a boolean, "text" is a string
<jrb> and the bold column might be used by more then one column or renderer
<yippi> oh so each property *must* be in a unique column in the model?
<yippi> and properties other than "type" can be shared by various columns.
<jrb> for instance, that column might be logically the "message_unread" column in evolution
<jrb> type?
<yippi> you said "well, you can only have one type per column"
<yippi> or is "type" not really a property.
<jrb> type isn't a property
<yippi> i see.
<yippi> okay.  you've answered all of my questions.  I think I undestand how it fits together now.
<jrb> look at gtk_tree_model_get_types
<yippi> okay.
* jrb obviously needs to write many docs
<yippi> :) :
<yippi> :)


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]