]> Pileus Git - ~andy/gtk/blob - gtk/gtktogglebutton.c
Add optional movement on push to buttons (based on patch from Soeren
[~andy/gtk] / gtk / gtktogglebutton.c
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 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.
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  * Lesser General Public License for more details.
13  *
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.
18  */
19
20 /*
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/. 
25  */
26
27 #include "gtklabel.h"
28 #include "gtkmain.h"
29 #include "gtksignal.h"
30 #include "gtktogglebutton.h"
31 #include "gtkintl.h"
32
33 #define DEFAULT_LEFT_POS  4
34 #define DEFAULT_TOP_POS   4
35 #define DEFAULT_SPACING   7
36
37 enum {
38   TOGGLED,
39   LAST_SIGNAL
40 };
41
42 enum {
43   PROP_0,
44   PROP_ACTIVE,
45   PROP_INCONSISTENT,
46   PROP_DRAW_INDICATOR
47 };
48
49
50 static void gtk_toggle_button_class_init    (GtkToggleButtonClass *klass);
51 static void gtk_toggle_button_init          (GtkToggleButton      *toggle_button);
52 static void gtk_toggle_button_paint         (GtkWidget            *widget,
53                                              GdkRectangle         *area);
54 static void gtk_toggle_button_size_allocate (GtkWidget            *widget,
55                                              GtkAllocation        *allocation);
56 static gint gtk_toggle_button_expose        (GtkWidget            *widget,
57                                              GdkEventExpose       *event);
58 static void gtk_toggle_button_pressed       (GtkButton            *button);
59 static void gtk_toggle_button_released      (GtkButton            *button);
60 static void gtk_toggle_button_clicked       (GtkButton            *button);
61 static void gtk_toggle_button_set_property  (GObject              *object,
62                                              guint                 prop_id,
63                                              const GValue         *value,
64                                              GParamSpec           *pspec);
65 static void gtk_toggle_button_get_property  (GObject              *object,
66                                              guint                 prop_id,
67                                              GValue               *value,
68                                              GParamSpec           *pspec);
69 static void gtk_toggle_button_realize       (GtkWidget            *widget);
70 static void gtk_toggle_button_unrealize     (GtkWidget            *widget);
71 static void gtk_toggle_button_map           (GtkWidget            *widget);
72 static void gtk_toggle_button_unmap         (GtkWidget            *widget);
73 static void gtk_toggle_button_update_state  (GtkButton            *button);
74
75 static guint toggle_button_signals[LAST_SIGNAL] = { 0 };
76 static GtkContainerClass *parent_class = NULL;
77
78 GtkType
79 gtk_toggle_button_get_type (void)
80 {
81   static GtkType toggle_button_type = 0;
82
83   if (!toggle_button_type)
84     {
85       static const GtkTypeInfo toggle_button_info =
86       {
87         "GtkToggleButton",
88         sizeof (GtkToggleButton),
89         sizeof (GtkToggleButtonClass),
90         (GtkClassInitFunc) gtk_toggle_button_class_init,
91         (GtkObjectInitFunc) gtk_toggle_button_init,
92         /* reserved_1 */ NULL,
93         /* reserved_2 */ NULL,
94         (GtkClassInitFunc) NULL,
95       };
96
97       toggle_button_type = gtk_type_unique (GTK_TYPE_BUTTON, &toggle_button_info);
98     }
99
100   return toggle_button_type;
101 }
102
103 static void
104 gtk_toggle_button_class_init (GtkToggleButtonClass *class)
105 {
106   GtkObjectClass *object_class;
107   GObjectClass   *gobject_class;
108   GtkWidgetClass *widget_class;
109   GtkContainerClass *container_class;
110   GtkButtonClass *button_class;
111
112   object_class = (GtkObjectClass*) class;
113   gobject_class = G_OBJECT_CLASS (class);
114   widget_class = (GtkWidgetClass*) class;
115   container_class = (GtkContainerClass*) class;
116   button_class = (GtkButtonClass*) class;
117
118   parent_class = gtk_type_class (GTK_TYPE_BUTTON);
119
120
121   gobject_class->set_property = gtk_toggle_button_set_property;
122   gobject_class->get_property = gtk_toggle_button_get_property;
123
124   widget_class->size_allocate = gtk_toggle_button_size_allocate;
125   widget_class->expose_event = gtk_toggle_button_expose;
126   widget_class->realize = gtk_toggle_button_realize;
127   widget_class->unrealize = gtk_toggle_button_unrealize;
128   widget_class->map = gtk_toggle_button_map;
129   widget_class->unmap = gtk_toggle_button_unmap;
130
131   button_class->pressed = gtk_toggle_button_pressed;
132   button_class->released = gtk_toggle_button_released;
133   button_class->clicked = gtk_toggle_button_clicked;
134   button_class->enter = gtk_toggle_button_update_state;
135   button_class->leave = gtk_toggle_button_update_state;
136
137   class->toggled = NULL;
138
139   g_object_class_install_property (gobject_class,
140                                    PROP_ACTIVE,
141                                    g_param_spec_boolean ("active",
142                                                          _("Active"),
143                                                          _("If the toggle button should be pressed in or not"),
144                                                          FALSE,
145                                                          G_PARAM_READWRITE));
146
147   g_object_class_install_property (gobject_class,
148                                    PROP_INCONSISTENT,
149                                    g_param_spec_boolean ("inconsistent",
150                                                          _("Inconsistent"),
151                                                          _("If the toggle button is in an \"in between\" state."),
152                                                          FALSE,
153                                                          G_PARAM_READWRITE));
154
155   g_object_class_install_property (gobject_class,
156                                    PROP_DRAW_INDICATOR,
157                                    g_param_spec_boolean ("draw_indicator",
158                                                          _("Draw Indicator"),
159                                                          _("If the toggle part of the button is displayed"),
160                                                          FALSE,
161                                                          G_PARAM_READWRITE));
162
163   toggle_button_signals[TOGGLED] =
164     gtk_signal_new ("toggled",
165                     GTK_RUN_FIRST,
166                     GTK_CLASS_TYPE (object_class),
167                     GTK_SIGNAL_OFFSET (GtkToggleButtonClass, toggled),
168                     gtk_marshal_VOID__VOID,
169                     GTK_TYPE_NONE, 0);
170 }
171
172 static void
173 gtk_toggle_button_init (GtkToggleButton *toggle_button)
174 {
175   toggle_button->active = FALSE;
176   toggle_button->draw_indicator = FALSE;
177   GTK_WIDGET_UNSET_FLAGS (toggle_button, GTK_NO_WINDOW);
178 }
179
180
181 GtkWidget*
182 gtk_toggle_button_new (void)
183 {
184   return GTK_WIDGET (gtk_type_new (gtk_toggle_button_get_type ()));
185 }
186
187 GtkWidget*
188 gtk_toggle_button_new_with_label (const gchar *label)
189 {
190   GtkWidget *toggle_button;
191   GtkWidget *label_widget;
192
193   toggle_button = gtk_toggle_button_new ();
194   label_widget = gtk_label_new (label);
195   gtk_misc_set_alignment (GTK_MISC (label_widget), 0.5, 0.5);
196
197   gtk_container_add (GTK_CONTAINER (toggle_button), label_widget);
198   gtk_widget_show (label_widget);
199
200   return toggle_button;
201 }
202
203 /**
204  * gtk_toggle_button_new_with_mnemonic:
205  * @label: the text of the button, with an underscore in front of the
206  *         mnemonic character
207  * @returns: a new #GtkToggleButton
208  *
209  * Creates a new #GtkToggleButton containing a label. The label
210  * will be created using gtk_label_new_with_mnemonic(), so underscores
211  * in @label indicate the mnemonic for the button.
212  **/
213 GtkWidget*
214 gtk_toggle_button_new_with_mnemonic (const gchar *label)
215 {
216   GtkWidget *toggle_button;
217   GtkWidget *label_widget;
218
219   toggle_button = gtk_toggle_button_new ();
220   label_widget = gtk_label_new_with_mnemonic (label);
221   gtk_misc_set_alignment (GTK_MISC (label_widget), 0.5, 0.5);
222
223   gtk_container_add (GTK_CONTAINER (toggle_button), label_widget);
224   gtk_widget_show (label_widget);
225
226   return toggle_button;
227 }
228
229 static void
230 gtk_toggle_button_set_property (GObject      *object,
231                                 guint         prop_id,
232                                 const GValue *value,
233                                 GParamSpec   *pspec)
234 {
235   GtkToggleButton *tb;
236
237   tb = GTK_TOGGLE_BUTTON (object);
238
239   switch (prop_id)
240     {
241     case PROP_ACTIVE:
242       gtk_toggle_button_set_active (tb, g_value_get_boolean (value));
243       break;
244     case PROP_INCONSISTENT:
245       gtk_toggle_button_set_inconsistent (tb, g_value_get_boolean (value));
246       break;
247     case PROP_DRAW_INDICATOR:
248       gtk_toggle_button_set_mode (tb, g_value_get_boolean (value));
249       break;
250     default:
251       break;
252     }
253 }
254
255 static void
256 gtk_toggle_button_get_property (GObject      *object,
257                                 guint         prop_id,
258                                 GValue       *value,
259                                 GParamSpec   *pspec)
260 {
261   GtkToggleButton *tb;
262
263   tb = GTK_TOGGLE_BUTTON (object);
264
265   switch (prop_id)
266     {
267     case PROP_ACTIVE:
268       g_value_set_boolean (value, tb->active);
269       break;
270     case PROP_INCONSISTENT:
271       g_value_set_boolean (value, tb->inconsistent);
272       break;
273     case PROP_DRAW_INDICATOR:
274       g_value_set_boolean (value, tb->draw_indicator);
275       break;
276     default:
277       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
278       break;
279     }
280 }
281
282 void
283 gtk_toggle_button_set_mode (GtkToggleButton *toggle_button,
284                             gboolean         draw_indicator)
285 {
286   GtkWidget *widget;
287
288   g_return_if_fail (GTK_IS_TOGGLE_BUTTON (toggle_button));
289
290   widget = GTK_WIDGET (toggle_button);
291
292   draw_indicator = draw_indicator ? TRUE : FALSE;
293
294   if (toggle_button->draw_indicator != draw_indicator)
295     {
296       if (GTK_WIDGET_REALIZED (toggle_button))
297         {
298           gboolean visible = GTK_WIDGET_VISIBLE (toggle_button);
299
300           if (visible)
301             gtk_widget_hide (widget);
302
303           gtk_widget_unrealize (widget);
304           toggle_button->draw_indicator = draw_indicator;
305
306           if (toggle_button->draw_indicator)
307             GTK_WIDGET_SET_FLAGS (toggle_button, GTK_NO_WINDOW);
308           else
309             GTK_WIDGET_UNSET_FLAGS (toggle_button, GTK_NO_WINDOW);
310           
311           gtk_widget_realize (widget);
312
313           if (visible)
314             gtk_widget_show (widget);
315         }
316       else
317         {
318           toggle_button->draw_indicator = draw_indicator;
319
320           if (toggle_button->draw_indicator)
321             GTK_WIDGET_SET_FLAGS (toggle_button, GTK_NO_WINDOW);
322           else
323             GTK_WIDGET_UNSET_FLAGS (toggle_button, GTK_NO_WINDOW);
324         }
325
326       if (GTK_WIDGET_VISIBLE (toggle_button))
327         gtk_widget_queue_resize (GTK_WIDGET (toggle_button));
328
329       g_object_notify (G_OBJECT (toggle_button), "draw_indicator");
330     }
331 }
332
333 /**
334  * gtk_toggle_button_get_mode:
335  * @toggle_button: a #GtkToggleButton
336  *
337  * Retrieves whether the button is displayed as a separate indicator
338  * and label. See gtk_toggle_button_set_mode().
339  *
340  * Return value: %TRUE if the togglebutton is drawn as a separate indicator
341  *   and label.
342  **/
343 gboolean
344 gtk_toggle_button_get_mode (GtkToggleButton *toggle_button)
345 {
346   g_return_val_if_fail (GTK_IS_TOGGLE_BUTTON (toggle_button), FALSE);
347
348   return toggle_button->draw_indicator;
349 }
350
351 void
352 gtk_toggle_button_set_active (GtkToggleButton *toggle_button,
353                               gboolean         is_active)
354 {
355   g_return_if_fail (GTK_IS_TOGGLE_BUTTON (toggle_button));
356
357   is_active = is_active != FALSE;
358
359   if (toggle_button->active != is_active)
360     gtk_button_clicked (GTK_BUTTON (toggle_button));
361 }
362
363
364 gboolean
365 gtk_toggle_button_get_active (GtkToggleButton *toggle_button)
366 {
367   g_return_val_if_fail (GTK_IS_TOGGLE_BUTTON (toggle_button), FALSE);
368
369   return (toggle_button->active) ? TRUE : FALSE;
370 }
371
372
373 void
374 gtk_toggle_button_toggled (GtkToggleButton *toggle_button)
375 {
376   g_return_if_fail (GTK_IS_TOGGLE_BUTTON (toggle_button));
377
378   gtk_signal_emit (GTK_OBJECT (toggle_button), toggle_button_signals[TOGGLED]);
379 }
380
381 /**
382  * gtk_toggle_button_set_inconsistent:
383  * @toggle_button: a #GtkToggleButton
384  * @setting: %TRUE if state is inconsistent
385  *
386  * If the user has selected a range of elements (such as some text or
387  * spreadsheet cells) that are affected by a toggle button, and the
388  * current values in that range are inconsistent, you may want to
389  * display the toggle in an "in between" state. This function turns on
390  * "in between" display.  Normally you would turn off the inconsistent
391  * state again if the user toggles the toggle button. This has to be
392  * done manually, gtk_toggle_button_set_inconsistent() only affects
393  * visual appearance, it doesn't affect the semantics of the button.
394  * 
395  **/
396 void
397 gtk_toggle_button_set_inconsistent (GtkToggleButton *toggle_button,
398                                     gboolean         setting)
399 {
400   g_return_if_fail (GTK_IS_TOGGLE_BUTTON (toggle_button));
401   
402   setting = setting != FALSE;
403
404   if (setting != toggle_button->inconsistent)
405     {
406       toggle_button->inconsistent = setting;
407       
408       gtk_toggle_button_update_state (GTK_BUTTON (toggle_button));
409       gtk_widget_queue_draw (GTK_WIDGET (toggle_button));
410
411       g_object_notify (G_OBJECT (toggle_button), "inconsistent");      
412     }
413 }
414
415 /**
416  * gtk_toggle_button_get_inconsistent:
417  * @toggle_button: a #GtkToggleButton
418  * 
419  * Gets the value set by gtk_toggle_button_set_inconsistent().
420  * 
421  * Return value: %TRUE if the button is displayed as inconsistent, %FALSE otherwise
422  **/
423 gboolean
424 gtk_toggle_button_get_inconsistent (GtkToggleButton *toggle_button)
425 {
426   g_return_val_if_fail (GTK_IS_TOGGLE_BUTTON (toggle_button), FALSE);
427
428   return toggle_button->inconsistent;
429 }
430
431 static void
432 gtk_toggle_button_paint (GtkWidget    *widget,
433                          GdkRectangle *area)
434 {
435   GtkButton *button;
436   GtkToggleButton *toggle_button;
437   GtkShadowType shadow_type;
438   GtkStateType state_type;
439   gint width, height;
440   gboolean interior_focus;
441   gint x, y;
442
443   button = GTK_BUTTON (widget);
444   toggle_button = GTK_TOGGLE_BUTTON (widget);
445
446   if (GTK_WIDGET_DRAWABLE (widget))
447     {
448       gtk_widget_style_get (widget, "interior_focus", &interior_focus, NULL);
449       
450       x = 0;
451       y = 0;
452       width = widget->allocation.width - GTK_CONTAINER (widget)->border_width * 2;
453       height = widget->allocation.height - GTK_CONTAINER (widget)->border_width * 2;
454
455       gdk_window_set_back_pixmap (widget->window, NULL, TRUE);
456       gdk_window_clear_area (widget->window, area->x, area->y, area->width, area->height);
457
458       if (GTK_WIDGET_HAS_DEFAULT (widget) &&
459           GTK_BUTTON (widget)->relief == GTK_RELIEF_NORMAL)
460         {
461           gtk_paint_box (widget->style, widget->window,
462                          GTK_STATE_NORMAL, GTK_SHADOW_IN,
463                          area, widget, "togglebuttondefault",
464                          x, y, width, height);
465         }
466
467       if (GTK_WIDGET_CAN_DEFAULT (widget))
468         {
469           x += widget->style->xthickness;
470           y += widget->style->ythickness;
471           width -= 2 * x + DEFAULT_SPACING;
472           height -= 2 * y + DEFAULT_SPACING;
473           x += DEFAULT_LEFT_POS;
474           y += DEFAULT_TOP_POS;
475         }
476
477       if (GTK_WIDGET_HAS_FOCUS (widget) && !interior_focus)
478         {
479           x += 1;
480           y += 1;
481           width -= 2;
482           height -= 2;
483         }
484
485       state_type = GTK_WIDGET_STATE (widget);
486       
487       if (toggle_button->inconsistent)
488         {
489           if (state_type == GTK_STATE_ACTIVE)
490             state_type = GTK_STATE_NORMAL;
491           shadow_type = GTK_SHADOW_ETCHED_IN;
492         }
493       else
494         shadow_type = button->depressed ? GTK_SHADOW_IN : GTK_SHADOW_OUT;
495
496       if (button->relief != GTK_RELIEF_NONE ||
497           (GTK_WIDGET_STATE(widget) != GTK_STATE_NORMAL &&
498            GTK_WIDGET_STATE(widget) != GTK_STATE_INSENSITIVE))
499         gtk_paint_box (widget->style, widget->window,
500                        state_type,
501                        shadow_type, area, widget, "togglebutton",
502                        x, y, width, height);
503       
504       if (GTK_WIDGET_HAS_FOCUS (widget))
505         {
506           if (interior_focus)
507             {
508               x += widget->style->xthickness + 1;
509               y += widget->style->xthickness + 1;
510               width -= 2 * (widget->style->xthickness + 1);
511               height -= 2 * (widget->style->ythickness + 1);
512             }
513           else
514             {
515               x -= 1;
516               y -= 1;
517               width += 2;
518               height += 2;
519             }
520
521           gtk_paint_focus (widget->style, widget->window,
522                            area, widget, "togglebutton",
523                            x, y, width - 1, height - 1);
524         }
525     }
526 }
527
528 static void
529 gtk_toggle_button_size_allocate (GtkWidget     *widget,
530                                  GtkAllocation *allocation)
531 {
532   if (!GTK_WIDGET_NO_WINDOW (widget) &&
533       GTK_WIDGET_CLASS (parent_class)->size_allocate)
534     GTK_WIDGET_CLASS (parent_class)->size_allocate (widget, allocation);
535 }
536
537 static gint
538 gtk_toggle_button_expose (GtkWidget      *widget,
539                           GdkEventExpose *event)
540 {
541   if (GTK_WIDGET_DRAWABLE (widget))
542     {
543       GtkWidget *child = GTK_BIN (widget)->child;
544
545       gtk_toggle_button_paint (widget, &event->area);
546
547       if (child)
548         gtk_container_propagate_expose (GTK_CONTAINER (widget), child, event);
549     }
550   
551   return TRUE;
552 }
553
554 static void
555 gtk_toggle_button_pressed (GtkButton *button)
556 {
557   button->button_down = TRUE;
558
559   gtk_toggle_button_update_state (button);
560 }
561
562 static void
563 gtk_toggle_button_released (GtkButton *button)
564 {
565   if (button->button_down)
566     {
567       button->button_down = FALSE;
568
569       if (button->in_button)
570         gtk_button_clicked (button);
571
572       gtk_toggle_button_update_state (button);
573     }
574 }
575
576 static void
577 gtk_toggle_button_clicked (GtkButton *button)
578 {
579   GtkToggleButton *toggle_button = GTK_TOGGLE_BUTTON (button);
580   toggle_button->active = !toggle_button->active;
581
582   gtk_toggle_button_toggled (toggle_button);
583
584   gtk_toggle_button_update_state (button);
585
586   g_object_notify (G_OBJECT (toggle_button), "active");
587 }
588
589 static void
590 gtk_toggle_button_realize (GtkWidget *widget)
591 {
592   GtkToggleButton *toggle_button;
593   GdkWindowAttr attributes;
594   gint attributes_mask;
595   gint border_width;
596   
597   g_return_if_fail (GTK_IS_TOGGLE_BUTTON (widget));
598   
599   toggle_button = GTK_TOGGLE_BUTTON (widget);
600   GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
601   
602   border_width = GTK_CONTAINER (widget)->border_width;
603   
604   attributes.window_type = GDK_WINDOW_CHILD;
605   attributes.x = widget->allocation.x + border_width;
606   attributes.y = widget->allocation.y + border_width;
607   attributes.width = widget->allocation.width - border_width * 2;
608   attributes.height = widget->allocation.height - border_width * 2;
609   attributes.event_mask = gtk_widget_get_events (widget);
610   attributes.event_mask |= (GDK_EXPOSURE_MASK |
611                             GDK_BUTTON_PRESS_MASK |
612                             GDK_BUTTON_RELEASE_MASK |
613                             GDK_ENTER_NOTIFY_MASK |
614                             GDK_LEAVE_NOTIFY_MASK);
615
616   if (GTK_WIDGET_NO_WINDOW (widget))
617     {
618       attributes.wclass = GDK_INPUT_ONLY;
619       attributes_mask = GDK_WA_X | GDK_WA_Y;
620
621       widget->window = gtk_widget_get_parent_window (widget);
622       gdk_window_ref (widget->window);
623       
624       toggle_button->event_window = gdk_window_new (gtk_widget_get_parent_window (widget),
625                                                     &attributes, attributes_mask);
626       gdk_window_set_user_data (toggle_button->event_window, toggle_button);
627     }
628   else
629     {
630       attributes.wclass = GDK_INPUT_OUTPUT;
631       attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
632       attributes.visual = gtk_widget_get_visual (widget);
633       attributes.colormap = gtk_widget_get_colormap (widget);
634       widget->window = gdk_window_new (gtk_widget_get_parent_window (widget),
635                                        &attributes, attributes_mask);
636       gdk_window_set_user_data (widget->window, toggle_button);
637     }
638
639   widget->style = gtk_style_attach (widget->style, widget->window);
640
641   if (!GTK_WIDGET_NO_WINDOW (widget))
642     gtk_style_set_background (widget->style, widget->window, GTK_STATE_NORMAL);
643 }
644   
645 static void
646 gtk_toggle_button_unrealize (GtkWidget *widget)
647 {
648   GtkToggleButton *toggle_button;
649   
650   g_return_if_fail (GTK_IS_TOGGLE_BUTTON (widget));
651
652   toggle_button = GTK_TOGGLE_BUTTON (widget);
653   
654   if (GTK_WIDGET_NO_WINDOW (widget))
655     {
656       gdk_window_set_user_data (toggle_button->event_window, NULL);
657       gdk_window_destroy (toggle_button->event_window);
658       toggle_button->event_window = NULL;
659     }
660
661   if (GTK_WIDGET_CLASS (parent_class)->unrealize)
662     (* GTK_WIDGET_CLASS (parent_class)->unrealize) (widget);
663 }
664
665 static void
666 gtk_toggle_button_map (GtkWidget *widget)
667 {
668   g_return_if_fail (GTK_IS_TOGGLE_BUTTON (widget));
669
670   if (GTK_WIDGET_NO_WINDOW (widget))
671     gdk_window_show (GTK_TOGGLE_BUTTON (widget)->event_window);
672
673   GTK_WIDGET_CLASS (parent_class)->map (widget);
674 }
675
676 static void
677 gtk_toggle_button_unmap (GtkWidget *widget)
678 {
679   g_return_if_fail (GTK_IS_TOGGLE_BUTTON (widget));
680
681   if (GTK_WIDGET_NO_WINDOW (widget))
682     gdk_window_hide (GTK_TOGGLE_BUTTON (widget)->event_window);
683
684   GTK_WIDGET_CLASS (parent_class)->unmap (widget);
685 }
686
687 static void
688 gtk_toggle_button_update_state (GtkButton *button)
689 {
690   GtkToggleButton *toggle_button = GTK_TOGGLE_BUTTON (button);
691   gboolean depressed;
692   GtkStateType new_state;
693
694   if (toggle_button->inconsistent)
695     depressed = FALSE;
696   else if (button->in_button && button->button_down)
697     depressed = !toggle_button->active;
698   else
699     depressed = toggle_button->active;
700       
701   if (!button->button_down && button->in_button)
702     new_state = GTK_STATE_PRELIGHT;
703   else
704     new_state = depressed ? GTK_STATE_ACTIVE: GTK_STATE_NORMAL;
705
706   _gtk_button_set_depressed (button, depressed); 
707   gtk_widget_set_state (GTK_WIDGET (toggle_button), new_state);
708 }