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 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.
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.
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.
19 #include "gtktreeitem.h"
21 #include "gtksignal.h"
31 typedef void (*GtkTreeSignal) (GtkObject *object,
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,
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,
58 static void gtk_tree_foreach (GtkContainer *container,
60 gpointer callback_data);
62 static void gtk_real_tree_select_child (GtkTree *tree,
64 static void gtk_real_tree_unselect_child (GtkTree *tree,
67 static void gtk_tree_marshal_signal (GtkObject *object,
72 static GtkContainerClass *parent_class = NULL;
73 static gint tree_signals[LAST_SIGNAL] = { 0 };
78 static guint tree_type = 0;
82 GtkTypeInfo tree_info =
86 sizeof (GtkTreeClass),
87 (GtkClassInitFunc) gtk_tree_class_init,
88 (GtkObjectInitFunc) gtk_tree_init,
93 tree_type = gtk_type_unique (gtk_container_get_type (), &tree_info);
100 gtk_tree_class_init (GtkTreeClass *class)
102 GtkObjectClass *object_class;
103 GtkWidgetClass *widget_class;
104 GtkContainerClass *container_class;
106 object_class = (GtkObjectClass*) class;
107 widget_class = (GtkWidgetClass*) class;
108 container_class = (GtkContainerClass*) class;
110 parent_class = gtk_type_class (gtk_container_get_type ());
112 tree_signals[SELECTION_CHANGED] =
113 gtk_signal_new ("selection_changed",
116 GTK_SIGNAL_OFFSET (GtkTreeClass, selection_changed),
117 gtk_signal_default_marshaller,
119 tree_signals[SELECT_CHILD] =
120 gtk_signal_new ("select_child",
123 GTK_SIGNAL_OFFSET (GtkTreeClass, select_child),
124 gtk_tree_marshal_signal,
127 tree_signals[UNSELECT_CHILD] =
128 gtk_signal_new ("unselect_child",
131 GTK_SIGNAL_OFFSET (GtkTreeClass, unselect_child),
132 gtk_tree_marshal_signal,
136 gtk_object_class_add_signals (object_class, tree_signals, LAST_SIGNAL);
138 object_class->destroy = gtk_tree_destroy;
140 widget_class->map = gtk_tree_map;
141 widget_class->unmap = gtk_tree_unmap;
142 widget_class->realize = gtk_tree_realize;
143 widget_class->draw = gtk_tree_draw;
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 = (void *) gtk_tree_remove_item;
153 container_class->foreach = gtk_tree_foreach;
155 class->selection_changed = NULL;
156 class->select_child = gtk_real_tree_select_child;
157 class->unselect_child = gtk_real_tree_unselect_child;
161 gtk_tree_init (GtkTree *tree)
163 tree->children = NULL;
164 tree->root_tree = NULL;
165 tree->selection = NULL;
166 tree->tree_owner = NULL;
167 tree->selection_mode = GTK_SELECTION_SINGLE;
168 tree->indent_value = 9;
169 tree->current_indent = 0;
171 tree->view_mode = GTK_TREE_VIEW_LINE;
178 return GTK_WIDGET (gtk_type_new (gtk_tree_get_type ()));
182 gtk_tree_append (GtkTree *tree,
186 g_return_if_fail (tree != NULL);
187 g_return_if_fail (GTK_IS_TREE_ITEM (child));
189 gtk_tree_insert(tree, child, -1);
193 gtk_tree_prepend (GtkTree *tree,
196 g_return_if_fail (tree != NULL);
197 g_return_if_fail (GTK_IS_TREE_ITEM (child));
199 gtk_tree_insert(tree, child, 0);
204 gtk_tree_insert (GtkTree *tree,
210 g_return_if_fail (tree != NULL || child != NULL);
211 g_return_if_fail (GTK_IS_TREE_ITEM(child));
213 /* set parent widget to item */
214 gtk_widget_set_parent (child, GTK_WIDGET (tree));
216 if (GTK_WIDGET_VISIBLE (child->parent))
218 if (GTK_WIDGET_REALIZED (child->parent) &&
219 !GTK_WIDGET_REALIZED (child))
220 gtk_widget_realize (child);
222 if (GTK_WIDGET_MAPPED (child->parent) &&
223 !GTK_WIDGET_MAPPED (child))
224 gtk_widget_map (child);
227 nchildren = g_list_length (tree->children);
229 if ((position < 0) || (position > nchildren))
230 position = nchildren;
232 if (position == nchildren)
234 tree->children = g_list_append(tree->children, child);
238 tree->children = g_list_insert(tree->children, child, position);
241 if (GTK_WIDGET_VISIBLE (tree))
242 gtk_widget_queue_resize (GTK_WIDGET (tree));
247 gtk_tree_add (GtkContainer *container,
252 g_return_if_fail (container != NULL);
253 g_return_if_fail (GTK_IS_TREE (container));
254 g_return_if_fail (widget != NULL);
256 tree = GTK_TREE (container);
258 gtk_widget_set_parent (widget, GTK_WIDGET (container));
259 if (GTK_WIDGET_VISIBLE (widget->parent))
261 if (GTK_WIDGET_REALIZED (widget->parent) &&
262 !GTK_WIDGET_REALIZED (widget))
263 gtk_widget_realize (widget);
265 if (GTK_WIDGET_MAPPED (widget->parent) &&
266 !GTK_WIDGET_MAPPED (widget))
267 gtk_widget_map (widget);
270 tree->children = g_list_append (tree->children, widget);
272 if (!tree->selection && (tree->selection_mode == GTK_SELECTION_BROWSE))
274 gtk_tree_select_child (tree, widget);
277 if (GTK_WIDGET_VISIBLE (widget) && GTK_WIDGET_VISIBLE (container))
278 gtk_widget_queue_resize (widget);
283 gtk_tree_button_press (GtkWidget *widget,
284 GdkEventButton *event)
289 g_return_val_if_fail (widget != NULL, FALSE);
290 g_return_val_if_fail (GTK_IS_TREE (widget), FALSE);
291 g_return_val_if_fail (event != NULL, FALSE);
293 tree = GTK_TREE (widget);
294 item = gtk_get_event_widget ((GdkEvent*) event);
296 while (!gtk_type_is_a (GTK_WIDGET_TYPE (item), gtk_tree_item_get_type ()))
299 switch(event->button)
302 gtk_tree_select_child (tree, item);
305 if(GTK_TREE_ITEM(item)->subtree) gtk_tree_item_expand(GTK_TREE_ITEM(item));
308 if(GTK_TREE_ITEM(item)->subtree) gtk_tree_item_collapse(GTK_TREE_ITEM(item));
316 gtk_tree_button_release (GtkWidget *widget,
317 GdkEventButton *event)
322 g_return_val_if_fail (widget != NULL, FALSE);
323 g_return_val_if_fail (GTK_IS_TREE (widget), FALSE);
324 g_return_val_if_fail (event != NULL, FALSE);
326 tree = GTK_TREE (widget);
327 item = gtk_get_event_widget ((GdkEvent*) event);
333 gtk_tree_child_position (GtkTree *tree,
340 g_return_val_if_fail (tree != NULL, -1);
341 g_return_val_if_fail (GTK_IS_TREE (tree), -1);
342 g_return_val_if_fail (child != NULL, -1);
345 children = tree->children;
349 if (child == GTK_WIDGET (children->data))
353 children = children->next;
361 gtk_tree_clear_items (GtkTree *tree,
365 g_return_if_fail (tree != NULL);
366 g_return_if_fail (GTK_IS_TREE (tree));
371 gtk_tree_destroy (GtkObject *object)
377 g_return_if_fail (object != NULL);
378 g_return_if_fail (GTK_IS_TREE (object));
380 tree = GTK_TREE (object);
382 children = tree->children;
385 child = children->data;
386 children = children->next;
388 gtk_widget_ref (child);
389 gtk_widget_unparent (child);
390 gtk_widget_destroy (child);
391 gtk_widget_unref (child);
394 g_list_free (tree->children);
395 tree->children = NULL;
397 if (tree->root_tree == tree)
400 for (node = tree->selection; node; node = node->next)
401 gtk_widget_unref ((GtkWidget *)node->data);
402 g_list_free (tree->selection);
403 tree->selection = NULL;
406 if (GTK_OBJECT_CLASS (parent_class)->destroy)
407 (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
411 gtk_tree_draw (GtkWidget *widget,
417 GdkRectangle child_area;
421 g_return_if_fail (widget != NULL);
422 g_return_if_fail (GTK_IS_TREE (widget));
423 g_return_if_fail (area != NULL);
425 if (GTK_WIDGET_DRAWABLE (widget))
427 tree = GTK_TREE (widget);
429 children = tree->children;
432 child = children->data;
433 children = children->next;
435 if (gtk_widget_intersect (child, area, &child_area))
436 gtk_widget_draw (child, &child_area);
438 if((subtree = GTK_TREE_ITEM(child)->subtree) &&
439 GTK_WIDGET_VISIBLE(subtree) &&
440 gtk_widget_intersect (subtree, area, &child_area))
441 gtk_widget_draw (subtree, &child_area);
448 gtk_tree_expose (GtkWidget *widget,
449 GdkEventExpose *event)
453 GdkEventExpose child_event;
457 g_return_val_if_fail (widget != NULL, FALSE);
458 g_return_val_if_fail (GTK_IS_TREE (widget), FALSE);
459 g_return_val_if_fail (event != NULL, FALSE);
461 if (GTK_WIDGET_DRAWABLE (widget))
463 tree = GTK_TREE (widget);
465 child_event = *event;
467 children = tree->children;
470 child = children->data;
471 children = children->next;
473 if (GTK_WIDGET_NO_WINDOW (child) &&
474 gtk_widget_intersect (child, &event->area, &child_event.area))
475 gtk_widget_event (child, (GdkEvent*) &child_event);
484 gtk_tree_foreach (GtkContainer *container,
485 GtkCallback callback,
486 gpointer callback_data)
493 g_return_if_fail (container != NULL);
494 g_return_if_fail (GTK_IS_TREE (container));
495 g_return_if_fail (callback != NULL);
497 tree = GTK_TREE (container);
498 children = tree->children;
502 child = children->data;
503 children = children->next;
505 (* callback) (child, callback_data);
507 if(GTK_TREE_ITEM(child)->subtree)
508 (* callback)(GTK_TREE_ITEM(child)->subtree, callback_data);
513 gtk_tree_map (GtkWidget *widget)
520 g_return_if_fail (widget != NULL);
521 g_return_if_fail (GTK_IS_TREE (widget));
523 GTK_WIDGET_SET_FLAGS (widget, GTK_MAPPED);
524 tree = GTK_TREE (widget);
526 gdk_window_show (widget->window);
528 if(GTK_IS_TREE(widget->parent))
530 /* set root tree for this tree */
531 tree->root_tree = GTK_TREE(widget->parent)->root_tree;
533 tree->level = GTK_TREE(GTK_WIDGET(tree)->parent)->level+1;
534 tree->indent_value = GTK_TREE(GTK_WIDGET(tree)->parent)->indent_value;
535 tree->current_indent = GTK_TREE(GTK_WIDGET(tree)->parent)->current_indent +
537 tree->view_mode = GTK_TREE(GTK_WIDGET(tree)->parent)->view_mode;
538 tree->view_line = GTK_TREE(GTK_WIDGET(tree)->parent)->view_line;
541 tree->root_tree = tree;
543 children = tree->children;
546 child = children->data;
547 children = children->next;
549 if (GTK_WIDGET_VISIBLE (child) &&
550 !GTK_WIDGET_MAPPED (child))
551 gtk_widget_map (child);
553 if ((child = GTK_WIDGET(GTK_TREE_ITEM(child)->subtree)) &&
554 GTK_WIDGET_VISIBLE (child) &&
555 !GTK_WIDGET_MAPPED (child))
556 gtk_widget_map (child);
561 gtk_tree_marshal_signal (GtkObject *object,
568 rfunc = (GtkTreeSignal) func;
570 (* rfunc) (object, GTK_VALUE_OBJECT (args[0]), func_data);
574 gtk_tree_motion_notify (GtkWidget *widget,
575 GdkEventMotion *event)
577 g_return_val_if_fail (widget != NULL, FALSE);
578 g_return_val_if_fail (GTK_IS_TREE (widget), FALSE);
579 g_return_val_if_fail (event != NULL, FALSE);
581 g_print("gtk_tree_motion_notify\n");
587 gtk_tree_realize (GtkWidget *widget)
589 GdkWindowAttr attributes;
590 gint attributes_mask;
593 g_return_if_fail (widget != NULL);
594 g_return_if_fail (GTK_IS_TREE (widget));
596 GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
598 attributes.window_type = GDK_WINDOW_CHILD;
599 attributes.x = widget->allocation.x;
600 attributes.y = widget->allocation.y;
601 attributes.width = widget->allocation.width;
602 attributes.height = widget->allocation.height;
603 attributes.wclass = GDK_INPUT_OUTPUT;
604 attributes.visual = gtk_widget_get_visual (widget);
605 attributes.colormap = gtk_widget_get_colormap (widget);
606 attributes.event_mask = GDK_EXPOSURE_MASK;
608 attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
610 widget->window = gdk_window_new (gtk_widget_get_parent_window (widget), &attributes, attributes_mask);
611 gdk_window_set_user_data (widget->window, widget);
613 widget->style = gtk_style_attach (widget->style, widget->window);
614 gdk_window_set_background (widget->window,
615 &widget->style->base[GTK_STATE_NORMAL]);
620 gtk_tree_remove_item (GtkTree *container,
625 g_return_if_fail (container != NULL);
626 g_return_if_fail (GTK_IS_TREE (container));
627 g_return_if_fail (widget != NULL);
628 g_return_if_fail (container == GTK_TREE (widget->parent));
630 item_list = g_list_alloc ();
631 item_list->data = widget;
633 gtk_tree_remove_items (GTK_TREE (container), item_list);
635 g_list_free (item_list);
639 gtk_tree_remove_items (GtkTree *tree,
643 GList *selected_widgets;
645 GtkTree *real_tree, *root_tree;
647 g_return_if_fail (tree != NULL);
648 g_return_if_fail (GTK_IS_TREE (tree));
650 root_tree = GTK_TREE(GTK_TREE_ROOT_TREE(tree));
652 selected_widgets = NULL;
657 widget = tmp_list->data;
658 tmp_list = tmp_list->next;
660 /* get real owner of this widget */
661 real_tree = GTK_TREE(widget->parent);
663 if (widget->state == GTK_STATE_SELECTED)
664 selected_widgets = g_list_prepend (selected_widgets, widget);
666 /* remove this item of his real parent */
667 real_tree->children = g_list_remove (real_tree->children, widget);
669 /* delete subtree if there is no children in it */
670 if(real_tree->children == NULL &&
671 real_tree != root_tree)
673 gtk_tree_item_remove_subtree(GTK_TREE_ITEM(real_tree->tree_owner));
676 /* remove subtree associate at this item if it exist */
677 if(GTK_TREE_ITEM(widget)->subtree)
679 if (GTK_WIDGET_MAPPED (GTK_TREE_ITEM(widget)->subtree))
680 gtk_widget_unmap (GTK_TREE_ITEM(widget)->subtree);
682 gtk_widget_unparent (GTK_TREE_ITEM(widget)->subtree);
683 GTK_TREE_ITEM(widget)->subtree = NULL;
686 /* remove really widget for this item */
687 if (GTK_WIDGET_MAPPED (widget))
688 gtk_widget_unmap (widget);
690 gtk_widget_unparent (widget);
693 if (selected_widgets)
695 tmp_list = selected_widgets;
698 widget = tmp_list->data;
699 tmp_list = tmp_list->next;
701 gtk_tree_unselect_child (tree, widget);
705 g_list_free (selected_widgets);
707 if (root_tree->children && !root_tree->selection &&
708 (root_tree->selection_mode == GTK_SELECTION_BROWSE))
710 widget = root_tree->children->data;
711 gtk_tree_select_child (root_tree, widget);
714 if (GTK_WIDGET_VISIBLE (root_tree))
715 gtk_widget_queue_resize (GTK_WIDGET (root_tree));
719 gtk_tree_select_child (GtkTree *tree,
723 gtk_signal_emit (GTK_OBJECT (tree), tree_signals[SELECT_CHILD], child);
728 gtk_tree_select_item (GtkTree *tree,
734 g_return_if_fail (tree != NULL);
735 g_return_if_fail (GTK_IS_TREE (tree));
737 tmp_list = g_list_nth (tree->children, item);
739 gtk_tree_select_child (tree, GTK_WIDGET (tmp_list->data));
744 gtk_tree_size_allocate (GtkWidget *widget,
745 GtkAllocation *allocation)
748 GtkWidget *child, *subtree;
749 GtkAllocation child_allocation;
753 g_return_if_fail (widget != NULL);
754 g_return_if_fail (GTK_IS_TREE (widget));
755 g_return_if_fail (allocation != NULL);
757 tree = GTK_TREE (widget);
759 widget->allocation = *allocation;
760 if (GTK_WIDGET_REALIZED (widget))
761 gdk_window_move_resize (widget->window,
762 allocation->x, allocation->y,
763 allocation->width, allocation->height);
767 child_allocation.x = GTK_CONTAINER (tree)->border_width;
768 child_allocation.y = GTK_CONTAINER (tree)->border_width;
769 child_allocation.width = allocation->width - child_allocation.x * 2;
771 children = tree->children;
775 child = children->data;
776 children = children->next;
778 if (GTK_WIDGET_VISIBLE (child))
780 child_allocation.height = child->requisition.height;
782 gtk_widget_size_allocate (child, &child_allocation);
784 child_allocation.y += child_allocation.height;
786 if((subtree = GTK_TREE_ITEM(child)->subtree))
787 if(GTK_WIDGET_VISIBLE (subtree))
789 child_allocation.height = subtree->requisition.height;
790 gtk_widget_size_allocate (subtree, &child_allocation);
791 child_allocation.y += child_allocation.height;
800 gtk_tree_size_request (GtkWidget *widget,
801 GtkRequisition *requisition)
804 GtkWidget *child, *subtree;
808 g_return_if_fail (widget != NULL);
809 g_return_if_fail (GTK_IS_TREE (widget));
810 g_return_if_fail (requisition != NULL);
812 tree = GTK_TREE (widget);
813 requisition->width = 0;
814 requisition->height = 0;
816 children = tree->children;
819 child = children->data;
820 children = children->next;
822 if (GTK_WIDGET_VISIBLE (child))
824 gtk_widget_size_request (child, &child->requisition);
826 requisition->width = MAX (requisition->width, child->requisition.width);
827 requisition->height += child->requisition.height;
829 if((subtree = GTK_TREE_ITEM(child)->subtree) &&
830 GTK_WIDGET_VISIBLE (subtree))
832 gtk_widget_size_request (subtree, &subtree->requisition);
834 requisition->width = MAX (requisition->width,
835 subtree->requisition.width);
837 requisition->height += subtree->requisition.height;
842 requisition->width += GTK_CONTAINER (tree)->border_width * 2;
843 requisition->height += GTK_CONTAINER (tree)->border_width * 2;
845 requisition->width = MAX (requisition->width, 1);
846 requisition->height = MAX (requisition->height, 1);
851 gtk_tree_unmap (GtkWidget *widget)
854 g_return_if_fail (widget != NULL);
855 g_return_if_fail (GTK_IS_TREE (widget));
857 GTK_WIDGET_UNSET_FLAGS (widget, GTK_MAPPED);
858 gdk_window_hide (widget->window);
863 gtk_tree_unselect_child (GtkTree *tree,
866 gtk_signal_emit (GTK_OBJECT (tree), tree_signals[UNSELECT_CHILD], child);
870 gtk_tree_unselect_item (GtkTree *tree,
876 g_return_if_fail (tree != NULL);
877 g_return_if_fail (GTK_IS_TREE (tree));
879 tmp_list = g_list_nth (tree->children, item);
881 gtk_tree_unselect_child (tree, GTK_WIDGET (tmp_list->data));
886 gtk_real_tree_select_child (GtkTree *tree,
889 GList *selection, *root_selection;
894 g_return_if_fail (tree != NULL);
895 g_return_if_fail (GTK_IS_TREE (tree));
896 g_return_if_fail (child != NULL);
897 g_return_if_fail (GTK_IS_TREE_ITEM (child));
899 root_selection = tree->root_tree->selection;
901 switch (tree->root_tree->selection_mode)
903 case GTK_SELECTION_SINGLE:
905 selection = root_selection;
907 /* remove old selection list */
910 tmp_item = selection->data;
912 if (tmp_item != child)
914 gtk_tree_item_deselect (GTK_TREE_ITEM (tmp_item));
916 tmp_list = selection;
917 selection = selection->next;
919 root_selection = g_list_remove_link (root_selection, tmp_list);
920 gtk_widget_unref (tmp_item);
922 g_list_free (tmp_list);
925 selection = selection->next;
928 if (child->state == GTK_STATE_NORMAL)
930 gtk_tree_item_select (GTK_TREE_ITEM (child));
931 root_selection = g_list_prepend (root_selection, child);
932 gtk_widget_ref (child);
934 else if (child->state == GTK_STATE_SELECTED)
936 gtk_tree_item_deselect (GTK_TREE_ITEM (child));
937 root_selection = g_list_remove (root_selection, child);
938 gtk_widget_unref (child);
941 tree->root_tree->selection = root_selection;
943 gtk_signal_emit (GTK_OBJECT (tree->root_tree),
944 tree_signals[SELECTION_CHANGED]);
948 case GTK_SELECTION_BROWSE:
949 selection = root_selection;
953 tmp_item = selection->data;
955 if (tmp_item != child)
957 gtk_tree_item_deselect (GTK_TREE_ITEM (tmp_item));
959 tmp_list = selection;
960 selection = selection->next;
962 root_selection = g_list_remove_link (root_selection, tmp_list);
963 gtk_widget_unref (tmp_item);
965 g_list_free (tmp_list);
968 selection = selection->next;
971 tree->root_tree->selection = root_selection;
973 if (child->state == GTK_STATE_NORMAL)
975 gtk_tree_item_select (GTK_TREE_ITEM (child));
976 root_selection = g_list_prepend (root_selection, child);
977 gtk_widget_ref (child);
978 tree->root_tree->selection = root_selection;
979 gtk_signal_emit (GTK_OBJECT (tree->root_tree),
980 tree_signals[SELECTION_CHANGED]);
984 case GTK_SELECTION_MULTIPLE:
985 if (child->state == GTK_STATE_NORMAL)
987 gtk_tree_item_select (GTK_TREE_ITEM (child));
988 root_selection = g_list_prepend (root_selection, child);
989 gtk_widget_ref (child);
990 tree->root_tree->selection = root_selection;
991 gtk_signal_emit (GTK_OBJECT (tree->root_tree),
992 tree_signals[SELECTION_CHANGED]);
994 else if (child->state == GTK_STATE_SELECTED)
996 gtk_tree_item_deselect (GTK_TREE_ITEM (child));
997 root_selection = g_list_remove (root_selection, child);
998 gtk_widget_unref (child);
999 tree->root_tree->selection = root_selection;
1000 gtk_signal_emit (GTK_OBJECT (tree->root_tree),
1001 tree_signals[SELECTION_CHANGED]);
1005 case GTK_SELECTION_EXTENDED:
1011 gtk_real_tree_unselect_child (GtkTree *tree,
1015 g_return_if_fail (tree != NULL);
1016 g_return_if_fail (GTK_IS_TREE (tree));
1017 g_return_if_fail (child != NULL);
1018 g_return_if_fail (GTK_IS_TREE_ITEM (child));
1020 switch (tree->selection_mode)
1022 case GTK_SELECTION_SINGLE:
1023 case GTK_SELECTION_MULTIPLE:
1024 case GTK_SELECTION_BROWSE:
1025 if (child->state == GTK_STATE_SELECTED)
1027 GtkTree* root_tree = GTK_TREE_ROOT_TREE(tree);
1028 gtk_tree_item_deselect (GTK_TREE_ITEM (child));
1029 root_tree->selection = g_list_remove (root_tree->selection, child);
1030 gtk_widget_unref (child);
1031 gtk_signal_emit (GTK_OBJECT (tree->root_tree),
1032 tree_signals[SELECTION_CHANGED]);
1036 case GTK_SELECTION_EXTENDED:
1042 gtk_tree_set_selection_mode (GtkTree *tree,
1043 GtkSelectionMode mode)
1045 g_return_if_fail (tree != NULL);
1046 g_return_if_fail (GTK_IS_TREE (tree));
1048 tree->selection_mode = mode;
1052 gtk_tree_set_view_mode (GtkTree *tree,
1053 GtkTreeViewMode mode)
1055 g_return_if_fail (tree != NULL);
1056 g_return_if_fail (GTK_IS_TREE (tree));
1058 tree->view_mode = mode;
1062 gtk_tree_set_view_lines (GtkTree *tree,
1065 g_return_if_fail (tree != NULL);
1066 g_return_if_fail (GTK_IS_TREE (tree));
1068 tree->view_line = flag;