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 this library. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20 /*
21 * Author: James Henstridge <james@daa.com.au>
22 *
23 * Modified by the GTK+ Team and others 2003. See the AUTHORS
24 * file for a list of people on the GTK+ Team. See the ChangeLog
25 * files for a list of changes. These files are distributed with
26 * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
27 */
28
29 #include "config.h"
30
31 #define GDK_DISABLE_DEPRECATION_WARNINGS
32
33 #include "gtkintl.h"
34 #include "gtktoggleaction.h"
35 #include "gtktoggletoolbutton.h"
36 #include "gtktogglebutton.h"
37 #include "gtkcheckmenuitem.h"
38 #include "gtkprivate.h"
39
40
41 /**
42 * SECTION:gtktoggleaction
43 * @Short_description: An action which can be toggled between two states
44 * @Title: GtkToggleAction
45 *
46 * A #GtkToggleAction corresponds roughly to a #GtkCheckMenuItem. It has an
47 * “active” state specifying whether the action has been checked or not.
48 */
49
50 struct _GtkToggleActionPrivate
51 {
52 guint active : 1;
53 guint draw_as_radio : 1;
54 };
55
56 enum
57 {
58 TOGGLED,
59 LAST_SIGNAL
60 };
61
62 enum {
63 PROP_0,
64 PROP_DRAW_AS_RADIO,
65 PROP_ACTIVE
66 };
67
68 G_DEFINE_TYPE_WITH_PRIVATE (GtkToggleAction, gtk_toggle_action, GTK_TYPE_ACTION)
69
70 static void gtk_toggle_action_activate (GtkAction *action);
71 static void set_property (GObject *object,
72 guint prop_id,
73 const GValue *value,
74 GParamSpec *pspec);
75 static void get_property (GObject *object,
76 guint prop_id,
77 GValue *value,
78 GParamSpec *pspec);
79 static GtkWidget *create_menu_item (GtkAction *action);
80
81
82 static guint action_signals[LAST_SIGNAL] = { 0 };
83
84 static void
gtk_toggle_action_class_init(GtkToggleActionClass * klass)85 gtk_toggle_action_class_init (GtkToggleActionClass *klass)
86 {
87 GObjectClass *gobject_class;
88 GtkActionClass *action_class;
89
90 gobject_class = G_OBJECT_CLASS (klass);
91 action_class = GTK_ACTION_CLASS (klass);
92
93 gobject_class->set_property = set_property;
94 gobject_class->get_property = get_property;
95
96 action_class->activate = gtk_toggle_action_activate;
97
98 action_class->menu_item_type = GTK_TYPE_CHECK_MENU_ITEM;
99 action_class->toolbar_item_type = GTK_TYPE_TOGGLE_TOOL_BUTTON;
100
101 action_class->create_menu_item = create_menu_item;
102
103 klass->toggled = NULL;
104
105 /**
106 * GtkToggleAction:draw-as-radio:
107 *
108 * Whether the proxies for this action look like radio action proxies.
109 *
110 * This is an appearance property and thus only applies if
111 * #GtkActivatable:use-action-appearance is %TRUE.
112 *
113 * Deprecated: 3.10
114 */
115 g_object_class_install_property (gobject_class,
116 PROP_DRAW_AS_RADIO,
117 g_param_spec_boolean ("draw-as-radio",
118 P_("Create the same proxies as a radio action"),
119 P_("Whether the proxies for this action look like radio action proxies"),
120 FALSE,
121 GTK_PARAM_READWRITE));
122
123 /**
124 * GtkToggleAction:active:
125 *
126 * Whether the toggle action should be active.
127 *
128 * Since: 2.10
129 *
130 * Deprecated: 3.10
131 */
132 g_object_class_install_property (gobject_class,
133 PROP_ACTIVE,
134 g_param_spec_boolean ("active",
135 P_("Active"),
136 P_("Whether the toggle action should be active"),
137 FALSE,
138 GTK_PARAM_READWRITE));
139 /**
140 * GtkToggleAction::toggled:
141 * @toggleaction: the object which received the signal.
142 *
143 * Should be connected if you wish to perform an action
144 * whenever the #GtkToggleAction state is changed.
145 *
146 * Deprecated: 3.10
147 */
148 action_signals[TOGGLED] =
149 g_signal_new (I_("toggled"),
150 G_OBJECT_CLASS_TYPE (klass),
151 G_SIGNAL_RUN_FIRST,
152 G_STRUCT_OFFSET (GtkToggleActionClass, toggled),
153 NULL, NULL,
154 NULL,
155 G_TYPE_NONE, 0);
156 }
157
158 static void
gtk_toggle_action_init(GtkToggleAction * action)159 gtk_toggle_action_init (GtkToggleAction *action)
160 {
161 action->private_data = gtk_toggle_action_get_instance_private (action);
162 action->private_data->active = FALSE;
163 action->private_data->draw_as_radio = FALSE;
164 }
165
166 /**
167 * gtk_toggle_action_new:
168 * @name: A unique name for the action
169 * @label: (allow-none): The label displayed in menu items and on buttons,
170 * or %NULL
171 * @tooltip: (allow-none): A tooltip for the action, or %NULL
172 * @stock_id: (allow-none): The stock icon to display in widgets representing
173 * the action, or %NULL
174 *
175 * Creates a new #GtkToggleAction object. To add the action to
176 * a #GtkActionGroup and set the accelerator for the action,
177 * call gtk_action_group_add_action_with_accel().
178 *
179 * Returns: a new #GtkToggleAction
180 *
181 * Since: 2.4
182 *
183 * Deprecated: 3.10
184 */
185 GtkToggleAction *
gtk_toggle_action_new(const gchar * name,const gchar * label,const gchar * tooltip,const gchar * stock_id)186 gtk_toggle_action_new (const gchar *name,
187 const gchar *label,
188 const gchar *tooltip,
189 const gchar *stock_id)
190 {
191 g_return_val_if_fail (name != NULL, NULL);
192
193 return g_object_new (GTK_TYPE_TOGGLE_ACTION,
194 "name", name,
195 "label", label,
196 "tooltip", tooltip,
197 "stock-id", stock_id,
198 NULL);
199 }
200
201 static void
get_property(GObject * object,guint prop_id,GValue * value,GParamSpec * pspec)202 get_property (GObject *object,
203 guint prop_id,
204 GValue *value,
205 GParamSpec *pspec)
206 {
207 GtkToggleAction *action = GTK_TOGGLE_ACTION (object);
208
209 switch (prop_id)
210 {
211 case PROP_DRAW_AS_RADIO:
212 g_value_set_boolean (value, gtk_toggle_action_get_draw_as_radio (action));
213 break;
214 case PROP_ACTIVE:
215 g_value_set_boolean (value, gtk_toggle_action_get_active (action));
216 break;
217 default:
218 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
219 break;
220 }
221 }
222
223 static void
set_property(GObject * object,guint prop_id,const GValue * value,GParamSpec * pspec)224 set_property (GObject *object,
225 guint prop_id,
226 const GValue *value,
227 GParamSpec *pspec)
228 {
229 GtkToggleAction *action = GTK_TOGGLE_ACTION (object);
230
231 switch (prop_id)
232 {
233 case PROP_DRAW_AS_RADIO:
234 gtk_toggle_action_set_draw_as_radio (action, g_value_get_boolean (value));
235 break;
236 case PROP_ACTIVE:
237 gtk_toggle_action_set_active (action, g_value_get_boolean (value));
238 break;
239 default:
240 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
241 break;
242 }
243 }
244
245 static void
gtk_toggle_action_activate(GtkAction * action)246 gtk_toggle_action_activate (GtkAction *action)
247 {
248 GtkToggleAction *toggle_action;
249
250 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
251
252 toggle_action = GTK_TOGGLE_ACTION (action);
253
254 toggle_action->private_data->active = !toggle_action->private_data->active;
255
256 g_object_notify (G_OBJECT (action), "active");
257
258 gtk_toggle_action_toggled (toggle_action);
259 }
260
261 /**
262 * gtk_toggle_action_toggled:
263 * @action: the action object
264 *
265 * Emits the “toggled” signal on the toggle action.
266 *
267 * Since: 2.4
268 *
269 * Deprecated: 3.10
270 */
271 void
gtk_toggle_action_toggled(GtkToggleAction * action)272 gtk_toggle_action_toggled (GtkToggleAction *action)
273 {
274 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
275
276 g_signal_emit (action, action_signals[TOGGLED], 0);
277 }
278
279 /**
280 * gtk_toggle_action_set_active:
281 * @action: the action object
282 * @is_active: whether the action should be checked or not
283 *
284 * Sets the checked state on the toggle action.
285 *
286 * Since: 2.4
287 *
288 * Deprecated: 3.10
289 */
290 void
gtk_toggle_action_set_active(GtkToggleAction * action,gboolean is_active)291 gtk_toggle_action_set_active (GtkToggleAction *action,
292 gboolean is_active)
293 {
294 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
295
296 is_active = is_active != FALSE;
297
298 if (action->private_data->active != is_active)
299 _gtk_action_emit_activate (GTK_ACTION (action));
300 }
301
302 /**
303 * gtk_toggle_action_get_active:
304 * @action: the action object
305 *
306 * Returns the checked state of the toggle action.
307 *
308 * Returns: the checked state of the toggle action
309 *
310 * Since: 2.4
311 *
312 * Deprecated: 3.10
313 */
314 gboolean
gtk_toggle_action_get_active(GtkToggleAction * action)315 gtk_toggle_action_get_active (GtkToggleAction *action)
316 {
317 g_return_val_if_fail (GTK_IS_TOGGLE_ACTION (action), FALSE);
318
319 return action->private_data->active;
320 }
321
322
323 /**
324 * gtk_toggle_action_set_draw_as_radio:
325 * @action: the action object
326 * @draw_as_radio: whether the action should have proxies like a radio
327 * action
328 *
329 * Sets whether the action should have proxies like a radio action.
330 *
331 * Since: 2.4
332 *
333 * Deprecated: 3.10
334 */
335 void
gtk_toggle_action_set_draw_as_radio(GtkToggleAction * action,gboolean draw_as_radio)336 gtk_toggle_action_set_draw_as_radio (GtkToggleAction *action,
337 gboolean draw_as_radio)
338 {
339 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
340
341 draw_as_radio = draw_as_radio != FALSE;
342
343 if (action->private_data->draw_as_radio != draw_as_radio)
344 {
345 action->private_data->draw_as_radio = draw_as_radio;
346
347 g_object_notify (G_OBJECT (action), "draw-as-radio");
348 }
349 }
350
351 /**
352 * gtk_toggle_action_get_draw_as_radio:
353 * @action: the action object
354 *
355 * Returns whether the action should have proxies like a radio action.
356 *
357 * Returns: whether the action should have proxies like a radio action.
358 *
359 * Since: 2.4
360 *
361 * Deprecated: 3.10
362 */
363 gboolean
gtk_toggle_action_get_draw_as_radio(GtkToggleAction * action)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 *
create_menu_item(GtkAction * action)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 }
380
381
382 /* Private */
383
384 /*
385 * _gtk_toggle_action_set_active:
386 * @toggle_action: a #GtkToggleAction
387 * @is_active: whether the action is active or not
388 *
389 * Sets the #GtkToggleAction:active property directly. This function does
390 * not emit signals or notifications: it is left to the caller to do so.
391 *
392 * Deprecated: 3.10
393 */
394 void
_gtk_toggle_action_set_active(GtkToggleAction * toggle_action,gboolean is_active)395 _gtk_toggle_action_set_active (GtkToggleAction *toggle_action,
396 gboolean is_active)
397 {
398 GtkToggleActionPrivate *priv = toggle_action->private_data;
399
400 priv->active = is_active;
401 }
402