A Week for Releasing

I’ve set a deadline for doing a weekly post. Well, last week, I missed. It was a really busy week. I was building a web-page, and I haven’t done that in like 10 months or something so I had a lot to catch up. It was fun, though. I’m right now looking forward to start playing around with Rails 4

On the other side my Gnome duties caught up with me. I’ve been acting as Contacts maintainer with Alex for a while now. But so far, he was doing the releasing part. I, usually, implemented new stuff, reviewed patches, fixed bugs, but no more. This past week since Alex is on vacation I had to fill in doing the release.

I was prompted by Matthias Clasen for doing a release of gnome-contacts for the 3.9.4 development release of Gnome. In the process, I realized I can’t log into master.gnome.org for the purposes of uploading the packages. So, Mathias kindly offered himself to upload the package. Later I got my account authorized, and I was able to release gnome-contacts-3.8.3. This latter one, I was surprised to see it packaged this morning into Archlinux.

These two releases are only bug fixes, yet there nasty bugs fixed there. You can read the NEWS file, or the commit log to find about.

What’s next on Contacts ? I want to implement New Contact flow inline and get rid of dialog, and close a bunch of bugs around it. Also, yesterday I got a bug from Allan about updating a bit the selection pattern, and I would like to work on it.

Update: I have to thanks Jonh Wendell for his fix of the webcam bug.

June Update on Calendar

I’ve made a commitment with myself of posting updates of the stuff I’m working once a week. This one is the first, and I expected to be out by Monday, but an octopress update and a plugin installation for handling image galleries kept me from doing it.

By now, I’m a little tired of writing, therefore I’ll be quick about it.

A few weeks ago I restarted the work on Calendar with the hope of adding a bunch of new features in Gtk+ to the project. I started by creating a new branch, since I was sure the build would break a lot times in between, and didn’t want to spoil master

I’d set for myself a bunch of points I want to accomplish by rewriting the UI and some of them has been done, some others, not yet. That’s the main reason why I keep the branch still around. As soon as I feel the work is done, I’ll come back to work on master

I wanted to:

  1. Ditch clutter dependency. Use only Gtk+ widgets.
  2. Include GtkSearchBar, GtkStack and some of the latest Gnome UI guidelines
  3. Use GtkBuilder’s ui files as much as I can
  4. Rework week-view to use GtkOverlay instead of my own solution

So far 1, 2 and 3 has been accomplished. Point number 4 is going well since I manage to craft a day-view with the same requirements of week-view that does not need to use GtkOverlay.

Some of the work done is showcased below

Software Updates

It’s been a very long time since I posted anything. You might not know, I live in Santiago de Cuba, Cuba, one of the cities trashed by the hurricane Sandy. That left us a bunch of loses and lack of communication for weeks. We went without power for at least 14 days, so you can imagine why I was not posting updates. Some time has passed and the city is growing back from its ashes.

I’ve been working on Calendar, trying to get some minimal functioning application, to get something out for you to use, and then I can continue improving the rest. For now, I’ve focused on enable a fully working the “Event Details” dialog. The thing is kinda clunky yet, but it works. It needs more polish and heavy testing, though.

I also went and made a year-view implementation, which is almost fully functional. This one was easy, was almost copy/paste from the old month-view implementation. The month-view also received a full face-lift. The previous version had some super-rough edges when months didn’t fit in a 35 cells grid. That has been fixed, our designers pulled some rabbits out of their hats. The new design, which is already implemented suggest a scrolling animation, but I want to be sure it works before going into it.

I’m trying to get Calendar in beta shape for 3.8 release. I’m still need to implement three views: list-view, day-view and week-view, and the search mechanism, with the results showing. For the week-view I have an implementation which have scrolling issues, I have to take care of.

Some minor mojo I don’t want to pass unnoticed:

  • Squared buttons in the toolbar, thxs to Debarshy Ray for the suggestion and Cosimo’s libgd for the hack.
  • We added a proper use of g_clear_object
  • Simple keyboard shortcuts, for Quit and change amount views.

Now some screenshots

A Challenge of Locales

When developing an application aiming for everyone worldwide to use, there are certain challenges you will face. Right now, mine is fighting laziness and locales.

I’m developing some widget for specifying a date and I’ve been struggling with date formats across locales So, after reading a huge number of manpages, source-code, and so on I stumble on this code.

#include <langinfo.h>
#include <locale.h>
#include <stdio.h>
#include <stdlib.h>

int
main(int argc, char *argv[])
{
  setlocale(LC_ALL,"");
  printf("%s\n",nl_langinfo(D_FMT));
  exit(EXIT_SUCCESS);
}

This will show me your date format according to your locale. What I will ask, compile and run this code in your pc, and post the answer here along with your locales.

See you around.

Update: Thxs for the comments. Two things: I’ve just updated the code, thxs to Tom, adding setlocale line made the code works. Second: Thxs to Tommi (first comment). That was the info I was looking for.

Making You Own Widget

A few days ago, I was in gtk+ irc channel and there was someone making the kind of question I’ve done myself like a hundred times. Thankfully the guys in the channel hasn’t got tired of me, yet. They are pretty helpful once they realize you’ve done your homework.

