]> Pileus Git - ~andy/gtk/blob - gtk/gtktree.c
512d4a491ec10ef6d8c23a7816938de615708108
[~andy/gtk] / gtk / gtktree.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 Free
16  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17  */
18 #include "gtktree.h"
19 #include "gtktreeitem.h"
20 #include "gtkmain.h"
21 #include "gtksignal.h"
22 #include "gtklist.h"
23
24 enum {
25   SELECTION_CHANGED,
26   SELECT_CHILD,
27   UNSELECT_CHILD,
28   LAST_SIGNAL
29 };
30
31 typedef void (*GtkTreeSignal) (GtkObject *object,
32                                gpointer   arg1,
33                                gpointer   data);
34
35
36 static void gtk_tree_class_init (GtkTreeClass *klass);
37 static void gtk_tree_init       (GtkTree      *tree);
38 static void gtk_tree_destroy         (GtkObject      *object);
39 static void gtk_tree_map             (GtkWidget      *widget);
40 static void gtk_tree_unmap           (GtkWidget      *widget);
41 static void gtk_tree_realize         (GtkWidget      *widget);
42 static void gtk_tree_draw            (GtkWidget      *widget,
43                                       GdkRectangle   *area);
44 static gint gtk_tree_expose          (GtkWidget      *widget,
45                                       GdkEventExpose *event);
46 static gint gtk_tree_motion_notify   (GtkWidget      *widget,
47                                       GdkEventMotion *event);
48 static gint gtk_tree_button_press    (GtkWidget      *widget,
49                                       GdkEventButton *event);
50 static gint gtk_tree_button_release  (GtkWidget      *widget,
51                                       GdkEventButton *event);
52 static void gtk_tree_size_request    (GtkWidget      *widget,
53                                       GtkRequisition *requisition);
54 static void gtk_tree_size_allocate   (GtkWidget      *widget,
55                                       GtkAllocation  *allocation);
56 static void gtk_tree_add             (GtkContainer   *container,
57                                       GtkWidget      *widget);
58 static void gtk_tree_remove          (GtkContainer   *container,
59                                       GtkWidget      *widget);
60 static void gtk_tree_foreach         (GtkContainer   *container,
61                                       GtkCallback     callback,
62                                       gpointer        callback_data);
63
64 static void gtk_real_tree_select_child   (GtkTree       *tree,
65                                           GtkWidget     *child);
66 static void gtk_real_tree_unselect_child (GtkTree       *tree,
67                                           GtkWidget     *child);
68
69 static void gtk_tree_marshal_signal (GtkObject      *object,
70                                      GtkSignalFunc   func,
71                                      gpointer        func_data,
72                                      GtkArg         *args);
73
74 static GtkContainerClass *parent_class = NULL;
75 static gint tree_signals[LAST_SIGNAL] = { 0 };
76
77 guint
78 gtk_tree_get_type ()
79 {
80   static guint tree_type = 0;
81
82   if (!tree_type)
83     {
84       GtkTypeInfo tree_info =
85       {
86         "GtkTree",
87         sizeof (GtkTree),
88         sizeof (GtkTreeClass),
89         (GtkClassInitFunc) gtk_tree_class_init,
90         (GtkObjectInitFunc) gtk_tree_init,
91         (GtkArgFunc) NULL,
92       };
93
94       tree_type = gtk_type_unique (gtk_container_get_type (), &tree_info);
95     }
96
97   return tree_type;
98 }
99
100 static void
101 gtk_tree_class_init (GtkTreeClass *class)
102 {
103   GtkObjectClass *object_class;
104   GtkWidgetClass *widget_class;
105   GtkContainerClass *container_class;
106
107   object_class = (GtkObjectClass*) class;
108   widget_class = (GtkWidgetClass*) class;
109   container_class = (GtkContainerClass*) class;
110
111   parent_class = gtk_type_class (gtk_container_get_type ());
112
113   tree_signals[SELECTION_CHANGED] =
114     gtk_signal_new ("selection_changed",
115                     GTK_RUN_FIRST,
116                     object_class->type,
117                     GTK_SIGNAL_OFFSET (GtkTreeClass, selection_changed),
118                     gtk_signal_default_marshaller,
119                     GTK_TYPE_NONE, 0);
120   tree_signals[SELECT_CHILD] =
121     gtk_signal_new ("select_child",
122                     GTK_RUN_FIRST,
123                     object_class->type,
124                     GTK_SIGNAL_OFFSET (GtkTreeClass, select_child),
125                     gtk_tree_marshal_signal,
126                     GTK_TYPE_NONE, 1,
127                     GTK_TYPE_WIDGET);
128   tree_signals[UNSELECT_CHILD] =
129     gtk_signal_new ("unselect_child",
130                     GTK_RUN_FIRST,
131                     object_class->type,
132                     GTK_SIGNAL_OFFSET (GtkTreeClass, unselect_child),
133                     gtk_tree_marshal_signal,
134                     GTK_TYPE_NONE, 1,
135                     GTK_TYPE_WIDGET);
136
137   gtk_object_class_add_signals (object_class, tree_signals, LAST_SIGNAL);
138
139   object_class->destroy = gtk_tree_destroy;
140
141   widget_class->map = gtk_tree_map;
142   widget_class->unmap = gtk_tree_unmap;
143   widget_class->realize = gtk_tree_realize;
144   widget_class->draw = gtk_tree_draw;
145   widget_class->expose_event = gtk_tree_expose;
146   widget_class->motion_notify_event = gtk_tree_motion_notify;
147   widget_class->button_press_event = gtk_tree_button_press;
148   widget_class->button_release_event = gtk_tree_button_release;
149   widget_class->size_request = gtk_tree_size_request;
150   widget_class->size_allocate = gtk_tree_size_allocate;
151
152   container_class->add = gtk_tree_add;
153   container_class->remove = gtk_tree_remove;
154   container_class->foreach = gtk_tree_foreach;
155
156   class->selection_changed = NULL;
157   class->select_child = gtk_real_tree_select_child;
158   class->unselect_child = gtk_real_tree_unselect_child;
159 }
160
161 static void
162 gtk_tree_init (GtkTree *tree)
163 {
164   tree->children = NULL;
165   tree->root_tree = NULL;
166   tree->selection = NULL;
167   tree->tree_owner = NULL;
168   tree->selection_mode = GTK_SELECTION_SINGLE;
169   tree->indent_value = 9;
170   tree->current_indent = 0;
171   tree->level = 0;
172   tree->view_mode = GTK_TREE_VIEW_LINE;
173   tree->view_line = 1;
174 }
175
176 GtkWidget*
177 gtk_tree_new ()
178 {
179   return GTK_WIDGET (gtk_type_new (gtk_tree_get_type ()));
180 }
181
182 void
183 gtk_tree_append (GtkTree   *tree,
184                  GtkWidget *child)
185 {
186
187   g_return_if_fail (tree != NULL);
188   g_return_if_fail (GTK_IS_TREE_ITEM (child));
189
190   gtk_tree_insert(tree, child, -1);
191 }
192
193 void
194 gtk_tree_prepend (GtkTree   *tree,
195                   GtkWidget *child)
196 {
197   g_return_if_fail (tree != NULL);
198   g_return_if_fail (GTK_IS_TREE_ITEM (child));
199
200   gtk_tree_insert(tree, child, 0);
201
202 }
203
204 void
205 gtk_tree_insert (GtkTree   *tree,
206                  GtkWidget *child,
207                  gint       position)
208 {
209   gint nchildren;
210     
211   g_return_if_fail (tree != NULL || child != NULL);
212   g_return_if_fail (GTK_IS_TREE_ITEM(child));
213
214   /* set parent widget to item */
215   gtk_widget_set_parent (child, GTK_WIDGET (tree));
216     
217   if (GTK_WIDGET_VISIBLE (child->parent))
218     {
219       if (GTK_WIDGET_REALIZED (child->parent) &&
220           !GTK_WIDGET_REALIZED (child))
221         gtk_widget_realize (child);
222
223       if (GTK_WIDGET_MAPPED (child->parent) &&
224           !GTK_WIDGET_MAPPED (child))
225         gtk_widget_map (child);
226     }
227
228   nchildren = g_list_length (tree->children);
229     
230   if ((position < 0) || (position > nchildren))
231     position = nchildren;
232
233   if (position == nchildren)
234     {
235       tree->children = g_list_append(tree->children, child);
236     }
237   else
238     {
239       g_list_insert(tree->children, child, position);
240     }
241     
242   if (GTK_WIDGET_VISIBLE (tree))
243     gtk_widget_queue_resize (GTK_WIDGET (tree));
244
245 }
246
247 static void
248 gtk_tree_add (GtkContainer *container,
249               GtkWidget    *widget)
250 {
251   GtkTree *tree;
252
253   g_return_if_fail (container != NULL);
254   g_return_if_fail (GTK_IS_TREE (container));
255   g_return_if_fail (widget != NULL);
256
257   tree = GTK_TREE (container);
258
259   gtk_widget_set_parent (widget, GTK_WIDGET (container));
260   if (GTK_WIDGET_VISIBLE (widget->parent))
261     {
262       if (GTK_WIDGET_REALIZED (widget->parent) &&
263           !GTK_WIDGET_REALIZED (widget))
264         gtk_widget_realize (widget);
265
266       if (GTK_WIDGET_MAPPED (widget->parent) &&
267           !GTK_WIDGET_MAPPED (widget))
268         gtk_widget_map (widget);
269     }
270
271   tree->children = g_list_append (tree->children, widget);
272
273 #if 0
274   if (!tree->selection && (tree->selection_mode == GTK_SELECTION_BROWSE))
275     {
276       gtk_tree_select_child (tree, widget);
277     }
278 #endif
279
280   if (GTK_WIDGET_VISIBLE (widget) && GTK_WIDGET_VISIBLE (container))
281     gtk_widget_queue_resize (widget);
282
283 }
284
285 static gint
286 gtk_tree_button_press (GtkWidget      *widget,
287                        GdkEventButton *event)
288 {
289   GtkTree *tree;
290   GtkWidget *item;
291
292   g_return_val_if_fail (widget != NULL, FALSE);
293   g_return_val_if_fail (GTK_IS_TREE (widget), FALSE);
294   g_return_val_if_fail (event != NULL, FALSE);
295
296   tree = GTK_TREE (widget);
297   item = gtk_get_event_widget ((GdkEvent*) event);
298
299   while (!gtk_type_is_a (GTK_WIDGET_TYPE (item), gtk_tree_item_get_type ()))
300     item = item->parent;
301
302   switch(event->button) 
303     {
304     case 1:
305       gtk_tree_select_child (tree, item);
306       break;
307     case 2:
308       if(GTK_TREE_ITEM(item)->subtree) gtk_tree_item_expand(GTK_TREE_ITEM(item));
309       break;
310     case 3:
311       if(GTK_TREE_ITEM(item)->subtree) gtk_tree_item_collapse(GTK_TREE_ITEM(item));
312       break;
313     }
314
315   return TRUE;
316 }
317
318 static gint
319 gtk_tree_button_release (GtkWidget      *widget,
320                          GdkEventButton *event)
321 {
322   GtkTree *tree;
323   GtkWidget *item;
324
325   g_return_val_if_fail (widget != NULL, FALSE);
326   g_return_val_if_fail (GTK_IS_TREE (widget), FALSE);
327   g_return_val_if_fail (event != NULL, FALSE);
328
329   tree = GTK_TREE (widget);
330   item = gtk_get_event_widget ((GdkEvent*) event);
331
332   return TRUE;
333 }
334
335 gint
336 gtk_tree_child_position (GtkTree   *tree,
337                          GtkWidget *child)
338 {
339   GList *children;
340   gint pos;
341
342
343   g_return_val_if_fail (tree != NULL, -1);
344   g_return_val_if_fail (GTK_IS_TREE (tree), -1);
345   g_return_val_if_fail (child != NULL, -1);
346
347   pos = 0;
348   children = tree->children;
349
350   while (children)
351     {
352       if (child == GTK_WIDGET (children->data)) 
353         return pos;
354
355       pos += 1;
356       children = children->next;
357     }
358
359
360   return -1;
361 }
362
363 void
364 gtk_tree_clear_items (GtkTree *tree,
365                       gint     start,
366                       gint     end)
367 {
368   g_return_if_fail (tree != NULL);
369   g_return_if_fail (GTK_IS_TREE (tree));
370
371 }
372
373 static void
374 gtk_tree_destroy (GtkObject *object)
375 {
376   GtkTree *tree;
377   GtkWidget *child;
378   GList *children;
379
380   g_return_if_fail (object != NULL);
381   g_return_if_fail (GTK_IS_TREE (object));
382
383   tree = GTK_TREE (object);
384
385   children = tree->children;
386   while (children)
387     {
388       child = children->data;
389       children = children->next;
390
391       child->parent = NULL;
392       gtk_object_unref (GTK_OBJECT (child));
393       gtk_widget_destroy (child);
394     }
395
396   g_list_free (tree->children);
397
398   if(tree->root_tree == NULL)
399     g_list_free (tree->selection);
400
401   if (GTK_OBJECT_CLASS (parent_class)->destroy)
402     (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
403 }
404
405 static void
406 gtk_tree_draw (GtkWidget    *widget,
407                GdkRectangle *area)
408 {
409   GtkTree *tree;
410   GtkWidget *subtree;
411   GtkWidget *child;
412   GdkRectangle child_area;
413   GList *children;
414
415
416   g_return_if_fail (widget != NULL);
417   g_return_if_fail (GTK_IS_TREE (widget));
418   g_return_if_fail (area != NULL);
419
420   if (GTK_WIDGET_DRAWABLE (widget))
421     {
422       tree = GTK_TREE (widget);
423
424       children = tree->children;
425       while (children)
426         {
427           child = children->data;
428           children = children->next;
429
430           if (gtk_widget_intersect (child, area, &child_area))
431             gtk_widget_draw (child, &child_area);
432
433           if((subtree = GTK_TREE_ITEM(child)->subtree) &&
434              GTK_WIDGET_VISIBLE(subtree) &&
435              gtk_widget_intersect (subtree, area, &child_area))
436             gtk_widget_draw (subtree, &child_area);
437         }
438     }
439
440 }
441
442 static gint
443 gtk_tree_expose (GtkWidget      *widget,
444                  GdkEventExpose *event)
445 {
446   GtkTree *tree;
447   GtkWidget *child;
448   GdkEventExpose child_event;
449   GList *children;
450
451
452   g_return_val_if_fail (widget != NULL, FALSE);
453   g_return_val_if_fail (GTK_IS_TREE (widget), FALSE);
454   g_return_val_if_fail (event != NULL, FALSE);
455
456   if (GTK_WIDGET_DRAWABLE (widget))
457     {
458       tree = GTK_TREE (widget);
459
460       child_event = *event;
461
462       children = tree->children;
463       while (children)
464         {
465           child = children->data;
466           children = children->next;
467
468           if (GTK_WIDGET_NO_WINDOW (child) &&
469               gtk_widget_intersect (child, &event->area, &child_event.area))
470             gtk_widget_event (child, (GdkEvent*) &child_event);
471         }
472     }
473
474
475   return FALSE;
476 }
477
478 static void
479 gtk_tree_foreach (GtkContainer *container,
480                   GtkCallback   callback,
481                   gpointer      callback_data)
482 {
483   GtkTree *tree;
484   GtkWidget *child;
485   GList *children;
486
487
488   g_return_if_fail (container != NULL);
489   g_return_if_fail (GTK_IS_TREE (container));
490   g_return_if_fail (callback != NULL);
491
492   tree = GTK_TREE (container);
493   children = tree->children;
494
495   while (children)
496     {
497       child = children->data;
498       children = children->next;
499
500       (* callback) (child, callback_data);
501
502       if(GTK_TREE_ITEM(child)->subtree)
503         (* callback)(GTK_TREE_ITEM(child)->subtree, callback_data);
504     }
505 }
506
507 static void
508 gtk_tree_map (GtkWidget *widget)
509 {
510   GtkTree *tree;
511   GtkWidget *child;
512   GList *children;
513
514
515   g_return_if_fail (widget != NULL);
516   g_return_if_fail (GTK_IS_TREE (widget));
517
518   GTK_WIDGET_SET_FLAGS (widget, GTK_MAPPED);
519   tree = GTK_TREE (widget);
520
521   gdk_window_show (widget->window);
522
523   if(GTK_IS_TREE(widget->parent)) 
524     {
525       /* set root tree for this tree */
526       tree->root_tree = GTK_TREE(widget->parent)->root_tree;
527
528       tree->level = GTK_TREE(GTK_WIDGET(tree)->parent)->level+1;
529       tree->indent_value = GTK_TREE(GTK_WIDGET(tree)->parent)->indent_value;
530       tree->current_indent = GTK_TREE(GTK_WIDGET(tree)->parent)->current_indent + 
531         tree->indent_value;
532       tree->view_mode = GTK_TREE(GTK_WIDGET(tree)->parent)->view_mode;
533       tree->view_line = GTK_TREE(GTK_WIDGET(tree)->parent)->view_line;
534     } 
535   else
536     tree->root_tree = tree;
537
538   children = tree->children;
539   while (children)
540     {
541       child = children->data;
542       children = children->next;
543
544       if (GTK_WIDGET_VISIBLE (child) &&
545           !GTK_WIDGET_MAPPED (child))
546         gtk_widget_map (child);
547
548       if ((child = GTK_WIDGET(GTK_TREE_ITEM(child)->subtree)) &&
549           GTK_WIDGET_VISIBLE (child) &&
550           !GTK_WIDGET_MAPPED (child))
551         gtk_widget_map (child);
552     }
553 }
554
555 static void
556 gtk_tree_marshal_signal (GtkObject      *object,
557                          GtkSignalFunc   func,
558                          gpointer        func_data,
559                          GtkArg         *args)
560 {
561   GtkTreeSignal rfunc;
562
563   rfunc = (GtkTreeSignal) func;
564
565   (* rfunc) (object, GTK_VALUE_OBJECT (args[0]), func_data);
566 }
567
568 static gint
569 gtk_tree_motion_notify (GtkWidget      *widget,
570                         GdkEventMotion *event)
571 {
572   g_return_val_if_fail (widget != NULL, FALSE);
573   g_return_val_if_fail (GTK_IS_TREE (widget), FALSE);
574   g_return_val_if_fail (event != NULL, FALSE);
575
576   g_print("gtk_tree_motion_notify\n");
577
578   return FALSE;
579 }
580
581 static void
582 gtk_tree_realize (GtkWidget *widget)
583 {
584   GdkWindowAttr attributes;
585   gint attributes_mask;
586
587
588   g_return_if_fail (widget != NULL);
589   g_return_if_fail (GTK_IS_TREE (widget));
590
591   GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
592
593   attributes.window_type = GDK_WINDOW_CHILD;
594   attributes.x = widget->allocation.x;
595   attributes.y = widget->allocation.y;
596   attributes.width = widget->allocation.width;
597   attributes.height = widget->allocation.height;
598   attributes.wclass = GDK_INPUT_OUTPUT;
599   attributes.visual = gtk_widget_get_visual (widget);
600   attributes.colormap = gtk_widget_get_colormap (widget);
601   attributes.event_mask = GDK_EXPOSURE_MASK;
602
603   attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
604
605   widget->window = gdk_window_new (widget->parent->window, &attributes, attributes_mask);
606   gdk_window_set_user_data (widget->window, widget);
607
608   widget->style = gtk_style_attach (widget->style, widget->window);
609   gdk_window_set_background (widget->window, &widget->style->white);
610
611 }
612
613 static void
614 gtk_tree_remove (GtkContainer *container,
615                  GtkWidget    *widget)
616 {
617   GList *item_list;
618
619   g_return_if_fail (container != NULL);
620   g_return_if_fail (GTK_IS_TREE (container));
621   g_return_if_fail (widget != NULL);
622   g_return_if_fail (container == GTK_CONTAINER (widget->parent));
623
624   item_list = g_list_alloc ();
625   item_list->data = widget;
626   
627   gtk_tree_remove_items (GTK_TREE (container), item_list);
628   
629   g_list_free (item_list);
630 }
631
632 void
633 gtk_tree_remove_items (GtkTree *tree,
634                        GList   *items)
635 {
636   GtkWidget *widget;
637   GList *selected_widgets;
638   GList *tmp_list;
639   GtkTree *real_tree, *root_tree;
640
641   g_return_if_fail (tree != NULL);
642   g_return_if_fail (GTK_IS_TREE (tree));
643
644   root_tree = GTK_TREE(GTK_TREE_ROOT_TREE(tree));
645   tmp_list = items;
646   selected_widgets = NULL;
647   widget = NULL;
648
649   while (tmp_list)
650     {
651       widget = tmp_list->data;
652       tmp_list = tmp_list->next;
653
654       /* get real owner of this widget */
655       real_tree = GTK_TREE(widget->parent);
656       
657       if (widget->state == GTK_STATE_SELECTED)
658         selected_widgets = g_list_prepend (selected_widgets, widget);
659
660       /* remove this item of his real parent */
661       real_tree->children = g_list_remove (real_tree->children, widget);
662
663       /* delete subtree if there is no children in it */
664       if(real_tree->children == NULL && 
665          real_tree != root_tree)
666         {
667           gtk_tree_item_remove_subtree(GTK_TREE_ITEM(real_tree->tree_owner));
668         }
669
670       /* remove subtree associate at this item if it exist */      
671       if(GTK_TREE_ITEM(widget)->subtree) 
672         {
673           if (GTK_WIDGET_MAPPED (GTK_TREE_ITEM(widget)->subtree))
674             gtk_widget_unmap (GTK_TREE_ITEM(widget)->subtree);
675
676           gtk_widget_unparent (GTK_TREE_ITEM(widget)->subtree);
677         }
678
679       /* remove really widget for this item */
680       if (GTK_WIDGET_MAPPED (widget))
681         gtk_widget_unmap (widget);
682
683       gtk_widget_unparent (widget);
684     }
685
686   if (selected_widgets)
687     {
688       tmp_list = selected_widgets;
689       while (tmp_list)
690         {
691           widget = tmp_list->data;
692           tmp_list = tmp_list->next;
693
694           gtk_tree_unselect_child (tree, widget);
695         }
696     }
697
698   g_list_free (selected_widgets);
699
700   if (root_tree->children && !root_tree->selection &&
701       (root_tree->selection_mode == GTK_SELECTION_BROWSE))
702     {
703       widget = root_tree->children->data;
704       gtk_tree_select_child (root_tree, widget);
705     }
706
707   if (GTK_WIDGET_VISIBLE (root_tree))
708     gtk_widget_queue_resize (GTK_WIDGET (root_tree));
709 }
710  
711 void
712 gtk_tree_select_child (GtkTree   *tree,
713                        GtkWidget *child)
714 {
715
716   gtk_signal_emit (GTK_OBJECT (tree), tree_signals[SELECT_CHILD], child);
717
718 }
719
720 void
721 gtk_tree_select_item (GtkTree   *tree,
722                       gint     item)
723 {
724   GList *tmp_list;
725
726
727   g_return_if_fail (tree != NULL);
728   g_return_if_fail (GTK_IS_TREE (tree));
729
730   tmp_list = g_list_nth (tree->children, item);
731   if (tmp_list)
732     gtk_tree_select_child (tree, GTK_WIDGET (tmp_list->data));
733
734 }
735
736 static void
737 gtk_tree_size_allocate (GtkWidget     *widget,
738                         GtkAllocation *allocation)
739 {
740   GtkTree *tree;
741   GtkWidget *child, *subtree;
742   GtkAllocation child_allocation;
743   GList *children;
744
745
746   g_return_if_fail (widget != NULL);
747   g_return_if_fail (GTK_IS_TREE (widget));
748   g_return_if_fail (allocation != NULL);
749
750   tree = GTK_TREE (widget);
751
752   widget->allocation = *allocation;
753   if (GTK_WIDGET_REALIZED (widget))
754     gdk_window_move_resize (widget->window,
755                             allocation->x, allocation->y,
756                             allocation->width, allocation->height);
757   
758   if (tree->children)
759     {
760       child_allocation.x = GTK_CONTAINER (tree)->border_width;
761       child_allocation.y = GTK_CONTAINER (tree)->border_width;
762       child_allocation.width = allocation->width - child_allocation.x * 2;
763
764       children = tree->children;
765
766       while (children)
767         {
768           child = children->data;
769           children = children->next;
770
771           if (GTK_WIDGET_VISIBLE (child))
772             {
773               child_allocation.height = child->requisition.height;
774
775               gtk_widget_size_allocate (child, &child_allocation);
776
777               child_allocation.y += child_allocation.height;
778
779               if((subtree = GTK_TREE_ITEM(child)->subtree))
780                 if(GTK_WIDGET_VISIBLE (subtree))
781                   {
782                     child_allocation.height = subtree->requisition.height;
783                     gtk_widget_size_allocate (subtree, &child_allocation);
784                     child_allocation.y += child_allocation.height;
785                   }
786             }
787         }
788     }
789
790 }
791
792 static void
793 gtk_tree_size_request (GtkWidget      *widget,
794                        GtkRequisition *requisition)
795 {
796   GtkTree *tree;
797   GtkWidget *child, *subtree;
798   GList *children;
799
800
801   g_return_if_fail (widget != NULL);
802   g_return_if_fail (GTK_IS_TREE (widget));
803   g_return_if_fail (requisition != NULL);
804
805   tree = GTK_TREE (widget);
806   requisition->width = 0;
807   requisition->height = 0;
808
809   children = tree->children;
810   while (children)
811     {
812       child = children->data;
813       children = children->next;
814
815       if (GTK_WIDGET_VISIBLE (child))
816         {
817           gtk_widget_size_request (child, &child->requisition);
818
819           requisition->width = MAX (requisition->width, child->requisition.width);
820           requisition->height += child->requisition.height;
821
822           if((subtree = GTK_TREE_ITEM(child)->subtree) &&
823              GTK_WIDGET_VISIBLE (subtree))
824             {
825               gtk_widget_size_request (subtree, &subtree->requisition);
826
827               requisition->width = MAX (requisition->width, 
828                                         subtree->requisition.width);
829
830               requisition->height += subtree->requisition.height;
831             }
832         }
833     }
834
835   requisition->width += GTK_CONTAINER (tree)->border_width * 2;
836   requisition->height += GTK_CONTAINER (tree)->border_width * 2;
837
838   requisition->width = MAX (requisition->width, 1);
839   requisition->height = MAX (requisition->height, 1);
840
841 }
842
843 static void
844 gtk_tree_unmap (GtkWidget *widget)
845 {
846
847   g_return_if_fail (widget != NULL);
848   g_return_if_fail (GTK_IS_TREE (widget));
849
850   GTK_WIDGET_UNSET_FLAGS (widget, GTK_MAPPED);
851   gdk_window_hide (widget->window);
852
853 }
854
855 void
856 gtk_tree_unselect_child (GtkTree   *tree,
857                          GtkWidget *child)
858 {
859   gtk_signal_emit (GTK_OBJECT (tree), tree_signals[UNSELECT_CHILD], child);
860 }
861
862 void
863 gtk_tree_unselect_item (GtkTree *tree,
864                         gint     item)
865 {
866   GList *tmp_list;
867
868
869   g_return_if_fail (tree != NULL);
870   g_return_if_fail (GTK_IS_TREE (tree));
871
872   tmp_list = g_list_nth (tree->children, item);
873   if (tmp_list)
874     gtk_tree_unselect_child (tree, GTK_WIDGET (tmp_list->data));
875
876 }
877
878 static void
879 gtk_real_tree_select_child (GtkTree   *tree,
880                             GtkWidget *child)
881 {
882   GList *selection, *root_selection;
883   GList *tmp_list;
884   GtkWidget *tmp_item;
885
886
887   g_return_if_fail (tree != NULL);
888   g_return_if_fail (GTK_IS_TREE (tree));
889   g_return_if_fail (child != NULL);
890   g_return_if_fail (GTK_IS_TREE_ITEM (child));
891
892   root_selection = tree->root_tree->selection;
893
894   switch (tree->root_tree->selection_mode)
895     {
896     case GTK_SELECTION_SINGLE:
897
898       selection = root_selection;
899
900       /* remove old selection list */
901       while (selection)
902         {
903           tmp_item = selection->data;
904
905           if (tmp_item != child)
906             {
907               gtk_tree_item_deselect (GTK_TREE_ITEM (tmp_item));
908
909               tmp_list = selection;
910               selection = selection->next;
911
912               root_selection = g_list_remove_link (root_selection, tmp_list);
913
914               g_list_free (tmp_list);
915             }
916           else
917             selection = selection->next;
918         }
919
920       if (child->state == GTK_STATE_NORMAL)
921         {
922           gtk_tree_item_select (GTK_TREE_ITEM (child));
923           root_selection = g_list_prepend (root_selection, child);
924         }
925       else if (child->state == GTK_STATE_SELECTED)
926         {
927           gtk_tree_item_deselect (GTK_TREE_ITEM (child));
928           root_selection = g_list_remove (root_selection, child);
929         }
930
931       tree->root_tree->selection= root_selection;
932
933       gtk_signal_emit (GTK_OBJECT (tree->root_tree), 
934                        tree_signals[SELECTION_CHANGED]);
935
936     case GTK_SELECTION_BROWSE:
937       selection = root_selection;
938
939       while (selection)
940         {
941           tmp_item = selection->data;
942
943           if (tmp_item != child)
944             {
945               gtk_tree_item_deselect (GTK_TREE_ITEM (tmp_item));
946
947               tmp_list = selection;
948               selection = selection->next;
949
950               root_selection = g_list_remove_link (root_selection, tmp_list);
951
952               g_list_free (tmp_list);
953             }
954           else
955             selection = selection->next;
956         }
957
958       tree->root_tree->selection= root_selection;
959
960       if (child->state == GTK_STATE_NORMAL)
961         {
962           gtk_tree_item_select (GTK_TREE_ITEM (child));
963           root_selection = g_list_prepend (root_selection, child);
964           tree->root_tree->selection= root_selection;
965           gtk_signal_emit (GTK_OBJECT (tree->root_tree), 
966                            tree_signals[SELECTION_CHANGED]);
967         }
968       break;
969
970     case GTK_SELECTION_MULTIPLE:
971       if (child->state == GTK_STATE_NORMAL)
972         {
973           gtk_tree_item_select (GTK_TREE_ITEM (child));
974           root_selection = g_list_prepend (root_selection, child);
975           tree->root_tree->selection= root_selection;
976           gtk_signal_emit (GTK_OBJECT (tree->root_tree), 
977                            tree_signals[SELECTION_CHANGED]);
978         }
979       else if (child->state == GTK_STATE_SELECTED)
980         {
981           gtk_tree_item_deselect (GTK_TREE_ITEM (child));
982           root_selection = g_list_remove (root_selection, child);
983           tree->root_tree->selection= root_selection;
984           gtk_signal_emit (GTK_OBJECT (tree->root_tree), 
985                            tree_signals[SELECTION_CHANGED]);
986         }
987       break;
988
989     case GTK_SELECTION_EXTENDED:
990       break;
991     }
992 }
993
994 static void
995 gtk_real_tree_unselect_child (GtkTree   *tree,
996                               GtkWidget *child)
997 {
998
999   g_return_if_fail (tree != NULL);
1000   g_return_if_fail (GTK_IS_TREE (tree));
1001   g_return_if_fail (child != NULL);
1002   g_return_if_fail (GTK_IS_TREE_ITEM (child));
1003
1004   switch (tree->selection_mode)
1005     {
1006     case GTK_SELECTION_SINGLE:
1007     case GTK_SELECTION_MULTIPLE:
1008     case GTK_SELECTION_BROWSE:
1009       if (child->state == GTK_STATE_SELECTED)
1010         {
1011           GtkTree* root_tree = GTK_TREE_ROOT_TREE(tree);
1012           gtk_tree_item_deselect (GTK_TREE_ITEM (child));
1013           root_tree->selection = g_list_remove (root_tree->selection, child);
1014           gtk_signal_emit (GTK_OBJECT (tree->root_tree), 
1015                            tree_signals[SELECTION_CHANGED]);
1016         }
1017       break;
1018
1019     case GTK_SELECTION_EXTENDED:
1020       break;
1021     }
1022 }
1023
1024 void
1025 gtk_tree_set_selection_mode (GtkTree       *tree,
1026                              GtkSelectionMode mode) 
1027 {
1028   g_return_if_fail (tree != NULL);
1029   g_return_if_fail (GTK_IS_TREE (tree));
1030
1031   tree->selection_mode = mode;
1032 }
1033
1034 void
1035 gtk_tree_set_view_mode (GtkTree       *tree,
1036                         GtkTreeViewMode mode) 
1037 {
1038   g_return_if_fail (tree != NULL);
1039   g_return_if_fail (GTK_IS_TREE (tree));
1040
1041   tree->view_mode = mode;
1042 }
1043
1044 void
1045 gtk_tree_set_view_lines (GtkTree       *tree,
1046                          guint          flag) 
1047 {
1048   g_return_if_fail (tree != NULL);
1049   g_return_if_fail (GTK_IS_TREE (tree));
1050
1051   tree->view_line = flag;
1052 }