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);
101 /* GtkCellLayout implementation */
102 static void gtk_tree_view_column_cell_layout_pack_start (GtkCellLayout *cell_layout,
103 GtkCellRenderer *cell,
105 static void gtk_tree_view_column_cell_layout_pack_end (GtkCellLayout *cell_layout,
106 GtkCellRenderer *cell,
108 static void gtk_tree_view_column_cell_layout_clear (GtkCellLayout *cell_layout);
109 static void gtk_tree_view_column_cell_layout_add_attribute (GtkCellLayout *cell_layout,
110 GtkCellRenderer *cell,
111 const gchar *attribute,
113 static void gtk_tree_view_column_cell_layout_set_cell_data_func (GtkCellLayout *cell_layout,
114 GtkCellRenderer *cell,
115 GtkCellLayoutDataFunc func,
117 GDestroyNotify destroy);
118 static void gtk_tree_view_column_cell_layout_clear_attributes (GtkCellLayout *cell_layout,
119 GtkCellRenderer *cell);
120 static void gtk_tree_view_column_cell_layout_reorder (GtkCellLayout *cell_layout,
121 GtkCellRenderer *cell,
123 static GList *gtk_tree_view_column_cell_layout_get_cells (GtkCellLayout *cell_layout);
125 /* Button handling code */
126 static void gtk_tree_view_column_create_button (GtkTreeViewColumn *tree_column);
127 static void gtk_tree_view_column_update_button (GtkTreeViewColumn *tree_column);
129 /* Button signal handlers */
130 static gint gtk_tree_view_column_button_event (GtkWidget *widget,
133 static void gtk_tree_view_column_button_clicked (GtkWidget *widget,
135 static gboolean gtk_tree_view_column_mnemonic_activate (GtkWidget *widget,
136 gboolean group_cycling,
139 /* Property handlers */
140 static void gtk_tree_view_model_sort_column_changed (GtkTreeSortable *sortable,
141 GtkTreeViewColumn *tree_column);
143 /* Internal functions */
144 static void gtk_tree_view_column_sort (GtkTreeViewColumn *tree_column,
146 static void gtk_tree_view_column_setup_sort_column_id_callback (GtkTreeViewColumn *tree_column);
147 static void gtk_tree_view_column_set_attributesv (GtkTreeViewColumn *tree_column,
148 GtkCellRenderer *cell_renderer,
151 /* GtkBuildable implementation */
152 static void gtk_tree_view_column_buildable_init (GtkBuildableIface *iface);
154 static guint tree_column_signals[LAST_SIGNAL] = { 0 };
156 G_DEFINE_TYPE_WITH_CODE (GtkTreeViewColumn, gtk_tree_view_column, G_TYPE_INITIALLY_UNOWNED,
157 G_IMPLEMENT_INTERFACE (GTK_TYPE_CELL_LAYOUT,
158 gtk_tree_view_column_cell_layout_init)
159 G_IMPLEMENT_INTERFACE (GTK_TYPE_BUILDABLE,
160 gtk_tree_view_column_buildable_init))
164 gtk_tree_view_column_class_init (GtkTreeViewColumnClass *class)
166 GObjectClass *object_class;
168 object_class = (GObjectClass*) class;
170 class->clicked = NULL;
172 object_class->finalize = gtk_tree_view_column_finalize;
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));
346 gtk_tree_view_column_buildable_init (GtkBuildableIface *iface)
348 iface->add_child = _gtk_cell_layout_buildable_add_child;
349 iface->custom_tag_start = _gtk_cell_layout_buildable_custom_tag_start;
350 iface->custom_tag_end = _gtk_cell_layout_buildable_custom_tag_end;
354 gtk_tree_view_column_cell_layout_init (GtkCellLayoutIface *iface)
356 iface->pack_start = gtk_tree_view_column_cell_layout_pack_start;
357 iface->pack_end = gtk_tree_view_column_cell_layout_pack_end;
358 iface->clear = gtk_tree_view_column_cell_layout_clear;
359 iface->add_attribute = gtk_tree_view_column_cell_layout_add_attribute;
360 iface->set_cell_data_func = gtk_tree_view_column_cell_layout_set_cell_data_func;
361 iface->clear_attributes = gtk_tree_view_column_cell_layout_clear_attributes;
362 iface->reorder = gtk_tree_view_column_cell_layout_reorder;
363 iface->get_cells = gtk_tree_view_column_cell_layout_get_cells;
367 gtk_tree_view_column_init (GtkTreeViewColumn *tree_column)
369 tree_column->button = NULL;
370 tree_column->xalign = 0.0;
371 tree_column->width = 0;
372 tree_column->requested_width = -1;
373 tree_column->min_width = -1;
374 tree_column->max_width = -1;
375 tree_column->resized_width = 0;
376 tree_column->column_type = GTK_TREE_VIEW_COLUMN_GROW_ONLY;
377 tree_column->visible = TRUE;
378 tree_column->resizable = FALSE;
379 tree_column->expand = FALSE;
380 tree_column->clickable = FALSE;
381 tree_column->dirty = TRUE;
382 tree_column->sort_order = GTK_SORT_ASCENDING;
383 tree_column->show_sort_indicator = FALSE;
384 tree_column->property_changed_signal = 0;
385 tree_column->sort_clicked_signal = 0;
386 tree_column->sort_column_changed_signal = 0;
387 tree_column->sort_column_id = -1;
388 tree_column->reorderable = FALSE;
389 tree_column->maybe_reordered = FALSE;
390 tree_column->fixed_width = 1;
391 tree_column->use_resized_width = FALSE;
392 tree_column->title = g_strdup ("");
394 tree_column->cell_area = gtk_cell_area_box_new ();
395 gtk_cell_area_set_style_detail (tree_column->cell_area, "treeview");
396 tree_column->cell_area_context = gtk_cell_area_create_context (tree_column->cell_area);
400 gtk_tree_view_column_finalize (GObject *object)
402 GtkTreeViewColumn *tree_column = (GtkTreeViewColumn *) object;
404 g_object_unref (tree_column->cell_area_context);
405 g_object_unref (tree_column->cell_area);
407 g_free (tree_column->title);
409 if (tree_column->child)
410 g_object_unref (tree_column->child);
412 G_OBJECT_CLASS (gtk_tree_view_column_parent_class)->finalize (object);
416 gtk_tree_view_column_set_property (GObject *object,
421 GtkTreeViewColumn *tree_column;
423 tree_column = GTK_TREE_VIEW_COLUMN (object);
428 gtk_tree_view_column_set_visible (tree_column,
429 g_value_get_boolean (value));
433 gtk_tree_view_column_set_resizable (tree_column,
434 g_value_get_boolean (value));
438 gtk_tree_view_column_set_sizing (tree_column,
439 g_value_get_enum (value));
442 case PROP_FIXED_WIDTH:
443 gtk_tree_view_column_set_fixed_width (tree_column,
444 g_value_get_int (value));
448 gtk_tree_view_column_set_min_width (tree_column,
449 g_value_get_int (value));
453 gtk_tree_view_column_set_max_width (tree_column,
454 g_value_get_int (value));
458 gtk_tree_view_column_set_spacing (tree_column,
459 g_value_get_int (value));
463 gtk_tree_view_column_set_title (tree_column,
464 g_value_get_string (value));
468 gtk_tree_view_column_set_expand (tree_column,
469 g_value_get_boolean (value));
473 gtk_tree_view_column_set_clickable (tree_column,
474 g_value_get_boolean (value));
478 gtk_tree_view_column_set_widget (tree_column,
479 (GtkWidget*) g_value_get_object (value));
483 gtk_tree_view_column_set_alignment (tree_column,
484 g_value_get_float (value));
487 case PROP_REORDERABLE:
488 gtk_tree_view_column_set_reorderable (tree_column,
489 g_value_get_boolean (value));
492 case PROP_SORT_INDICATOR:
493 gtk_tree_view_column_set_sort_indicator (tree_column,
494 g_value_get_boolean (value));
497 case PROP_SORT_ORDER:
498 gtk_tree_view_column_set_sort_order (tree_column,
499 g_value_get_enum (value));
502 case PROP_SORT_COLUMN_ID:
503 gtk_tree_view_column_set_sort_column_id (tree_column,
504 g_value_get_int (value));
508 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
514 gtk_tree_view_column_get_property (GObject *object,
519 GtkTreeViewColumn *tree_column;
521 tree_column = GTK_TREE_VIEW_COLUMN (object);
526 g_value_set_boolean (value,
527 gtk_tree_view_column_get_visible (tree_column));
531 g_value_set_boolean (value,
532 gtk_tree_view_column_get_resizable (tree_column));
536 g_value_set_int (value,
537 gtk_tree_view_column_get_width (tree_column));
541 g_value_set_int (value,
542 gtk_tree_view_column_get_spacing (tree_column));
546 g_value_set_enum (value,
547 gtk_tree_view_column_get_sizing (tree_column));
550 case PROP_FIXED_WIDTH:
551 g_value_set_int (value,
552 gtk_tree_view_column_get_fixed_width (tree_column));
556 g_value_set_int (value,
557 gtk_tree_view_column_get_min_width (tree_column));
561 g_value_set_int (value,
562 gtk_tree_view_column_get_max_width (tree_column));
566 g_value_set_string (value,
567 gtk_tree_view_column_get_title (tree_column));
571 g_value_set_boolean (value,
572 gtk_tree_view_column_get_expand (tree_column));
576 g_value_set_boolean (value,
577 gtk_tree_view_column_get_clickable (tree_column));
581 g_value_set_object (value,
582 (GObject*) gtk_tree_view_column_get_widget (tree_column));
586 g_value_set_float (value,
587 gtk_tree_view_column_get_alignment (tree_column));
590 case PROP_REORDERABLE:
591 g_value_set_boolean (value,
592 gtk_tree_view_column_get_reorderable (tree_column));
595 case PROP_SORT_INDICATOR:
596 g_value_set_boolean (value,
597 gtk_tree_view_column_get_sort_indicator (tree_column));
600 case PROP_SORT_ORDER:
601 g_value_set_enum (value,
602 gtk_tree_view_column_get_sort_order (tree_column));
605 case PROP_SORT_COLUMN_ID:
606 g_value_set_int (value,
607 gtk_tree_view_column_get_sort_column_id (tree_column));
611 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
616 /* Implementation of GtkCellLayout interface
620 gtk_tree_view_column_cell_layout_pack_start (GtkCellLayout *cell_layout,
621 GtkCellRenderer *cell,
624 GtkTreeViewColumn *column;
626 g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (cell_layout));
627 column = GTK_TREE_VIEW_COLUMN (cell_layout);
629 gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (column->cell_area),
634 gtk_tree_view_column_cell_layout_pack_end (GtkCellLayout *cell_layout,
635 GtkCellRenderer *cell,
638 GtkTreeViewColumn *column;
640 g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (cell_layout));
641 column = GTK_TREE_VIEW_COLUMN (cell_layout);
643 gtk_cell_layout_pack_end (GTK_CELL_LAYOUT (column->cell_area),
648 gtk_tree_view_column_cell_layout_clear (GtkCellLayout *cell_layout)
650 GtkTreeViewColumn *column;
652 g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (cell_layout));
653 column = GTK_TREE_VIEW_COLUMN (cell_layout);
655 gtk_cell_layout_clear (GTK_CELL_LAYOUT (column->cell_area));
659 gtk_tree_view_column_cell_layout_add_attribute (GtkCellLayout *cell_layout,
660 GtkCellRenderer *cell,
661 const gchar *attribute,
664 GtkTreeViewColumn *tree_column;
666 g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (cell_layout));
667 tree_column = GTK_TREE_VIEW_COLUMN (cell_layout);
669 gtk_cell_layout_add_attribute (GTK_CELL_LAYOUT (tree_column->cell_area),
670 cell, attribute, column);
672 if (tree_column->tree_view)
673 _gtk_tree_view_column_cell_set_dirty (tree_column, TRUE);
677 gtk_tree_view_column_cell_layout_set_cell_data_func (GtkCellLayout *cell_layout,
678 GtkCellRenderer *cell,
679 GtkCellLayoutDataFunc func,
681 GDestroyNotify destroy)
683 GtkTreeViewColumn *column;
685 g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (cell_layout));
686 column = GTK_TREE_VIEW_COLUMN (cell_layout);
688 gtk_cell_layout_set_cell_data_func (GTK_CELL_LAYOUT (column->cell_area),
689 cell, func, func_data, destroy);
691 if (column->tree_view)
692 _gtk_tree_view_column_cell_set_dirty (column, TRUE);
696 gtk_tree_view_column_cell_layout_clear_attributes (GtkCellLayout *cell_layout,
697 GtkCellRenderer *cell_renderer)
699 GtkTreeViewColumn *column;
701 g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (cell_layout));
702 column = GTK_TREE_VIEW_COLUMN (cell_layout);
704 gtk_cell_layout_clear_attributes (GTK_CELL_LAYOUT (column->cell_area),
709 gtk_tree_view_column_cell_layout_reorder (GtkCellLayout *cell_layout,
710 GtkCellRenderer *cell,
713 GtkTreeViewColumn *column;
715 g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (cell_layout));
716 column = GTK_TREE_VIEW_COLUMN (cell_layout);
718 gtk_cell_layout_reorder (GTK_CELL_LAYOUT (column->cell_area),
721 if (column->tree_view)
722 gtk_widget_queue_draw (column->tree_view);
725 /* Button handling code
728 gtk_tree_view_column_create_button (GtkTreeViewColumn *tree_column)
730 GtkTreeView *tree_view;
734 tree_view = (GtkTreeView *) tree_column->tree_view;
736 g_return_if_fail (GTK_IS_TREE_VIEW (tree_view));
737 g_return_if_fail (tree_column->button == NULL);
739 gtk_widget_push_composite_child ();
740 tree_column->button = gtk_button_new ();
741 gtk_widget_add_events (tree_column->button, GDK_POINTER_MOTION_MASK);
742 gtk_widget_pop_composite_child ();
744 /* make sure we own a reference to it as well. */
745 if (tree_view->priv->header_window)
746 gtk_widget_set_parent_window (tree_column->button, tree_view->priv->header_window);
747 gtk_widget_set_parent (tree_column->button, GTK_WIDGET (tree_view));
749 g_signal_connect (tree_column->button, "event",
750 G_CALLBACK (gtk_tree_view_column_button_event),
752 g_signal_connect (tree_column->button, "clicked",
753 G_CALLBACK (gtk_tree_view_column_button_clicked),
756 tree_column->alignment = gtk_alignment_new (tree_column->xalign, 0.5, 0.0, 0.0);
758 hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 2);
759 tree_column->arrow = gtk_arrow_new (GTK_ARROW_DOWN, GTK_SHADOW_IN);
761 if (tree_column->child)
762 child = tree_column->child;
765 child = gtk_label_new (tree_column->title);
766 gtk_widget_show (child);
769 g_signal_connect (child, "mnemonic-activate",
770 G_CALLBACK (gtk_tree_view_column_mnemonic_activate),
773 if (tree_column->xalign <= 0.5)
774 gtk_box_pack_end (GTK_BOX (hbox), tree_column->arrow, FALSE, FALSE, 0);
776 gtk_box_pack_start (GTK_BOX (hbox), tree_column->arrow, FALSE, FALSE, 0);
778 gtk_box_pack_start (GTK_BOX (hbox), tree_column->alignment, TRUE, TRUE, 0);
780 gtk_container_add (GTK_CONTAINER (tree_column->alignment), child);
781 gtk_container_add (GTK_CONTAINER (tree_column->button), hbox);
783 gtk_widget_show (hbox);
784 gtk_widget_show (tree_column->alignment);
785 gtk_tree_view_column_update_button (tree_column);
789 gtk_tree_view_column_update_button (GtkTreeViewColumn *tree_column)
791 gint sort_column_id = -1;
793 GtkWidget *alignment;
795 GtkWidget *current_child;
796 GtkArrowType arrow_type = GTK_ARROW_NONE;
799 if (tree_column->tree_view)
800 model = gtk_tree_view_get_model (GTK_TREE_VIEW (tree_column->tree_view));
804 /* Create a button if necessary */
805 if (tree_column->visible &&
806 tree_column->button == NULL &&
807 tree_column->tree_view &&
808 gtk_widget_get_realized (tree_column->tree_view))
809 gtk_tree_view_column_create_button (tree_column);
811 if (! tree_column->button)
814 hbox = gtk_bin_get_child (GTK_BIN (tree_column->button));
815 alignment = tree_column->alignment;
816 arrow = tree_column->arrow;
817 current_child = gtk_bin_get_child (GTK_BIN (alignment));
819 /* Set up the actual button */
820 gtk_alignment_set (GTK_ALIGNMENT (alignment), tree_column->xalign,
823 if (tree_column->child)
825 if (current_child != tree_column->child)
827 gtk_container_remove (GTK_CONTAINER (alignment),
829 gtk_container_add (GTK_CONTAINER (alignment),
835 if (current_child == NULL)
837 current_child = gtk_label_new (NULL);
838 gtk_widget_show (current_child);
839 gtk_container_add (GTK_CONTAINER (alignment),
843 g_return_if_fail (GTK_IS_LABEL (current_child));
845 if (tree_column->title)
846 gtk_label_set_text_with_mnemonic (GTK_LABEL (current_child),
849 gtk_label_set_text_with_mnemonic (GTK_LABEL (current_child),
853 if (GTK_IS_TREE_SORTABLE (model))
854 gtk_tree_sortable_get_sort_column_id (GTK_TREE_SORTABLE (model),
858 if (tree_column->show_sort_indicator)
860 gboolean alternative;
862 g_object_get (gtk_widget_get_settings (tree_column->tree_view),
863 "gtk-alternative-sort-arrows", &alternative,
866 switch (tree_column->sort_order)
868 case GTK_SORT_ASCENDING:
869 arrow_type = alternative ? GTK_ARROW_UP : GTK_ARROW_DOWN;
872 case GTK_SORT_DESCENDING:
873 arrow_type = alternative ? GTK_ARROW_DOWN : GTK_ARROW_UP;
877 g_warning (G_STRLOC": bad sort order");
882 gtk_arrow_set (GTK_ARROW (arrow),
886 /* Put arrow on the right if the text is left-or-center justified, and on the
887 * left otherwise; do this by packing boxes, so flipping text direction will
890 g_object_ref (arrow);
891 gtk_container_remove (GTK_CONTAINER (hbox), arrow);
893 if (tree_column->xalign <= 0.5)
895 gtk_box_pack_end (GTK_BOX (hbox), arrow, FALSE, FALSE, 0);
899 gtk_box_pack_start (GTK_BOX (hbox), arrow, FALSE, FALSE, 0);
900 /* move it to the front */
901 gtk_box_reorder_child (GTK_BOX (hbox), arrow, 0);
903 g_object_unref (arrow);
905 if (tree_column->show_sort_indicator
906 || (GTK_IS_TREE_SORTABLE (model) && tree_column->sort_column_id >= 0))
907 gtk_widget_show (arrow);
909 gtk_widget_hide (arrow);
911 /* It's always safe to hide the button. It isn't always safe to show it, as
912 * if you show it before it's realized, it'll get the wrong window. */
913 if (tree_column->button &&
914 tree_column->tree_view != NULL &&
915 gtk_widget_get_realized (tree_column->tree_view))
917 if (tree_column->visible)
919 gtk_widget_show_now (tree_column->button);
920 if (tree_column->window)
922 if (tree_column->resizable)
924 gdk_window_show (tree_column->window);
925 gdk_window_raise (tree_column->window);
929 gdk_window_hide (tree_column->window);
935 gtk_widget_hide (tree_column->button);
936 if (tree_column->window)
937 gdk_window_hide (tree_column->window);
941 if (tree_column->reorderable || tree_column->clickable)
943 gtk_widget_set_can_focus (tree_column->button, TRUE);
947 gtk_widget_set_can_focus (tree_column->button, FALSE);
948 if (gtk_widget_has_focus (tree_column->button))
950 GtkWidget *toplevel = gtk_widget_get_toplevel (tree_column->tree_view);
951 if (gtk_widget_is_toplevel (toplevel))
953 gtk_window_set_focus (GTK_WINDOW (toplevel), NULL);
957 /* Queue a resize on the assumption that we always want to catch all changes
958 * and columns don't change all that often.
960 if (gtk_widget_get_realized (tree_column->tree_view))
961 gtk_widget_queue_resize (tree_column->tree_view);
965 /* Button signal handlers
969 gtk_tree_view_column_button_event (GtkWidget *widget,
973 GtkTreeViewColumn *column = (GtkTreeViewColumn *) data;
975 g_return_val_if_fail (event != NULL, FALSE);
977 if (event->type == GDK_BUTTON_PRESS &&
978 column->reorderable &&
979 ((GdkEventButton *)event)->button == 1)
981 column->maybe_reordered = TRUE;
982 gdk_window_get_pointer (gtk_button_get_event_window (GTK_BUTTON (widget)),
986 gtk_widget_grab_focus (widget);
989 if (event->type == GDK_BUTTON_RELEASE ||
990 event->type == GDK_LEAVE_NOTIFY)
991 column->maybe_reordered = FALSE;
993 if (event->type == GDK_MOTION_NOTIFY &&
994 column->maybe_reordered &&
995 (gtk_drag_check_threshold (widget,
998 (gint) ((GdkEventMotion *)event)->x,
999 (gint) ((GdkEventMotion *)event)->y)))
1001 column->maybe_reordered = FALSE;
1002 _gtk_tree_view_column_start_drag (GTK_TREE_VIEW (column->tree_view), column,
1003 event->motion.device);
1006 if (column->clickable == FALSE)
1008 switch (event->type)
1010 case GDK_BUTTON_PRESS:
1011 case GDK_2BUTTON_PRESS:
1012 case GDK_3BUTTON_PRESS:
1013 case GDK_MOTION_NOTIFY:
1014 case GDK_BUTTON_RELEASE:
1015 case GDK_ENTER_NOTIFY:
1016 case GDK_LEAVE_NOTIFY:
1027 gtk_tree_view_column_button_clicked (GtkWidget *widget, gpointer data)
1029 g_signal_emit_by_name (data, "clicked");
1033 gtk_tree_view_column_mnemonic_activate (GtkWidget *widget,
1034 gboolean group_cycling,
1037 GtkTreeViewColumn *column = (GtkTreeViewColumn *)data;
1039 g_return_val_if_fail (GTK_IS_TREE_VIEW_COLUMN (column), FALSE);
1041 GTK_TREE_VIEW (column->tree_view)->priv->focus_column = column;
1042 if (column->clickable)
1043 gtk_button_clicked (GTK_BUTTON (column->button));
1044 else if (gtk_widget_get_can_focus (column->button))
1045 gtk_widget_grab_focus (column->button);
1047 gtk_widget_grab_focus (column->tree_view);
1053 gtk_tree_view_model_sort_column_changed (GtkTreeSortable *sortable,
1054 GtkTreeViewColumn *column)
1056 gint sort_column_id;
1059 if (gtk_tree_sortable_get_sort_column_id (sortable,
1063 if (sort_column_id == column->sort_column_id)
1065 gtk_tree_view_column_set_sort_indicator (column, TRUE);
1066 gtk_tree_view_column_set_sort_order (column, order);
1070 gtk_tree_view_column_set_sort_indicator (column, FALSE);
1075 gtk_tree_view_column_set_sort_indicator (column, FALSE);
1080 gtk_tree_view_column_sort (GtkTreeViewColumn *tree_column,
1083 gint sort_column_id;
1085 gboolean has_sort_column;
1086 gboolean has_default_sort_func;
1088 g_return_if_fail (tree_column->tree_view != NULL);
1091 gtk_tree_sortable_get_sort_column_id (GTK_TREE_SORTABLE (GTK_TREE_VIEW (tree_column->tree_view)->priv->model),
1094 has_default_sort_func =
1095 gtk_tree_sortable_has_default_sort_func (GTK_TREE_SORTABLE (GTK_TREE_VIEW (tree_column->tree_view)->priv->model));
1097 if (has_sort_column &&
1098 sort_column_id == tree_column->sort_column_id)
1100 if (order == GTK_SORT_ASCENDING)
1101 gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (GTK_TREE_VIEW (tree_column->tree_view)->priv->model),
1102 tree_column->sort_column_id,
1103 GTK_SORT_DESCENDING);
1104 else if (order == GTK_SORT_DESCENDING && has_default_sort_func)
1105 gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (GTK_TREE_VIEW (tree_column->tree_view)->priv->model),
1106 GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID,
1107 GTK_SORT_ASCENDING);
1109 gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (GTK_TREE_VIEW (tree_column->tree_view)->priv->model),
1110 tree_column->sort_column_id,
1111 GTK_SORT_ASCENDING);
1115 gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (GTK_TREE_VIEW (tree_column->tree_view)->priv->model),
1116 tree_column->sort_column_id,
1117 GTK_SORT_ASCENDING);
1123 gtk_tree_view_column_setup_sort_column_id_callback (GtkTreeViewColumn *tree_column)
1125 GtkTreeModel *model;
1127 if (tree_column->tree_view == NULL)
1130 model = gtk_tree_view_get_model (GTK_TREE_VIEW (tree_column->tree_view));
1135 if (GTK_IS_TREE_SORTABLE (model) &&
1136 tree_column->sort_column_id != -1)
1138 gint real_sort_column_id;
1139 GtkSortType real_order;
1141 if (tree_column->sort_column_changed_signal == 0)
1142 tree_column->sort_column_changed_signal =
1143 g_signal_connect (model, "sort-column-changed",
1144 G_CALLBACK (gtk_tree_view_model_sort_column_changed),
1147 if (gtk_tree_sortable_get_sort_column_id (GTK_TREE_SORTABLE (model),
1148 &real_sort_column_id,
1150 (real_sort_column_id == tree_column->sort_column_id))
1152 gtk_tree_view_column_set_sort_indicator (tree_column, TRUE);
1153 gtk_tree_view_column_set_sort_order (tree_column, real_order);
1157 gtk_tree_view_column_set_sort_indicator (tree_column, FALSE);
1163 gtk_tree_view_column_add_editable_callback (GtkCellArea *area,
1164 GtkCellRenderer *renderer,
1165 GtkCellEditable *edit_widget,
1166 GdkRectangle *cell_area,
1167 const gchar *path_string,
1171 GtkTreeViewColumn *column = user_data;
1173 path = gtk_tree_path_new_from_string (path_string);
1175 _gtk_tree_view_add_editable (GTK_TREE_VIEW (column->tree_view),
1181 gtk_tree_path_free (path);
1185 gtk_tree_view_column_remove_editable_callback (GtkCellArea *area,
1186 GtkCellRenderer *renderer,
1187 GtkCellEditable *edit_widget,
1190 GtkTreeViewColumn *column = user_data;
1192 _gtk_tree_view_remove_editable (GTK_TREE_VIEW (column->tree_view),
1197 /* Exported Private Functions.
1198 * These should only be called by gtktreeview.c or gtktreeviewcolumn.c
1202 _gtk_tree_view_column_realize_button (GtkTreeViewColumn *column)
1204 GtkAllocation allocation;
1205 GtkTreeView *tree_view;
1207 guint attributes_mask;
1210 tree_view = (GtkTreeView *)column->tree_view;
1211 rtl = (gtk_widget_get_direction (GTK_WIDGET (tree_view)) == GTK_TEXT_DIR_RTL);
1213 g_return_if_fail (GTK_IS_TREE_VIEW (tree_view));
1214 g_return_if_fail (gtk_widget_get_realized (GTK_WIDGET (tree_view)));
1215 g_return_if_fail (tree_view->priv->header_window != NULL);
1216 g_return_if_fail (column->button != NULL);
1218 gtk_widget_set_parent_window (column->button, tree_view->priv->header_window);
1220 if (column->visible)
1221 gtk_widget_show (column->button);
1223 attr.window_type = GDK_WINDOW_CHILD;
1224 attr.wclass = GDK_INPUT_ONLY;
1225 attr.visual = gtk_widget_get_visual (GTK_WIDGET (tree_view));
1226 attr.event_mask = gtk_widget_get_events (GTK_WIDGET (tree_view)) |
1227 (GDK_BUTTON_PRESS_MASK |
1228 GDK_BUTTON_RELEASE_MASK |
1229 GDK_POINTER_MOTION_MASK |
1230 GDK_POINTER_MOTION_HINT_MASK |
1231 GDK_KEY_PRESS_MASK);
1232 attributes_mask = GDK_WA_CURSOR | GDK_WA_X | GDK_WA_Y;
1233 attr.cursor = gdk_cursor_new_for_display (gdk_window_get_display (tree_view->priv->header_window),
1234 GDK_SB_H_DOUBLE_ARROW);
1236 attr.width = TREE_VIEW_DRAG_WIDTH;
1237 attr.height = tree_view->priv->header_height;
1239 gtk_widget_get_allocation (column->button, &allocation);
1240 attr.x = (allocation.x + (rtl ? 0 : allocation.width)) - TREE_VIEW_DRAG_WIDTH / 2;
1241 column->window = gdk_window_new (tree_view->priv->header_window,
1242 &attr, attributes_mask);
1243 gdk_window_set_user_data (column->window, tree_view);
1245 gtk_tree_view_column_update_button (column);
1247 gdk_cursor_unref (attr.cursor);
1251 _gtk_tree_view_column_unrealize_button (GtkTreeViewColumn *column)
1253 g_return_if_fail (column != NULL);
1254 g_return_if_fail (column->window != NULL);
1256 gdk_window_set_user_data (column->window, NULL);
1257 gdk_window_destroy (column->window);
1258 column->window = NULL;
1262 _gtk_tree_view_column_unset_model (GtkTreeViewColumn *column,
1263 GtkTreeModel *old_model)
1265 if (column->sort_column_changed_signal)
1267 g_signal_handler_disconnect (old_model,
1268 column->sort_column_changed_signal);
1269 column->sort_column_changed_signal = 0;
1271 gtk_tree_view_column_set_sort_indicator (column, FALSE);
1275 _gtk_tree_view_column_set_tree_view (GtkTreeViewColumn *column,
1276 GtkTreeView *tree_view)
1278 g_assert (column->tree_view == NULL);
1280 column->tree_view = GTK_WIDGET (tree_view);
1281 gtk_tree_view_column_create_button (column);
1283 column->add_editable_signal =
1284 g_signal_connect (column->cell_area, "add-editable",
1285 G_CALLBACK (gtk_tree_view_column_add_editable_callback),
1287 column->remove_editable_signal =
1288 g_signal_connect (column->cell_area, "remove-editable",
1289 G_CALLBACK (gtk_tree_view_column_remove_editable_callback),
1292 column->property_changed_signal =
1293 g_signal_connect_swapped (tree_view,
1295 G_CALLBACK (gtk_tree_view_column_setup_sort_column_id_callback),
1298 gtk_tree_view_column_setup_sort_column_id_callback (column);
1302 _gtk_tree_view_column_unset_tree_view (GtkTreeViewColumn *column)
1304 if (column->tree_view && column->button)
1306 gtk_container_remove (GTK_CONTAINER (column->tree_view), column->button);
1308 if (column->property_changed_signal)
1310 g_signal_handler_disconnect (column->tree_view, column->property_changed_signal);
1311 column->property_changed_signal = 0;
1314 if (column->sort_column_changed_signal)
1316 g_signal_handler_disconnect (gtk_tree_view_get_model (GTK_TREE_VIEW (column->tree_view)),
1317 column->sort_column_changed_signal);
1318 column->sort_column_changed_signal = 0;
1321 column->tree_view = NULL;
1322 column->button = NULL;
1326 _gtk_tree_view_column_has_editable_cell (GtkTreeViewColumn *column)
1328 gboolean ret = FALSE;
1329 GList *list, *cells;
1331 cells = gtk_cell_layout_get_cells (GTK_CELL_LAYOUT (column->cell_area));
1333 for (list = cells; list; list = list->next)
1335 GtkCellRenderer *cell = list->data;
1336 GtkCellRendererMode mode;
1338 g_object_get (cell, "mode", &mode, NULL);
1340 if (mode == GTK_CELL_RENDERER_MODE_EDITABLE)
1347 g_list_free (cells);
1352 /* gets cell being edited */
1354 _gtk_tree_view_column_get_edited_cell (GtkTreeViewColumn *column)
1356 return gtk_cell_area_get_edited_cell (column->cell_area);
1359 /* Public Functions */
1363 * gtk_tree_view_column_new:
1365 * Creates a new #GtkTreeViewColumn.
1367 * Return value: A newly created #GtkTreeViewColumn.
1370 gtk_tree_view_column_new (void)
1372 GtkTreeViewColumn *tree_column;
1374 tree_column = g_object_new (GTK_TYPE_TREE_VIEW_COLUMN, NULL);
1380 * gtk_tree_view_column_new_with_attributes:
1381 * @title: The title to set the header to.
1382 * @cell: The #GtkCellRenderer.
1383 * @Varargs: A %NULL-terminated list of attributes.
1385 * Creates a new #GtkTreeViewColumn with a number of default values. This is
1386 * equivalent to calling gtk_tree_view_column_set_title(),
1387 * gtk_tree_view_column_pack_start(), and
1388 * gtk_tree_view_column_set_attributes() on the newly created #GtkTreeViewColumn.
1390 * Here's a simple example:
1392 * enum { TEXT_COLUMN, COLOR_COLUMN, N_COLUMNS };
1395 * GtkTreeViewColumn *column;
1396 * GtkCellRenderer *renderer = gtk_cell_renderer_text_new ();
1398 * column = gtk_tree_view_column_new_with_attributes ("Title",
1400 * "text", TEXT_COLUMN,
1401 * "foreground", COLOR_COLUMN,
1406 * Return value: A newly created #GtkTreeViewColumn.
1409 gtk_tree_view_column_new_with_attributes (const gchar *title,
1410 GtkCellRenderer *cell,
1413 GtkTreeViewColumn *retval;
1416 retval = gtk_tree_view_column_new ();
1418 gtk_tree_view_column_set_title (retval, title);
1419 gtk_tree_view_column_pack_start (retval, cell, TRUE);
1421 va_start (args, cell);
1422 gtk_tree_view_column_set_attributesv (retval, cell, args);
1429 * gtk_tree_view_column_pack_start:
1430 * @tree_column: A #GtkTreeViewColumn.
1431 * @cell: The #GtkCellRenderer.
1432 * @expand: %TRUE if @cell is to be given extra space allocated to @tree_column.
1434 * Packs the @cell into the beginning of the column. If @expand is %FALSE, then
1435 * the @cell is allocated no more space than it needs. Any unused space is divided
1436 * evenly between cells for which @expand is %TRUE.
1439 gtk_tree_view_column_pack_start (GtkTreeViewColumn *tree_column,
1440 GtkCellRenderer *cell,
1443 gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (tree_column), cell, expand);
1447 * gtk_tree_view_column_pack_end:
1448 * @tree_column: A #GtkTreeViewColumn.
1449 * @cell: The #GtkCellRenderer.
1450 * @expand: %TRUE if @cell is to be given extra space allocated to @tree_column.
1452 * Adds the @cell to end of the column. If @expand is %FALSE, then the @cell
1453 * is allocated no more space than it needs. Any unused space is divided
1454 * evenly between cells for which @expand is %TRUE.
1457 gtk_tree_view_column_pack_end (GtkTreeViewColumn *tree_column,
1458 GtkCellRenderer *cell,
1461 gtk_cell_layout_pack_end (GTK_CELL_LAYOUT (tree_column), cell, expand);
1465 * gtk_tree_view_column_clear:
1466 * @tree_column: A #GtkTreeViewColumn
1468 * Unsets all the mappings on all renderers on the @tree_column.
1471 gtk_tree_view_column_clear (GtkTreeViewColumn *tree_column)
1473 gtk_cell_layout_clear (GTK_CELL_LAYOUT (tree_column));
1477 gtk_tree_view_column_cell_layout_get_cells (GtkCellLayout *layout)
1479 GtkTreeViewColumn *tree_column = GTK_TREE_VIEW_COLUMN (layout);
1481 return gtk_cell_layout_get_cells (GTK_CELL_LAYOUT (tree_column->cell_area));
1485 * gtk_tree_view_column_add_attribute:
1486 * @tree_column: A #GtkTreeViewColumn.
1487 * @cell_renderer: the #GtkCellRenderer to set attributes on
1488 * @attribute: An attribute on the renderer
1489 * @column: The column position on the model to get the attribute from.
1491 * Adds an attribute mapping to the list in @tree_column. The @column is the
1492 * column of the model to get a value from, and the @attribute is the
1493 * parameter on @cell_renderer to be set from the value. So for example
1494 * if column 2 of the model contains strings, you could have the
1495 * "text" attribute of a #GtkCellRendererText get its values from
1499 gtk_tree_view_column_add_attribute (GtkTreeViewColumn *tree_column,
1500 GtkCellRenderer *cell_renderer,
1501 const gchar *attribute,
1504 gtk_cell_layout_add_attribute (GTK_CELL_LAYOUT (tree_column),
1505 cell_renderer, attribute, column);
1509 gtk_tree_view_column_set_attributesv (GtkTreeViewColumn *tree_column,
1510 GtkCellRenderer *cell_renderer,
1516 attribute = va_arg (args, gchar *);
1518 gtk_cell_layout_clear_attributes (GTK_CELL_LAYOUT (tree_column->cell_area),
1521 while (attribute != NULL)
1523 column = va_arg (args, gint);
1524 gtk_cell_layout_add_attribute (GTK_CELL_LAYOUT (tree_column->cell_area),
1525 cell_renderer, attribute, column);
1526 attribute = va_arg (args, gchar *);
1531 * gtk_tree_view_column_set_attributes:
1532 * @tree_column: A #GtkTreeViewColumn.
1533 * @cell_renderer: the #GtkCellRenderer we're setting the attributes of
1534 * @Varargs: A %NULL-terminated list of attributes.
1536 * Sets the attributes in the list as the attributes of @tree_column.
1537 * The attributes should be in attribute/column order, as in
1538 * gtk_tree_view_column_add_attribute(). All existing attributes
1539 * are removed, and replaced with the new attributes.
1542 gtk_tree_view_column_set_attributes (GtkTreeViewColumn *tree_column,
1543 GtkCellRenderer *cell_renderer,
1548 g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column));
1549 g_return_if_fail (GTK_IS_CELL_RENDERER (cell_renderer));
1551 va_start (args, cell_renderer);
1552 gtk_tree_view_column_set_attributesv (tree_column, cell_renderer, args);
1558 * gtk_tree_view_column_set_cell_data_func:
1559 * @tree_column: A #GtkTreeViewColumn
1560 * @cell_renderer: A #GtkCellRenderer
1561 * @func: The #GtkTreeViewColumnFunc to use.
1562 * @func_data: The user data for @func.
1563 * @destroy: The destroy notification for @func_data
1565 * Sets the #GtkTreeViewColumnFunc to use for the column. This
1566 * function is used instead of the standard attributes mapping for
1567 * setting the column value, and should set the value of @tree_column's
1568 * cell renderer as appropriate. @func may be %NULL to remove an
1572 gtk_tree_view_column_set_cell_data_func (GtkTreeViewColumn *tree_column,
1573 GtkCellRenderer *cell_renderer,
1574 GtkTreeCellDataFunc func,
1576 GDestroyNotify destroy)
1578 gtk_cell_layout_set_cell_data_func (GTK_CELL_LAYOUT (tree_column),
1580 (GtkCellLayoutDataFunc)func,
1581 func_data, destroy);
1586 * gtk_tree_view_column_clear_attributes:
1587 * @tree_column: a #GtkTreeViewColumn
1588 * @cell_renderer: a #GtkCellRenderer to clear the attribute mapping on.
1590 * Clears all existing attributes previously set with
1591 * gtk_tree_view_column_set_attributes().
1594 gtk_tree_view_column_clear_attributes (GtkTreeViewColumn *tree_column,
1595 GtkCellRenderer *cell_renderer)
1597 gtk_cell_layout_clear_attributes (GTK_CELL_LAYOUT (tree_column),
1602 * gtk_tree_view_column_set_spacing:
1603 * @tree_column: A #GtkTreeViewColumn.
1604 * @spacing: distance between cell renderers in pixels.
1606 * Sets the spacing field of @tree_column, which is the number of pixels to
1607 * place between cell renderers packed into it.
1610 gtk_tree_view_column_set_spacing (GtkTreeViewColumn *tree_column,
1613 g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column));
1614 g_return_if_fail (spacing >= 0);
1616 gtk_cell_area_box_set_spacing (GTK_CELL_AREA_BOX (tree_column->cell_area),
1618 if (tree_column->tree_view)
1619 _gtk_tree_view_column_cell_set_dirty (tree_column, TRUE);
1623 * gtk_tree_view_column_get_spacing:
1624 * @tree_column: A #GtkTreeViewColumn.
1626 * Returns the spacing of @tree_column.
1628 * Return value: the spacing of @tree_column.
1631 gtk_tree_view_column_get_spacing (GtkTreeViewColumn *tree_column)
1633 g_return_val_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column), 0);
1635 return gtk_cell_area_box_get_spacing (GTK_CELL_AREA_BOX (tree_column->cell_area));
1638 /* Options for manipulating the columns */
1641 * gtk_tree_view_column_set_visible:
1642 * @tree_column: A #GtkTreeViewColumn.
1643 * @visible: %TRUE if the @tree_column is visible.
1645 * Sets the visibility of @tree_column.
1648 gtk_tree_view_column_set_visible (GtkTreeViewColumn *tree_column,
1651 g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column));
1653 visible = !! visible;
1655 if (tree_column->visible == visible)
1658 tree_column->visible = visible;
1660 if (tree_column->visible)
1661 _gtk_tree_view_column_cell_set_dirty (tree_column, TRUE);
1663 gtk_tree_view_column_update_button (tree_column);
1664 g_object_notify (G_OBJECT (tree_column), "visible");
1668 * gtk_tree_view_column_get_visible:
1669 * @tree_column: A #GtkTreeViewColumn.
1671 * Returns %TRUE if @tree_column is visible.
1673 * Return value: whether the column is visible or not. If it is visible, then
1674 * the tree will show the column.
1677 gtk_tree_view_column_get_visible (GtkTreeViewColumn *tree_column)
1679 g_return_val_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column), FALSE);
1681 return tree_column->visible;
1685 * gtk_tree_view_column_set_resizable:
1686 * @tree_column: A #GtkTreeViewColumn
1687 * @resizable: %TRUE, if the column can be resized
1689 * If @resizable is %TRUE, then the user can explicitly resize the column by
1690 * grabbing the outer edge of the column button. If resizable is %TRUE and
1691 * sizing mode of the column is #GTK_TREE_VIEW_COLUMN_AUTOSIZE, then the sizing
1692 * mode is changed to #GTK_TREE_VIEW_COLUMN_GROW_ONLY.
1695 gtk_tree_view_column_set_resizable (GtkTreeViewColumn *tree_column,
1698 g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column));
1700 resizable = !! resizable;
1702 if (tree_column->resizable == resizable)
1705 tree_column->resizable = resizable;
1707 if (resizable && tree_column->column_type == GTK_TREE_VIEW_COLUMN_AUTOSIZE)
1708 gtk_tree_view_column_set_sizing (tree_column, GTK_TREE_VIEW_COLUMN_GROW_ONLY);
1710 gtk_tree_view_column_update_button (tree_column);
1712 g_object_notify (G_OBJECT (tree_column), "resizable");
1716 * gtk_tree_view_column_get_resizable:
1717 * @tree_column: A #GtkTreeViewColumn
1719 * Returns %TRUE if the @tree_column can be resized by the end user.
1721 * Return value: %TRUE, if the @tree_column can be resized.
1724 gtk_tree_view_column_get_resizable (GtkTreeViewColumn *tree_column)
1726 g_return_val_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column), FALSE);
1728 return tree_column->resizable;
1733 * gtk_tree_view_column_set_sizing:
1734 * @tree_column: A #GtkTreeViewColumn.
1735 * @type: The #GtkTreeViewColumnSizing.
1737 * Sets the growth behavior of @tree_column to @type.
1740 gtk_tree_view_column_set_sizing (GtkTreeViewColumn *tree_column,
1741 GtkTreeViewColumnSizing type)
1743 g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column));
1745 if (type == tree_column->column_type)
1748 if (type == GTK_TREE_VIEW_COLUMN_AUTOSIZE)
1749 gtk_tree_view_column_set_resizable (tree_column, FALSE);
1752 /* I was clearly on crack when I wrote this. I'm not sure what's supposed to
1753 * be below so I'll leave it until I figure it out.
1755 if (tree_column->column_type == GTK_TREE_VIEW_COLUMN_AUTOSIZE &&
1756 tree_column->requested_width != -1)
1758 gtk_tree_view_column_set_sizing (tree_column, tree_column->requested_width);
1761 tree_column->column_type = type;
1763 gtk_tree_view_column_update_button (tree_column);
1765 g_object_notify (G_OBJECT (tree_column), "sizing");
1769 * gtk_tree_view_column_get_sizing:
1770 * @tree_column: A #GtkTreeViewColumn.
1772 * Returns the current type of @tree_column.
1774 * Return value: The type of @tree_column.
1776 GtkTreeViewColumnSizing
1777 gtk_tree_view_column_get_sizing (GtkTreeViewColumn *tree_column)
1779 g_return_val_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column), 0);
1781 return tree_column->column_type;
1785 * gtk_tree_view_column_get_width:
1786 * @tree_column: A #GtkTreeViewColumn.
1788 * Returns the current size of @tree_column in pixels.
1790 * Return value: The current width of @tree_column.
1793 gtk_tree_view_column_get_width (GtkTreeViewColumn *tree_column)
1795 g_return_val_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column), 0);
1797 return tree_column->width;
1801 _gtk_tree_view_column_set_width (GtkTreeViewColumn *tree_column,
1804 g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column));
1806 gtk_cell_area_context_allocate (tree_column->cell_area_context, width, -1);
1807 tree_column->width = width;
1811 * gtk_tree_view_column_set_fixed_width:
1812 * @tree_column: A #GtkTreeViewColumn.
1813 * @fixed_width: The size to set @tree_column to. Must be greater than 0.
1815 * Sets the size of the column in pixels. This is meaningful only if the sizing
1816 * type is #GTK_TREE_VIEW_COLUMN_FIXED. The size of the column is clamped to
1817 * the min/max width for the column. Please note that the min/max width of the
1818 * column doesn't actually affect the "fixed_width" property of the widget, just
1819 * the actual size when displayed.
1822 gtk_tree_view_column_set_fixed_width (GtkTreeViewColumn *tree_column,
1825 g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column));
1826 g_return_if_fail (fixed_width > 0);
1828 tree_column->fixed_width = fixed_width;
1829 tree_column->use_resized_width = FALSE;
1831 if (tree_column->tree_view &&
1832 gtk_widget_get_realized (tree_column->tree_view) &&
1833 tree_column->column_type == GTK_TREE_VIEW_COLUMN_FIXED)
1835 gtk_widget_queue_resize (tree_column->tree_view);
1838 g_object_notify (G_OBJECT (tree_column), "fixed-width");
1842 * gtk_tree_view_column_get_fixed_width:
1843 * @tree_column: a #GtkTreeViewColumn
1845 * Gets the fixed width of the column. This value is only meaning may not be
1846 * the actual width of the column on the screen, just what is requested.
1848 * Return value: the fixed width of the column
1851 gtk_tree_view_column_get_fixed_width (GtkTreeViewColumn *tree_column)
1853 g_return_val_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column), 0);
1855 return tree_column->fixed_width;
1859 * gtk_tree_view_column_set_min_width:
1860 * @tree_column: A #GtkTreeViewColumn.
1861 * @min_width: The minimum width of the column in pixels, or -1.
1863 * Sets the minimum width of the @tree_column. If @min_width is -1, then the
1864 * minimum width is unset.
1867 gtk_tree_view_column_set_min_width (GtkTreeViewColumn *tree_column,
1870 g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column));
1871 g_return_if_fail (min_width >= -1);
1873 if (min_width == tree_column->min_width)
1876 if (tree_column->visible &&
1877 tree_column->tree_view != NULL &&
1878 gtk_widget_get_realized (tree_column->tree_view))
1880 if (min_width > tree_column->width)
1881 gtk_widget_queue_resize (tree_column->tree_view);
1884 tree_column->min_width = min_width;
1885 g_object_freeze_notify (G_OBJECT (tree_column));
1886 if (tree_column->max_width != -1 && tree_column->max_width < min_width)
1888 tree_column->max_width = min_width;
1889 g_object_notify (G_OBJECT (tree_column), "max-width");
1891 g_object_notify (G_OBJECT (tree_column), "min-width");
1892 g_object_thaw_notify (G_OBJECT (tree_column));
1894 if (tree_column->column_type == GTK_TREE_VIEW_COLUMN_AUTOSIZE)
1895 _gtk_tree_view_column_autosize (GTK_TREE_VIEW (tree_column->tree_view),
1900 * gtk_tree_view_column_get_min_width:
1901 * @tree_column: A #GtkTreeViewColumn.
1903 * Returns the minimum width in pixels of the @tree_column, or -1 if no minimum
1906 * Return value: The minimum width of the @tree_column.
1909 gtk_tree_view_column_get_min_width (GtkTreeViewColumn *tree_column)
1911 g_return_val_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column), -1);
1913 return tree_column->min_width;
1917 * gtk_tree_view_column_set_max_width:
1918 * @tree_column: A #GtkTreeViewColumn.
1919 * @max_width: The maximum width of the column in pixels, or -1.
1921 * Sets the maximum width of the @tree_column. If @max_width is -1, then the
1922 * maximum width is unset. Note, the column can actually be wider than max
1923 * width if it's the last column in a view. In this case, the column expands to
1924 * fill any extra space.
1927 gtk_tree_view_column_set_max_width (GtkTreeViewColumn *tree_column,
1930 g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column));
1931 g_return_if_fail (max_width >= -1);
1933 if (max_width == tree_column->max_width)
1936 if (tree_column->visible &&
1937 tree_column->tree_view != NULL &&
1938 gtk_widget_get_realized (tree_column->tree_view))
1940 if (max_width != -1 && max_width < tree_column->width)
1941 gtk_widget_queue_resize (tree_column->tree_view);
1944 tree_column->max_width = max_width;
1945 g_object_freeze_notify (G_OBJECT (tree_column));
1946 if (max_width != -1 && max_width < tree_column->min_width)
1948 tree_column->min_width = max_width;
1949 g_object_notify (G_OBJECT (tree_column), "min-width");
1951 g_object_notify (G_OBJECT (tree_column), "max-width");
1952 g_object_thaw_notify (G_OBJECT (tree_column));
1954 if (tree_column->column_type == GTK_TREE_VIEW_COLUMN_AUTOSIZE)
1955 _gtk_tree_view_column_autosize (GTK_TREE_VIEW (tree_column->tree_view),
1960 * gtk_tree_view_column_get_max_width:
1961 * @tree_column: A #GtkTreeViewColumn.
1963 * Returns the maximum width in pixels of the @tree_column, or -1 if no maximum
1966 * Return value: The maximum width of the @tree_column.
1969 gtk_tree_view_column_get_max_width (GtkTreeViewColumn *tree_column)
1971 g_return_val_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column), -1);
1973 return tree_column->max_width;
1977 * gtk_tree_view_column_clicked:
1978 * @tree_column: a #GtkTreeViewColumn
1980 * Emits the "clicked" signal on the column. This function will only work if
1981 * @tree_column is clickable.
1984 gtk_tree_view_column_clicked (GtkTreeViewColumn *tree_column)
1986 g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column));
1988 if (tree_column->visible &&
1989 tree_column->button &&
1990 tree_column->clickable)
1991 gtk_button_clicked (GTK_BUTTON (tree_column->button));
1995 * gtk_tree_view_column_set_title:
1996 * @tree_column: A #GtkTreeViewColumn.
1997 * @title: The title of the @tree_column.
1999 * Sets the title of the @tree_column. If a custom widget has been set, then
2000 * this value is ignored.
2003 gtk_tree_view_column_set_title (GtkTreeViewColumn *tree_column,
2008 g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column));
2010 new_title = g_strdup (title);
2011 g_free (tree_column->title);
2012 tree_column->title = new_title;
2014 gtk_tree_view_column_update_button (tree_column);
2015 g_object_notify (G_OBJECT (tree_column), "title");
2019 * gtk_tree_view_column_get_title:
2020 * @tree_column: A #GtkTreeViewColumn.
2022 * Returns the title of the widget.
2024 * Return value: the title of the column. This string should not be
2025 * modified or freed.
2027 G_CONST_RETURN gchar *
2028 gtk_tree_view_column_get_title (GtkTreeViewColumn *tree_column)
2030 g_return_val_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column), NULL);
2032 return tree_column->title;
2036 * gtk_tree_view_column_set_expand:
2037 * @tree_column: A #GtkTreeViewColumn
2038 * @expand: %TRUE if the column should take available extra space, %FALSE if not
2040 * Sets the column to take available extra space. This space is shared equally
2041 * amongst all columns that have the expand set to %TRUE. If no column has this
2042 * option set, then the last column gets all extra space. By default, every
2043 * column is created with this %FALSE.
2048 gtk_tree_view_column_set_expand (GtkTreeViewColumn *tree_column,
2051 g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column));
2053 expand = expand?TRUE:FALSE;
2054 if (tree_column->expand == expand)
2056 tree_column->expand = expand;
2058 if (tree_column->visible &&
2059 tree_column->tree_view != NULL &&
2060 gtk_widget_get_realized (tree_column->tree_view))
2062 /* We want to continue using the original width of the
2063 * column that includes additional space added by the user
2064 * resizing the columns and possibly extra (expanded) space, which
2065 * are not included in the resized width.
2067 tree_column->use_resized_width = FALSE;
2069 gtk_widget_queue_resize (tree_column->tree_view);
2072 g_object_notify (G_OBJECT (tree_column), "expand");
2076 * gtk_tree_view_column_get_expand:
2077 * @tree_column: a #GtkTreeViewColumn
2079 * Return %TRUE if the column expands to take any available space.
2081 * Return value: %TRUE, if the column expands
2086 gtk_tree_view_column_get_expand (GtkTreeViewColumn *tree_column)
2088 g_return_val_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column), FALSE);
2090 return tree_column->expand;
2094 * gtk_tree_view_column_set_clickable:
2095 * @tree_column: A #GtkTreeViewColumn.
2096 * @clickable: %TRUE if the header is active.
2098 * Sets the header to be active if @active is %TRUE. When the header is active,
2099 * then it can take keyboard focus, and can be clicked.
2102 gtk_tree_view_column_set_clickable (GtkTreeViewColumn *tree_column,
2105 g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column));
2107 clickable = !! clickable;
2108 if (tree_column->clickable == clickable)
2111 tree_column->clickable = clickable;
2112 gtk_tree_view_column_update_button (tree_column);
2113 g_object_notify (G_OBJECT (tree_column), "clickable");
2117 * gtk_tree_view_column_get_clickable:
2118 * @tree_column: a #GtkTreeViewColumn
2120 * Returns %TRUE if the user can click on the header for the column.
2122 * Return value: %TRUE if user can click the column header.
2125 gtk_tree_view_column_get_clickable (GtkTreeViewColumn *tree_column)
2127 g_return_val_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column), FALSE);
2129 return tree_column->clickable;
2133 * gtk_tree_view_column_set_widget:
2134 * @tree_column: A #GtkTreeViewColumn.
2135 * @widget: (allow-none): A child #GtkWidget, or %NULL.
2137 * Sets the widget in the header to be @widget. If widget is %NULL, then the
2138 * header button is set with a #GtkLabel set to the title of @tree_column.
2141 gtk_tree_view_column_set_widget (GtkTreeViewColumn *tree_column,
2144 g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column));
2145 g_return_if_fail (widget == NULL || GTK_IS_WIDGET (widget));
2148 g_object_ref_sink (widget);
2150 if (tree_column->child)
2151 g_object_unref (tree_column->child);
2153 tree_column->child = widget;
2154 gtk_tree_view_column_update_button (tree_column);
2155 g_object_notify (G_OBJECT (tree_column), "widget");
2159 * gtk_tree_view_column_get_widget:
2160 * @tree_column: A #GtkTreeViewColumn.
2162 * Returns the #GtkWidget in the button on the column header.
2163 * If a custom widget has not been set then %NULL is returned.
2165 * Return value: (transfer none): The #GtkWidget in the column
2169 gtk_tree_view_column_get_widget (GtkTreeViewColumn *tree_column)
2171 g_return_val_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column), NULL);
2173 return tree_column->child;
2177 * gtk_tree_view_column_set_alignment:
2178 * @tree_column: A #GtkTreeViewColumn.
2179 * @xalign: The alignment, which is between [0.0 and 1.0] inclusive.
2181 * Sets the alignment of the title or custom widget inside the column header.
2182 * The alignment determines its location inside the button -- 0.0 for left, 0.5
2183 * for center, 1.0 for right.
2186 gtk_tree_view_column_set_alignment (GtkTreeViewColumn *tree_column,
2189 g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column));
2191 xalign = CLAMP (xalign, 0.0, 1.0);
2193 if (tree_column->xalign == xalign)
2196 tree_column->xalign = xalign;
2197 gtk_tree_view_column_update_button (tree_column);
2198 g_object_notify (G_OBJECT (tree_column), "alignment");
2202 * gtk_tree_view_column_get_alignment:
2203 * @tree_column: A #GtkTreeViewColumn.
2205 * Returns the current x alignment of @tree_column. This value can range
2206 * between 0.0 and 1.0.
2208 * Return value: The current alignent of @tree_column.
2211 gtk_tree_view_column_get_alignment (GtkTreeViewColumn *tree_column)
2213 g_return_val_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column), 0.5);
2215 return tree_column->xalign;
2219 * gtk_tree_view_column_set_reorderable:
2220 * @tree_column: A #GtkTreeViewColumn
2221 * @reorderable: %TRUE, if the column can be reordered.
2223 * If @reorderable is %TRUE, then the column can be reordered by the end user
2224 * dragging the header.
2227 gtk_tree_view_column_set_reorderable (GtkTreeViewColumn *tree_column,
2228 gboolean reorderable)
2230 g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column));
2233 gtk_tree_view_column_set_clickable (tree_column, TRUE);*/
2235 if (tree_column->reorderable == (reorderable?TRUE:FALSE))
2238 tree_column->reorderable = (reorderable?TRUE:FALSE);
2239 gtk_tree_view_column_update_button (tree_column);
2240 g_object_notify (G_OBJECT (tree_column), "reorderable");
2244 * gtk_tree_view_column_get_reorderable:
2245 * @tree_column: A #GtkTreeViewColumn
2247 * Returns %TRUE if the @tree_column can be reordered by the user.
2249 * Return value: %TRUE if the @tree_column can be reordered by the user.
2252 gtk_tree_view_column_get_reorderable (GtkTreeViewColumn *tree_column)
2254 g_return_val_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column), FALSE);
2256 return tree_column->reorderable;
2261 * gtk_tree_view_column_set_sort_column_id:
2262 * @tree_column: a #GtkTreeViewColumn
2263 * @sort_column_id: The @sort_column_id of the model to sort on.
2265 * Sets the logical @sort_column_id that this column sorts on when this column
2266 * is selected for sorting. Doing so makes the column header clickable.
2269 gtk_tree_view_column_set_sort_column_id (GtkTreeViewColumn *tree_column,
2270 gint sort_column_id)
2272 g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column));
2273 g_return_if_fail (sort_column_id >= -1);
2275 if (tree_column->sort_column_id == sort_column_id)
2278 tree_column->sort_column_id = sort_column_id;
2280 /* Handle unsetting the id */
2281 if (sort_column_id == -1)
2283 GtkTreeModel *model = gtk_tree_view_get_model (GTK_TREE_VIEW (tree_column->tree_view));
2285 if (tree_column->sort_clicked_signal)
2287 g_signal_handler_disconnect (tree_column, tree_column->sort_clicked_signal);
2288 tree_column->sort_clicked_signal = 0;
2291 if (tree_column->sort_column_changed_signal)
2293 g_signal_handler_disconnect (model, tree_column->sort_column_changed_signal);
2294 tree_column->sort_column_changed_signal = 0;
2297 gtk_tree_view_column_set_sort_order (tree_column, GTK_SORT_ASCENDING);
2298 gtk_tree_view_column_set_sort_indicator (tree_column, FALSE);
2299 gtk_tree_view_column_set_clickable (tree_column, FALSE);
2300 g_object_notify (G_OBJECT (tree_column), "sort-column-id");
2304 gtk_tree_view_column_set_clickable (tree_column, TRUE);
2306 if (! tree_column->sort_clicked_signal)
2307 tree_column->sort_clicked_signal = g_signal_connect (tree_column,
2309 G_CALLBACK (gtk_tree_view_column_sort),
2312 gtk_tree_view_column_setup_sort_column_id_callback (tree_column);
2313 g_object_notify (G_OBJECT (tree_column), "sort-column-id");
2317 * gtk_tree_view_column_get_sort_column_id:
2318 * @tree_column: a #GtkTreeViewColumn
2320 * Gets the logical @sort_column_id that the model sorts on when this
2321 * column is selected for sorting.
2322 * See gtk_tree_view_column_set_sort_column_id().
2324 * Return value: the current @sort_column_id for this column, or -1 if
2325 * this column can't be used for sorting.
2328 gtk_tree_view_column_get_sort_column_id (GtkTreeViewColumn *tree_column)
2330 g_return_val_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column), 0);
2332 return tree_column->sort_column_id;
2336 * gtk_tree_view_column_set_sort_indicator:
2337 * @tree_column: a #GtkTreeViewColumn
2338 * @setting: %TRUE to display an indicator that the column is sorted
2340 * Call this function with a @setting of %TRUE to display an arrow in
2341 * the header button indicating the column is sorted. Call
2342 * gtk_tree_view_column_set_sort_order() to change the direction of
2347 gtk_tree_view_column_set_sort_indicator (GtkTreeViewColumn *tree_column,
2350 g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column));
2352 setting = setting != FALSE;
2354 if (setting == tree_column->show_sort_indicator)
2357 tree_column->show_sort_indicator = setting;
2358 gtk_tree_view_column_update_button (tree_column);
2359 g_object_notify (G_OBJECT (tree_column), "sort-indicator");
2363 * gtk_tree_view_column_get_sort_indicator:
2364 * @tree_column: a #GtkTreeViewColumn
2366 * Gets the value set by gtk_tree_view_column_set_sort_indicator().
2368 * Return value: whether the sort indicator arrow is displayed
2371 gtk_tree_view_column_get_sort_indicator (GtkTreeViewColumn *tree_column)
2373 g_return_val_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column), FALSE);
2375 return tree_column->show_sort_indicator;
2379 * gtk_tree_view_column_set_sort_order:
2380 * @tree_column: a #GtkTreeViewColumn
2381 * @order: sort order that the sort indicator should indicate
2383 * Changes the appearance of the sort indicator.
2385 * This <emphasis>does not</emphasis> actually sort the model. Use
2386 * gtk_tree_view_column_set_sort_column_id() if you want automatic sorting
2387 * support. This function is primarily for custom sorting behavior, and should
2388 * be used in conjunction with gtk_tree_sortable_set_sort_column() to do
2389 * that. For custom models, the mechanism will vary.
2391 * The sort indicator changes direction to indicate normal sort or reverse sort.
2392 * Note that you must have the sort indicator enabled to see anything when
2393 * calling this function; see gtk_tree_view_column_set_sort_indicator().
2396 gtk_tree_view_column_set_sort_order (GtkTreeViewColumn *tree_column,
2399 g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column));
2401 if (order == tree_column->sort_order)
2404 tree_column->sort_order = order;
2405 gtk_tree_view_column_update_button (tree_column);
2406 g_object_notify (G_OBJECT (tree_column), "sort-order");
2410 * gtk_tree_view_column_get_sort_order:
2411 * @tree_column: a #GtkTreeViewColumn
2413 * Gets the value set by gtk_tree_view_column_set_sort_order().
2415 * Return value: the sort order the sort indicator is indicating
2418 gtk_tree_view_column_get_sort_order (GtkTreeViewColumn *tree_column)
2420 g_return_val_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column), 0);
2422 return tree_column->sort_order;
2426 * gtk_tree_view_column_cell_set_cell_data:
2427 * @tree_column: A #GtkTreeViewColumn.
2428 * @tree_model: The #GtkTreeModel to to get the cell renderers attributes from.
2429 * @iter: The #GtkTreeIter to to get the cell renderer's attributes from.
2430 * @is_expander: %TRUE, if the row has children
2431 * @is_expanded: %TRUE, if the row has visible children
2433 * Sets the cell renderer based on the @tree_model and @iter. That is, for
2434 * every attribute mapping in @tree_column, it will get a value from the set
2435 * column on the @iter, and use that value to set the attribute on the cell
2436 * renderer. This is used primarily by the #GtkTreeView.
2439 gtk_tree_view_column_cell_set_cell_data (GtkTreeViewColumn *tree_column,
2440 GtkTreeModel *tree_model,
2442 gboolean is_expander,
2443 gboolean is_expanded)
2445 g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column));
2447 if (tree_model == NULL)
2450 gtk_cell_area_apply_attributes (tree_column->cell_area, tree_model, iter,
2451 is_expander, is_expanded);
2455 * gtk_tree_view_column_cell_get_size:
2456 * @tree_column: A #GtkTreeViewColumn.
2457 * @cell_area: (allow-none): The area a cell in the column will be allocated, or %NULL
2458 * @x_offset: (allow-none): location to return x offset of a cell relative to @cell_area, or %NULL
2459 * @y_offset: (allow-none): location to return y offset of a cell relative to @cell_area, or %NULL
2460 * @width: (allow-none): location to return width needed to render a cell, or %NULL
2461 * @height: (allow-none): location to return height needed to render a cell, or %NULL
2463 * Obtains the width and height needed to render the column. This is used
2464 * primarily by the #GtkTreeView.
2467 gtk_tree_view_column_cell_get_size (GtkTreeViewColumn *tree_column,
2468 const GdkRectangle *cell_area,
2474 int focus_line_width;
2476 g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column));
2483 /* FIXME: This is a temporary hack to get things to allocate mostly right.
2485 * We will add twice the focus-line-width to the for-width
2486 * parameter below. If we do not do this, the height returned is the
2487 * height for two lines of text instead of one. It feels like some lines
2488 * get less width than expected (due to subtraction of focus_line_width?)
2489 * and will unnecessarily wrap.
2491 gtk_widget_style_get (tree_column->tree_view,
2492 "focus-line-width", &focus_line_width,
2495 gtk_cell_area_context_sum_preferred_width (tree_column->cell_area_context);
2497 gtk_cell_area_get_preferred_width (tree_column->cell_area,
2498 tree_column->cell_area_context,
2499 tree_column->tree_view,
2501 gtk_cell_area_get_preferred_height_for_width (tree_column->cell_area,
2502 tree_column->cell_area_context,
2503 tree_column->tree_view,
2504 *width + focus_line_width * 2,
2511 * gtk_tree_view_column_cell_render:
2512 * @tree_column: A #GtkTreeViewColumn.
2513 * @cr: cairo context to draw to
2514 * @background_area: entire cell area (including tree expanders and maybe padding on the sides)
2515 * @cell_area: area normally rendered by a cell renderer
2516 * @flags: flags that affect rendering
2518 * Renders the cell contained by #tree_column. This is used primarily by the
2522 _gtk_tree_view_column_cell_render (GtkTreeViewColumn *tree_column,
2524 const GdkRectangle *background_area,
2525 const GdkRectangle *cell_area,
2527 gboolean draw_focus)
2529 g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column));
2530 g_return_if_fail (cr != NULL);
2531 g_return_if_fail (background_area != NULL);
2532 g_return_if_fail (cell_area != NULL);
2536 gtk_cell_area_render (tree_column->cell_area, tree_column->cell_area_context,
2537 tree_column->tree_view, cr,
2538 background_area, cell_area, flags,
2545 _gtk_tree_view_column_cell_event (GtkTreeViewColumn *tree_column,
2546 GtkCellEditable **editable_widget,
2549 const GdkRectangle *background_area,
2550 const GdkRectangle *cell_area,
2553 g_return_val_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column), FALSE);
2555 /* FIXME: Should we pass background area here as well?
2556 * What will happen to the path_string and editable widget
2559 return gtk_cell_area_event (tree_column->cell_area,
2560 tree_column->cell_area_context,
2561 tree_column->tree_view,
2568 _gtk_tree_view_column_get_focus_area (GtkTreeViewColumn *tree_column,
2569 const GdkRectangle *background_area,
2570 const GdkRectangle *cell_area,
2571 GdkRectangle *focus_area)
2575 gtk_tree_view_column_cell_process_action (tree_column,
2588 _gtk_tree_view_column_cell_focus (GtkTreeViewColumn *tree_column,
2594 GtkDirectionType direction = 0;
2596 rtl = gtk_widget_get_direction (GTK_WIDGET (tree_column->tree_view)) == GTK_TEXT_DIR_RTL;
2601 direction = GTK_DIR_LEFT;
2605 direction = GTK_DIR_RIGHT;
2609 /* if we are the current focus column and have multiple editable cells,
2610 * try to select the next one, else move the focus to the next column
2612 if (GTK_TREE_VIEW (tree_column->tree_view)->priv->focus_column == tree_column)
2614 if (gtk_cell_area_focus (tree_column->cell_area, direction))
2615 /* Focus stays in this column, so we are done */
2618 /* FIXME: RTL support for the following: */
2619 if (count == -1 && !left)
2621 direction = GTK_DIR_RIGHT;
2622 gtk_cell_area_focus (tree_column->cell_area, direction);
2624 else if (count == 1 && !right)
2626 direction = GTK_DIR_LEFT;
2627 gtk_cell_area_focus (tree_column->cell_area, direction);
2633 return gtk_cell_area_focus (tree_column->cell_area, direction);
2637 * gtk_tree_view_column_cell_is_visible:
2638 * @tree_column: A #GtkTreeViewColumn
2640 * Returns %TRUE if any of the cells packed into the @tree_column are visible.
2641 * For this to be meaningful, you must first initialize the cells with
2642 * gtk_tree_view_column_cell_set_cell_data()
2644 * Return value: %TRUE, if any of the cells packed into the @tree_column are currently visible
2647 gtk_tree_view_column_cell_is_visible (GtkTreeViewColumn *tree_column)
2652 g_return_val_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column), FALSE);
2654 cells = gtk_cell_layout_get_cells (GTK_CELL_LAYOUT (tree_column->cell_area));
2655 for (list = cells; list; list = list->next)
2657 if (gtk_cell_renderer_get_visible (list->data))
2659 g_list_free (cells);
2664 g_list_free (cells);
2670 * gtk_tree_view_column_focus_cell:
2671 * @tree_column: A #GtkTreeViewColumn
2672 * @cell: A #GtkCellRenderer
2674 * Sets the current keyboard focus to be at @cell, if the column contains
2675 * 2 or more editable and activatable cells.
2680 gtk_tree_view_column_focus_cell (GtkTreeViewColumn *tree_column,
2681 GtkCellRenderer *cell)
2683 g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column));
2684 g_return_if_fail (GTK_IS_CELL_RENDERER (cell));
2686 gtk_cell_area_set_focus_cell (tree_column->cell_area, cell);
2690 _gtk_tree_view_column_cell_set_dirty (GtkTreeViewColumn *tree_column,
2691 gboolean install_handler)
2693 gtk_cell_area_context_reset (tree_column->cell_area_context);
2695 tree_column->dirty = TRUE;
2696 tree_column->requested_width = -1;
2697 tree_column->width = 0;
2699 if (tree_column->tree_view &&
2700 gtk_widget_get_realized (tree_column->tree_view))
2702 if (install_handler)
2703 _gtk_tree_view_install_mark_rows_col_dirty (GTK_TREE_VIEW (tree_column->tree_view));
2705 GTK_TREE_VIEW (tree_column->tree_view)->priv->mark_rows_col_dirty = TRUE;
2706 gtk_widget_queue_resize (tree_column->tree_view);
2711 * gtk_tree_view_column_cell_get_position:
2712 * @tree_column: a #GtkTreeViewColumn
2713 * @cell_renderer: a #GtkCellRenderer
2714 * @start_pos: return location for the horizontal position of @cell within
2715 * @tree_column, may be %NULL
2716 * @width: return location for the width of @cell, may be %NULL
2718 * Obtains the horizontal position and size of a cell in a column. If the
2719 * cell is not found in the column, @start_pos and @width are not changed and
2720 * %FALSE is returned.
2722 * Return value: %TRUE if @cell belongs to @tree_column.
2725 gtk_tree_view_column_cell_get_position (GtkTreeViewColumn *tree_column,
2726 GtkCellRenderer *cell_renderer,
2730 GdkRectangle zero_cell_area = { 0, };
2731 GdkRectangle allocation;
2733 /* FIXME: Could use a boolean return value for invalid cells */
2734 gtk_cell_area_get_cell_allocation (tree_column->cell_area,
2735 tree_column->cell_area_context,
2736 tree_column->tree_view,
2742 *start_pos = allocation.x;
2744 *width = allocation.width;
2750 * gtk_tree_view_column_queue_resize:
2751 * @tree_column: A #GtkTreeViewColumn
2753 * Flags the column, and the cell renderers added to this column, to have
2754 * their sizes renegotiated.
2759 gtk_tree_view_column_queue_resize (GtkTreeViewColumn *tree_column)
2761 g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column));
2763 if (tree_column->tree_view)
2764 _gtk_tree_view_column_cell_set_dirty (tree_column, TRUE);
2768 * gtk_tree_view_column_get_tree_view:
2769 * @tree_column: A #GtkTreeViewColumn
2771 * Returns the #GtkTreeView wherein @tree_column has been inserted.
2772 * If @column is currently not inserted in any tree view, %NULL is
2775 * Return value: (transfer none): The tree view wherein @column has
2776 * been inserted if any, %NULL otherwise.
2781 gtk_tree_view_column_get_tree_view (GtkTreeViewColumn *tree_column)
2783 g_return_val_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column), NULL);
2785 return tree_column->tree_view;