]> Pileus Git - ~andy/gtk/blob - gtk/gtktoggleaction.c
Test buttons and toggle buttons as proxies.
[~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 "gtktoggleaction.h"
34 #include "gtktoggleactionprivate.h"
35 #include "gtktoggletoolbutton.h"
36 #include "gtktogglebutton.h"
37 #include "gtkcheckmenuitem.h"
38
39 enum 
40 {
41   TOGGLED,
42   LAST_SIGNAL
43 };
44
45 static void gtk_toggle_action_init       (GtkToggleAction *action);
46 static void gtk_toggle_action_class_init (GtkToggleActionClass *class);
47
48 GType
49 gtk_toggle_action_get_type (void)
50 {
51   static GtkType type = 0;
52
53   if (!type)
54     {
55       static const GTypeInfo type_info =
56       {
57         sizeof (GtkToggleActionClass),
58         (GBaseInitFunc) NULL,
59         (GBaseFinalizeFunc) NULL,
60         (GClassInitFunc) gtk_toggle_action_class_init,
61         (GClassFinalizeFunc) NULL,
62         NULL,
63         
64         sizeof (GtkToggleAction),
65         0, /* n_preallocs */
66         (GInstanceInitFunc) gtk_toggle_action_init,
67       };
68
69       type = g_type_register_static (GTK_TYPE_ACTION,
70                                      "GtkToggleAction",
71                                      &type_info, 0);
72     }
73   return type;
74 }
75
76 static void gtk_toggle_action_activate     (GtkAction *action);
77 static void gtk_toggle_action_real_toggled (GtkToggleAction *action);
78 static void connect_proxy                  (GtkAction *action,
79                                             GtkWidget *proxy);
80 static void disconnect_proxy               (GtkAction *action,
81                                             GtkWidget *proxy);
82
83 static GObjectClass *parent_class = NULL;
84 static guint         action_signals[LAST_SIGNAL] = { 0 };
85
86 static void
87 gtk_toggle_action_class_init (GtkToggleActionClass *klass)
88 {
89   GObjectClass *gobject_class;
90   GtkActionClass *action_class;
91
92   parent_class = g_type_class_peek_parent (klass);
93   gobject_class = G_OBJECT_CLASS (klass);
94   action_class = GTK_ACTION_CLASS (klass);
95
96   action_class->activate = gtk_toggle_action_activate;
97   action_class->connect_proxy = connect_proxy;
98   action_class->disconnect_proxy = disconnect_proxy;
99
100   action_class->menu_item_type = GTK_TYPE_CHECK_MENU_ITEM;
101   action_class->toolbar_item_type = GTK_TYPE_TOGGLE_TOOL_BUTTON;
102
103   klass->toggled = gtk_toggle_action_real_toggled;
104
105   action_signals[TOGGLED] =
106     g_signal_new ("toggled",
107                   G_OBJECT_CLASS_TYPE (klass),
108                   G_SIGNAL_RUN_FIRST,
109                   G_STRUCT_OFFSET (GtkToggleActionClass, toggled),
110                   NULL, NULL,
111                   g_cclosure_marshal_VOID__VOID,
112                   G_TYPE_NONE, 0);
113
114   g_type_class_add_private (gobject_class, sizeof (GtkToggleActionPrivate));
115 }
116
117 static void
118 gtk_toggle_action_init (GtkToggleAction *action)
119 {
120   action->private_data = GTK_TOGGLE_ACTION_GET_PRIVATE (action);
121   action->private_data->active = FALSE;
122 }
123
124 static void
125 gtk_toggle_action_activate (GtkAction *action)
126 {
127   GtkToggleAction *toggle_action;
128
129   g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
130
131   toggle_action = GTK_TOGGLE_ACTION (action);
132
133   toggle_action->private_data->active = !toggle_action->private_data->active;
134
135   gtk_toggle_action_toggled (toggle_action);
136 }
137
138 static void
139 gtk_toggle_action_real_toggled (GtkToggleAction *action)
140 {
141   GSList *slist;
142
143   g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
144
145   for (slist = gtk_action_get_proxies (GTK_ACTION (action)); slist; slist = slist->next)
146     {
147       GtkWidget *proxy = slist->data;
148
149       gtk_action_block_activate_from (GTK_ACTION (action), proxy);
150       if (GTK_IS_CHECK_MENU_ITEM (proxy))
151         gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (proxy),
152                                         action->private_data->active);
153       else if (GTK_IS_TOGGLE_TOOL_BUTTON (proxy))
154         gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON (proxy),
155                                            action->private_data->active);
156       else if (GTK_IS_TOGGLE_BUTTON (proxy))
157         gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (proxy),
158                                       action->private_data->active);
159       else {
160         g_warning ("Don't know how to toggle `%s' widgets",
161                    G_OBJECT_TYPE_NAME (proxy));
162       }
163       gtk_action_unblock_activate_from (GTK_ACTION (action), proxy);
164     }
165 }
166
167 static void
168 connect_proxy (GtkAction *action, 
169                GtkWidget *proxy)
170 {
171   GtkToggleAction *toggle_action;
172
173   toggle_action = GTK_TOGGLE_ACTION (action);
174
175   /* do this before hand, so that we don't call the "activate" handler */
176   if (GTK_IS_MENU_ITEM (proxy))
177     gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (proxy),
178                                     toggle_action->private_data->active);
179   else if (GTK_IS_TOGGLE_TOOL_BUTTON (proxy))
180     gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON (proxy),
181                                        toggle_action->private_data->active);
182   else if (GTK_IS_TOGGLE_BUTTON (proxy))
183     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (proxy),
184                                   toggle_action->private_data->active);
185
186   (* GTK_ACTION_CLASS (parent_class)->connect_proxy) (action, proxy);
187 }
188
189 static void
190 disconnect_proxy (GtkAction *action, 
191                   GtkWidget *proxy)
192 {
193   GtkToggleAction *toggle_action;
194
195   toggle_action = GTK_TOGGLE_ACTION (action);
196
197   (* GTK_ACTION_CLASS (parent_class)->disconnect_proxy) (action, proxy);
198 }
199
200 /**
201  * gtk_toggle_action_toggled:
202  * @action: the action object
203  *
204  * Emits the "toggled" signal on the toggle action.
205  *
206  * Since: 2.4
207  */
208 void
209 gtk_toggle_action_toggled (GtkToggleAction *action)
210 {
211   g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
212
213   g_signal_emit (action, action_signals[TOGGLED], 0);
214 }
215
216 /**
217  * gtk_toggle_action_set_active:
218  * @action: the action object
219  * @is_active: whether the action should be checked or not
220  *
221  * Sets the checked state on the toggle action.
222  *
223  * Since: 2.4
224  */
225 void
226 gtk_toggle_action_set_active (GtkToggleAction *action, 
227                               gboolean         is_active)
228 {
229   g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
230
231   is_active = is_active != FALSE;
232
233   if (action->private_data->active != is_active)
234     {
235       gtk_action_activate (GTK_ACTION (action));
236     }
237 }
238
239 /**
240  * gtk_toggle_action_get_active:
241  * @action: the action object
242  *
243  * Returns: the checked state of the toggle action
244  *
245  * Since: 2.4
246  */
247 gboolean
248 gtk_toggle_action_get_active (GtkToggleAction *action)
249 {
250   g_return_val_if_fail (GTK_IS_TOGGLE_ACTION (action), FALSE);
251
252   return action->private_data->active;
253 }