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