]> Pileus Git - ~andy/gtk/blobdiff - gtk/gtkradioaction.c
label: refactor code
[~andy/gtk] / gtk / gtkradioaction.c
index b2f60b46c55a4f35339ce05f944c6481345e924b..4a5aaa786f1e27d340bd2fa8485529cc56a78bf3 100644 (file)
@@ -14,9 +14,7 @@
  * Library General Public License for more details.
  *
  * You should have received a copy of the GNU Library General Public
- * License along with the Gnome Library; see the file COPYING.LIB.  If not,
- * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
  */
 
 /*
  * GTK+ at ftp://ftp.gtk.org/pub/gtk/. 
  */
 
-#include <config.h>
+#include "config.h"
 
 #include "gtkradioaction.h"
 #include "gtkradiomenuitem.h"
-#include "gtktoggleactionprivate.h"
 #include "gtktoggletoolbutton.h"
 #include "gtkintl.h"
 #include "gtkprivate.h"
-#include "gtkalias.h"
 
-#define GTK_RADIO_ACTION_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GTK_TYPE_RADIO_ACTION, GtkRadioActionPrivate))
+/**
+ * SECTION:gtkradioaction
+ * @Short_description: An action of which only one in a group can be active
+ * @Title: GtkRadioAction
+ *
+ * A #GtkRadioAction is similar to #GtkRadioMenuItem. A number of radio
+ * actions can be linked together so that only one may be active at any
+ * one time.
+ */
+
 
 struct _GtkRadioActionPrivate 
 {
@@ -56,11 +61,10 @@ enum
 {
   PROP_0,
   PROP_VALUE,
-  PROP_GROUP
+  PROP_GROUP,
+  PROP_CURRENT_VALUE
 };
 
-static void gtk_radio_action_init         (GtkRadioAction *action);
-static void gtk_radio_action_class_init   (GtkRadioActionClass *class);
 static void gtk_radio_action_finalize     (GObject *object);
 static void gtk_radio_action_set_property (GObject         *object,
                                           guint            prop_id,
@@ -74,35 +78,8 @@ static void gtk_radio_action_activate     (GtkAction *action);
 static GtkWidget *create_menu_item        (GtkAction *action);
 
 
-GType
-gtk_radio_action_get_type (void)
-{
-  static GtkType type = 0;
-
-  if (!type)
-    {
-      static const GTypeInfo type_info =
-      {
-        sizeof (GtkRadioActionClass),
-        (GBaseInitFunc) NULL,
-        (GBaseFinalizeFunc) NULL,
-        (GClassInitFunc) gtk_radio_action_class_init,
-        (GClassFinalizeFunc) NULL,
-        NULL,
-        
-        sizeof (GtkRadioAction),
-        0, /* n_preallocs */
-        (GInstanceInitFunc) gtk_radio_action_init,
-      };
-
-      type = g_type_register_static (GTK_TYPE_TOGGLE_ACTION,
-                                     I_("GtkRadioAction"),
-                                     &type_info, 0);
-    }
-  return type;
-}
+G_DEFINE_TYPE (GtkRadioAction, gtk_radio_action, GTK_TYPE_TOGGLE_ACTION)
 
-static GObjectClass *parent_class = NULL;
 static guint         radio_action_signals[LAST_SIGNAL] = { 0 };
 
 static void
@@ -111,7 +88,6 @@ gtk_radio_action_class_init (GtkRadioActionClass *klass)
   GObjectClass *gobject_class;
   GtkActionClass *action_class;
 
-  parent_class = g_type_class_peek_parent (klass);
   gobject_class = G_OBJECT_CLASS (klass);
   action_class = GTK_ACTION_CLASS (klass);
 
@@ -159,6 +135,24 @@ gtk_radio_action_class_init (GtkRadioActionClass *klass)
                                                        GTK_TYPE_RADIO_ACTION,
                                                        GTK_PARAM_WRITABLE));
 
