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