Older blog entries for lgs (starting at number 9)

Somebody told me Python is an easy language and it's fun to program with it. Very true. But what about Python development? Specifically Python bindings development? Well, it's a nightmare, I can tell you.

After having my first GtkGrid version released yesterday (0.0.1) I decided to make the Python bindings today. It began very good: I understood pretty well how the h2def.py, override files and python-codegen.py works all together to create a Python C module.

But then problems started to arrive in no particular order. First my gtkgrid module didn't get imported properly and I got an undefined reference to a function codegen was putting on grid.c. After asking to gjc he told me it was probably a bug in codegen. So I filled a bug report in bugzilla and to my surprise gjc had a patch 20 minutes later!! This is user support and not what some big companies claim they do. I applied the patch and everything worked smoothly. :)

So next step was to show my cute small binding to the world but proper autotools stuff was needed for that because I was using a hard coded Makefile to build the module. And this is where the second part of the nightmare began.

I looked at the diacanvas2 Makefile.am/configure.in files. I looked at the pygtk Makefile.am/configure.in files and I copied everything pretty literal but it didn't work. I copied the pygtk autogen.sh file and some m4 macros and got some errors fixed, but still didn't work. After more than 2 hours reading autotools documentation and trying different aproaches I go really frustrated. I was also a little bit tired.

Then I give distutils a try and can you believe it? In less than 5 minutes I got it working. So after a whole day my conclusions are:

  • pygtk developers are really nice guys that will help you
  • autotools are a nightmare only designed to make your head explode
  • Python tools are nice and you should use them and avoid using C tools for things different than C.

Well, let's see if somebody gets interested in the (in)famous Grid

After several days I managed to have the scrolling working not without some pain. You know, expose areas are evil specially if you assume things you shouldn't...

GtkTreeView scroll is different for vertical and horizontal directions. I still don't know why this inconsistency but I decided to do both directions identical. The main reason is code readability. I'm a Python programmer so you can guess speed is not my top priority...

Next thing in mind is to support mouse clicks to change the current cell.

11 Feb 2004 (updated 13 Feb 2004 at 09:49 UTC) »

Things are getting complicated...

First the Allocate nightmare. When the user enters into a cell I call gtk_cell_renderer_start_editing and it gives me a brand new GtkCellEditable widget. Then I put it on the Grid by calling gtk_size_allocate but it is not shown properly and I can't give it the focus. Thanks to Owen who iluminated me and told me that only inside the gtk_size_allocate of the Grid it is legal to call gtk_size_allocate on the children of the grid. Yes, the GtkCellEditable widget must be a child of the Grid. First problem solved :) . You can see how nice are the GTK+ Gurus by reading this piece of IRC chat:

<lgs> is it legal to call gtk_widget_size_allocate without calling gtk_widget_size_request if we don't care about our children wishes?
<owen> lgs: No. A) The only time a custom widget is allowed to call gtk_widget_size_allocate() is in it's gtk_widget_size_allocate() handler
<owen> B) A widget must call size_request() on all children in it's size_request() handler, even if it ignores the result
<lgs> owen, what if I add a child after the size_request of the parent has been called
<owen> Actually also A') A custom widget must call gtk_widget_size_allocate() on all its children in it's size_allocate() handler
<lgs> owen, what's the equivalent to gtk_widget_queue_draw, for size issues?
<owen> lgs: When you add a child, GTK+ automatically queues a resize, so you'll
get a size_allocate()
<owen> lgs: gtk_widget_queue_resize()
<lgs> how gtk+ knows that I added a child? when I call gtk_widget_set_parent?
<owen> lgs: Yeah
<lgs> cool, thanks a lot owen
<lgs> that makes me understand a little bit more of the gtktreeview.c code

After some time playing with the key bindings of the Grid I realized that what I needed to do is to listen for key presses in the GtkCellEditable and move the focus that way. So I got moving left and right of my grid and it worked.

But moving up and down didn't work because strangely I wasn't getting up and down key press. I dived into the GtkEntry code and I discovered why: when calling gtk_cell_editable_start_editing it connect a signal handler to the key press event and check if the user press these arrows to do something special. Solution: noo to call gtk_cell_editable_start_editing. Second problem solved :)

But best of all, while I'm writing these lines people in the #gnome-hispano channel (setepo and apg) are fixing bugs and giving me suggestions (Devin). I feel the power of free software ...

After the orkut effect this weekend I didn't code too much. Luckily I managed to advance a little bit today.

I needed to see the libgnomecanvas code to see how to generate the marshaler for my first signal: "move-cursor". So changes to configure.in and Makefile.am were mandatory.