+  /**
+   * GtkRadioAction:current-value:
+   *
+   * The value property of the currently active member of the group to which
+   * this action belongs. 
+   *
+   * Since: 2.10
+   */
+  g_object_class_install_property (gobject_class,
+                                  PROP_CURRENT_VALUE,
+                                   g_param_spec_int ("current-value",
+                                                    P_("The current value"),
+                                                    P_("The value property of the currently active member of the group to which this action belongs."),
+                                                    G_MININT,
+                                                    G_MAXINT,
+                                                    0,
+                                                    GTK_PARAM_READWRITE));
+
   /**
    * GtkRadioAction::changed:
    * @action: the action on which the signal is emitted
@@ -184,19 +178,26 @@ gtk_radio_action_class_init (GtkRadioActionClass *klass)
 static void
 gtk_radio_action_init (GtkRadioAction *action)
 {
-  action->private_data = GTK_RADIO_ACTION_GET_PRIVATE (action);
+  action->private_data = G_TYPE_INSTANCE_GET_PRIVATE (action,
+                                                      GTK_TYPE_RADIO_ACTION,
+                                                      GtkRadioActionPrivate);
+
   action->private_data->group = g_slist_prepend (NULL, action);
   action->private_data->value = 0;
+
+  gtk_toggle_action_set_draw_as_radio (GTK_TOGGLE_ACTION (action), TRUE);
 }
 
 /**
  * gtk_radio_action_new:
  * @name: A unique name for the action
- * @label: The label displayed in menu items and on buttons
- * @tooltip: A tooltip for this action
- * @stock_id: The stock icon to display in widgets representing this action
- * @value: The value which gtk_radio_action_get_current_value() should return
- *    if this action is selected.
+ * @label: (allow-none): The label displayed in menu items and on buttons,
+ *   or %NULL
+ * @tooltip: (allow-none): A tooltip for this action, or %NULL
+ * @stock_id: (allow-none): The stock icon to display in widgets representing
+ *   this action, or %NULL
+ * @value: The value which gtk_radio_action_get_current_value() should
+ *   return if this action is selected.
  *
  * Creates a new #GtkRadioAction object. To add the action to
  * a #GtkActionGroup and set the accelerator for the action,
@@ -213,17 +214,15 @@ gtk_radio_action_new (const gchar *name,
                      const gchar *stock_id,
                      gint value)
 {
-  GtkRadioAction *action;
-
-  action = g_object_new (GTK_TYPE_RADIO_ACTION,
-                        "name", name,
-                        "label", label,
-                        "tooltip", tooltip,
-                        "stock-id", stock_id,
-                        "value", value,
-                        NULL);
-
-  return action;
+  g_return_val_if_fail (name != NULL, NULL);
+
+  return g_object_new (GTK_TYPE_RADIO_ACTION,
+                       "name", name,
+                       "label", label,
+                       "tooltip", tooltip,
+                       "stock-id", stock_id,
+                       "value", value,
+                       NULL);
 }
 
 static void
@@ -246,7 +245,7 @@ gtk_radio_action_finalize (GObject *object)
       tmp_action->private_data->group = action->private_data->group;
     }
 
-  (* parent_class->finalize) (object);
+  G_OBJECT_CLASS (gtk_radio_action_parent_class)->finalize (object);
 }
 
 static void
@@ -278,6 +277,10 @@ gtk_radio_action_set_property (GObject         *object,
          }
       }
       break;
+    case PROP_CURRENT_VALUE:
+      gtk_radio_action_set_current_value (radio_action,
+                                          g_value_get_int (value));
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -299,6 +302,10 @@ gtk_radio_action_get_property (GObject    *object,
     case PROP_VALUE:
       g_value_set_int (value, radio_action->private_data->value);
       break;
+    case PROP_CURRENT_VALUE:
+      g_value_set_int (value,
+                       gtk_radio_action_get_current_value (radio_action));
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -312,11 +319,13 @@ gtk_radio_action_activate (GtkAction *action)
   GtkToggleAction *toggle_action;
   GtkToggleAction *tmp_action;
   GSList *tmp_list;
+  gboolean active;
 
   radio_action = GTK_RADIO_ACTION (action);
   toggle_action = GTK_TOGGLE_ACTION (action);
 
-  if (toggle_action->private_data->active)
+  active = gtk_toggle_action_get_active (toggle_action);
+  if (active)
     {
       tmp_list = radio_action->private_data->group;
 
@@ -325,16 +334,20 @@ gtk_radio_action_activate (GtkAction *action)
          tmp_action = tmp_list->data;
          tmp_list = tmp_list->next;
 
-         if (tmp_action->private_data->active && (tmp_action != toggle_action)) 
+         if (gtk_toggle_action_get_active (tmp_action) &&
+              (tmp_action != toggle_action))
            {
-             toggle_action->private_data->active = !toggle_action->private_data->active;
+              _gtk_toggle_action_set_active (toggle_action, !active);
+
              break;
            }
        }
+      g_object_notify (G_OBJECT (action), "active");
     }
   else
     {
-      toggle_action->private_data->active = !toggle_action->private_data->active;
+      _gtk_toggle_action_set_active (toggle_action, !active);
+      g_object_notify (G_OBJECT (action), "active");
 
       tmp_list = radio_action->private_data->group;
       while (tmp_list)
@@ -342,7 +355,8 @@ gtk_radio_action_activate (GtkAction *action)
          tmp_action = tmp_list->data;
          tmp_list = tmp_list->next;
 
-         if (tmp_action->private_data->active && (tmp_action != toggle_action))
+          if (gtk_toggle_action_get_active (tmp_action) &&
+              (tmp_action != toggle_action))
            {
              _gtk_action_emit_activate (GTK_ACTION (tmp_action));
              break;
@@ -355,6 +369,8 @@ gtk_radio_action_activate (GtkAction *action)
          tmp_action = tmp_list->data;
          tmp_list = tmp_list->next;
          
+          g_object_notify (G_OBJECT (tmp_action), "current-value");
+
          g_signal_emit (tmp_action, radio_action_signals[CHANGED], 0, radio_action);
        }
     }
@@ -379,20 +395,20 @@ create_menu_item (GtkAction *action)
  * to the group. 
  *
  * A common way to set up a group of radio group is the following:
- * <informalexample><programlisting>
+ * |[
  *   GSList *group = NULL;
  *   GtkRadioAction *action;
  *  
- *   while (/<!-- -->* more actions to add *<!-- -->/)
+ *   while (/&ast; more actions to add &ast;/)
  *     {
  *        action = gtk_radio_action_new (...);
  *        
  *        gtk_radio_action_set_group (action, group);
  *        group = gtk_radio_action_get_group (action);
  *     }
- * </programlisting></informalexample>
+ * ]|
  *
- * Returns: the list representing the radio group for this object
+ * Returns:  (element-type GtkRadioAction) (transfer none): the list representing the radio group for this object
  *
  * Since: 2.4
  */
