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.
20 #include "gtktreeitem.h"
21 #include "gtkeventbox.h"
22 #include "gtkpixmap.h"
24 #include "gtksignal.h"
26 /* remove comment if you want replace loading pixmap by static bitmap
28 experimental code and it is buggy */
29 /* #define WITH_BITMAP */
31 #define DEFAULT_DELTA 9
34 #include "tree_plus.xbm"
35 #include "tree_minus.xbm"
44 typedef void (*GtkTreeItemSignal) (GtkObject *object,
48 static void gtk_tree_item_class_init (GtkTreeItemClass *klass);
49 static void gtk_tree_item_init (GtkTreeItem *tree_item);
50 static void gtk_tree_item_realize (GtkWidget *widget);
51 static void gtk_tree_item_size_request (GtkWidget *widget,
52 GtkRequisition *requisition);
53 static void gtk_tree_item_size_allocate (GtkWidget *widget,
54 GtkAllocation *allocation);
55 static void gtk_tree_item_draw (GtkWidget *widget,
57 static void gtk_tree_item_draw_focus (GtkWidget *widget);
58 static gint gtk_tree_item_button_press (GtkWidget *widget,
59 GdkEventButton *event);
60 static gint gtk_tree_item_expose (GtkWidget *widget,
61 GdkEventExpose *event);
62 static gint gtk_tree_item_focus_in (GtkWidget *widget,
63 GdkEventFocus *event);
64 static gint gtk_tree_item_focus_out (GtkWidget *widget,
65 GdkEventFocus *event);
66 static void gtk_real_tree_item_select (GtkItem *item);
67 static void gtk_real_tree_item_deselect (GtkItem *item);
68 static void gtk_real_tree_item_toggle (GtkItem *item);
69 static void gtk_real_tree_item_expand (GtkTreeItem *item);
70 static void gtk_real_tree_item_collapse (GtkTreeItem *item);
71 static void gtk_real_tree_item_expand (GtkTreeItem *item);
72 static void gtk_real_tree_item_collapse (GtkTreeItem *item);
73 static void gtk_tree_item_marshal_signal (GtkObject *object,
77 static void gtk_tree_item_destroy (GtkObject *object);
78 static void gtk_tree_item_subtree_button_click (GtkWidget *widget);
79 static void gtk_tree_item_subtree_button_changed_state (GtkWidget *widget);
81 static void gtk_tree_item_map(GtkWidget*);
82 static void gtk_tree_item_unmap(GtkWidget*);
84 static GtkItemClass *parent_class = NULL;
85 static GtkContainerClass *container_class = NULL;
86 static gint tree_item_signals[LAST_SIGNAL] = { 0 };
89 gtk_tree_item_get_type ()
91 static guint tree_item_type = 0;
95 GtkTypeInfo tree_item_info =
99 sizeof (GtkTreeItemClass),
100 (GtkClassInitFunc) gtk_tree_item_class_init,
101 (GtkObjectInitFunc) gtk_tree_item_init,
102 (GtkArgSetFunc) NULL,
103 (GtkArgGetFunc) NULL,
106 tree_item_type = gtk_type_unique (gtk_item_get_type (), &tree_item_info);
109 return tree_item_type;
113 gtk_tree_item_class_init (GtkTreeItemClass *class)
115 GtkObjectClass *object_class;
116 GtkWidgetClass *widget_class;
117 GtkItemClass *item_class;
119 object_class = (GtkObjectClass*) class;
120 widget_class = (GtkWidgetClass*) class;
121 item_class = (GtkItemClass*) class;
122 container_class = (GtkContainerClass*) class;
124 parent_class = gtk_type_class (gtk_item_get_type ());
126 tree_item_signals[EXPAND_TREE] =
127 gtk_signal_new ("expand",
130 GTK_SIGNAL_OFFSET (GtkTreeItemClass, expand),
131 gtk_tree_item_marshal_signal,
133 tree_item_signals[COLLAPSE_TREE] =
134 gtk_signal_new ("collapse",
137 GTK_SIGNAL_OFFSET (GtkTreeItemClass, collapse),
138 gtk_tree_item_marshal_signal,
141 gtk_object_class_add_signals (object_class, tree_item_signals, LAST_SIGNAL);
143 object_class->destroy = gtk_tree_item_destroy;
145 widget_class->realize = gtk_tree_item_realize;
146 widget_class->size_request = gtk_tree_item_size_request;
147 widget_class->size_allocate = gtk_tree_item_size_allocate;
148 widget_class->draw = gtk_tree_item_draw;
149 widget_class->draw_focus = gtk_tree_item_draw_focus;
150 widget_class->button_press_event = gtk_tree_item_button_press;
151 widget_class->expose_event = gtk_tree_item_expose;
152 widget_class->focus_in_event = gtk_tree_item_focus_in;
153 widget_class->focus_out_event = gtk_tree_item_focus_out;
154 widget_class->map = gtk_tree_item_map;
155 widget_class->unmap = gtk_tree_item_unmap;
157 item_class->select = gtk_real_tree_item_select;
158 item_class->deselect = gtk_real_tree_item_deselect;
159 item_class->toggle = gtk_real_tree_item_toggle;
161 class->expand = gtk_real_tree_item_expand;
162 class->collapse = gtk_real_tree_item_collapse;
164 container_class = (GtkContainerClass*) parent_class;
167 /* callback for event box mouse event */
169 gtk_tree_item_subtree_button_click (GtkWidget *widget)
173 item = (GtkTreeItem*) gtk_object_get_user_data(GTK_OBJECT(widget));
174 if(!GTK_WIDGET_IS_SENSITIVE(item))
178 gtk_tree_item_collapse(item);
180 gtk_tree_item_expand(item);
183 /* callback for event box state changed */
185 gtk_tree_item_subtree_button_changed_state(GtkWidget *w)
187 if(GTK_WIDGET_VISIBLE (w)) {
189 if (w->state == GTK_STATE_NORMAL)
190 gdk_window_set_background (w->window, &w->style->base[w->state]);
192 gdk_window_set_background (w->window, &w->style->bg[w->state]);
194 if (GTK_WIDGET_DRAWABLE(w))
195 gdk_window_clear_area (w->window, 0, 0,
196 w->allocation.width, w->allocation.height);
201 gtk_tree_item_init (GtkTreeItem *tree_item)
203 GtkWidget *eventbox, *pixmapwid;
204 static GdkPixmap *pixmap_plus = NULL;
205 static GdkPixmap *pixmap_minus = NULL;
207 static GdkBitmap *mask = NULL;
209 static GtkStyle *style = NULL;
211 tree_item->expanded = FALSE;
212 tree_item->subtree = NULL;
213 GTK_WIDGET_SET_FLAGS (tree_item, GTK_CAN_FOCUS);
218 style=gtk_widget_get_style(GTK_WIDGET(tree_item));
221 /* create pixmaps for one time, based on xpm file */
222 pixmap_plus = gdk_pixmap_create_from_xpm (GTK_WIDGET(tree_item)->window, &mask,
223 &style->bg[GTK_STATE_NORMAL],
226 g_warning("gtk_tree_item_init: can't find tree_plus.xpm file !\n");
228 pixmap_minus = gdk_pixmap_create_from_xpm (GTK_WIDGET(tree_item)->window, &mask,
229 &style->bg[GTK_STATE_NORMAL],
232 g_warning("gtk_tree_item_init: can't find tree_minus.xpm file !\n");
235 pixmap_plus = gdk_pixmap_create_from_data(GTK_WIDGET(tree_item)->window,
236 (gchar*) tree_plus_bits,
237 tree_plus_width, tree_plus_height, -1,
241 pixmap_minus = gdk_pixmap_create_from_data(GTK_WIDGET(tree_item)->window,
242 (gchar*) tree_minus_bits,
243 tree_minus_width, tree_minus_height, -1,
246 #endif /* WITH_BITMAP */
249 if(pixmap_plus && pixmap_minus)
251 /* create an event box containing one pixmaps */
252 eventbox = gtk_event_box_new();
253 gtk_widget_set_events (eventbox, GDK_BUTTON_PRESS_MASK);
254 gtk_signal_connect(GTK_OBJECT(eventbox), "state_changed",
255 (GtkSignalFunc)gtk_tree_item_subtree_button_changed_state,
257 gtk_signal_connect(GTK_OBJECT(eventbox), "realize",
258 (GtkSignalFunc)gtk_tree_item_subtree_button_changed_state,
260 gtk_signal_connect(GTK_OBJECT(eventbox), "button_press_event",
261 (GtkSignalFunc)gtk_tree_item_subtree_button_click,
263 gtk_object_set_user_data(GTK_OBJECT(eventbox), tree_item);
264 tree_item->pixmaps_box = eventbox;
266 /* create pixmap for button '+' */
268 pixmapwid = gtk_pixmap_new (pixmap_plus, mask);
270 pixmapwid = gtk_pixmap_new (pixmap_plus, NULL);
272 if(!tree_item->expanded)
273 gtk_container_add(GTK_CONTAINER(eventbox), pixmapwid);
274 gtk_widget_show(pixmapwid);
275 tree_item->plus_pix_widget = pixmapwid;
276 gtk_widget_ref (tree_item->plus_pix_widget);
277 gtk_object_sink (GTK_OBJECT (tree_item->plus_pix_widget));
279 /* create pixmap for button '-' */
281 pixmapwid = gtk_pixmap_new (pixmap_minus, mask);
283 pixmapwid = gtk_pixmap_new (pixmap_minus, NULL);
285 if(tree_item->expanded)
286 gtk_container_add(GTK_CONTAINER(eventbox), pixmapwid);
287 gtk_widget_show(pixmapwid);
288 tree_item->minus_pix_widget = pixmapwid;
289 gtk_widget_ref (tree_item->minus_pix_widget);
290 gtk_object_sink (GTK_OBJECT (tree_item->minus_pix_widget));
292 gtk_widget_set_parent(eventbox, GTK_WIDGET(tree_item));
294 tree_item->pixmaps_box = NULL;
301 GtkWidget *tree_item;
303 tree_item = GTK_WIDGET (gtk_type_new (gtk_tree_item_get_type ()));
309 gtk_tree_item_new_with_label (gchar *label)
311 GtkWidget *tree_item;
312 GtkWidget *label_widget;
315 tree_item = gtk_tree_item_new ();
316 label_widget = gtk_label_new (label);
317 gtk_misc_set_alignment (GTK_MISC (label_widget), 0.0, 0.5);
319 gtk_container_add (GTK_CONTAINER (tree_item), label_widget);
320 gtk_widget_show (label_widget);
327 gtk_tree_item_set_subtree (GtkTreeItem *tree_item,
330 g_return_if_fail (tree_item != NULL);
331 g_return_if_fail (GTK_IS_TREE_ITEM (tree_item));
333 if(tree_item->subtree) {
334 g_warning("there is already a subtree for this tree item\n");
338 tree_item->subtree = subtree;
339 GTK_TREE(subtree)->tree_owner = GTK_WIDGET(tree_item);
341 /* set root tree for selection list */
342 GTK_TREE(subtree)->root_tree = GTK_TREE(GTK_WIDGET(tree_item)->parent)->root_tree;
344 /* show subtree button */
345 if(tree_item->pixmaps_box)
346 gtk_widget_show(tree_item->pixmaps_box);
348 /* set parent widget */
349 gtk_widget_set_parent(subtree, GTK_WIDGET(tree_item)->parent);
351 if(GTK_WIDGET_VISIBLE(GTK_WIDGET(tree_item)))
353 if(GTK_WIDGET_REALIZED (GTK_WIDGET(tree_item)) &&
354 !GTK_WIDGET_REALIZED (GTK_WIDGET(subtree)))
355 gtk_widget_realize (GTK_WIDGET(subtree));
357 if(GTK_WIDGET_MAPPED (GTK_WIDGET(tree_item)) &&
358 !GTK_WIDGET_MAPPED (GTK_WIDGET(subtree)))
359 gtk_widget_map (GTK_WIDGET(subtree));
362 if(tree_item->expanded)
363 gtk_widget_show(subtree);
365 gtk_widget_hide(subtree);
367 if (GTK_WIDGET_VISIBLE (tree_item) && GTK_WIDGET_VISIBLE (tree_item))
368 gtk_widget_queue_resize (GTK_WIDGET(tree_item));
373 gtk_tree_item_select (GtkTreeItem *tree_item)
376 gtk_item_select (GTK_ITEM (tree_item));
381 gtk_tree_item_deselect (GtkTreeItem *tree_item)
384 gtk_item_deselect (GTK_ITEM (tree_item));
389 gtk_tree_item_expand (GtkTreeItem *tree_item)
392 gtk_signal_emit (GTK_OBJECT (tree_item), tree_item_signals[EXPAND_TREE], NULL);
397 gtk_tree_item_collapse (GtkTreeItem *tree_item)
400 gtk_signal_emit (GTK_OBJECT (tree_item), tree_item_signals[COLLAPSE_TREE], NULL);
405 gtk_tree_item_realize (GtkWidget *widget)
407 g_return_if_fail (widget != NULL);
408 g_return_if_fail (GTK_IS_TREE_ITEM (widget));
410 if (GTK_WIDGET_CLASS (parent_class)->realize)
411 (* GTK_WIDGET_CLASS (parent_class)->realize) (widget);
413 gdk_window_set_background (widget->window,
414 &widget->style->base[GTK_STATE_NORMAL]);
418 gtk_tree_item_size_request (GtkWidget *widget,
419 GtkRequisition *requisition)
424 g_return_if_fail (widget != NULL);
425 g_return_if_fail (GTK_IS_TREE_ITEM (widget));
426 g_return_if_fail (requisition != NULL);
428 bin = GTK_BIN (widget);
429 item = GTK_TREE_ITEM(widget);
431 requisition->width = (GTK_CONTAINER (widget)->border_width +
432 widget->style->klass->xthickness) * 2;
433 requisition->height = GTK_CONTAINER (widget)->border_width * 2;
435 if (bin->child && GTK_WIDGET_VISIBLE (bin->child))
437 gtk_widget_size_request (bin->child, &bin->child->requisition);
439 requisition->width += bin->child->requisition.width;
441 gtk_widget_size_request (item->pixmaps_box,
442 &item->pixmaps_box->requisition);
443 requisition->width += item->pixmaps_box->requisition.width + DEFAULT_DELTA +
444 GTK_TREE(widget->parent)->current_indent;
446 requisition->height += MAX(bin->child->requisition.height,
447 item->pixmaps_box->requisition.height);
452 gtk_tree_item_size_allocate (GtkWidget *widget,
453 GtkAllocation *allocation)
457 GtkAllocation child_allocation;
461 g_return_if_fail (widget != NULL);
462 g_return_if_fail (GTK_IS_TREE_ITEM (widget));
463 g_return_if_fail (allocation != NULL);
465 widget->allocation = *allocation;
466 if (GTK_WIDGET_REALIZED (widget))
467 gdk_window_move_resize (widget->window,
468 allocation->x, allocation->y,
469 allocation->width, allocation->height);
471 bin = GTK_BIN (widget);
472 item = GTK_TREE_ITEM(widget);
476 border_width = (GTK_CONTAINER (widget)->border_width +
477 widget->style->klass->xthickness);
479 child_allocation.x = border_width + GTK_TREE(widget->parent)->current_indent;
480 child_allocation.y = GTK_CONTAINER (widget)->border_width;
483 child_allocation.height = allocation->height - child_allocation.y * 2;
484 child_allocation.width = item->pixmaps_box->requisition.width;
486 child_allocation.y += 1;
487 child_allocation.height -= 2;
488 gtk_widget_size_allocate (item->pixmaps_box, &child_allocation);
490 child_allocation.height += 2;
492 child_allocation.width = item->pixmaps_box->requisition.width;
493 child_allocation.height = item->pixmaps_box->requisition.height;
495 temp = allocation->height - child_allocation.height;
496 child_allocation.y += ( temp / 2 ) + ( temp % 2 );
498 gtk_widget_size_allocate (item->pixmaps_box, &child_allocation);
500 child_allocation.y = GTK_CONTAINER (widget)->border_width;
501 child_allocation.height = allocation->height - child_allocation.y * 2;
503 child_allocation.x += item->pixmaps_box->requisition.width+DEFAULT_DELTA;
505 child_allocation.width =
506 allocation->width - (child_allocation.x + border_width);
508 gtk_widget_size_allocate (bin->child, &child_allocation);
514 gtk_tree_item_draw_lines(GtkWidget *widget)
518 guint lx1, ly1, lx2, ly2;
520 item = GTK_TREE_ITEM(widget);
521 tree = GTK_TREE(widget->parent);
523 /* draw vertical line */
524 lx1 = item->pixmaps_box->allocation.width;
525 lx1 = lx2 = ( lx1 / 2 ) + ( lx1 % 2 ) +
526 GTK_CONTAINER(widget)->border_width + 1 + tree->current_indent;
528 ly2 = widget->allocation.height;
530 if(g_list_last(tree->children)->data == (gpointer)widget)
531 ly2 = (ly2 / 2) + (ly2 % 2);
533 if(tree != tree->root_tree)
534 gdk_draw_line(widget->window, widget->style->black_gc,
537 /* draw vertical line for subtree connecting */
538 if(g_list_last(tree->children)->data != (gpointer)widget)
539 ly2 = (ly2 / 2) + (ly2 % 2);
541 lx2 += DEFAULT_DELTA;
543 if(item->subtree && item->expanded)
544 gdk_draw_line(widget->window, widget->style->black_gc,
545 lx2, ly2, lx2, widget->allocation.height);
547 /* draw horizontal line */
551 gdk_draw_line(widget->window, widget->style->black_gc,
554 lx2 -= DEFAULT_DELTA+2;
556 ly2 = widget->allocation.height;
558 if(tree != tree->root_tree)
560 item = GTK_TREE_ITEM(tree->tree_owner);
561 tree = GTK_TREE(GTK_WIDGET(tree)->parent);
562 while(tree != tree->root_tree) {
563 lx1 = lx2 -= tree->indent_value;
565 if(g_list_last(tree->children)->data != (gpointer)item)
566 gdk_draw_line(widget->window, widget->style->black_gc,
568 item = GTK_TREE_ITEM(tree->tree_owner);
569 tree = GTK_TREE(GTK_WIDGET(tree)->parent);
575 gtk_tree_item_draw (GtkWidget *widget,
579 GdkRectangle child_area, item_area;
580 GtkTreeItem* tree_item;
582 g_return_if_fail (widget != NULL);
583 g_return_if_fail (GTK_IS_TREE_ITEM (widget));
584 g_return_if_fail (area != NULL);
586 if (GTK_WIDGET_DRAWABLE (widget))
588 bin = GTK_BIN (widget);
589 tree_item = GTK_TREE_ITEM(widget);
591 /* draw left size of tree item */
592 item_area.x = 0; item_area.y = 0;
593 item_area.width = tree_item->pixmaps_box->allocation.width+DEFAULT_DELTA +
594 (GTK_TREE(widget->parent)->current_indent + 2);
595 item_area.height = widget->allocation.height;
597 if(gdk_rectangle_intersect(&item_area, area, &child_area)) {
599 if (!GTK_WIDGET_IS_SENSITIVE (widget))
600 gtk_style_set_background (widget->style, widget->window,
601 GTK_STATE_INSENSITIVE);
602 else if(GTK_TREE(widget->parent)->view_mode == GTK_TREE_VIEW_LINE &&
603 widget->state == GTK_STATE_SELECTED)
604 gtk_style_set_background (widget->style, widget->window, widget->state);
606 gdk_window_set_background (widget->window,
607 &widget->style->base[GTK_STATE_NORMAL]);
609 gdk_window_clear_area (widget->window,
610 child_area.x, child_area.y,
611 child_area.width, child_area.height);
613 /* gtk_tree_item_draw_lines(widget); */
615 if (tree_item->pixmaps_box &&
616 GTK_WIDGET_VISIBLE(tree_item->pixmaps_box) &&
617 gtk_widget_intersect (tree_item->pixmaps_box, area, &child_area))
618 gtk_widget_draw (tree_item->pixmaps_box, &child_area);
621 /* draw right side */
622 if(gtk_widget_intersect (bin->child, area, &child_area)) {
624 if (!GTK_WIDGET_IS_SENSITIVE (widget))
625 gtk_style_set_background (widget->style, widget->window,
626 GTK_STATE_INSENSITIVE);
627 else if (widget->state == GTK_STATE_NORMAL)
628 gdk_window_set_background(widget->window, &widget->style->base[GTK_STATE_NORMAL]);
630 gtk_style_set_background (widget->style, widget->window, widget->state);
632 gdk_window_clear_area (widget->window, child_area.x, child_area.y,
633 child_area.width+1, child_area.height);
636 GTK_WIDGET_VISIBLE(bin->child) &&
637 gtk_widget_intersect (bin->child, area, &child_area))
638 gtk_widget_draw (bin->child, &child_area);
641 gtk_widget_draw_focus (widget);
646 gtk_tree_item_draw_focus (GtkWidget *widget)
651 g_return_if_fail (widget != NULL);
652 g_return_if_fail (GTK_IS_TREE_ITEM (widget));
654 if (GTK_WIDGET_DRAWABLE (widget))
656 if (GTK_WIDGET_HAS_FOCUS (widget))
657 gc = widget->style->black_gc;
658 else if (!GTK_WIDGET_IS_SENSITIVE (widget))
659 gc = widget->style->bg_gc[GTK_STATE_INSENSITIVE];
660 else if (widget->state == GTK_STATE_NORMAL)
661 gc = widget->style->base_gc[GTK_STATE_NORMAL];
663 gc = widget->style->bg_gc[widget->state];
667 if(GTK_TREE(widget->parent)->view_mode == GTK_TREE_VIEW_ITEM)
668 dx = GTK_TREE_ITEM(widget)->pixmaps_box->allocation.width + DEFAULT_DELTA +
669 GTK_TREE(widget->parent)->current_indent+1;
671 gdk_draw_rectangle (widget->window, gc, FALSE, dx, 0,
672 widget->allocation.width - 1 - dx,
673 widget->allocation.height - 1);
675 if(GTK_TREE(widget->parent)->view_line)
676 gtk_tree_item_draw_lines(widget);
681 gtk_tree_item_button_press (GtkWidget *widget,
682 GdkEventButton *event)
685 g_return_val_if_fail (widget != NULL, FALSE);
686 g_return_val_if_fail (GTK_IS_TREE_ITEM (widget), FALSE);
687 g_return_val_if_fail (event != NULL, FALSE);
689 if (event->type == GDK_BUTTON_PRESS
690 && GTK_WIDGET_IS_SENSITIVE(widget)
691 && !GTK_WIDGET_HAS_FOCUS (widget))
692 gtk_widget_grab_focus (widget);
698 gtk_tree_item_expose (GtkWidget *widget,
699 GdkEventExpose *event)
701 g_return_val_if_fail (widget != NULL, FALSE);
702 g_return_val_if_fail (GTK_IS_TREE_ITEM (widget), FALSE);
703 g_return_val_if_fail (event != NULL, FALSE);
705 if (GTK_WIDGET_DRAWABLE (widget))
706 gtk_tree_item_draw(widget, &event->area);
712 gtk_tree_item_focus_in (GtkWidget *widget,
713 GdkEventFocus *event)
716 g_return_val_if_fail (widget != NULL, FALSE);
717 g_return_val_if_fail (GTK_IS_TREE_ITEM (widget), FALSE);
718 g_return_val_if_fail (event != NULL, FALSE);
720 GTK_WIDGET_SET_FLAGS (widget, GTK_HAS_FOCUS);
721 gtk_widget_draw_focus (widget);
728 gtk_tree_item_focus_out (GtkWidget *widget,
729 GdkEventFocus *event)
732 g_return_val_if_fail (widget != NULL, FALSE);
733 g_return_val_if_fail (GTK_IS_TREE_ITEM (widget), FALSE);
734 g_return_val_if_fail (event != NULL, FALSE);
736 GTK_WIDGET_UNSET_FLAGS (widget, GTK_HAS_FOCUS);
737 gtk_widget_draw_focus (widget);
744 gtk_real_tree_item_select (GtkItem *item)
747 g_return_if_fail (item != NULL);
748 g_return_if_fail (GTK_IS_TREE_ITEM (item));
750 if (GTK_WIDGET (item)->state == GTK_STATE_SELECTED
751 || !GTK_WIDGET_IS_SENSITIVE(item))
754 if(GTK_TREE(GTK_WIDGET(item)->parent)->view_mode == GTK_TREE_VIEW_LINE)
755 gtk_widget_set_state (GTK_TREE_ITEM (item)->pixmaps_box, GTK_STATE_SELECTED);
757 gtk_widget_set_state (GTK_WIDGET (item), GTK_STATE_SELECTED);
759 gtk_widget_queue_draw (GTK_WIDGET (item));
763 gtk_real_tree_item_deselect (GtkItem *item)
766 g_return_if_fail (item != NULL);
767 g_return_if_fail (GTK_IS_TREE_ITEM (item));
769 if (GTK_WIDGET (item)->state == GTK_STATE_NORMAL)
772 if(GTK_WIDGET_MAPPED(GTK_WIDGET (item)))
774 gtk_widget_set_state (GTK_WIDGET (item), GTK_STATE_NORMAL);
776 if(GTK_TREE(GTK_WIDGET(item)->parent)->view_mode == GTK_TREE_VIEW_LINE)
777 gtk_widget_set_state (GTK_TREE_ITEM (item)->pixmaps_box, GTK_STATE_NORMAL);
779 gtk_widget_queue_draw (GTK_WIDGET (item));
784 gtk_real_tree_item_toggle (GtkItem *item)
787 g_return_if_fail (item != NULL);
788 g_return_if_fail (GTK_IS_TREE_ITEM (item));
790 if(!GTK_WIDGET_IS_SENSITIVE(item))
793 if (GTK_WIDGET (item)->parent && GTK_IS_TREE (GTK_WIDGET (item)->parent))
794 gtk_tree_select_child (GTK_TREE (GTK_WIDGET (item)->parent),
798 /* Should we really bother with this bit? A listitem not in a list?
799 * -Johannes Keukelaar
800 * yes, always be on the save side!
803 if (GTK_WIDGET (item)->state == GTK_STATE_SELECTED)
804 gtk_widget_set_state (GTK_WIDGET (item), GTK_STATE_NORMAL);
806 gtk_widget_set_state (GTK_WIDGET (item), GTK_STATE_SELECTED);
807 gtk_widget_queue_draw (GTK_WIDGET (item));
812 gtk_tree_item_marshal_signal (GtkObject *object,
817 GtkTreeItemSignal rfunc;
819 rfunc = (GtkTreeItemSignal) func;
821 (* rfunc) (object, GTK_VALUE_OBJECT (args[0]), func_data);
825 gtk_real_tree_item_expand (GtkTreeItem *tree_item)
829 g_return_if_fail (tree_item != NULL);
830 g_return_if_fail (GTK_IS_TREE_ITEM (tree_item));
831 g_return_if_fail (tree_item->subtree != NULL);
834 if(!tree_item->expanded)
836 tree = GTK_TREE(GTK_WIDGET(tree_item)->parent);
838 /* hide subtree widget */
839 gtk_widget_show(tree_item->subtree);
841 /* hide button '+' and show button '-' */
842 if(tree_item->pixmaps_box) {
843 gtk_container_remove(GTK_CONTAINER(tree_item->pixmaps_box),
844 tree_item->plus_pix_widget);
845 gtk_container_add(GTK_CONTAINER(tree_item->pixmaps_box),
846 tree_item->minus_pix_widget);
848 if(tree->root_tree) gtk_widget_queue_resize(GTK_WIDGET(tree->root_tree));
849 tree_item->expanded = TRUE;
854 gtk_real_tree_item_collapse (GtkTreeItem *tree_item)
858 g_return_if_fail (tree_item != NULL);
859 g_return_if_fail (GTK_IS_TREE_ITEM (tree_item));
860 g_return_if_fail (tree_item->subtree != NULL);
862 if(tree_item->expanded)
864 tree = GTK_TREE(GTK_WIDGET(tree_item)->parent);
866 /* hide subtree widget */
867 gtk_widget_hide(tree_item->subtree);
869 /* hide button '-' and show button '+' */
870 if(tree_item->pixmaps_box) {
871 gtk_container_remove(GTK_CONTAINER(tree_item->pixmaps_box),
872 tree_item->minus_pix_widget);
873 gtk_container_add(GTK_CONTAINER(tree_item->pixmaps_box),
874 tree_item->plus_pix_widget);
876 if(tree->root_tree) gtk_widget_queue_resize(GTK_WIDGET(tree->root_tree));
877 tree_item->expanded = FALSE;
883 gtk_tree_item_destroy (GtkObject *object)
888 g_return_if_fail (object != NULL);
889 g_return_if_fail (GTK_IS_TREE_ITEM (object));
891 item = GTK_TREE_ITEM(object);
893 /* free sub tree if it exist */
894 if((child = item->subtree))
896 gtk_widget_ref (child);
897 gtk_widget_unparent (child);
898 gtk_widget_destroy (child);
899 gtk_widget_unref (child);
900 item->subtree = NULL;
903 /* free pixmaps box */
904 if((child = item->pixmaps_box))
906 gtk_widget_ref (child);
907 gtk_widget_unparent (child);
908 gtk_widget_destroy (child);
909 gtk_widget_unref (child);
910 item->pixmaps_box = NULL;
913 /* destroy plus pixmap */
914 if (item->plus_pix_widget)
916 gtk_widget_destroy (item->plus_pix_widget);
917 gtk_widget_unref (item->plus_pix_widget);
918 item->plus_pix_widget = NULL;
921 /* destroy minus pixmap */
922 if (item->minus_pix_widget)
924 gtk_widget_destroy (item->minus_pix_widget);
925 gtk_widget_unref (item->minus_pix_widget);
926 item->minus_pix_widget = NULL;
929 if (GTK_OBJECT_CLASS (parent_class)->destroy)
930 (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
935 gtk_tree_item_remove_subtree (GtkTreeItem* item)
937 g_return_if_fail(item != NULL);
938 g_return_if_fail(GTK_IS_TREE_ITEM(item));
939 g_return_if_fail(item->subtree);
941 if(GTK_TREE(item->subtree)->children)
942 gtk_tree_remove_items(GTK_TREE(item->subtree),
943 GTK_TREE(item->subtree)->children);
945 if (GTK_WIDGET_MAPPED (item->subtree))
946 gtk_widget_unmap (item->subtree);
948 gtk_widget_unparent (item->subtree);
950 if(item->pixmaps_box)
951 gtk_widget_hide(item->pixmaps_box);
953 item->subtree = NULL;
954 item->expanded = FALSE;
955 if(item->pixmaps_box) {
956 gtk_container_remove(GTK_CONTAINER(item->pixmaps_box),
957 item->minus_pix_widget);
958 gtk_container_add(GTK_CONTAINER(item->pixmaps_box),
959 item->plus_pix_widget);
964 gtk_tree_item_map (GtkWidget *widget)
969 g_return_if_fail (widget != NULL);
970 g_return_if_fail (GTK_IS_TREE_ITEM (widget));
972 GTK_WIDGET_SET_FLAGS (widget, GTK_MAPPED);
973 bin = GTK_BIN (widget);
974 item = GTK_TREE_ITEM(widget);
976 if (!GTK_WIDGET_NO_WINDOW (widget))
977 gdk_window_show (widget->window);
979 gtk_widget_queue_draw (widget);
981 if(item->pixmaps_box &&
982 GTK_WIDGET_VISIBLE (item->pixmaps_box) &&
983 !GTK_WIDGET_MAPPED (item->pixmaps_box))
984 gtk_widget_map (item->pixmaps_box);
987 GTK_WIDGET_VISIBLE (bin->child) &&
988 !GTK_WIDGET_MAPPED (bin->child))
989 gtk_widget_map (bin->child);
993 gtk_tree_item_unmap (GtkWidget *widget)
998 g_return_if_fail (widget != NULL);
999 g_return_if_fail (GTK_IS_TREE_ITEM (widget));
1001 GTK_WIDGET_UNSET_FLAGS (widget, GTK_MAPPED);
1002 bin = GTK_BIN (widget);
1003 item = GTK_TREE_ITEM(widget);
1005 if (GTK_WIDGET_NO_WINDOW (widget))
1006 gdk_window_clear_area (widget->window,
1007 widget->allocation.x,
1008 widget->allocation.y,
1009 widget->allocation.width,
1010 widget->allocation.height);
1012 gdk_window_hide (widget->window);
1014 if(item->pixmaps_box &&
1015 GTK_WIDGET_VISIBLE (item->pixmaps_box) &&
1016 GTK_WIDGET_MAPPED (item->pixmaps_box))
1017 gtk_widget_unmap (bin->child);
1020 GTK_WIDGET_VISIBLE (bin->child) &&
1021 GTK_WIDGET_MAPPED (bin->child))
1022 gtk_widget_unmap (bin->child);