All this for what? Well now you can use the arrow keys to navigate through the cells of the grid. No edition so far but at least you can see how the focus changes.

A screenshot is worthy again. See how the cell 3, 2 is the current cell.

3 Feb 2004 (updated 3 Feb 2004 at 11:10 UTC) »

Some more progress: now the grid uses the GtkListStore as its model. We are a little bit closer to the MVC architecture.

Wanna see more screenshots? Well this time nothing is really spectacular but I can tell you is a important step to separate the data from the widget. Ok, the screenshot is here.

Now it's time to paste some code. As an add-on, the GtkGrid API will be pretty similar to the GtkTreeView one, so programmers will not need to learn a lot of different things. Let's see an example of how to use it:

  /* Create the model and populate it */
  for (i=0; i<n_columns; i++)
    types[i] = G_TYPE_STRING;

model = gtk_list_store_newv (n_columns, types);

for (y=0; y<n_rows; y++) { GtkTreeIter iter; gtk_list_store_append (model, &iter); for (x=0; x<n_columns; x++) { GValue value = { 0, }; g_value_init (&value, G_TYPE_STRING); snprintf (buffer, 99, "cell %d %d", y, x); g_value_set_string (&value, buffer); gtk_list_store_set_value (model, &iter, x, &value); } }

/* Create the grid with the model */ grid = GTK_GRID (gtk_grid_new_with_model (model));

for (i=0; i<n_columns; i++) { renderer = gtk_cell_renderer_text_new (); column = gtk_grid_column_new_with_attributes ("testing", renderer, "text", i, NULL); gtk_grid_append_column(grid, column); }

Well, things are going pretty well so far but I guess that's because I'm just biting the edge of the iceberg. The easy parts, in other words.

I have a demo with 10 columns and unlimited rows that use GtkCellRendereText with data created on the fly. You can see it right here

Next step: to use the GtkListStore

Mental note: I need to write some design documents right now because every time someone ask me for the Grid I keep repeating the same boring stuff.

Well, things are going pretty well so far but I guess that's because I'm just biting the edge of the iceberg. The easy parts, in other words.

I have a demo with 10 columns and unlimited rows that use GtkCellRendereText with data created on the fly. You can see it right here

Mental note: I need to write some design documents right now because every time someone ask me for the Grid I keep repeating the same boring stuff.

First steps towards the use of Gtk Renderers. Now I have a GtkGridColumn class pretty similar to GtkTreeViewColumn and it will use renderers.

The demo program is used for testing purposes so far and is going pretty well. I have a toy grid with two columns and two renderers.

For those of you who care about this I set up a subversion repository at

svn://www.sicem.biz/sicem/gtkgrid

Finally it seems that there are people interested in a Grid like acs :)

25 Jan 2004 (updated 27 Jan 2004 at 17:50 UTC) »

Some progress with the GtkGrid. After trying to get my expose method called without success I realized I have to add the GDK_EXPOSURE_MASK to the main gdk window of the widget.

Then I played with some gtk_paint_* functions and this is what I got. It starts looking like a real Grid :)

This is my tentative Roadmap for the Grid:

  1. Create a GtkGridColumn class that will hold the renderer for that column
  2. Add GtkGridColumns to the GtkGrid and modify the expose event to use the renderers instead of hardcoded drawing stuff.
  3. Add a model property to the GtkGrid and make sure it is a GtkListStore
  4. Work on some key events to navigate through the grid
  5. Add scrolling support
  6. Add more gdk windows for the header and the left sidebar
  7. Make the header and sidebar functional by letting to select whole rows and columns
  8. Gettext support for properties
  9. Drag and drop of columns and rows

You don't see dates on that roadmap, that's right because I don't know how long will it takes me to write each step as this is the first widget I write.

23 Jan 2004 (updated 23 Jan 2004 at 11:58 UTC) »

Yesterday I started to work on a GTK+ widget. After trying the GtkTreeView extensively and talking with some GTK+ gurus (Owen and Kris) I decided to write a Grid Widget from scratch.

I also tryed GtkSheet from the library gtkextra and it is pretty good. But the code is too big and I doubt it will ever get into the gtk library.

So my main goals are (order is significant):

  1. To get a Grid widget for easily edition of big amount of tabular data (think about databases).
  2. To learn how to create a gtk widget
  3. To learn how to create python bindings from a gtk widget
  4. Ideally, to get my code into the gtk library :). There is a bug in bugzilla.gnome.org asking for this widget so if my code is not too bad I may be lucky

So far I have read Havoc's book, gtktreeview.c and the GLib Object System tutorial. I also have the autotools working for this project and already typed some boilerplate code

Let's see what happens....

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!