Sunday, September 25, 2011

Drawing a pixbuf with cairo

I wanted to be able to add an image to a drawing area and draw onto it with cairo. The standard way to draw an image with cairo is to use a surface, created for example with cairo_image_surface_create_from_png. This seems to limit you to various image formats, in my case the images I want to use are in a non-trivial format (BAS image plate scans) which I can get into pixbuf format. I'm not sure if this is the best solution, but I used
pixbuf = gdk_pixbuf_scale_simple (pixbuf, GDK_INTERP_BILINEAR);

gdk_cairo_set_source_pixbuf (cr, pixbuf, 0, 0);

cairo_rectangle (cr, 0, 0, width, height);

cairo_fill (cr);
where width and height are for the drawing area.

Tuesday, September 13, 2011

Gtk with Anjuta, first steps.

I've recently been trying out Gnome 3 after installing Fedora 15. I worked through the developer tutorials (Image viewer and the guitar tuner) for developing using Anjuta with Gtk. I remember from looking at a glade tutorial a few years ago, that a useful technique is to create a struct as a central store for widgets and other data, which can then be passed to every callback as user_data. So I thought I'd have a go...

After creating a project in Anjuta (using the simple Gtk option), I used the designer to add a button box and a few controls. I added a button, two range widgets and a label. The idea was just to test if I could set some values with the range widgets, then update the label when the button is clicked.


I then added a typedef struct called xy_t at the top of main.c which stores two values x and y, as well as a label widget.
#include <config.h>
#include <gtk/gtk.h>

typedef struct
{
     int x, y;
     GtkWidget *label;
} xy_t;
At the top of the create_window function, create a struct of type xy_t called data:
    xy_t *data;
    data = g_slice_new (xy_t);
    data->x = 0;
    data->y = 0;
After loading the UI, we need to connect the label in the data struct with the label from the builder.
    data->label = GTK_WIDGET (gtk_builder_get_object 
        (builder, "label"));
Then pass the data structure to all the callback functions:
    gtk_builder_connect_signals (builder, data);
Then add a few callbacks (above the destroy callback). The range widgets update the values of x and y. When the button is clicked, it updates the label with the values of x and y.
    void
    print_xy (GtkButton *button, gpointer user_data)
    {
         xy_t *point = user_data;
         int x = point->x;
         int y = point->y;
         printf("%d %d\n", x, y);
         char l[10];
         sprintf(l, "%d %d", point->x, point->y);
         gtk_label_set_text (point->label, l);
    }
    void
    update_x (GtkRange *range, gpointer user_data)
    {
         xy_t *point = user_data;
         int val = gtk_range_get_value (range);
         point->x = val;
         printf("label %d\n", val);
    }
Pretty pointless, but I just wanted to demonstrate to myself how to create a struct which can then be passed to all the callback functions. The struct can contain widgets which must be linked to the widgets created by the builder. It may not be the best way to do it, but it seems to work, and maybe useful for other novices like me for whom it isn't obvious.

Monday, September 12, 2011