Re: Introducing GtkTreeModelFilter



On Mon, 2002-12-30 at 03:34, Owen Taylor wrote:
> Kristian Rietveld <kris gtk org> writes:
> 
> > *  filter specific rows, based on data from a "visible column", a column
> > storing booleans indicating whether the row should be filtered or not,
> > or based on the return value of a "visible function", which gets a
> > model, iter and user_data and returns a boolean indicating whether the
> > row should be filtered or not.
> 
> What's the relationship between the visible function and the 
> visible column? Can you set both at once? (The visible column
> can be trivially implemented in terms of a visible function,
> so perhaps one-or-the-other-but-not-both makes the most sense?)

You can only set one at once, and it is indeed trivial to implement the
visible column idea in terms of a visible function. If it is preferable
to remove the visible_column idea from the API, then that is a trivial
thing to do. Though it may make sense to have it in the standard API,
for convenience.

> 
> > *  modify the "appearance" of the model, using a modify function. You
> > pass in the number of columns you want to have, together with the GTypes
> > and a modify function. For each row, the modify function will be called,
> > with a model, iter, GValue, column number, and user_data. The modify
> > function should set a correct value in the GValue, which will be shown
> > in the model. This is extremely powerful and allows for just changing
> > some values and also for creating a completely different model based on
> > the given child model. It's a bit difficult to explain this, you would
> > just have to see this in action.
> 
> This seems like a pretty powerful feature, but, I have some
> reservation about it too:
> 
>  - It seems to largely duplicate the functionality of 
>    gtk_tree_view_column_set_cell_data_func(); both allow
>    you to put in a function that munges the model values
>    in an abtrary 

That's true, though when using the filter model you get the ability to
wrap this model as bonus. For example, you can wrap the filter model in
a GtkTreeModelSort and get sorting for free.

The original idea behind this modify-func was to modify values (which is
also possible from _set_cell_data_func() of course), but with this API
you get some nice extras for free.

>  - It sounds like it would make a program rather hard to understand,
>    in that you have two sets of different model columns to 
>    think about it.

True, but the same problem poses when you think of the set of columns
from the TreeModel and the set of columns from the TreeView seperately.
And most of the time you would implement the storage model and the
filter model together as a kind of backend, so during the development of
the frontend you would only be exposed to the columns of the filter
model anyway.

> 
> Are there some good examples of when it comes in handy?

Different independently sorted views of the same model. Which looks like
(I hope evo doesn't mungle my "nice" ascii art):

              / GtkTreeModelFilter - GtkTreeModelSort - GtkTreeView
GtkTreeStore +
              \ GtkTreeModelFilter - GtkTreeModelSort - GtkTreeView

This is the only handy use I can think of ATM. I am sure that there are
some other nice uses. I actually implemented this because it was on
jrb's feature list :P.

> > Would it be a good idea to make my data really private using Owen's cool
> > GObjectPrivate thing?
> 
> Yes (when we have it). I've arrived at the opinion that
> it almost never makes sense to have public data members.

Yeah me too. Yay for private data!!

>  
> > Sidenote: you can set a modify or (filter function/filter column) only
> > *once*.
> 
> Why? Would it be hard to change? These types of restrictions 
> tend to seem harmless, but often are a real pain for things
> like GUI builders.

I think this will be easy to add now I have this _refilter function. It
will be slow though. I have actually discussed this with jrb, and IIRC
he said it wasn't really needed and would be painful. But maybe it was
unfair to mention that (sorry jrb) (:.

>   
> > typedef void (* GtkTreeModelFilterModifyFunc) (GtkTreeModel *model,
> >                                                GtkTreeIter  *iter,
> >                                                GValue       *value,
> >                                                gint          column,
> >                                                gpointer      data);
> 
> I think you should swap value and column in the ordering here,
> since the iter/column together specify the piece of data to
> retrieve.

Agreed.

>  
> > GType         gtk_tree_model_filter_get_type                   (void);
> > GtkTreeModel *gtk_tree_model_filter_new                        (GtkTreeModel                  *child_model,
> >                                                                 GtkTreePath                   *root);
> 
> Similar to the question above, would it be possible to have 
> set_model(), set_root() functions? Mandatory arguments to the
> constructor, can be done as construct-only properties, but
> language bindings (and GUI builders) are happiest if there
> are no mandatory arguments at all.

Both are mandatory arguments and should be implemented as construct-only
properties. Changing model and vroot after construction is really
painful, and it would be much faster to just create a new filter model.
I don't see much point in changing this function as there will be
construct-only properties (if I remember correctly I already added
those).

> 
> > void          gtk_tree_model_filter_set_modify_func            (GtkTreeModelFilter            *filter,
> >                                                                 gint                           n_columns,
> >                                                                 GType                         *types,
> >                                                                 GtkTreeModelFilterModifyFunc   func,
> >                                                                 gpointer                       data,
> >                                                                 GtkDestroyNotify               destroy);
> 
> Hmmm, there is some argument that the API here for providing the
> types should parallel gtk_list_store_new/newv. 

Agreed.

> 
> > /* conversion */
> > void          gtk_tree_model_filter_convert_child_iter_to_iter (GtkTreeModelFilter            *filter,
> >                                                                 GtkTreeIter                   *filter_iter,
> >                                                                 GtkTreeIter                   *child_iter);
> 
> I think this function makes sense, but it is probably worth noting in
> the API docs that this function has to convert the iter to a path and
> back, since otherwise people may think that it is more efficient
> than the path version and jump through hoops to use it instead.

Indeed. I will add the same note to the GtkTreeModelSort docs.

> 
> > void          gtk_tree_model_filter_refilter                   (GtkTreeModelFilter            *filter);
> > void          gtk_tree_model_filter_clear_cache                (GtkTreeModelFilter            *filter);
> 
> What do these do?

_refilter basically emits a row_changed signal for each child node, so
the ModelFilter will "refilter" the node. This is of course pretty slow.
Though it is useful when you change the requirements for being visible
in the visible function.

_clear_cache comes from the ModelSort and clears the model of any cached
iters that haven't been reffed with gtk_tree_model_ref_node().


I hope this helped,



	-Kris

> 
> Generally, looks really sensible, straightforward and useful.
> 
> Regards,
>                                         Owen
> _______________________________________________
> gtk-devel-list mailing list
> gtk-devel-list gnome org
> http://mail.gnome.org/mailman/listinfo/gtk-devel-list



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