1 /* GTK - The GIMP Toolkit
2 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
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.
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.
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.
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/.
28 #include "gtktreeitem.h"
30 #include "gtksignal.h"
40 static void gtk_tree_class_init (GtkTreeClass *klass);
41 static void gtk_tree_init (GtkTree *tree);
42 static void gtk_tree_destroy (GtkObject *object);
43 static void gtk_tree_map (GtkWidget *widget);
44 static void gtk_tree_unmap (GtkWidget *widget);
45 static void gtk_tree_realize (GtkWidget *widget);
46 static gint gtk_tree_expose (GtkWidget *widget,
47 GdkEventExpose *event);
48 static gint gtk_tree_motion_notify (GtkWidget *widget,
49 GdkEventMotion *event);
50 static gint gtk_tree_button_press (GtkWidget *widget,
51 GdkEventButton *event);
52 static gint gtk_tree_button_release (GtkWidget *widget,
53 GdkEventButton *event);
54 static void gtk_tree_size_request (GtkWidget *widget,
55 GtkRequisition *requisition);
56 static void gtk_tree_size_allocate (GtkWidget *widget,
57 GtkAllocation *allocation);
58 static void gtk_tree_add (GtkContainer *container,
60 static void gtk_tree_forall (GtkContainer *container,
61 gboolean include_internals,
63 gpointer callback_data);
65 static void gtk_real_tree_select_child (GtkTree *tree,
67 static void gtk_real_tree_unselect_child (GtkTree *tree,
70 static GtkType gtk_tree_child_type (GtkContainer *container);
72 static GtkContainerClass *parent_class = NULL;
73 static guint tree_signals[LAST_SIGNAL] = { 0 };
76 gtk_tree_get_type (void)
78 static GtkType tree_type = 0;
82 static const GtkTypeInfo tree_info =
86 sizeof (GtkTreeClass),
87 (GtkClassInitFunc) gtk_tree_class_init,
88 (GtkObjectInitFunc) gtk_tree_init,
89 /* reserved_1 */ NULL,
90 /* reserved_2 */ NULL,
91 (GtkClassInitFunc) NULL,
94 tree_type = gtk_type_unique (gtk_container_get_type (), &tree_info);
101 gtk_tree_class_init (GtkTreeClass *class)
103 GtkObjectClass *object_class;
104 GtkWidgetClass *widget_class;
105 GtkContainerClass *container_class;
107 object_class = (GtkObjectClass*) class;
108 widget_class = (GtkWidgetClass*) class;
109 container_class = (GtkContainerClass*) class;
111 parent_class = gtk_type_class (gtk_container_get_type ());
113 tree_signals[SELECTION_CHANGED] =
114 gtk_signal_new ("selection_changed",
116 GTK_CLASS_TYPE (object_class),
117 GTK_SIGNAL_OFFSET (GtkTreeClass, selection_changed),
118 gtk_marshal_VOID__VOID,
120 tree_signals[SELECT_CHILD] =
121 gtk_signal_new ("select_child",
123 GTK_CLASS_TYPE (object_class),
124 GTK_SIGNAL_OFFSET (GtkTreeClass, select_child),
125 gtk_marshal_VOID__POINTER,
128 tree_signals[UNSELECT_CHILD] =
129 gtk_signal_new ("unselect_child",
131 GTK_CLASS_TYPE (object_class),
132 GTK_SIGNAL_OFFSET (GtkTreeClass, unselect_child),
133 gtk_marshal_VOID__POINTER,
137 gtk_object_class_add_signals (object_class, tree_signals, LAST_SIGNAL);
139 object_class->destroy = gtk_tree_destroy;
141 widget_class->map = gtk_tree_map;
142 widget_class->unmap = gtk_tree_unmap;
143 widget_class->realize = gtk_tree_realize;
144 widget_class->expose_event = gtk_tree_expose;
145 widget_class->motion_notify_event = gtk_tree_motion_notify;
146 widget_class->button_press_event = gtk_tree_button_press;
147 widget_class->button_release_event = gtk_tree_button_release;
148 widget_class->size_request = gtk_tree_size_request;
149 widget_class->size_allocate = gtk_tree_size_allocate;
151 container_class->add = gtk_tree_add;
152 container_class->remove =
153 (void (*)(GtkContainer *, GtkWidget *)) gtk_tree_remove_item;
154 container_class->forall = gtk_tree_forall;
155 container_class->child_type = gtk_tree_child_type;
157 class->selection_changed = NULL;
158 class->select_child = gtk_real_tree_select_child;
159 class->unselect_child = gtk_real_tree_unselect_child;
163 gtk_tree_child_type (GtkContainer *container)
165 return GTK_TYPE_TREE_ITEM;
169 gtk_tree_init (GtkTree *tree)
171 tree->children = NULL;
172 tree->root_tree = NULL;
173 tree->selection = NULL;
174 tree->tree_owner = NULL;
175 tree->selection_mode = GTK_SELECTION_SINGLE;
176 tree->indent_value = 9;
177 tree->current_indent = 0;
179 tree->view_mode = GTK_TREE_VIEW_LINE;
186 return GTK_WIDGET (gtk_type_new (gtk_tree_get_type ()));
190 gtk_tree_append (GtkTree *tree,
191 GtkWidget *tree_item)
193 g_return_if_fail (tree != NULL);
194 g_return_if_fail (GTK_IS_TREE (tree));
195 g_return_if_fail (tree_item != NULL);
196 g_return_if_fail (GTK_IS_TREE_ITEM (tree_item));
198 gtk_tree_insert (tree, tree_item, -1);
202 gtk_tree_prepend (GtkTree *tree,
203 GtkWidget *tree_item)
205 g_return_if_fail (tree != NULL);
206 g_return_if_fail (GTK_IS_TREE (tree));
207 g_return_if_fail (tree_item != NULL);
208 g_return_if_fail (GTK_IS_TREE_ITEM (tree_item));
210 gtk_tree_insert (tree, tree_item, 0);
214 gtk_tree_insert (GtkTree *tree,
215 GtkWidget *tree_item,
220 g_return_if_fail (tree != NULL);
221 g_return_if_fail (GTK_IS_TREE (tree));
222 g_return_if_fail (tree_item != NULL);
223 g_return_if_fail (GTK_IS_TREE_ITEM (tree_item));
225 nchildren = g_list_length (tree->children);
227 if ((position < 0) || (position > nchildren))
228 position = nchildren;
230 if (position == nchildren)
231 tree->children = g_list_append (tree->children, tree_item);
233 tree->children = g_list_insert (tree->children, tree_item, position);
235 gtk_widget_set_parent (tree_item, GTK_WIDGET (tree));
237 if (GTK_WIDGET_REALIZED (tree_item->parent))
238 gtk_widget_realize (tree_item);
240 if (GTK_WIDGET_VISIBLE (tree_item->parent) && GTK_WIDGET_VISIBLE (tree_item))
242 if (GTK_WIDGET_MAPPED (tree_item->parent))
243 gtk_widget_map (tree_item);
245 gtk_widget_queue_resize (tree_item);
250 gtk_tree_add (GtkContainer *container,
255 g_return_if_fail (container != NULL);
256 g_return_if_fail (GTK_IS_TREE (container));
257 g_return_if_fail (GTK_IS_TREE_ITEM (child));
259 tree = GTK_TREE (container);
261 tree->children = g_list_append (tree->children, child);
263 gtk_widget_set_parent (child, GTK_WIDGET (container));
265 if (GTK_WIDGET_REALIZED (child->parent))
266 gtk_widget_realize (child);
268 if (GTK_WIDGET_VISIBLE (child->parent) && GTK_WIDGET_VISIBLE (child))
270 if (GTK_WIDGET_MAPPED (child->parent))
271 gtk_widget_map (child);
273 gtk_widget_queue_resize (child);
276 if (!tree->selection && (tree->selection_mode == GTK_SELECTION_BROWSE))
277 gtk_tree_select_child (tree, child);
281 gtk_tree_button_press (GtkWidget *widget,
282 GdkEventButton *event)
287 g_return_val_if_fail (widget != NULL, FALSE);
288 g_return_val_if_fail (GTK_IS_TREE (widget), FALSE);
289 g_return_val_if_fail (event != NULL, FALSE);
291 tree = GTK_TREE (widget);
292 item = gtk_get_event_widget ((GdkEvent*) event);
294 while (item && !GTK_IS_TREE_ITEM (item))
297 if (!item || (item->parent != widget))
300 switch(event->button)
303 gtk_tree_select_child (tree, item);
306 if(GTK_TREE_ITEM(item)->subtree) gtk_tree_item_expand(GTK_TREE_ITEM(item));
309 if(GTK_TREE_ITEM(item)->subtree) gtk_tree_item_collapse(GTK_TREE_ITEM(item));
317 gtk_tree_button_release (GtkWidget *widget,
318 GdkEventButton *event)
323 g_return_val_if_fail (widget != NULL, FALSE);
324 g_return_val_if_fail (GTK_IS_TREE (widget), FALSE);
325 g_return_val_if_fail (event != NULL, FALSE);
327 tree = GTK_TREE (widget);
328 item = gtk_get_event_widget ((GdkEvent*) event);
334 gtk_tree_child_position (GtkTree *tree,
341 g_return_val_if_fail (tree != NULL, -1);
342 g_return_val_if_fail (GTK_IS_TREE (tree), -1);
343 g_return_val_if_fail (child != NULL, -1);
346 children = tree->children;
350 if (child == GTK_WIDGET (children->data))
354 children = children->next;
362 gtk_tree_clear_items (GtkTree *tree,
372 g_return_if_fail (tree != NULL);
373 g_return_if_fail (GTK_IS_TREE (tree));
375 nchildren = g_list_length (tree->children);
379 if ((end < 0) || (end > nchildren))
385 tmp_list = g_list_nth (tree->children, start);
388 while (tmp_list && index <= end)
390 widget = tmp_list->data;
391 tmp_list = tmp_list->next;
394 clear_list = g_list_prepend (clear_list, widget);
397 gtk_tree_remove_items (tree, clear_list);
402 gtk_tree_destroy (GtkObject *object)
408 g_return_if_fail (object != NULL);
409 g_return_if_fail (GTK_IS_TREE (object));
411 tree = GTK_TREE (object);
413 children = tree->children;
416 child = children->data;
417 children = children->next;
419 gtk_widget_ref (child);
420 gtk_widget_unparent (child);
421 gtk_widget_destroy (child);
422 gtk_widget_unref (child);
425 g_list_free (tree->children);
426 tree->children = NULL;
428 if (tree->root_tree == tree)
431 for (node = tree->selection; node; node = node->next)
432 gtk_widget_unref ((GtkWidget *)node->data);
433 g_list_free (tree->selection);
434 tree->selection = NULL;
437 if (GTK_OBJECT_CLASS (parent_class)->destroy)
438 (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
442 gtk_tree_expose (GtkWidget *widget,
443 GdkEventExpose *event)
447 GdkEventExpose child_event;
451 g_return_val_if_fail (widget != NULL, FALSE);
452 g_return_val_if_fail (GTK_IS_TREE (widget), FALSE);
453 g_return_val_if_fail (event != NULL, FALSE);
455 if (GTK_WIDGET_DRAWABLE (widget))
457 tree = GTK_TREE (widget);
459 child_event = *event;
461 children = tree->children;
464 child = children->data;
465 children = children->next;
467 if (GTK_WIDGET_NO_WINDOW (child) &&
468 gtk_widget_intersect (child, &event->area, &child_event.area))
469 gtk_widget_event (child, (GdkEvent*) &child_event);
478 gtk_tree_forall (GtkContainer *container,
479 gboolean include_internals,
480 GtkCallback callback,
481 gpointer callback_data)
488 g_return_if_fail (container != NULL);
489 g_return_if_fail (GTK_IS_TREE (container));
490 g_return_if_fail (callback != NULL);
492 tree = GTK_TREE (container);
493 children = tree->children;
497 child = children->data;
498 children = children->next;
500 (* callback) (child, callback_data);
505 gtk_tree_map (GtkWidget *widget)
512 g_return_if_fail (widget != NULL);
513 g_return_if_fail (GTK_IS_TREE (widget));
515 GTK_WIDGET_SET_FLAGS (widget, GTK_MAPPED);
516 tree = GTK_TREE (widget);
518 if(GTK_IS_TREE(widget->parent))
520 /* set root tree for this tree */
521 tree->root_tree = GTK_TREE(widget->parent)->root_tree;
523 tree->level = GTK_TREE(GTK_WIDGET(tree)->parent)->level+1;
524 tree->indent_value = GTK_TREE(GTK_WIDGET(tree)->parent)->indent_value;
525 tree->current_indent = GTK_TREE(GTK_WIDGET(tree)->parent)->current_indent +
527 tree->view_mode = GTK_TREE(GTK_WIDGET(tree)->parent)->view_mode;
528 tree->view_line = GTK_TREE(GTK_WIDGET(tree)->parent)->view_line;
531 tree->root_tree = tree;
533 children = tree->children;
536 child = children->data;
537 children = children->next;
539 if (GTK_WIDGET_VISIBLE (child) &&
540 !GTK_WIDGET_MAPPED (child))
541 gtk_widget_map (child);
543 if (GTK_TREE_ITEM (child)->subtree)
545 child = GTK_WIDGET (GTK_TREE_ITEM (child)->subtree);
547 if (GTK_WIDGET_VISIBLE (child) && !GTK_WIDGET_MAPPED (child))
548 gtk_widget_map (child);
552 gdk_window_show (widget->window);
556 gtk_tree_motion_notify (GtkWidget *widget,
557 GdkEventMotion *event)
559 g_return_val_if_fail (widget != NULL, FALSE);
560 g_return_val_if_fail (GTK_IS_TREE (widget), FALSE);
561 g_return_val_if_fail (event != NULL, FALSE);
564 g_message("gtk_tree_motion_notify\n");
565 #endif /* TREE_DEBUG */
571 gtk_tree_realize (GtkWidget *widget)
573 GdkWindowAttr attributes;
574 gint attributes_mask;
577 g_return_if_fail (widget != NULL);
578 g_return_if_fail (GTK_IS_TREE (widget));
580 GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
582 attributes.window_type = GDK_WINDOW_CHILD;
583 attributes.x = widget->allocation.x;
584 attributes.y = widget->allocation.y;
585 attributes.width = widget->allocation.width;
586 attributes.height = widget->allocation.height;
587 attributes.wclass = GDK_INPUT_OUTPUT;
588 attributes.visual = gtk_widget_get_visual (widget);
589 attributes.colormap = gtk_widget_get_colormap (widget);
590 attributes.event_mask = gtk_widget_get_events (widget) | GDK_EXPOSURE_MASK;
592 attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
594 widget->window = gdk_window_new (gtk_widget_get_parent_window (widget), &attributes, attributes_mask);
595 gdk_window_set_user_data (widget->window, widget);
597 widget->style = gtk_style_attach (widget->style, widget->window);
598 gdk_window_set_background (widget->window,
599 &widget->style->base[GTK_STATE_NORMAL]);
603 gtk_tree_remove_item (GtkTree *container,
608 g_return_if_fail (container != NULL);
609 g_return_if_fail (GTK_IS_TREE (container));
610 g_return_if_fail (widget != NULL);
611 g_return_if_fail (container == GTK_TREE (widget->parent));
613 item_list = g_list_append (NULL, widget);
615 gtk_tree_remove_items (GTK_TREE (container), item_list);
617 g_list_free (item_list);
620 /* used by gtk_tree_remove_items to make the function independant of
621 order in list of items to remove.
622 Sort item bu depth in tree */
624 gtk_tree_sort_item_by_depth(GtkWidget* a, GtkWidget* b)
626 if((GTK_TREE(a->parent)->level) < (GTK_TREE(b->parent)->level))
628 if((GTK_TREE(a->parent)->level) > (GTK_TREE(b->parent)->level))
635 gtk_tree_remove_items (GtkTree *tree,
639 GList *selected_widgets;
645 g_return_if_fail (tree != NULL);
646 g_return_if_fail (GTK_IS_TREE (tree));
649 g_message("+ gtk_tree_remove_items [ tree %#x items list %#x ]\n", (int)tree, (int)items);
650 #endif /* TREE_DEBUG */
652 /* We may not yet be mapped, so we actively have to find our
656 root_tree = tree->root_tree;
659 GtkWidget *tmp = GTK_WIDGET (tree);
660 while (tmp->parent && GTK_IS_TREE (tmp->parent))
663 root_tree = GTK_TREE (tmp);
667 selected_widgets = NULL;
672 g_message("* sort list by depth\n");
673 #endif /* TREE_DEBUG */
679 g_message ("* item [%#x] depth [%d]\n",
681 (int)GTK_TREE(GTK_WIDGET(tmp_list->data)->parent)->level);
682 #endif /* TREE_DEBUG */
684 sorted_list = g_list_insert_sorted(sorted_list,
686 (GCompareFunc)gtk_tree_sort_item_by_depth);
687 tmp_list = g_list_next(tmp_list);
691 /* print sorted list */
692 g_message("* sorted list result\n");
693 tmp_list = sorted_list;
696 g_message("* item [%#x] depth [%d]\n",
698 (int)GTK_TREE(GTK_WIDGET(tmp_list->data)->parent)->level);
699 tmp_list = g_list_next(tmp_list);
701 #endif /* TREE_DEBUG */
704 g_message("* scan sorted list\n");
705 #endif /* TREE_DEBUG */
707 tmp_list = sorted_list;
710 widget = tmp_list->data;
711 tmp_list = tmp_list->next;
714 g_message("* item [%#x] subtree [%#x]\n",
715 (int)widget, (int)GTK_TREE_ITEM_SUBTREE(widget));
716 #endif /* TREE_DEBUG */
718 /* get real owner of this widget */
719 real_tree = GTK_TREE(widget->parent);
721 g_message("* subtree having this widget [%#x]\n", (int)real_tree);
722 #endif /* TREE_DEBUG */
725 if (widget->state == GTK_STATE_SELECTED)
727 selected_widgets = g_list_prepend (selected_widgets, widget);
729 g_message("* selected widget - adding it in selected list [%#x]\n",
730 (int)selected_widgets);
731 #endif /* TREE_DEBUG */
734 /* remove this item from its real parent */
736 g_message("* remove widget from its owner tree\n");
737 #endif /* TREE_DEBUG */
738 real_tree->children = g_list_remove (real_tree->children, widget);
740 /* remove subtree associate at this item if it exist */
741 if(GTK_TREE_ITEM(widget)->subtree)
744 g_message("* remove subtree associate at this item [%#x]\n",
745 (int) GTK_TREE_ITEM(widget)->subtree);
746 #endif /* TREE_DEBUG */
747 if (GTK_WIDGET_MAPPED (GTK_TREE_ITEM(widget)->subtree))
748 gtk_widget_unmap (GTK_TREE_ITEM(widget)->subtree);
750 gtk_widget_unparent (GTK_TREE_ITEM(widget)->subtree);
751 GTK_TREE_ITEM(widget)->subtree = NULL;
754 /* really remove widget for this item */
756 g_message("* unmap and unparent widget [%#x]\n", (int)widget);
757 #endif /* TREE_DEBUG */
758 if (GTK_WIDGET_MAPPED (widget))
759 gtk_widget_unmap (widget);
761 gtk_widget_unparent (widget);
763 /* delete subtree if there is no children in it */
764 if(real_tree->children == NULL &&
765 real_tree != root_tree)
768 g_message("* owner tree don't have children ... destroy it\n");
769 #endif /* TREE_DEBUG */
770 gtk_tree_item_remove_subtree(GTK_TREE_ITEM(real_tree->tree_owner));
774 g_message("* next item in list\n");
775 #endif /* TREE_DEBUG */
778 if (selected_widgets)
781 g_message("* scan selected item list\n");
782 #endif /* TREE_DEBUG */
783 tmp_list = selected_widgets;
786 widget = tmp_list->data;
787 tmp_list = tmp_list->next;
790 g_message("* widget [%#x] subtree [%#x]\n",
791 (int)widget, (int)GTK_TREE_ITEM_SUBTREE(widget));
792 #endif /* TREE_DEBUG */
794 /* remove widget of selection */
795 root_tree->selection = g_list_remove (root_tree->selection, widget);
797 /* unref it to authorize is destruction */
798 gtk_widget_unref (widget);
801 /* emit only one selection_changed signal */
802 gtk_signal_emit (GTK_OBJECT (root_tree),
803 tree_signals[SELECTION_CHANGED]);
807 g_message("* free selected_widgets list\n");
808 #endif /* TREE_DEBUG */
809 g_list_free (selected_widgets);
810 g_list_free (sorted_list);
812 if (root_tree->children && !root_tree->selection &&
813 (root_tree->selection_mode == GTK_SELECTION_BROWSE))
816 g_message("* BROWSE mode, select another item\n");
817 #endif /* TREE_DEBUG */
818 widget = root_tree->children->data;
819 gtk_tree_select_child (root_tree, widget);
822 if (GTK_WIDGET_VISIBLE (root_tree))
825 g_message("* query queue resizing for root_tree\n");
826 #endif /* TREE_DEBUG */
827 gtk_widget_queue_resize (GTK_WIDGET (root_tree));
832 gtk_tree_select_child (GtkTree *tree,
833 GtkWidget *tree_item)
835 g_return_if_fail (tree != NULL);
836 g_return_if_fail (GTK_IS_TREE (tree));
837 g_return_if_fail (tree_item != NULL);
838 g_return_if_fail (GTK_IS_TREE_ITEM (tree_item));
840 gtk_signal_emit (GTK_OBJECT (tree), tree_signals[SELECT_CHILD], tree_item);
844 gtk_tree_select_item (GtkTree *tree,
849 g_return_if_fail (tree != NULL);
850 g_return_if_fail (GTK_IS_TREE (tree));
852 tmp_list = g_list_nth (tree->children, item);
854 gtk_tree_select_child (tree, GTK_WIDGET (tmp_list->data));
859 gtk_tree_size_allocate (GtkWidget *widget,
860 GtkAllocation *allocation)
863 GtkWidget *child, *subtree;
864 GtkAllocation child_allocation;
868 g_return_if_fail (widget != NULL);
869 g_return_if_fail (GTK_IS_TREE (widget));
870 g_return_if_fail (allocation != NULL);
872 tree = GTK_TREE (widget);
874 widget->allocation = *allocation;
875 if (GTK_WIDGET_REALIZED (widget))
876 gdk_window_move_resize (widget->window,
877 allocation->x, allocation->y,
878 allocation->width, allocation->height);
882 child_allocation.x = GTK_CONTAINER (tree)->border_width;
883 child_allocation.y = GTK_CONTAINER (tree)->border_width;
884 child_allocation.width = MAX (1, (gint)allocation->width - child_allocation.x * 2);
886 children = tree->children;
890 child = children->data;
891 children = children->next;
893 if (GTK_WIDGET_VISIBLE (child))
895 GtkRequisition child_requisition;
896 gtk_widget_get_child_requisition (child, &child_requisition);
898 child_allocation.height = child_requisition.height;
900 gtk_widget_size_allocate (child, &child_allocation);
902 child_allocation.y += child_allocation.height;
904 if((subtree = GTK_TREE_ITEM(child)->subtree))
905 if(GTK_WIDGET_VISIBLE (subtree))
907 child_allocation.height = subtree->requisition.height;
908 gtk_widget_size_allocate (subtree, &child_allocation);
909 child_allocation.y += child_allocation.height;
918 gtk_tree_size_request (GtkWidget *widget,
919 GtkRequisition *requisition)
922 GtkWidget *child, *subtree;
924 GtkRequisition child_requisition;
927 g_return_if_fail (widget != NULL);
928 g_return_if_fail (GTK_IS_TREE (widget));
929 g_return_if_fail (requisition != NULL);
931 tree = GTK_TREE (widget);
932 requisition->width = 0;
933 requisition->height = 0;
935 children = tree->children;
938 child = children->data;
939 children = children->next;
941 if (GTK_WIDGET_VISIBLE (child))
943 gtk_widget_size_request (child, &child_requisition);
945 requisition->width = MAX (requisition->width, child_requisition.width);
946 requisition->height += child_requisition.height;
948 if((subtree = GTK_TREE_ITEM(child)->subtree) &&
949 GTK_WIDGET_VISIBLE (subtree))
951 gtk_widget_size_request (subtree, &child_requisition);
953 requisition->width = MAX (requisition->width,
954 child_requisition.width);
956 requisition->height += child_requisition.height;
961 requisition->width += GTK_CONTAINER (tree)->border_width * 2;
962 requisition->height += GTK_CONTAINER (tree)->border_width * 2;
964 requisition->width = MAX (requisition->width, 1);
965 requisition->height = MAX (requisition->height, 1);
970 gtk_tree_unmap (GtkWidget *widget)
973 g_return_if_fail (widget != NULL);
974 g_return_if_fail (GTK_IS_TREE (widget));
976 GTK_WIDGET_UNSET_FLAGS (widget, GTK_MAPPED);
977 gdk_window_hide (widget->window);
982 gtk_tree_unselect_child (GtkTree *tree,
983 GtkWidget *tree_item)
985 g_return_if_fail (tree != NULL);
986 g_return_if_fail (GTK_IS_TREE (tree));
987 g_return_if_fail (tree_item != NULL);
988 g_return_if_fail (GTK_IS_TREE_ITEM (tree_item));
990 gtk_signal_emit (GTK_OBJECT (tree), tree_signals[UNSELECT_CHILD], tree_item);
994 gtk_tree_unselect_item (GtkTree *tree,
999 g_return_if_fail (tree != NULL);
1000 g_return_if_fail (GTK_IS_TREE (tree));
1002 tmp_list = g_list_nth (tree->children, item);
1004 gtk_tree_unselect_child (tree, GTK_WIDGET (tmp_list->data));
1009 gtk_real_tree_select_child (GtkTree *tree,
1012 GList *selection, *root_selection;
1014 GtkWidget *tmp_item;
1016 g_return_if_fail (tree != NULL);
1017 g_return_if_fail (GTK_IS_TREE (tree));
1018 g_return_if_fail (child != NULL);
1019 g_return_if_fail (GTK_IS_TREE_ITEM (child));
1021 if (!tree->root_tree)
1023 g_warning (G_STRLOC ": unable to select a child in a tree prior to realization");
1027 root_selection = tree->root_tree->selection;
1029 switch (tree->root_tree->selection_mode)
1031 case GTK_SELECTION_SINGLE:
1033 selection = root_selection;
1035 /* remove old selection list */
1038 tmp_item = selection->data;
1040 if (tmp_item != child)
1042 gtk_tree_item_deselect (GTK_TREE_ITEM (tmp_item));
1044 tmp_list = selection;
1045 selection = selection->next;
1047 root_selection = g_list_remove_link (root_selection, tmp_list);
1048 gtk_widget_unref (tmp_item);
1050 g_list_free (tmp_list);
1053 selection = selection->next;
1056 if (child->state == GTK_STATE_NORMAL)
1058 gtk_tree_item_select (GTK_TREE_ITEM (child));
1059 root_selection = g_list_prepend (root_selection, child);
1060 gtk_widget_ref (child);
1062 else if (child->state == GTK_STATE_SELECTED)
1064 gtk_tree_item_deselect (GTK_TREE_ITEM (child));
1065 root_selection = g_list_remove (root_selection, child);
1066 gtk_widget_unref (child);
1069 tree->root_tree->selection = root_selection;
1071 gtk_signal_emit (GTK_OBJECT (tree->root_tree),
1072 tree_signals[SELECTION_CHANGED]);
1076 case GTK_SELECTION_BROWSE:
1077 selection = root_selection;
1081 tmp_item = selection->data;
1083 if (tmp_item != child)
1085 gtk_tree_item_deselect (GTK_TREE_ITEM (tmp_item));
1087 tmp_list = selection;
1088 selection = selection->next;
1090 root_selection = g_list_remove_link (root_selection, tmp_list);
1091 gtk_widget_unref (tmp_item);
1093 g_list_free (tmp_list);
1096 selection = selection->next;
1099 tree->root_tree->selection = root_selection;
1101 if (child->state == GTK_STATE_NORMAL)
1103 gtk_tree_item_select (GTK_TREE_ITEM (child));
1104 root_selection = g_list_prepend (root_selection, child);
1105 gtk_widget_ref (child);
1106 tree->root_tree->selection = root_selection;
1107 gtk_signal_emit (GTK_OBJECT (tree->root_tree),
1108 tree_signals[SELECTION_CHANGED]);
1112 case GTK_SELECTION_MULTIPLE:
1113 if (child->state == GTK_STATE_NORMAL)
1115 gtk_tree_item_select (GTK_TREE_ITEM (child));
1116 root_selection = g_list_prepend (root_selection, child);
1117 gtk_widget_ref (child);
1118 tree->root_tree->selection = root_selection;
1119 gtk_signal_emit (GTK_OBJECT (tree->root_tree),
1120 tree_signals[SELECTION_CHANGED]);
1122 else if (child->state == GTK_STATE_SELECTED)
1124 gtk_tree_item_deselect (GTK_TREE_ITEM (child));
1125 root_selection = g_list_remove (root_selection, child);
1126 gtk_widget_unref (child);
1127 tree->root_tree->selection = root_selection;
1128 gtk_signal_emit (GTK_OBJECT (tree->root_tree),
1129 tree_signals[SELECTION_CHANGED]);
1133 case GTK_SELECTION_EXTENDED:
1139 gtk_real_tree_unselect_child (GtkTree *tree,
1142 g_return_if_fail (tree != NULL);
1143 g_return_if_fail (GTK_IS_TREE (tree));
1144 g_return_if_fail (child != NULL);
1145 g_return_if_fail (GTK_IS_TREE_ITEM (child));
1147 switch (tree->selection_mode)
1149 case GTK_SELECTION_SINGLE:
1150 case GTK_SELECTION_MULTIPLE:
1151 case GTK_SELECTION_BROWSE:
1152 if (child->state == GTK_STATE_SELECTED)
1154 GtkTree* root_tree = GTK_TREE_ROOT_TREE(tree);
1155 gtk_tree_item_deselect (GTK_TREE_ITEM (child));
1156 root_tree->selection = g_list_remove (root_tree->selection, child);
1157 gtk_widget_unref (child);
1158 gtk_signal_emit (GTK_OBJECT (tree->root_tree),
1159 tree_signals[SELECTION_CHANGED]);
1163 case GTK_SELECTION_EXTENDED:
1169 gtk_tree_set_selection_mode (GtkTree *tree,
1170 GtkSelectionMode mode)
1172 g_return_if_fail (tree != NULL);
1173 g_return_if_fail (GTK_IS_TREE (tree));
1175 tree->selection_mode = mode;
1179 gtk_tree_set_view_mode (GtkTree *tree,
1180 GtkTreeViewMode mode)
1182 g_return_if_fail (tree != NULL);
1183 g_return_if_fail (GTK_IS_TREE (tree));
1185 tree->view_mode = mode;
1189 gtk_tree_set_view_lines (GtkTree *tree,
1192 g_return_if_fail (tree != NULL);
1193 g_return_if_fail (GTK_IS_TREE (tree));
1195 tree->view_line = flag;