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.

No comments:

Post a Comment