@@ -407,7 +423,7 @@ gtk_radio_action_get_group (GtkRadioAction *action)
 /**
  * gtk_radio_action_set_group:
  * @action: the action object
- * @group: a list representing a radio group
+ * @group: (element-type GtkRadioAction): a list representing a radio group
  *
  * Sets the radio group for the radio action object.
  *
@@ -453,6 +469,61 @@ gtk_radio_action_set_group (GtkRadioAction *action,
     }
 }
 
+/**
+ * gtk_radio_action_join_group:
+ * @action: the action object
+ * @group_source: (allow-none): a radio action object whos group we are 
+ *   joining, or %NULL to remove the radio action from its group
+ *
+ * Joins a radio action object to the group of another radio action object.
+ *
+ * Use this in language bindings instead of the gtk_radio_action_get_group() 
+ * and gtk_radio_action_set_group() methods
+ *
+ * A common way to set up a group of radio actions is the following:
+ * |[
+ *   GtkRadioAction *action;
+ *   GtkRadioAction *last_action;
+ *  
+ *   while (/&ast; more actions to add &ast;/)
+ *     {
+ *        action = gtk_radio_action_new (...);
+ *        
+ *        gtk_radio_action_join_group (action, last_action);
+ *        last_action = action;
+ *     }
+ * ]|
+ * 
+ * Since: 3.0
+ */
+void
+gtk_radio_action_join_group (GtkRadioAction *action, 
+                            GtkRadioAction *group_source)
+{
+  g_return_if_fail (GTK_IS_RADIO_ACTION (action));
+  g_return_if_fail (group_source == NULL || GTK_IS_RADIO_ACTION (group_source));  
+
+  if (group_source)
+    {
+      GSList *group;
+      group = gtk_radio_action_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_action_set_group (group_source, NULL);
+          group = gtk_radio_action_get_group (group_source);
+        }
+
+      gtk_radio_action_set_group (action, group);
+    }
+  else
+    {
+      gtk_radio_action_set_group (action, NULL);
+    }
+}
+
 /**
  * gtk_radio_action_get_current_value:
  * @action: a #GtkRadioAction
@@ -477,7 +548,7 @@ gtk_radio_action_get_current_value (GtkRadioAction *action)
        {
          GtkToggleAction *toggle_action = slist->data;
 
-         if (toggle_action->private_data->active)
+         if (gtk_toggle_action_get_active (toggle_action))
            return GTK_RADIO_ACTION (toggle_action)->private_data->value;
        }
     }
@@ -485,5 +556,42 @@ gtk_radio_action_get_current_value (GtkRadioAction *action)
   return action->private_data->value;
 }
 
-#define __GTK_RADIO_ACTION_C__
-#include "gtkaliasdef.c"
+/**
+ * gtk_radio_action_set_current_value:
+ * @action: a #GtkRadioAction
+ * @current_value: the new value
+ * 
+ * Sets the currently active group member to the member with value
+ * property @current_value.
+ *
+ * Since: 2.10
+ **/
+void
+gtk_radio_action_set_current_value (GtkRadioAction *action,
+                                    gint            current_value)
+{
+  GSList *slist;
+
+  g_return_if_fail (GTK_IS_RADIO_ACTION (action));
+
+  if (action->private_data->group)
+    {
+      for (slist = action->private_data->group; slist; slist = slist->next)
+       {
+         GtkRadioAction *radio_action = slist->data;
+
+         if (radio_action->private_data->value == current_value)
+            {
+              gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (radio_action),
+                                            TRUE);
+              return;
+            }
+       }
+    }
+
+  if (action->private_data->value == current_value)
+    gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), TRUE);
+  else
+    g_warning ("Radio group does not contain an action with value '%d'",
+              current_value);
+}