1 /* GTK - The GIMP Toolkit
2 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
21 * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
22 * file for a list of people on the GTK+ Team. See the ChangeLog
23 * files for a list of changes. These files are distributed with
24 * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
27 #include "gtkaccellabel.h"
28 #include "gtkradiomenuitem.h"
31 static void gtk_radio_menu_item_class_init (GtkRadioMenuItemClass *klass);
32 static void gtk_radio_menu_item_init (GtkRadioMenuItem *radio_menu_item);
33 static void gtk_radio_menu_item_destroy (GtkObject *object);
34 static void gtk_radio_menu_item_activate (GtkMenuItem *menu_item);
35 static void gtk_radio_menu_item_draw_indicator (GtkCheckMenuItem *check_menu_item,
38 static GtkCheckMenuItemClass *parent_class = NULL;
41 gtk_radio_menu_item_get_type (void)
43 static GType radio_menu_item_type = 0;
45 if (!radio_menu_item_type)
47 static const GTypeInfo radio_menu_item_info =
49 sizeof (GtkRadioMenuItemClass),
51 NULL, /* base_finalize */
52 (GClassInitFunc) gtk_radio_menu_item_class_init,
53 NULL, /* class_finalize */
54 NULL, /* class_data */
55 sizeof (GtkRadioMenuItem),
57 (GInstanceInitFunc) gtk_radio_menu_item_init,
60 radio_menu_item_type =
61 g_type_register_static (GTK_TYPE_CHECK_MENU_ITEM, "GtkRadioMenuItem",
62 &radio_menu_item_info, 0);
65 return radio_menu_item_type;
69 gtk_radio_menu_item_new (GSList *group)
71 GtkRadioMenuItem *radio_menu_item;
73 radio_menu_item = g_object_new (GTK_TYPE_RADIO_MENU_ITEM, NULL);
75 gtk_radio_menu_item_set_group (radio_menu_item, group);
77 return GTK_WIDGET (radio_menu_item);
81 gtk_radio_menu_item_set_group (GtkRadioMenuItem *radio_menu_item,
84 g_return_if_fail (GTK_IS_RADIO_MENU_ITEM (radio_menu_item));
85 g_return_if_fail (!g_slist_find (group, radio_menu_item));
87 if (radio_menu_item->group)
91 radio_menu_item->group = g_slist_remove (radio_menu_item->group, radio_menu_item);
93 for (slist = radio_menu_item->group; slist; slist = slist->next)
95 GtkRadioMenuItem *tmp_item;
97 tmp_item = slist->data;
99 tmp_item->group = radio_menu_item->group;
103 radio_menu_item->group = g_slist_prepend (group, radio_menu_item);
109 for (slist = group; slist; slist = slist->next)
111 GtkRadioMenuItem *tmp_item;
113 tmp_item = slist->data;
115 tmp_item->group = radio_menu_item->group;
120 GTK_CHECK_MENU_ITEM (radio_menu_item)->active = TRUE;
121 /* gtk_widget_set_state (GTK_WIDGET (radio_menu_item), GTK_STATE_ACTIVE);
127 gtk_radio_menu_item_new_with_label (GSList *group,
130 GtkWidget *radio_menu_item;
131 GtkWidget *accel_label;
133 radio_menu_item = gtk_radio_menu_item_new (group);
134 accel_label = gtk_accel_label_new (label);
135 gtk_misc_set_alignment (GTK_MISC (accel_label), 0.0, 0.5);
136 gtk_container_add (GTK_CONTAINER (radio_menu_item), accel_label);
137 gtk_accel_label_set_accel_widget (GTK_ACCEL_LABEL (accel_label), radio_menu_item);
138 gtk_widget_show (accel_label);
140 return radio_menu_item;
145 * gtk_radio_menu_item_new_with_mnemonic:
146 * @group: group the radio menu item is inside
147 * @label: the text of the button, with an underscore in front of the
149 * @returns: a new #GtkRadioMenuItem
151 * Creates a new #GtkRadioMenuItem containing a label. The label
152 * will be created using gtk_label_new_with_mnemonic(), so underscores
153 * in @label indicate the mnemonic for the menu item.
156 gtk_radio_menu_item_new_with_mnemonic (GSList *group,
159 GtkWidget *radio_menu_item;
160 GtkWidget *accel_label;
162 radio_menu_item = gtk_radio_menu_item_new (group);
163 accel_label = g_object_new (GTK_TYPE_ACCEL_LABEL, NULL);
164 gtk_label_set_text_with_mnemonic (GTK_LABEL (accel_label), label);
165 gtk_misc_set_alignment (GTK_MISC (accel_label), 0.0, 0.5);
167 gtk_container_add (GTK_CONTAINER (radio_menu_item), accel_label);
168 gtk_accel_label_set_accel_widget (GTK_ACCEL_LABEL (accel_label), radio_menu_item);
169 gtk_widget_show (accel_label);
171 return radio_menu_item;
175 gtk_radio_menu_item_get_group (GtkRadioMenuItem *radio_menu_item)
177 g_return_val_if_fail (GTK_IS_RADIO_MENU_ITEM (radio_menu_item), NULL);
179 return radio_menu_item->group;
184 gtk_radio_menu_item_class_init (GtkRadioMenuItemClass *klass)
186 GtkObjectClass *object_class;
187 GtkMenuItemClass *menu_item_class;
188 GtkCheckMenuItemClass *check_menu_item_class;
190 object_class = (GtkObjectClass*) klass;
191 menu_item_class = (GtkMenuItemClass*) klass;
192 check_menu_item_class = (GtkCheckMenuItemClass*) klass;
194 parent_class = g_type_class_peek_parent (klass);
196 object_class->destroy = gtk_radio_menu_item_destroy;
198 menu_item_class->activate = gtk_radio_menu_item_activate;
200 check_menu_item_class->draw_indicator = gtk_radio_menu_item_draw_indicator;
204 gtk_radio_menu_item_init (GtkRadioMenuItem *radio_menu_item)
206 radio_menu_item->group = g_slist_prepend (NULL, radio_menu_item);
210 gtk_radio_menu_item_destroy (GtkObject *object)
212 GtkRadioMenuItem *radio_menu_item;
213 GtkRadioMenuItem *tmp_menu_item;
216 g_return_if_fail (GTK_IS_RADIO_MENU_ITEM (object));
218 radio_menu_item = GTK_RADIO_MENU_ITEM (object);
220 radio_menu_item->group = g_slist_remove (radio_menu_item->group,
222 tmp_list = radio_menu_item->group;
226 tmp_menu_item = tmp_list->data;
227 tmp_list = tmp_list->next;
229 tmp_menu_item->group = radio_menu_item->group;
232 /* this radio menu item is no longer in the group */
233 radio_menu_item->group = NULL;
235 if (GTK_OBJECT_CLASS (parent_class)->destroy)
236 (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
240 gtk_radio_menu_item_activate (GtkMenuItem *menu_item)
242 GtkRadioMenuItem *radio_menu_item;
243 GtkCheckMenuItem *check_menu_item;
244 GtkCheckMenuItem *tmp_menu_item;
248 g_return_if_fail (GTK_IS_RADIO_MENU_ITEM (menu_item));
250 radio_menu_item = GTK_RADIO_MENU_ITEM (menu_item);
251 check_menu_item = GTK_CHECK_MENU_ITEM (menu_item);
254 if (check_menu_item->active)
256 tmp_menu_item = NULL;
257 tmp_list = radio_menu_item->group;
261 tmp_menu_item = tmp_list->data;
262 tmp_list = tmp_list->next;
264 if (tmp_menu_item->active && (tmp_menu_item != check_menu_item))
267 tmp_menu_item = NULL;
273 check_menu_item->active = !check_menu_item->active;
279 check_menu_item->active = !check_menu_item->active;
281 tmp_list = radio_menu_item->group;
284 tmp_menu_item = tmp_list->data;
285 tmp_list = tmp_list->next;
287 if (tmp_menu_item->active && (tmp_menu_item != check_menu_item))
289 gtk_menu_item_activate (GTK_MENU_ITEM (tmp_menu_item));
296 gtk_check_menu_item_toggled (check_menu_item);
297 gtk_widget_queue_draw (GTK_WIDGET (radio_menu_item));
301 gtk_radio_menu_item_draw_indicator (GtkCheckMenuItem *check_menu_item,
305 GtkStateType state_type;
306 GtkShadowType shadow_type;
311 g_return_if_fail (GTK_IS_RADIO_MENU_ITEM (check_menu_item));
313 if (GTK_WIDGET_DRAWABLE (check_menu_item))
315 widget = GTK_WIDGET (check_menu_item);
319 offset = GTK_CONTAINER (check_menu_item)->border_width +
320 widget->style->xthickness + 2;
321 if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR)
322 x = widget->allocation.x + offset;
324 x = widget->allocation.x + widget->allocation.width - width - offset;
325 y = widget->allocation.y + (widget->allocation.height - height) / 2;
327 if (check_menu_item->active ||
328 check_menu_item->always_show_toggle ||
329 (GTK_WIDGET_STATE (check_menu_item) == GTK_STATE_PRELIGHT))
331 state_type = GTK_WIDGET_STATE (widget);
332 if (check_menu_item->active ||
333 !check_menu_item->always_show_toggle)
334 shadow_type = GTK_SHADOW_IN;
336 shadow_type = GTK_SHADOW_OUT;
338 if (check_menu_item->inconsistent)
339 shadow_type = GTK_SHADOW_ETCHED_IN;
341 if (!GTK_WIDGET_IS_SENSITIVE (widget))
342 state_type = GTK_STATE_INSENSITIVE;
344 gtk_paint_option (widget->style, widget->window,
345 state_type, shadow_type,
346 area, widget, "option",
347 x, y, width, height);