Once you start hacking around with Gtk+, the next thing you’ll want to do is to make your own widgets. And for that there’s little to none documentation, guides or tutorial. There’s a huge amount of knowledge in Gtk+ source itself, but most people doesn’t like to read code, or doesn’t know how to. They should, though

Here I’ll try to show, from the newbie point, how Gtk+ draw things, and what’s the guidelines to accomplish certain tasks when making widgets for Gtk+. This is, as well, a reminder for myself, since most times I need to go into IRC to ask the same things all over again.

I will split the post in three main sections which corresponds to the important parts in a widget lifetime.

Size handling

One of the thing you need when you’re making widgets is knowing the dimensions everything will have inside. Size requisition and allocation is the step where this happens.

Explanations of this process appears here in GtkWidget’s documentation. It includes most of the size requisition process and geometry management.

Gtk+ widgets are arranged in a hierarchy where container widgets pack others and handle its size and allocation. The widget containing yours will ask the natural and minimal size you want to have, and after making some internal calculations will assign your widget a size and allocation. The first part is called size requisition and the second size allocation. The virtual methods you need to implement here are:

Now, what to do on each one of these methods ?, Calculate what size you want for the widget, and return it. Let’s say you have a widget which have a text saying “Hello” inside, then, you need to ask Pango to calculate the width and height for you, add the margins and padding (if you want to take those into account) and return the size accordingly.

What’s width-for-height and height-for-width methods for ?, Widget have by definition one request-mode, its width depends on its height or the other way around. This is totally decided by you, accordingly to the type of widget you’re creating. The purpose of these methods is to retrieve these measures, the width of a widget given a specified height, and viceversa. About this part, read carefully the docs above and go asking in the IRC for more help if stuck.

One thing to keep in mind is that the allocated size to your widget, could be not the same you requested in the get_preferred methods, so the widget should work with the given allocation instead of any other measure.

Rule of thumb: Implement the four methods of size requisition almost always, and the size-allocate one if needed.

Drawing stuff

This is the core of the matter, but there’s no much to tell in here. Use cairo to draw, the API is pretty simple. Use cairo primitives to draw inside the implementation of draw virtual method. There, is given a context which is clipped from one of the GdkWindow of the widget, you should draw in that context. Other than this, here are some remarks:

  • How to draw an icon from the theme into the cairo_context_t ?. Obtain a GdkPixbuf from the icon with gtk_icon_theme_load_icon or gtk_icon_info_load_symbolic depending on the icon, and draw it to the context with gdk_cairo_set_source_pixbuf

  • How do I get my lines subpixel thin ?. Turns out that cairo can draw lines thinner than one pixel, but for that to happen you need to place the cairo starting point in the middle of the pixel, so the drawing can be made, and look just like you want.

    /* a vertical 0.3 pixel line */
    cairo_set_line_width (cr, 0.3);
    cairo_move_to (cr, 10, 10.4);
    cairo_rel_line_to (cr, 0, 10);
    cairo_stroke (cr);
    

Finally, use whenever you need gtk_render_background, gtk_render_frame family and friends over any alternative drawing you could think of doing. These functions will get colors and border size and radius from the CSS theming engine, therefore you’re spared a bunch of work.

Processing events

How to receive and handle mouse, touch and button events. My first attempt to catching and handling event was to implement virtual method button_press and button_release, that didn’t worked. Not that easily.

For catching input events in your custom widget, you will need a GdkWindow suited for those purposes. The preferred idiom here is:

  • In your realize method, create a GdkWindow with gdk_window_new and set its type to GDK_WINDOW_CHILD, this would assure to catch the input events if they occur inside you window. After created the window, call gdk_window_show to show it. You will use gdk_window_set_user_data to relate the window with your widget.
  • In your size_allocate method, you need to place the window where it should, by using gdk_window_move_resize.
  • Now, you can implement button_press and the likes of them to handle your events.

There are virtual methods for handling mouse button presses, and a releases, but no for high-level actions as click and double-click, you need to detect those by detecting sequences of presses and releases. Nonetheless, for double-click the GdkEventButton will have the type field set to GDK_2BUTTON_PRESS which will certainly help. For key-press/release events, I have to say, I haven’t had nothing to do with those yet. So, that will be left to the next time.

Putting things together

I won’t paste the code entirely, I’ll just describe the order in which the above mentioned steps will most likely occur.

Usually, as you must have guessed by now, the first thing your widget will receive is a request for its preferred size using gtk_widget_get_preferred_width and friends. After that, the parent will follow to allocate the size, there your implementation of size_allocate will run, and then, the painting will happen. About the realize part, it will happens almost anytime, the only thing you can be sure of is: it will happens before your widget had to paint itself. One thing worth mentioning is that a widget could be allocated a bunch of times before it ever gets to the painting part.

About a full example of code, one the simplest widgets for showing all of this is GtkButton. You can read the source of in the Gtk+ tree. Here’s the header: gtkbutton.h and the source gtkbutton.c. As I said above, reaching into Gtk+ internals is the best way to learn to use the toolkit and the framework.

Conclusion

Obviously this a pretty simple post about some of the more common tasks you’ll meet with when making a custom widget. There are several more complex widgets which are far from this, but those are left for later.

Hope it helps, and if you find any mistake, please contact me immediately so I can fix it.