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
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-1999. 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 "gtktreeitem2.h"
30 #include <gtk/gtkmain.h>
31 #include <gtk/gtksignal.h>
32 #include <gtk/gtklist.h>
41 static void gtk_tree2_class_init (GtkTree2Class *klass);
42 static void gtk_tree2_init (GtkTree2 *tree);
43 static void gtk_tree2_destroy (GtkObject *object);
44 static void gtk_tree2_map (GtkWidget *widget);
45 static void gtk_tree2_unmap (GtkWidget *widget);
46 static void gtk_tree2_realize (GtkWidget *widget);
47 static void gtk_tree2_draw (GtkWidget *widget,
49 static gint gtk_tree2_expose (GtkWidget *widget,
50 GdkEventExpose *event);
51 static gint gtk_tree2_motion_notify (GtkWidget *widget,
52 GdkEventMotion *event);
53 static gint gtk_tree2_button_press (GtkWidget *widget,
54 GdkEventButton *event);
55 static gint gtk_tree2_button_release (GtkWidget *widget,
56 GdkEventButton *event);
57 static void gtk_tree2_size_request (GtkWidget *widget,
58 GtkRequisition *requisition);
59 static void gtk_tree2_size_allocate (GtkWidget *widget,
60 GtkAllocation *allocation);
61 static void gtk_tree2_add (GtkContainer *container,
63 static void gtk_tree2_forall (GtkContainer *container,
64 gboolean include_internals,
66 gpointer callback_data);
68 static void gtk_real_tree2_select_child (GtkTree2 *tree,
70 static void gtk_real_tree2_unselect_child (GtkTree2 *tree,
73 static GtkType gtk_tree2_child_type (GtkContainer *container);
75 static GtkContainerClass *parent_class = NULL;
76 static guint tree_signals[LAST_SIGNAL] = { 0 };
79 gtk_tree2_get_type (void)
81 static GtkType tree_type = 0;
85 static const GtkTypeInfo tree_info =
89 sizeof (GtkTree2Class),
90 (GtkClassInitFunc) gtk_tree2_class_init,
91 (GtkObjectInitFunc) gtk_tree2_init,
92 /* reserved_1 */ NULL,
93 /* reserved_2 */ NULL,
94 (GtkClassInitFunc) NULL,
97 tree_type = gtk_type_unique (gtk_container_get_type (), &tree_info);
104 gtk_tree2_class_init (GtkTree2Class *class)
106 GtkObjectClass *object_class;
107 GtkWidgetClass *widget_class;
108 GtkContainerClass *container_class;
110 object_class = (GtkObjectClass*) class;
111 widget_class = (GtkWidgetClass*) class;
112 container_class = (GtkContainerClass*) class;
114 parent_class = gtk_type_class (gtk_container_get_type ());
116 tree_signals[SELECTION_CHANGED] =
117 gtk_signal_new ("selection_changed",
120 GTK_SIGNAL_OFFSET (GtkTree2Class, selection_changed),
121 gtk_marshal_NONE__NONE,
123 tree_signals[SELECT_CHILD] =
124 gtk_signal_new ("select_child",
127 GTK_SIGNAL_OFFSET (GtkTree2Class, select_child),
128 gtk_marshal_NONE__POINTER,
131 tree_signals[UNSELECT_CHILD] =
132 gtk_signal_new ("unselect_child",
135 GTK_SIGNAL_OFFSET (GtkTree2Class, unselect_child),
136 gtk_marshal_NONE__POINTER,
140 gtk_object_class_add_signals (object_class, tree_signals, LAST_SIGNAL);
142 object_class->destroy = gtk_tree2_destroy;
144 widget_class->map = gtk_tree2_map;
145 widget_class->unmap = gtk_tree2_unmap;
146 widget_class->realize = gtk_tree2_realize;
147 widget_class->draw = gtk_tree2_draw;
148 widget_class->expose_event = gtk_tree2_expose;
149 widget_class->motion_notify_event = gtk_tree2_motion_notify;
150 widget_class->button_press_event = gtk_tree2_button_press;
151 widget_class->button_release_event = gtk_tree2_button_release;
152 widget_class->size_request = gtk_tree2_size_request;
153 widget_class->size_allocate = gtk_tree2_size_allocate;
155 container_class->add = gtk_tree2_add;
156 container_class->remove =
157 (void (*)(GtkContainer *, GtkWidget *)) gtk_tree2_remove_item;
158 container_class->forall = gtk_tree2_forall;
159 container_class->child_type = gtk_tree2_child_type;
161 class->selection_changed = NULL;
162 class->select_child = gtk_real_tree2_select_child;
163 class->unselect_child = gtk_real_tree2_unselect_child;
167 gtk_tree2_child_type (GtkContainer *container)
169 return GTK_TYPE_TREE_ITEM2;
173 gtk_tree2_init (GtkTree2 *tree)
175 tree->children = NULL;
176 tree->root_tree = NULL;
177 tree->selection = NULL;
178 tree->tree_owner = NULL;
179 tree->selection_mode = GTK_SELECTION_SINGLE;
180 tree->indent_value = 9;
181 tree->current_indent = 0;
183 tree->view_mode = GTK_TREE2_VIEW_LINE;
190 return GTK_WIDGET (gtk_type_new (gtk_tree2_get_type ()));
194 gtk_tree2_append (GtkTree2 *tree,
195 GtkWidget *tree_item)
197 g_return_if_fail (tree != NULL);
198 g_return_if_fail (GTK_IS_TREE2 (tree));
199 g_return_if_fail (tree_item != NULL);
200 g_return_if_fail (GTK_IS_TREE_ITEM2 (tree_item));
202 gtk_tree2_insert (tree, tree_item, -1);
206 gtk_tree2_prepend (GtkTree2 *tree,
207 GtkWidget *tree_item)
209 g_return_if_fail (tree != NULL);
210 g_return_if_fail (GTK_IS_TREE2 (tree));
211 g_return_if_fail (tree_item != NULL);
212 g_return_if_fail (GTK_IS_TREE_ITEM2 (tree_item));
214 gtk_tree2_insert (tree, tree_item, 0);
218 gtk_tree2_insert (GtkTree2 *tree,
219 GtkWidget *tree_item,
224 g_return_if_fail (tree != NULL);
225 g_return_if_fail (GTK_IS_TREE2 (tree));
226 g_return_if_fail (tree_item != NULL);
227 g_return_if_fail (GTK_IS_TREE_ITEM2 (tree_item));
229 nchildren = g_list_length (tree->children);
231 if ((position < 0) || (position > nchildren))
232 position = nchildren;
234 if (position == nchildren)
235 tree->children = g_list_append (tree->children, tree_item);
237 tree->children = g_list_insert (tree->children, tree_item, position);
239 gtk_widget_set_parent (tree_item, GTK_WIDGET (tree));
241 if (GTK_WIDGET_REALIZED (tree_item->parent))
242 gtk_widget_realize (tree_item);
244 if (GTK_WIDGET_VISIBLE (tree_item->parent) && GTK_WIDGET_VISIBLE (tree_item))
246 if (GTK_WIDGET_MAPPED (tree_item->parent))
247 gtk_widget_map (tree_item);
249 gtk_widget_queue_resize (tree_item);
253 /* moves the pos child up in the tree */
255 gtk_tree2_item_up (GtkTree2 *tree,
259 GList *children, *tmp;
261 g_return_if_fail (tree != NULL);
262 g_return_if_fail (GTK_IS_TREE2 (tree));
264 children = (tree->children);
265 nchildren = g_list_length (tree->children);
267 if ((position < 1) || (position >= nchildren))
270 for (i=1; i < position; i++)
271 children = (children->next);
273 tmp = children->next;
276 tree->children = children->next;
277 children->next->prev = NULL;
281 children->prev->next = children->next;
282 children->next->prev = children->prev;
284 children->next = tmp->next;
285 children->prev = tmp;
287 tmp->next->prev = children;
288 tmp->next = children;
290 if (GTK_WIDGET_VISIBLE (tree))
292 /* if (GTK_WIDGET_VISIBLE (GTK_WIDGET(children->data)))
293 gtk_widget_queue_resize (GTK_WIDGET(children->data));
294 if (GTK_WIDGET_VISIBLE (GTK_WIDGET(tmp->data)))
295 gtk_widget_queue_resize (GTK_WIDGET(tmp->data));
297 gtk_widget_queue_resize (GTK_WIDGET(tree));
302 gtk_tree2_add (GtkContainer *container,
307 g_return_if_fail (container != NULL);
308 g_return_if_fail (GTK_IS_TREE2 (container));
309 g_return_if_fail (GTK_IS_TREE_ITEM2 (child));
311 tree = GTK_TREE2 (container);
313 tree->children = g_list_append (tree->children, child);
315 gtk_widget_set_parent (child, GTK_WIDGET (container));
317 if (GTK_WIDGET_REALIZED (child->parent))
318 gtk_widget_realize (child);
320 if (GTK_WIDGET_VISIBLE (child->parent) && GTK_WIDGET_VISIBLE (child))
322 if (GTK_WIDGET_MAPPED (child->parent))
323 gtk_widget_map (child);
325 gtk_widget_queue_resize (child);
328 if (!tree->selection && (tree->selection_mode == GTK_SELECTION_BROWSE))
329 gtk_tree2_select_child (tree, child);
333 gtk_tree2_button_press (GtkWidget *widget,
334 GdkEventButton *event)
339 g_return_val_if_fail (widget != NULL, FALSE);
340 g_return_val_if_fail (GTK_IS_TREE2 (widget), FALSE);
341 g_return_val_if_fail (event != NULL, FALSE);
343 tree = GTK_TREE2 (widget);
344 item = gtk_get_event_widget ((GdkEvent*) event);
346 while (item && !GTK_IS_TREE_ITEM2 (item))
349 if (!item || (item->parent != widget))
352 switch(event->button)
355 gtk_tree2_select_child (tree, item);
358 if(GTK_TREE_ITEM2(item)->subtree) gtk_tree_item2_expand(GTK_TREE_ITEM2(item));
361 if(GTK_TREE_ITEM2(item)->subtree) gtk_tree_item2_collapse(GTK_TREE_ITEM2(item));
369 gtk_tree2_button_release (GtkWidget *widget,
370 GdkEventButton *event)
375 g_return_val_if_fail (widget != NULL, FALSE);
376 g_return_val_if_fail (GTK_IS_TREE2 (widget), FALSE);
377 g_return_val_if_fail (event != NULL, FALSE);
379 tree = GTK_TREE2 (widget);
380 item = gtk_get_event_widget ((GdkEvent*) event);
386 gtk_tree2_child_position (GtkTree2 *tree,
393 g_return_val_if_fail (tree != NULL, -1);
394 g_return_val_if_fail (GTK_IS_TREE2 (tree), -1);
395 g_return_val_if_fail (child != NULL, -1);
398 children = tree->children;
402 if (child == GTK_WIDGET (children->data))
406 children = children->next;
414 gtk_tree2_clear_items (GtkTree2 *tree,
424 g_return_if_fail (tree != NULL);
425 g_return_if_fail (GTK_IS_TREE2 (tree));
427 nchildren = g_list_length (tree->children);
431 if ((end < 0) || (end > nchildren))
437 tmp_list = g_list_nth (tree->children, start);
440 while (tmp_list && index <= end)
442 widget = tmp_list->data;
443 tmp_list = tmp_list->next;
446 clear_list = g_list_prepend (clear_list, widget);
449 gtk_tree2_remove_items (tree, clear_list);
454 gtk_tree2_destroy (GtkObject *object)
460 g_return_if_fail (object != NULL);
461 g_return_if_fail (GTK_IS_TREE2 (object));
463 tree = GTK_TREE2 (object);
465 children = tree->children;
468 child = children->data;
469 children = children->next;
471 gtk_widget_ref (child);
472 gtk_widget_unparent (child);
473 gtk_widget_destroy (child);
474 gtk_widget_unref (child);
477 g_list_free (tree->children);
478 tree->children = NULL;
480 if (tree->root_tree == tree)
483 for (node = tree->selection; node; node = node->next)
484 gtk_widget_unref ((GtkWidget *)node->data);
485 g_list_free (tree->selection);
486 tree->selection = NULL;
489 if (GTK_OBJECT_CLASS (parent_class)->destroy)
490 (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
494 gtk_tree2_draw (GtkWidget *widget,
500 GdkRectangle child_area;
504 g_return_if_fail (widget != NULL);
505 g_return_if_fail (GTK_IS_TREE2 (widget));
506 g_return_if_fail (area != NULL);
508 if (GTK_WIDGET_DRAWABLE (widget))
510 tree = GTK_TREE2 (widget);
512 children = tree->children;
515 child = children->data;
516 children = children->next;
518 if (gtk_widget_intersect (child, area, &child_area))
519 gtk_widget_draw (child, &child_area);
521 if((subtree = GTK_TREE_ITEM2(child)->subtree) &&
522 GTK_WIDGET_VISIBLE(subtree) &&
523 gtk_widget_intersect (subtree, area, &child_area))
524 gtk_widget_draw (subtree, &child_area);
531 gtk_tree2_expose (GtkWidget *widget,
532 GdkEventExpose *event)
536 GdkEventExpose child_event;
540 g_return_val_if_fail (widget != NULL, FALSE);
541 g_return_val_if_fail (GTK_IS_TREE2 (widget), FALSE);
542 g_return_val_if_fail (event != NULL, FALSE);
544 if (GTK_WIDGET_DRAWABLE (widget))
546 tree = GTK_TREE2 (widget);
548 child_event = *event;
550 children = tree->children;
553 child = children->data;
554 children = children->next;
556 if (GTK_WIDGET_NO_WINDOW (child) &&
557 gtk_widget_intersect (child, &event->area, &child_event.area))
558 gtk_widget_event (child, (GdkEvent*) &child_event);
567 gtk_tree2_forall (GtkContainer *container,
568 gboolean include_internals,
569 GtkCallback callback,
570 gpointer callback_data)
577 g_return_if_fail (container != NULL);
578 g_return_if_fail (GTK_IS_TREE2 (container));
579 g_return_if_fail (callback != NULL);
581 tree = GTK_TREE2 (container);
582 children = tree->children;
586 child = children->data;
587 children = children->next;
589 (* callback) (child, callback_data);
591 if (include_internals && GTK_TREE_ITEM2(child)->subtree)
592 (* callback) (GTK_TREE_ITEM2(child)->subtree, callback_data);
597 gtk_tree2_map (GtkWidget *widget)
604 g_return_if_fail (widget != NULL);
605 g_return_if_fail (GTK_IS_TREE2 (widget));
607 GTK_WIDGET_SET_FLAGS (widget, GTK_MAPPED);
608 tree = GTK_TREE2 (widget);
610 if(GTK_IS_TREE2(widget->parent))
612 /* set root tree for this tree */
613 tree->root_tree = GTK_TREE2(widget->parent)->root_tree;
615 tree->level = GTK_TREE2(GTK_WIDGET(tree)->parent)->level+1;
616 tree->indent_value = GTK_TREE2(GTK_WIDGET(tree)->parent)->indent_value;
617 tree->current_indent = GTK_TREE2(GTK_WIDGET(tree)->parent)->current_indent +
619 tree->view_mode = GTK_TREE2(GTK_WIDGET(tree)->parent)->view_mode;
620 tree->view_line = GTK_TREE2(GTK_WIDGET(tree)->parent)->view_line;
623 tree->root_tree = tree;
625 children = tree->children;
628 child = children->data;
629 children = children->next;
631 if (GTK_WIDGET_VISIBLE (child) &&
632 !GTK_WIDGET_MAPPED (child))
633 gtk_widget_map (child);
635 if (GTK_TREE_ITEM2 (child)->subtree)
637 child = GTK_WIDGET (GTK_TREE_ITEM2 (child)->subtree);
639 if (GTK_WIDGET_VISIBLE (child) && !GTK_WIDGET_MAPPED (child))
640 gtk_widget_map (child);
644 gdk_window_show (widget->window);
648 gtk_tree2_motion_notify (GtkWidget *widget,
649 GdkEventMotion *event)
651 g_return_val_if_fail (widget != NULL, FALSE);
652 g_return_val_if_fail (GTK_IS_TREE2 (widget), FALSE);
653 g_return_val_if_fail (event != NULL, FALSE);
656 g_message("gtk_tree2_motion_notify\n");
657 #endif /* TREE_DEBUG */
663 gtk_tree2_realize (GtkWidget *widget)
665 GdkWindowAttr attributes;
666 gint attributes_mask;
669 g_return_if_fail (widget != NULL);
670 g_return_if_fail (GTK_IS_TREE2 (widget));
672 GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
674 attributes.window_type = GDK_WINDOW_CHILD;
675 attributes.x = widget->allocation.x;
676 attributes.y = widget->allocation.y;
677 attributes.width = widget->allocation.width;
678 attributes.height = widget->allocation.height;
679 attributes.wclass = GDK_INPUT_OUTPUT;
680 attributes.visual = gtk_widget_get_visual (widget);
681 attributes.colormap = gtk_widget_get_colormap (widget);
682 attributes.event_mask = gtk_widget_get_events (widget) | GDK_EXPOSURE_MASK;
684 attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
686 widget->window = gdk_window_new (gtk_widget_get_parent_window (widget), &attributes, attributes_mask);
687 gdk_window_set_user_data (widget->window, widget);
689 widget->style = gtk_style_attach (widget->style, widget->window);
690 gdk_window_set_background (widget->window,
691 &widget->style->base[GTK_STATE_NORMAL]);
695 gtk_tree2_remove_item (GtkTree2 *container,
700 g_return_if_fail (container != NULL);
701 g_return_if_fail (GTK_IS_TREE2 (container));
702 g_return_if_fail (widget != NULL);
703 g_return_if_fail (container == GTK_TREE2 (widget->parent));
705 item_list = g_list_append (NULL, widget);
707 gtk_tree2_remove_items (GTK_TREE2 (container), item_list);
709 g_list_free (item_list);
712 /* used by gtk_tree2_remove_items to make the function independant of
713 order in list of items to remove.
714 Sort item bu depth in tree */
716 gtk_tree2_sort_item_by_depth(GtkWidget* a, GtkWidget* b)
718 if((GTK_TREE2(a->parent)->level) < (GTK_TREE2(b->parent)->level))
720 if((GTK_TREE2(a->parent)->level) > (GTK_TREE2(b->parent)->level))
727 gtk_tree2_remove_items (GtkTree2 *tree,
731 GList *selected_widgets;
737 g_return_if_fail (tree != NULL);
738 g_return_if_fail (GTK_IS_TREE2 (tree));
741 g_message("+ gtk_tree2_remove_items [ tree %#x items list %#x ]\n", (int)tree, (int)items);
742 #endif /* TREE_DEBUG */
744 /* We may not yet be mapped, so we actively have to find our
748 root_tree = tree->root_tree;
751 GtkWidget *tmp = GTK_WIDGET (tree);
752 while (tmp->parent && GTK_IS_TREE2 (tmp->parent))
755 root_tree = GTK_TREE2 (tmp);
759 selected_widgets = NULL;
764 g_message("* sort list by depth\n");
765 #endif /* TREE_DEBUG */
771 g_message ("* item [%#x] depth [%d]\n",
773 (int)GTK_TREE2(GTK_WIDGET(tmp_list->data)->parent)->level);
774 #endif /* TREE_DEBUG */
776 sorted_list = g_list_insert_sorted(sorted_list,
778 (GCompareFunc)gtk_tree2_sort_item_by_depth);
779 tmp_list = g_list_next(tmp_list);
783 /* print sorted list */
784 g_message("* sorted list result\n");
785 tmp_list = sorted_list;
788 g_message("* item [%#x] depth [%d]\n",
790 (int)GTK_TREE2(GTK_WIDGET(tmp_list->data)->parent)->level);
791 tmp_list = g_list_next(tmp_list);
793 #endif /* TREE_DEBUG */
796 g_message("* scan sorted list\n");
797 #endif /* TREE_DEBUG */
799 tmp_list = sorted_list;
802 widget = tmp_list->data;
803 tmp_list = tmp_list->next;
806 g_message("* item [%#x] subtree [%#x]\n",
807 (int)widget, (int)GTK_TREE_ITEM2_SUBTREE(widget));
808 #endif /* TREE_DEBUG */
810 /* get real owner of this widget */
811 real_tree = GTK_TREE2(widget->parent);
813 g_message("* subtree having this widget [%#x]\n", (int)real_tree);
814 #endif /* TREE_DEBUG */
817 if (widget->state == GTK_STATE_SELECTED)
819 selected_widgets = g_list_prepend (selected_widgets, widget);
821 g_message("* selected widget - adding it in selected list [%#x]\n",
822 (int)selected_widgets);
823 #endif /* TREE_DEBUG */
826 /* remove this item from its real parent */
828 g_message("* remove widget from its owner tree\n");
829 #endif /* TREE_DEBUG */
830 real_tree->children = g_list_remove (real_tree->children, widget);
832 /* remove subtree associate at this item if it exist */
833 if(GTK_TREE_ITEM2(widget)->subtree)
836 g_message("* remove subtree associate at this item [%#x]\n",
837 (int) GTK_TREE_ITEM2(widget)->subtree);
838 #endif /* TREE_DEBUG */
839 if (GTK_WIDGET_MAPPED (GTK_TREE_ITEM2(widget)->subtree))
840 gtk_widget_unmap (GTK_TREE_ITEM2(widget)->subtree);
842 gtk_widget_unparent (GTK_TREE_ITEM2(widget)->subtree);
843 GTK_TREE_ITEM2(widget)->subtree = NULL;
846 /* really remove widget for this item */
848 g_message("* unmap and unparent widget [%#x]\n", (int)widget);
849 #endif /* TREE_DEBUG */
850 if (GTK_WIDGET_MAPPED (widget))
851 gtk_widget_unmap (widget);
853 gtk_widget_unparent (widget);
855 /* delete subtree if there is no children in it */
857 /* if(real_tree->children == NULL &&
858 real_tree != root_tree)
862 g_message("* owner tree don't have children ... destroy it\n");
863 #endif /* TREE_DEBUG */
865 gtk_tree_item2_remove_subtree(GTK_TREE_ITEM2(real_tree->tree_owner));
869 g_message("* next item in list\n");
870 #endif /* TREE_DEBUG */
873 if (selected_widgets)
876 g_message("* scan selected item list\n");
877 #endif /* TREE_DEBUG */
878 tmp_list = selected_widgets;
881 widget = tmp_list->data;
882 tmp_list = tmp_list->next;
885 g_message("* widget [%#x] subtree [%#x]\n",
886 (int)widget, (int)GTK_TREE_ITEM2_SUBTREE(widget));
887 #endif /* TREE_DEBUG */
889 /* remove widget of selection */
890 root_tree->selection = g_list_remove (root_tree->selection, widget);
892 /* unref it to authorize is destruction */
893 gtk_widget_unref (widget);
896 /* emit only one selection_changed signal */
897 gtk_signal_emit (GTK_OBJECT (root_tree),
898 tree_signals[SELECTION_CHANGED]);
902 g_message("* free selected_widgets list\n");
903 #endif /* TREE_DEBUG */
904 g_list_free (selected_widgets);
905 g_list_free (sorted_list);
907 if (root_tree->children && !root_tree->selection &&
908 (root_tree->selection_mode == GTK_SELECTION_BROWSE))
911 g_message("* BROWSE mode, select another item\n");
912 #endif /* TREE_DEBUG */
913 widget = root_tree->children->data;
914 gtk_tree2_select_child (root_tree, widget);
917 if (GTK_WIDGET_VISIBLE (root_tree))
920 g_message("* query queue resizing for root_tree\n");
921 #endif /* TREE_DEBUG */
922 gtk_widget_queue_resize (GTK_WIDGET (root_tree));
927 gtk_tree2_select_child (GtkTree2 *tree,
928 GtkWidget *tree_item)
930 g_return_if_fail (tree != NULL);
931 g_return_if_fail (GTK_IS_TREE2 (tree));
932 g_return_if_fail (tree_item != NULL);
933 g_return_if_fail (GTK_IS_TREE_ITEM2 (tree_item));
935 gtk_signal_emit (GTK_OBJECT (tree), tree_signals[SELECT_CHILD], tree_item);
939 gtk_tree2_select_next_child (GtkTree2 *tree,
940 GtkWidget *tree_item, gboolean descend)
944 g_return_if_fail (tree != NULL);
945 g_return_if_fail (GTK_IS_TREE2 (tree));
946 g_return_if_fail (tree_item != NULL);
947 g_return_if_fail (GTK_IS_TREE_ITEM2 (tree_item));
949 if (descend && GTK_TREE2(GTK_TREE_ITEM2(tree_item)->subtree)->children)
951 gtk_signal_emit (GTK_OBJECT (GTK_TREE_ITEM2(tree_item)->subtree), tree_signals[SELECT_CHILD], GTK_TREE2(GTK_TREE_ITEM2(tree_item)->subtree)->children->data);
955 children = tree->children;
958 if (tree_item == GTK_WIDGET (children->data))
961 children = children->next;
963 if (!children) return;
966 gtk_signal_emit (GTK_OBJECT (tree), tree_signals[SELECT_CHILD], children->next->data);
967 else if (tree != tree->root_tree)
969 children = GTK_TREE2(GTK_WIDGET(tree)->parent)->children;
970 gtk_tree2_select_next_child (GTK_TREE2(GTK_WIDGET(tree)->parent), tree->tree_owner, FALSE);
975 /* we know that tree is not the roor_tree and that
976 tree_items always have subtrees */
978 gtk_tree2_select_prev_child (GtkTree2 *tree,
979 GtkWidget *tree_item)
982 GtkTreeItem2 *tree_item2;
984 g_return_if_fail (tree != NULL);
985 g_return_if_fail (GTK_IS_TREE2 (tree));
986 g_return_if_fail (tree_item != NULL);
987 g_return_if_fail (GTK_IS_TREE_ITEM2 (tree_item));
990 children = tree->children;
993 if (tree_item == GTK_WIDGET (children->data))
996 children = children->next;
998 if (!children) return;
1000 if (children = children->prev)
1002 tree_item2 = GTK_TREE_ITEM2(children->data);
1003 while (GTK_TREE2(tree_item2->subtree)->children)
1005 children = GTK_TREE2(tree_item2->subtree)->children;
1006 while (children->next)
1007 children = children->next;
1008 tree_item2 = GTK_TREE_ITEM2(children->data);
1010 gtk_signal_emit (GTK_OBJECT (GTK_WIDGET(tree_item2)->parent), tree_signals[SELECT_CHILD], tree_item2);
1014 gtk_signal_emit (GTK_OBJECT (GTK_WIDGET(tree)->parent), tree_signals[SELECT_CHILD], tree->tree_owner);
1020 gtk_tree2_select_item (GtkTree2 *tree,
1025 g_return_if_fail (tree != NULL);
1026 g_return_if_fail (GTK_IS_TREE2 (tree));
1028 tmp_list = g_list_nth (tree->children, item);
1030 gtk_tree2_select_child (tree, GTK_WIDGET (tmp_list->data));
1035 gtk_tree2_size_allocate (GtkWidget *widget,
1036 GtkAllocation *allocation)
1039 GtkWidget *child, *subtree;
1040 GtkAllocation child_allocation;
1044 g_return_if_fail (widget != NULL);
1045 g_return_if_fail (GTK_IS_TREE2 (widget));
1046 g_return_if_fail (allocation != NULL);
1048 tree = GTK_TREE2 (widget);
1050 widget->allocation = *allocation;
1051 if (GTK_WIDGET_REALIZED (widget))
1052 gdk_window_move_resize (widget->window,
1053 allocation->x, allocation->y,
1054 allocation->width, allocation->height);
1058 child_allocation.x = GTK_CONTAINER (tree)->border_width;
1059 child_allocation.y = GTK_CONTAINER (tree)->border_width;
1060 child_allocation.width = MAX (1, (gint)allocation->width - child_allocation.x * 2);
1062 children = tree->children;
1066 child = children->data;
1067 children = children->next;
1069 if (GTK_WIDGET_VISIBLE (child))
1071 GtkRequisition child_requisition;
1072 gtk_widget_get_child_requisition (child, &child_requisition);
1074 child_allocation.height = child_requisition.height;
1076 gtk_widget_size_allocate (child, &child_allocation);
1078 child_allocation.y += child_allocation.height;
1080 if((subtree = GTK_TREE_ITEM2(child)->subtree))
1081 if(GTK_WIDGET_VISIBLE (subtree))
1083 child_allocation.height = subtree->requisition.height;
1084 gtk_widget_size_allocate (subtree, &child_allocation);
1085 child_allocation.y += child_allocation.height;
1094 gtk_tree2_size_request (GtkWidget *widget,
1095 GtkRequisition *requisition)
1098 GtkWidget *child, *subtree;
1100 GtkRequisition child_requisition;
1103 g_return_if_fail (widget != NULL);
1104 g_return_if_fail (GTK_IS_TREE2 (widget));
1105 g_return_if_fail (requisition != NULL);
1107 tree = GTK_TREE2 (widget);
1108 requisition->width = 0;
1109 requisition->height = 0;
1111 children = tree->children;
1114 child = children->data;
1115 children = children->next;
1117 if (GTK_WIDGET_VISIBLE (child))
1119 gtk_widget_size_request (child, &child_requisition);
1121 requisition->width = MAX (requisition->width, child_requisition.width);
1122 requisition->height += child_requisition.height;
1124 if((subtree = GTK_TREE_ITEM2(child)->subtree) &&
1125 GTK_WIDGET_VISIBLE (subtree))
1127 gtk_widget_size_request (subtree, &child_requisition);
1129 requisition->width = MAX (requisition->width,
1130 child_requisition.width);
1132 requisition->height += child_requisition.height;
1137 requisition->width += GTK_CONTAINER (tree)->border_width * 2;
1138 requisition->height += GTK_CONTAINER (tree)->border_width * 2;
1140 requisition->width = MAX (requisition->width, 1);
1141 requisition->height = MAX (requisition->height, 1);
1146 gtk_tree2_unmap (GtkWidget *widget)
1149 g_return_if_fail (widget != NULL);
1150 g_return_if_fail (GTK_IS_TREE2 (widget));
1152 GTK_WIDGET_UNSET_FLAGS (widget, GTK_MAPPED);
1153 gdk_window_hide (widget->window);
1158 gtk_tree2_unselect_child (GtkTree2 *tree,
1159 GtkWidget *tree_item)
1161 g_return_if_fail (tree != NULL);
1162 g_return_if_fail (GTK_IS_TREE2 (tree));
1163 g_return_if_fail (tree_item != NULL);
1164 g_return_if_fail (GTK_IS_TREE_ITEM2 (tree_item));
1166 gtk_signal_emit (GTK_OBJECT (tree), tree_signals[UNSELECT_CHILD], tree_item);
1170 gtk_tree2_unselect_item (GtkTree2 *tree,
1175 g_return_if_fail (tree != NULL);
1176 g_return_if_fail (GTK_IS_TREE2 (tree));
1178 tmp_list = g_list_nth (tree->children, item);
1180 gtk_tree2_unselect_child (tree, GTK_WIDGET (tmp_list->data));
1185 gtk_real_tree2_select_child (GtkTree2 *tree,
1188 GList *selection, *root_selection;
1190 GtkWidget *tmp_item;
1192 g_return_if_fail (tree != NULL);
1193 g_return_if_fail (GTK_IS_TREE2 (tree));
1194 g_return_if_fail (child != NULL);
1195 g_return_if_fail (GTK_IS_TREE_ITEM2 (child));
1197 root_selection = tree->root_tree->selection;
1199 switch (tree->root_tree->selection_mode)
1201 case GTK_SELECTION_SINGLE:
1203 selection = root_selection;
1205 /* remove old selection list */
1208 tmp_item = selection->data;
1210 if (tmp_item != child)
1212 gtk_tree_item2_deselect (GTK_TREE_ITEM2 (tmp_item));
1214 tmp_list = selection;
1215 selection = selection->next;
1217 root_selection = g_list_remove_link (root_selection, tmp_list);
1218 gtk_widget_unref (tmp_item);
1220 g_list_free (tmp_list);
1223 selection = selection->next;
1226 if (child->state == GTK_STATE_NORMAL)
1228 gtk_tree_item2_select (GTK_TREE_ITEM2 (child));
1229 root_selection = g_list_prepend (root_selection, child);
1230 gtk_widget_ref (child);
1232 else if (child->state == GTK_STATE_SELECTED)
1234 gtk_tree_item2_deselect (GTK_TREE_ITEM2 (child));
1235 root_selection = g_list_remove (root_selection, child);
1236 gtk_widget_unref (child);
1239 tree->root_tree->selection = root_selection;
1241 gtk_signal_emit (GTK_OBJECT (tree->root_tree),
1242 tree_signals[SELECTION_CHANGED]);
1246 case GTK_SELECTION_BROWSE:
1247 selection = root_selection;
1251 tmp_item = selection->data;
1253 if (tmp_item != child)
1255 gtk_tree_item2_deselect (GTK_TREE_ITEM2 (tmp_item));
1257 tmp_list = selection;
1258 selection = selection->next;
1260 root_selection = g_list_remove_link (root_selection, tmp_list);
1261 gtk_widget_unref (tmp_item);
1263 g_list_free (tmp_list);
1266 selection = selection->next;
1269 tree->root_tree->selection = root_selection;
1271 if (child->state == GTK_STATE_NORMAL)
1273 gtk_tree_item2_select (GTK_TREE_ITEM2 (child));
1274 root_selection = g_list_prepend (root_selection, child);
1275 gtk_widget_ref (child);
1276 tree->root_tree->selection = root_selection;
1277 gtk_signal_emit (GTK_OBJECT (tree->root_tree),
1278 tree_signals[SELECTION_CHANGED]);
1282 case GTK_SELECTION_MULTIPLE:
1283 if (child->state == GTK_STATE_NORMAL)
1285 gtk_tree_item2_select (GTK_TREE_ITEM2 (child));
1286 root_selection = g_list_prepend (root_selection, child);
1287 gtk_widget_ref (child);
1288 tree->root_tree->selection = root_selection;
1289 gtk_signal_emit (GTK_OBJECT (tree->root_tree),
1290 tree_signals[SELECTION_CHANGED]);
1292 else if (child->state == GTK_STATE_SELECTED)
1294 gtk_tree_item2_deselect (GTK_TREE_ITEM2 (child));
1295 root_selection = g_list_remove (root_selection, child);
1296 gtk_widget_unref (child);
1297 tree->root_tree->selection = root_selection;
1298 gtk_signal_emit (GTK_OBJECT (tree->root_tree),
1299 tree_signals[SELECTION_CHANGED]);
1303 case GTK_SELECTION_EXTENDED:
1309 gtk_real_tree2_unselect_child (GtkTree2 *tree,
1312 g_return_if_fail (tree != NULL);
1313 g_return_if_fail (GTK_IS_TREE2 (tree));
1314 g_return_if_fail (child != NULL);
1315 g_return_if_fail (GTK_IS_TREE_ITEM2 (child));
1317 switch (tree->selection_mode)
1319 case GTK_SELECTION_SINGLE:
1320 case GTK_SELECTION_MULTIPLE:
1321 case GTK_SELECTION_BROWSE:
1322 if (child->state == GTK_STATE_SELECTED)
1324 GtkTree2* root_tree = GTK_TREE2_ROOT_TREE(tree);
1325 gtk_tree_item2_deselect (GTK_TREE_ITEM2 (child));
1326 root_tree->selection = g_list_remove (root_tree->selection, child);
1327 gtk_widget_unref (child);
1328 gtk_signal_emit (GTK_OBJECT (tree->root_tree),
1329 tree_signals[SELECTION_CHANGED]);
1333 case GTK_SELECTION_EXTENDED:
1339 gtk_tree2_set_selection_mode (GtkTree2 *tree,
1340 GtkSelectionMode mode)
1342 g_return_if_fail (tree != NULL);
1343 g_return_if_fail (GTK_IS_TREE2 (tree));
1345 tree->selection_mode = mode;
1349 gtk_tree2_set_view_mode (GtkTree2 *tree,
1350 GtkTree2ViewMode mode)
1352 g_return_if_fail (tree != NULL);
1353 g_return_if_fail (GTK_IS_TREE2 (tree));
1355 tree->view_mode = mode;
1359 gtk_tree2_set_view_lines (GtkTree2 *tree,
1362 g_return_if_fail (tree != NULL);
1363 g_return_if_fail (GTK_IS_TREE2 (tree));
1365 tree->view_line = flag;
1369 gtk_tree2_item_up_1 (GtkTree2 *tree,
1376 g_return_if_fail (tree != NULL);
1377 g_return_if_fail (GTK_IS_TREE2 (tree));
1379 tmp = tree->children;
1380 length = g_list_length (tmp);
1381 if (pos <= 0 || pos >= length) { return; }
1382 data = g_list_nth_data (tree->children, pos);
1383 g_list_remove (tree->children, data);
1384 tree->children = g_list_insert (tree->children, data, pos-1);