Re: g_signal



John Darrington wrote:

Can someone point me to  an example of how to create a g_object that
emits g_signals.  The `documentation' is nothing more than a list of
function prototypes.  Furthermore, g_signal.h is uncommented...

Look at attached example, there's an GObject derived from GtkButton.
It emits "pushed" signal when his parent emits "clicked".

Olexiy



/*
        Simple GObject with one signal. Derived from GtkButton, emits "pushed" signal
        on GtkButton's "clicked".

        Can be compiled with smth like:
        gcc -Wall `pkg-config gtk+-2.0 --cflags --libs` -o sig -o sig.c

                Olexiy Avramchenko
*/

#include <gtk/gtk.h>


/* simple GtkSigObject implementation { */

#define GTK_TYPE_SIG_OBJECT     gtk_sig_object_get_type()
#define GTK_SIG_OBJECT(obj)     G_TYPE_CHECK_INSTANCE_CAST((obj), GTK_TYPE_SIG_OBJECT, GtkSigObject)

typedef struct _GtkSigObject
{
        GtkButton       parent_instance;
} GtkSigObject;

typedef struct _GtkSigObjectClass
{
        GtkButtonClass  parent_class;
} GtkSigObjectClass;


enum {
        SIG_OBJECT_SIGNAL_PUSHED,
        SIG_OBJECT_LAST_SIGNAL
};

static gint sig_object_signals[SIG_OBJECT_LAST_SIGNAL] = {0};

static void gtk_sig_object_class_init(GtkSigObjectClass *klass)
{
GObjectClass *object_class;

        object_class = G_OBJECT_CLASS(klass);

        /* creates "pushed" signal */
        sig_object_signals[SIG_OBJECT_SIGNAL_PUSHED] =
                g_signal_new(
                                "pushed",
                                G_TYPE_FROM_CLASS(klass),
                                G_SIGNAL_RUN_FIRST,
                                0,
                                NULL,
                                NULL,
                                g_cclosure_marshal_VOID__VOID,
                                G_TYPE_NONE,
                                0
                );
}

GType gtk_sig_object_get_type()
{
static GType sig_object_type=0;

        if (!sig_object_type)  {
        static const GTypeInfo sig_object_info =
        {
                sizeof(GtkSigObjectClass),
                NULL,
                NULL,
                (GClassInitFunc)gtk_sig_object_class_init,
                NULL,
                NULL,
                sizeof(GtkSigObject),
                0,
                NULL,
                
        };
                sig_object_type = g_type_register_static(
                                                                GTK_TYPE_BUTTON,
                                                                "GtkSigObject",
                                                                &sig_object_info,
                                                                0
                );
        }
        
        return sig_object_type;
}

static void gtk_sig_object_clicked(GtkWidget *widget)
{
        /* here emits the "pushed" signal */
        g_signal_emit(widget, sig_object_signals[SIG_OBJECT_SIGNAL_PUSHED], 0);
}

GtkWidget *gtk_sig_object_new()
{
GtkWidget *widget;

        widget = GTK_WIDGET(g_object_new(GTK_TYPE_SIG_OBJECT, NULL));

        g_signal_connect(G_OBJECT(widget), "clicked", G_CALLBACK(gtk_sig_object_clicked), NULL);

        return widget;
}

/* } simple GtkSigObject implementation */


/* creates and shows the dialog on "pushed" */
static void pop_dialog(GtkWidget *widget, GtkWindow *window)
{
GtkWidget *dialog;
GtkWidget *vbox;
GtkWidget *label;
GtkWidget *button;

        dialog = gtk_window_new(GTK_WINDOW_TOPLEVEL);
        gtk_window_set_modal(GTK_WINDOW(dialog), TRUE);
        gtk_window_set_transient_for(GTK_WINDOW(dialog), window);
        gtk_container_set_border_width(GTK_CONTAINER(dialog), 8);
        g_signal_connect(G_OBJECT(dialog), "delete_event", G_CALLBACK(gtk_widget_destroy), NULL);

        vbox = gtk_vbox_new(FALSE, 0);
        gtk_container_add(GTK_CONTAINER(dialog), vbox);

        label = gtk_label_new(NULL);
        gtk_label_set_markup(GTK_LABEL(label), "we just got <big><u>pushed</u></big> signal!");
        gtk_box_pack_start(GTK_BOX(vbox), label, FALSE,FALSE, 0);

        button = gtk_button_new_from_stock(GTK_STOCK_CLOSE);
        g_signal_connect_swapped(G_OBJECT(button), "clicked", G_CALLBACK(gtk_widget_destroy), dialog);
        gtk_box_pack_start(GTK_BOX(vbox), button, FALSE,FALSE, 4);

        gtk_widget_show_all(dialog);
}

int main(int argc, char **argv)
{
GtkWidget *window;
GtkWidget *vbox;
GtkWidget *sig_object;
GtkWidget *button;

        gtk_init(&argc, &argv);

        window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
        gtk_container_set_border_width(GTK_CONTAINER(window), 8);
        g_signal_connect(G_OBJECT(window), "delete_event", G_CALLBACK(gtk_main_quit), NULL);

        vbox = gtk_vbox_new(FALSE, 0);
        gtk_container_add(GTK_CONTAINER(window), vbox);

        /* creating our object */
        sig_object = gtk_sig_object_new();
        /* setting the label for parent's GtkButton */
        gtk_button_set_label(GTK_BUTTON(sig_object), "pu$h me");
        gtk_box_pack_start(GTK_BOX(vbox), sig_object, FALSE,FALSE, 4);
        /* connecting callback to "pushed" */
        g_signal_connect(G_OBJECT(sig_object), "pushed", G_CALLBACK(pop_dialog), window);

        button = gtk_button_new_from_stock(GTK_STOCK_QUIT);
        g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(gtk_main_quit), NULL);
        gtk_box_pack_start(GTK_BOX(vbox), button, FALSE,FALSE, 0);

        gtk_widget_show_all(window);

        gtk_main();
        return 0;
}


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]