X-Git-Url: http://pileus.org/git/?a=blobdiff_plain;f=gtk%2Fgtktreeviewcolumn.c;h=af2317cab7250bf3d0be3599a948e339ffad828c;hb=5d011386a69aa59d6eda1e3ef32005efd831c179;hp=7a8bb7367d57e6bffdc872b878b0ad1843593e23;hpb=bf1aa2ad87ecb164282bf9a655464a16209cc774;p=~andy%2Fgtk diff --git a/gtk/gtktreeviewcolumn.c b/gtk/gtktreeviewcolumn.c index 7a8bb7367..af2317cab 100644 --- a/gtk/gtktreeviewcolumn.c +++ b/gtk/gtktreeviewcolumn.c @@ -12,9 +12,7 @@ * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. + * License along with this library. If not, see . */ #include "config.h" @@ -29,13 +27,15 @@ #include "gtkbutton.h" #include "gtkalignment.h" #include "gtklabel.h" -#include "gtkhbox.h" +#include "gtkbox.h" #include "gtkmarshalers.h" #include "gtkarrow.h" #include "gtkcellareacontext.h" #include "gtkcellareabox.h" #include "gtkprivate.h" #include "gtkintl.h" +#include "gtktypebuiltins.h" +#include "a11y/gtktreeviewaccessibleprivate.h" /** @@ -75,6 +75,9 @@ static GObject *gtk_tree_view_column_constructor (GType GObjectConstructParam *construct_properties); /* GtkCellLayout implementation */ +static void gtk_tree_view_column_ensure_cell_area (GtkTreeViewColumn *column, + GtkCellArea *cell_area); + static GtkCellArea *gtk_tree_view_column_cell_layout_get_area (GtkCellLayout *cell_layout); /* Button handling code */ @@ -137,7 +140,7 @@ struct _GtkTreeViewColumnPrivate /* see gtk+/doc/tree-column-sizing.txt for more information on them */ GtkTreeViewColumnSizing column_type; gint padding; - gint resized_width; + gint x_offset; gint width; gint fixed_width; gint min_width; @@ -170,7 +173,6 @@ struct _GtkTreeViewColumnPrivate guint show_sort_indicator : 1; guint maybe_reordered : 1; guint reorderable : 1; - guint use_resized_width : 1; guint expand : 1; }; @@ -179,6 +181,7 @@ enum PROP_0, PROP_VISIBLE, PROP_RESIZABLE, + PROP_X_OFFSET, PROP_WIDTH, PROP_SPACING, PROP_SIZING, @@ -252,6 +255,16 @@ gtk_tree_view_column_class_init (GtkTreeViewColumnClass *class) FALSE, GTK_PARAM_READWRITE)); + g_object_class_install_property (object_class, + PROP_X_OFFSET, + g_param_spec_int ("x-offset", + P_("X position"), + P_("Current X position of the column"), + -G_MAXINT, + G_MAXINT, + 0, + GTK_PARAM_READABLE)); + g_object_class_install_property (object_class, PROP_WIDTH, g_param_spec_int ("width", @@ -284,9 +297,9 @@ gtk_tree_view_column_class_init (GtkTreeViewColumnClass *class) g_param_spec_int ("fixed-width", P_("Fixed Width"), P_("Current fixed width of the column"), - 1, + -1, G_MAXINT, - 1, /* not useful */ + -1, GTK_PARAM_READWRITE)); g_object_class_install_property (object_class, @@ -381,7 +394,7 @@ gtk_tree_view_column_class_init (GtkTreeViewColumnClass *class) * GtkTreeViewColumn:sort-column-id: * * Logical sort column ID this column sorts on when selected for sorting. Setting the sort column ID makes the column header - * clickable. Set to %-1 to make the column unsortable. + * clickable. Set to -1 to make the column unsortable. * * Since: 2.18 **/ @@ -400,6 +413,9 @@ gtk_tree_view_column_class_init (GtkTreeViewColumnClass *class) * * The #GtkCellArea used to layout cell renderers for this column. * + * If no area is specified when creating the tree view column with gtk_tree_view_column_new_with_area() + * a horizontally oriented #GtkCellAreaBox will be used. + * * Since: 3.0 */ g_object_class_install_property (object_class, @@ -454,7 +470,6 @@ gtk_tree_view_column_init (GtkTreeViewColumn *tree_column) priv->padding = -1; priv->min_width = -1; priv->max_width = -1; - priv->resized_width = 0; priv->column_type = GTK_TREE_VIEW_COLUMN_GROW_ONLY; priv->visible = TRUE; priv->resizable = FALSE; @@ -469,48 +484,24 @@ gtk_tree_view_column_init (GtkTreeViewColumn *tree_column) priv->sort_column_id = -1; priv->reorderable = FALSE; priv->maybe_reordered = FALSE; - priv->fixed_width = 1; - priv->use_resized_width = FALSE; + priv->fixed_width = -1; priv->title = g_strdup (""); } static GObject * -gtk_tree_view_column_constructor (GType type, - guint n_construct_properties, - GObjectConstructParam *construct_properties) +gtk_tree_view_column_constructor (GType type, + guint n_construct_properties, + GObjectConstructParam *construct_properties) { GtkTreeViewColumn *tree_column; - GtkTreeViewColumnPrivate *priv; GObject *object; object = G_OBJECT_CLASS (gtk_tree_view_column_parent_class)->constructor (type, n_construct_properties, construct_properties); tree_column = (GtkTreeViewColumn *) object; - priv = tree_column->priv; - - if (!priv->cell_area) - { - priv->cell_area = gtk_cell_area_box_new (); - g_object_ref_sink (priv->cell_area); - } - gtk_cell_area_set_style_detail (priv->cell_area, "treeview"); - - priv->add_editable_signal = - g_signal_connect (priv->cell_area, "add-editable", - G_CALLBACK (gtk_tree_view_column_add_editable_callback), - tree_column); - priv->remove_editable_signal = - g_signal_connect (priv->cell_area, "remove-editable", - G_CALLBACK (gtk_tree_view_column_remove_editable_callback), - tree_column); - - priv->cell_area_context = gtk_cell_area_create_context (priv->cell_area); - - priv->context_changed_signal = - g_signal_connect (priv->cell_area_context, "notify", - G_CALLBACK (gtk_tree_view_column_context_changed), tree_column); + gtk_tree_view_column_ensure_cell_area (tree_column, NULL); return object; } @@ -521,6 +512,12 @@ gtk_tree_view_column_dispose (GObject *object) GtkTreeViewColumn *tree_column = (GtkTreeViewColumn *) object; GtkTreeViewColumnPrivate *priv = tree_column->priv; + /* Remove this column from its treeview, + * in case this column is destroyed before its treeview. + */ + if (priv->tree_view) + gtk_tree_view_remove_column (GTK_TREE_VIEW (priv->tree_view), tree_column); + if (priv->cell_area_context) { g_signal_handler_disconnect (priv->cell_area_context, @@ -538,7 +535,7 @@ gtk_tree_view_column_dispose (GObject *object) priv->add_editable_signal); g_signal_handler_disconnect (priv->cell_area, priv->remove_editable_signal); - + g_object_unref (priv->cell_area); priv->cell_area = NULL; priv->add_editable_signal = 0; @@ -663,9 +660,18 @@ gtk_tree_view_column_set_property (GObject *object, area = g_value_get_object (value); if (area) - tree_column->priv->cell_area = g_object_ref_sink (area); + { + if (tree_column->priv->cell_area != NULL) + { + g_warning ("cell-area has already been set, ignoring construct property"); + g_object_ref_sink (area); + g_object_unref (area); + } + else + gtk_tree_view_column_ensure_cell_area (tree_column, area); + } break; - + default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -694,6 +700,11 @@ gtk_tree_view_column_get_property (GObject *object, gtk_tree_view_column_get_resizable (tree_column)); break; + case PROP_X_OFFSET: + g_value_set_int (value, + gtk_tree_view_column_get_x_offset (tree_column)); + break; + case PROP_WIDTH: g_value_set_int (value, gtk_tree_view_column_get_width (tree_column)); @@ -781,12 +792,49 @@ gtk_tree_view_column_get_property (GObject *object, /* Implementation of GtkCellLayout interface */ + +static void +gtk_tree_view_column_ensure_cell_area (GtkTreeViewColumn *column, + GtkCellArea *cell_area) +{ + GtkTreeViewColumnPrivate *priv = column->priv; + + if (priv->cell_area) + return; + + if (cell_area) + priv->cell_area = cell_area; + else + priv->cell_area = gtk_cell_area_box_new (); + + g_object_ref_sink (priv->cell_area); + + priv->add_editable_signal = + g_signal_connect (priv->cell_area, "add-editable", + G_CALLBACK (gtk_tree_view_column_add_editable_callback), + column); + priv->remove_editable_signal = + g_signal_connect (priv->cell_area, "remove-editable", + G_CALLBACK (gtk_tree_view_column_remove_editable_callback), + column); + + priv->cell_area_context = gtk_cell_area_create_context (priv->cell_area); + + priv->context_changed_signal = + g_signal_connect (priv->cell_area_context, "notify", + G_CALLBACK (gtk_tree_view_column_context_changed), + column); +} + static GtkCellArea * gtk_tree_view_column_cell_layout_get_area (GtkCellLayout *cell_layout) { GtkTreeViewColumn *column = GTK_TREE_VIEW_COLUMN (cell_layout); GtkTreeViewColumnPrivate *priv = column->priv; + if (G_UNLIKELY (!priv->cell_area)) + gtk_tree_view_column_ensure_cell_area (column, NULL); + return priv->cell_area; } @@ -807,6 +855,8 @@ gtk_tree_view_column_create_button (GtkTreeViewColumn *tree_column) gtk_widget_push_composite_child (); priv->button = gtk_button_new (); + if (priv->visible) + gtk_widget_show (priv->button); gtk_widget_add_events (priv->button, GDK_POINTER_MOTION_MASK); gtk_widget_pop_composite_child (); @@ -985,9 +1035,11 @@ gtk_tree_view_column_update_button (GtkTreeViewColumn *tree_column) priv->tree_view != NULL && gtk_widget_get_realized (priv->tree_view)) { - if (priv->visible) + if (priv->visible && + gdk_window_is_visible (_gtk_tree_view_get_header_window (GTK_TREE_VIEW (priv->tree_view)))) { - gtk_widget_show_now (priv->button); + gtk_widget_show (priv->button); + if (priv->window) { if (priv->resizable) @@ -1048,13 +1100,14 @@ gtk_tree_view_column_button_event (GtkWidget *widget, if (event->type == GDK_BUTTON_PRESS && priv->reorderable && - ((GdkEventButton *)event)->button == 1) + ((GdkEventButton *)event)->button == GDK_BUTTON_PRIMARY) { priv->maybe_reordered = TRUE; - gdk_window_get_pointer (gtk_button_get_event_window (GTK_BUTTON (widget)), - &priv->drag_x, - &priv->drag_y, - NULL); + gdk_window_get_device_position (gtk_button_get_event_window (GTK_BUTTON (widget)), + gdk_event_get_device (event), + &priv->drag_x, + &priv->drag_y, + NULL); gtk_widget_grab_focus (widget); } @@ -1246,17 +1299,21 @@ gtk_tree_view_column_context_changed (GtkCellAreaContext *context, GParamSpec *pspec, GtkTreeViewColumn *tree_column) { + /* Here we want the column re-requested if the underlying context was + * actually reset for any reason, this can happen if the underlying + * area/cell configuration changes (i.e. cell packing properties + * or cell spacing and the like) + * + * Note that we block this handler while requesting for sizes + * so there is no need to check for the new context size being -1, + * we also block the handler when explicitly resetting the context + * so as to avoid some infinite stack recursion. + */ if (!strcmp (pspec->name, "minimum-width") || !strcmp (pspec->name, "natural-width") || !strcmp (pspec->name, "minimum-height") || !strcmp (pspec->name, "natural-height")) - { - /* XXX We want to do something specific if the size actually got cleared - * or if it just grew a little bit because of a data change and we - * are in GROW_ONLY mode. - */ - _gtk_tree_view_column_cell_set_dirty (tree_column, TRUE); - } + _gtk_tree_view_column_cell_set_dirty (tree_column, TRUE); } static void @@ -1323,9 +1380,6 @@ _gtk_tree_view_column_realize_button (GtkTreeViewColumn *column) g_return_if_fail (_gtk_tree_view_get_header_window (tree_view) != NULL); gtk_widget_set_parent_window (priv->button, _gtk_tree_view_get_header_window (tree_view)); - if (priv->visible) - gtk_widget_show (priv->button); - attr.window_type = GDK_WINDOW_CHILD; attr.wclass = GDK_INPUT_ONLY; attr.visual = gtk_widget_get_visual (GTK_WIDGET (tree_view)); @@ -1346,11 +1400,11 @@ _gtk_tree_view_column_realize_button (GtkTreeViewColumn *column) attr.x = (allocation.x + (rtl ? 0 : allocation.width)) - TREE_VIEW_DRAG_WIDTH / 2; priv->window = gdk_window_new (_gtk_tree_view_get_header_window (tree_view), &attr, attributes_mask); - gdk_window_set_user_data (priv->window, tree_view); + gtk_widget_register_window (GTK_WIDGET (tree_view), priv->window); gtk_tree_view_column_update_button (column); - gdk_cursor_unref (attr.cursor); + g_object_unref (attr.cursor); } void @@ -1363,7 +1417,7 @@ _gtk_tree_view_column_unrealize_button (GtkTreeViewColumn *column) priv = column->priv; g_return_if_fail (priv->window != NULL); - gdk_window_set_user_data (priv->window, NULL); + gtk_widget_unregister_window (GTK_WIDGET (priv->tree_view), priv->window); gdk_window_destroy (priv->window); priv->window = NULL; } @@ -1468,36 +1522,86 @@ _gtk_tree_view_column_get_edited_cell (GtkTreeViewColumn *column) GtkCellRenderer * _gtk_tree_view_column_get_cell_at_pos (GtkTreeViewColumn *column, - gint x) + GdkRectangle *cell_area, + GdkRectangle *background_area, + gint x, + gint y) { - GList *list; - GList *cell; GtkCellRenderer *match = NULL; GtkTreeViewColumnPrivate *priv = column->priv; - list = gtk_cell_layout_get_cells (GTK_CELL_LAYOUT (column)); - for (cell = list; cell; cell = cell->next) - { - GdkRectangle zero_cell_area = { 0, }; - GdkRectangle allocation; + /* If (x, y) is outside of the background area, immediately return */ + if (x < background_area->x || + x > background_area->x + background_area->width || + y < background_area->y || + y > background_area->y + background_area->height) + return NULL; + + /* If (x, y) is inside the background area, clamp it to the cell_area + * so that a cell is still returned. The main reason for doing this + * (on the x axis) is for handling clicks in the indentation area + * (either at the left or right depending on RTL setting). Another + * reason is for handling clicks on the area where the focus rectangle + * is drawn (this is outside of cell area), this manifests itself + * mainly when a large setting is used for focus-line-width. + */ + if (x < cell_area->x) + x = cell_area->x; + else if (x > cell_area->x + cell_area->width) + x = cell_area->x + cell_area->width; + + if (y < cell_area->y) + y = cell_area->y; + else if (y > cell_area->y + cell_area->height) + y = cell_area->y + cell_area->height; + + match = gtk_cell_area_get_cell_at_position (priv->cell_area, + priv->cell_area_context, + priv->tree_view, + cell_area, + x, y, + NULL); - gtk_cell_area_get_cell_allocation (priv->cell_area, - priv->cell_area_context, - priv->tree_view, - cell->data, - &zero_cell_area, - &allocation); + return match; +} - if (allocation.x <= x && x <= allocation.x + allocation.width) - { - match = cell->data; - break; - } - } +gboolean +_gtk_tree_view_column_is_blank_at_pos (GtkTreeViewColumn *column, + GdkRectangle *cell_area, + GdkRectangle *background_area, + gint x, + gint y) +{ + GtkCellRenderer *match; + GdkRectangle cell_alloc, aligned_area, inner_area; + GtkTreeViewColumnPrivate *priv = column->priv; - g_list_free (list); + match = _gtk_tree_view_column_get_cell_at_pos (column, + cell_area, + background_area, + x, y); + if (!match) + return FALSE; - return match; + gtk_cell_area_get_cell_allocation (priv->cell_area, + priv->cell_area_context, + priv->tree_view, + match, + cell_area, + &cell_alloc); + + gtk_cell_area_inner_cell_area (priv->cell_area, priv->tree_view, + &cell_alloc, &inner_area); + gtk_cell_renderer_get_aligned_area (match, priv->tree_view, 0, + &inner_area, &aligned_area); + + if (x < aligned_area.x || + x > aligned_area.x + aligned_area.width || + y < aligned_area.y || + y > aligned_area.y + aligned_area.height) + return TRUE; + + return FALSE; } /* Public Functions */ @@ -1521,13 +1625,34 @@ gtk_tree_view_column_new (void) } /** - * gtk_tree_view_column_new_with_attributes: - * @title: The title to set the header to. - * @cell: The #GtkCellRenderer. - * @Varargs: A %NULL-terminated list of attributes. + * gtk_tree_view_column_new_with_area: + * @area: the #GtkCellArea that the newly created column should use to layout cells. * - * Creates a new #GtkTreeViewColumn with a number of default values. This is - * equivalent to calling gtk_tree_view_column_set_title(), + * Creates a new #GtkTreeViewColumn using @area to render its cells. + * + * Return value: A newly created #GtkTreeViewColumn. + * + * Since: 3.0 + */ +GtkTreeViewColumn * +gtk_tree_view_column_new_with_area (GtkCellArea *area) +{ + GtkTreeViewColumn *tree_column; + + tree_column = g_object_new (GTK_TYPE_TREE_VIEW_COLUMN, "cell-area", area, NULL); + + return tree_column; +} + + +/** + * gtk_tree_view_column_new_with_attributes: + * @title: The title to set the header to + * @cell: The #GtkCellRenderer + * @...: A %NULL-terminated list of attributes + * + * Creates a new #GtkTreeViewColumn with a number of default values. + * This is equivalent to calling gtk_tree_view_column_set_title(), * gtk_tree_view_column_pack_start(), and * gtk_tree_view_column_set_attributes() on the newly created #GtkTreeViewColumn. * @@ -1666,15 +1791,15 @@ gtk_tree_view_column_set_attributesv (GtkTreeViewColumn *tree_column, /** * gtk_tree_view_column_set_attributes: - * @tree_column: A #GtkTreeViewColumn. + * @tree_column: A #GtkTreeViewColumn * @cell_renderer: the #GtkCellRenderer we're setting the attributes of - * @Varargs: A %NULL-terminated list of attributes. - * + * @...: A %NULL-terminated list of attributes + * * Sets the attributes in the list as the attributes of @tree_column. * The attributes should be in attribute/column order, as in * gtk_tree_view_column_add_attribute(). All existing attributes * are removed, and replaced with the new attributes. - **/ + */ void gtk_tree_view_column_set_attributes (GtkTreeViewColumn *tree_column, GtkCellRenderer *cell_renderer, @@ -1695,11 +1820,11 @@ gtk_tree_view_column_set_attributes (GtkTreeViewColumn *tree_column, * gtk_tree_view_column_set_cell_data_func: * @tree_column: A #GtkTreeViewColumn * @cell_renderer: A #GtkCellRenderer - * @func: The #GtkTreeViewColumnFunc to use. + * @func: (allow-none): The #GtkTreeCellDataFunc to use. * @func_data: The user data for @func. * @destroy: The destroy notification for @func_data * - * Sets the #GtkTreeViewColumnFunc to use for the column. This + * Sets the #GtkTreeCellDataFunc to use for the column. This * function is used instead of the standard attributes mapping for * setting the column value, and should set the value of @tree_column's * cell renderer as appropriate. @func may be %NULL to remove an @@ -1788,10 +1913,10 @@ gtk_tree_view_column_get_spacing (GtkTreeViewColumn *tree_column) * @visible: %TRUE if the @tree_column is visible. * * Sets the visibility of @tree_column. - **/ + */ void gtk_tree_view_column_set_visible (GtkTreeViewColumn *tree_column, - gboolean visible) + gboolean visible) { GtkTreeViewColumnPrivate *priv; @@ -1799,7 +1924,7 @@ gtk_tree_view_column_set_visible (GtkTreeViewColumn *tree_column, priv = tree_column->priv; visible = !! visible; - + if (priv->visible == visible) return; @@ -1808,6 +1933,13 @@ gtk_tree_view_column_set_visible (GtkTreeViewColumn *tree_column, if (priv->visible) _gtk_tree_view_column_cell_set_dirty (tree_column, TRUE); + if (priv->tree_view) + { + _gtk_tree_view_reset_header_styles (GTK_TREE_VIEW (priv->tree_view)); + _gtk_tree_view_accessible_toggle_visibility (GTK_TREE_VIEW (priv->tree_view), + tree_column); + } + gtk_tree_view_column_update_button (tree_column); g_object_notify (G_OBJECT (tree_column), "visible"); } @@ -1942,52 +2074,66 @@ gtk_tree_view_column_get_width (GtkTreeViewColumn *tree_column) return tree_column->priv->width; } +/** + * gtk_tree_view_column_get_x_offset: + * @tree_column: A #GtkTreeViewColumn. + * + * Returns the current X offset of @tree_column in pixels. + * + * Return value: The current X offset of @tree_column. + * + * Since: 3.2 + */ gint -_gtk_tree_view_column_request_width (GtkTreeViewColumn *tree_column) +gtk_tree_view_column_get_x_offset (GtkTreeViewColumn *tree_column) { - GtkTreeViewColumnPrivate *priv; - gint real_requested_width; - - priv = tree_column->priv; + g_return_val_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column), 0); - if (priv->use_resized_width) - { - real_requested_width = priv->resized_width; - } - else if (priv->column_type == GTK_TREE_VIEW_COLUMN_FIXED) - { - real_requested_width = priv->fixed_width; - } - else if (gtk_tree_view_get_headers_visible (GTK_TREE_VIEW (priv->tree_view))) - { - gint button_request; - gint requested_width; + return tree_column->priv->x_offset; +} - gtk_cell_area_context_get_preferred_width (priv->cell_area_context, &requested_width, NULL); - requested_width += priv->padding; +void +_gtk_tree_view_column_request_width (GtkTreeViewColumn *tree_column, + gint *minimum, + gint *natural) +{ + GtkTreeViewColumnPrivate *priv = tree_column->priv; + gint minimum_width = 1, natural_width = 1; + gint button_minimum, button_natural; - gtk_widget_get_preferred_width (priv->button, &button_request, NULL); - real_requested_width = MAX (requested_width, button_request); - } - else + if (priv->column_type != GTK_TREE_VIEW_COLUMN_FIXED) { - gint requested_width; - - gtk_cell_area_context_get_preferred_width (priv->cell_area_context, &requested_width, NULL); - requested_width += priv->padding; + gtk_cell_area_context_get_preferred_width (priv->cell_area_context, &minimum_width, &natural_width); + minimum_width += priv->padding; + natural_width += priv->padding; - real_requested_width = requested_width; - if (real_requested_width < 0) - real_requested_width = 0; + if (gtk_tree_view_get_headers_visible (GTK_TREE_VIEW (priv->tree_view))) + { + gtk_widget_get_preferred_width (priv->button, &button_minimum, &button_natural); + minimum_width = MAX (minimum_width, button_minimum); + natural_width = MAX (natural_width, button_natural); + } } + if (priv->fixed_width != -1) + natural_width = MAX (priv->fixed_width, minimum_width); + if (priv->min_width != -1) - real_requested_width = MAX (real_requested_width, priv->min_width); + { + minimum_width = MAX (minimum_width, priv->min_width); + natural_width = MAX (natural_width, priv->min_width); + } if (priv->max_width != -1) - real_requested_width = MIN (real_requested_width, priv->max_width); + { + minimum_width = MIN (minimum_width, priv->max_width); + natural_width = MIN (natural_width, priv->max_width); + } - return real_requested_width; + if (minimum != NULL) + *minimum = minimum_width; + if (natural != NULL) + *natural = natural_width; } void @@ -1996,23 +2142,30 @@ _gtk_tree_view_column_allocate (GtkTreeViewColumn *tree_column, int width) { GtkTreeViewColumnPrivate *priv; - GtkAllocation allocation; gboolean rtl; + GtkAllocation allocation = { 0, 0, 0, 0 }; g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column)); priv = tree_column->priv; + if (priv->width != width) + gtk_widget_queue_draw (priv->tree_view); + + priv->x_offset = x_offset; priv->width = width; gtk_cell_area_context_allocate (priv->cell_area_context, priv->width - priv->padding, -1); - allocation.x = x_offset; - allocation.y = 0; - allocation.width = width; - allocation.height = _gtk_tree_view_get_header_height (GTK_TREE_VIEW (priv->tree_view)); + if (gtk_tree_view_get_headers_visible (GTK_TREE_VIEW (priv->tree_view))) + { + allocation.x = x_offset; + allocation.y = 0; + allocation.width = width; + allocation.height = _gtk_tree_view_get_header_height (GTK_TREE_VIEW (priv->tree_view)); - gtk_widget_size_allocate (priv->button, &allocation); + gtk_widget_size_allocate (priv->button, &allocation); + } if (priv->window) { @@ -2023,19 +2176,26 @@ _gtk_tree_view_column_allocate (GtkTreeViewColumn *tree_column, TREE_VIEW_DRAG_WIDTH, allocation.height); } + g_object_notify (G_OBJECT (tree_column), "x-offset"); g_object_notify (G_OBJECT (tree_column), "width"); } /** * gtk_tree_view_column_set_fixed_width: * @tree_column: A #GtkTreeViewColumn. - * @fixed_width: The size to set @tree_column to. Must be greater than 0. - * - * Sets the size of the column in pixels. This is meaningful only if the sizing - * type is #GTK_TREE_VIEW_COLUMN_FIXED. The size of the column is clamped to - * the min/max width for the column. Please note that the min/max width of the - * column doesn't actually affect the "fixed_width" property of the widget, just - * the actual size when displayed. + * @fixed_width: The new fixed width, in pixels, or -1. + * + * If @fixed_width is not -1, sets the fixed width of @tree_column; otherwise + * unsets it. The effective value of @fixed_width is clamped between the + * minumum and maximum width of the column; however, the value stored in the + * "fixed-width" property is not clamped. If the column sizing is + * #GTK_TREE_VIEW_COLUMN_GROW_ONLY or #GTK_TREE_VIEW_COLUMN_AUTOSIZE, setting a + * fixed width overrides the automatically calculated width. Note that + * @fixed_width is only a hint to GTK+; the width actually allocated to the + * column may be greater or less than requested. + * + * Along with "expand", the "fixed-width" property changes when the column is + * resized by the user. **/ void gtk_tree_view_column_set_fixed_width (GtkTreeViewColumn *tree_column, @@ -2044,16 +2204,15 @@ gtk_tree_view_column_set_fixed_width (GtkTreeViewColumn *tree_column, GtkTreeViewColumnPrivate *priv; g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column)); - g_return_if_fail (fixed_width > 0); + g_return_if_fail (fixed_width >= -1); priv = tree_column->priv; priv->fixed_width = fixed_width; - priv->use_resized_width = FALSE; - if (priv->tree_view && - gtk_widget_get_realized (priv->tree_view) && - priv->column_type == GTK_TREE_VIEW_COLUMN_FIXED) + if (priv->visible && + priv->tree_view != NULL && + gtk_widget_get_realized (priv->tree_view)) { gtk_widget_queue_resize (priv->tree_view); } @@ -2063,12 +2222,12 @@ gtk_tree_view_column_set_fixed_width (GtkTreeViewColumn *tree_column, /** * gtk_tree_view_column_get_fixed_width: - * @tree_column: a #GtkTreeViewColumn - * - * Gets the fixed width of the column. This value is only meaning may not be - * the actual width of the column on the screen, just what is requested. - * - * Return value: the fixed width of the column + * @tree_column: A #GtkTreeViewColumn. + * + * Gets the fixed width of the column. This may not be the actual displayed + * width of the column; for that, use gtk_tree_view_column_get_width(). + * + * Return value: The fixed width of the column. **/ gint gtk_tree_view_column_get_fixed_width (GtkTreeViewColumn *tree_column) @@ -2262,7 +2421,7 @@ gtk_tree_view_column_set_title (GtkTreeViewColumn *tree_column, * Return value: the title of the column. This string should not be * modified or freed. **/ -G_CONST_RETURN gchar * +const gchar * gtk_tree_view_column_get_title (GtkTreeViewColumn *tree_column) { g_return_val_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column), NULL); @@ -2272,14 +2431,17 @@ gtk_tree_view_column_get_title (GtkTreeViewColumn *tree_column) /** * gtk_tree_view_column_set_expand: - * @tree_column: A #GtkTreeViewColumn - * @expand: %TRUE if the column should take available extra space, %FALSE if not - * + * @tree_column: A #GtkTreeViewColumn. + * @expand: %TRUE if the column should expand to fill available space. + * * Sets the column to take available extra space. This space is shared equally * amongst all columns that have the expand set to %TRUE. If no column has this * option set, then the last column gets all extra space. By default, every * column is created with this %FALSE. * + * Along with "fixed-width", the "expand" property changes when the column is + * resized by the user. + * * Since: 2.4 **/ void @@ -2301,13 +2463,6 @@ gtk_tree_view_column_set_expand (GtkTreeViewColumn *tree_column, priv->tree_view != NULL && gtk_widget_get_realized (priv->tree_view)) { - /* We want to continue using the original width of the - * column that includes additional space added by the user - * resizing the columns and possibly extra (expanded) space, which - * are not included in the resized width. - */ - priv->use_resized_width = FALSE; - gtk_widget_queue_resize (priv->tree_view); } @@ -2316,11 +2471,11 @@ gtk_tree_view_column_set_expand (GtkTreeViewColumn *tree_column, /** * gtk_tree_view_column_get_expand: - * @tree_column: a #GtkTreeViewColumn - * - * Return %TRUE if the column expands to take any available space. - * - * Return value: %TRUE, if the column expands + * @tree_column: A #GtkTreeViewColumn. + * + * Returns %TRUE if the column expands to fill available space. + * + * Return value: %TRUE if the column expands to fill available space. * * Since: 2.4 **/ @@ -2337,8 +2492,8 @@ gtk_tree_view_column_get_expand (GtkTreeViewColumn *tree_column) * @tree_column: A #GtkTreeViewColumn. * @clickable: %TRUE if the header is active. * - * Sets the header to be active if @active is %TRUE. When the header is active, - * then it can take keyboard focus, and can be clicked. + * Sets the header to be active if @clickable is %TRUE. When the header is + * active, then it can take keyboard focus, and can be clicked. **/ void gtk_tree_view_column_set_clickable (GtkTreeViewColumn *tree_column, @@ -2647,7 +2802,7 @@ gtk_tree_view_column_get_sort_indicator (GtkTreeViewColumn *tree_column) * This does not actually sort the model. Use * gtk_tree_view_column_set_sort_column_id() if you want automatic sorting * support. This function is primarily for custom sorting behavior, and should - * be used in conjunction with gtk_tree_sortable_set_sort_column() to do + * be used in conjunction with gtk_tree_sortable_set_sort_column_id() to do * that. For custom models, the mechanism will vary. * * The sort indicator changes direction to indicate normal sort or reverse sort. @@ -2717,10 +2872,10 @@ gtk_tree_view_column_cell_set_cell_data (GtkTreeViewColumn *tree_column, * gtk_tree_view_column_cell_get_size: * @tree_column: A #GtkTreeViewColumn. * @cell_area: (allow-none): The area a cell in the column will be allocated, or %NULL - * @x_offset: (allow-none): location to return x offset of a cell relative to @cell_area, or %NULL - * @y_offset: (allow-none): location to return y offset of a cell relative to @cell_area, or %NULL - * @width: (allow-none): location to return width needed to render a cell, or %NULL - * @height: (allow-none): location to return height needed to render a cell, or %NULL + * @x_offset: (out) (allow-none): location to return x offset of a cell relative to @cell_area, or %NULL + * @y_offset: (out) (allow-none): location to return y offset of a cell relative to @cell_area, or %NULL + * @width: (out) (allow-none): location to return width needed to render a cell, or %NULL + * @height: (out) (allow-none): location to return height needed to render a cell, or %NULL * * Obtains the width and height needed to render the column. This is used * primarily by the #GtkTreeView. @@ -2892,6 +3047,15 @@ _gtk_tree_view_column_cell_set_dirty (GtkTreeViewColumn *tree_column, priv->padding = 0; priv->width = 0; + /* Issue a manual reset on the context to have all + * sizes re-requested for the context. + */ + g_signal_handler_block (priv->cell_area_context, + priv->context_changed_signal); + gtk_cell_area_context_reset (priv->cell_area_context); + g_signal_handler_unblock (priv->cell_area_context, + priv->context_changed_signal); + if (priv->tree_view && gtk_widget_get_realized (priv->tree_view)) { @@ -2910,9 +3074,10 @@ _gtk_tree_view_column_cell_get_dirty (GtkTreeViewColumn *tree_column) * gtk_tree_view_column_cell_get_position: * @tree_column: a #GtkTreeViewColumn * @cell_renderer: a #GtkCellRenderer - * @x_offset: return location for the horizontal position of @cell within - * @tree_column, may be %NULL - * @width: return location for the width of @cell, may be %NULL + * @x_offset: (out) (allow-none): return location for the horizontal + * position of @cell within @tree_column, may be %NULL + * @width: (out) (allow-none): return location for the width of @cell, + * may be %NULL * * Obtains the horizontal position and size of a cell in a column. If the * cell is not found in the column, @start_pos and @width are not changed and @@ -2927,7 +3092,7 @@ gtk_tree_view_column_cell_get_position (GtkTreeViewColumn *tree_column, gint *width) { GtkTreeViewColumnPrivate *priv; - GdkRectangle zero_cell_area = { 0, }; + GdkRectangle cell_area; GdkRectangle allocation; g_return_val_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column), FALSE); @@ -2935,16 +3100,22 @@ gtk_tree_view_column_cell_get_position (GtkTreeViewColumn *tree_column, priv = tree_column->priv; - /* FIXME: Could use a boolean return value for invalid cells */ + if (! gtk_cell_area_has_renderer (priv->cell_area, cell_renderer)) + return FALSE; + + gtk_tree_view_get_background_area (GTK_TREE_VIEW (priv->tree_view), + NULL, tree_column, &cell_area); + gtk_cell_area_get_cell_allocation (priv->cell_area, priv->cell_area_context, priv->tree_view, cell_renderer, - &zero_cell_area, + &cell_area, &allocation); if (x_offset) - *x_offset = allocation.x; + *x_offset = allocation.x - cell_area.x; + if (width) *width = allocation.width; @@ -3031,33 +3202,6 @@ _gtk_tree_view_column_get_requested_width (GtkTreeViewColumn *column) return requested_width + column->priv->padding; } - -void -_gtk_tree_view_column_set_resized_width (GtkTreeViewColumn *column, - gint width) -{ - column->priv->resized_width = width; -} - -gint -_gtk_tree_view_column_get_resized_width (GtkTreeViewColumn *column) -{ - return column->priv->resized_width; -} - -void -_gtk_tree_view_column_set_use_resized_width (GtkTreeViewColumn *column, - gboolean use_resized_width) -{ - column->priv->use_resized_width = use_resized_width; -} - -gboolean -_gtk_tree_view_column_get_use_resized_width (GtkTreeViewColumn *column) -{ - return column->priv->use_resized_width; -} - gint _gtk_tree_view_column_get_drag_x (GtkTreeViewColumn *column) {