Re: Add GtkRadioGroup?
- From: Tristan Van Berkom <tristanvb openismus com>
- To: Alexander Larsson <alexl redhat com>
- Cc: "gtk-devel-list gnome org" <gtk-devel-list gnome org>
- Subject: Re: Add GtkRadioGroup?
- Date: Fri, 29 Oct 2010 12:43:11 +0900
On Thu, 2010-10-28 at 22:38 +0200, Alexander Larsson wrote:
> One thing I remember being really confused about when learning gtk+ is
> the GSList * usage for the group in GtkRadioButton. We have added some
> scaffolding now that makes this somewhat better, but whats the chance of
> actually fixing this by adding a real GtkRadioGroup class and using it
> for radio buttons/menus/toolitems/actions?
>
> It'll be a slight api break, but it should be trivial to fix up any
> problems and the compiler should catch them all.
>
> In addition to removing the GSList crap we can also add proper signals
> for when the group contents changes (added/removed items) and a single
> signal for the group when we get a new active item.
>
> Below is a small example patch, mostly just compile tested. If there is
> interest in doing this I'll try to find some time to do a full patch.
>
> Opinions?
Hi,
I like the idea of not using the GSList too.
But I wonder, don't we already accomplish this with
GtkRadioAction ?
I'm not sure the two entities would play nicely together
either, maybe it makes sense to deprecate or even remove
GSList interaction and just converge towards usage of
a GtkRadioAction.
Cheers,
-Tristan
>
> diff --git a/gtk/Makefile.am b/gtk/Makefile.am
> index 0774710..4345413 100644
> --- a/gtk/Makefile.am
> +++ b/gtk/Makefile.am
> @@ -258,6 +258,7 @@ gtk_public_h_sources = \
> gtkprogressbar.h \
> gtkradioaction.h \
> gtkradiobutton.h \
> + gtkradiogroup.h \
> gtkradiomenuitem.h \
> gtkradiotoolbutton.h \
> gtkrange.h \
> @@ -378,6 +379,7 @@ gtk_private_h_sources = \
> gtkprintoperation-private.h\
> gtkprintutils.h \
> gtkprivate.h \
> + gtkradiogroupprivate.h \
> gtkrbtree.h \
> gtkrecentchooserdefault.h \
> gtkrecentchooserprivate.h \
> @@ -530,6 +532,7 @@ gtk_base_c_sources = \
> gtkprogressbar.c \
> gtkradioaction.c \
> gtkradiobutton.c \
> + gtkradiogroup.c \
> gtkradiomenuitem.c \
> gtkradiotoolbutton.c \
> gtkrange.c \
> diff --git a/gtk/gtkradiobutton.c b/gtk/gtkradiobutton.c
> index 7a51b95..3baf611 100644
> --- a/gtk/gtkradiobutton.c
> +++ b/gtk/gtkradiobutton.c
> @@ -28,6 +28,7 @@
> #include "gtklabel.h"
> #include "gtkmarshalers.h"
> #include "gtkradiobutton.h"
> +#include "gtkradiogroupprivate.h"
> #include "gtkprivate.h"
> #include "gtkintl.h"
>
> @@ -105,7 +106,7 @@
>
> struct _GtkRadioButtonPrivate
> {
> - GSList *group;
> + GtkRadioGroup *group;
> };
>
> enum {
> @@ -211,7 +212,8 @@ gtk_radio_button_init (GtkRadioButton *radio_button)
>
> GTK_BUTTON (radio_button)->depress_on_activate = FALSE;
>
> - priv->group = g_slist_prepend (NULL, radio_button);
> + priv->group = g_object_ref_sink (gtk_radio_group_new ());
> + _gtk_radio_group_add_item (priv->group, G_OBJECT (radio_button));
>
> _gtk_button_set_depressed (GTK_BUTTON (radio_button), TRUE);
> gtk_widget_set_state (GTK_WIDGET (radio_button), GTK_STATE_ACTIVE);
> @@ -229,17 +231,17 @@ gtk_radio_button_set_property (GObject *object,
>
> switch (prop_id)
> {
> - GSList *slist;
> + GtkRadioGroup *group;
> GtkRadioButton *button;
>
> case PROP_GROUP:
> button = g_value_get_object (value);
>
> if (button)
> - slist = gtk_radio_button_get_group (button);
> + group = gtk_radio_button_get_group (button);
> else
> - slist = NULL;
> - gtk_radio_button_set_group (radio_button, slist);
> + group = NULL;
> + gtk_radio_button_set_group (radio_button, group);
> break;
> default:
> G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
> @@ -264,8 +266,9 @@ gtk_radio_button_get_property (GObject *object,
> /**
> * gtk_radio_button_set_group:
> * @radio_button: a #GtkRadioButton.
> - * @group: (transfer none) (element-type GtkRadioButton): an existing radio
> - * button group, such as one returned from gtk_radio_button_get_group().
> + * @group: a ¤GtkRadioGroup: an existing radio
> + * button group, such as one returned from gtk_radio_button_get_group(), or %NULL
> + * to create a new group for the button.
> *
> * Sets a #GtkRadioButton's group. It should be noted that this does not change
> * the layout of your interface in any way, so if you are changing the group,
> @@ -274,57 +277,40 @@ gtk_radio_button_get_property (GObject *object,
> */
> void
> gtk_radio_button_set_group (GtkRadioButton *radio_button,
> - GSList *group)
> + GtkRadioGroup *group)
> {
> GtkRadioButtonPrivate *priv;
> - GtkWidget *old_group_singleton = NULL;
> - GtkWidget *new_group_singleton = NULL;
> + GObject *old_group_singleton;
> + GObject *new_group_singleton;
> + GObject *old_group_active;
>
> g_return_if_fail (GTK_IS_RADIO_BUTTON (radio_button));
> - g_return_if_fail (!g_slist_find (group, radio_button));
>
> priv = radio_button->priv;
>
> - if (priv->group)
> - {
> - GSList *slist;
> + if (priv->group == group)
> + return;
>
> - priv->group = g_slist_remove (priv->group, radio_button);
> + if (group == NULL)
> + group = gtk_radio_group_new ();
>
> - if (priv->group && !priv->group->next)
> - old_group_singleton = g_object_ref (priv->group->data);
> + _gtk_radio_group_remove_item (priv->group, G_OBJECT (radio_button));
> + old_group_singleton = _gtk_radio_group_get_singleton (priv->group);
>
> - for (slist = priv->group; slist; slist = slist->next)
> - {
> - GtkRadioButton *tmp_button;
> -
> - tmp_button = slist->data;
> + /* Ensure some widget is active in the old group */
> + old_group_active = gtk_radio_group_get_active_item (priv->group);
> + if (old_group_active)
> + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (old_group_active), TRUE);
>
> - tmp_button->priv->group = priv->group;
> - }
> - }
> -
> - if (group && !group->next)
> - new_group_singleton = g_object_ref (group->data);
> + g_object_unref (priv->group);
>
> - priv->group = g_slist_prepend (group, radio_button);
> + priv->group = g_object_ref_sink (group);
> + new_group_singleton = _gtk_radio_group_get_singleton (group);
>
> - if (group)
> - {
> - GSList *slist;
> -
> - for (slist = group; slist; slist = slist->next)
> - {
> - GtkRadioButton *tmp_button;
> -
> - tmp_button = slist->data;
> -
> - tmp_button->priv->group = priv->group;
> - }
> - }
> + _gtk_radio_group_add_item (group, G_OBJECT (radio_button));
>
> g_object_ref (radio_button);
> -
> +
> g_object_notify (G_OBJECT (radio_button), "group");
> g_signal_emit (radio_button, group_changed_signal, 0);
> if (old_group_singleton)
> @@ -338,7 +324,8 @@ gtk_radio_button_set_group (GtkRadioButton *radio_button,
> g_object_unref (new_group_singleton);
> }
>
> - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (radio_button), group == NULL);
> + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (radio_button),
> + gtk_radio_group_get_active_item (group) == G_OBJECT (radio_button));
>
> g_object_unref (radio_button);
> }
> @@ -379,17 +366,8 @@ gtk_radio_button_join_group (GtkRadioButton *radio_button,
>
> if (group_source)
> {
> - GSList *group;
> + GtkRadioGroup *group;
> group = gtk_radio_button_get_group (group_source);
> -
> - if (!group)
> - {
> - /* if we are not already part of a group we need to set up a new one
> - and then get the newly created group */
> - gtk_radio_button_set_group (group_source, NULL);
> - group = gtk_radio_button_get_group (group_source);
> - }
> -
> gtk_radio_button_set_group (radio_button, group);
> }
> else
> @@ -408,7 +386,7 @@ gtk_radio_button_join_group (GtkRadioButton *radio_button,
> * Returns: a new radio button
> */
> GtkWidget*
> -gtk_radio_button_new (GSList *group)
> +gtk_radio_button_new (GtkRadioGroup *group)
> {
> GtkRadioButton *radio_button;
>
> @@ -431,7 +409,7 @@ gtk_radio_button_new (GSList *group)
> * Returns: (transfer full): a new radio button.
> */
> GtkWidget*
> -gtk_radio_button_new_with_label (GSList *group,
> +gtk_radio_button_new_with_label (GtkRadioGroup *group,
> const gchar *label)
> {
> GtkWidget *radio_button;
> @@ -459,7 +437,7 @@ gtk_radio_button_new_with_label (GSList *group,
> * Returns: (transfer full): a new #GtkRadioButton
> */
> GtkWidget*
> -gtk_radio_button_new_with_mnemonic (GSList *group,
> +gtk_radio_button_new_with_mnemonic (GtkRadioGroup *group,
> const gchar *label)
> {
> GtkWidget *radio_button;
> @@ -488,10 +466,10 @@ gtk_radio_button_new_with_mnemonic (GSList *group,
> GtkWidget*
> gtk_radio_button_new_from_widget (GtkRadioButton *radio_group_member)
> {
> - GSList *l = NULL;
> + GtkRadioGroup *group = NULL;
> if (radio_group_member)
> - l = gtk_radio_button_get_group (radio_group_member);
> - return gtk_radio_button_new (l);
> + group = gtk_radio_button_get_group (radio_group_member);
> + return gtk_radio_button_new (group);
> }
>
> /**
> @@ -508,10 +486,10 @@ GtkWidget*
> gtk_radio_button_new_with_label_from_widget (GtkRadioButton *radio_group_member,
> const gchar *label)
> {
> - GSList *l = NULL;
> + GtkRadioGroup *group = NULL;
> if (radio_group_member)
> - l = gtk_radio_button_get_group (radio_group_member);
> - return gtk_radio_button_new_with_label (l, label);
> + group = gtk_radio_button_get_group (radio_group_member);
> + return gtk_radio_button_new_with_label (group, label);
> }
>
> /**
> @@ -530,10 +508,10 @@ GtkWidget*
> gtk_radio_button_new_with_mnemonic_from_widget (GtkRadioButton *radio_group_member,
> const gchar *label)
> {
> - GSList *l = NULL;
> + GtkRadioGroup *group = NULL;
> if (radio_group_member)
> - l = gtk_radio_button_get_group (radio_group_member);
> - return gtk_radio_button_new_with_mnemonic (l, label);
> + group = gtk_radio_button_get_group (radio_group_member);
> + return gtk_radio_button_new_with_mnemonic (group, label);
> }
>
>
> @@ -548,7 +526,7 @@ gtk_radio_button_new_with_mnemonic_from_widget (GtkRadioButton *radio_group_memb
> * as @radio_button. The returned list is owned by the radio button
> * and must not be modified or freed.
> */
> -GSList*
> +GtkRadioGroup *
> gtk_radio_button_get_group (GtkRadioButton *radio_button)
> {
> g_return_val_if_fail (GTK_IS_RADIO_BUTTON (radio_button), NULL);
> @@ -560,32 +538,28 @@ gtk_radio_button_get_group (GtkRadioButton *radio_button)
> static void
> gtk_radio_button_destroy (GtkWidget *widget)
> {
> - GtkWidget *old_group_singleton = NULL;
> + GObject *old_group_singleton = NULL;
> + GObject *old_group_active;
> GtkRadioButton *radio_button = GTK_RADIO_BUTTON (widget);
> GtkRadioButtonPrivate *priv = radio_button->priv;
> - GtkRadioButton *tmp_button;
> - GSList *tmp_list;
> - gboolean was_in_group;
> -
> - was_in_group = priv->group && priv->group->next;
> -
> - priv->group = g_slist_remove (priv->group, radio_button);
> - if (priv->group && !priv->group->next)
> - old_group_singleton = priv->group->data;
> -
> - tmp_list = priv->group;
> + gboolean was_in_group = FALSE;
>
> - while (tmp_list)
> + if (priv->group)
> {
> - tmp_button = tmp_list->data;
> - tmp_list = tmp_list->next;
> -
> - tmp_button->priv->group = priv->group;
> + _gtk_radio_group_remove_item (priv->group, G_OBJECT (radio_button));
> + was_in_group = !_gtk_radio_group_is_empty (priv->group);
> + old_group_singleton = _gtk_radio_group_get_singleton (priv->group);
> +
> + /* Ensure some widget is active in the old group */
> + old_group_active = gtk_radio_group_get_active_item (priv->group);
> + if (old_group_active)
> + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (old_group_active), TRUE);
> +
> + /* this button is no longer in the group */
> + g_object_unref (priv->group);
> + priv->group = NULL;
> }
>
> - /* this button is no longer in the group */
> - priv->group = NULL;
> -
> if (old_group_singleton)
> g_signal_emit (old_group_singleton, group_changed_signal, 0);
> if (was_in_group)
> @@ -647,7 +621,6 @@ gtk_radio_button_focus (GtkWidget *widget,
> {
> GtkRadioButton *radio_button = GTK_RADIO_BUTTON (widget);
> GtkRadioButtonPrivate *priv = radio_button->priv;
> - GSList *tmp_slist;
>
> /* Radio buttons with draw_indicator unset focus "normally", since
> * they look like buttons to the user.
> @@ -668,12 +641,12 @@ gtk_radio_button_focus (GtkWidget *widget,
> {
> case GTK_DIR_LEFT:
> case GTK_DIR_RIGHT:
> - focus_list = g_slist_copy (priv->group);
> + focus_list = g_slist_copy (gtk_radio_group_get_items (priv->group));
> focus_list = g_slist_sort_with_data (focus_list, left_right_compare, toplevel);
> break;
> case GTK_DIR_UP:
> case GTK_DIR_DOWN:
> - focus_list = g_slist_copy (priv->group);
> + focus_list = g_slist_copy (gtk_radio_group_get_items (priv->group));
> focus_list = g_slist_sort_with_data (focus_list, up_down_compare, toplevel);
> break;
> case GTK_DIR_TAB_FORWARD:
> @@ -756,22 +729,15 @@ gtk_radio_button_focus (GtkWidget *widget,
> }
> else
> {
> - GtkRadioButton *selected_button = NULL;
> -
> + GObject *selected_button;
> +
> /* We accept the focus if, we don't have the focus and
> * - we are the currently active button in the group
> * - there is no currently active radio button.
> */
> -
> - tmp_slist = priv->group;
> - while (tmp_slist)
> - {
> - if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (tmp_slist->data)))
> - selected_button = tmp_slist->data;
> - tmp_slist = tmp_slist->next;
> - }
> -
> - if (selected_button && selected_button != radio_button)
> +
> + selected_button = gtk_radio_group_get_active_item (priv->group);
> + if (selected_button && selected_button != G_OBJECT (radio_button))
> return FALSE;
>
> gtk_widget_grab_focus (widget);
> @@ -785,9 +751,8 @@ gtk_radio_button_clicked (GtkButton *button)
> GtkRadioButton *radio_button = GTK_RADIO_BUTTON (button);
> GtkRadioButtonPrivate *priv = radio_button->priv;
> GtkToggleButton *toggle_button = GTK_TOGGLE_BUTTON (button);
> - GtkToggleButton *tmp_button;
> + GObject *active_item;
> GtkStateType new_state;
> - GSList *tmp_list;
> gint toggled;
> gboolean depressed;
>
> @@ -797,22 +762,9 @@ gtk_radio_button_clicked (GtkButton *button)
>
> if (gtk_toggle_button_get_active (toggle_button))
> {
> - tmp_button = NULL;
> - tmp_list = priv->group;
> -
> - while (tmp_list)
> - {
> - tmp_button = tmp_list->data;
> - tmp_list = tmp_list->next;
> -
> - if (tmp_button != toggle_button &&
> - gtk_toggle_button_get_active (tmp_button))
> - break;
> + active_item = gtk_radio_group_get_active_item (priv->group);
>
> - tmp_button = NULL;
> - }
> -
> - if (!tmp_button)
> + if (active_item == NULL || active_item == G_OBJECT (button))
> {
> new_state = (button->in_button ? GTK_STATE_PRELIGHT : GTK_STATE_ACTIVE);
> }
> @@ -830,18 +782,10 @@ gtk_radio_button_clicked (GtkButton *button)
> _gtk_toggle_button_set_active (toggle_button,
> !gtk_toggle_button_get_active (toggle_button));
>
> - tmp_list = priv->group;
> - while (tmp_list)
> - {
> - tmp_button = tmp_list->data;
> - tmp_list = tmp_list->next;
> -
> - if (gtk_toggle_button_get_active (tmp_button) && (tmp_button != toggle_button))
> - {
> - gtk_button_clicked (GTK_BUTTON (tmp_button));
> - break;
> - }
> - }
> + active_item = gtk_radio_group_get_active_item (priv->group);
> + _gtk_radio_group_set_active_item (priv->group, G_OBJECT (toggle_button));
> + if (active_item != G_OBJECT (toggle_button))
> + gtk_button_clicked (GTK_BUTTON (active_item));
>
> new_state = (button->in_button ? GTK_STATE_PRELIGHT : GTK_STATE_ACTIVE);
> }
> diff --git a/gtk/gtkradiobutton.h b/gtk/gtkradiobutton.h
> index 2fe40c6..1ee2454 100644
> --- a/gtk/gtkradiobutton.h
> +++ b/gtk/gtkradiobutton.h
> @@ -33,6 +33,7 @@
>
>
> #include <gtk/gtkcheckbutton.h>
> +#include <gtk/gtkradiogroup.h>
>
>
> G_BEGIN_DECLS
> @@ -74,21 +75,22 @@ struct _GtkRadioButtonClass
>
> GType gtk_radio_button_get_type (void) G_GNUC_CONST;
>
> -GtkWidget* gtk_radio_button_new (GSList *group);
> -GtkWidget* gtk_radio_button_new_from_widget (GtkRadioButton *radio_group_member);
> -GtkWidget* gtk_radio_button_new_with_label (GSList *group,
> - const gchar *label);
> -GtkWidget* gtk_radio_button_new_with_label_from_widget (GtkRadioButton *radio_group_member,
> - const gchar *label);
> -GtkWidget* gtk_radio_button_new_with_mnemonic (GSList *group,
> - const gchar *label);
> -GtkWidget* gtk_radio_button_new_with_mnemonic_from_widget (GtkRadioButton *radio_group_member,
> - const gchar *label);
> -GSList* gtk_radio_button_get_group (GtkRadioButton *radio_button);
> -void gtk_radio_button_set_group (GtkRadioButton *radio_button,
> - GSList *group);
> -void gtk_radio_button_join_group (GtkRadioButton *radio_button,
> - GtkRadioButton *group_source);
> +GtkWidget* gtk_radio_button_new (GtkRadioGroup *group);
> +GtkWidget* gtk_radio_button_new_from_widget (GtkRadioButton *radio_group_member);
> +GtkWidget* gtk_radio_button_new_with_label (GtkRadioGroup *group,
> + const gchar *label);
> +GtkWidget* gtk_radio_button_new_with_label_from_widget (GtkRadioButton *radio_group_member,
> + const gchar *label);
> +GtkWidget* gtk_radio_button_new_with_mnemonic (GtkRadioGroup *group,
> + const gchar *label);
> +GtkWidget* gtk_radio_button_new_with_mnemonic_from_widget (GtkRadioButton *radio_group_member,
> + const gchar *label);
> +GtkRadioGroup *gtk_radio_button_get_group (GtkRadioButton *radio_button);
> +void gtk_radio_button_set_group (GtkRadioButton *radio_button,
> + GtkRadioGroup *group);
> +void gtk_radio_button_join_group (GtkRadioButton *radio_button,
> + GtkRadioButton *group_source);
> +
> G_END_DECLS
>
> #endif /* __GTK_RADIO_BUTTON_H__ */
> diff --git a/gtk/gtkradiogroup.c b/gtk/gtkradiogroup.c
> new file mode 100644
> index 0000000..06dface
> --- /dev/null
> +++ b/gtk/gtkradiogroup.c
> @@ -0,0 +1,263 @@
> +/* GTK - The GIMP Toolkit
> + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
> + *
> + * This library is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU Lesser General Public
> + * License as published by the Free Software Foundation; either
> + * version 2 of the License, or (at your option) any later version.
> + *
> + * This library is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> + * Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public
> + * License along with this library; if not, write to the
> + * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
> + * Boston, MA 02111-1307, USA.
> + */
> +
> +/*
> + * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
> + * file for a list of people on the GTK+ Team. See the ChangeLog
> + * files for a list of changes. These files are distributed with
> + * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
> + */
> +
> +#include "config.h"
> +#include "gtkradiogroupprivate.h"
> +#include "gtkprivate.h"
> +#include "gtkmarshalers.h"
> +#include "gtkintl.h"
> +
> +/**
> + * SECTION:gtkradiogroup
> + * @Short_description: A group of object having radiobutton like behaviour
> + * @Title: GtkRadioGroup
> + * @See_also: #GtkRadioButton, ...TODO
> + *
> + * ....TODO
> + */
> +
> +
> +struct _GtkRadioGroupPrivate
> +{
> + GSList *items;
> + GObject *active;
> +};
> +
> +enum {
> + PROP_0,
> + PROP_ACTIVE_ITEM
> +};
> +
> +
> +static void gtk_radio_group_set_property (GObject *object,
> + guint prop_id,
> + const GValue *value,
> + GParamSpec *pspec);
> +static void gtk_radio_group_get_property (GObject *object,
> + guint prop_id,
> + GValue *value,
> + GParamSpec *pspec);
> +
> +G_DEFINE_TYPE (GtkRadioGroup, gtk_radio_group, G_TYPE_INITIALLY_UNOWNED)
> +
> +enum {
> + CHANGED,
> + ACTIVE_CHANGED,
> + LAST_SIGNAL
> +};
> +
> +static guint signals[LAST_SIGNAL] = { 0 };
> +
> +static void
> +gtk_radio_group_class_init (GtkRadioGroupClass *class)
> +{
> + GObjectClass *gobject_class;
> +
> + gobject_class = G_OBJECT_CLASS (class);
> +
> + gobject_class->set_property = gtk_radio_group_set_property;
> + gobject_class->get_property = gtk_radio_group_get_property;
> +
> + /**
> + * GtkRadioGroup:active-item:
> + *
> + * Sets a new group for a radio group.
> + */
> + g_object_class_install_property (gobject_class,
> + PROP_ACTIVE_ITEM,
> + g_param_spec_object ("active-item",
> + P_("Active item"),
> + P_("The active item in the radio group."),
> + G_TYPE_OBJECT,
> + GTK_PARAM_WRITABLE));
> + class->changed = NULL;
> + class->active_changed = NULL;
> +
> + /**
> + * GtkRadioGroup::active-changed:
> + * @object: the new active object
> + *
> + * ...TODO fix
> + */
> + signals[ACTIVE_CHANGED] = g_signal_new (I_("active-changed"),
> + G_OBJECT_CLASS_TYPE (gobject_class),
> + G_SIGNAL_RUN_FIRST,
> + G_STRUCT_OFFSET (GtkRadioGroupClass, active_changed),
> + NULL, NULL,
> + _gtk_marshal_VOID__OBJECT,
> + G_TYPE_NONE, 0);
> +
> +
> + /* TODO: add changed signal */
> +
> + g_type_class_add_private (class, sizeof (GtkRadioGroupPrivate));
> +}
> +
> +static void
> +gtk_radio_group_init (GtkRadioGroup *radio_group)
> +{
> + GtkRadioGroupPrivate *priv;
> +
> + radio_group->priv = G_TYPE_INSTANCE_GET_PRIVATE (radio_group,
> + GTK_TYPE_RADIO_GROUP,
> + GtkRadioGroupPrivate);
> + priv = radio_group->priv;
> +
> + priv->items = NULL;
> + priv->active = NULL;
> +}
> +
> +static void
> +gtk_radio_group_set_property (GObject *object,
> + guint prop_id,
> + const GValue *value,
> + GParamSpec *pspec)
> +{
> + GtkRadioGroup *radio_group;
> +
> + radio_group = GTK_RADIO_GROUP (object);
> +
> + switch (prop_id)
> + {
> + default:
> + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
> + break;
> + }
> +}
> +
> +static void
> +gtk_radio_group_get_property (GObject *object,
> + guint prop_id,
> + GValue *value,
> + GParamSpec *pspec)
> +{
> + switch (prop_id)
> + {
> + default:
> + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
> + break;
> + }
> +}
> +
> +/**
> + * gtk_radio_group_new:
> + *
> + * Creates a new empty #GtkRadioGroup.
> + *
> + * Returns: a new radio group
> + */
> +GtkRadioGroup*
> +gtk_radio_group_new (void)
> +{
> + GtkRadioGroup *radio_group;
> +
> + radio_group = g_object_new (GTK_TYPE_RADIO_GROUP, NULL);
> +
> + return radio_group;
> +}
> +
> +GSList*
> +gtk_radio_group_get_items (GtkRadioGroup *radio_group)
> +{
> + g_return_val_if_fail (GTK_IS_RADIO_GROUP (radio_group), NULL);
> +
> + return radio_group->priv->items;
> +}
> +
> +GObject *
> +gtk_radio_group_get_active_item (GtkRadioGroup *radio_group)
> +{
> + g_return_val_if_fail (GTK_IS_RADIO_GROUP (radio_group), NULL);
> +
> + return radio_group->priv->active;
> +}
> +
> +gboolean
> +_gtk_radio_group_is_empty (GtkRadioGroup *radio_group)
> +{
> + return radio_group->priv->items == NULL;
> +}
> +
> +GObject *
> +_gtk_radio_group_get_singleton (GtkRadioGroup *radio_group)
> +{
> + GtkRadioGroupPrivate *priv;
> +
> + priv = radio_group->priv;
> + if (priv->items != NULL && priv->items->next == NULL)
> + return g_object_ref (priv->items->data);
> + return NULL;
> +}
> +
> +void
> +_gtk_radio_group_add_item (GtkRadioGroup *radio_group,
> + GObject *item)
> +{
> + GtkRadioGroupPrivate *priv;
> +
> + g_return_if_fail (GTK_IS_RADIO_GROUP (radio_group));
> + g_return_if_fail (!g_slist_find (radio_group->priv->items, item));
> +
> + priv = radio_group->priv;
> + priv->items = g_slist_prepend (priv->items, item);
> + if (priv->active == NULL)
> + priv->active = item;
> +}
> +
> +/* Caller must emit active-changed if removed was active?? */
> +void
> +_gtk_radio_group_remove_item (GtkRadioGroup *radio_group,
> + GObject *item)
> +{
> + GtkRadioGroupPrivate *priv;
> +
> + g_return_if_fail (GTK_IS_RADIO_GROUP (radio_group));
> + g_return_if_fail (g_slist_find (radio_group->priv->items, item));
> +
> + priv = radio_group->priv;
> + priv->items = g_slist_remove (priv->items, item);
> +
> + if (priv->active == item)
> + {
> + if (priv->items)
> + priv->active = priv->items->data;
> + else
> + priv->active = NULL;
> + }
> +}
> +
> +void
> +_gtk_radio_group_set_active_item (GtkRadioGroup *radio_group,
> + GObject *item)
> +{
> + radio_group->priv->active = item;
> +}
> +
> +void
> +_gtk_radio_group_emit_active_changed (GtkRadioGroup *radio_group)
> +{
> + g_signal_emit (radio_group, signals[ACTIVE_CHANGED], 0, radio_group->priv->active);
> +}
> diff --git a/gtk/gtkradiogroup.h b/gtk/gtkradiogroup.h
> new file mode 100644
> index 0000000..3906bf8
> --- /dev/null
> +++ b/gtk/gtkradiogroup.h
> @@ -0,0 +1,82 @@
> +/* GTK - The GIMP Toolkit
> + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
> + *
> + * This library is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU Lesser General Public
> + * License as published by the Free Software Foundation; either
> + * version 2 of the License, or (at your option) any later version.
> + *
> + * This library is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> + * Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public
> + * License along with this library; if not, write to the
> + * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
> + * Boston, MA 02111-1307, USA.
> + */
> +
> +/*
> + * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
> + * file for a list of people on the GTK+ Team. See the ChangeLog
> + * files for a list of changes. These files are distributed with
> + * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
> + */
> +
> +#if !defined (__GTK_H_INSIDE__) && !defined (GTK_COMPILATION)
> +#error "Only <gtk/gtk.h> can be included directly."
> +#endif
> +
> +#ifndef __GTK_RADIO_GROUP_H__
> +#define __GTK_RADIO_GROUP_H__
> +
> +#include <gdk/gdk.h>
> +
> +G_BEGIN_DECLS
> +
> +#define GTK_TYPE_RADIO_GROUP (gtk_radio_group_get_type ())
> +#define GTK_RADIO_GROUP(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_RADIO_GROUP, GtkRadioGroup))
> +#define GTK_RADIO_GROUP_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_RADIO_GROUP, GtkRadioGroupClass))
> +#define GTK_IS_RADIO_GROUP(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_RADIO_GROUP))
> +#define GTK_IS_RADIO_GROUP_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_RADIO_GROUP))
> +#define GTK_RADIO_GROUP_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_RADIO_GROUP, GtkRadioGroupClass))
> +
> +
> +typedef struct _GtkRadioGroup GtkRadioGroup;
> +typedef struct _GtkRadioGroupPrivate GtkRadioGroupPrivate;
> +typedef struct _GtkRadioGroupClass GtkRadioGroupClass;
> +
> +struct _GtkRadioGroup
> +{
> + GInitiallyUnowned parent_instance;
> +
> + /*< private >*/
> + GtkRadioGroupPrivate *priv;
> +};
> +
> +struct _GtkRadioGroupClass
> +{
> + GInitiallyUnownedClass parent_class;
> +
> + /* Signals */
> + void (*changed) (GtkRadioGroup *radio_group);
> + void (*active_changed) (GtkRadioGroup *radio_group, GObject *active);
> +
> + /* Padding for future expansion */
> + void (*_gtk_reserved1) (void);
> + void (*_gtk_reserved2) (void);
> + void (*_gtk_reserved3) (void);
> + void (*_gtk_reserved4) (void);
> +};
> +
> +
> +GType gtk_radio_group_get_type (void) G_GNUC_CONST;
> +
> +GtkRadioGroup* gtk_radio_group_new (void);
> +GSList* gtk_radio_group_get_items (GtkRadioGroup *radio_group);
> +GObject * gtk_radio_group_get_active_item (GtkRadioGroup *radio_group);
> +
> +G_END_DECLS
> +
> +#endif /* __GTK_RADIO_GROUP_H__ */
> diff --git a/gtk/gtkradiogroupprivate.h b/gtk/gtkradiogroupprivate.h
> new file mode 100644
> index 0000000..29ef587
> --- /dev/null
> +++ b/gtk/gtkradiogroupprivate.h
> @@ -0,0 +1,46 @@
> +/* GTK - The GIMP Toolkit
> + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
> + *
> + * This library is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU Lesser General Public
> + * License as published by the Free Software Foundation; either
> + * version 2 of the License, or (at your option) any later version.
> + *
> + * This library is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> + * Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public
> + * License along with this library; if not, write to the
> + * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
> + * Boston, MA 02111-1307, USA.
> + */
> +
> +/*
> + * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
> + * file for a list of people on the GTK+ Team. See the ChangeLog
> + * files for a list of changes. These files are distributed with
> + * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
> + */
> +
> +#ifndef __GTK_RADIO_GROUP_PRIVATE_H__
> +#define __GTK_RADIO_GROUP_PRIVATE_H__
> +
> +#include <gtk/gtkradiogroup.h>
> +
> +G_BEGIN_DECLS
> +
> +void _gtk_radio_group_add_item (GtkRadioGroup *radio_group,
> + GObject *item);
> +void _gtk_radio_group_remove_item (GtkRadioGroup *radio_group,
> + GObject *item);
> +gboolean _gtk_radio_group_is_empty (GtkRadioGroup *radio_group);
> +GObject *_gtk_radio_group_get_singleton (GtkRadioGroup *radio_group);
> +void _gtk_radio_group_set_active_item (GtkRadioGroup *radio_group,
> + GObject *item);
> +void _gtk_radio_group_emit_active_changed (GtkRadioGroup *radio_group);
> +
> +G_END_DECLS
> +
> +#endif /* __GTK_RADIO_GROUP_PRIVATE_H__ */
>
>
>
>
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]