source: trunk/third/gtk/gtk/gtkradiomenuitem.c @ 14482

Revision 14482, 8.2 KB checked in by ghudson, 24 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r14481, which included commits to RCS files with non-trunk default branches.
Line 
1/* GTK - The GIMP Toolkit
2 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library 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.
8 *
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 * Library General Public License for more details.
13 *
14 * You should have received a copy of the GNU Library 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.
18 */
19
20/*
21 * Modified by the GTK+ Team and others 1997-1999.  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/.
25 */
26
27#include "gtkaccellabel.h"
28#include "gtkradiomenuitem.h"
29
30
31static void gtk_radio_menu_item_class_init     (GtkRadioMenuItemClass *klass);
32static void gtk_radio_menu_item_init           (GtkRadioMenuItem      *radio_menu_item);
33static void gtk_radio_menu_item_destroy        (GtkObject             *object);
34static void gtk_radio_menu_item_activate       (GtkMenuItem           *menu_item);
35static void gtk_radio_menu_item_draw_indicator (GtkCheckMenuItem      *check_menu_item,
36                                                GdkRectangle          *area);
37
38static GtkCheckMenuItemClass *parent_class = NULL;
39
40GtkType
41gtk_radio_menu_item_get_type (void)
42{
43  static GtkType radio_menu_item_type = 0;
44
45  if (!radio_menu_item_type)
46    {
47      static const GtkTypeInfo radio_menu_item_info =
48      {
49        "GtkRadioMenuItem",
50        sizeof (GtkRadioMenuItem),
51        sizeof (GtkRadioMenuItemClass),
52        (GtkClassInitFunc) gtk_radio_menu_item_class_init,
53        (GtkObjectInitFunc) gtk_radio_menu_item_init,
54        /* reserved_1 */ NULL,
55        /* reserved_2 */ NULL,
56        (GtkClassInitFunc) NULL,
57      };
58
59      radio_menu_item_type = gtk_type_unique (gtk_check_menu_item_get_type (), &radio_menu_item_info);
60    }
61
62  return radio_menu_item_type;
63}
64
65GtkWidget*
66gtk_radio_menu_item_new (GSList *group)
67{
68  GtkRadioMenuItem *radio_menu_item;
69
70  radio_menu_item = gtk_type_new (gtk_radio_menu_item_get_type ());
71
72  gtk_radio_menu_item_set_group (radio_menu_item, group);
73
74  return GTK_WIDGET (radio_menu_item);
75}
76
77void
78gtk_radio_menu_item_set_group (GtkRadioMenuItem *radio_menu_item,
79                               GSList           *group)
80{
81  g_return_if_fail (radio_menu_item != NULL);
82  g_return_if_fail (GTK_IS_RADIO_MENU_ITEM (radio_menu_item));
83  g_return_if_fail (!g_slist_find (group, radio_menu_item));
84 
85  if (radio_menu_item->group)
86    {
87      GSList *slist;
88     
89      radio_menu_item->group = g_slist_remove (radio_menu_item->group, radio_menu_item);
90     
91      for (slist = radio_menu_item->group; slist; slist = slist->next)
92        {
93          GtkRadioMenuItem *tmp_item;
94         
95          tmp_item = slist->data;
96         
97          tmp_item->group = radio_menu_item->group;
98        }
99    }
100 
101  radio_menu_item->group = g_slist_prepend (group, radio_menu_item);
102 
103  if (group)
104    {
105      GSList *slist;
106     
107      for (slist = group; slist; slist = slist->next)
108        {
109          GtkRadioMenuItem *tmp_item;
110         
111          tmp_item = slist->data;
112         
113          tmp_item->group = radio_menu_item->group;
114        }
115    }
116  else
117    {
118      GTK_CHECK_MENU_ITEM (radio_menu_item)->active = TRUE;
119      /* gtk_widget_set_state (GTK_WIDGET (radio_menu_item), GTK_STATE_ACTIVE);
120       */
121    }
122}
123
124GtkWidget*
125gtk_radio_menu_item_new_with_label (GSList *group,
126                                    const gchar *label)
127{
128  GtkWidget *radio_menu_item;
129  GtkWidget *accel_label;
130
131  radio_menu_item = gtk_radio_menu_item_new (group);
132  accel_label = gtk_accel_label_new (label);
133  gtk_misc_set_alignment (GTK_MISC (accel_label), 0.0, 0.5);
134  gtk_container_add (GTK_CONTAINER (radio_menu_item), accel_label);
135  gtk_accel_label_set_accel_widget (GTK_ACCEL_LABEL (accel_label), radio_menu_item);
136  gtk_widget_show (accel_label);
137
138  return radio_menu_item;
139}
140
141GSList*
142gtk_radio_menu_item_group (GtkRadioMenuItem *radio_menu_item)
143{
144  g_return_val_if_fail (radio_menu_item != NULL, NULL);
145  g_return_val_if_fail (GTK_IS_RADIO_MENU_ITEM (radio_menu_item), NULL);
146
147  return radio_menu_item->group;
148}
149
150
151static void
152gtk_radio_menu_item_class_init (GtkRadioMenuItemClass *klass)
153{
154  GtkObjectClass *object_class;
155  GtkMenuItemClass *menu_item_class;
156  GtkCheckMenuItemClass *check_menu_item_class;
157
158  object_class = (GtkObjectClass*) klass;
159  menu_item_class = (GtkMenuItemClass*) klass;
160  check_menu_item_class = (GtkCheckMenuItemClass*) klass;
161
162  parent_class = gtk_type_class (gtk_check_menu_item_get_type ());
163
164  object_class->destroy = gtk_radio_menu_item_destroy;
165
166  menu_item_class->activate = gtk_radio_menu_item_activate;
167
168  check_menu_item_class->draw_indicator = gtk_radio_menu_item_draw_indicator;
169}
170
171static void
172gtk_radio_menu_item_init (GtkRadioMenuItem *radio_menu_item)
173{
174  radio_menu_item->group = g_slist_prepend (NULL, radio_menu_item);
175}
176
177static void
178gtk_radio_menu_item_destroy (GtkObject *object)
179{
180  GtkRadioMenuItem *radio_menu_item;
181  GtkRadioMenuItem *tmp_menu_item;
182  GSList *tmp_list;
183
184  g_return_if_fail (object != NULL);
185  g_return_if_fail (GTK_IS_RADIO_MENU_ITEM (object));
186
187  radio_menu_item = GTK_RADIO_MENU_ITEM (object);
188
189  radio_menu_item->group = g_slist_remove (radio_menu_item->group,
190                                           radio_menu_item);
191  tmp_list = radio_menu_item->group;
192
193  while (tmp_list)
194    {
195      tmp_menu_item = tmp_list->data;
196      tmp_list = tmp_list->next;
197
198      tmp_menu_item->group = radio_menu_item->group;
199    }
200
201  if (GTK_OBJECT_CLASS (parent_class)->destroy)
202    (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
203}
204
205static void
206gtk_radio_menu_item_activate (GtkMenuItem *menu_item)
207{
208  GtkRadioMenuItem *radio_menu_item;
209  GtkCheckMenuItem *check_menu_item;
210  GtkCheckMenuItem *tmp_menu_item;
211  GSList *tmp_list;
212  gint toggled;
213
214  g_return_if_fail (menu_item != NULL);
215  g_return_if_fail (GTK_IS_RADIO_MENU_ITEM (menu_item));
216
217  radio_menu_item = GTK_RADIO_MENU_ITEM (menu_item);
218  check_menu_item = GTK_CHECK_MENU_ITEM (menu_item);
219  toggled = FALSE;
220
221  if (check_menu_item->active)
222    {
223      tmp_menu_item = NULL;
224      tmp_list = radio_menu_item->group;
225
226      while (tmp_list)
227        {
228          tmp_menu_item = tmp_list->data;
229          tmp_list = tmp_list->next;
230
231          if (tmp_menu_item->active && (tmp_menu_item != check_menu_item))
232            break;
233
234          tmp_menu_item = NULL;
235        }
236
237      if (tmp_menu_item)
238        {
239          toggled = TRUE;
240          check_menu_item->active = !check_menu_item->active;
241        }
242    }
243  else
244    {
245      toggled = TRUE;
246      check_menu_item->active = !check_menu_item->active;
247
248      tmp_list = radio_menu_item->group;
249      while (tmp_list)
250        {
251          tmp_menu_item = tmp_list->data;
252          tmp_list = tmp_list->next;
253
254          if (tmp_menu_item->active && (tmp_menu_item != check_menu_item))
255            {
256              gtk_menu_item_activate (GTK_MENU_ITEM (tmp_menu_item));
257              break;
258            }
259        }
260    }
261
262  if (toggled)
263    gtk_check_menu_item_toggled (check_menu_item);
264  gtk_widget_queue_draw (GTK_WIDGET (radio_menu_item));
265}
266
267static void
268gtk_radio_menu_item_draw_indicator (GtkCheckMenuItem *check_menu_item,
269                                    GdkRectangle     *area)
270{
271  GtkWidget *widget;
272  GtkStateType state_type;
273  GtkShadowType shadow_type;
274  gint width, height;
275  gint x, y;
276
277  g_return_if_fail (check_menu_item != NULL);
278  g_return_if_fail (GTK_IS_RADIO_MENU_ITEM (check_menu_item));
279
280  if (GTK_WIDGET_DRAWABLE (check_menu_item))
281    {
282      widget = GTK_WIDGET (check_menu_item);
283
284      width = 8;
285      height = 8;
286      x = (GTK_CONTAINER (check_menu_item)->border_width +
287           widget->style->klass->xthickness + 2);
288      y = (widget->allocation.height - height) / 2;
289
290      if (check_menu_item->active ||
291          check_menu_item->always_show_toggle ||
292          (GTK_WIDGET_STATE (check_menu_item) == GTK_STATE_PRELIGHT))
293        {
294          state_type = GTK_WIDGET_STATE (widget);
295          if (check_menu_item->active ||
296              !check_menu_item->always_show_toggle)
297            shadow_type = GTK_SHADOW_IN;
298          else
299            shadow_type = GTK_SHADOW_OUT;
300
301          gtk_paint_option (widget->style, widget->window,
302                            state_type, shadow_type,
303                            area, widget, "option",
304                            x, y, width, height);
305        }
306    }
307}
308
Note: See TracBrowser for help on using the repository browser.