X-Git-Url: http://pileus.org/git/?a=blobdiff_plain;f=gtk%2Fgtktreeviewcolumn.c;h=af2317cab7250bf3d0be3599a948e339ffad828c;hb=1865b9a1116d166c9abc5c75f5d01270574007c5;hp=07f9880d4fc60b3f7d01420ccccc59b5c52fe4b0;hpb=81e1d02de3f0d26be4ebda0237fcad345fa0f39a;p=~andy%2Fgtk
diff --git a/gtk/gtktreeviewcolumn.c b/gtk/gtktreeviewcolumn.c
index 07f9880d4..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 */
@@ -136,8 +139,8 @@ struct _GtkTreeViewColumnPrivate
/* Sizing fields */
/* see gtk+/doc/tree-column-sizing.txt for more information on them */
GtkTreeViewColumnSizing column_type;
- gint requested_width;
- gint resized_width;
+ gint padding;
+ 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,
@@ -193,7 +196,8 @@ enum
PROP_REORDERABLE,
PROP_SORT_INDICATOR,
PROP_SORT_ORDER,
- PROP_SORT_COLUMN_ID
+ PROP_SORT_COLUMN_ID,
+ PROP_CELL_AREA
};
enum
@@ -251,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",
@@ -283,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,
@@ -380,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
**/
@@ -394,6 +408,24 @@ gtk_tree_view_column_class_init (GtkTreeViewColumnClass *class)
-1,
GTK_PARAM_READWRITE));
+ /**
+ * GtkTreeViewColumn:cell-area:
+ *
+ * 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,
+ PROP_CELL_AREA,
+ g_param_spec_object ("cell-area",
+ P_("Cell Area"),
+ P_("The GtkCellArea used to layout cells"),
+ GTK_TYPE_CELL_AREA,
+ GTK_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+
g_type_class_add_private (class, sizeof (GtkTreeViewColumnPrivate));
}
@@ -435,10 +467,9 @@ gtk_tree_view_column_init (GtkTreeViewColumn *tree_column)
priv->button = NULL;
priv->xalign = 0.0;
priv->width = 0;
- priv->requested_width = -1;
+ 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;
@@ -453,17 +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 ("");
+}
- priv->cell_area = gtk_cell_area_box_new ();
- gtk_cell_area_set_style_detail (priv->cell_area, "treeview");
- priv->cell_area_context = gtk_cell_area_create_context (priv->cell_area);
+static GObject *
+gtk_tree_view_column_constructor (GType type,
+ guint n_construct_properties,
+ GObjectConstructParam *construct_properties)
+{
+ GtkTreeViewColumn *tree_column;
+ GObject *object;
- priv->context_changed_signal =
- g_signal_connect (priv->cell_area_context, "notify",
- G_CALLBACK (gtk_tree_view_column_context_changed), tree_column);
+ object = G_OBJECT_CLASS (gtk_tree_view_column_parent_class)->constructor
+ (type, n_construct_properties, construct_properties);
+
+ tree_column = (GtkTreeViewColumn *) object;
+
+ gtk_tree_view_column_ensure_cell_area (tree_column, NULL);
return object;
}
@@ -474,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,
@@ -487,8 +531,15 @@ gtk_tree_view_column_dispose (GObject *object)
if (priv->cell_area)
{
+ g_signal_handler_disconnect (priv->cell_area,
+ 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;
+ priv->remove_editable_signal = 0;
}
if (priv->child)
@@ -609,9 +660,18 @@ gtk_tree_view_column_set_property (GObject *object,
area = g_value_get_object (value);
if (area)
- tree_column->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;
@@ -640,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));
@@ -716,7 +781,7 @@ gtk_tree_view_column_get_property (GObject *object,
break;
case PROP_CELL_AREA:
- g_value_set_object (value, tree_column->cell_area);
+ g_value_set_object (value, tree_column->priv->cell_area);
break;
default:
@@ -727,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;
}
@@ -753,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 ();
@@ -931,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)
@@ -994,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);
}
@@ -1192,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
@@ -1217,15 +1328,18 @@ gtk_tree_view_column_add_editable_callback (GtkCellArea *area,
GtkTreeViewColumnPrivate *priv = column->priv;
GtkTreePath *path;
- path = gtk_tree_path_new_from_string (path_string);
-
- _gtk_tree_view_add_editable (GTK_TREE_VIEW (priv->tree_view),
- column,
- path,
- edit_widget,
- cell_area);
-
- gtk_tree_path_free (path);
+ if (priv->tree_view)
+ {
+ path = gtk_tree_path_new_from_string (path_string);
+
+ _gtk_tree_view_add_editable (GTK_TREE_VIEW (priv->tree_view),
+ column,
+ path,
+ edit_widget,
+ cell_area);
+
+ gtk_tree_path_free (path);
+ }
}
static void
@@ -1237,9 +1351,10 @@ gtk_tree_view_column_remove_editable_callback (GtkCellArea *area,
GtkTreeViewColumn *column = user_data;
GtkTreeViewColumnPrivate *priv = column->priv;
- _gtk_tree_view_remove_editable (GTK_TREE_VIEW (priv->tree_view),
- column,
- edit_widget);
+ if (priv->tree_view)
+ _gtk_tree_view_remove_editable (GTK_TREE_VIEW (priv->tree_view),
+ column,
+ edit_widget);
}
/* Exported Private Functions.
@@ -1265,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));
@@ -1288,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
@@ -1305,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;
}
@@ -1336,15 +1448,6 @@ _gtk_tree_view_column_set_tree_view (GtkTreeViewColumn *column,
priv->tree_view = GTK_WIDGET (tree_view);
gtk_tree_view_column_create_button (column);
- 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->property_changed_signal =
g_signal_connect_swapped (tree_view,
"notify::model",
@@ -1417,6 +1520,90 @@ _gtk_tree_view_column_get_edited_cell (GtkTreeViewColumn *column)
return gtk_cell_area_get_edited_cell (priv->cell_area);
}
+GtkCellRenderer *
+_gtk_tree_view_column_get_cell_at_pos (GtkTreeViewColumn *column,
+ GdkRectangle *cell_area,
+ GdkRectangle *background_area,
+ gint x,
+ gint y)
+{
+ GtkCellRenderer *match = NULL;
+ GtkTreeViewColumnPrivate *priv = column->priv;
+
+ /* 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);
+
+ return match;
+}
+
+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;
+
+ match = _gtk_tree_view_column_get_cell_at_pos (column,
+ cell_area,
+ background_area,
+ x, y);
+ if (!match)
+ return FALSE;
+
+ 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 */
@@ -1438,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 using @area to render its cells.
*
- * Creates a new #GtkTreeViewColumn with a number of default values. This is
- * equivalent to calling gtk_tree_view_column_set_title(),
+ * 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.
*
@@ -1583,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,
@@ -1612,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
@@ -1705,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;
@@ -1716,7 +1924,7 @@ gtk_tree_view_column_set_visible (GtkTreeViewColumn *tree_column,
priv = tree_column->priv;
visible = !! visible;
-
+
if (priv->visible == visible)
return;
@@ -1725,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");
}
@@ -1820,16 +2035,6 @@ gtk_tree_view_column_set_sizing (GtkTreeViewColumn *tree_column,
if (type == GTK_TREE_VIEW_COLUMN_AUTOSIZE)
gtk_tree_view_column_set_resizable (tree_column, FALSE);
-#if 0
- /* I was clearly on crack when I wrote this. I'm not sure what's supposed to
- * be below so I'll leave it until I figure it out.
- */
- if (priv->column_type == GTK_TREE_VIEW_COLUMN_AUTOSIZE &&
- priv->requested_width != -1)
- {
- gtk_tree_view_column_set_sizing (tree_column, priv->requested_width);
- }
-#endif
priv->column_type = type;
gtk_tree_view_column_update_button (tree_column);
@@ -1869,69 +2074,98 @@ 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;
+ g_return_val_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column), 0);
- priv = tree_column->priv;
+ return tree_column->priv->x_offset;
+}
- 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;
+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 (priv->requested_width, button_request);
- }
- else
+ if (priv->column_type != GTK_TREE_VIEW_COLUMN_FIXED)
{
- real_requested_width = priv->requested_width;
- if (real_requested_width < 0)
- real_requested_width = 0;
+ gtk_cell_area_context_get_preferred_width (priv->cell_area_context, &minimum_width, &natural_width);
+ minimum_width += priv->padding;
+ natural_width += priv->padding;
+
+ 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
_gtk_tree_view_column_allocate (GtkTreeViewColumn *tree_column,
int x_offset,
- int width,
- int cell_width)
+ 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, cell_width, -1);
+ 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)
{
@@ -1942,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,
@@ -1963,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);
}
@@ -1982,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)
@@ -2181,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);
@@ -2191,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
@@ -2220,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);
}
@@ -2235,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
**/
@@ -2256,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,
@@ -2566,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.
@@ -2636,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.
@@ -2653,41 +2889,27 @@ gtk_tree_view_column_cell_get_size (GtkTreeViewColumn *tree_column,
gint *height)
{
GtkTreeViewColumnPrivate *priv;
- int focus_line_width;
+ gint min_width = 0, min_height = 0;
g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column));
priv = tree_column->priv;
- if (height)
- * height = 0;
- if (width)
- * width = 0;
-
- /* FIXME: This is a temporary hack to get things to allocate mostly right.
- *
- * We will add twice the focus-line-width to the for-width
- * parameter below. If we do not do this, the height returned is the
- * height for two lines of text instead of one. It feels like some lines
- * get less width than expected (due to subtraction of focus_line_width?)
- * and will unnecessarily wrap.
- */
- gtk_widget_style_get (priv->tree_view,
- "focus-line-width", &focus_line_width,
- NULL);
-
g_signal_handler_block (priv->cell_area_context,
priv->context_changed_signal);
gtk_cell_area_get_preferred_width (priv->cell_area,
priv->cell_area_context,
priv->tree_view,
- width, NULL);
+ NULL, NULL);
+
+ gtk_cell_area_context_get_preferred_width (priv->cell_area_context, &min_width, NULL);
+
gtk_cell_area_get_preferred_height_for_width (priv->cell_area,
priv->cell_area_context,
priv->tree_view,
- *width + focus_line_width * 2,
- height,
+ min_width,
+ &min_height,
NULL);
g_signal_handler_unblock (priv->cell_area_context,
@@ -2741,10 +2963,7 @@ _gtk_tree_view_column_cell_render (GtkTreeViewColumn *tree_column,
gboolean
_gtk_tree_view_column_cell_event (GtkTreeViewColumn *tree_column,
- GtkCellEditable **editable_widget,
GdkEvent *event,
- gchar *path_string,
- const GdkRectangle *background_area,
const GdkRectangle *cell_area,
guint flags)
{
@@ -2754,20 +2973,6 @@ _gtk_tree_view_column_cell_event (GtkTreeViewColumn *tree_column,
priv = tree_column->priv;
- /* FIXME: Should we pass background area here as well?
- * What will happen to the path_string and editable widget
- * variables?
- *
- * Answer, No dont pass background area... editable widgets
- * grab the pointer and keyboard so the treeview doesnt
- * recieve these events while editable widgets are editing.
- *
- * Also it's important that gtk_cell_area_apply_attributes be
- * called before passing the event to the cell (maybe we need to
- * instead use the path_string here to apply the attributes ?,
- * if the attributes are applied, the underlying CellArea knows
- * the path string, which is expected when handling events).
- */
return gtk_cell_area_event (priv->cell_area,
priv->cell_area_context,
priv->tree_view,
@@ -2776,76 +2981,6 @@ _gtk_tree_view_column_cell_event (GtkTreeViewColumn *tree_column,
flags);
}
-void
-_gtk_tree_view_column_get_focus_area (GtkTreeViewColumn *tree_column,
- const GdkRectangle *background_area,
- const GdkRectangle *cell_area,
- GdkRectangle *focus_area)
-{
- /* FIXME */
-#if 0
- gtk_tree_view_column_cell_process_action (tree_column,
- NULL,
- background_area,
- cell_area,
- 0,
- CELL_ACTION_FOCUS,
- focus_area,
- NULL, NULL, NULL);
-#endif
-}
-
-
-gboolean
-_gtk_tree_view_column_cell_focus (GtkTreeViewColumn *tree_column,
- gint count,
- gboolean left,
- gboolean right)
-{
- gboolean rtl;
- GtkDirectionType direction = 0;
- GtkTreeViewColumnPrivate *priv = tree_column->priv;
-
- rtl = gtk_widget_get_direction (priv->tree_view) == GTK_TEXT_DIR_RTL;
-
- switch (count)
- {
- case -1:
- direction = GTK_DIR_LEFT;
- break;
-
- case 1:
- direction = GTK_DIR_RIGHT;
- break;
- }
-
- /* if we are the current focus column and have multiple editable cells,
- * try to select the next one, else move the focus to the next column
- */
- if (_gtk_tree_view_get_focus_column (GTK_TREE_VIEW (priv->tree_view)) == tree_column)
- {
- if (gtk_cell_area_focus (priv->cell_area, direction))
- /* Focus stays in this column, so we are done */
- return TRUE;
-
- /* FIXME: RTL support for the following: */
- if (count == -1 && !left)
- {
- direction = GTK_DIR_RIGHT;
- gtk_cell_area_focus (priv->cell_area, direction);
- }
- else if (count == 1 && !right)
- {
- direction = GTK_DIR_LEFT;
- gtk_cell_area_focus (priv->cell_area, direction);
- }
-
- return FALSE;
- }
-
- return gtk_cell_area_focus (priv->cell_area, direction);
-}
-
/**
* gtk_tree_view_column_cell_is_visible:
* @tree_column: A #GtkTreeViewColumn
@@ -2909,9 +3044,18 @@ _gtk_tree_view_column_cell_set_dirty (GtkTreeViewColumn *tree_column,
GtkTreeViewColumnPrivate *priv = tree_column->priv;
priv->dirty = TRUE;
- priv->requested_width = -1;
+ 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))
{
@@ -2930,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
- * @start_pos: 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
@@ -2943,11 +3088,11 @@ _gtk_tree_view_column_cell_get_dirty (GtkTreeViewColumn *tree_column)
gboolean
gtk_tree_view_column_cell_get_position (GtkTreeViewColumn *tree_column,
GtkCellRenderer *cell_renderer,
- gint *start_pos,
+ gint *x_offset,
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);
@@ -2955,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 (start_pos)
- *start_pos = allocation.x;
+ if (x_offset)
+ *x_offset = allocation.x - cell_area.x;
+
if (width)
*width = allocation.width;
@@ -3035,42 +3186,20 @@ _gtk_tree_view_column_get_window (GtkTreeViewColumn *column)
}
void
-_gtk_tree_view_column_set_requested_width (GtkTreeViewColumn *column,
- gint width)
+_gtk_tree_view_column_push_padding (GtkTreeViewColumn *column,
+ gint padding)
{
- column->priv->requested_width = width;
+ column->priv->padding = MAX (column->priv->padding, padding);
}
gint
_gtk_tree_view_column_get_requested_width (GtkTreeViewColumn *column)
{
- return column->priv->requested_width;
-}
-
-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;
-}
+ gint requested_width;
-void
-_gtk_tree_view_column_set_use_resized_width (GtkTreeViewColumn *column,
- gboolean use_resized_width)
-{
- column->priv->use_resized_width = use_resized_width;
-}
+ gtk_cell_area_context_get_preferred_width (column->priv->cell_area_context, &requested_width, NULL);
-gboolean
-_gtk_tree_view_column_get_use_resized_width (GtkTreeViewColumn *column)
-{
- return column->priv->use_resized_width;
+ return requested_width + column->priv->padding;
}
gint