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.
22 #include "gtktreeviewcolumn.h"
26 #include "gtktreeview.h"
27 #include "gtktreeprivate.h"
28 #include "gtkcelllayout.h"
29 #include "gtkbutton.h"
30 #include "gtkalignment.h"
33 #include "gtkmarshalers.h"
35 #include "gtkcellareacontext.h"
36 #include "gtkcellareabox.h"
37 #include "gtkprivate.h"
42 * SECTION:gtktreeviewcolumn
43 * @Short_description: A visible column in a GtkTreeView widget
44 * @Title: GtkTreeViewColumn
45 * @See_also: #GtkTreeView, #GtkTreeSelection, #GtkTreeDnd, #GtkTreeMode, #GtkTreeSortable,
46 * #GtkTreeModelSort, #GtkListStore, #GtkTreeStore, #GtkCellRenderer, #GtkCellEditable,
47 * #GtkCellRendererPixbuf, #GtkCellRendererText, #GtkCellRendererToggle
49 * The GtkTreeViewColumn object represents a visible column in a #GtkTreeView widget.
50 * It allows to set properties of the column header, and functions as a holding pen for
51 * the cell renderers which determine how the data in the column is displayed.
53 * Please refer to the <link linkend="TreeWidget">tree widget conceptual overview</link>
54 * for an overview of all the objects and data types related to the tree widget and how
88 static void gtk_tree_view_column_cell_layout_init (GtkCellLayoutIface *iface);
91 static void gtk_tree_view_column_set_property (GObject *object,
95 static void gtk_tree_view_column_get_property (GObject *object,
99 static void gtk_tree_view_column_finalize (GObject *object);
100 static void gtk_tree_view_column_dispose (GObject *object);
101 static GObject *gtk_tree_view_column_constructor (GType type,
102 guint n_construct_properties,
103 GObjectConstructParam *construct_properties);
105 /* GtkCellLayout implementation */
106 static GtkCellArea *gtk_tree_view_column_cell_layout_get_area (GtkCellLayout *cell_layout);
108 /* Button handling code */
109 static void gtk_tree_view_column_create_button (GtkTreeViewColumn *tree_column);
110 static void gtk_tree_view_column_update_button (GtkTreeViewColumn *tree_column);
112 /* Button signal handlers */
113 static gint gtk_tree_view_column_button_event (GtkWidget *widget,
116 static void gtk_tree_view_column_button_clicked (GtkWidget *widget,
118 static gboolean gtk_tree_view_column_mnemonic_activate (GtkWidget *widget,
119 gboolean group_cycling,
122 /* Property handlers */
123 static void gtk_tree_view_model_sort_column_changed (GtkTreeSortable *sortable,
124 GtkTreeViewColumn *tree_column);
126 /* GtkCellArea/GtkCellAreaContext callbacks */
127 static void gtk_tree_view_column_context_changed (GtkCellAreaContext *context,
129 GtkTreeViewColumn *tree_column);
130 static void gtk_tree_view_column_add_editable_callback (GtkCellArea *area,
131 GtkCellRenderer *renderer,
132 GtkCellEditable *edit_widget,
133 GdkRectangle *cell_area,
134 const gchar *path_string,
136 static void gtk_tree_view_column_remove_editable_callback (GtkCellArea *area,
137 GtkCellRenderer *renderer,
138 GtkCellEditable *edit_widget,
141 /* Internal functions */
142 static void gtk_tree_view_column_sort (GtkTreeViewColumn *tree_column,
144 static void gtk_tree_view_column_setup_sort_column_id_callback (GtkTreeViewColumn *tree_column);
145 static void gtk_tree_view_column_set_attributesv (GtkTreeViewColumn *tree_column,
146 GtkCellRenderer *cell_renderer,
149 /* GtkBuildable implementation */
150 static void gtk_tree_view_column_buildable_init (GtkBuildableIface *iface);
152 static guint tree_column_signals[LAST_SIGNAL] = { 0 };
154 G_DEFINE_TYPE_WITH_CODE (GtkTreeViewColumn, gtk_tree_view_column, G_TYPE_INITIALLY_UNOWNED,
155 G_IMPLEMENT_INTERFACE (GTK_TYPE_CELL_LAYOUT,
156 gtk_tree_view_column_cell_layout_init)
157 G_IMPLEMENT_INTERFACE (GTK_TYPE_BUILDABLE,
158 gtk_tree_view_column_buildable_init))
162 gtk_tree_view_column_class_init (GtkTreeViewColumnClass *class)
164 GObjectClass *object_class;
166 object_class = (GObjectClass*) class;
168 class->clicked = NULL;
170 object_class->constructor = gtk_tree_view_column_constructor;
171 object_class->finalize = gtk_tree_view_column_finalize;
172 object_class->dispose = gtk_tree_view_column_dispose;
173 object_class->set_property = gtk_tree_view_column_set_property;
174 object_class->get_property = gtk_tree_view_column_get_property;
176 tree_column_signals[CLICKED] =
177 g_signal_new (I_("clicked"),
178 G_OBJECT_CLASS_TYPE (object_class),
180 G_STRUCT_OFFSET (GtkTreeViewColumnClass, clicked),
182 _gtk_marshal_VOID__VOID,
185 g_object_class_install_property (object_class,
187 g_param_spec_boolean ("visible",
189 P_("Whether to display the column"),
191 GTK_PARAM_READWRITE));
193 g_object_class_install_property (object_class,
195 g_param_spec_boolean ("resizable",
197 P_("Column is user-resizable"),
199 GTK_PARAM_READWRITE));
201 g_object_class_install_property (object_class,
203 g_param_spec_int ("width",
205 P_("Current width of the column"),
209 GTK_PARAM_READABLE));
210 g_object_class_install_property (object_class,
212 g_param_spec_int ("spacing",
214 P_("Space which is inserted between cells"),
218 GTK_PARAM_READWRITE));
219 g_object_class_install_property (object_class,
221 g_param_spec_enum ("sizing",
223 P_("Resize mode of the column"),
224 GTK_TYPE_TREE_VIEW_COLUMN_SIZING,
225 GTK_TREE_VIEW_COLUMN_GROW_ONLY,
226 GTK_PARAM_READWRITE));
228 g_object_class_install_property (object_class,
230 g_param_spec_int ("fixed-width",
232 P_("Current fixed width of the column"),
236 GTK_PARAM_READWRITE));
238 g_object_class_install_property (object_class,
240 g_param_spec_int ("min-width",
242 P_("Minimum allowed width of the column"),
246 GTK_PARAM_READWRITE));
248 g_object_class_install_property (object_class,
250 g_param_spec_int ("max-width",
252 P_("Maximum allowed width of the column"),
256 GTK_PARAM_READWRITE));
258 g_object_class_install_property (object_class,
260 g_param_spec_string ("title",
262 P_("Title to appear in column header"),
264 GTK_PARAM_READWRITE));
266 g_object_class_install_property (object_class,
268 g_param_spec_boolean ("expand",
270 P_("Column gets share of extra width allocated to the widget"),
272 GTK_PARAM_READWRITE));
274 g_object_class_install_property (object_class,
276 g_param_spec_boolean ("clickable",
278 P_("Whether the header can be clicked"),
280 GTK_PARAM_READWRITE));
283 g_object_class_install_property (object_class,
285 g_param_spec_object ("widget",
287 P_("Widget to put in column header button instead of column title"),
289 GTK_PARAM_READWRITE));
291 g_object_class_install_property (object_class,
293 g_param_spec_float ("alignment",
295 P_("X Alignment of the column header text or widget"),
299 GTK_PARAM_READWRITE));
301 g_object_class_install_property (object_class,
303 g_param_spec_boolean ("reorderable",
305 P_("Whether the column can be reordered around the headers"),
307 GTK_PARAM_READWRITE));
309 g_object_class_install_property (object_class,
311 g_param_spec_boolean ("sort-indicator",
312 P_("Sort indicator"),
313 P_("Whether to show a sort indicator"),
315 GTK_PARAM_READWRITE));
317 g_object_class_install_property (object_class,
319 g_param_spec_enum ("sort-order",
321 P_("Sort direction the sort indicator should indicate"),
324 GTK_PARAM_READWRITE));
327 * GtkTreeViewColumn:sort-column-id:
329 * Logical sort column ID this column sorts on when selected for sorting. Setting the sort column ID makes the column header
330 * clickable. Set to %-1 to make the column unsortable.
334 g_object_class_install_property (object_class,
336 g_param_spec_int ("sort-column-id",
337 P_("Sort column ID"),
338 P_("Logical sort column ID this column sorts on when selected for sorting"),
342 GTK_PARAM_READWRITE));
345 * GtkTreeViewColumn:cell-area:
347 * The #GtkCellArea used to layout cell renderers for this column.
351 g_object_class_install_property (object_class,
353 g_param_spec_object ("cell-area",
355 P_("The GtkCellArea used to layout cells"),
357 GTK_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
362 gtk_tree_view_column_buildable_init (GtkBuildableIface *iface)
364 iface->add_child = _gtk_cell_layout_buildable_add_child;
365 iface->custom_tag_start = _gtk_cell_layout_buildable_custom_tag_start;
366 iface->custom_tag_end = _gtk_cell_layout_buildable_custom_tag_end;
370 gtk_tree_view_column_cell_layout_init (GtkCellLayoutIface *iface)
372 iface->get_area = gtk_tree_view_column_cell_layout_get_area;
376 gtk_tree_view_column_init (GtkTreeViewColumn *tree_column)
378 tree_column->button = NULL;
379 tree_column->xalign = 0.0;
380 tree_column->width = 0;
381 tree_column->requested_width = -1;
382 tree_column->min_width = -1;
383 tree_column->max_width = -1;
384 tree_column->resized_width = 0;
385 tree_column->column_type = GTK_TREE_VIEW_COLUMN_GROW_ONLY;
386 tree_column->visible = TRUE;
387 tree_column->resizable = FALSE;
388 tree_column->expand = FALSE;
389 tree_column->clickable = FALSE;
390 tree_column->dirty = TRUE;
391 tree_column->sort_order = GTK_SORT_ASCENDING;
392 tree_column->show_sort_indicator = FALSE;
393 tree_column->property_changed_signal = 0;
394 tree_column->sort_clicked_signal = 0;
395 tree_column->sort_column_changed_signal = 0;
396 tree_column->sort_column_id = -1;
397 tree_column->reorderable = FALSE;
398 tree_column->maybe_reordered = FALSE;
399 tree_column->fixed_width = 1;
400 tree_column->use_resized_width = FALSE;
401 tree_column->title = g_strdup ("");
405 gtk_tree_view_column_constructor (GType type,
406 guint n_construct_properties,
407 GObjectConstructParam *construct_properties)
409 GtkTreeViewColumn *tree_column;
412 object = G_OBJECT_CLASS (gtk_tree_view_column_parent_class)->constructor
413 (type, n_construct_properties, construct_properties);
415 tree_column = (GtkTreeViewColumn *) object;
417 if (!tree_column->cell_area)
419 tree_column->cell_area = gtk_cell_area_box_new ();
420 g_object_ref_sink (tree_column->cell_area);
423 gtk_cell_area_set_style_detail (tree_column->cell_area, "treeview");
425 tree_column->add_editable_signal =
426 g_signal_connect (tree_column->cell_area, "add-editable",
427 G_CALLBACK (gtk_tree_view_column_add_editable_callback),
429 tree_column->remove_editable_signal =
430 g_signal_connect (tree_column->cell_area, "remove-editable",
431 G_CALLBACK (gtk_tree_view_column_remove_editable_callback),
434 tree_column->cell_area_context = gtk_cell_area_create_context (tree_column->cell_area);
436 tree_column->context_changed_signal =
437 g_signal_connect (priv->cell_area_context, "notify",
438 G_CALLBACK (gtk_tree_view_column_context_changed), tree_column);
444 gtk_tree_view_column_dispose (GObject *object)
446 GtkTreeViewColumn *tree_column = (GtkTreeViewColumn *) object;
448 if (tree_column->cell_area_context)
450 g_signal_handler_disconnect (tree_column->cell_area_context,
451 tree_column->context_changed_signal);
453 g_object_unref (tree_column->cell_area_context);
455 tree_column->cell_area_context = NULL;
456 tree_column->context_changed_signal = 0;
459 if (tree_column->cell_area)
461 g_signal_handler_disconnect (tree_column->cell_area,
462 tree_column->add_editable_signal);
463 g_signal_handler_disconnect (tree_column->cell_area,
464 tree_column->remove_editable_signal);
466 g_object_unref (tree_column->cell_area);
467 tree_column->cell_area = NULL;
468 tree_column->add_editable_signal = 0;
469 tree_column->remove_editable_signal = 0;
472 if (tree_column->child)
474 g_object_unref (tree_column->child);
475 tree_column->child = NULL;
478 G_OBJECT_CLASS (gtk_tree_view_column_parent_class)->dispose (object);
482 gtk_tree_view_column_finalize (GObject *object)
484 GtkTreeViewColumn *tree_column = (GtkTreeViewColumn *) object;
486 g_free (tree_column->title);
488 G_OBJECT_CLASS (gtk_tree_view_column_parent_class)->finalize (object);
492 gtk_tree_view_column_set_property (GObject *object,
497 GtkTreeViewColumn *tree_column;
500 tree_column = GTK_TREE_VIEW_COLUMN (object);
505 gtk_tree_view_column_set_visible (tree_column,
506 g_value_get_boolean (value));
510 gtk_tree_view_column_set_resizable (tree_column,
511 g_value_get_boolean (value));
515 gtk_tree_view_column_set_sizing (tree_column,
516 g_value_get_enum (value));
519 case PROP_FIXED_WIDTH:
520 gtk_tree_view_column_set_fixed_width (tree_column,
521 g_value_get_int (value));
525 gtk_tree_view_column_set_min_width (tree_column,
526 g_value_get_int (value));
530 gtk_tree_view_column_set_max_width (tree_column,
531 g_value_get_int (value));
535 gtk_tree_view_column_set_spacing (tree_column,
536 g_value_get_int (value));
540 gtk_tree_view_column_set_title (tree_column,
541 g_value_get_string (value));
545 gtk_tree_view_column_set_expand (tree_column,
546 g_value_get_boolean (value));
550 gtk_tree_view_column_set_clickable (tree_column,
551 g_value_get_boolean (value));
555 gtk_tree_view_column_set_widget (tree_column,
556 (GtkWidget*) g_value_get_object (value));
560 gtk_tree_view_column_set_alignment (tree_column,
561 g_value_get_float (value));
564 case PROP_REORDERABLE:
565 gtk_tree_view_column_set_reorderable (tree_column,
566 g_value_get_boolean (value));
569 case PROP_SORT_INDICATOR:
570 gtk_tree_view_column_set_sort_indicator (tree_column,
571 g_value_get_boolean (value));
574 case PROP_SORT_ORDER:
575 gtk_tree_view_column_set_sort_order (tree_column,
576 g_value_get_enum (value));
579 case PROP_SORT_COLUMN_ID:
580 gtk_tree_view_column_set_sort_column_id (tree_column,
581 g_value_get_int (value));
585 /* Construct-only, can only be assigned once */
586 area = g_value_get_object (value);
589 tree_column->cell_area = g_object_ref_sink (area);
593 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
599 gtk_tree_view_column_get_property (GObject *object,
604 GtkTreeViewColumn *tree_column;
606 tree_column = GTK_TREE_VIEW_COLUMN (object);
611 g_value_set_boolean (value,
612 gtk_tree_view_column_get_visible (tree_column));
616 g_value_set_boolean (value,
617 gtk_tree_view_column_get_resizable (tree_column));
621 g_value_set_int (value,
622 gtk_tree_view_column_get_width (tree_column));
626 g_value_set_int (value,
627 gtk_tree_view_column_get_spacing (tree_column));
631 g_value_set_enum (value,
632 gtk_tree_view_column_get_sizing (tree_column));
635 case PROP_FIXED_WIDTH:
636 g_value_set_int (value,
637 gtk_tree_view_column_get_fixed_width (tree_column));
641 g_value_set_int (value,
642 gtk_tree_view_column_get_min_width (tree_column));
646 g_value_set_int (value,
647 gtk_tree_view_column_get_max_width (tree_column));
651 g_value_set_string (value,
652 gtk_tree_view_column_get_title (tree_column));
656 g_value_set_boolean (value,
657 gtk_tree_view_column_get_expand (tree_column));
661 g_value_set_boolean (value,
662 gtk_tree_view_column_get_clickable (tree_column));
666 g_value_set_object (value,
667 (GObject*) gtk_tree_view_column_get_widget (tree_column));
671 g_value_set_float (value,
672 gtk_tree_view_column_get_alignment (tree_column));
675 case PROP_REORDERABLE:
676 g_value_set_boolean (value,
677 gtk_tree_view_column_get_reorderable (tree_column));
680 case PROP_SORT_INDICATOR:
681 g_value_set_boolean (value,
682 gtk_tree_view_column_get_sort_indicator (tree_column));
685 case PROP_SORT_ORDER:
686 g_value_set_enum (value,
687 gtk_tree_view_column_get_sort_order (tree_column));
690 case PROP_SORT_COLUMN_ID:
691 g_value_set_int (value,
692 gtk_tree_view_column_get_sort_column_id (tree_column));
696 g_value_set_object (value, tree_column->priv->cell_area);
700 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
705 /* Implementation of GtkCellLayout interface
708 gtk_tree_view_column_cell_layout_get_area (GtkCellLayout *cell_layout)
710 GtkTreeViewColumn *column;
712 g_return_val_if_fail (GTK_IS_TREE_VIEW_COLUMN (cell_layout), NULL);
713 column = GTK_TREE_VIEW_COLUMN (cell_layout);
715 return column->cell_area;
718 /* Button handling code
721 gtk_tree_view_column_create_button (GtkTreeViewColumn *tree_column)
723 GtkTreeView *tree_view;
727 tree_view = (GtkTreeView *) tree_column->tree_view;
729 g_return_if_fail (GTK_IS_TREE_VIEW (tree_view));
730 g_return_if_fail (tree_column->button == NULL);
732 gtk_widget_push_composite_child ();
733 tree_column->button = gtk_button_new ();
734 gtk_widget_add_events (tree_column->button, GDK_POINTER_MOTION_MASK);
735 gtk_widget_pop_composite_child ();
737 /* make sure we own a reference to it as well. */
738 if (tree_view->priv->header_window)
739 gtk_widget_set_parent_window (tree_column->button, tree_view->priv->header_window);
740 gtk_widget_set_parent (tree_column->button, GTK_WIDGET (tree_view));
742 g_signal_connect (tree_column->button, "event",
743 G_CALLBACK (gtk_tree_view_column_button_event),
745 g_signal_connect (tree_column->button, "clicked",
746 G_CALLBACK (gtk_tree_view_column_button_clicked),
749 tree_column->alignment = gtk_alignment_new (tree_column->xalign, 0.5, 0.0, 0.0);
751 hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 2);
752 tree_column->arrow = gtk_arrow_new (GTK_ARROW_DOWN, GTK_SHADOW_IN);
754 if (tree_column->child)
755 child = tree_column->child;
758 child = gtk_label_new (tree_column->title);
759 gtk_widget_show (child);
762 g_signal_connect (child, "mnemonic-activate",
763 G_CALLBACK (gtk_tree_view_column_mnemonic_activate),
766 if (tree_column->xalign <= 0.5)
767 gtk_box_pack_end (GTK_BOX (hbox), tree_column->arrow, FALSE, FALSE, 0);
769 gtk_box_pack_start (GTK_BOX (hbox), tree_column->arrow, FALSE, FALSE, 0);
771 gtk_box_pack_start (GTK_BOX (hbox), tree_column->alignment, TRUE, TRUE, 0);
773 gtk_container_add (GTK_CONTAINER (tree_column->alignment), child);
774 gtk_container_add (GTK_CONTAINER (tree_column->button), hbox);
776 gtk_widget_show (hbox);
777 gtk_widget_show (tree_column->alignment);
778 gtk_tree_view_column_update_button (tree_column);
782 gtk_tree_view_column_update_button (GtkTreeViewColumn *tree_column)
784 gint sort_column_id = -1;
786 GtkWidget *alignment;
788 GtkWidget *current_child;
789 GtkArrowType arrow_type = GTK_ARROW_NONE;
792 if (tree_column->tree_view)
793 model = gtk_tree_view_get_model (GTK_TREE_VIEW (tree_column->tree_view));
797 /* Create a button if necessary */
798 if (tree_column->visible &&
799 tree_column->button == NULL &&
800 tree_column->tree_view &&
801 gtk_widget_get_realized (tree_column->tree_view))
802 gtk_tree_view_column_create_button (tree_column);
804 if (! tree_column->button)
807 hbox = gtk_bin_get_child (GTK_BIN (tree_column->button));
808 alignment = tree_column->alignment;
809 arrow = tree_column->arrow;
810 current_child = gtk_bin_get_child (GTK_BIN (alignment));
812 /* Set up the actual button */
813 gtk_alignment_set (GTK_ALIGNMENT (alignment), tree_column->xalign,
816 if (tree_column->child)
818 if (current_child != tree_column->child)
820 gtk_container_remove (GTK_CONTAINER (alignment),
822 gtk_container_add (GTK_CONTAINER (alignment),
828 if (current_child == NULL)
830 current_child = gtk_label_new (NULL);
831 gtk_widget_show (current_child);
832 gtk_container_add (GTK_CONTAINER (alignment),
836 g_return_if_fail (GTK_IS_LABEL (current_child));
838 if (tree_column->title)
839 gtk_label_set_text_with_mnemonic (GTK_LABEL (current_child),
842 gtk_label_set_text_with_mnemonic (GTK_LABEL (current_child),
846 if (GTK_IS_TREE_SORTABLE (model))
847 gtk_tree_sortable_get_sort_column_id (GTK_TREE_SORTABLE (model),
851 if (tree_column->show_sort_indicator)
853 gboolean alternative;
855 g_object_get (gtk_widget_get_settings (tree_column->tree_view),
856 "gtk-alternative-sort-arrows", &alternative,
859 switch (tree_column->sort_order)
861 case GTK_SORT_ASCENDING:
862 arrow_type = alternative ? GTK_ARROW_UP : GTK_ARROW_DOWN;
865 case GTK_SORT_DESCENDING:
866 arrow_type = alternative ? GTK_ARROW_DOWN : GTK_ARROW_UP;
870 g_warning (G_STRLOC": bad sort order");
875 gtk_arrow_set (GTK_ARROW (arrow),
879 /* Put arrow on the right if the text is left-or-center justified, and on the
880 * left otherwise; do this by packing boxes, so flipping text direction will
883 g_object_ref (arrow);
884 gtk_container_remove (GTK_CONTAINER (hbox), arrow);
886 if (tree_column->xalign <= 0.5)
888 gtk_box_pack_end (GTK_BOX (hbox), arrow, FALSE, FALSE, 0);
892 gtk_box_pack_start (GTK_BOX (hbox), arrow, FALSE, FALSE, 0);
893 /* move it to the front */
894 gtk_box_reorder_child (GTK_BOX (hbox), arrow, 0);
896 g_object_unref (arrow);
898 if (tree_column->show_sort_indicator
899 || (GTK_IS_TREE_SORTABLE (model) && tree_column->sort_column_id >= 0))
900 gtk_widget_show (arrow);
902 gtk_widget_hide (arrow);
904 /* It's always safe to hide the button. It isn't always safe to show it, as
905 * if you show it before it's realized, it'll get the wrong window. */
906 if (tree_column->button &&
907 tree_column->tree_view != NULL &&
908 gtk_widget_get_realized (tree_column->tree_view))
910 if (tree_column->visible)
912 gtk_widget_show_now (tree_column->button);
913 if (tree_column->window)
915 if (tree_column->resizable)
917 gdk_window_show (tree_column->window);
918 gdk_window_raise (tree_column->window);
922 gdk_window_hide (tree_column->window);
928 gtk_widget_hide (tree_column->button);
929 if (tree_column->window)
930 gdk_window_hide (tree_column->window);
934 if (tree_column->reorderable || tree_column->clickable)
936 gtk_widget_set_can_focus (tree_column->button, TRUE);
940 gtk_widget_set_can_focus (tree_column->button, FALSE);
941 if (gtk_widget_has_focus (tree_column->button))
943 GtkWidget *toplevel = gtk_widget_get_toplevel (tree_column->tree_view);
944 if (gtk_widget_is_toplevel (toplevel))
946 gtk_window_set_focus (GTK_WINDOW (toplevel), NULL);
950 /* Queue a resize on the assumption that we always want to catch all changes
951 * and columns don't change all that often.
953 if (gtk_widget_get_realized (tree_column->tree_view))
954 gtk_widget_queue_resize (tree_column->tree_view);
958 /* Button signal handlers
962 gtk_tree_view_column_button_event (GtkWidget *widget,
966 GtkTreeViewColumn *column = (GtkTreeViewColumn *) data;
968 g_return_val_if_fail (event != NULL, FALSE);
970 if (event->type == GDK_BUTTON_PRESS &&
971 column->reorderable &&
972 ((GdkEventButton *)event)->button == 1)
974 column->maybe_reordered = TRUE;
975 gdk_window_get_pointer (gtk_button_get_event_window (GTK_BUTTON (widget)),
979 gtk_widget_grab_focus (widget);
982 if (event->type == GDK_BUTTON_RELEASE ||
983 event->type == GDK_LEAVE_NOTIFY)
984 column->maybe_reordered = FALSE;
986 if (event->type == GDK_MOTION_NOTIFY &&
987 column->maybe_reordered &&
988 (gtk_drag_check_threshold (widget,
991 (gint) ((GdkEventMotion *)event)->x,
992 (gint) ((GdkEventMotion *)event)->y)))
994 column->maybe_reordered = FALSE;
995 _gtk_tree_view_column_start_drag (GTK_TREE_VIEW (column->tree_view), column,
996 event->motion.device);
999 if (column->clickable == FALSE)
1001 switch (event->type)
1003 case GDK_BUTTON_PRESS:
1004 case GDK_2BUTTON_PRESS:
1005 case GDK_3BUTTON_PRESS:
1006 case GDK_MOTION_NOTIFY:
1007 case GDK_BUTTON_RELEASE:
1008 case GDK_ENTER_NOTIFY:
1009 case GDK_LEAVE_NOTIFY:
1020 gtk_tree_view_column_button_clicked (GtkWidget *widget, gpointer data)
1022 g_signal_emit_by_name (data, "clicked");
1026 gtk_tree_view_column_mnemonic_activate (GtkWidget *widget,
1027 gboolean group_cycling,
1030 GtkTreeViewColumn *column = (GtkTreeViewColumn *)data;
1032 g_return_val_if_fail (GTK_IS_TREE_VIEW_COLUMN (column), FALSE);
1034 GTK_TREE_VIEW (column->tree_view)->priv->focus_column = column;
1035 if (column->clickable)
1036 gtk_button_clicked (GTK_BUTTON (column->button));
1037 else if (gtk_widget_get_can_focus (column->button))
1038 gtk_widget_grab_focus (column->button);
1040 gtk_widget_grab_focus (column->tree_view);
1046 gtk_tree_view_model_sort_column_changed (GtkTreeSortable *sortable,
1047 GtkTreeViewColumn *column)
1049 gint sort_column_id;
1052 if (gtk_tree_sortable_get_sort_column_id (sortable,
1056 if (sort_column_id == column->sort_column_id)
1058 gtk_tree_view_column_set_sort_indicator (column, TRUE);
1059 gtk_tree_view_column_set_sort_order (column, order);
1063 gtk_tree_view_column_set_sort_indicator (column, FALSE);
1068 gtk_tree_view_column_set_sort_indicator (column, FALSE);
1073 gtk_tree_view_column_sort (GtkTreeViewColumn *tree_column,
1076 gint sort_column_id;
1078 gboolean has_sort_column;
1079 gboolean has_default_sort_func;
1081 g_return_if_fail (tree_column->tree_view != NULL);
1084 gtk_tree_sortable_get_sort_column_id (GTK_TREE_SORTABLE (GTK_TREE_VIEW (tree_column->tree_view)->priv->model),
1087 has_default_sort_func =
1088 gtk_tree_sortable_has_default_sort_func (GTK_TREE_SORTABLE (GTK_TREE_VIEW (tree_column->tree_view)->priv->model));
1090 if (has_sort_column &&
1091 sort_column_id == tree_column->sort_column_id)
1093 if (order == GTK_SORT_ASCENDING)
1094 gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (GTK_TREE_VIEW (tree_column->tree_view)->priv->model),
1095 tree_column->sort_column_id,
1096 GTK_SORT_DESCENDING);
1097 else if (order == GTK_SORT_DESCENDING && has_default_sort_func)
1098 gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (GTK_TREE_VIEW (tree_column->tree_view)->priv->model),
1099 GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID,
1100 GTK_SORT_ASCENDING);
1102 gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (GTK_TREE_VIEW (tree_column->tree_view)->priv->model),
1103 tree_column->sort_column_id,
1104 GTK_SORT_ASCENDING);
1108 gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (GTK_TREE_VIEW (tree_column->tree_view)->priv->model),
1109 tree_column->sort_column_id,
1110 GTK_SORT_ASCENDING);
1116 gtk_tree_view_column_setup_sort_column_id_callback (GtkTreeViewColumn *tree_column)
1118 GtkTreeModel *model;
1120 if (tree_column->tree_view == NULL)
1123 model = gtk_tree_view_get_model (GTK_TREE_VIEW (tree_column->tree_view));
1128 if (GTK_IS_TREE_SORTABLE (model) &&
1129 tree_column->sort_column_id != -1)
1131 gint real_sort_column_id;
1132 GtkSortType real_order;
1134 if (tree_column->sort_column_changed_signal == 0)
1135 tree_column->sort_column_changed_signal =
1136 g_signal_connect (model, "sort-column-changed",
1137 G_CALLBACK (gtk_tree_view_model_sort_column_changed),
1140 if (gtk_tree_sortable_get_sort_column_id (GTK_TREE_SORTABLE (model),
1141 &real_sort_column_id,
1143 (real_sort_column_id == tree_column->sort_column_id))
1145 gtk_tree_view_column_set_sort_indicator (tree_column, TRUE);
1146 gtk_tree_view_column_set_sort_order (tree_column, real_order);
1150 gtk_tree_view_column_set_sort_indicator (tree_column, FALSE);
1156 gtk_tree_view_column_context_changed (GtkCellAreaContext *context,
1158 GtkTreeViewColumn *tree_column)
1160 if (!strcmp (pspec->name, "minimum-width") ||
1161 !strcmp (pspec->name, "natural-width") ||
1162 !strcmp (pspec->name, "minimum-height") ||
1163 !strcmp (pspec->name, "natural-height"))
1165 /* XXX We want to do something specific if the size actually got cleared
1166 * or if it just grew a little bit because of a data change and we
1167 * are in GROW_ONLY mode.
1169 _gtk_tree_view_column_cell_set_dirty (tree_column, TRUE);
1174 gtk_tree_view_column_add_editable_callback (GtkCellArea *area,
1175 GtkCellRenderer *renderer,
1176 GtkCellEditable *edit_widget,
1177 GdkRectangle *cell_area,
1178 const gchar *path_string,
1182 GtkTreeViewColumn *column = user_data;
1184 if (column->tree_view)
1186 path = gtk_tree_path_new_from_string (path_string);
1188 _gtk_tree_view_add_editable (GTK_TREE_VIEW (column->tree_view),
1194 gtk_tree_path_free (path);
1199 gtk_tree_view_column_remove_editable_callback (GtkCellArea *area,
1200 GtkCellRenderer *renderer,
1201 GtkCellEditable *edit_widget,
1204 GtkTreeViewColumn *column = user_data;
1206 if (column->tree_view)
1207 _gtk_tree_view_remove_editable (GTK_TREE_VIEW (column->tree_view),
1212 /* Exported Private Functions.
1213 * These should only be called by gtktreeview.c or gtktreeviewcolumn.c
1217 _gtk_tree_view_column_realize_button (GtkTreeViewColumn *column)
1219 GtkAllocation allocation;
1220 GtkTreeView *tree_view;
1222 guint attributes_mask;
1225 tree_view = (GtkTreeView *)column->tree_view;
1226 rtl = (gtk_widget_get_direction (GTK_WIDGET (tree_view)) == GTK_TEXT_DIR_RTL);
1228 g_return_if_fail (GTK_IS_TREE_VIEW (tree_view));
1229 g_return_if_fail (gtk_widget_get_realized (GTK_WIDGET (tree_view)));
1230 g_return_if_fail (tree_view->priv->header_window != NULL);
1231 g_return_if_fail (column->button != NULL);
1233 gtk_widget_set_parent_window (column->button, tree_view->priv->header_window);
1235 if (column->visible)
1236 gtk_widget_show (column->button);
1238 attr.window_type = GDK_WINDOW_CHILD;
1239 attr.wclass = GDK_INPUT_ONLY;
1240 attr.visual = gtk_widget_get_visual (GTK_WIDGET (tree_view));
1241 attr.event_mask = gtk_widget_get_events (GTK_WIDGET (tree_view)) |
1242 (GDK_BUTTON_PRESS_MASK |
1243 GDK_BUTTON_RELEASE_MASK |
1244 GDK_POINTER_MOTION_MASK |
1245 GDK_POINTER_MOTION_HINT_MASK |
1246 GDK_KEY_PRESS_MASK);
1247 attributes_mask = GDK_WA_CURSOR | GDK_WA_X | GDK_WA_Y;
1248 attr.cursor = gdk_cursor_new_for_display (gdk_window_get_display (tree_view->priv->header_window),
1249 GDK_SB_H_DOUBLE_ARROW);
1251 attr.width = TREE_VIEW_DRAG_WIDTH;
1252 attr.height = tree_view->priv->header_height;
1254 gtk_widget_get_allocation (column->button, &allocation);
1255 attr.x = (allocation.x + (rtl ? 0 : allocation.width)) - TREE_VIEW_DRAG_WIDTH / 2;
1256 column->window = gdk_window_new (tree_view->priv->header_window,
1257 &attr, attributes_mask);
1258 gdk_window_set_user_data (column->window, tree_view);
1260 gtk_tree_view_column_update_button (column);
1262 gdk_cursor_unref (attr.cursor);
1266 _gtk_tree_view_column_unrealize_button (GtkTreeViewColumn *column)
1268 g_return_if_fail (column != NULL);
1269 g_return_if_fail (column->window != NULL);
1271 gdk_window_set_user_data (column->window, NULL);
1272 gdk_window_destroy (column->window);
1273 column->window = NULL;
1277 _gtk_tree_view_column_unset_model (GtkTreeViewColumn *column,
1278 GtkTreeModel *old_model)
1280 if (column->sort_column_changed_signal)
1282 g_signal_handler_disconnect (old_model,
1283 column->sort_column_changed_signal);
1284 column->sort_column_changed_signal = 0;
1286 gtk_tree_view_column_set_sort_indicator (column, FALSE);
1290 _gtk_tree_view_column_set_tree_view (GtkTreeViewColumn *column,
1291 GtkTreeView *tree_view)
1293 g_assert (column->tree_view == NULL);
1295 column->tree_view = GTK_WIDGET (tree_view);
1296 gtk_tree_view_column_create_button (column);
1298 column->property_changed_signal =
1299 g_signal_connect_swapped (tree_view,
1301 G_CALLBACK (gtk_tree_view_column_setup_sort_column_id_callback),
1304 gtk_tree_view_column_setup_sort_column_id_callback (column);
1308 _gtk_tree_view_column_unset_tree_view (GtkTreeViewColumn *column)
1310 if (column->tree_view && column->button)
1312 gtk_container_remove (GTK_CONTAINER (column->tree_view), column->button);
1314 if (column->property_changed_signal)
1316 g_signal_handler_disconnect (column->tree_view, column->property_changed_signal);
1317 column->property_changed_signal = 0;
1320 if (column->sort_column_changed_signal)
1322 g_signal_handler_disconnect (gtk_tree_view_get_model (GTK_TREE_VIEW (column->tree_view)),
1323 column->sort_column_changed_signal);
1324 column->sort_column_changed_signal = 0;
1327 column->tree_view = NULL;
1328 column->button = NULL;
1332 _gtk_tree_view_column_has_editable_cell (GtkTreeViewColumn *column)
1334 gboolean ret = FALSE;
1335 GList *list, *cells;
1337 cells = gtk_cell_layout_get_cells (GTK_CELL_LAYOUT (column->cell_area));
1339 for (list = cells; list; list = list->next)
1341 GtkCellRenderer *cell = list->data;
1342 GtkCellRendererMode mode;
1344 g_object_get (cell, "mode", &mode, NULL);
1346 if (mode == GTK_CELL_RENDERER_MODE_EDITABLE)
1353 g_list_free (cells);
1358 /* gets cell being edited */
1360 _gtk_tree_view_column_get_edited_cell (GtkTreeViewColumn *column)
1362 return gtk_cell_area_get_edited_cell (column->cell_area);
1365 /* Public Functions */
1369 * gtk_tree_view_column_new:
1371 * Creates a new #GtkTreeViewColumn.
1373 * Return value: A newly created #GtkTreeViewColumn.
1376 gtk_tree_view_column_new (void)
1378 GtkTreeViewColumn *tree_column;
1380 tree_column = g_object_new (GTK_TYPE_TREE_VIEW_COLUMN, NULL);
1386 * gtk_tree_view_column_new_with_attributes:
1387 * @title: The title to set the header to.
1388 * @cell: The #GtkCellRenderer.
1389 * @Varargs: A %NULL-terminated list of attributes.
1391 * Creates a new #GtkTreeViewColumn with a number of default values. This is
1392 * equivalent to calling gtk_tree_view_column_set_title(),
1393 * gtk_tree_view_column_pack_start(), and
1394 * gtk_tree_view_column_set_attributes() on the newly created #GtkTreeViewColumn.
1396 * Here's a simple example:
1398 * enum { TEXT_COLUMN, COLOR_COLUMN, N_COLUMNS };
1401 * GtkTreeViewColumn *column;
1402 * GtkCellRenderer *renderer = gtk_cell_renderer_text_new ();
1404 * column = gtk_tree_view_column_new_with_attributes ("Title",
1406 * "text", TEXT_COLUMN,
1407 * "foreground", COLOR_COLUMN,
1412 * Return value: A newly created #GtkTreeViewColumn.
1415 gtk_tree_view_column_new_with_attributes (const gchar *title,
1416 GtkCellRenderer *cell,
1419 GtkTreeViewColumn *retval;
1422 retval = gtk_tree_view_column_new ();
1424 gtk_tree_view_column_set_title (retval, title);
1425 gtk_tree_view_column_pack_start (retval, cell, TRUE);
1427 va_start (args, cell);
1428 gtk_tree_view_column_set_attributesv (retval, cell, args);
1435 * gtk_tree_view_column_pack_start:
1436 * @tree_column: A #GtkTreeViewColumn.
1437 * @cell: The #GtkCellRenderer.
1438 * @expand: %TRUE if @cell is to be given extra space allocated to @tree_column.
1440 * Packs the @cell into the beginning of the column. If @expand is %FALSE, then
1441 * the @cell is allocated no more space than it needs. Any unused space is divided
1442 * evenly between cells for which @expand is %TRUE.
1445 gtk_tree_view_column_pack_start (GtkTreeViewColumn *tree_column,
1446 GtkCellRenderer *cell,
1449 gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (tree_column), cell, expand);
1453 * gtk_tree_view_column_pack_end:
1454 * @tree_column: A #GtkTreeViewColumn.
1455 * @cell: The #GtkCellRenderer.
1456 * @expand: %TRUE if @cell is to be given extra space allocated to @tree_column.
1458 * Adds the @cell to end of the column. If @expand is %FALSE, then the @cell
1459 * is allocated no more space than it needs. Any unused space is divided
1460 * evenly between cells for which @expand is %TRUE.
1463 gtk_tree_view_column_pack_end (GtkTreeViewColumn *tree_column,
1464 GtkCellRenderer *cell,
1467 gtk_cell_layout_pack_end (GTK_CELL_LAYOUT (tree_column), cell, expand);
1471 * gtk_tree_view_column_clear:
1472 * @tree_column: A #GtkTreeViewColumn
1474 * Unsets all the mappings on all renderers on the @tree_column.
1477 gtk_tree_view_column_clear (GtkTreeViewColumn *tree_column)
1479 gtk_cell_layout_clear (GTK_CELL_LAYOUT (tree_column));
1483 * gtk_tree_view_column_add_attribute:
1484 * @tree_column: A #GtkTreeViewColumn.
1485 * @cell_renderer: the #GtkCellRenderer to set attributes on
1486 * @attribute: An attribute on the renderer
1487 * @column: The column position on the model to get the attribute from.
1489 * Adds an attribute mapping to the list in @tree_column. The @column is the
1490 * column of the model to get a value from, and the @attribute is the
1491 * parameter on @cell_renderer to be set from the value. So for example
1492 * if column 2 of the model contains strings, you could have the
1493 * "text" attribute of a #GtkCellRendererText get its values from
1497 gtk_tree_view_column_add_attribute (GtkTreeViewColumn *tree_column,
1498 GtkCellRenderer *cell_renderer,
1499 const gchar *attribute,
1502 gtk_cell_layout_add_attribute (GTK_CELL_LAYOUT (tree_column),
1503 cell_renderer, attribute, column);
1507 gtk_tree_view_column_set_attributesv (GtkTreeViewColumn *tree_column,
1508 GtkCellRenderer *cell_renderer,
1514 attribute = va_arg (args, gchar *);
1516 gtk_cell_layout_clear_attributes (GTK_CELL_LAYOUT (tree_column->cell_area),
1519 while (attribute != NULL)
1521 column = va_arg (args, gint);
1522 gtk_cell_layout_add_attribute (GTK_CELL_LAYOUT (tree_column->cell_area),
1523 cell_renderer, attribute, column);
1524 attribute = va_arg (args, gchar *);
1529 * gtk_tree_view_column_set_attributes:
1530 * @tree_column: A #GtkTreeViewColumn.
1531 * @cell_renderer: the #GtkCellRenderer we're setting the attributes of
1532 * @Varargs: A %NULL-terminated list of attributes.
1534 * Sets the attributes in the list as the attributes of @tree_column.
1535 * The attributes should be in attribute/column order, as in
1536 * gtk_tree_view_column_add_attribute(). All existing attributes
1537 * are removed, and replaced with the new attributes.
1540 gtk_tree_view_column_set_attributes (GtkTreeViewColumn *tree_column,
1541 GtkCellRenderer *cell_renderer,
1546 g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column));
1547 g_return_if_fail (GTK_IS_CELL_RENDERER (cell_renderer));
1549 va_start (args, cell_renderer);
1550 gtk_tree_view_column_set_attributesv (tree_column, cell_renderer, args);
1556 * gtk_tree_view_column_set_cell_data_func:
1557 * @tree_column: A #GtkTreeViewColumn
1558 * @cell_renderer: A #GtkCellRenderer
1559 * @func: The #GtkTreeViewColumnFunc to use.
1560 * @func_data: The user data for @func.
1561 * @destroy: The destroy notification for @func_data
1563 * Sets the #GtkTreeViewColumnFunc to use for the column. This
1564 * function is used instead of the standard attributes mapping for
1565 * setting the column value, and should set the value of @tree_column's
1566 * cell renderer as appropriate. @func may be %NULL to remove an
1570 gtk_tree_view_column_set_cell_data_func (GtkTreeViewColumn *tree_column,
1571 GtkCellRenderer *cell_renderer,
1572 GtkTreeCellDataFunc func,
1574 GDestroyNotify destroy)
1576 gtk_cell_layout_set_cell_data_func (GTK_CELL_LAYOUT (tree_column),
1578 (GtkCellLayoutDataFunc)func,
1579 func_data, destroy);
1584 * gtk_tree_view_column_clear_attributes:
1585 * @tree_column: a #GtkTreeViewColumn
1586 * @cell_renderer: a #GtkCellRenderer to clear the attribute mapping on.
1588 * Clears all existing attributes previously set with
1589 * gtk_tree_view_column_set_attributes().
1592 gtk_tree_view_column_clear_attributes (GtkTreeViewColumn *tree_column,
1593 GtkCellRenderer *cell_renderer)
1595 gtk_cell_layout_clear_attributes (GTK_CELL_LAYOUT (tree_column),
1600 * gtk_tree_view_column_set_spacing:
1601 * @tree_column: A #GtkTreeViewColumn.
1602 * @spacing: distance between cell renderers in pixels.
1604 * Sets the spacing field of @tree_column, which is the number of pixels to
1605 * place between cell renderers packed into it.
1608 gtk_tree_view_column_set_spacing (GtkTreeViewColumn *tree_column,
1611 g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column));
1612 g_return_if_fail (spacing >= 0);
1614 gtk_cell_area_box_set_spacing (GTK_CELL_AREA_BOX (tree_column->cell_area),
1616 if (tree_column->tree_view)
1617 _gtk_tree_view_column_cell_set_dirty (tree_column, TRUE);
1621 * gtk_tree_view_column_get_spacing:
1622 * @tree_column: A #GtkTreeViewColumn.
1624 * Returns the spacing of @tree_column.
1626 * Return value: the spacing of @tree_column.
1629 gtk_tree_view_column_get_spacing (GtkTreeViewColumn *tree_column)
1631 g_return_val_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column), 0);
1633 return gtk_cell_area_box_get_spacing (GTK_CELL_AREA_BOX (tree_column->cell_area));
1636 /* Options for manipulating the columns */
1639 * gtk_tree_view_column_set_visible:
1640 * @tree_column: A #GtkTreeViewColumn.
1641 * @visible: %TRUE if the @tree_column is visible.
1643 * Sets the visibility of @tree_column.
1646 gtk_tree_view_column_set_visible (GtkTreeViewColumn *tree_column,
1649 g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column));
1651 visible = !! visible;
1653 if (tree_column->visible == visible)
1656 tree_column->visible = visible;
1658 if (tree_column->visible)
1659 _gtk_tree_view_column_cell_set_dirty (tree_column, TRUE);
1661 gtk_tree_view_column_update_button (tree_column);
1662 g_object_notify (G_OBJECT (tree_column), "visible");
1666 * gtk_tree_view_column_get_visible:
1667 * @tree_column: A #GtkTreeViewColumn.
1669 * Returns %TRUE if @tree_column is visible.
1671 * Return value: whether the column is visible or not. If it is visible, then
1672 * the tree will show the column.
1675 gtk_tree_view_column_get_visible (GtkTreeViewColumn *tree_column)
1677 g_return_val_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column), FALSE);
1679 return tree_column->visible;
1683 * gtk_tree_view_column_set_resizable:
1684 * @tree_column: A #GtkTreeViewColumn
1685 * @resizable: %TRUE, if the column can be resized
1687 * If @resizable is %TRUE, then the user can explicitly resize the column by
1688 * grabbing the outer edge of the column button. If resizable is %TRUE and
1689 * sizing mode of the column is #GTK_TREE_VIEW_COLUMN_AUTOSIZE, then the sizing
1690 * mode is changed to #GTK_TREE_VIEW_COLUMN_GROW_ONLY.
1693 gtk_tree_view_column_set_resizable (GtkTreeViewColumn *tree_column,
1696 g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column));
1698 resizable = !! resizable;
1700 if (tree_column->resizable == resizable)
1703 tree_column->resizable = resizable;
1705 if (resizable && tree_column->column_type == GTK_TREE_VIEW_COLUMN_AUTOSIZE)
1706 gtk_tree_view_column_set_sizing (tree_column, GTK_TREE_VIEW_COLUMN_GROW_ONLY);
1708 gtk_tree_view_column_update_button (tree_column);
1710 g_object_notify (G_OBJECT (tree_column), "resizable");
1714 * gtk_tree_view_column_get_resizable:
1715 * @tree_column: A #GtkTreeViewColumn
1717 * Returns %TRUE if the @tree_column can be resized by the end user.
1719 * Return value: %TRUE, if the @tree_column can be resized.
1722 gtk_tree_view_column_get_resizable (GtkTreeViewColumn *tree_column)
1724 g_return_val_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column), FALSE);
1726 return tree_column->resizable;
1731 * gtk_tree_view_column_set_sizing:
1732 * @tree_column: A #GtkTreeViewColumn.
1733 * @type: The #GtkTreeViewColumnSizing.
1735 * Sets the growth behavior of @tree_column to @type.
1738 gtk_tree_view_column_set_sizing (GtkTreeViewColumn *tree_column,
1739 GtkTreeViewColumnSizing type)
1741 g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column));
1743 if (type == tree_column->column_type)
1746 if (type == GTK_TREE_VIEW_COLUMN_AUTOSIZE)
1747 gtk_tree_view_column_set_resizable (tree_column, FALSE);
1750 /* I was clearly on crack when I wrote this. I'm not sure what's supposed to
1751 * be below so I'll leave it until I figure it out.
1753 if (tree_column->column_type == GTK_TREE_VIEW_COLUMN_AUTOSIZE &&
1754 tree_column->requested_width != -1)
1756 gtk_tree_view_column_set_sizing (tree_column, tree_column->requested_width);
1759 tree_column->column_type = type;
1761 gtk_tree_view_column_update_button (tree_column);
1763 g_object_notify (G_OBJECT (tree_column), "sizing");
1767 * gtk_tree_view_column_get_sizing:
1768 * @tree_column: A #GtkTreeViewColumn.
1770 * Returns the current type of @tree_column.
1772 * Return value: The type of @tree_column.
1774 GtkTreeViewColumnSizing
1775 gtk_tree_view_column_get_sizing (GtkTreeViewColumn *tree_column)
1777 g_return_val_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column), 0);
1779 return tree_column->column_type;
1783 * gtk_tree_view_column_get_width:
1784 * @tree_column: A #GtkTreeViewColumn.
1786 * Returns the current size of @tree_column in pixels.
1788 * Return value: The current width of @tree_column.
1791 gtk_tree_view_column_get_width (GtkTreeViewColumn *tree_column)
1793 g_return_val_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column), 0);
1795 return tree_column->width;
1799 _gtk_tree_view_column_set_width (GtkTreeViewColumn *tree_column,
1803 g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column));
1805 gtk_cell_area_context_allocate (tree_column->cell_area_context, internal_width, -1);
1806 tree_column->width = width;
1808 g_object_notify (G_OBJECT (tree_column), "width");
1812 * gtk_tree_view_column_set_fixed_width:
1813 * @tree_column: A #GtkTreeViewColumn.
1814 * @fixed_width: The size to set @tree_column to. Must be greater than 0.
1816 * Sets the size of the column in pixels. This is meaningful only if the sizing
1817 * type is #GTK_TREE_VIEW_COLUMN_FIXED. The size of the column is clamped to
1818 * the min/max width for the column. Please note that the min/max width of the
1819 * column doesn't actually affect the "fixed_width" property of the widget, just
1820 * the actual size when displayed.
1823 gtk_tree_view_column_set_fixed_width (GtkTreeViewColumn *tree_column,
1826 g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column));
1827 g_return_if_fail (fixed_width > 0);
1829 tree_column->fixed_width = fixed_width;
1830 tree_column->use_resized_width = FALSE;
1832 if (tree_column->tree_view &&
1833 gtk_widget_get_realized (tree_column->tree_view) &&
1834 tree_column->column_type == GTK_TREE_VIEW_COLUMN_FIXED)
1836 gtk_widget_queue_resize (tree_column->tree_view);
1839 g_object_notify (G_OBJECT (tree_column), "fixed-width");
1843 * gtk_tree_view_column_get_fixed_width:
1844 * @tree_column: a #GtkTreeViewColumn
1846 * Gets the fixed width of the column. This value is only meaning may not be
1847 * the actual width of the column on the screen, just what is requested.
1849 * Return value: the fixed width of the column
1852 gtk_tree_view_column_get_fixed_width (GtkTreeViewColumn *tree_column)
1854 g_return_val_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column), 0);
1856 return tree_column->fixed_width;
1860 * gtk_tree_view_column_set_min_width:
1861 * @tree_column: A #GtkTreeViewColumn.
1862 * @min_width: The minimum width of the column in pixels, or -1.
1864 * Sets the minimum width of the @tree_column. If @min_width is -1, then the
1865 * minimum width is unset.
1868 gtk_tree_view_column_set_min_width (GtkTreeViewColumn *tree_column,
1871 g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column));
1872 g_return_if_fail (min_width >= -1);
1874 if (min_width == tree_column->min_width)
1877 if (tree_column->visible &&
1878 tree_column->tree_view != NULL &&
1879 gtk_widget_get_realized (tree_column->tree_view))
1881 if (min_width > tree_column->width)
1882 gtk_widget_queue_resize (tree_column->tree_view);
1885 tree_column->min_width = min_width;
1886 g_object_freeze_notify (G_OBJECT (tree_column));
1887 if (tree_column->max_width != -1 && tree_column->max_width < min_width)
1889 tree_column->max_width = min_width;
1890 g_object_notify (G_OBJECT (tree_column), "max-width");
1892 g_object_notify (G_OBJECT (tree_column), "min-width");
1893 g_object_thaw_notify (G_OBJECT (tree_column));
1895 if (tree_column->column_type == GTK_TREE_VIEW_COLUMN_AUTOSIZE)
1896 _gtk_tree_view_column_autosize (GTK_TREE_VIEW (tree_column->tree_view),
1901 * gtk_tree_view_column_get_min_width:
1902 * @tree_column: A #GtkTreeViewColumn.
1904 * Returns the minimum width in pixels of the @tree_column, or -1 if no minimum
1907 * Return value: The minimum width of the @tree_column.
1910 gtk_tree_view_column_get_min_width (GtkTreeViewColumn *tree_column)
1912 g_return_val_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column), -1);
1914 return tree_column->min_width;
1918 * gtk_tree_view_column_set_max_width:
1919 * @tree_column: A #GtkTreeViewColumn.
1920 * @max_width: The maximum width of the column in pixels, or -1.
1922 * Sets the maximum width of the @tree_column. If @max_width is -1, then the
1923 * maximum width is unset. Note, the column can actually be wider than max
1924 * width if it's the last column in a view. In this case, the column expands to
1925 * fill any extra space.
1928 gtk_tree_view_column_set_max_width (GtkTreeViewColumn *tree_column,
1931 g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column));
1932 g_return_if_fail (max_width >= -1);
1934 if (max_width == tree_column->max_width)
1937 if (tree_column->visible &&
1938 tree_column->tree_view != NULL &&
1939 gtk_widget_get_realized (tree_column->tree_view))
1941 if (max_width != -1 && max_width < tree_column->width)
1942 gtk_widget_queue_resize (tree_column->tree_view);
1945 tree_column->max_width = max_width;
1946 g_object_freeze_notify (G_OBJECT (tree_column));
1947 if (max_width != -1 && max_width < tree_column->min_width)
1949 tree_column->min_width = max_width;
1950 g_object_notify (G_OBJECT (tree_column), "min-width");
1952 g_object_notify (G_OBJECT (tree_column), "max-width");
1953 g_object_thaw_notify (G_OBJECT (tree_column));
1955 if (tree_column->column_type == GTK_TREE_VIEW_COLUMN_AUTOSIZE)
1956 _gtk_tree_view_column_autosize (GTK_TREE_VIEW (tree_column->tree_view),
1961 * gtk_tree_view_column_get_max_width:
1962 * @tree_column: A #GtkTreeViewColumn.
1964 * Returns the maximum width in pixels of the @tree_column, or -1 if no maximum
1967 * Return value: The maximum width of the @tree_column.
1970 gtk_tree_view_column_get_max_width (GtkTreeViewColumn *tree_column)
1972 g_return_val_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column), -1);
1974 return tree_column->max_width;
1978 * gtk_tree_view_column_clicked:
1979 * @tree_column: a #GtkTreeViewColumn
1981 * Emits the "clicked" signal on the column. This function will only work if
1982 * @tree_column is clickable.
1985 gtk_tree_view_column_clicked (GtkTreeViewColumn *tree_column)
1987 g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column));
1989 if (tree_column->visible &&
1990 tree_column->button &&
1991 tree_column->clickable)
1992 gtk_button_clicked (GTK_BUTTON (tree_column->button));
1996 * gtk_tree_view_column_set_title:
1997 * @tree_column: A #GtkTreeViewColumn.
1998 * @title: The title of the @tree_column.
2000 * Sets the title of the @tree_column. If a custom widget has been set, then
2001 * this value is ignored.
2004 gtk_tree_view_column_set_title (GtkTreeViewColumn *tree_column,
2009 g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column));
2011 new_title = g_strdup (title);
2012 g_free (tree_column->title);
2013 tree_column->title = new_title;
2015 gtk_tree_view_column_update_button (tree_column);
2016 g_object_notify (G_OBJECT (tree_column), "title");
2020 * gtk_tree_view_column_get_title:
2021 * @tree_column: A #GtkTreeViewColumn.
2023 * Returns the title of the widget.
2025 * Return value: the title of the column. This string should not be
2026 * modified or freed.
2028 G_CONST_RETURN gchar *
2029 gtk_tree_view_column_get_title (GtkTreeViewColumn *tree_column)
2031 g_return_val_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column), NULL);
2033 return tree_column->title;
2037 * gtk_tree_view_column_set_expand:
2038 * @tree_column: A #GtkTreeViewColumn
2039 * @expand: %TRUE if the column should take available extra space, %FALSE if not
2041 * Sets the column to take available extra space. This space is shared equally
2042 * amongst all columns that have the expand set to %TRUE. If no column has this
2043 * option set, then the last column gets all extra space. By default, every
2044 * column is created with this %FALSE.
2049 gtk_tree_view_column_set_expand (GtkTreeViewColumn *tree_column,
2052 g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column));
2054 expand = expand?TRUE:FALSE;
2055 if (tree_column->expand == expand)
2057 tree_column->expand = expand;
2059 if (tree_column->visible &&
2060 tree_column->tree_view != NULL &&
2061 gtk_widget_get_realized (tree_column->tree_view))
2063 /* We want to continue using the original width of the
2064 * column that includes additional space added by the user
2065 * resizing the columns and possibly extra (expanded) space, which
2066 * are not included in the resized width.
2068 tree_column->use_resized_width = FALSE;
2070 gtk_widget_queue_resize (tree_column->tree_view);
2073 g_object_notify (G_OBJECT (tree_column), "expand");
2077 * gtk_tree_view_column_get_expand:
2078 * @tree_column: a #GtkTreeViewColumn
2080 * Return %TRUE if the column expands to take any available space.
2082 * Return value: %TRUE, if the column expands
2087 gtk_tree_view_column_get_expand (GtkTreeViewColumn *tree_column)
2089 g_return_val_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column), FALSE);
2091 return tree_column->expand;
2095 * gtk_tree_view_column_set_clickable:
2096 * @tree_column: A #GtkTreeViewColumn.
2097 * @clickable: %TRUE if the header is active.
2099 * Sets the header to be active if @active is %TRUE. When the header is active,
2100 * then it can take keyboard focus, and can be clicked.
2103 gtk_tree_view_column_set_clickable (GtkTreeViewColumn *tree_column,
2106 g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column));
2108 clickable = !! clickable;
2109 if (tree_column->clickable == clickable)
2112 tree_column->clickable = clickable;
2113 gtk_tree_view_column_update_button (tree_column);
2114 g_object_notify (G_OBJECT (tree_column), "clickable");
2118 * gtk_tree_view_column_get_clickable:
2119 * @tree_column: a #GtkTreeViewColumn
2121 * Returns %TRUE if the user can click on the header for the column.
2123 * Return value: %TRUE if user can click the column header.
2126 gtk_tree_view_column_get_clickable (GtkTreeViewColumn *tree_column)
2128 g_return_val_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column), FALSE);
2130 return tree_column->clickable;
2134 * gtk_tree_view_column_set_widget:
2135 * @tree_column: A #GtkTreeViewColumn.
2136 * @widget: (allow-none): A child #GtkWidget, or %NULL.
2138 * Sets the widget in the header to be @widget. If widget is %NULL, then the
2139 * header button is set with a #GtkLabel set to the title of @tree_column.
2142 gtk_tree_view_column_set_widget (GtkTreeViewColumn *tree_column,
2145 g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column));
2146 g_return_if_fail (widget == NULL || GTK_IS_WIDGET (widget));
2149 g_object_ref_sink (widget);
2151 if (tree_column->child)
2152 g_object_unref (tree_column->child);
2154 tree_column->child = widget;
2155 gtk_tree_view_column_update_button (tree_column);
2156 g_object_notify (G_OBJECT (tree_column), "widget");
2160 * gtk_tree_view_column_get_widget:
2161 * @tree_column: A #GtkTreeViewColumn.
2163 * Returns the #GtkWidget in the button on the column header.
2164 * If a custom widget has not been set then %NULL is returned.
2166 * Return value: (transfer none): The #GtkWidget in the column
2170 gtk_tree_view_column_get_widget (GtkTreeViewColumn *tree_column)
2172 g_return_val_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column), NULL);
2174 return tree_column->child;
2178 * gtk_tree_view_column_set_alignment:
2179 * @tree_column: A #GtkTreeViewColumn.
2180 * @xalign: The alignment, which is between [0.0 and 1.0] inclusive.
2182 * Sets the alignment of the title or custom widget inside the column header.
2183 * The alignment determines its location inside the button -- 0.0 for left, 0.5
2184 * for center, 1.0 for right.
2187 gtk_tree_view_column_set_alignment (GtkTreeViewColumn *tree_column,
2190 g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column));
2192 xalign = CLAMP (xalign, 0.0, 1.0);
2194 if (tree_column->xalign == xalign)
2197 tree_column->xalign = xalign;
2198 gtk_tree_view_column_update_button (tree_column);
2199 g_object_notify (G_OBJECT (tree_column), "alignment");
2203 * gtk_tree_view_column_get_alignment:
2204 * @tree_column: A #GtkTreeViewColumn.
2206 * Returns the current x alignment of @tree_column. This value can range
2207 * between 0.0 and 1.0.
2209 * Return value: The current alignent of @tree_column.
2212 gtk_tree_view_column_get_alignment (GtkTreeViewColumn *tree_column)
2214 g_return_val_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column), 0.5);
2216 return tree_column->xalign;
2220 * gtk_tree_view_column_set_reorderable:
2221 * @tree_column: A #GtkTreeViewColumn
2222 * @reorderable: %TRUE, if the column can be reordered.
2224 * If @reorderable is %TRUE, then the column can be reordered by the end user
2225 * dragging the header.
2228 gtk_tree_view_column_set_reorderable (GtkTreeViewColumn *tree_column,
2229 gboolean reorderable)
2231 g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column));
2234 gtk_tree_view_column_set_clickable (tree_column, TRUE);*/
2236 if (tree_column->reorderable == (reorderable?TRUE:FALSE))
2239 tree_column->reorderable = (reorderable?TRUE:FALSE);
2240 gtk_tree_view_column_update_button (tree_column);
2241 g_object_notify (G_OBJECT (tree_column), "reorderable");
2245 * gtk_tree_view_column_get_reorderable:
2246 * @tree_column: A #GtkTreeViewColumn
2248 * Returns %TRUE if the @tree_column can be reordered by the user.
2250 * Return value: %TRUE if the @tree_column can be reordered by the user.
2253 gtk_tree_view_column_get_reorderable (GtkTreeViewColumn *tree_column)
2255 g_return_val_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column), FALSE);
2257 return tree_column->reorderable;
2262 * gtk_tree_view_column_set_sort_column_id:
2263 * @tree_column: a #GtkTreeViewColumn
2264 * @sort_column_id: The @sort_column_id of the model to sort on.
2266 * Sets the logical @sort_column_id that this column sorts on when this column
2267 * is selected for sorting. Doing so makes the column header clickable.
2270 gtk_tree_view_column_set_sort_column_id (GtkTreeViewColumn *tree_column,
2271 gint sort_column_id)
2273 g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column));
2274 g_return_if_fail (sort_column_id >= -1);
2276 if (tree_column->sort_column_id == sort_column_id)
2279 tree_column->sort_column_id = sort_column_id;
2281 /* Handle unsetting the id */
2282 if (sort_column_id == -1)
2284 GtkTreeModel *model = gtk_tree_view_get_model (GTK_TREE_VIEW (tree_column->tree_view));
2286 if (tree_column->sort_clicked_signal)
2288 g_signal_handler_disconnect (tree_column, tree_column->sort_clicked_signal);
2289 tree_column->sort_clicked_signal = 0;
2292 if (tree_column->sort_column_changed_signal)
2294 g_signal_handler_disconnect (model, tree_column->sort_column_changed_signal);
2295 tree_column->sort_column_changed_signal = 0;
2298 gtk_tree_view_column_set_sort_order (tree_column, GTK_SORT_ASCENDING);
2299 gtk_tree_view_column_set_sort_indicator (tree_column, FALSE);
2300 gtk_tree_view_column_set_clickable (tree_column, FALSE);
2301 g_object_notify (G_OBJECT (tree_column), "sort-column-id");
2305 gtk_tree_view_column_set_clickable (tree_column, TRUE);
2307 if (! tree_column->sort_clicked_signal)
2308 tree_column->sort_clicked_signal = g_signal_connect (tree_column,
2310 G_CALLBACK (gtk_tree_view_column_sort),
2313 gtk_tree_view_column_setup_sort_column_id_callback (tree_column);
2314 g_object_notify (G_OBJECT (tree_column), "sort-column-id");
2318 * gtk_tree_view_column_get_sort_column_id:
2319 * @tree_column: a #GtkTreeViewColumn
2321 * Gets the logical @sort_column_id that the model sorts on when this
2322 * column is selected for sorting.
2323 * See gtk_tree_view_column_set_sort_column_id().
2325 * Return value: the current @sort_column_id for this column, or -1 if
2326 * this column can't be used for sorting.
2329 gtk_tree_view_column_get_sort_column_id (GtkTreeViewColumn *tree_column)
2331 g_return_val_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column), 0);
2333 return tree_column->sort_column_id;
2337 * gtk_tree_view_column_set_sort_indicator:
2338 * @tree_column: a #GtkTreeViewColumn
2339 * @setting: %TRUE to display an indicator that the column is sorted
2341 * Call this function with a @setting of %TRUE to display an arrow in
2342 * the header button indicating the column is sorted. Call
2343 * gtk_tree_view_column_set_sort_order() to change the direction of
2348 gtk_tree_view_column_set_sort_indicator (GtkTreeViewColumn *tree_column,
2351 g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column));
2353 setting = setting != FALSE;
2355 if (setting == tree_column->show_sort_indicator)
2358 tree_column->show_sort_indicator = setting;
2359 gtk_tree_view_column_update_button (tree_column);
2360 g_object_notify (G_OBJECT (tree_column), "sort-indicator");
2364 * gtk_tree_view_column_get_sort_indicator:
2365 * @tree_column: a #GtkTreeViewColumn
2367 * Gets the value set by gtk_tree_view_column_set_sort_indicator().
2369 * Return value: whether the sort indicator arrow is displayed
2372 gtk_tree_view_column_get_sort_indicator (GtkTreeViewColumn *tree_column)
2374 g_return_val_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column), FALSE);
2376 return tree_column->show_sort_indicator;
2380 * gtk_tree_view_column_set_sort_order:
2381 * @tree_column: a #GtkTreeViewColumn
2382 * @order: sort order that the sort indicator should indicate
2384 * Changes the appearance of the sort indicator.
2386 * This <emphasis>does not</emphasis> actually sort the model. Use
2387 * gtk_tree_view_column_set_sort_column_id() if you want automatic sorting
2388 * support. This function is primarily for custom sorting behavior, and should
2389 * be used in conjunction with gtk_tree_sortable_set_sort_column() to do
2390 * that. For custom models, the mechanism will vary.
2392 * The sort indicator changes direction to indicate normal sort or reverse sort.
2393 * Note that you must have the sort indicator enabled to see anything when
2394 * calling this function; see gtk_tree_view_column_set_sort_indicator().
2397 gtk_tree_view_column_set_sort_order (GtkTreeViewColumn *tree_column,
2400 g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column));
2402 if (order == tree_column->sort_order)
2405 tree_column->sort_order = order;
2406 gtk_tree_view_column_update_button (tree_column);
2407 g_object_notify (G_OBJECT (tree_column), "sort-order");
2411 * gtk_tree_view_column_get_sort_order:
2412 * @tree_column: a #GtkTreeViewColumn
2414 * Gets the value set by gtk_tree_view_column_set_sort_order().
2416 * Return value: the sort order the sort indicator is indicating
2419 gtk_tree_view_column_get_sort_order (GtkTreeViewColumn *tree_column)
2421 g_return_val_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column), 0);
2423 return tree_column->sort_order;
2427 * gtk_tree_view_column_cell_set_cell_data:
2428 * @tree_column: A #GtkTreeViewColumn.
2429 * @tree_model: The #GtkTreeModel to to get the cell renderers attributes from.
2430 * @iter: The #GtkTreeIter to to get the cell renderer's attributes from.
2431 * @is_expander: %TRUE, if the row has children
2432 * @is_expanded: %TRUE, if the row has visible children
2434 * Sets the cell renderer based on the @tree_model and @iter. That is, for
2435 * every attribute mapping in @tree_column, it will get a value from the set
2436 * column on the @iter, and use that value to set the attribute on the cell
2437 * renderer. This is used primarily by the #GtkTreeView.
2440 gtk_tree_view_column_cell_set_cell_data (GtkTreeViewColumn *tree_column,
2441 GtkTreeModel *tree_model,
2443 gboolean is_expander,
2444 gboolean is_expanded)
2446 g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column));
2448 if (tree_model == NULL)
2451 gtk_cell_area_apply_attributes (tree_column->cell_area, tree_model, iter,
2452 is_expander, is_expanded);
2456 * gtk_tree_view_column_cell_get_size:
2457 * @tree_column: A #GtkTreeViewColumn.
2458 * @cell_area: (allow-none): The area a cell in the column will be allocated, or %NULL
2459 * @x_offset: (allow-none): location to return x offset of a cell relative to @cell_area, or %NULL
2460 * @y_offset: (allow-none): location to return y offset of a cell relative to @cell_area, or %NULL
2461 * @width: (allow-none): location to return width needed to render a cell, or %NULL
2462 * @height: (allow-none): location to return height needed to render a cell, or %NULL
2464 * Obtains the width and height needed to render the column. This is used
2465 * primarily by the #GtkTreeView.
2468 gtk_tree_view_column_cell_get_size (GtkTreeViewColumn *tree_column,
2469 const GdkRectangle *cell_area,
2475 int focus_line_width;
2477 g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column));
2484 /* FIXME: This is a temporary hack to get things to allocate mostly right.
2486 * We will add twice the focus-line-width to the for-width
2487 * parameter below. If we do not do this, the height returned is the
2488 * height for two lines of text instead of one. It feels like some lines
2489 * get less width than expected (due to subtraction of focus_line_width?)
2490 * and will unnecessarily wrap.
2492 gtk_widget_style_get (tree_column->tree_view,
2493 "focus-line-width", &focus_line_width,
2496 g_signal_handler_block (tree_column->cell_area_context,
2497 tree_column->context_changed_signal);
2499 gtk_cell_area_get_preferred_width (tree_column->cell_area,
2500 tree_column->cell_area_context,
2501 tree_column->tree_view,
2503 gtk_cell_area_get_preferred_height_for_width (tree_column->cell_area,
2504 tree_column->cell_area_context,
2505 tree_column->tree_view,
2506 *width + focus_line_width * 2,
2510 g_signal_handler_unblock (tree_column->cell_area_context,
2511 tree_column->context_changed_signal);
2516 * gtk_tree_view_column_cell_render:
2517 * @tree_column: A #GtkTreeViewColumn.
2518 * @cr: cairo context to draw to
2519 * @background_area: entire cell area (including tree expanders and maybe padding on the sides)
2520 * @cell_area: area normally rendered by a cell renderer
2521 * @flags: flags that affect rendering
2523 * Renders the cell contained by #tree_column. This is used primarily by the
2527 _gtk_tree_view_column_cell_render (GtkTreeViewColumn *tree_column,
2529 const GdkRectangle *background_area,
2530 const GdkRectangle *cell_area,
2532 gboolean draw_focus)
2534 g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column));
2535 g_return_if_fail (cr != NULL);
2536 g_return_if_fail (background_area != NULL);
2537 g_return_if_fail (cell_area != NULL);
2541 gtk_cell_area_render (tree_column->cell_area, tree_column->cell_area_context,
2542 tree_column->tree_view, cr,
2543 background_area, cell_area, flags,
2550 _gtk_tree_view_column_cell_event (GtkTreeViewColumn *tree_column,
2551 GtkCellEditable **editable_widget,
2554 const GdkRectangle *background_area,
2555 const GdkRectangle *cell_area,
2558 g_return_val_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column), FALSE);
2560 /* FIXME: Should we pass background area here as well?
2561 * What will happen to the path_string and editable widget
2564 return gtk_cell_area_event (tree_column->cell_area,
2565 tree_column->cell_area_context,
2566 tree_column->tree_view,
2573 _gtk_tree_view_column_get_focus_area (GtkTreeViewColumn *tree_column,
2574 const GdkRectangle *background_area,
2575 const GdkRectangle *cell_area,
2576 GdkRectangle *focus_area)
2580 gtk_tree_view_column_cell_process_action (tree_column,
2593 _gtk_tree_view_column_cell_focus (GtkTreeViewColumn *tree_column,
2599 GtkDirectionType direction = 0;
2601 rtl = gtk_widget_get_direction (GTK_WIDGET (tree_column->tree_view)) == GTK_TEXT_DIR_RTL;
2606 direction = GTK_DIR_LEFT;
2610 direction = GTK_DIR_RIGHT;
2614 /* if we are the current focus column and have multiple editable cells,
2615 * try to select the next one, else move the focus to the next column
2617 if (GTK_TREE_VIEW (tree_column->tree_view)->priv->focus_column == tree_column)
2619 if (gtk_cell_area_focus (tree_column->cell_area, direction))
2620 /* Focus stays in this column, so we are done */
2623 /* FIXME: RTL support for the following: */
2624 if (count == -1 && !left)
2626 direction = GTK_DIR_RIGHT;
2627 gtk_cell_area_focus (tree_column->cell_area, direction);
2629 else if (count == 1 && !right)
2631 direction = GTK_DIR_LEFT;
2632 gtk_cell_area_focus (tree_column->cell_area, direction);
2638 return gtk_cell_area_focus (tree_column->cell_area, direction);
2642 * gtk_tree_view_column_cell_is_visible:
2643 * @tree_column: A #GtkTreeViewColumn
2645 * Returns %TRUE if any of the cells packed into the @tree_column are visible.
2646 * For this to be meaningful, you must first initialize the cells with
2647 * gtk_tree_view_column_cell_set_cell_data()
2649 * Return value: %TRUE, if any of the cells packed into the @tree_column are currently visible
2652 gtk_tree_view_column_cell_is_visible (GtkTreeViewColumn *tree_column)
2657 g_return_val_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column), FALSE);
2659 cells = gtk_cell_layout_get_cells (GTK_CELL_LAYOUT (tree_column->cell_area));
2660 for (list = cells; list; list = list->next)
2662 if (gtk_cell_renderer_get_visible (list->data))
2664 g_list_free (cells);
2669 g_list_free (cells);
2675 * gtk_tree_view_column_focus_cell:
2676 * @tree_column: A #GtkTreeViewColumn
2677 * @cell: A #GtkCellRenderer
2679 * Sets the current keyboard focus to be at @cell, if the column contains
2680 * 2 or more editable and activatable cells.
2685 gtk_tree_view_column_focus_cell (GtkTreeViewColumn *tree_column,
2686 GtkCellRenderer *cell)
2688 g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column));
2689 g_return_if_fail (GTK_IS_CELL_RENDERER (cell));
2691 gtk_cell_area_set_focus_cell (tree_column->cell_area, cell);
2695 _gtk_tree_view_column_cell_set_dirty (GtkTreeViewColumn *tree_column,
2696 gboolean install_handler)
2698 tree_column->dirty = TRUE;
2699 tree_column->requested_width = -1;
2700 tree_column->width = 0;
2702 if (tree_column->tree_view &&
2703 gtk_widget_get_realized (tree_column->tree_view))
2705 if (install_handler)
2706 _gtk_tree_view_install_mark_rows_col_dirty (GTK_TREE_VIEW (tree_column->tree_view));
2708 GTK_TREE_VIEW (tree_column->tree_view)->priv->mark_rows_col_dirty = TRUE;
2709 gtk_widget_queue_resize (tree_column->tree_view);
2714 * gtk_tree_view_column_cell_get_position:
2715 * @tree_column: a #GtkTreeViewColumn
2716 * @cell_renderer: a #GtkCellRenderer
2717 * @start_pos: return location for the horizontal position of @cell within
2718 * @tree_column, may be %NULL
2719 * @width: return location for the width of @cell, may be %NULL
2721 * Obtains the horizontal position and size of a cell in a column. If the
2722 * cell is not found in the column, @start_pos and @width are not changed and
2723 * %FALSE is returned.
2725 * Return value: %TRUE if @cell belongs to @tree_column.
2728 gtk_tree_view_column_cell_get_position (GtkTreeViewColumn *tree_column,
2729 GtkCellRenderer *cell_renderer,
2733 GdkRectangle zero_cell_area = { 0, };
2734 GdkRectangle allocation;
2736 /* FIXME: Could use a boolean return value for invalid cells */
2737 gtk_cell_area_get_cell_allocation (tree_column->cell_area,
2738 tree_column->cell_area_context,
2739 tree_column->tree_view,
2745 *start_pos = allocation.x;
2747 *width = allocation.width;
2753 * gtk_tree_view_column_queue_resize:
2754 * @tree_column: A #GtkTreeViewColumn
2756 * Flags the column, and the cell renderers added to this column, to have
2757 * their sizes renegotiated.
2762 gtk_tree_view_column_queue_resize (GtkTreeViewColumn *tree_column)
2764 g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column));
2766 if (tree_column->tree_view)
2767 _gtk_tree_view_column_cell_set_dirty (tree_column, TRUE);
2771 * gtk_tree_view_column_get_tree_view:
2772 * @tree_column: A #GtkTreeViewColumn
2774 * Returns the #GtkTreeView wherein @tree_column has been inserted.
2775 * If @column is currently not inserted in any tree view, %NULL is
2778 * Return value: (transfer none): The tree view wherein @column has
2779 * been inserted if any, %NULL otherwise.
2784 gtk_tree_view_column_get_tree_view (GtkTreeViewColumn *tree_column)
2786 g_return_val_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column), NULL);
2788 return tree_column->tree_view;