]> Pileus Git - ~andy/gtk/blob - gtk/gtklistitem.c
don't autoselect focus_row in case of GTK_SELECTION_EXTENDED
[~andy/gtk] / gtk / gtklistitem.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 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 #include "gtkbindings.h"
21 #include "gtklabel.h"
22 #include "gtklistitem.h"
23 #include "gtklist.h"
24 #include "gtksignal.h"
25 #include <gdk/gdkkeysyms.h>
26
27
28 enum
29 {
30   TOGGLE_FOCUS_ROW,
31   SELECT_ALL,
32   UNSELECT_ALL,
33   UNDO_SELECTION,
34   START_SELECTION,
35   END_SELECTION,
36   TOGGLE_ADD_MODE,
37   EXTEND_SELECTION,
38   SCROLL_VERTICAL,
39   SCROLL_HORIZONTAL,
40   LAST_SIGNAL
41 };
42
43 static void gtk_list_item_class_init        (GtkListItemClass *klass);
44 static void gtk_list_item_init              (GtkListItem      *list_item);
45 static void gtk_list_item_realize           (GtkWidget        *widget);
46 static void gtk_list_item_size_request      (GtkWidget        *widget,
47                                              GtkRequisition   *requisition);
48 static void gtk_list_item_size_allocate     (GtkWidget        *widget,
49                                              GtkAllocation    *allocation);
50 static void gtk_list_item_style_set         (GtkWidget        *widget,
51                                              GtkStyle         *previous_style);
52 static void gtk_list_item_draw              (GtkWidget        *widget,
53                                              GdkRectangle     *area);
54 static void gtk_list_item_draw_focus        (GtkWidget        *widget);
55 static gint gtk_list_item_button_press      (GtkWidget        *widget,
56                                              GdkEventButton   *event);
57 static gint gtk_list_item_expose            (GtkWidget        *widget,
58                                              GdkEventExpose   *event);
59 static gint gtk_list_item_focus_in          (GtkWidget        *widget,
60                                              GdkEventFocus    *event);
61 static gint gtk_list_item_focus_out         (GtkWidget        *widget,
62                                              GdkEventFocus    *event);
63 static void gtk_real_list_item_select       (GtkItem          *item);
64 static void gtk_real_list_item_deselect     (GtkItem          *item);
65 static void gtk_real_list_item_toggle       (GtkItem          *item);
66
67
68 static GtkItemClass *parent_class = NULL;
69 static guint list_item_signals[LAST_SIGNAL] = {0};
70
71
72 GtkType
73 gtk_list_item_get_type (void)
74 {
75   static GtkType list_item_type = 0;
76
77   if (!list_item_type)
78     {
79       static const GtkTypeInfo list_item_info =
80       {
81         "GtkListItem",
82         sizeof (GtkListItem),
83         sizeof (GtkListItemClass),
84         (GtkClassInitFunc) gtk_list_item_class_init,
85         (GtkObjectInitFunc) gtk_list_item_init,
86         /* reserved_1 */ NULL,
87         /* reserved_2 */ NULL,
88         (GtkClassInitFunc) NULL,
89       };
90
91       list_item_type = gtk_type_unique (gtk_item_get_type (), &list_item_info);
92     }
93
94   return list_item_type;
95 }
96
97 static void
98 gtk_list_item_class_init (GtkListItemClass *class)
99 {
100   GtkObjectClass *object_class;
101   GtkWidgetClass *widget_class;
102   GtkItemClass *item_class;
103   GtkBindingSet *binding_set;
104
105   object_class = (GtkObjectClass*) class;
106   widget_class = (GtkWidgetClass*) class;
107   item_class = (GtkItemClass*) class;
108
109   parent_class = gtk_type_class (gtk_item_get_type ());
110
111   list_item_signals[TOGGLE_FOCUS_ROW] =
112     gtk_signal_new ("toggle_focus_row",
113                     GTK_RUN_LAST | GTK_RUN_ACTION,
114                     object_class->type,
115                     GTK_SIGNAL_OFFSET (GtkListItemClass, toggle_focus_row),
116                     gtk_marshal_NONE__NONE,
117                     GTK_TYPE_NONE, 0);
118   list_item_signals[SELECT_ALL] =
119     gtk_signal_new ("select_all",
120                     GTK_RUN_LAST | GTK_RUN_ACTION,
121                     object_class->type,
122                     GTK_SIGNAL_OFFSET (GtkListItemClass, select_all),
123                     gtk_marshal_NONE__NONE,
124                     GTK_TYPE_NONE, 0);
125   list_item_signals[UNSELECT_ALL] =
126     gtk_signal_new ("unselect_all",
127                     GTK_RUN_LAST | GTK_RUN_ACTION,
128                     object_class->type,
129                     GTK_SIGNAL_OFFSET (GtkListItemClass, unselect_all),
130                     gtk_marshal_NONE__NONE,
131                     GTK_TYPE_NONE, 0);
132   list_item_signals[UNDO_SELECTION] =
133     gtk_signal_new ("undo_selection",
134                     GTK_RUN_LAST | GTK_RUN_ACTION,
135                     object_class->type,
136                     GTK_SIGNAL_OFFSET (GtkListItemClass, undo_selection),
137                     gtk_marshal_NONE__NONE,
138                     GTK_TYPE_NONE, 0);
139   list_item_signals[START_SELECTION] =
140     gtk_signal_new ("start_selection",
141                     GTK_RUN_LAST | GTK_RUN_ACTION,
142                     object_class->type,
143                     GTK_SIGNAL_OFFSET (GtkListItemClass, start_selection),
144                     gtk_marshal_NONE__NONE,
145                     GTK_TYPE_NONE, 0);
146   list_item_signals[END_SELECTION] =
147     gtk_signal_new ("end_selection",
148                     GTK_RUN_LAST | GTK_RUN_ACTION,
149                     object_class->type,
150                     GTK_SIGNAL_OFFSET (GtkListItemClass, end_selection),
151                     gtk_marshal_NONE__NONE,
152                     GTK_TYPE_NONE, 0);
153   list_item_signals[TOGGLE_ADD_MODE] =
154     gtk_signal_new ("toggle_add_mode",
155                     GTK_RUN_LAST | GTK_RUN_ACTION,
156                     object_class->type,
157                     GTK_SIGNAL_OFFSET (GtkListItemClass, toggle_add_mode),
158                     gtk_marshal_NONE__NONE,
159                     GTK_TYPE_NONE, 0);
160   list_item_signals[EXTEND_SELECTION] =
161     gtk_signal_new ("extend_selection",
162                     GTK_RUN_LAST | GTK_RUN_ACTION,
163                     object_class->type,
164                     GTK_SIGNAL_OFFSET (GtkListItemClass, extend_selection),
165                     gtk_marshal_NONE__ENUM_FLOAT_BOOL,
166                     GTK_TYPE_NONE, 3,
167                     GTK_TYPE_ENUM, GTK_TYPE_FLOAT, GTK_TYPE_BOOL);
168   list_item_signals[SCROLL_VERTICAL] =
169     gtk_signal_new ("scroll_vertical",
170                     GTK_RUN_LAST | GTK_RUN_ACTION,
171                     object_class->type,
172                     GTK_SIGNAL_OFFSET (GtkListItemClass, scroll_vertical),
173                     gtk_marshal_NONE__ENUM_FLOAT,
174                     GTK_TYPE_NONE, 2, GTK_TYPE_ENUM, GTK_TYPE_FLOAT);
175   list_item_signals[SCROLL_HORIZONTAL] =
176     gtk_signal_new ("scroll_horizontal",
177                     GTK_RUN_LAST | GTK_RUN_ACTION,
178                     object_class->type,
179                     GTK_SIGNAL_OFFSET (GtkListItemClass, scroll_horizontal),
180                     gtk_marshal_NONE__ENUM_FLOAT,
181                     GTK_TYPE_NONE, 2, GTK_TYPE_ENUM, GTK_TYPE_FLOAT);
182
183   gtk_object_class_add_signals (object_class, list_item_signals, LAST_SIGNAL);
184
185   widget_class->realize = gtk_list_item_realize;
186   widget_class->size_request = gtk_list_item_size_request;
187   widget_class->size_allocate = gtk_list_item_size_allocate;
188   widget_class->style_set = gtk_list_item_style_set;
189   widget_class->draw = gtk_list_item_draw;
190   widget_class->draw_focus = gtk_list_item_draw_focus;
191   widget_class->button_press_event = gtk_list_item_button_press;
192   widget_class->expose_event = gtk_list_item_expose;
193   widget_class->focus_in_event = gtk_list_item_focus_in;
194   widget_class->focus_out_event = gtk_list_item_focus_out;
195
196   item_class->select = gtk_real_list_item_select;
197   item_class->deselect = gtk_real_list_item_deselect;
198   item_class->toggle = gtk_real_list_item_toggle;
199
200   class->toggle_focus_row = NULL;
201   class->select_all = NULL;
202   class->unselect_all = NULL;
203   class->undo_selection = NULL;
204   class->start_selection = NULL;
205   class->end_selection = NULL;
206   class->extend_selection = NULL;
207   class->scroll_horizontal = NULL;
208   class->scroll_vertical = NULL;
209   class->toggle_add_mode = NULL;
210
211
212   binding_set = gtk_binding_set_by_class (class);
213   gtk_binding_entry_add_signal (binding_set, GDK_Up, 0,
214                                 "scroll_vertical", 2,
215                                 GTK_TYPE_ENUM, GTK_SCROLL_STEP_BACKWARD,
216                                 GTK_TYPE_FLOAT, 0.0);
217   gtk_binding_entry_add_signal (binding_set, GDK_Down, 0,
218                                 "scroll_vertical", 2,
219                                 GTK_TYPE_ENUM, GTK_SCROLL_STEP_FORWARD,
220                                 GTK_TYPE_FLOAT, 0.0);
221   gtk_binding_entry_add_signal (binding_set, GDK_Page_Up, 0,
222                                 "scroll_vertical", 2,
223                                 GTK_TYPE_ENUM, GTK_SCROLL_PAGE_BACKWARD,
224                                 GTK_TYPE_FLOAT, 0.0);
225   gtk_binding_entry_add_signal (binding_set, GDK_Page_Down, 0,
226                                 "scroll_vertical", 2,
227                                 GTK_TYPE_ENUM, GTK_SCROLL_PAGE_FORWARD,
228                                 GTK_TYPE_FLOAT, 0.0);
229   gtk_binding_entry_add_signal (binding_set, GDK_Home, GDK_CONTROL_MASK,
230                                 "scroll_vertical", 2,
231                                 GTK_TYPE_ENUM, GTK_SCROLL_JUMP,
232                                 GTK_TYPE_FLOAT, 0.0);
233   gtk_binding_entry_add_signal (binding_set, GDK_End, GDK_CONTROL_MASK,
234                                 "scroll_vertical", 2,
235                                 GTK_TYPE_ENUM, GTK_SCROLL_JUMP,
236                                 GTK_TYPE_FLOAT, 1.0);
237
238   gtk_binding_entry_add_signal (binding_set, GDK_Up, GDK_SHIFT_MASK,
239                                 "extend_selection", 3,
240                                 GTK_TYPE_ENUM, GTK_SCROLL_STEP_BACKWARD,
241                                 GTK_TYPE_FLOAT, 0.0, GTK_TYPE_BOOL, TRUE);
242   gtk_binding_entry_add_signal (binding_set, GDK_Down, GDK_SHIFT_MASK,
243                                 "extend_selection", 3,
244                                 GTK_TYPE_ENUM, GTK_SCROLL_STEP_FORWARD,
245                                 GTK_TYPE_FLOAT, 0.0, GTK_TYPE_BOOL, TRUE);
246   gtk_binding_entry_add_signal (binding_set, GDK_Page_Up, GDK_SHIFT_MASK,
247                                 "extend_selection", 3,
248                                 GTK_TYPE_ENUM, GTK_SCROLL_PAGE_BACKWARD,
249                                 GTK_TYPE_FLOAT, 0.0, GTK_TYPE_BOOL, TRUE);
250   gtk_binding_entry_add_signal (binding_set, GDK_Page_Down, GDK_SHIFT_MASK,
251                                 "extend_selection", 3,
252                                 GTK_TYPE_ENUM, GTK_SCROLL_PAGE_FORWARD,
253                                 GTK_TYPE_FLOAT, 0.0, GTK_TYPE_BOOL, TRUE);
254   gtk_binding_entry_add_signal (binding_set, GDK_Home,
255                                 GDK_SHIFT_MASK | GDK_CONTROL_MASK,
256                                 "extend_selection", 3,
257                                 GTK_TYPE_ENUM, GTK_SCROLL_JUMP,
258                                 GTK_TYPE_FLOAT, 0.0, GTK_TYPE_BOOL, TRUE);
259   gtk_binding_entry_add_signal (binding_set, GDK_End,
260                                 GDK_SHIFT_MASK | GDK_CONTROL_MASK,
261                                 "extend_selection", 3,
262                                 GTK_TYPE_ENUM, GTK_SCROLL_JUMP,
263                                 GTK_TYPE_FLOAT, 1.0, GTK_TYPE_BOOL, TRUE);
264
265   gtk_binding_entry_add_signal (binding_set, GDK_Left, 0,
266                                 "scroll_horizontal", 2,
267                                 GTK_TYPE_ENUM, GTK_SCROLL_STEP_BACKWARD,
268                                 GTK_TYPE_FLOAT, 0.0);
269   gtk_binding_entry_add_signal (binding_set, GDK_Right, 0,
270                                 "scroll_horizontal", 2,
271                                 GTK_TYPE_ENUM, GTK_SCROLL_STEP_FORWARD,
272                                 GTK_TYPE_FLOAT, 0.0);
273   gtk_binding_entry_add_signal (binding_set, GDK_Home, 0,
274                                 "scroll_horizontal", 2,
275                                 GTK_TYPE_ENUM, GTK_SCROLL_JUMP,
276                                 GTK_TYPE_FLOAT, 0.0);
277   gtk_binding_entry_add_signal (binding_set, GDK_End, 0,
278                                 "scroll_horizontal", 2,
279                                 GTK_TYPE_ENUM, GTK_SCROLL_JUMP,
280                                 GTK_TYPE_FLOAT, 1.0);
281
282   gtk_binding_entry_add_signal (binding_set, GDK_Escape, 0,
283                                 "undo_selection", 0);
284   gtk_binding_entry_add_signal (binding_set, GDK_space, 0,
285                                 "toggle_focus_row", 0);
286   gtk_binding_entry_add_signal (binding_set, GDK_space, GDK_CONTROL_MASK,
287                                 "toggle_add_mode", 0);
288   gtk_binding_entry_add_signal (binding_set, '/', GDK_CONTROL_MASK,
289                                 "select_all", 0);
290   gtk_binding_entry_add_signal (binding_set, '\\', GDK_CONTROL_MASK,
291                                 "unselect_all", 0);
292   gtk_binding_entry_add_signal (binding_set, GDK_Shift_L,
293                                 GDK_RELEASE_MASK | GDK_SHIFT_MASK,
294                                 "end_selection", 0);
295   gtk_binding_entry_add_signal (binding_set, GDK_Shift_R,
296                                 GDK_RELEASE_MASK | GDK_SHIFT_MASK,
297                                 "end_selection", 0);
298   gtk_binding_entry_add_signal (binding_set, GDK_Shift_R,
299                                 GDK_RELEASE_MASK | GDK_SHIFT_MASK |
300                                 GDK_CONTROL_MASK,
301                                 "end_selection", 0);
302 }
303
304 static void
305 gtk_list_item_init (GtkListItem *list_item)
306 {
307   GTK_WIDGET_SET_FLAGS (list_item, GTK_CAN_FOCUS);
308 }
309
310 GtkWidget*
311 gtk_list_item_new (void)
312 {
313   return GTK_WIDGET (gtk_type_new (gtk_list_item_get_type ()));
314 }
315
316 GtkWidget*
317 gtk_list_item_new_with_label (const gchar *label)
318 {
319   GtkWidget *list_item;
320   GtkWidget *label_widget;
321
322   list_item = gtk_list_item_new ();
323   label_widget = gtk_label_new (label);
324   gtk_misc_set_alignment (GTK_MISC (label_widget), 0.0, 0.5);
325
326   gtk_container_add (GTK_CONTAINER (list_item), label_widget);
327   gtk_widget_show (label_widget);
328
329   return list_item;
330 }
331
332 void
333 gtk_list_item_select (GtkListItem *list_item)
334 {
335   gtk_item_select (GTK_ITEM (list_item));
336 }
337
338 void
339 gtk_list_item_deselect (GtkListItem *list_item)
340 {
341   gtk_item_deselect (GTK_ITEM (list_item));
342 }
343
344
345 static void
346 gtk_list_item_realize (GtkWidget *widget)
347 {
348   GdkWindowAttr attributes;
349   gint attributes_mask;
350
351   /*if (GTK_WIDGET_CLASS (parent_class)->realize)
352     (* GTK_WIDGET_CLASS (parent_class)->realize) (widget);*/
353
354   g_return_if_fail (widget != NULL);
355   g_return_if_fail (GTK_IS_LIST_ITEM (widget));
356
357   GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
358
359   attributes.x = widget->allocation.x;
360   attributes.y = widget->allocation.y;
361   attributes.width = widget->allocation.width;
362   attributes.height = widget->allocation.height;
363   attributes.window_type = GDK_WINDOW_CHILD;
364   attributes.wclass = GDK_INPUT_OUTPUT;
365   attributes.visual = gtk_widget_get_visual (widget);
366   attributes.colormap = gtk_widget_get_colormap (widget);
367   attributes.event_mask = (gtk_widget_get_events (widget) |
368                            GDK_EXPOSURE_MASK |
369                            GDK_BUTTON_PRESS_MASK |
370                            GDK_BUTTON_RELEASE_MASK |
371                            GDK_KEY_PRESS_MASK |
372                            GDK_KEY_RELEASE_MASK |
373                            GDK_ENTER_NOTIFY_MASK |
374                            GDK_LEAVE_NOTIFY_MASK);
375
376   attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
377   widget->window = gdk_window_new (gtk_widget_get_parent_window (widget), &attributes, attributes_mask);
378   gdk_window_set_user_data (widget->window, widget);
379
380   widget->style = gtk_style_attach (widget->style, widget->window);
381   gdk_window_set_background (widget->window, 
382                              &widget->style->base[GTK_STATE_NORMAL]);
383 }
384
385 static void
386 gtk_list_item_size_request (GtkWidget      *widget,
387                             GtkRequisition *requisition)
388 {
389   GtkBin *bin;
390   GtkRequisition child_requisition;
391
392   g_return_if_fail (widget != NULL);
393   g_return_if_fail (GTK_IS_LIST_ITEM (widget));
394   g_return_if_fail (requisition != NULL);
395
396   bin = GTK_BIN (widget);
397
398   requisition->width = (GTK_CONTAINER (widget)->border_width +
399                         widget->style->klass->xthickness) * 2;
400   requisition->height = GTK_CONTAINER (widget)->border_width * 2;
401
402   if (bin->child && GTK_WIDGET_VISIBLE (bin->child))
403     {
404       gtk_widget_size_request (bin->child, &child_requisition);
405
406       requisition->width += child_requisition.width;
407       requisition->height += child_requisition.height;
408     }
409 }
410
411 static void
412 gtk_list_item_size_allocate (GtkWidget     *widget,
413                              GtkAllocation *allocation)
414 {
415   GtkBin *bin;
416   GtkAllocation child_allocation;
417
418   g_return_if_fail (widget != NULL);
419   g_return_if_fail (GTK_IS_LIST_ITEM (widget));
420   g_return_if_fail (allocation != NULL);
421
422   widget->allocation = *allocation;
423   if (GTK_WIDGET_REALIZED (widget))
424     gdk_window_move_resize (widget->window,
425                             allocation->x, allocation->y,
426                             allocation->width, allocation->height);
427
428   bin = GTK_BIN (widget);
429
430   if (bin->child)
431     {
432       child_allocation.x = (GTK_CONTAINER (widget)->border_width +
433                             widget->style->klass->xthickness);
434       child_allocation.y = GTK_CONTAINER (widget)->border_width;
435       child_allocation.width = allocation->width - child_allocation.x * 2;
436       child_allocation.height = allocation->height - child_allocation.y * 2;
437
438       gtk_widget_size_allocate (bin->child, &child_allocation);
439     }
440 }
441
442 static void 
443 gtk_list_item_style_set (GtkWidget      *widget,
444                          GtkStyle       *previous_style)
445 {
446   g_return_if_fail (widget != NULL);
447
448   if (previous_style && GTK_WIDGET_REALIZED (widget))
449     gdk_window_set_background (widget->window, &widget->style->base[GTK_WIDGET_STATE (widget)]);
450 }
451
452 static void
453 gtk_list_item_draw (GtkWidget    *widget,
454                     GdkRectangle *area)
455 {
456   GtkBin *bin;
457   GdkRectangle child_area;
458
459   g_return_if_fail (widget != NULL);
460   g_return_if_fail (GTK_IS_LIST_ITEM (widget));
461   g_return_if_fail (area != NULL);
462
463   if (GTK_WIDGET_DRAWABLE (widget))
464     {
465       bin = GTK_BIN (widget);
466
467       if (widget->state == GTK_STATE_NORMAL)
468         {
469           gdk_window_set_back_pixmap (widget->window, NULL, TRUE);
470           gdk_window_clear_area (widget->window, area->x, area->y, area->width, area->height);
471         }
472       else
473         {
474           gtk_paint_flat_box(widget->style, widget->window, 
475                              widget->state, GTK_SHADOW_ETCHED_OUT,
476                              area, widget, "listitem",
477                              0, 0, -1, -1);           
478         }
479
480       if (bin->child && gtk_widget_intersect (bin->child, area, &child_area))
481         gtk_widget_draw (bin->child, &child_area);
482
483       if (GTK_WIDGET_HAS_FOCUS (widget))
484         {
485           if (GTK_IS_LIST (widget->parent) && GTK_LIST (widget->parent)->add_mode)
486             gtk_paint_focus (widget->style, widget->window,
487                              NULL, widget, "add-mode",
488                              0, 0,
489                              widget->allocation.width - 1,
490                              widget->allocation.height - 1);
491           else
492             gtk_paint_focus (widget->style, widget->window,
493                              NULL, widget, NULL,
494                              0, 0,
495                              widget->allocation.width - 1,
496                              widget->allocation.height - 1);
497         }
498     }
499 }
500
501 static void
502 gtk_list_item_draw_focus (GtkWidget *widget)
503 {
504   g_return_if_fail (widget != NULL);
505   g_return_if_fail (GTK_IS_LIST_ITEM (widget));
506   
507   gtk_widget_draw(widget, NULL);
508 }
509
510 static gint
511 gtk_list_item_button_press (GtkWidget      *widget,
512                             GdkEventButton *event)
513 {
514   g_return_val_if_fail (widget != NULL, FALSE);
515   g_return_val_if_fail (GTK_IS_LIST_ITEM (widget), FALSE);
516   g_return_val_if_fail (event != NULL, FALSE);
517
518   if (event->type == GDK_BUTTON_PRESS)
519     if (!GTK_WIDGET_HAS_FOCUS (widget))
520       gtk_widget_grab_focus (widget);
521
522   return FALSE;
523 }
524
525 static gint
526 gtk_list_item_expose (GtkWidget      *widget,
527                       GdkEventExpose *event)
528 {
529   GtkBin *bin;
530   GdkEventExpose child_event;
531
532   g_return_val_if_fail (widget != NULL, FALSE);
533   g_return_val_if_fail (GTK_IS_LIST_ITEM (widget), FALSE);
534   g_return_val_if_fail (event != NULL, FALSE);
535
536   if (GTK_WIDGET_DRAWABLE (widget))
537     {
538       bin = GTK_BIN (widget);
539
540       if (!GTK_WIDGET_IS_SENSITIVE (widget))
541         gdk_window_set_background (widget->window, &widget->style->bg[GTK_STATE_INSENSITIVE]);
542       else if (widget->state == GTK_STATE_NORMAL)
543         gdk_window_set_background (widget->window, &widget->style->base[GTK_STATE_NORMAL]);
544       else
545         gdk_window_set_background (widget->window, &widget->style->bg[widget->state]);
546
547       gdk_window_clear_area (widget->window, event->area.x, event->area.y,
548                              event->area.width, event->area.height);
549
550       if (bin->child)
551         {
552           child_event = *event;
553
554           if (GTK_WIDGET_NO_WINDOW (bin->child) &&
555               gtk_widget_intersect (bin->child, &event->area, &child_event.area))
556             gtk_widget_event (bin->child, (GdkEvent*) &child_event);
557         }
558
559       gtk_widget_draw_focus (widget);
560     }
561
562   return FALSE;
563 }
564
565 static gint
566 gtk_list_item_focus_in (GtkWidget     *widget,
567                         GdkEventFocus *event)
568 {
569   g_return_val_if_fail (widget != NULL, FALSE);
570   g_return_val_if_fail (GTK_IS_LIST_ITEM (widget), FALSE);
571   g_return_val_if_fail (event != NULL, FALSE);
572
573   GTK_WIDGET_SET_FLAGS (widget, GTK_HAS_FOCUS);
574   gtk_widget_draw_focus (widget);
575
576   return FALSE;
577 }
578
579 static gint
580 gtk_list_item_focus_out (GtkWidget     *widget,
581                          GdkEventFocus *event)
582 {
583   g_return_val_if_fail (widget != NULL, FALSE);
584   g_return_val_if_fail (GTK_IS_LIST_ITEM (widget), FALSE);
585   g_return_val_if_fail (event != NULL, FALSE);
586
587   GTK_WIDGET_UNSET_FLAGS (widget, GTK_HAS_FOCUS);
588   gtk_widget_draw_focus (widget);
589
590   return FALSE;
591 }
592
593 static void
594 gtk_real_list_item_select (GtkItem *item)
595 {
596   g_return_if_fail (item != NULL);
597   g_return_if_fail (GTK_IS_LIST_ITEM (item));
598
599   switch (GTK_WIDGET (item)->state)
600     {
601     case GTK_STATE_SELECTED:
602     case GTK_STATE_INSENSITIVE:
603       break;
604     default:
605       gtk_widget_set_state (GTK_WIDGET (item), GTK_STATE_SELECTED);
606       break;
607     }
608 }
609
610 static void
611 gtk_real_list_item_deselect (GtkItem *item)
612 {
613   g_return_if_fail (item != NULL);
614   g_return_if_fail (GTK_IS_LIST_ITEM (item));
615
616   if (GTK_WIDGET (item)->state == GTK_STATE_SELECTED)
617     gtk_widget_set_state (GTK_WIDGET (item), GTK_STATE_NORMAL);
618 }
619
620 static void
621 gtk_real_list_item_toggle (GtkItem *item)
622 {
623   g_return_if_fail (item != NULL);
624   g_return_if_fail (GTK_IS_LIST_ITEM (item));
625   
626   switch (GTK_WIDGET (item)->state)
627     {
628     case GTK_STATE_SELECTED:
629       gtk_widget_set_state (GTK_WIDGET (item), GTK_STATE_NORMAL);
630       break;
631     case GTK_STATE_INSENSITIVE:
632       break;
633     default:
634       gtk_widget_set_state (GTK_WIDGET (item), GTK_STATE_SELECTED);
635       break;
636     }
637 }