diff --git a/ChangeLog b/ChangeLog index 8a522f75c6..5c71e1afaa 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,16 @@ +2007-06-04 Emmanuele Bassi + + * gtk/gtkradiobutton.h: + * gtk/gtkradiobutton.c: + * gtk/gtk.symbols: Add gtk_radio_button_set_value(), + gtk_radio_button_get_current_value() and gtk_radio_button_get_value(). + Use these functions to set and get an arbitrary integer associated to + a GtkRadioButton in a group, like the value associated to a + GtkRadioAction. + + * tests/testgtk.c: + (create_radio_buttons), (radio_toggled_cb): Exercise the new API. + 2007-06-03 Torsten Schoenfeld * gtk/gtkicontheme.c (choose_icon): Initialize unthemed_icon to NULL diff --git a/gtk/gtk.symbols b/gtk/gtk.symbols index 2c7963580d..83809b2f71 100644 --- a/gtk/gtk.symbols +++ b/gtk/gtk.symbols @@ -2953,6 +2953,8 @@ gtk_radio_action_set_group #if IN_FILE(__GTK_RADIO_BUTTON_C__) gtk_radio_button_get_group gtk_radio_button_get_type G_GNUC_CONST +gtk_radio_button_get_current_value +gtk_radio_button_get_value gtk_radio_button_new gtk_radio_button_new_from_widget gtk_radio_button_new_with_label @@ -2960,6 +2962,7 @@ gtk_radio_button_new_with_label_from_widget gtk_radio_button_new_with_mnemonic gtk_radio_button_new_with_mnemonic_from_widget gtk_radio_button_set_group +gtk_radio_button_set_value #endif #endif diff --git a/gtk/gtkradiobutton.c b/gtk/gtkradiobutton.c index b4de838f49..e8af94890c 100644 --- a/gtk/gtkradiobutton.c +++ b/gtk/gtkradiobutton.c @@ -32,12 +32,22 @@ #include "gtkintl.h" #include "gtkalias.h" +#define GTK_RADIO_BUTTON_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GTK_TYPE_RADIO_BUTTON, GtkRadioButtonPrivate)) + +#define GTK_RADIO_BUTTON_VALUE_UNSET (G_MAXINT) + +typedef struct _GtkRadioButtonPrivate GtkRadioButtonPrivate; enum { PROP_0, - PROP_GROUP + PROP_GROUP, + PROP_VALUE }; +struct _GtkRadioButtonPrivate +{ + gint value; +}; static void gtk_radio_button_destroy (GtkObject *object); static gboolean gtk_radio_button_focus (GtkWidget *widget, @@ -73,6 +83,8 @@ gtk_radio_button_class_init (GtkRadioButtonClass *class) button_class = (GtkButtonClass*) class; check_button_class = (GtkCheckButtonClass*) class; + g_type_class_add_private (class, sizeof (GtkRadioButtonPrivate)); + gobject_class->set_property = gtk_radio_button_set_property; gobject_class->get_property = gtk_radio_button_get_property; @@ -83,6 +95,25 @@ gtk_radio_button_class_init (GtkRadioButtonClass *class) P_("The radio button whose group this widget belongs to."), GTK_TYPE_RADIO_BUTTON, GTK_PARAM_WRITABLE)); + /** + * GtkRadioButton:value: + * + * The value is an arbitrary integer which can be used as a + * convenient way to determine which button in a group is + * currently active in a ::toggled signal handler. + * + * Since: 2.12 + */ + g_object_class_install_property (gobject_class, + PROP_VALUE, + g_param_spec_int ("value", + P_("Value"), + P_("The value bound to the radio button"), + G_MININT, G_MAXINT - 1, + G_MAXINT - 1, + GTK_PARAM_READWRITE)); + + object_class->destroy = gtk_radio_button_destroy; widget_class->focus = gtk_radio_button_focus; @@ -118,6 +149,11 @@ gtk_radio_button_class_init (GtkRadioButtonClass *class) static void gtk_radio_button_init (GtkRadioButton *radio_button) { + GtkRadioButtonPrivate *priv; + + priv = GTK_RADIO_BUTTON_GET_PRIVATE (radio_button); + priv->value = GTK_RADIO_BUTTON_VALUE_UNSET; + GTK_WIDGET_SET_FLAGS (radio_button, GTK_NO_WINDOW); GTK_WIDGET_UNSET_FLAGS (radio_button, GTK_RECEIVES_DEFAULT); @@ -147,7 +183,7 @@ gtk_radio_button_set_property (GObject *object, GtkRadioButton *button; case PROP_GROUP: - button = g_value_get_object (value); + button = g_value_get_object (value); if (button) slist = gtk_radio_button_get_group (button); @@ -155,6 +191,9 @@ gtk_radio_button_set_property (GObject *object, slist = NULL; gtk_radio_button_set_group (radio_button, slist); break; + case PROP_VALUE: + gtk_radio_button_set_value (radio_button, g_value_get_int (value)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -167,8 +206,13 @@ gtk_radio_button_get_property (GObject *object, GValue *value, GParamSpec *pspec) { + GtkRadioButton *radio_button = GTK_RADIO_BUTTON (object); + switch (prop_id) { + case PROP_VALUE: + g_value_set_int (value, gtk_radio_button_get_value (radio_button)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -742,5 +786,105 @@ gtk_radio_button_draw_indicator (GtkCheckButton *check_button, } } +/** + * gtk_radio_button_get_value: + * @radio_button: a #GtkRadioButton + * + * Retrieve the value property of the @radio_button set using + * gtk_radio_button_set_value. If no value was set, the position + * of @radio_button in the radio button group is returned. + * + * Return value: the value property of the radio button + * + * Since: 2.12 + */ +gint +gtk_radio_button_get_value (GtkRadioButton *radio_button) +{ + GtkRadioButtonPrivate *priv; + gint retval; + + g_return_val_if_fail (GTK_IS_RADIO_BUTTON (radio_button), 0); + + priv = GTK_RADIO_BUTTON_GET_PRIVATE (radio_button); + + retval = priv->value; + + if (retval == GTK_RADIO_BUTTON_VALUE_UNSET) + { + gint index = g_slist_index (radio_button->group, radio_button); + gint length = g_slist_length (radio_button->group); + + retval = length - index; + } + + return retval; +} + +/** + * gtk_radio_button_set_value: + * @radio_button: a #GtkRadioButton + * @value: the value bound to the radio button + * + * Set the value bound to the radio button. The value is an arbitrary + * integer which can be used as a convenient way to determine which + * radio button in a group is currently active in an ::toggled signal + * handler. + * + * Since: 2.12 + */ +void +gtk_radio_button_set_value (GtkRadioButton *radio_button, + gint value) +{ + GtkRadioButtonPrivate *priv; + + g_return_if_fail (GTK_IS_RADIO_BUTTON (radio_button)); + g_return_if_fail (value < GTK_RADIO_BUTTON_VALUE_UNSET); + + priv = GTK_RADIO_BUTTON_GET_PRIVATE (radio_button); + + if (priv->value != value) + { + g_object_ref (radio_button); + + priv->value = value; + + g_object_notify (G_OBJECT (radio_button), "value"); + g_object_unref (radio_button); + } +} + +/** + * gtk_radio_button_get_current_value: + * @radio_button: a #GtkRadioButton + * + * Returns the value of the currently selected radio button inside + * the same group of @radio_button. + * + * Return value: the value set with gtk_radio_button_set_value() or + * the current position inside the group. + * + * Since: 2.12 + */ +gint +gtk_radio_button_get_current_value (GtkRadioButton *radio_button) +{ + GSList *l; + + g_return_val_if_fail (GTK_IS_RADIO_BUTTON (radio_button), + GTK_RADIO_BUTTON_VALUE_UNSET); + + for (l = radio_button->group; l; l = l->next) + { + GtkToggleButton *button = GTK_TOGGLE_BUTTON (l->data); + + if (gtk_toggle_button_get_active (button)) + return gtk_radio_button_get_value (GTK_RADIO_BUTTON (l->data)); + } + + return GTK_RADIO_BUTTON_VALUE_UNSET; +} + #define __GTK_RADIO_BUTTON_C__ #include "gtkaliasdef.c" diff --git a/gtk/gtkradiobutton.h b/gtk/gtkradiobutton.h index 6f7ce3a1ef..9ebdff19aa 100644 --- a/gtk/gtkradiobutton.h +++ b/gtk/gtkradiobutton.h @@ -41,7 +41,6 @@ G_BEGIN_DECLS #define GTK_IS_RADIO_BUTTON_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_RADIO_BUTTON)) #define GTK_RADIO_BUTTON_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_RADIO_BUTTON, GtkRadioButtonClass)) - typedef struct _GtkRadioButton GtkRadioButton; typedef struct _GtkRadioButtonClass GtkRadioButtonClass; @@ -81,6 +80,10 @@ GtkWidget* gtk_radio_button_new_with_mnemonic_from_widget (GtkRadioButton *group GSList* gtk_radio_button_get_group (GtkRadioButton *radio_button); void gtk_radio_button_set_group (GtkRadioButton *radio_button, GSList *group); +gint gtk_radio_button_get_value (GtkRadioButton *radio_button); +void gtk_radio_button_set_value (GtkRadioButton *radio_button, + gint value); +gint gtk_radio_button_get_current_value (GtkRadioButton *radio_button); #ifndef GTK_DISABLE_DEPRECATED #define gtk_radio_button_group gtk_radio_button_get_group diff --git a/tests/testgtk.c b/tests/testgtk.c index 44eb4fcc50..90e269ff3b 100644 --- a/tests/testgtk.c +++ b/tests/testgtk.c @@ -1108,6 +1108,26 @@ create_check_buttons (GtkWidget *widget) * GtkRadioButton */ +enum { + RADIO_1 = 0, + RADIO_2 = 10, + RADIO_3 = 20, + RADIO_4 = 30, + RADIO_5 = 40, + RADIO_6 = 42 +}; + +static void +radio_toggled_cb (GtkToggleButton *toggle_button, + gpointer user_data) +{ + GtkRadioButton *radio_button = GTK_RADIO_BUTTON (toggle_button); + + g_print ("Radio button (value:%d) toggled (active:%s)\n", + gtk_radio_button_get_value (radio_button), + gtk_toggle_button_get_active (toggle_button) ? "yes" : "no"); +} + static void create_radio_buttons (GtkWidget *widget) { @@ -1143,17 +1163,22 @@ create_radio_buttons (GtkWidget *widget) gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0); button = gtk_radio_button_new_with_label (NULL, "button1"); + gtk_radio_button_set_value (GTK_RADIO_BUTTON (button), RADIO_1); + g_signal_connect (button, "toggled", G_CALLBACK (radio_toggled_cb), NULL); gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0); button = gtk_radio_button_new_with_label ( gtk_radio_button_get_group (GTK_RADIO_BUTTON (button)), "button2"); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE); + g_signal_connect (button, "toggled", G_CALLBACK (radio_toggled_cb), NULL); gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0); button = gtk_radio_button_new_with_label ( gtk_radio_button_get_group (GTK_RADIO_BUTTON (button)), "button3"); + gtk_radio_button_set_value (GTK_RADIO_BUTTON (button), RADIO_3); + g_signal_connect (button, "toggled", G_CALLBACK (radio_toggled_cb), NULL); gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0); button = gtk_radio_button_new_with_label ( @@ -1170,20 +1195,26 @@ create_radio_buttons (GtkWidget *widget) gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0); button = gtk_radio_button_new_with_label (NULL, "button4"); + gtk_radio_button_set_value (GTK_RADIO_BUTTON (button), RADIO_4); gtk_toggle_button_set_mode (GTK_TOGGLE_BUTTON (button), FALSE); + g_signal_connect (button, "toggled", G_CALLBACK (radio_toggled_cb), NULL); gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0); button = gtk_radio_button_new_with_label ( gtk_radio_button_get_group (GTK_RADIO_BUTTON (button)), "button5"); + gtk_radio_button_set_value (GTK_RADIO_BUTTON (button), RADIO_5); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE); gtk_toggle_button_set_mode (GTK_TOGGLE_BUTTON (button), FALSE); + g_signal_connect (button, "toggled", G_CALLBACK (radio_toggled_cb), NULL); gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0); button = gtk_radio_button_new_with_label ( gtk_radio_button_get_group (GTK_RADIO_BUTTON (button)), "button6"); + gtk_radio_button_set_value (GTK_RADIO_BUTTON (button), RADIO_6); gtk_toggle_button_set_mode (GTK_TOGGLE_BUTTON (button), FALSE); + g_signal_connect (button, "toggled", G_CALLBACK (radio_toggled_cb), NULL); gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0); separator = gtk_hseparator_new ();