Re: What signals should I be using with a GtkCombo?



On Wed, 2001-09-05 at 02:52, Skip Montanaro wrote:
> (hopefully this will only go out once.  i've been having email config
> problems today.)
> 
> I must just not be thinking about this right, but I'm having trouble
> figuring out what signal(s) I should be connecting to for a
> GtkCombo. GtkCombo's contain both an entry and a list, and either can be
> used to change the value.  It seems to me like GtkCombo ought to emit its
> own "value-changed" signal, but it doesn't.
> 
> The best I've been able to come up with is to connect to the GtkEntry's
> "activate" signal and the "selection-changed" signal of the GtkList.  That
> doesn't seem right either, since the activate signal of the GtkEntry is
> normally used to pop up the list, so I'd have to call gtk_combo_disable_
> activate to use the entry's activate signal.  Is that the usual way?

I agree completely. I've looked a bit at the combo resently, and the API
doesn't strike me as particularly well chosen...

> I think GtkCombo should provide a value-changed signal along with a
> get_value method, but maybe I'm thinking too high-level. ;-)
> 
> Any suggestions appreciated,

'ere you go then. I've attached a widget that wraps the combo and
translates the entry's "changed" and the lists "select-child" into
"changed" events. It isn't particularly polished, but you can get there
from this.

It is a quick hack to add this one feature, and probably requires a lot
more work to be generally useful, but since I am not in a pressing need
for an improved combo I'm not going to go further with it. It is yours
to hack with.

	/mailund

-- 
Atheists are people who have no invisible means of support
#ifndef COMBO_WRAPPER_H
#define COMBO_WRAPPER_H

#include <gtk/gtk.h>

/* --- DEFINING NEW CLASS ------------------------------------------ */

#define TYPE_COMBO_WRAPPER (combo_wrapper_get_type ())
#define COMBO_WRAPPER(obj) (GTK_CHECK_CAST (obj, combo_wrapper_get_type (), ComboWrapper))
#define COMBO_WRAPPER_CLASS(klass) (GTK_CHECK_CLASS_CAST (klass, combo_wrapper_get_type (), ComboWrapperClass))
#define IS_COMBO_WRAPPER(obj) (GTK_CHECK_TYPE (obj, combo_wrapper_get_type ()))
#define IS_COMBO_WRAPPER_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), TYPE_COMBO_WRAPPER))

typedef struct _ComboWrapper        ComboWrapper;
typedef struct _ComboWrapperClass   ComboWrapperClass;

struct _ComboWrapper {
  GtkCombo combo;
};

struct _ComboWrapperClass {
  GtkComboClass combo_class;
};

guint          combo_wrapper_get_type           (void);
GtkWidget     *combo_wrapper_new                (void);

#endif // COMBO_WRAPPER_H
#include "combo-wrapper.h"

/* object stuff */
static void   combo_wrapper_class_init          (ComboWrapperClass    *klass);
static void   combo_wrapper_init                (ComboWrapper         *combo_wrapper);
static void   combo_wrapper_destroy             (GtkObject          *object);

static GtkObjectClass *parent_class = NULL;

guint
combo_wrapper_get_type ()
{
    static guint combo_wrapper_type = 0;

    if (!combo_wrapper_type)
	{
	    GtkTypeInfo combo_wrapper_info =
	    {
		"ComboWrapper",
		sizeof (ComboWrapper),
		sizeof (ComboWrapperClass),
		(GtkClassInitFunc) combo_wrapper_class_init,
		(GtkObjectInitFunc) combo_wrapper_init,
		(GtkArgSetFunc) NULL,
		(GtkArgGetFunc) NULL,
		(GtkClassInitFunc) NULL,
	    };

	    combo_wrapper_type =
		gtk_type_unique (gtk_combo_get_type (), &combo_wrapper_info);
	}

    return combo_wrapper_type;
}

enum {
    CHANGED,
    LAST_SIGNAL
};
static guint combo_wrapper_signals[LAST_SIGNAL] = { 0 };


static void
combo_wrapper_class_init (ComboWrapperClass *class)
{
    GtkObjectClass *object_class;

    object_class = (GtkObjectClass*) class;

    /* init local data */
    parent_class = gtk_type_class (gtk_object_get_type ());

    object_class->destroy = combo_wrapper_destroy;

    /* set up signals */
    combo_wrapper_signals[CHANGED] =
	gtk_signal_new ("changed",
			GTK_RUN_FIRST,
			object_class->type,
			0,		/* offset.  We don't have a class
					   signal handler */
			gtk_marshal_NONE__NONE,
			GTK_TYPE_NONE, 0);

    gtk_object_class_add_signals (object_class, combo_wrapper_signals, LAST_SIGNAL);

}

static void
change_emitter (ComboWrapper *combo_wrapper)
{
  gtk_signal_emit (GTK_OBJECT (combo_wrapper),
		   combo_wrapper_signals[CHANGED]);
}

static void
combo_wrapper_init (ComboWrapper *combo_wrapper)
{
    GtkCombo *combo = GTK_COMBO (combo_wrapper);
    gtk_signal_connect_object (GTK_OBJECT (combo->entry), "changed",
			       (GtkSignalFunc) change_emitter,
			       GTK_OBJECT (combo_wrapper));
    gtk_signal_connect_object (GTK_OBJECT (combo->list), "select-child",
			       (GtkSignalFunc) change_emitter,
			       GTK_OBJECT (combo_wrapper));
    return;
}

static void
combo_wrapper_destroy (GtkObject *object)
{
    g_return_if_fail (object != NULL);
    g_return_if_fail (IS_COMBO_WRAPPER (object));

    GTK_OBJECT_CLASS(parent_class)->destroy (object);
}

GtkWidget*
combo_wrapper_new (void)
{
    return GTK_WIDGET (gtk_type_new (combo_wrapper_get_type ()));
}

/* --- testing --- */

static void
changed_event (void)
{
    g_print ("changed!\n");
}

int
main (int argc, char *argv[])
{
    GtkWidget *win;
    GtkWidget *combo;
    GList *popdown_list;

    gtk_init (&argc, &argv);

    win = gtk_window_new (GTK_WINDOW_TOPLEVEL);

    popdown_list = NULL;
    popdown_list = g_list_prepend (popdown_list, "three");
    popdown_list = g_list_prepend (popdown_list, "two");
    popdown_list = g_list_prepend (popdown_list, "one");

    combo = combo_wrapper_new ();
    gtk_combo_set_popdown_strings (GTK_COMBO (combo),
				   popdown_list);

    gtk_container_add (GTK_CONTAINER (win), combo);

    gtk_signal_connect (GTK_OBJECT (combo),
			"changed",
			GTK_SIGNAL_FUNC (changed_event),
			combo);

    gtk_widget_show_all (win);

    gtk_main ();

    return 0;
}



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