2 * Copyright (C) 2000 Red Hat, Inc., Jonathan Blandford <jrb@redhat.com>
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.
20 #include "gtktreeviewcolumn.h"
21 #include "gtktreeview.h"
22 #include "gtktreeprivate.h"
23 #include "gtksignal.h"
24 #include "gtkbutton.h"
25 #include "gtkalignment.h"
28 #include "gtkmarshalers.h"
58 typedef struct _GtkTreeViewColumnCellInfo GtkTreeViewColumnCellInfo;
59 struct _GtkTreeViewColumnCellInfo
61 GtkCellRenderer *cell;
63 GtkTreeCellDataFunc func;
65 GtkDestroyNotify destroy;
73 static void gtk_tree_view_column_init (GtkTreeViewColumn *tree_column);
74 static void gtk_tree_view_column_class_init (GtkTreeViewColumnClass *klass);
77 static void gtk_tree_view_column_set_property (GObject *object,
81 static void gtk_tree_view_column_get_property (GObject *object,
85 static void gtk_tree_view_column_finalize (GObject *object);
87 /* Button handling code */
88 static void gtk_tree_view_column_create_button (GtkTreeViewColumn *tree_column);
89 static void gtk_tree_view_column_update_button (GtkTreeViewColumn *tree_column);
91 /* Button signal handlers */
92 static gint gtk_tree_view_column_button_event (GtkWidget *widget,
95 static void gtk_tree_view_column_button_clicked (GtkWidget *widget,
97 static gboolean gtk_tree_view_column_mnemonic_activate (GtkWidget *widget,
98 gboolean group_cycling,
101 /* Property handlers */
102 static void gtk_tree_view_model_sort_column_changed (GtkTreeSortable *sortable,
103 GtkTreeViewColumn *tree_column);
105 /* Internal functions */
106 static void gtk_tree_view_column_sort (GtkTreeViewColumn *tree_column,
108 static void gtk_tree_view_column_setup_sort_column_id_callback (GtkTreeViewColumn *tree_column);
109 static void gtk_tree_view_column_set_attributesv (GtkTreeViewColumn *tree_column,
110 GtkCellRenderer *cell_renderer,
112 static GtkTreeViewColumnCellInfo *gtk_tree_view_column_get_cell_info (GtkTreeViewColumn *tree_column,
113 GtkCellRenderer *cell_renderer);
117 static GtkObjectClass *parent_class = NULL;
118 static guint tree_column_signals[LAST_SIGNAL] = { 0 };
122 gtk_tree_view_column_get_type (void)
124 static GtkType tree_column_type = 0;
126 if (!tree_column_type)
128 static const GTypeInfo tree_column_info =
130 sizeof (GtkTreeViewColumnClass),
131 NULL, /* base_init */
132 NULL, /* base_finalize */
133 (GClassInitFunc) gtk_tree_view_column_class_init,
134 NULL, /* class_finalize */
135 NULL, /* class_data */
136 sizeof (GtkTreeViewColumn),
138 (GInstanceInitFunc) gtk_tree_view_column_init,
141 tree_column_type = g_type_register_static (GTK_TYPE_OBJECT, "GtkTreeViewColumn", &tree_column_info, 0);
144 return tree_column_type;
148 gtk_tree_view_column_class_init (GtkTreeViewColumnClass *class)
150 GObjectClass *object_class;
152 object_class = (GObjectClass*) class;
154 parent_class = g_type_class_peek_parent (class);
156 class->clicked = NULL;
158 object_class->finalize = gtk_tree_view_column_finalize;
159 object_class->set_property = gtk_tree_view_column_set_property;
160 object_class->get_property = gtk_tree_view_column_get_property;
162 tree_column_signals[CLICKED] =
163 g_signal_new ("clicked",
164 GTK_CLASS_TYPE (object_class),
166 G_STRUCT_OFFSET (GtkTreeViewColumnClass, clicked),
168 _gtk_marshal_VOID__VOID,
171 g_object_class_install_property (object_class,
173 g_param_spec_boolean ("visible",
175 _("Whether to display the column"),
177 G_PARAM_READABLE | G_PARAM_WRITABLE));
179 g_object_class_install_property (object_class,
181 g_param_spec_boolean ("resizable",
183 _("Column is user-resizable"),
185 G_PARAM_READABLE | G_PARAM_WRITABLE));
187 g_object_class_install_property (object_class,
189 g_param_spec_int ("width",
191 _("Current width of the column"),
196 g_object_class_install_property (object_class,
198 g_param_spec_enum ("sizing",
200 _("Resize mode of the column"),
201 GTK_TYPE_TREE_VIEW_COLUMN_SIZING,
202 GTK_TREE_VIEW_COLUMN_AUTOSIZE,
203 G_PARAM_READABLE | G_PARAM_WRITABLE));
205 g_object_class_install_property (object_class,
207 g_param_spec_int ("fixed_width",
209 _("Current fixed width of the column"),
213 G_PARAM_READABLE | G_PARAM_WRITABLE));
215 g_object_class_install_property (object_class,
217 g_param_spec_int ("min_width",
219 _("Minimum allowed width of the column"),
223 G_PARAM_READABLE | G_PARAM_WRITABLE));
225 g_object_class_install_property (object_class,
227 g_param_spec_int ("max_width",
229 _("Maximum allowed width of the column"),
233 G_PARAM_READABLE | G_PARAM_WRITABLE));
235 g_object_class_install_property (object_class,
237 g_param_spec_string ("title",
239 _("Title to appear in column header"),
241 G_PARAM_READABLE | G_PARAM_WRITABLE));
243 g_object_class_install_property (object_class,
245 g_param_spec_boolean ("clickable",
247 _("Whether the header can be clicked"),
249 G_PARAM_READABLE | G_PARAM_WRITABLE));
252 g_object_class_install_property (object_class,
254 g_param_spec_object ("widget",
256 _("Widget to put in column header button instead of column title"),
258 G_PARAM_READABLE | G_PARAM_WRITABLE));
260 g_object_class_install_property (object_class,
262 g_param_spec_float ("alignment",
264 _("X Alignment of the column header text or widget"),
268 G_PARAM_READABLE | G_PARAM_WRITABLE));
270 g_object_class_install_property (object_class,
272 g_param_spec_boolean ("reorderable",
274 _("Whether the column can be reordered around the headers"),
276 G_PARAM_READABLE | G_PARAM_WRITABLE));
278 g_object_class_install_property (object_class,
280 g_param_spec_boolean ("sort_indicator",
282 _("Whether to show a sort indicator"),
284 G_PARAM_READABLE | G_PARAM_WRITABLE));
286 g_object_class_install_property (object_class,
288 g_param_spec_enum ("sort_order",
290 _("Sort direction the sort indicator should indicate"),
293 G_PARAM_READABLE | G_PARAM_WRITABLE));
298 gtk_tree_view_column_init (GtkTreeViewColumn *tree_column)
300 tree_column->button = NULL;
301 tree_column->xalign = 0.0;
302 tree_column->width = 0;
303 tree_column->requested_width = -1;
304 tree_column->min_width = -1;
305 tree_column->max_width = -1;
306 tree_column->resized_width = 0;
307 tree_column->column_type = GTK_TREE_VIEW_COLUMN_GROW_ONLY;
308 tree_column->visible = TRUE;
309 tree_column->resizable = FALSE;
310 tree_column->clickable = FALSE;
311 tree_column->dirty = TRUE;
312 tree_column->sort_order = GTK_SORT_ASCENDING;
313 tree_column->show_sort_indicator = FALSE;
314 tree_column->property_changed_signal = 0;
315 tree_column->sort_clicked_signal = 0;
316 tree_column->sort_column_changed_signal = 0;
317 tree_column->sort_column_id = -1;
318 tree_column->reorderable = FALSE;
319 tree_column->maybe_reordered = FALSE;
320 tree_column->use_resized_width = FALSE;
324 gtk_tree_view_column_finalize (GObject *object)
326 GtkTreeViewColumn *tree_column = (GtkTreeViewColumn *) object;
329 for (list = tree_column->cell_list; list; list = list->next)
331 GtkTreeViewColumnCellInfo *info = (GtkTreeViewColumnCellInfo *) list->data;
335 GtkDestroyNotify d = info->destroy;
337 info->destroy = NULL;
340 gtk_tree_view_column_clear_attributes (tree_column, info->cell);
341 g_object_unref (G_OBJECT (info->cell));
345 g_free (tree_column->title);
347 G_OBJECT_CLASS (parent_class)->finalize (object);
351 gtk_tree_view_column_set_property (GObject *object,
356 GtkTreeViewColumn *tree_column;
358 tree_column = GTK_TREE_VIEW_COLUMN (object);
363 gtk_tree_view_column_set_visible (tree_column,
364 g_value_get_boolean (value));
368 gtk_tree_view_column_set_resizable (tree_column,
369 g_value_get_boolean (value));
373 gtk_tree_view_column_set_sizing (tree_column,
374 g_value_get_enum (value));
377 case PROP_FIXED_WIDTH:
378 gtk_tree_view_column_set_fixed_width (tree_column,
379 g_value_get_int (value));
383 gtk_tree_view_column_set_min_width (tree_column,
384 g_value_get_int (value));
388 gtk_tree_view_column_set_max_width (tree_column,
389 g_value_get_int (value));
393 gtk_tree_view_column_set_title (tree_column,
394 g_value_get_string (value));
398 gtk_tree_view_column_set_clickable (tree_column,
399 g_value_get_boolean (value));
403 gtk_tree_view_column_set_widget (tree_column,
404 (GtkWidget*) g_value_get_object (value));
408 gtk_tree_view_column_set_alignment (tree_column,
409 g_value_get_float (value));
412 case PROP_REORDERABLE:
413 gtk_tree_view_column_set_reorderable (tree_column,
414 g_value_get_boolean (value));
417 case PROP_SORT_INDICATOR:
418 gtk_tree_view_column_set_sort_indicator (tree_column,
419 g_value_get_boolean (value));
422 case PROP_SORT_ORDER:
423 gtk_tree_view_column_set_sort_order (tree_column,
424 g_value_get_enum (value));
428 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
434 gtk_tree_view_column_get_property (GObject *object,
439 GtkTreeViewColumn *tree_column;
441 tree_column = GTK_TREE_VIEW_COLUMN (object);
446 g_value_set_boolean (value,
447 gtk_tree_view_column_get_visible (tree_column));
451 g_value_set_boolean (value,
452 gtk_tree_view_column_get_resizable (tree_column));
456 g_value_set_int (value,
457 gtk_tree_view_column_get_width (tree_column));
461 g_value_set_enum (value,
462 gtk_tree_view_column_get_sizing (tree_column));
465 case PROP_FIXED_WIDTH:
466 g_value_set_int (value,
467 gtk_tree_view_column_get_fixed_width (tree_column));
471 g_value_set_int (value,
472 gtk_tree_view_column_get_min_width (tree_column));
476 g_value_set_int (value,
477 gtk_tree_view_column_get_max_width (tree_column));
481 g_value_set_string (value,
482 gtk_tree_view_column_get_title (tree_column));
486 g_value_set_boolean (value,
487 gtk_tree_view_column_get_clickable (tree_column));
491 g_value_set_object (value,
492 (GObject*) gtk_tree_view_column_get_widget (tree_column));
496 g_value_set_float (value,
497 gtk_tree_view_column_get_alignment (tree_column));
500 case PROP_REORDERABLE:
501 g_value_set_boolean (value,
502 gtk_tree_view_column_get_reorderable (tree_column));
505 case PROP_SORT_INDICATOR:
506 g_value_set_boolean (value,
507 gtk_tree_view_column_get_sort_indicator (tree_column));
510 case PROP_SORT_ORDER:
511 g_value_set_enum (value,
512 gtk_tree_view_column_get_sort_order (tree_column));
516 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
524 /* Button handling code
527 gtk_tree_view_column_create_button (GtkTreeViewColumn *tree_column)
529 GtkTreeView *tree_view;
533 tree_view = (GtkTreeView *) tree_column->tree_view;
535 g_return_if_fail (GTK_IS_TREE_VIEW (tree_view));
536 g_return_if_fail (tree_column->button == NULL);
538 gtk_widget_push_composite_child ();
539 tree_column->button = gtk_button_new ();
540 gtk_widget_add_events (tree_column->button, GDK_POINTER_MOTION_MASK);
541 gtk_widget_pop_composite_child ();
543 /* make sure we own a reference to it as well. */
544 if (tree_view->priv->header_window)
545 gtk_widget_set_parent_window (tree_column->button, tree_view->priv->header_window);
546 gtk_widget_set_parent (tree_column->button, GTK_WIDGET (tree_view));
548 g_signal_connect (G_OBJECT (tree_column->button), "event",
549 G_CALLBACK (gtk_tree_view_column_button_event),
550 (gpointer) tree_column);
551 g_signal_connect (G_OBJECT (tree_column->button), "clicked",
552 (GtkSignalFunc) gtk_tree_view_column_button_clicked,
553 (gpointer) tree_column);
555 tree_column->alignment = gtk_alignment_new (tree_column->xalign, 0.5, 0.0, 0.0);
557 hbox = gtk_hbox_new (FALSE, 2);
558 tree_column->arrow = gtk_arrow_new (GTK_ARROW_DOWN, GTK_SHADOW_IN);
560 if (tree_column->child)
561 child = tree_column->child;
564 child = gtk_label_new (tree_column->title);
565 gtk_widget_show (child);
568 g_signal_connect (G_OBJECT (child), "mnemonic_activate",
569 G_CALLBACK (gtk_tree_view_column_mnemonic_activate),
570 (gpointer) tree_column);
572 if (tree_column->xalign <= 0.5)
573 gtk_box_pack_end (GTK_BOX (hbox), tree_column->arrow, FALSE, FALSE, 0);
575 gtk_box_pack_start (GTK_BOX (hbox), tree_column->arrow, FALSE, FALSE, 0);
577 gtk_box_pack_start (GTK_BOX (hbox), tree_column->alignment, TRUE, TRUE, 0);
579 gtk_container_add (GTK_CONTAINER (tree_column->alignment), child);
580 gtk_container_add (GTK_CONTAINER (tree_column->button), hbox);
582 gtk_widget_show (hbox);
583 gtk_widget_show (tree_column->alignment);
584 gtk_tree_view_column_update_button (tree_column);
588 gtk_tree_view_column_update_button (GtkTreeViewColumn *tree_column)
591 GtkWidget *alignment;
593 GtkWidget *current_child;
595 /* Create a button if necessary */
596 if (tree_column->visible &&
597 tree_column->button == NULL &&
598 tree_column->tree_view &&
599 GTK_WIDGET_REALIZED (tree_column->tree_view))
600 gtk_tree_view_column_create_button (tree_column);
602 if (! tree_column->button)
605 hbox = GTK_BIN (tree_column->button)->child;
606 alignment = tree_column->alignment;
607 arrow = tree_column->arrow;
608 current_child = GTK_BIN (alignment)->child;
610 /* Set up the actual button */
611 gtk_alignment_set (GTK_ALIGNMENT (alignment), tree_column->xalign,
614 if (tree_column->child)
616 if (current_child != tree_column->child)
618 gtk_container_remove (GTK_CONTAINER (alignment),
620 gtk_container_add (GTK_CONTAINER (alignment),
626 if (current_child == NULL)
628 current_child = gtk_label_new (NULL);
629 gtk_widget_show (current_child);
630 gtk_container_add (GTK_CONTAINER (alignment),
634 g_return_if_fail (GTK_IS_LABEL (current_child));
636 if (tree_column->title)
637 gtk_label_set_text_with_mnemonic (GTK_LABEL (current_child),
640 gtk_label_set_text_with_mnemonic (GTK_LABEL (current_child),
644 switch (tree_column->sort_order)
646 case GTK_SORT_ASCENDING:
647 gtk_arrow_set (GTK_ARROW (arrow),
652 case GTK_SORT_DESCENDING:
653 gtk_arrow_set (GTK_ARROW (arrow),
659 g_warning (G_STRLOC": bad sort order");
663 /* Put arrow on the right if the text is left-or-center justified, and on the
664 * left otherwise; do this by packing boxes, so flipping text direction will
667 gtk_widget_ref (arrow);
668 gtk_container_remove (GTK_CONTAINER (hbox), arrow);
670 if (tree_column->xalign <= 0.5)
672 gtk_box_pack_end (GTK_BOX (hbox), arrow, FALSE, FALSE, 0);
676 gtk_box_pack_start (GTK_BOX (hbox), arrow, FALSE, FALSE, 0);
677 /* move it to the front */
678 gtk_box_reorder_child (GTK_BOX (hbox), arrow, 0);
680 gtk_widget_unref (arrow);
682 if (tree_column->show_sort_indicator)
683 gtk_widget_show (arrow);
685 gtk_widget_hide (arrow);
687 /* It's always safe to hide the button. It isn't always safe to show it, as
688 * if you show it before it's realized, it'll get the wrong window. */
689 if (tree_column->button &&
690 tree_column->tree_view != NULL &&
691 GTK_WIDGET_REALIZED (tree_column->tree_view))
693 if (tree_column->visible)
695 gtk_widget_show_now (tree_column->button);
696 if (tree_column->window)
698 if (tree_column->resizable)
700 gdk_window_show (tree_column->window);
701 gdk_window_raise (tree_column->window);
705 gdk_window_hide (tree_column->window);
711 gtk_widget_hide (tree_column->button);
712 if (tree_column->window)
713 gdk_window_hide (tree_column->window);
717 if (tree_column->reorderable || tree_column->clickable)
719 GTK_WIDGET_SET_FLAGS (tree_column->button, GTK_CAN_FOCUS);
723 GTK_WIDGET_UNSET_FLAGS (tree_column->button, GTK_CAN_FOCUS);
724 if (GTK_WIDGET_HAS_FOCUS (tree_column->button))
726 GtkWidget *toplevel = gtk_widget_get_toplevel (tree_column->tree_view);
727 if (GTK_WIDGET_TOPLEVEL (toplevel))
729 gtk_window_set_focus (GTK_WINDOW (toplevel), NULL);
733 /* Queue a resize on the assumption that we always want to catch all changes
734 * and columns don't change all that often.
736 if (GTK_WIDGET_REALIZED (tree_column->tree_view))
737 gtk_widget_queue_resize (tree_column->tree_view);
741 /* Button signal handlers
745 gtk_tree_view_column_button_event (GtkWidget *widget,
749 GtkTreeViewColumn *column = (GtkTreeViewColumn *) data;
751 g_return_val_if_fail (event != NULL, FALSE);
753 if (event->type == GDK_BUTTON_PRESS &&
756 column->maybe_reordered = TRUE;
757 gdk_window_get_pointer (widget->window,
761 gtk_widget_grab_focus (widget);
764 if (event->type == GDK_BUTTON_RELEASE &&
765 column->maybe_reordered)
766 column->maybe_reordered = FALSE;
768 if (event->type == GDK_MOTION_NOTIFY &&
769 (column->maybe_reordered) &&
770 (gtk_drag_check_threshold (widget,
773 (gint) ((GdkEventMotion *)event)->x,
774 (gint) ((GdkEventMotion *)event)->y)))
776 column->maybe_reordered = FALSE;
777 /* this is to change our drag_x to be relative to
778 * tree_view->priv->bin_window, instead of our window.
780 column->drag_x -= column->button->allocation.x;
781 _gtk_tree_view_column_start_drag (GTK_TREE_VIEW (column->tree_view), column);
784 if (column->clickable == FALSE)
788 case GDK_BUTTON_PRESS:
789 case GDK_2BUTTON_PRESS:
790 case GDK_3BUTTON_PRESS:
791 case GDK_MOTION_NOTIFY:
792 case GDK_BUTTON_RELEASE:
793 case GDK_ENTER_NOTIFY:
794 case GDK_LEAVE_NOTIFY:
805 gtk_tree_view_column_button_clicked (GtkWidget *widget, gpointer data)
807 g_signal_emit_by_name (G_OBJECT (data), "clicked");
811 gtk_tree_view_column_mnemonic_activate (GtkWidget *widget,
812 gboolean group_cycling,
815 GtkTreeViewColumn *column = (GtkTreeViewColumn *)data;
817 g_return_val_if_fail (GTK_IS_TREE_VIEW_COLUMN (column), FALSE);
819 GTK_TREE_VIEW (column->tree_view)->priv->focus_column = column;
820 if (column->clickable)
821 gtk_button_clicked (GTK_BUTTON (column->button));
822 else if (GTK_WIDGET_CAN_FOCUS (column->button))
823 gtk_widget_grab_focus (column->button);
825 gtk_widget_grab_focus (column->tree_view);
831 gtk_tree_view_model_sort_column_changed (GtkTreeSortable *sortable,
832 GtkTreeViewColumn *column)
837 if (gtk_tree_sortable_get_sort_column_id (sortable,
841 if (sort_column_id == column->sort_column_id)
843 gtk_tree_view_column_set_sort_indicator (column, TRUE);
844 gtk_tree_view_column_set_sort_order (column, order);
848 gtk_tree_view_column_set_sort_indicator (column, FALSE);
853 gtk_tree_view_column_set_sort_indicator (column, FALSE);
858 gtk_tree_view_column_sort (GtkTreeViewColumn *tree_column,
863 gboolean has_sort_column;
864 gboolean has_default_sort_func;
866 g_return_if_fail (tree_column->tree_view != NULL);
869 gtk_tree_sortable_get_sort_column_id (GTK_TREE_SORTABLE (GTK_TREE_VIEW (tree_column->tree_view)->priv->model),
872 has_default_sort_func =
873 gtk_tree_sortable_has_default_sort_func (GTK_TREE_SORTABLE (GTK_TREE_VIEW (tree_column->tree_view)->priv->model));
875 if (has_sort_column &&
876 sort_column_id == tree_column->sort_column_id)
878 if (order == GTK_SORT_ASCENDING)
879 gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (GTK_TREE_VIEW (tree_column->tree_view)->priv->model),
880 tree_column->sort_column_id,
881 GTK_SORT_DESCENDING);
882 else if (order == GTK_SORT_DESCENDING && has_default_sort_func)
883 gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (GTK_TREE_VIEW (tree_column->tree_view)->priv->model),
884 GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID,
887 gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (GTK_TREE_VIEW (tree_column->tree_view)->priv->model),
888 tree_column->sort_column_id,
893 gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (GTK_TREE_VIEW (tree_column->tree_view)->priv->model),
894 tree_column->sort_column_id,
901 gtk_tree_view_column_setup_sort_column_id_callback (GtkTreeViewColumn *tree_column)
905 if (tree_column->tree_view == NULL)
908 model = gtk_tree_view_get_model (GTK_TREE_VIEW (tree_column->tree_view));
913 if (GTK_IS_TREE_SORTABLE (model) &&
914 tree_column->sort_column_id != -1)
916 gint real_sort_column_id;
917 GtkSortType real_order;
919 if (tree_column->sort_column_changed_signal == 0)
920 tree_column->sort_column_changed_signal =
921 g_signal_connect (G_OBJECT (model), "sort_column_changed",
922 GTK_SIGNAL_FUNC (gtk_tree_view_model_sort_column_changed),
925 if (gtk_tree_sortable_get_sort_column_id (GTK_TREE_SORTABLE (model),
926 &real_sort_column_id,
928 (real_sort_column_id == tree_column->sort_column_id))
930 gtk_tree_view_column_set_sort_indicator (tree_column, TRUE);
931 gtk_tree_view_column_set_sort_order (tree_column, real_order);
939 /* Exported Private Functions.
940 * These should only be called by gtktreeview.c or gtktreeviewcolumn.c
944 _gtk_tree_view_column_realize_button (GtkTreeViewColumn *column)
946 GtkTreeView *tree_view;
948 guint attributes_mask;
950 tree_view = (GtkTreeView *)column->tree_view;
952 g_return_if_fail (GTK_IS_TREE_VIEW (tree_view));
953 g_return_if_fail (GTK_WIDGET_REALIZED (tree_view));
954 g_return_if_fail (tree_view->priv->header_window != NULL);
955 g_return_if_fail (column->button != NULL);
957 gtk_widget_set_parent_window (column->button, tree_view->priv->header_window);
960 gtk_widget_show (column->button);
962 attr.window_type = GDK_WINDOW_CHILD;
963 attr.wclass = GDK_INPUT_ONLY;
964 attr.visual = gtk_widget_get_visual (GTK_WIDGET (tree_view));
965 attr.colormap = gtk_widget_get_colormap (GTK_WIDGET (tree_view));
966 attr.event_mask = gtk_widget_get_events (GTK_WIDGET (tree_view));
967 attr.event_mask = (GDK_BUTTON_PRESS_MASK |
968 GDK_BUTTON_RELEASE_MASK |
969 GDK_POINTER_MOTION_MASK |
970 GDK_POINTER_MOTION_HINT_MASK |
972 attributes_mask = GDK_WA_CURSOR | GDK_WA_X | GDK_WA_Y;
973 attr.cursor = gdk_cursor_new (GDK_SB_H_DOUBLE_ARROW);
976 attr.width = TREE_VIEW_DRAG_WIDTH;
977 attr.height = tree_view->priv->header_height;
979 attr.x = (column->button->allocation.x + column->button->allocation.width) - 3;
981 column->window = gdk_window_new (tree_view->priv->header_window,
982 &attr, attributes_mask);
983 gdk_window_set_user_data (column->window, tree_view);
985 gtk_tree_view_column_update_button (column);
987 gdk_cursor_unref (attr.cursor);
991 _gtk_tree_view_column_unrealize_button (GtkTreeViewColumn *column)
993 g_return_if_fail (column != NULL);
994 g_return_if_fail (column->window != NULL);
996 gdk_window_set_user_data (column->window, NULL);
997 gdk_window_destroy (column->window);
998 column->window = NULL;
1002 _gtk_tree_view_column_set_tree_view (GtkTreeViewColumn *column,
1003 GtkTreeView *tree_view)
1005 g_assert (column->tree_view == NULL);
1007 column->tree_view = GTK_WIDGET (tree_view);
1008 gtk_tree_view_column_create_button (column);
1010 column->property_changed_signal =
1011 g_signal_connect_swapped (GTK_OBJECT (tree_view),
1013 GTK_SIGNAL_FUNC (gtk_tree_view_column_setup_sort_column_id_callback),
1016 gtk_tree_view_column_setup_sort_column_id_callback (column);
1020 _gtk_tree_view_column_unset_tree_view (GtkTreeViewColumn *column)
1022 if (column->tree_view && column->button)
1024 gtk_container_remove (GTK_CONTAINER (column->tree_view), column->button);
1026 if (column->property_changed_signal)
1028 g_signal_handler_disconnect (G_OBJECT (column->tree_view), column->property_changed_signal);
1029 column->property_changed_signal = 0;
1032 if (column->sort_column_changed_signal)
1034 g_signal_handler_disconnect (G_OBJECT (gtk_tree_view_get_model (GTK_TREE_VIEW (column->tree_view))),
1035 column->sort_column_changed_signal);
1036 column->sort_column_changed_signal = 0;
1039 column->tree_view = NULL;
1040 column->button = NULL;
1043 /* Public Functions */
1047 * gtk_tree_view_column_new:
1049 * Creates a new #GtkTreeViewColumn.
1051 * Return value: A newly created #GtkTreeViewColumn.
1054 gtk_tree_view_column_new (void)
1056 GtkTreeViewColumn *tree_column;
1058 tree_column = GTK_TREE_VIEW_COLUMN (gtk_type_new (GTK_TYPE_TREE_VIEW_COLUMN));
1064 * gtk_tree_view_column_new_with_attributes:
1065 * @title: The title to set the header to.
1066 * @cell: The #GtkCellRenderer.
1067 * @Varargs: A %NULL-terminated list of attributes.
1069 * Creates a new #GtkTreeViewColumn with a number of default values. This is
1070 * equivalent to calling gtk_tree_view_column_set_title(),
1071 * gtk_tree_view_column_pack_start(), and
1072 * gtk_tree_view_column_set_attributes() on the newly created #GtkTreeViewColumn.
1074 * Here's a simple example:
1075 * <informalexample><programlisting>
1076 * <!>enum { TEXT_COLUMN, COLOR_COLUMN, N_COLUMNS };
1079 * <!> GtkTreeViewColumn *column;
1080 * <!> GtkCellRenderer *renderer = gtk_cell_renderer_text_new ();
1082 * <!> column = gtk_tree_view_column_new_with_attributes ("Title",
1084 * <!> "text", TEXT_COLUMN,
1085 * <!> "foreground", COLOR_COLUMN,
1088 * </programlisting></informalexample>
1090 * Return value: A newly created #GtkTreeViewColumn.
1093 gtk_tree_view_column_new_with_attributes (const gchar *title,
1094 GtkCellRenderer *cell,
1097 GtkTreeViewColumn *retval;
1100 retval = gtk_tree_view_column_new ();
1102 gtk_tree_view_column_set_title (retval, title);
1103 gtk_tree_view_column_pack_start (retval, cell, TRUE);
1105 va_start (args, cell);
1106 gtk_tree_view_column_set_attributesv (retval, cell, args);
1112 static GtkTreeViewColumnCellInfo *
1113 gtk_tree_view_column_get_cell_info (GtkTreeViewColumn *tree_column,
1114 GtkCellRenderer *cell_renderer)
1117 for (list = tree_column->cell_list; list; list = list->next)
1118 if (((GtkTreeViewColumnCellInfo *)list->data)->cell == cell_renderer)
1119 return (GtkTreeViewColumnCellInfo *) list->data;
1125 * gtk_tree_view_column_pack_start:
1126 * @tree_column: A #GtkTreeViewColumn.
1127 * @cell: The #GtkCellRenderer.
1128 * @expand: %TRUE if @cell is to be given extra space allocated to box.
1130 * Packs the @cell into the beginning column. If @expand is %TRUE, then the
1131 * @cell is allocated a share of all available space that the @tree_column has.
1134 gtk_tree_view_column_pack_start (GtkTreeViewColumn *tree_column,
1135 GtkCellRenderer *cell,
1138 GtkTreeViewColumnCellInfo *cell_info;
1140 g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column));
1141 g_return_if_fail (GTK_IS_CELL_RENDERER (cell));
1142 g_return_if_fail (! gtk_tree_view_column_get_cell_info (tree_column, cell));
1144 g_object_ref (G_OBJECT (cell));
1145 gtk_object_sink (GTK_OBJECT (cell));
1147 cell_info = g_new0 (GtkTreeViewColumnCellInfo, 1);
1148 cell_info->cell = cell;
1149 cell_info->expand = expand ? TRUE : FALSE;
1150 cell_info->pack = GTK_PACK_START;
1151 cell_info->has_focus = 0;
1152 cell_info->attributes = NULL;
1154 tree_column->cell_list = g_list_append (tree_column->cell_list, cell_info);
1158 * gtk_tree_view_column_pack_end:
1159 * @tree_column: A #GtkTreeViewColumn.
1160 * @cell: The #GtkCellRenderer.
1161 * @expand: %TRUE if @cell is to be given extra space allocated to box.
1163 * Packs the @cell into the column. If @expand is %TRUE, then the @cell is
1164 * allocated a share of all available space that the @tree_column has.
1167 gtk_tree_view_column_pack_end (GtkTreeViewColumn *tree_column,
1168 GtkCellRenderer *cell,
1171 GtkTreeViewColumnCellInfo *cell_info;
1173 g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column));
1174 g_return_if_fail (GTK_IS_CELL_RENDERER (cell));
1175 g_return_if_fail (! gtk_tree_view_column_get_cell_info (tree_column, cell));
1177 g_object_ref (G_OBJECT (cell));
1178 gtk_object_sink (GTK_OBJECT (cell));
1180 cell_info = g_new (GtkTreeViewColumnCellInfo, 1);
1181 cell_info->cell = cell;
1182 cell_info->expand = expand ? TRUE : FALSE;
1183 cell_info->pack = GTK_PACK_END;
1184 cell_info->has_focus = 0;
1185 cell_info->attributes = NULL;
1187 tree_column->cell_list = g_list_append (tree_column->cell_list, cell_info);
1192 * gtk_tree_view_column_clear:
1193 * @tree_column: A #GtkTreeViewColumn
1195 * Unsets all the mappings on all renderers on the @tree_column.
1198 gtk_tree_view_column_clear (GtkTreeViewColumn *tree_column)
1201 g_return_if_fail (tree_column != NULL);
1203 for (list = tree_column->cell_list; list; list = list->next)
1205 GtkTreeViewColumnCellInfo *info = (GtkTreeViewColumnCellInfo *)list->data;
1207 gtk_tree_view_column_clear_attributes (tree_column, info->cell);
1208 g_object_unref (G_OBJECT (info->cell));
1212 g_list_free (tree_column->cell_list);
1213 tree_column->cell_list = NULL;
1217 * gtk_tree_view_column_get_cell_renderers:
1218 * @tree_column: A #GtkTreeViewColumn
1220 * Returns a newly-allocated #GList of all the cell renderers in the column,
1221 * in no particular order. The list must be freed with g_list_free().
1223 * Return value: A list of #GtkCellRenderers
1226 gtk_tree_view_column_get_cell_renderers (GtkTreeViewColumn *tree_column)
1228 GList *retval = NULL, *list;
1230 g_return_val_if_fail (tree_column != NULL, NULL);
1232 for (list = tree_column->cell_list; list; list = list->next)
1234 GtkTreeViewColumnCellInfo *info = (GtkTreeViewColumnCellInfo *)list->data;
1236 retval = g_list_append (retval, info->cell);
1243 * gtk_tree_view_column_add_attribute:
1244 * @tree_column: A #GtkTreeViewColumn.
1245 * @cell_renderer: the #GtkCellRenderer to set attributes on
1246 * @attribute: An attribute on the renderer
1247 * @column: The column position on the model to get the attribute from.
1249 * Adds an attribute mapping to the list in @tree_column. The @column is the
1250 * column of the model to get a value from, and the @attribute is the
1251 * parameter on @cell_renderer to be set from the value. So for example
1252 * if column 2 of the model contains strings, you could have the
1253 * "text" attribute of a #GtkCellRendererText get its values from
1257 gtk_tree_view_column_add_attribute (GtkTreeViewColumn *tree_column,
1258 GtkCellRenderer *cell_renderer,
1259 const gchar *attribute,
1262 GtkTreeViewColumnCellInfo *info;
1264 g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column));
1265 info = gtk_tree_view_column_get_cell_info (tree_column, cell_renderer);
1266 g_return_if_fail (info != NULL);
1268 info->attributes = g_slist_prepend (info->attributes, GINT_TO_POINTER (column));
1269 info->attributes = g_slist_prepend (info->attributes, g_strdup (attribute));
1271 if (tree_column->tree_view)
1272 _gtk_tree_view_column_cell_set_dirty (tree_column, TRUE);
1277 gtk_tree_view_column_set_attributesv (GtkTreeViewColumn *tree_column,
1278 GtkCellRenderer *cell_renderer,
1284 attribute = va_arg (args, gchar *);
1286 gtk_tree_view_column_clear_attributes (tree_column, cell_renderer);
1288 while (attribute != NULL)
1290 column = va_arg (args, gint);
1291 gtk_tree_view_column_add_attribute (tree_column, cell_renderer, attribute, column);
1292 attribute = va_arg (args, gchar *);
1297 * gtk_tree_view_column_set_attributes:
1298 * @tree_column: A #GtkTreeViewColumn.
1299 * @cell_renderer: the #GtkCellRenderer we're setting the attributes of
1300 * @Varargs: A %NULL-terminated list of attributes.
1302 * Sets the attributes in the list as the attributes of @tree_column.
1303 * The attributes should be in attribute/column order, as in
1304 * gtk_tree_view_column_add_attribute(). All existing attributes
1305 * are removed, and replaced with the new attributes.
1308 gtk_tree_view_column_set_attributes (GtkTreeViewColumn *tree_column,
1309 GtkCellRenderer *cell_renderer,
1314 g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column));
1315 g_return_if_fail (GTK_IS_CELL_RENDERER (cell_renderer));
1316 g_return_if_fail (gtk_tree_view_column_get_cell_info (tree_column, cell_renderer));
1318 va_start (args, cell_renderer);
1319 gtk_tree_view_column_set_attributesv (tree_column, cell_renderer, args);
1325 * gtk_tree_view_column_set_cell_data_func:
1326 * @tree_column: A #GtkTreeViewColumn
1327 * @cell_renderer: A #GtkCellRenderer
1328 * @func: The #GtkTreeViewColumnFunc to use.
1329 * @func_data: The user data for @func.
1330 * @destroy: The destroy notification for @func_data
1332 * Sets the #GtkTreeViewColumnFunc to use for the column. This
1333 * function is used instead of the standard attributes mapping for
1334 * setting the column value, and should set the value of @tree_column's
1335 * cell renderer as appropriate. @func may be %NULL to remove an
1339 gtk_tree_view_column_set_cell_data_func (GtkTreeViewColumn *tree_column,
1340 GtkCellRenderer *cell_renderer,
1341 GtkTreeCellDataFunc func,
1343 GtkDestroyNotify destroy)
1345 GtkTreeViewColumnCellInfo *info;
1347 g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column));
1348 g_return_if_fail (GTK_IS_CELL_RENDERER (cell_renderer));
1349 info = gtk_tree_view_column_get_cell_info (tree_column, cell_renderer);
1351 g_return_if_fail (info != NULL);
1355 GtkDestroyNotify d = info->destroy;
1357 info->destroy = NULL;
1358 d (info->func_data);
1362 info->func_data = func_data;
1363 info->destroy = destroy;
1365 if (tree_column->tree_view)
1366 _gtk_tree_view_column_cell_set_dirty (tree_column, TRUE);
1371 * gtk_tree_view_column_clear_attributes:
1372 * @tree_column: a #GtkTreeViewColumn
1373 * @cell_renderer: a #GtkCellRenderer to clear the attribute mapping on.
1375 * Clears all existing attributes previously set with
1376 * gtk_tree_view_column_set_attributes().
1379 gtk_tree_view_column_clear_attributes (GtkTreeViewColumn *tree_column,
1380 GtkCellRenderer *cell_renderer)
1382 GtkTreeViewColumnCellInfo *info;
1385 g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column));
1386 g_return_if_fail (GTK_IS_CELL_RENDERER (cell_renderer));
1387 info = gtk_tree_view_column_get_cell_info (tree_column, cell_renderer);
1389 list = info->attributes;
1391 while (list && list->next)
1393 g_free (list->data);
1394 list = list->next->next;
1396 g_slist_free (info->attributes);
1397 info->attributes = NULL;
1399 if (tree_column->tree_view)
1400 _gtk_tree_view_column_cell_set_dirty (tree_column, TRUE);
1405 * gtk_tree_view_column_set_spacing:
1406 * @tree_column: A #GtkTreeViewColumn.
1407 * @spacing: distance between cell renderers in pixels.
1409 * Sets the spacing field of @tree_column, which is the number of pixels to
1410 * place between cell renderers packed into it.
1413 gtk_tree_view_column_set_spacing (GtkTreeViewColumn *tree_column,
1416 g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column));
1417 g_return_if_fail (spacing >= 0);
1419 if (tree_column->spacing == spacing)
1422 tree_column->spacing = spacing;
1423 if (tree_column->tree_view)
1424 _gtk_tree_view_column_cell_set_dirty (tree_column, TRUE);
1428 * gtk_tree_view_column_get_spacing:
1429 * @tree_column: A #GtkTreeViewColumn.
1431 * Returns the spacing of @tree_column.
1433 * Return value: the spacing of @tree_column.
1436 gtk_tree_view_column_get_spacing (GtkTreeViewColumn *tree_column)
1438 g_return_val_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column), 0);
1440 return tree_column->spacing;
1443 /* Options for manipulating the columns */
1446 * gtk_tree_view_column_set_visible:
1447 * @tree_column: A #GtkTreeViewColumn.
1448 * @visible: %TRUE if the @tree_column is visible.
1450 * Sets the visibility of @tree_column.
1453 gtk_tree_view_column_set_visible (GtkTreeViewColumn *tree_column,
1456 g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column));
1458 visible = !! visible;
1460 if (tree_column->visible == visible)
1463 tree_column->visible = visible;
1465 if (tree_column->visible)
1466 _gtk_tree_view_column_cell_set_dirty (tree_column, TRUE);
1468 gtk_tree_view_column_update_button (tree_column);
1469 g_object_notify (G_OBJECT (tree_column), "visible");
1473 * gtk_tree_view_column_get_visible:
1474 * @tree_column: A #GtkTreeViewColumn.
1476 * Returns %TRUE if @tree_column is visible.
1478 * Return value: whether the column is visible or not. If it is visible, then
1479 * the tree will show the column.
1482 gtk_tree_view_column_get_visible (GtkTreeViewColumn *tree_column)
1484 g_return_val_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column), FALSE);
1486 return tree_column->visible;
1490 * gtk_tree_view_column_set_resizable:
1491 * @tree_column: A #GtkTreeViewColumn
1492 * @resizable: %TRUE, if the column can be resized
1494 * If @resizable is %TRUE, then the user can explicitly resize the column by
1495 * grabbing the outer edge of the column button. If resizable is TRUE and
1496 * sizing mode of the column is #GTK_TREE_VIEW_COLUMN_AUTOSIZE, then the sizing
1497 * mode is changed to #GTK_TREE_VIEW_COLUMN_GROW_ONLY.
1500 gtk_tree_view_column_set_resizable (GtkTreeViewColumn *tree_column,
1503 g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column));
1505 resizable = !! resizable;
1507 if (tree_column->resizable == resizable)
1510 tree_column->resizable = resizable;
1512 if (resizable && tree_column->column_type == GTK_TREE_VIEW_COLUMN_AUTOSIZE)
1513 gtk_tree_view_column_set_sizing (tree_column, GTK_TREE_VIEW_COLUMN_GROW_ONLY);
1515 gtk_tree_view_column_update_button (tree_column);
1517 g_object_notify (G_OBJECT (tree_column), "resizable");
1521 * gtk_tree_view_column_get_resizable:
1522 * @tree_column: A #GtkTreeViewColumn
1524 * Returns #TRUE if the @tree_column can be resized by the end user.
1526 * Return value: #TRUE, if the @tree_column can be resized.
1529 gtk_tree_view_column_get_resizable (GtkTreeViewColumn *tree_column)
1531 g_return_val_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column), FALSE);
1533 return tree_column->resizable;
1538 * gtk_tree_view_column_set_sizing:
1539 * @tree_column: A #GtkTreeViewColumn.
1540 * @type: The #GtkTreeViewColumnSizing.
1542 * Sets the growth behavior of @tree_column to @type.
1545 gtk_tree_view_column_set_sizing (GtkTreeViewColumn *tree_column,
1546 GtkTreeViewColumnSizing type)
1548 g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column));
1550 if (type == tree_column->column_type)
1553 if (type == GTK_TREE_VIEW_COLUMN_AUTOSIZE)
1554 gtk_tree_view_column_set_resizable (tree_column, FALSE);
1557 /* I was clearly on crack when I wrote this. I'm not sure what's supposed to
1558 * be below so I'll leave it until I figure it out.
1560 if (tree_column->column_type == GTK_TREE_VIEW_COLUMN_AUTOSIZE &&
1561 tree_column->requested_width != -1)
1563 gtk_tree_view_column_set_sizing (tree_column, tree_column->requested_width);
1566 tree_column->column_type = type;
1568 gtk_tree_view_column_update_button (tree_column);
1570 g_object_notify (G_OBJECT (tree_column), "sizing");
1574 * gtk_tree_view_column_get_sizing:
1575 * @tree_column: A #GtkTreeViewColumn.
1577 * Returns the current type of @tree_column.
1579 * Return value: The type of @tree_column.
1581 GtkTreeViewColumnSizing
1582 gtk_tree_view_column_get_sizing (GtkTreeViewColumn *tree_column)
1584 g_return_val_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column), 0);
1586 return tree_column->column_type;
1590 * gtk_tree_view_column_get_width:
1591 * @tree_column: A #GtkTreeViewColumn.
1593 * Returns the current size of @tree_column in pixels.
1595 * Return value: The current width of @tree_column.
1598 gtk_tree_view_column_get_width (GtkTreeViewColumn *tree_column)
1600 g_return_val_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column), 0);
1602 return tree_column->width;
1606 * gtk_tree_view_column_set_fixed_width:
1607 * @tree_column: A #GtkTreeViewColumn.
1608 * @fixed_width: The size to set @tree_column to. Must be greater than 0.
1610 * Sets the size of the column in pixels. This is meaningful only if the sizing
1611 * type is #GTK_TREE_VIEW_COLUMN_FIXED. The size of the column is clamped to
1612 * the min/max width for the column. Please note that the min/max width of the
1613 * column doesn't actually affect the "fixed_width" property of the widget, just
1614 * the actual size when displayed.
1617 gtk_tree_view_column_set_fixed_width (GtkTreeViewColumn *tree_column,
1620 g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column));
1621 g_return_if_fail (fixed_width > 0);
1623 tree_column->fixed_width = fixed_width;
1625 if (tree_column->tree_view &&
1626 GTK_WIDGET_REALIZED (tree_column->tree_view) &&
1627 tree_column->column_type == GTK_TREE_VIEW_COLUMN_FIXED)
1629 gtk_widget_queue_resize (tree_column->tree_view);
1632 g_object_notify (G_OBJECT (tree_column), "fixed_width");
1636 * gtk_tree_view_column_get_fixed_width:
1637 * @tree_column: a #GtkTreeViewColumn
1639 * Gets the fixed width of the column. This value is only meaning may not be
1640 * the actual width of the column on the screen, just what is requested.
1642 * Return value: the fixed width of the column
1645 gtk_tree_view_column_get_fixed_width (GtkTreeViewColumn *tree_column)
1647 g_return_val_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column), 0);
1649 return tree_column->fixed_width;
1653 * gtk_tree_view_column_set_min_width:
1654 * @tree_column: A #GtkTreeViewColumn.
1655 * @min_width: The minimum width of the column in pixels, or -1.
1657 * Sets the minimum width of the @tree_column. If @min_width is -1, then the
1658 * minimum width is unset.
1661 gtk_tree_view_column_set_min_width (GtkTreeViewColumn *tree_column,
1664 g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column));
1665 g_return_if_fail (min_width >= -1);
1667 if (min_width == tree_column->min_width)
1670 if (tree_column->visible &&
1671 tree_column->tree_view != NULL &&
1672 GTK_WIDGET_REALIZED (tree_column->tree_view))
1674 if (min_width > tree_column->width)
1675 gtk_widget_queue_resize (tree_column->tree_view);
1678 tree_column->min_width = min_width;
1679 g_object_freeze_notify (G_OBJECT (tree_column));
1680 if (tree_column->max_width != -1 && tree_column->max_width < min_width)
1682 tree_column->max_width = min_width;
1683 g_object_notify (G_OBJECT (tree_column), "max_width");
1685 g_object_notify (G_OBJECT (tree_column), "min_width");
1686 g_object_thaw_notify (G_OBJECT (tree_column));
1690 * gtk_tree_view_column_get_min_width:
1691 * @tree_column: A #GtkTreeViewColumn.
1693 * Returns the minimum width in pixels of the @tree_column, or -1 if no minimum
1696 * Return value: The minimum width of the @tree_column.
1699 gtk_tree_view_column_get_min_width (GtkTreeViewColumn *tree_column)
1701 g_return_val_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column), -1);
1703 return tree_column->min_width;
1707 * gtk_tree_view_column_set_max_width:
1708 * @tree_column: A #GtkTreeViewColumn.
1709 * @max_width: The maximum width of the column in pixels, or -1.
1711 * Sets the maximum width of the @tree_column. If @max_width is -1, then the
1712 * maximum width is unset. Note, the column can actually be wider than max
1713 * width if it's the last column in a view. In this case, the column expands to
1714 * fill any extra space.
1717 gtk_tree_view_column_set_max_width (GtkTreeViewColumn *tree_column,
1720 g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column));
1721 g_return_if_fail (max_width >= -1);
1723 if (max_width == tree_column->max_width)
1726 if (tree_column->visible &&
1727 tree_column->tree_view != NULL &&
1728 GTK_WIDGET_REALIZED (tree_column->tree_view))
1730 if (max_width != -1 && max_width < tree_column->width)
1731 gtk_widget_queue_resize (tree_column->tree_view);
1734 tree_column->max_width = max_width;
1735 g_object_freeze_notify (G_OBJECT (tree_column));
1736 if (max_width != -1 && max_width < tree_column->min_width)
1738 tree_column->min_width = max_width;
1739 g_object_notify (G_OBJECT (tree_column), "min_width");
1741 g_object_notify (G_OBJECT (tree_column), "max_width");
1742 g_object_thaw_notify (G_OBJECT (tree_column));
1746 * gtk_tree_view_column_get_max_width:
1747 * @tree_column: A #GtkTreeViewColumn.
1749 * Returns the maximum width in pixels of the @tree_column, or -1 if no maximum
1752 * Return value: The maximum width of the @tree_column.
1755 gtk_tree_view_column_get_max_width (GtkTreeViewColumn *tree_column)
1757 g_return_val_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column), -1);
1759 return tree_column->max_width;
1763 * gtk_tree_view_column_clicked:
1764 * @tree_column: a #GtkTreeViewColumn
1766 * Emits the "clicked" signal on the column. This function will only work if
1767 * @tree_column is clickable.
1770 gtk_tree_view_column_clicked (GtkTreeViewColumn *tree_column)
1772 g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column));
1774 if (tree_column->visible &&
1775 tree_column->button &&
1776 tree_column->clickable)
1777 gtk_button_clicked (GTK_BUTTON (tree_column->button));
1781 * gtk_tree_view_column_set_title:
1782 * @tree_column: A #GtkTreeViewColumn.
1783 * @title: The title of the @tree_column.
1785 * Sets the title of the @tree_column. If a custom widget has been set, then
1786 * this value is ignored.
1789 gtk_tree_view_column_set_title (GtkTreeViewColumn *tree_column,
1792 g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column));
1794 g_free (tree_column->title);
1796 tree_column->title = g_strdup (title);
1798 tree_column->title = NULL;
1800 gtk_tree_view_column_update_button (tree_column);
1801 g_object_notify (G_OBJECT (tree_column), "title");
1805 * gtk_tree_view_column_get_title:
1806 * @tree_column: A #GtkTreeViewColumn.
1808 * Returns the title of the widget. This value should not be modified.
1810 * Return value: the title of the column.
1812 G_CONST_RETURN gchar *
1813 gtk_tree_view_column_get_title (GtkTreeViewColumn *tree_column)
1815 g_return_val_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column), NULL);
1817 return tree_column->title;
1821 * gtk_tree_view_column_set_clickable:
1822 * @tree_column: A #GtkTreeViewColumn.
1823 * @clickable: %TRUE if the header is active.
1825 * Sets the header to be active if @active is %TRUE. When the header is active,
1826 * then it can take keyboard focus, and can be clicked.
1829 gtk_tree_view_column_set_clickable (GtkTreeViewColumn *tree_column,
1832 g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column));
1834 clickable = !! clickable;
1835 if (tree_column->clickable == clickable)
1838 tree_column->clickable = clickable;
1839 gtk_tree_view_column_update_button (tree_column);
1840 g_object_notify (G_OBJECT (tree_column), "clickable");
1844 * gtk_tree_view_column_get_clickable:
1845 * @tree_column: a #GtkTreeViewColumn
1847 * Returns %TRUE if the user can click on the header for the column.
1849 * Return value: %TRUE if user can click the column header.
1852 gtk_tree_view_column_get_clickable (GtkTreeViewColumn *tree_column)
1854 g_return_val_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column), FALSE);
1856 return tree_column->clickable;
1860 * gtk_tree_view_column_set_widget:
1861 * @tree_column: A #GtkTreeViewColumn.
1862 * @widget: A child #GtkWidget, or %NULL.
1864 * Sets the widget in the header to be @widget. If widget is %NULL, then the
1865 * header button is set with a #GtkLabel set to the title of @tree_column.
1868 gtk_tree_view_column_set_widget (GtkTreeViewColumn *tree_column,
1871 g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column));
1872 g_return_if_fail (widget == NULL || GTK_IS_WIDGET (widget));
1876 gtk_object_ref (GTK_OBJECT (widget));
1877 gtk_object_sink (GTK_OBJECT (widget));
1880 if (tree_column->child)
1881 gtk_object_unref (GTK_OBJECT (tree_column->child));
1883 tree_column->child = widget;
1884 gtk_tree_view_column_update_button (tree_column);
1885 g_object_notify (G_OBJECT (tree_column), "widget");
1889 * gtk_tree_view_column_get_widget:
1890 * @tree_column: A #GtkTreeViewColumn.
1892 * Returns the #GtkWidget in the button on the column header. If a custom
1893 * widget has not been set then %NULL is returned.
1895 * Return value: The #GtkWidget in the column header, or %NULL
1898 gtk_tree_view_column_get_widget (GtkTreeViewColumn *tree_column)
1900 g_return_val_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column), NULL);
1902 return tree_column->child;
1906 * gtk_tree_view_column_set_alignment:
1907 * @tree_column: A #GtkTreeViewColumn.
1908 * @xalign: The alignment, which is between [0.0 and 1.0] inclusive.
1910 * Sets the alignment of the title or custom widget inside the column header.
1911 * The alignment determines its location inside the button -- 0.0 for left, 0.5
1912 * for center, 1.0 for right.
1915 gtk_tree_view_column_set_alignment (GtkTreeViewColumn *tree_column,
1918 g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column));
1920 xalign = CLAMP (xalign, 0.0, 1.0);
1922 if (tree_column->xalign == xalign)
1925 tree_column->xalign = xalign;
1926 gtk_tree_view_column_update_button (tree_column);
1927 g_object_notify (G_OBJECT (tree_column), "alignment");
1931 * gtk_tree_view_column_get_alignment:
1932 * @tree_column: A #GtkTreeViewColumn.
1934 * Returns the current x alignment of @tree_column. This value can range
1935 * between 0.0 and 1.0.
1937 * Return value: The current alignent of @tree_column.
1940 gtk_tree_view_column_get_alignment (GtkTreeViewColumn *tree_column)
1942 g_return_val_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column), 0.5);
1944 return tree_column->xalign;
1948 * gtk_tree_view_column_set_reorderable:
1949 * @tree_column: A #GtkTreeViewColumn
1950 * @reorderable: #TRUE, if the column can be reordered.
1952 * If @reorderable is #TRUE, then the column can be reordered by the end user
1953 * dragging the header.
1956 gtk_tree_view_column_set_reorderable (GtkTreeViewColumn *tree_column,
1957 gboolean reorderable)
1959 g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column));
1962 gtk_tree_view_column_set_clickable (tree_column, TRUE);*/
1964 if (tree_column->reorderable == (reorderable?TRUE:FALSE))
1967 tree_column->reorderable = (reorderable?TRUE:FALSE);
1968 gtk_tree_view_column_update_button (tree_column);
1969 g_object_notify (G_OBJECT (tree_column), "reorderable");
1973 * gtk_tree_view_column_get_reorderable:
1974 * @tree_column: A #GtkTreeViewColumn
1976 * Returns #TRUE if the @tree_column can be reordered by the user.
1978 * Return value: #TRUE if the @tree_column can be reordered by the user.
1981 gtk_tree_view_column_get_reorderable (GtkTreeViewColumn *tree_column)
1983 g_return_val_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column), FALSE);
1985 return tree_column->reorderable;
1990 * gtk_tree_view_column_set_sort_column_id:
1991 * @tree_column: a #GtkTreeViewColumn
1992 * @sort_column_id: The @sort_column_id of the model to sort on.
1994 * Sets the logical @sort_column_id that this column sorts on when this column
1995 * is selected for sorting. Doing so makes the column header clickable.
1998 gtk_tree_view_column_set_sort_column_id (GtkTreeViewColumn *tree_column,
1999 gint sort_column_id)
2001 g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column));
2002 g_return_if_fail (sort_column_id >= 0);
2004 if (tree_column->sort_column_id == sort_column_id)
2007 tree_column->sort_column_id = sort_column_id;
2009 /* Handle unsetting the id */
2010 if (sort_column_id == -1)
2012 if (tree_column->sort_clicked_signal)
2014 g_signal_handler_disconnect (G_OBJECT (tree_column), tree_column->sort_clicked_signal);
2015 tree_column->sort_clicked_signal = 0;
2018 if (tree_column->sort_column_changed_signal)
2020 g_signal_handler_disconnect (G_OBJECT (tree_column), tree_column->sort_column_changed_signal);
2021 tree_column->sort_column_changed_signal = 0;
2024 gtk_tree_view_column_set_sort_order (tree_column, GTK_SORT_ASCENDING);
2025 gtk_tree_view_column_set_sort_indicator (tree_column, FALSE);
2029 gtk_tree_view_column_set_clickable (tree_column, TRUE);
2031 if (! tree_column->sort_clicked_signal)
2032 tree_column->sort_clicked_signal = g_signal_connect (G_OBJECT (tree_column),
2034 G_CALLBACK (gtk_tree_view_column_sort),
2037 gtk_tree_view_column_setup_sort_column_id_callback (tree_column);
2041 * gtk_tree_view_column_get_sort_column_id:
2042 * @tree_column: a #GtkTreeViewColumn
2044 * Gets the logical @sort_column_id that the model sorts on when this
2045 * column is selected for sorting. See gtk_tree_view_column_set_sort_column_id().
2047 * Return value: the current @sort_column_id for this column, or -1 if
2048 * this column can't be used for sorting.
2051 gtk_tree_view_column_get_sort_column_id (GtkTreeViewColumn *tree_column)
2053 g_return_val_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column), 0);
2055 return tree_column->sort_column_id;
2059 * gtk_tree_view_column_set_sort_indicator:
2060 * @tree_column: a #GtkTreeViewColumn
2061 * @setting: %TRUE to display an indicator that the column is sorted
2063 * Call this function with a @setting of %TRUE to display an arrow in
2064 * the header button indicating the column is sorted. Call
2065 * gtk_tree_view_column_set_sort_order() to change the direction of
2070 gtk_tree_view_column_set_sort_indicator (GtkTreeViewColumn *tree_column,
2073 g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column));
2075 setting = setting != FALSE;
2077 if (setting == tree_column->show_sort_indicator)
2080 tree_column->show_sort_indicator = setting;
2081 gtk_tree_view_column_update_button (tree_column);
2082 g_object_notify (G_OBJECT (tree_column), "sort_indicator");
2086 * gtk_tree_view_column_get_sort_indicator:
2087 * @tree_column: a #GtkTreeViewColumn
2089 * Gets the value set by gtk_tree_view_column_set_sort_indicator().
2091 * Return value: whether the sort indicator arrow is displayed
2094 gtk_tree_view_column_get_sort_indicator (GtkTreeViewColumn *tree_column)
2096 g_return_val_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column), FALSE);
2098 return tree_column->show_sort_indicator;
2102 * gtk_tree_view_column_set_sort_order:
2103 * @tree_column: a #GtkTreeViewColumn
2104 * @order: sort order that the sort indicator should indicate
2106 * Changes the appearance of the sort indicator.
2108 * This <emphasis>does not</emphasis> actually sort the model. Use
2109 * gtk_tree_view_column_set_sort_column_id() if you want automatic sorting
2110 * support. This function is primarily for custom sorting behavior, and should
2111 * be used in conjunction with gtk_tree_sortable_set_sort_column() to do
2112 * that. For custom models, the mechanism will vary.
2114 * The sort indicator changes direction to indicate normal sort or reverse sort.
2115 * Note that you must have the sort indicator enabled to see anything when
2116 * calling this function; see gtk_tree_view_column_set_sort_indicator().
2119 gtk_tree_view_column_set_sort_order (GtkTreeViewColumn *tree_column,
2122 g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column));
2124 if (order == tree_column->sort_order)
2127 tree_column->sort_order = order;
2128 gtk_tree_view_column_update_button (tree_column);
2129 g_object_notify (G_OBJECT (tree_column), "sort_order");
2133 * gtk_tree_view_column_get_sort_order:
2134 * @tree_column: a #GtkTreeViewColumn
2136 * Gets the value set by gtk_tree_view_column_set_sort_order().
2138 * Return value: the sort order the sort indicator is indicating
2141 gtk_tree_view_column_get_sort_order (GtkTreeViewColumn *tree_column)
2143 g_return_val_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column), 0);
2145 return tree_column->sort_order;
2149 * gtk_tree_view_column_cell_set_cell_data:
2150 * @tree_column: A #GtkTreeViewColumn.
2151 * @tree_model: The #GtkTreeModel to to get the cell renderers attributes from.
2152 * @iter: The #GtkTreeIter to to get the cell renderer's attributes from.
2153 * @is_expander: %TRUE, if the row has children
2154 * @is_expanded: %TRUE, if the row has visible children
2156 * Sets the cell renderer based on the @tree_model and @tree_node. That is, for
2157 * every attribute mapping in @tree_column, it will get a value from the set
2158 * column on the @tree_node, and use that value to set the attribute on the cell
2159 * renderer. This is used primarily by the #GtkTreeView.
2162 gtk_tree_view_column_cell_set_cell_data (GtkTreeViewColumn *tree_column,
2163 GtkTreeModel *tree_model,
2165 gboolean is_expander,
2166 gboolean is_expanded)
2169 GValue value = { 0, };
2172 g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column));
2173 g_return_if_fail (tree_column->cell_list != NULL);
2175 if (tree_model == NULL)
2178 for (cell_list = tree_column->cell_list; cell_list; cell_list = cell_list->next)
2180 GtkTreeViewColumnCellInfo *info = (GtkTreeViewColumnCellInfo *) cell_list->data;
2181 GObject *cell = (GObject *) info->cell;
2183 list = info->attributes;
2185 g_object_freeze_notify (cell);
2186 g_object_set (cell, "is_expander", is_expander, "is_expanded", is_expanded, NULL);
2188 while (list && list->next)
2190 gtk_tree_model_get_value (tree_model, iter,
2191 GPOINTER_TO_INT (list->next->data),
2193 g_object_set_property (cell, (gchar *) list->data, &value);
2194 g_value_unset (&value);
2195 list = list->next->next;
2199 (* info->func) (tree_column, info->cell, tree_model, iter, info->func_data);
2200 g_object_thaw_notify (G_OBJECT (info->cell));
2206 * gtk_tree_view_column_cell_get_size:
2207 * @tree_column: A #GtkTreeViewColumn.
2208 * @cell_area: The area a the column will be allocated, or %NULL
2209 * @x_offset: location to return x offset of cell relative to @cell_area, or %NULL
2210 * @y_offset: location to return y offset of cell relative to @cell_area, or %NULL
2211 * @width: location to return width needed to render a cell, or %NULL
2212 * @height: location to return height needed to render a cell, or %NULL
2214 * Obtains the width and height needed to render the column. This is used
2215 * primarily by the #GtkTreeView.
2218 gtk_tree_view_column_cell_get_size (GtkTreeViewColumn *tree_column,
2219 GdkRectangle *cell_area,
2226 gboolean first_cell = TRUE;
2227 gint focus_line_width;
2229 g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column));
2236 gtk_widget_style_get (tree_column->tree_view, "focus-line-width", &focus_line_width, NULL);
2238 for (list = tree_column->cell_list; list; list = list->next)
2240 GtkTreeViewColumnCellInfo *info = (GtkTreeViewColumnCellInfo *) list->data;
2242 gint new_height = 0;
2244 g_object_get (info->cell, "visible", &visible, NULL);
2246 if (visible == FALSE)
2249 if (first_cell == FALSE && *width)
2250 *width += tree_column->spacing;
2252 gtk_cell_renderer_get_size (info->cell,
2253 tree_column->tree_view,
2261 * height = MAX (*height, new_height + focus_line_width * 2);
2262 info->requested_width = MAX (info->requested_width, new_width + focus_line_width * 2);
2264 * width += info->requested_width;
2269 /* both rendering and rendering focus are somewhat complicated, and a bit of
2270 * code. Rather than duplicate them, we put them together to keep the code in
2280 gtk_tree_view_column_cell_process_action (GtkTreeViewColumn *tree_column,
2282 GdkRectangle *background_area,
2283 GdkRectangle *cell_area,
2286 GdkRectangle *expose_area, /* RENDER */
2287 GdkRectangle *focus_rectangle, /* FOCUS */
2288 GtkCellEditable **editable_widget, /* EVENT */
2289 GdkEvent *event, /* EVENT */
2290 gchar *path_string) /* EVENT */
2293 GdkRectangle real_cell_area;
2294 gint expand_cell_count = 0;
2295 gint full_requested_width = 0;
2297 gint min_x, min_y, max_x, max_y;
2298 gint focus_line_width;
2305 real_cell_area = *cell_area;
2307 gtk_widget_style_get (GTK_WIDGET (tree_column->tree_view),
2308 "focus-line-width", &focus_line_width,
2310 /* Find out how my extra space we have to allocate */
2311 for (list = tree_column->cell_list; list; list = list->next)
2313 GtkTreeViewColumnCellInfo *info = (GtkTreeViewColumnCellInfo *) list->data;
2315 if (! info->cell->visible)
2318 if (info->expand == TRUE)
2319 expand_cell_count ++;
2320 full_requested_width += info->requested_width;
2323 extra_space = cell_area->width - full_requested_width;
2324 if (extra_space < 0)
2327 for (list = tree_column->cell_list; list; list = list->next)
2329 GtkTreeViewColumnCellInfo *info = (GtkTreeViewColumnCellInfo *) list->data;
2331 if (info->pack == GTK_PACK_END)
2334 if (! info->cell->visible)
2337 real_cell_area.width = info->requested_width +
2338 (info->expand?extra_space:0);
2339 real_cell_area.x += focus_line_width;
2340 if (action == CELL_ACTION_RENDER)
2342 gtk_cell_renderer_render (info->cell,
2344 tree_column->tree_view,
2350 else if (action == CELL_ACTION_FOCUS)
2352 gint x_offset, y_offset, width, height;
2354 gtk_cell_renderer_get_size (info->cell,
2355 tree_column->tree_view,
2357 &x_offset, &y_offset,
2360 if (min_x > (real_cell_area.x + x_offset))
2361 min_x = real_cell_area.x + x_offset;
2362 if (max_x < real_cell_area.x + x_offset + width)
2363 max_x = real_cell_area.x + x_offset + width;
2364 if (min_y > (real_cell_area.y + y_offset))
2365 min_y = real_cell_area.y + y_offset;
2366 if (max_y < real_cell_area.y + y_offset + height)
2367 max_y = real_cell_area.y + y_offset + height;
2369 else if (action == CELL_ACTION_EVENT)
2371 gboolean try_event = FALSE;
2375 if (real_cell_area.x <= ((GdkEventButton *)event)->x &&
2376 real_cell_area.x + real_cell_area.width > ((GdkEventButton *)event)->x)
2379 else /* if (info->has_focus)*/
2380 /* FIXME 73676: allow focusing individual cells */
2386 gboolean visible, mode;
2388 g_object_get (G_OBJECT (info->cell),
2389 "visible", &visible,
2392 if (visible && mode == GTK_CELL_RENDERER_MODE_ACTIVATABLE)
2394 if (gtk_cell_renderer_activate (info->cell,
2396 tree_column->tree_view,
2403 else if (visible && mode == GTK_CELL_RENDERER_MODE_EDITABLE)
2406 gtk_cell_renderer_start_editing (info->cell,
2408 tree_column->tree_view,
2414 if (*editable_widget != NULL)
2416 g_return_val_if_fail (GTK_IS_CELL_EDITABLE (*editable_widget), FALSE);
2423 real_cell_area.x += (info->requested_width + tree_column->spacing);
2425 for (list = g_list_last (tree_column->cell_list); list; list = list->prev)
2427 GtkTreeViewColumnCellInfo *info = (GtkTreeViewColumnCellInfo *) list->data;
2429 if (info->pack == GTK_PACK_START)
2432 if (! info->cell->visible)
2435 real_cell_area.width = info->requested_width +
2436 (info->expand?extra_space:0);
2437 if (action == CELL_ACTION_RENDER)
2439 gtk_cell_renderer_render (info->cell,
2441 tree_column->tree_view,
2447 else if (action == CELL_ACTION_FOCUS)
2449 gint x_offset, y_offset, width, height;
2451 gtk_cell_renderer_get_size (info->cell,
2452 tree_column->tree_view,
2454 &x_offset, &y_offset,
2457 if (min_x > (real_cell_area.x + x_offset))
2458 min_x = real_cell_area.x + x_offset;
2459 if (max_x < real_cell_area.x + x_offset + width)
2460 max_x = real_cell_area.x + x_offset + width;
2461 if (min_y > (real_cell_area.y + y_offset))
2462 min_y = real_cell_area.y + y_offset;
2463 if (max_y < real_cell_area.y + y_offset + height)
2464 max_y = real_cell_area.y + y_offset + height;
2466 real_cell_area.x += (info->requested_width + tree_column->spacing);
2469 if (action == CELL_ACTION_FOCUS)
2471 if (min_x >= max_x || min_y >= max_y)
2473 *focus_rectangle = *cell_area;
2474 /* don't change the focus_rectangle, just draw it nicely inside
2479 focus_rectangle->x = min_x - focus_line_width;
2480 focus_rectangle->y = min_y - focus_line_width;
2481 focus_rectangle->width = (max_x - min_x) + 2 * focus_line_width;
2482 focus_rectangle->height = (max_y - min_y) + 2 * focus_line_width;
2490 * gtk_tree_view_column_cell_render:
2491 * @tree_column: A #GtkTreeViewColumn.
2492 * @window: a #GdkDrawable to draw to
2493 * @background_area: entire cell area (including tree expanders and maybe padding on the sides)
2494 * @cell_area: area normally rendered by a cell renderer
2495 * @expose_area: area that actually needs updating
2496 * @flags: flags that affect rendering
2498 * Renders the cell contained by #tree_column. This is used primarily by the
2502 _gtk_tree_view_column_cell_render (GtkTreeViewColumn *tree_column,
2504 GdkRectangle *background_area,
2505 GdkRectangle *cell_area,
2506 GdkRectangle *expose_area,
2509 g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column));
2510 g_return_if_fail (background_area != NULL);
2511 g_return_if_fail (cell_area != NULL);
2512 g_return_if_fail (expose_area != NULL);
2514 gtk_tree_view_column_cell_process_action (tree_column,
2521 NULL, NULL, NULL, NULL);
2525 _gtk_tree_view_column_cell_event (GtkTreeViewColumn *tree_column,
2526 GtkCellEditable **editable_widget,
2529 GdkRectangle *background_area,
2530 GdkRectangle *cell_area,
2533 g_return_val_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column), FALSE);
2535 return gtk_tree_view_column_cell_process_action (tree_column,
2549 _gtk_tree_view_column_cell_focus (GtkTreeViewColumn *tree_column,
2552 /* FIXME 73676: allow focusing individual cells */
2553 if (GTK_TREE_VIEW (tree_column->tree_view)->priv->focus_column == tree_column)
2559 _gtk_tree_view_column_cell_draw_focus (GtkTreeViewColumn *tree_column,
2561 GdkRectangle *background_area,
2562 GdkRectangle *cell_area,
2563 GdkRectangle *expose_area,
2566 gint focus_line_width;
2567 GtkStateType cell_state;
2569 g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column));
2570 gtk_widget_style_get (GTK_WIDGET (tree_column->tree_view),
2571 "focus-line-width", &focus_line_width, NULL);
2572 if (tree_column->editable_widget)
2574 /* This function is only called on the editable row when editing.
2577 gtk_paint_focus (tree_column->tree_view->style,
2579 GTK_WIDGET_STATE (tree_column->tree_view),
2581 tree_column->tree_view,
2583 cell_area->x - focus_line_width,
2584 cell_area->y - focus_line_width,
2585 cell_area->width + 2 * focus_line_width,
2586 cell_area->height + 2 * focus_line_width);
2591 GdkRectangle focus_rectangle;
2592 gtk_tree_view_column_cell_process_action (tree_column,
2602 cell_state = flags & GTK_CELL_RENDERER_SELECTED ? GTK_STATE_SELECTED :
2603 (flags & GTK_CELL_RENDERER_PRELIT ? GTK_STATE_PRELIGHT :
2604 (flags & GTK_CELL_RENDERER_INSENSITIVE ? GTK_STATE_INSENSITIVE : GTK_STATE_NORMAL));
2605 gtk_paint_focus (tree_column->tree_view->style,
2609 tree_column->tree_view,
2613 focus_rectangle.width,
2614 focus_rectangle.height);
2619 * gtk_tree_view_column_cell_is_visible:
2620 * @tree_column: A #GtkTreeViewColumn
2622 * Returns #TRUE if any of the cells packed into the @tree_column are visible.
2623 * For this to be meaningful, you must first initialize the cells with
2624 * gtk_tree_view_column_cell_set_cell_data()
2626 * Return value: #TRUE, if any of the cells packed into the @tree_column are currently visible
2629 gtk_tree_view_column_cell_is_visible (GtkTreeViewColumn *tree_column)
2633 for (list = tree_column->cell_list; list; list = list->next)
2635 GtkTreeViewColumnCellInfo *info = (GtkTreeViewColumnCellInfo *) list->data;
2637 if (info->cell->visible)
2645 _gtk_tree_view_column_cell_set_dirty (GtkTreeViewColumn *tree_column,
2646 gboolean install_handler)
2650 for (list = tree_column->cell_list; list; list = list->next)
2652 GtkTreeViewColumnCellInfo *info = (GtkTreeViewColumnCellInfo *) list->data;
2654 info->requested_width = 0;
2656 tree_column->dirty = TRUE;
2657 tree_column->resized_width = MAX (tree_column->requested_width, tree_column->button_request);
2658 tree_column->requested_width = -1;
2659 tree_column->width = 0;
2661 if (tree_column->tree_view &&
2662 GTK_WIDGET_REALIZED (tree_column->tree_view))
2664 if (install_handler)
2665 _gtk_tree_view_install_mark_rows_col_dirty (GTK_TREE_VIEW (tree_column->tree_view));
2667 GTK_TREE_VIEW (tree_column->tree_view)->priv->mark_rows_col_dirty = TRUE;
2668 gtk_widget_queue_resize (tree_column->tree_view);
2673 _gtk_tree_view_column_start_editing (GtkTreeViewColumn *tree_column,
2674 GtkCellEditable *cell_editable)
2676 g_return_if_fail (tree_column->editable_widget == NULL);
2678 tree_column->editable_widget = cell_editable;
2682 _gtk_tree_view_column_stop_editing (GtkTreeViewColumn *tree_column)
2684 g_return_if_fail (tree_column->editable_widget != NULL);
2686 tree_column->editable_widget = NULL;