21 Mar 2005 lgs   » (Master)

Grid widget (again)

After a long time without talking about this, one of my favourite subjects, it's time to revisit this topic. The problem is GTK+ does not provide a widget for grids like the ones in GNUCash or (ehem) Microsoft Access. This kind of widgets are pretty useful when all the rows has the same format (e.g., every column has a type and other attributes) and the user needs to edit the data *fast*. Note that a Sheet, like the widget used in Gnumeric or other spreadsheet programs, does not have that property: one column can have different data types in different rows.

Are you sure GTK+ does not have that widget? What about the powerfull GtkTreeView? Yeah, you are right. The GtkTreeView is a damn cool widget with the features we are looking for:

  • Every row has the same format
  • You can edit the cells

Not to talk about the tons of other nice features the GtkTreeView also have (MVC architecture, sortable, filterable, column orderable, flexible renderers, ...). My only problem about the GtkTreeView was that the editing of the cell was not fast enough. With a standard configuration of a GtkTreeView the user needs to go to a cell, press enter to put it on editable mode, edit the cell and press enter again. Too much keystrokes == no fast editable.

Well, that was in the old pre 2.6 days. Now there is a way to make the TreeView fast when talking about editing. It is called 'start-editing' signal on the renderers. In 2.4 the problem was that once you start editing a cell you didn't have access to the widget used as the cell editor (usually a GtkEntry) so you couldn't connect a key-press-event handler to see what key the user pressed to go to the next cell. This is exactly the problem 'start-editing' solves in 2.6. Actually it is useful for many other cases.

I even started my own GtkGrid project to work around this problem in 2.4 which I don't regret at all even when now it is not necessary anymore. I learned a lot of things doing this:

  • How to write a widget from scracth in C
  • How to write Python bindings for such a widget
  • How to read more than 30.000 lines of code (GtkTreeView and friend classes) and not to die

Now for the lessons learned:

  • When you need a feature in GTK+ first ask *very politely* to the maintainers if it can be done. Note the difference between 'it can be done' and 'will you do it?'. I don't think I was unpolited in the above story, the problem was I just assumed that they will do it if it was a good idea. Now I know, there are too many good ideas in bugzilla.gnome.org that don't get done just as a matter of (lack of) resources.
  • If they say yes go to the code and try to write a patch for that. No matter how hard it seems to be. Writing something from scratch is almost always harder. Having a patch will give your request much more chances to be implemented. Be prepared to modify your patch as many times as the maintainers told you until they seem happy with it.
  • If they say no, don't give up, go to the code and see if there are some ideas the maintainers didn't considered and talk with them about those in a GTK+ meeting
  • Even then, maybe the feature you are requesting does not have its way in GTK+. Maybe this is the time to write something from scratch, but please, try the other steps first.

As Johan said, it seemed I had a problem with communication with this grid issue. I could have written a patch to add this 'start-editing' signal to GtkCellRenderer and showing its utility it may have been accepted. The problem was I didn't know enough about GTK+ internals to do this. Then when writing my widget I got this knowledge and that was when I should have written the patch. But it's too hard to throw away your code and do the right thing in this situation. Btw, I hate the fact that Johan is almost always right :-)

I have a demo of this concept that work pretty good but also has a couple of hacks. Let me know if you want to take a look at it.

Latest blog entries     Older blog entries

New Advogato Features

New HTML Parser: The long-awaited libxml2 based HTML parser code is live. It needs further work but already handles most markup better than the original parser.

Keep up with the latest Advogato features by reading the Advogato status blog.

If you're a C programmer with some spare time, take a look at the mod_virgule project page and help us with one of the tasks on the ToDo list!