]> Pileus Git - ~andy/gtk/blob - gtk/gtktoggleaction.c
Doc tweaks-
[~andy/gtk] / gtk / gtktoggleaction.c
1 /*
2  * GTK - The GIMP Toolkit
3  * Copyright (C) 1998, 1999 Red Hat, Inc.
4  * All rights reserved.
5  *
6  * This Library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Library General Public License as
8  * published by the Free Software Foundation; either version 2 of the
9  * License, or (at your option) any later version.
10  *
11  * This Library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Library General Public License for more details.
15  *
16  * You should have received a copy of the GNU Library General Public
17  * License along with the Gnome Library; see the file COPYING.LIB.  If not,
18  * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19  * Boston, MA 02111-1307, USA.
20  */
21
22 /*
23  * Author: James Henstridge <james@daa.com.au>
24  *
25  * Modified by the GTK+ Team and others 2003.  See the AUTHORS
26  * file for a list of people on the GTK+ Team.  See the ChangeLog
27  * files for a list of changes.  These files are distributed with
28  * GTK+ at ftp://ftp.gtk.org/pub/gtk/. 
29  */
30
31 #include <config.h>
32
33 #include "gtkintl.h"
34 #include "gtktoggleaction.h"
35 #include "gtktoggleactionprivate.h"
36 #include "gtktoggletoolbutton.h"
37 #include "gtktogglebutton.h"
38 #include "gtkcheckmenuitem.h"
39
40 enum 
41 {
42   TOGGLED,
43   LAST_SIGNAL
44 };
45
46 enum {
47   PROP_0,
48   PROP_DRAW_AS_RADIO
49 };
50
51 static void gtk_toggle_action_init       (GtkToggleAction *action);
52 static void gtk_toggle_action_class_init (GtkToggleActionClass *class);
53
54 GType
55 gtk_toggle_action_get_type (void)
56 {
57   static GtkType type = 0;
58
59   if (!type)
60     {
61       static const GTypeInfo type_info =
62       {
63         sizeof (GtkToggleActionClass),
64         (GBaseInitFunc) NULL,
65         (GBaseFinalizeFunc) NULL,
66         (GClassInitFunc) gtk_toggle_action_class_init,
67         (GClassFinalizeFunc) NULL,
68         NULL,
69         
70         sizeof (GtkToggleAction),
71         0, /* n_preallocs */
72         (GInstanceInitFunc) gtk_toggle_action_init,
73       };
74
75       type = g_type_register_static (GTK_TYPE_ACTION,
76                                      "GtkToggleAction",
77                                      &type_info, 0);
78     }
79   return type;
80 }
81
82 static void gtk_toggle_action_activate     (GtkAction       *action);
83 static void gtk_toggle_action_real_toggled (GtkToggleAction *action);
84 static void connect_proxy                  (GtkAction       *action,
85                                             GtkWidget       *proxy);
86 static void disconnect_proxy               (GtkAction       *action,
87                                             GtkWidget       *proxy);
88 static void set_property                   (GObject         *object,
89                                             guint            prop_id,
90                                             const GValue    *value,
91                                             GParamSpec      *pspec);
92 static void get_property                   (GObject         *object,
93                                             guint            prop_id,
94                                             GValue          *value,
95                                             GParamSpec      *pspec);
96 static GtkWidget *create_menu_item         (GtkAction       *action);
97
98
99 static GObjectClass *parent_class = NULL;
100 static guint         action_signals[LAST_SIGNAL] = { 0 };
101
102 static void
103 gtk_toggle_action_class_init (GtkToggleActionClass *klass)
104 {
105   GObjectClass *gobject_class;
106   GtkActionClass *action_class;
107
108   parent_class = g_type_class_peek_parent (klass);
109   gobject_class = G_OBJECT_CLASS (klass);
110   action_class = GTK_ACTION_CLASS (klass);
111
112   gobject_class->set_property = set_property;
113   gobject_class->get_property = get_property;
114
115   action_class->activate = gtk_toggle_action_activate;
116   action_class->connect_proxy = connect_proxy;
117   action_class->disconnect_proxy = disconnect_proxy;
118
119   action_class->menu_item_type = GTK_TYPE_CHECK_MENU_ITEM;
120   action_class->toolbar_item_type = GTK_TYPE_TOGGLE_TOOL_BUTTON;
121
122   action_class->create_menu_item = create_menu_item;
123
124   klass->toggled = gtk_toggle_action_real_toggled;
125
126   g_object_class_install_property (gobject_class,
127                                    PROP_DRAW_AS_RADIO,
128                                    g_param_spec_boolean ("draw_as_radio",
129                                                          _("Create the same proxies as a radio action"),
130                                                          _("Whether the proxies for this action look like radio action proxies"),
131                                                          FALSE,
132                                                          G_PARAM_READWRITE));
133
134   action_signals[TOGGLED] =
135     g_signal_new ("toggled",
136                   G_OBJECT_CLASS_TYPE (klass),
137                   G_SIGNAL_RUN_FIRST,
138                   G_STRUCT_OFFSET (GtkToggleActionClass, toggled),
139                   NULL, NULL,
140                   g_cclosure_marshal_VOID__VOID,
141                   G_TYPE_NONE, 0);
142
143   g_type_class_add_private (gobject_class, sizeof (GtkToggleActionPrivate));
144 }
145
146 static void
147 gtk_toggle_action_init (GtkToggleAction *action)
148 {
149   action->private_data = GTK_TOGGLE_ACTION_GET_PRIVATE (action);
150   action->private_data->active = FALSE;
151   action->private_data->draw_as_radio = FALSE;
152 }
153
154 static void
155 get_property (GObject     *object,
156               guint        prop_id,
157               GValue      *value,
158               GParamSpec  *pspec)
159 {
160   GtkToggleAction *action = GTK_TOGGLE_ACTION (object);
161   
162   switch (prop_id)
163     {
164     case PROP_DRAW_AS_RADIO:
165       g_value_set_boolean (value, gtk_toggle_action_get_draw_as_radio (action));
166       break;
167     default:
168       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
169       break;
170     }
171 }
172
173
174 static void
175 set_property (GObject      *object,
176               guint         prop_id,
177               const GValue *value,
178               GParamSpec   *pspec)
179 {
180   GtkToggleAction *action = GTK_TOGGLE_ACTION (object);
181   
182   switch (prop_id)
183     {
184     case PROP_DRAW_AS_RADIO:
185       gtk_toggle_action_set_draw_as_radio (action, g_value_get_boolean (value));
186       break;
187     default:
188       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
189       break;
190     }
191 }
192
193 static void
194 gtk_toggle_action_activate (GtkAction *action)
195 {
196   GtkToggleAction *toggle_action;
197
198   g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
199
200   toggle_action = GTK_TOGGLE_ACTION (action);
201
202   toggle_action->private_data->active = !toggle_action->private_data->active;
203
204   gtk_toggle_action_toggled (toggle_action);
205 }
206
207 static void
208 gtk_toggle_action_real_toggled (GtkToggleAction *action)
209 {
210   GSList *slist;
211
212   g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
213
214   for (slist = gtk_action_get_proxies (GTK_ACTION (action)); slist; slist = slist->next)
215     {
216       GtkWidget *proxy = slist->data;
217
218       gtk_action_block_activate_from (GTK_ACTION (action), proxy);
219       if (GTK_IS_CHECK_MENU_ITEM (proxy))
220         gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (proxy),
221                                         action->private_data->active);
222       else if (GTK_IS_TOGGLE_TOOL_BUTTON (proxy))
223         gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON (proxy),
224                                            action->private_data->active);
225       else if (GTK_IS_TOGGLE_BUTTON (proxy))
226         gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (proxy),
227                                       action->private_data->active);
228       else {
229         g_warning ("Don't know how to toggle `%s' widgets",
230                    G_OBJECT_TYPE_NAME (proxy));
231       }
232       gtk_action_unblock_activate_from (GTK_ACTION (action), proxy);
233     }
234 }
235
236 static void
237 connect_proxy (GtkAction *action, 
238                GtkWidget *proxy)
239 {
240   GtkToggleAction *toggle_action;
241
242   toggle_action = GTK_TOGGLE_ACTION (action);
243
244   /* do this before hand, so that we don't call the "activate" handler */
245   if (GTK_IS_MENU_ITEM (proxy))
246     gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (proxy),
247                                     toggle_action->private_data->active);
248   else if (GTK_IS_TOGGLE_TOOL_BUTTON (proxy))
249     gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON (proxy),
250                                        toggle_action->private_data->active);
251   else if (GTK_IS_TOGGLE_BUTTON (proxy))
252     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (proxy),
253                                   toggle_action->private_data->active);
254
255   (* GTK_ACTION_CLASS (parent_class)->connect_proxy) (action, proxy);
256 }
257
258 static void
259 disconnect_proxy (GtkAction *action, 
260                   GtkWidget *proxy)
261 {
262   GtkToggleAction *toggle_action;
263
264   toggle_action = GTK_TOGGLE_ACTION (action);
265
266   (* GTK_ACTION_CLASS (parent_class)->disconnect_proxy) (action, proxy);
267 }
268
269 /**
270  * gtk_toggle_action_toggled:
271  * @action: the action object
272  *
273  * Emits the "toggled" signal on the toggle action.
274  *
275  * Since: 2.4
276  */
277 void
278 gtk_toggle_action_toggled (GtkToggleAction *action)
279 {
280   g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
281
282   g_signal_emit (action, action_signals[TOGGLED], 0);
283 }
284
285 /**
286  * gtk_toggle_action_set_active:
287  * @action: the action object
288  * @is_active: whether the action should be checked or not
289  *
290  * Sets the checked state on the toggle action.
291  *
292  * Since: 2.4
293  */
294 void
295 gtk_toggle_action_set_active (GtkToggleAction *action, 
296                               gboolean         is_active)
297 {
298   g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
299
300   is_active = is_active != FALSE;
301
302   if (action->private_data->active != is_active)
303     {
304       gtk_action_activate (GTK_ACTION (action));
305     }
306 }
307
308 /**
309  * gtk_toggle_action_get_active:
310  * @action: the action object
311  *
312  * Returns the checked state of the toggle action.
313
314  * Returns: the checked state of the toggle action
315  *
316  * Since: 2.4
317  */
318 gboolean
319 gtk_toggle_action_get_active (GtkToggleAction *action)
320 {
321   g_return_val_if_fail (GTK_IS_TOGGLE_ACTION (action), FALSE);
322
323   return action->private_data->active;
324 }
325
326
327 /**
328  * gtk_toggle_action_set_draw_as_radio:
329  * @action: the action object
330  * @draw_as_radio: whether the action should have proxies like a radio 
331  *    action
332  *
333  * Sets whether the action should have proxies like a radio action.
334  *
335  * Since: 2.4
336  */
337 void
338 gtk_toggle_action_set_draw_as_radio (GtkToggleAction *action, 
339                                      gboolean         draw_as_radio)
340 {
341   g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
342
343   draw_as_radio = draw_as_radio != FALSE;
344
345   if (action->private_data->draw_as_radio != draw_as_radio)
346     {
347       action->private_data->draw_as_radio = draw_as_radio;
348       
349       g_object_notify (G_OBJECT (action), "draw_as_radio");      
350     }
351 }
352
353 /**
354  * gtk_toggle_action_get_draw_as_radio:
355  * @action: the action object
356  *
357  * Returns whether the action should have proxies like a radio action.
358  *
359  * Returns: whether the action should have proxies like a radio action.
360  *
361  * Since: 2.4
362  */
363 gboolean
364 gtk_toggle_action_get_draw_as_radio (GtkToggleAction *action)
365 {
366   g_return_val_if_fail (GTK_IS_TOGGLE_ACTION (action), FALSE);
367
368   return action->private_data->draw_as_radio;
369 }
370
371 static GtkWidget *
372 create_menu_item (GtkAction *action)
373 {
374   GtkToggleAction *toggle_action = GTK_TOGGLE_ACTION (action);
375
376   return g_object_new (GTK_TYPE_CHECK_MENU_ITEM, 
377                        "draw_as_radio", toggle_action->private_data->draw_as_radio,
378                        NULL);
379 }