Shotwell uses a layered model approach for this problem. There's a signalled SourceCollection which contains all the objects known to the application, i.e. every photo in the library.

Each page of the application (i.e. Events, Tags, Last Imported, etc.) has a signalled ViewCollection which subscribes to the SourceCollection's signals and populates itself with whatever objects it wants to show. That is, the ViewCollection is where filtering, sorting, even aggregation of multiple SourceCollections (i.e. display photos alongside videos) occurs.

The UI layer subscribes to the ViewCollection's signals, populates the screen with widgets, and reacts to signals being fired to update itself.

I don't know this is the approach everyone should use, or even if it's appropriate here, but we've had great success with this inside of Shotwell. At one point I thought about adapting and simplifying it into a library that built upon Gee (a signalled collections library) but never got that going.

I spoke about this with Lars Uebernickel at Montreal, and would be happy to discuss it further with anyone else interested as well.

-- Jim

On Thu, Oct 24, 2013 at 8:45 AM, Xavier Claessens <xclae...@gmail.com> wrote:
I definitely second that. Empathy/Contacts can easily have between 1000 to 5000 rows and I've measured that widget creation (and destruction) in
GtkListBoxRow is a real bottleneck. It's a bit hidden by folks having
even worse performances, though (but it improved recently and I did not
re-test).

I've opened https://bugzilla.gnome.org/show_bug.cgi?id=710414 for this
recently.

Another thing I would like to suggest for the model is advanced
filtering. I've implemented it on GtkListBox but it could be a model
thing instead. Dunno. See
https://bugzilla.gnome.org/show_bug.cgi?id=710204

On mer., 2013-10-23 at 11:57 +0200, Alexander Larsson wrote:
 More and more gnome apps are migrating to GtkListBox rather than
 GtkTreeView for lists, and we now have GtkFlowBox that replaces
 GtkIconView. These are nice for smaller lists, but with larger lists
 they are a bit heavy. We may want to look at optimizing whatever is
possible, but at some point it makes sense to have a model/view split
 that allows us to have large models without having each item in the
 model be instantiated as a widget, both for performance reasons
 and ease of use.
I've been thinking of ways to do this, and had plans to implement this, but atm I'm busy working on a side project, so I don't have time
 for this atm. I thought I'd write up a braindump of my ideas so that
 maybe someone else can look at it, or at least it won't be losts.
So, the general idea is that we have a model, and we create and update
 row widgets from the model based on some kind of template. The new
 GtkBuilder class templates is an excellent example of how this could
 work. We then create widgets as needed as they are scrolled into (or
 near) view. One obvious problem with this is that we don't know the
 height of the rows until we have widgets for them, so the listbox
probably has to be changed to implement GtkScrollable and do scrolling
 based on row-nr and average height rather than exact offsets.
The model itself is a set of GObjects, where the data in the model is
 stored as GObject properties. This is very flexible, in that we have
 names (no more column nr shit) for the data that is easy to map to
 properties (like GBinding, possibly with some transform function) in
 the row widget template, as well as to generic sorting/filtering
 functions. Property notification makes incremental updates
 possible. The GProperty work being done will make it very simple to
 create such model objects, and make property lookups very
efficient. Then we need to add a GObjectSet interface that has signals for when objects are added and removed to the set, which would be used as the model itself, but also as a property type for recursive models
 (i.e. trees).
View updates on a model like this can be pretty efficient. We connect
 to the added/removed signals on the set and keep track of the items
 (and per-view info like selection status) in the view in a sorted &
 filtered GSequence, then we connect to notify on all the model
 elements and whenever we get it we look up the GParamSpec to see how
 it affects the model (i.e. are we filtering/sorting/showing the
changed property). If anything is affected we flag things in the view
 and request and update on the frame clock, so that we can minimally
 update the view structure and any visible widgets at most once per
 frame.
I believe we should also have some sort property caches in the view
 objects. For instance any sort by string we should be monitoring
changes to the corresponding property and keep a g_utf8_collate_key()
 or g_utf8_collate_key_for_filename() key up to date for fast
comparisons. That should easily integrate with the update cycle above. We should also allow sorting based on object relationships. For instance, if we had a "GObject *parent" property that could be used to
 create a tree view if the view supported specifying that a child
 should be sorted directly after its parent. You can event do more
complex structures like the twitter-style "expand in-reply-to/replies
 before/after a tweet".
_______________________________________________
 gtk-devel-list mailing list
 gtk-devel-list@gnome.org
 https://mail.gnome.org/mailman/listinfo/gtk-devel-list


_______________________________________________
gtk-devel-list mailing list
gtk-devel-list@gnome.org
https://mail.gnome.org/mailman/listinfo/gtk-devel-list

_______________________________________________
gtk-devel-list mailing list
gtk-devel-list@gnome.org
https://mail.gnome.org/mailman/listinfo/gtk-devel-list

Reply via email to