summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gtk/gtkcellarea.h2
-rw-r--r--gtk/gtkcellareabox.c697
-rw-r--r--gtk/gtkcellareabox.h9
-rw-r--r--gtk/gtkcellareaboxiter.c302
-rw-r--r--gtk/gtkcellareaboxiter.h102
-rw-r--r--gtk/gtkcellareaiter.c226
-rw-r--r--gtk/gtkcellareaiter.h100
7 files changed, 978 insertions, 460 deletions
diff --git a/gtk/gtkcellarea.h b/gtk/gtkcellarea.h
index 5a9c770f71..9d4b16d5b4 100644
--- a/gtk/gtkcellarea.h
+++ b/gtk/gtkcellarea.h
@@ -31,7 +31,6 @@
#include <gtk/gtkcellrenderer.h>
#include <gtk/gtkwidget.h>
#include <gtk/gtktreemodel.h>
-#include <gtk/gtkcellareaiter.h>
G_BEGIN_DECLS
@@ -45,6 +44,7 @@ G_BEGIN_DECLS
typedef struct _GtkCellArea GtkCellArea;
typedef struct _GtkCellAreaClass GtkCellAreaClass;
typedef struct _GtkCellAreaPrivate GtkCellAreaPrivate;
+typedef struct _GtkCellAreaIter GtkCellAreaIter;
/**
* GtkCellCallback:
diff --git a/gtk/gtkcellareabox.c b/gtk/gtkcellareabox.c
index 511e8a0565..f1a7cc1ea9 100644
--- a/gtk/gtkcellareabox.c
+++ b/gtk/gtkcellareabox.c
@@ -97,20 +97,37 @@ static void gtk_cell_area_box_layout_reorder (GtkCellLayout
gint position);
-/* CellInfo metadata handling */
+/* CellInfo/CellGroup metadata handling */
typedef struct {
GtkCellRenderer *renderer;
- guint expand : 1;
- guint pack : 1;
+ guint expand : 1; /* Whether the cell expands */
+ guint pack : 1; /* Whether the cell is packed from the start or end */
+ guint align : 1; /* Whether to align this cell's position with adjacent rows */
} CellInfo;
-static CellInfo *cell_info_new (GtkCellRenderer *renderer,
- gboolean expand,
- GtkPackType pack);
-static void cell_info_free (CellInfo *info);
-static gint cell_info_find (CellInfo *info,
- GtkCellRenderer *renderer);
+typedef struct {
+ GList *cells;
+
+ guint id : 16;
+ guint expand : 1;
+} CellGroup;
+
+static CellInfo *cell_info_new (GtkCellRenderer *renderer,
+ GtkPackType pack,
+ gboolean expand,
+ gboolean align);
+static void cell_info_free (CellInfo *info);
+static gint cell_info_find (CellInfo *info,
+ GtkCellRenderer *renderer);
+
+static CellGroup *cell_group_new (guint id);
+static void cell_group_free (CellGroup *group);
+
+static GList *list_consecutive_cells (GtkCellAreaBox *box);
+static GList *construct_cell_groups (GtkCellAreaBox *box);
+static gint count_expand_groups (GtkCellAreaBox *box);
+static gint count_expand_cells (CellGroup *group);
struct _GtkCellAreaBoxPrivate
@@ -118,17 +135,15 @@ struct _GtkCellAreaBoxPrivate
GtkOrientation orientation;
GList *cells;
+ GList *groups;
gint spacing;
-
- guint align_cells : 1;
};
enum {
PROP_0,
PROP_ORIENTATION,
- PROP_SPACING,
- PROP_ALIGN_CELLS
+ PROP_SPACING
};
G_DEFINE_TYPE_WITH_CODE (GtkCellAreaBox, gtk_cell_area_box, GTK_TYPE_CELL_AREA,
@@ -136,6 +151,10 @@ G_DEFINE_TYPE_WITH_CODE (GtkCellAreaBox, gtk_cell_area_box, GTK_TYPE_CELL_AREA,
gtk_cell_area_box_cell_layout_init)
G_IMPLEMENT_INTERFACE (GTK_TYPE_ORIENTABLE, NULL));
+#define OPPOSITE_ORIENTATION(orientation) \
+ ((orientation) == GTK_ORIENTATION_HORIZONTAL ? \
+ GTK_ORIENTATION_VERTICAL : GTK_ORIENTATION_HORIZONTAL)
+
static void
gtk_cell_area_box_init (GtkCellAreaBox *box)
{
@@ -148,8 +167,8 @@ gtk_cell_area_box_init (GtkCellAreaBox *box)
priv->orientation = GTK_ORIENTATION_HORIZONTAL;
priv->cells = NULL;
+ priv->groups = NULL;
priv->spacing = 0;
- priv->align_cells = TRUE;
}
static void
@@ -190,32 +209,25 @@ gtk_cell_area_box_class_init (GtkCellAreaBoxClass *class)
0,
GTK_PARAM_READWRITE));
- g_object_class_install_property (object_class,
- PROP_ALIGN_CELLS,
- g_param_spec_boolean ("align-cells",
- P_("Align Cells"),
- P_("Whether cells should be aligned with those "
- "rendered in adjacent rows"),
- TRUE,
- GTK_PARAM_READWRITE));
-
g_type_class_add_private (object_class, sizeof (GtkCellAreaBoxPrivate));
}
/*************************************************************
- * CellInfo Basics *
+ * CellInfo/CellGroup Basics *
*************************************************************/
static CellInfo *
cell_info_new (GtkCellRenderer *renderer,
+ GtkPackType pack,
gboolean expand,
- GtkPackType pack)
+ gboolean align)
{
CellInfo *info = g_slice_new (CellInfo);
info->renderer = g_object_ref_sink (renderer);
- info->expand = expand;
info->pack = pack;
+ info->expand = expand;
+ info->align = align;
return info;
}
@@ -235,6 +247,139 @@ cell_info_find (CellInfo *info,
return (info->renderer == renderer) ? 0 : -1;
}
+static CellGroup *
+cell_group_new (guint id)
+{
+ CellGroup *group = g_slice_new0 (CellGroup);
+
+ group->id = id;
+
+ return group;
+}
+
+static void
+cell_group_free (CellGroup *group)
+{
+ g_list_free (group->cells);
+ g_slice_free (CellGroup, group);
+}
+
+static GList *
+list_consecutive_cells (GtkCellAreaBox *box)
+{
+ GtkCellAreaBoxPrivate *priv = box->priv;
+ GList *l, *consecutive_cells = NULL, *pack_end_cells = NULL;
+ CellInfo *info;
+
+ /* List cells in consecutive order taking their
+ * PACK_START/PACK_END options into account
+ */
+ for (l = priv->cells; l; l = l->next)
+ {
+ info = l->data;
+
+ if (info->pack == GTK_PACK_START)
+ consecutive_cells = g_list_prepend (consecutive_cells, info);
+ }
+
+ for (l = priv->cells; l; l = l->next)
+ {
+ info = l->data;
+
+ if (info->pack == GTK_PACK_END)
+ pack_end_cells = g_list_prepend (pack_end_cells, info);
+ }
+
+ consecutive_cells = g_list_reverse (consecutive_cells);
+ consecutive_cells = g_list_concat (consecutive_cells, pack_end_cells);
+
+ return consecutive_cells;
+}
+
+static GList *
+construct_cell_groups (GtkCellAreaBox *box)
+{
+ GtkCellAreaBoxPrivate *priv = box->priv;
+ CellGroup *group;
+ GList *cells, *l;
+ GList *groups = NULL;
+ guint id = 0;
+
+ if (!priv->cells)
+ return NULL;
+
+ cells = list_consecutive_cells (box);
+ group = cell_group_new (id++);
+ groups = g_list_prepend (groups, group);
+
+ for (l = cells; l; l = l->next)
+ {
+ CellInfo *info = l->data;
+
+ /* A new group starts with any aligned cell, the first group is implied */
+ if (info->align && l != cells)
+ {
+ group = cell_group_new (id++);
+ groups = g_list_prepend (groups, group);
+ }
+
+ group->cells = g_list_prepend (group->cells, info);
+
+ /* A group expands if it contains any expand cells */
+ if (info->expand)
+ group->expand = TRUE;
+ }
+
+ g_list_free (cells);
+
+ for (l = cells; l; l = l->next)
+ {
+ group = l->data;
+ group->cells = g_list_reverse (group->cells);
+ }
+
+ return g_list_reverse (groups);
+}
+
+static gint
+count_expand_groups (GtkCellAreaBox *box)
+{
+ GtkCellAreaBoxPrivate *priv = box->priv;
+ GList *l;
+ gint expand_groups = 0;
+
+ for (l = priv->groups; l; l = l->next)
+ {
+ CellGroup *group = l->data;
+
+ if (group->expand)
+ expand_groups++;
+ }
+
+ return expand_groups;
+}
+
+static gint
+count_expand_cells (CellGroup *group)
+{
+ GList *l;
+ gint expand_cells = 0;
+
+ if (!group->expand)
+ return 0;
+
+ for (l = group->cells; l; l = l->next)
+ {
+ CellInfo *info = l->data;
+
+ if (info->expand)
+ expand_cells++;
+ }
+
+ return expand_cells;
+}
+
+
/*************************************************************
* GObjectClass *
*************************************************************/
@@ -256,7 +401,17 @@ gtk_cell_area_box_set_property (GObject *object,
const GValue *value,
GParamSpec *pspec)
{
+ GtkCellAreaBox *box = GTK_CELL_AREA_BOX (object);
+ switch (prop_id)
+ {
+ case PROP_SPACING:
+ gtk_cell_area_box_set_spacing (box, g_value_get_int (value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
}
static void
@@ -265,7 +420,17 @@ gtk_cell_area_box_get_property (GObject *object,
GValue *value,
GParamSpec *pspec)
{
+ GtkCellAreaBox *box = GTK_CELL_AREA_BOX (object);
+ switch (prop_id)
+ {
+ case PROP_SPACING:
+ g_value_set_int (value, gtk_cell_area_box_get_spacing (box));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
}
/*************************************************************
@@ -276,7 +441,7 @@ gtk_cell_area_box_add (GtkCellArea *area,
GtkCellRenderer *renderer)
{
gtk_cell_area_box_pack_start (GTK_CELL_AREA_BOX (area),
- renderer, FALSE);
+ renderer, FALSE, TRUE);
}
static void
@@ -297,6 +462,16 @@ gtk_cell_area_box_remove (GtkCellArea *area,
cell_info_free (info);
priv->cells = g_list_delete_link (priv->cells, node);
+
+ /* Reconstruct cell groups
+ * XXX TODO: add a list of iters and weak_ref's on them, then
+ * flush the iters when we reconstruct groups, change spacing
+ * or child expand properties (i.e. notify size needs to be
+ * recalculated).
+ */
+ g_list_foreach (priv->groups, (GFunc)cell_group_free, NULL);
+ g_list_free (priv->groups);
+ priv->groups = construct_cell_groups (box);
}
else
g_warning ("Trying to remove a cell renderer that is not present GtkCellAreaBox");
@@ -387,137 +562,279 @@ compute_size (GtkCellAreaBox *box,
GtkOrientation orientation,
GtkCellAreaBoxIter *iter,
GtkWidget *widget,
+ gint for_size,
gint *minimum_size,
gint *natural_size)
{
GtkCellAreaBoxPrivate *priv = box->priv;
+ CellGroup *group;
CellInfo *info;
- GList *l;
+ GList *cell_list, *group_list;
gint min_size = 0;
gint nat_size = 0;
- gboolean first_cell = TRUE;
- for (l = priv->cells; l; l = l->next)
+ for (group_list = priv->groups; group_list; group_list = group_list->next)
{
- gint renderer_min_size, renderer_nat_size;
-
- info = l->data;
+ gint group_min_size = 0;
+ gint group_nat_size = 0;
- get_renderer_size (info->renderer, orientation, widget, -1,
- &renderer_min_size, &renderer_nat_size);
+ group = group_list->data;
- /* If we're aligning the cells we need to cache the max results
- * for all requests performed with the same iter.
- */
- if (priv->align_cells)
+ for (cell_list = group->cells; cell_list; cell_list = cell_list->next)
{
- if (orientation == GTK_ORIENTATION_HORIZONTAL)
- gtk_cell_area_box_iter_push_cell_width (iter, info->renderer,
- renderer_min_size, renderer_nat_size);
+ gint renderer_min_size, renderer_nat_size;
+
+ info = cell_list->data;
+
+ get_renderer_size (info->renderer, orientation, widget, for_size,
+ &renderer_min_size, &renderer_nat_size);
+
+ if (orientation == priv->orientation)
+ {
+ if (min_size > 0)
+ {
+ min_size += priv->spacing;
+ nat_size += priv->spacing;
+ }
+
+ if (group_min_size > 0)
+ {
+ group_min_size += priv->spacing;
+ group_nat_size += priv->spacing;
+ }
+
+ min_size += renderer_min_size;
+ nat_size += renderer_nat_size;
+ group_min_size += renderer_min_size;
+ group_nat_size += renderer_nat_size;
+ }
else
- gtk_cell_area_box_iter_push_cell_height (iter, info->renderer,
- renderer_min_size, renderer_nat_size);
+ {
+ min_size = MAX (min_size, renderer_min_size);
+ nat_size = MAX (nat_size, renderer_nat_size);
+ group_min_size = MAX (group_min_size, renderer_min_size);
+ group_nat_size = MAX (group_nat_size, renderer_nat_size);
+ }
}
- if (orientation == priv->orientation)
+ if (orientation == GTK_ORIENTATION_HORIZONTAL)
{
- min_size += renderer_min_size;
- nat_size += renderer_nat_size;
-
- if (!first_cell)
- {
- min_size += priv->spacing;
- nat_size += priv->spacing;
- }
+ if (for_size < 0)
+ gtk_cell_area_box_iter_push_group_width (iter, group->id, group_min_size, group_nat_size);
+ else
+ gtk_cell_area_box_iter_push_group_width_for_height (iter, group->id, for_size,
+ group_min_size, group_nat_size);
}
else
{
- min_size = MAX (min_size, renderer_min_size);
- nat_size = MAX (nat_size, renderer_nat_size);
+ if (for_size < 0)
+ gtk_cell_area_box_iter_push_group_height (iter, group->id, group_min_size, group_nat_size);
+ else
+ gtk_cell_area_box_iter_push_group_height_for_width (iter, group->id, for_size,
+ group_min_size, group_nat_size);
}
-
- if (first_cell)
- first_cell = FALSE;
}
*minimum_size = min_size;
*natural_size = nat_size;
}
+GtkRequestedSize *
+get_group_sizes (CellGroup *group,
+ GtkOrientation orientation,
+ GtkWidget *widget,
+ gint *n_sizes)
+{
+ GtkRequestedSize *sizes;
+ GList *l;
+ gint i;
+
+ *n_sizes = g_list_length (group->cells);
+ sizes = g_new (GtkRequestedSize, *n_sizes);
+
+ for (l = group->cells, i = 0; l; l = l->next, i++)
+ {
+ CellInfo *info = l->data;
+
+ sizes[i].data = info;
+
+ get_renderer_size (info->renderer,
+ orientation, widget, -1,
+ &sizes[i].minimum_size,
+ &sizes[i].natural_size);
+ }
+
+ return sizes;
+}
+
static void
-update_iter_aligned (GtkCellAreaBox *box,
- GtkCellAreaBoxIter *iter,
- gint for_size)
+compute_group_size_for_opposing_orientation (GtkCellAreaBox *box,
+ CellGroup *group,
+ GtkWidget *widget,
+ gint for_size,
+ gint *minimum_size,
+ gint *natural_size)
{
GtkCellAreaBoxPrivate *priv = box->priv;
- CellInfo *info;
- GList *l;
- gint min_size = 0;
- gint nat_size = 0;
- gboolean first_cell = TRUE;
- for (l = priv->cells; l; l = l->next)
+ /* Exception for single cell groups */
+ if (!group->cells->next)
{
- gint aligned_min_size, aligned_nat_size;
-
- info = l->data;
+ CellInfo *info = group->cells->data;
- if (priv->orientation == GTK_ORIENTATION_HORIZONTAL)
+ get_renderer_size (info->renderer,
+ OPPOSITE_ORIENTATION (priv->orientation),
+ widget, for_size, minimum_size, natural_size);
+ }
+ else
+ {
+ GtkRequestedSize *orientation_sizes;
+ CellInfo *info;
+ gint n_sizes, i;
+ gint n_expand_cells = count_expand_cells (group);
+ gint avail_size = for_size;
+ gint extra_size, extra_extra;
+ gint min_size = 0, nat_size = 0;
+
+ orientation_sizes = get_group_sizes (group, priv->orientation, widget, &n_sizes);
+
+ /* First naturally allocate the cells in the group into the for_size */
+ avail_size -= (n_sizes - 1) * priv->spacing;
+ for (i = 0; i < n_sizes; i++)
+ avail_size -= orientation_sizes[i].minimum_size;
+
+ avail_size = gtk_distribute_natural_allocation (avail_size, n_sizes, orientation_sizes);
+
+ /* Calculate/distribute expand for cells */
+ if (n_expand_cells > 0)
{
- if (for_size < 0)
- gtk_cell_area_box_iter_get_cell_width (iter, info->renderer,
- &aligned_min_size,
- &aligned_nat_size);
- else
- gtk_cell_area_box_iter_get_cell_width_for_height (iter, info->renderer,
- for_size,
- &aligned_min_size,
- &aligned_nat_size);
+ extra_size = avail_size / n_expand_cells;
+ extra_extra = avail_size % n_expand_cells;
}
else
- {
- if (for_size < 0)
- gtk_cell_area_box_iter_get_cell_height (iter, info->renderer,
- &aligned_min_size,
- &aligned_nat_size);
- else
- gtk_cell_area_box_iter_get_cell_height_for_width (iter, info->renderer,
- for_size,
- &aligned_min_size,
- &aligned_nat_size);
- }
+ extra_size = extra_extra = 0;
- min_size += aligned_min_size;
- nat_size += aligned_nat_size;
-
- if (!first_cell)
+ for (i = 0; i < n_sizes; i++)
{
- min_size += priv->spacing;
- nat_size += priv->spacing;
+ gint cell_min, cell_nat;
+
+ info = orientation_sizes[i].data;
+
+ if (info->expand)
+ {
+ orientation_sizes[i].minimum_size += extra_size;
+ if (extra_extra)
+ {
+ orientation_sizes[i].minimum_size++;
+ extra_extra--;
+ }
+ }
+
+ get_renderer_size (info->renderer,
+ OPPOSITE_ORIENTATION (priv->orientation),
+ widget,
+ orientation_sizes[i].minimum_size,
+ &cell_min, &cell_nat);
+
+ min_size = MAX (min_size, cell_min);
+ nat_size = MAX (nat_size, cell_nat);
}
-
- if (first_cell)
- first_cell = FALSE;
+
+ *minimum_size = min_size;
+ *natural_size = nat_size;
+
+ g_free (orientation_sizes);
}
+}
+
+static void
+compute_size_for_opposing_orientation (GtkCellAreaBox *box,
+ GtkCellAreaBoxIter *iter,
+ GtkWidget *widget,
+ gint for_size,
+ gint *minimum_size,
+ gint *natural_size)
+{
+ GtkCellAreaBoxPrivate *priv = box->priv;
+ CellGroup *group;
+ GList *group_list;
+ GtkRequestedSize *orientation_sizes;
+ gint n_groups, n_expand_groups, i;
+ gint avail_size = for_size;
+ gint extra_size, extra_extra;
+ gint min_size = 0, nat_size = 0;
+
+ n_expand_groups = count_expand_groups (box);
if (priv->orientation == GTK_ORIENTATION_HORIZONTAL)
+ orientation_sizes = gtk_cell_area_box_iter_get_widths (iter, &n_groups);
+ else
+ orientation_sizes = gtk_cell_area_box_iter_get_heights (iter, &n_groups);
+
+ /* First start by naturally allocating space among groups of cells */
+ avail_size -= (n_groups - 1) * priv->spacing;
+ for (i = 0; i < n_groups; i++)
+ avail_size -= orientation_sizes[i].minimum_size;
+
+ avail_size = gtk_distribute_natural_allocation (avail_size, n_groups, orientation_sizes);
+
+ /* Calculate/distribute expand for groups */
+ if (n_expand_groups > 0)
{
- if (for_size < 0)
- gtk_cell_area_iter_push_preferred_width (GTK_CELL_AREA_ITER (iter), min_size, nat_size);
- else
- gtk_cell_area_iter_push_preferred_width_for_height (GTK_CELL_AREA_ITER (iter),
- for_size, min_size, nat_size);
+ extra_size = avail_size / n_expand_groups;
+ extra_extra = avail_size % n_expand_groups;
}
else
+ extra_size = extra_extra = 0;
+
+ /* Now we need to naturally allocate sizes for cells in each group
+ * and push the height-for-width for each group accordingly while accumulating
+ * the overall height-for-width for this row.
+ */
+ for (group_list = priv->groups; group_list; group_list = group_list->next)
{
- if (for_size < 0)
- gtk_cell_area_iter_push_preferred_height (GTK_CELL_AREA_ITER (iter), min_size, nat_size);
+ gint group_min, group_nat;
+
+ group = group_list->data;
+
+ if (group->expand)
+ {
+ orientation_sizes[group->id].minimum_size += extra_size;
+ if (extra_extra)
+ {
+ orientation_sizes[group->id].minimum_size++;
+ extra_extra--;
+ }
+ }
+
+ /* Now we have the allocation for the group, request it's height-for-width */
+ compute_group_size_for_opposing_orientation (box, group, widget,
+ orientation_sizes[group->id].minimum_size,
+ &group_min, &group_nat);
+
+ min_size = MAX (min_size, group_min);
+ nat_size = MAX (nat_size, group_nat);
+
+ if (priv->orientation == GTK_ORIENTATION_HORIZONTAL)
+ {
+ gtk_cell_area_box_iter_push_group_height_for_width (iter, group->id, for_size,
+ group_min, group_nat);
+ }
else
- gtk_cell_area_iter_push_preferred_height_for_width (GTK_CELL_AREA_ITER (iter),
- for_size, min_size, nat_size);
+ {
+ gtk_cell_area_box_iter_push_group_width_for_height (iter, group->id, for_size,
+ group_min, group_nat);
+ }
}
+
+ *minimum_size = min_size;
+ *natural_size = nat_size;
+
+ g_free (orientation_sizes);
}
+
+
static void
gtk_cell_area_box_get_preferred_width (GtkCellArea *area,
GtkCellAreaIter *iter,
@@ -527,25 +844,16 @@ gtk_cell_area_box_get_preferred_width (GtkCellArea *area,
{
GtkCellAreaBox *box = GTK_CELL_AREA_BOX (area);
GtkCellAreaBoxIter *box_iter;
- GtkCellAreaBoxPrivate *priv;
gint min_width, nat_width;
g_return_if_fail (GTK_IS_CELL_AREA_BOX_ITER (iter));
box_iter = GTK_CELL_AREA_BOX_ITER (iter);
- priv = box->priv;
- /* Compute the size of all renderers for current row data, possibly
+ /* Compute the size of all renderers for current row data,
* bumping cell alignments in the iter along the way */
compute_size (box, GTK_ORIENTATION_HORIZONTAL,
- box_iter, widget, &min_width, &nat_width);
-
- /* Update width of the iter based on aligned cell sizes if
- * appropriate */
- if (priv->align_cells && priv->orientation == GTK_ORIENTATION_HORIZONTAL)
- update_iter_aligned (box, box_iter, -1);
- else
- gtk_cell_area_iter_push_preferred_width (iter, min_width, nat_width);
+ box_iter, widget, -1, &min_width, &nat_width);
if (minimum_width)
*minimum_width = min_width;
@@ -563,25 +871,16 @@ gtk_cell_area_box_get_preferred_height (GtkCellArea *area,
{
GtkCellAreaBox *box = GTK_CELL_AREA_BOX (area);
GtkCellAreaBoxIter *box_iter;
- GtkCellAreaBoxPrivate *priv;
gint min_height, nat_height;
g_return_if_fail (GTK_IS_CELL_AREA_BOX_ITER (iter));
box_iter = GTK_CELL_AREA_BOX_ITER (iter);
- priv = box->priv;
- /* Compute the size of all renderers for current row data, possibly
+ /* Compute the size of all renderers for current row data,
* bumping cell alignments in the iter along the way */
compute_size (box, GTK_ORIENTATION_VERTICAL,
- box_iter, widget, &min_height, &nat_height);
-
- /* Update width of the iter based on aligned cell sizes if
- * appropriate */
- if (priv->align_cells && priv->orientation == GTK_ORIENTATION_VERTICAL)
- update_iter_aligned (box, box_iter, -1);
- else
- gtk_cell_area_iter_push_preferred_height (iter, min_height, nat_height);
+ box_iter, widget, -1, &min_height, &nat_height);
if (minimum_height)
*minimum_height = min_height;
@@ -591,61 +890,6 @@ gtk_cell_area_box_get_preferred_height (GtkCellArea *area,
}
static void
-compute_size_for_orientation (GtkCellAreaBox *box,
- GtkCellAreaBoxIter *iter,
- GtkWidget *widget,
- gint for_size,
- gint *minimum_size,
- gint *natural_size)
-{
- GtkCellAreaBoxPrivate *priv = box->priv;
- CellInfo *info;
- GList *l;
- gint min_size = 0;
- gint nat_size = 0;
- gboolean first_cell = TRUE;
-
- for (l = priv->cells; l; l = l->next)
- {
- gint renderer_min_size, renderer_nat_size;
-
- info = l->data;
-
- get_renderer_size (info->renderer, priv->orientation, widget, for_size,
- &renderer_min_size, &renderer_nat_size);
-
- /* If we're aligning the cells we need to cache the max results
- * for all requests performed with the same iter.
- */
- if (priv->align_cells)
- {
- if (priv->orientation == GTK_ORIENTATION_HORIZONTAL)
- gtk_cell_area_box_iter_push_cell_width_for_height (iter, info->renderer, for_size,
- renderer_min_size, renderer_nat_size);
- else
- gtk_cell_area_box_iter_push_cell_height_for_width (iter, info->renderer, for_size,
- renderer_min_size, renderer_nat_size);
- }
-
- min_size += renderer_min_size;
- nat_size += renderer_nat_size;
-
- if (!first_cell)
- {
- min_size += priv->spacing;
- nat_size += priv->spacing;
- }
-
- if (first_cell)
- first_cell = FALSE;
- }
-
- *minimum_size = min_size;
- *natural_size = nat_size;
-}
-
-
-static void
gtk_cell_area_box_get_preferred_height_for_width (GtkCellArea *area,
GtkCellAreaIter *iter,
GtkWidget *widget,
@@ -665,21 +909,15 @@ gtk_cell_area_box_get_preferred_height_for_width (GtkCellArea *area,
if (priv->orientation == GTK_ORIENTATION_VERTICAL)
{
- /* Add up vertical requests of height for width and possibly push the overall
+ /* Add up vertical requests of height for width and push the overall
* cached sizes for alignments */
- compute_size_for_orientation (box, box_iter, widget, width, &min_height, &nat_height);
-
- /* Update the overall cached height for width based on aligned cells if appropriate */
- if (priv->align_cells)
- update_iter_aligned (box, box_iter, width);
- else
- gtk_cell_area_iter_push_preferred_height_for_width (GTK_CELL_AREA_ITER (iter),
- width, min_height, nat_height);
+ compute_size (box, priv->orientation, box_iter, widget, width, &min_height, &nat_height);
}
else
{
- /* XXX Juice: virtually allocate cells into the for_width possibly using the
+ /* Juice: virtually allocate cells into the for_width using the
* alignments and then return the overall height for that width, and cache it */
+ compute_size_for_opposing_orientation (box, box_iter, widget, width, &min_height, &nat_height);
}
if (minimum_height)
@@ -709,21 +947,15 @@ gtk_cell_area_box_get_preferred_width_for_height (GtkCellArea *area,
if (priv->orientation == GTK_ORIENTATION_HORIZONTAL)
{
- /* Add up vertical requests of height for width and possibly push the overall
+ /* Add up horizontal requests of width for height and push the overall
* cached sizes for alignments */
- compute_size_for_orientation (box, box_iter, widget, height, &min_width, &nat_width);
-
- /* Update the overall cached height for width based on aligned cells if appropriate */
- if (priv->align_cells)
- update_iter_aligned (box, box_iter, height);
- else
- gtk_cell_area_iter_push_preferred_height_for_width (GTK_CELL_AREA_ITER (iter),
- height, min_width, nat_width);
+ compute_size (box, priv->orientation, box_iter, widget, height, &min_width, &nat_width);
}
else
{
- /* XXX Juice: virtually allocate cells into the for_width possibly using the
- * alignments and then return the overall height for that width, and cache it */
+ /* Juice: horizontally allocate cells into the for_height using the
+ * alignments and then return the overall width for that height, and cache it */
+ compute_size_for_opposing_orientation (box, box_iter, widget, height, &min_width, &nat_width);
}
if (minimum_width)
@@ -750,7 +982,7 @@ gtk_cell_area_box_layout_pack_start (GtkCellLayout *cell_layout,
GtkCellRenderer *renderer,
gboolean expand)
{
- gtk_cell_area_box_pack_start (GTK_CELL_AREA_BOX (cell_layout), renderer, expand);
+ gtk_cell_area_box_pack_start (GTK_CELL_AREA_BOX (cell_layout), renderer, expand, TRUE);
}
static void
@@ -758,7 +990,7 @@ gtk_cell_area_box_layout_pack_end (GtkCellLayout *cell_layout,
GtkCellRenderer *renderer,
gboolean expand)
{
- gtk_cell_area_box_pack_end (GTK_CELL_AREA_BOX (cell_layout), renderer, expand);
+ gtk_cell_area_box_pack_end (GTK_CELL_AREA_BOX (cell_layout), renderer, expand, TRUE);
}
static void
@@ -795,7 +1027,8 @@ gtk_cell_area_box_new (void)
void
gtk_cell_area_box_pack_start (GtkCellAreaBox *box,
GtkCellRenderer *renderer,
- gboolean expand)
+ gboolean expand,
+ gboolean align)
{
GtkCellAreaBoxPrivate *priv;
CellInfo *info;
@@ -812,15 +1045,21 @@ gtk_cell_area_box_pack_start (GtkCellAreaBox *box,
return;
}
- info = cell_info_new (renderer, expand, GTK_PACK_START);
+ info = cell_info_new (renderer, GTK_PACK_START, expand, align);
priv->cells = g_list_append (priv->cells, info);
+
+ /* Reconstruct cell groups (TODO, notify created iters that size needs renegotiation) */
+ g_list_foreach (priv->groups, (GFunc)cell_group_free, NULL);
+ g_list_free (priv->groups);
+ priv->groups = construct_cell_groups (box);
}
void
gtk_cell_area_box_pack_end (GtkCellAreaBox *box,
GtkCellRenderer *renderer,
- gboolean expand)
+ gboolean expand,
+ gboolean align)
{
GtkCellAreaBoxPrivate *priv;
CellInfo *info;
@@ -837,9 +1076,14 @@ gtk_cell_area_box_pack_end (GtkCellAreaBox *box,
return;
}
- info = cell_info_new (renderer, expand, GTK_PACK_END);
+ info = cell_info_new (renderer, GTK_PACK_END, expand, align);
priv->cells = g_list_append (priv->cells, info);
+
+ /* Reconstruct cell groups (TODO, notify created iters that size needs renegotiation) */
+ g_list_foreach (priv->groups, (GFunc)cell_group_free, NULL);
+ g_list_free (priv->groups);
+ priv->groups = construct_cell_groups (box);
}
gint
@@ -864,32 +1108,7 @@ gtk_cell_area_box_set_spacing (GtkCellAreaBox *box,
{
priv->spacing = spacing;
+ /* TODO, notify created iters that size needs renegotiation */
g_object_notify (G_OBJECT (box), "spacing");
}
}
-
-gboolean
-gtk_cell_area_box_get_align_cells (GtkCellAreaBox *box)
-{
- g_return_val_if_fail (GTK_IS_CELL_AREA_BOX (box), FALSE);
-
- return box->priv->align_cells;
-}
-
-void
-gtk_cell_area_box_set_align_cells (GtkCellAreaBox *box,
- gboolean align)
-{
- GtkCellAreaBoxPrivate *priv;
-
- g_return_if_fail (GTK_IS_CELL_AREA_BOX (box));
-
- priv = box->priv;
-
- if (priv->align_cells != align)
- {
- priv->align_cells = align;
-
- g_object_notify (G_OBJECT (box), "align-cells");
- }
-}
diff --git a/gtk/gtkcellareabox.h b/gtk/gtkcellareabox.h
index ee29ffe8a0..0a0c052229 100644
--- a/gtk/gtkcellareabox.h
+++ b/gtk/gtkcellareabox.h
@@ -67,16 +67,15 @@ GType gtk_cell_area_box_get_type (void) G_GNUC_CONST;
GtkCellArea *gtk_cell_area_box_new (void);
void gtk_cell_area_box_pack_start (GtkCellAreaBox *box,
GtkCellRenderer *renderer,
- gboolean expand);
+ gboolean expand,
+ gboolean align);
void gtk_cell_area_box_pack_end (GtkCellAreaBox *box,
GtkCellRenderer *renderer,
- gboolean expand);
+ gboolean expand,
+ gboolean align);
gint gtk_cell_area_box_get_spacing (GtkCellAreaBox *box);
void gtk_cell_area_box_set_spacing (GtkCellAreaBox *box,
gint spacing);
-gboolean gtk_cell_area_box_get_align_cells (GtkCellAreaBox *box);
-void gtk_cell_area_box_set_align_cells (GtkCellAreaBox *box,
- gboolean align);
G_END_DECLS
diff --git a/gtk/gtkcellareaboxiter.c b/gtk/gtkcellareaboxiter.c
index 791d6b4041..9f3474d84f 100644
--- a/gtk/gtkcellareaboxiter.c
+++ b/gtk/gtkcellareaboxiter.c
@@ -23,12 +23,19 @@
#include "config.h"
#include "gtkintl.h"
+#include "gtkcellareabox.h"
#include "gtkcellareaboxiter.h"
/* GObjectClass */
static void gtk_cell_area_box_iter_finalize (GObject *object);
/* GtkCellAreaIterClass */
+static void gtk_cell_area_box_iter_sum_preferred_width (GtkCellAreaIter *iter);
+static void gtk_cell_area_box_iter_sum_preferred_height_for_width (GtkCellAreaIter *iter,
+ gint width);
+static void gtk_cell_area_box_iter_sum_preferred_height (GtkCellAreaIter *iter);
+static void gtk_cell_area_box_iter_sum_preferred_width_for_height (GtkCellAreaIter *iter,
+ gint height);
static void gtk_cell_area_box_iter_flush_preferred_width (GtkCellAreaIter *iter);
static void gtk_cell_area_box_iter_flush_preferred_height_for_width (GtkCellAreaIter *iter,
gint width);
@@ -88,6 +95,11 @@ gtk_cell_area_box_iter_class_init (GtkCellAreaBoxIterClass *class)
/* GObjectClass */
object_class->finalize = gtk_cell_area_box_iter_finalize;
+ iter_class->sum_preferred_width = gtk_cell_area_box_iter_sum_preferred_width;
+ iter_class->sum_preferred_height_for_width = gtk_cell_area_box_iter_sum_preferred_height_for_width;
+ iter_class->sum_preferred_height = gtk_cell_area_box_iter_sum_preferred_height;
+ iter_class->sum_preferred_width_for_height = gtk_cell_area_box_iter_sum_preferred_width_for_height;
+
iter_class->flush_preferred_width = gtk_cell_area_box_iter_flush_preferred_width;
iter_class->flush_preferred_height_for_width = gtk_cell_area_box_iter_flush_preferred_height_for_width;
iter_class->flush_preferred_height = gtk_cell_area_box_iter_flush_preferred_height;
@@ -137,6 +149,102 @@ gtk_cell_area_box_iter_finalize (GObject *object)
/*************************************************************
* GtkCellAreaIterClass *
*************************************************************/
+typedef struct {
+ gint min_size;
+ gint nat_size;
+ gint spacing;
+} AccumData;
+
+static void
+sum_base_size (gpointer group_id,
+ CachedSize *size,
+ AccumData *accum)
+{
+ if (accum->min_size > 0)
+ {
+ accum->min_size += accum->spacing;
+ accum->nat_size += accum->spacing;
+ }
+
+ accum->min_size += size->min_size;
+ accum->nat_size += size->nat_size;
+}
+
+static void
+sum_for_size (gpointer group_id,
+ CachedSize *size,
+ AccumData *accum)
+{
+ accum->min_size = MAX (accum->min_size, size->min_size);
+ accum->nat_size = MAX (accum->nat_size, size->nat_size);
+}
+
+static void
+gtk_cell_area_box_iter_sum_preferred_width (GtkCellAreaIter *iter)
+{
+ GtkCellAreaBoxIter *box_iter = GTK_CELL_AREA_BOX_ITER (iter);
+ GtkCellAreaBoxIterPrivate *priv = box_iter->priv;
+ GtkCellArea *area;
+ AccumData accum = { 0, };
+
+ area = gtk_cell_area_iter_get_area (iter);
+ accum.spacing = gtk_cell_area_box_get_spacing (GTK_CELL_AREA_BOX (area));
+
+ g_hash_table_foreach (priv->base_widths, (GHFunc)sum_base_size, &accum);
+ gtk_cell_area_iter_push_preferred_width (iter, accum.min_size, accum.nat_size);
+}
+
+static void
+gtk_cell_area_box_iter_sum_preferred_height_for_width (GtkCellAreaIter *iter,
+ gint width)
+{
+ GtkCellAreaBoxIter *box_iter = GTK_CELL_AREA_BOX_ITER (iter);
+ GtkCellAreaBoxIterPrivate *priv = box_iter->priv;
+ GHashTable *group_table;
+ AccumData accum = { 0, };
+
+ group_table = g_hash_table_lookup (priv->heights, GINT_TO_POINTER (width));
+
+ if (group_table)
+ {
+ g_hash_table_foreach (priv->base_widths, (GHFunc)sum_for_size, &accum);
+ gtk_cell_area_iter_push_preferred_height_for_width (iter, width, accum.min_size, accum.nat_size);
+ }
+}
+
+static void
+gtk_cell_area_box_iter_sum_preferred_height (GtkCellAreaIter *iter)
+{
+ GtkCellAreaBoxIter *box_iter = GTK_CELL_AREA_BOX_ITER (iter);
+ GtkCellAreaBoxIterPrivate *priv = box_iter->priv;
+ GtkCellArea *area;
+ AccumData accum = { 0, };
+
+ area = gtk_cell_area_iter_get_area (iter);
+ accum.spacing = gtk_cell_area_box_get_spacing (GTK_CELL_AREA_BOX (area));
+
+ g_hash_table_foreach (priv->base_heights, (GHFunc)sum_base_size, &accum);
+ gtk_cell_area_iter_push_preferred_width (iter, accum.min_size, accum.nat_size);
+}
+
+static void
+gtk_cell_area_box_iter_sum_preferred_width_for_height (GtkCellAreaIter *iter,
+ gint height)
+{
+ GtkCellAreaBoxIter *box_iter = GTK_CELL_AREA_BOX_ITER (iter);
+ GtkCellAreaBoxIterPrivate *priv = box_iter->priv;
+ GHashTable *group_table;
+ AccumData accum = { 0, };
+
+ group_table = g_hash_table_lookup (priv->widths, GINT_TO_POINTER (height));
+
+ if (group_table)
+ {
+ g_hash_table_foreach (priv->base_widths, (GHFunc)sum_for_size, &accum);
+ gtk_cell_area_iter_push_preferred_width_for_height (iter, height, accum.min_size, accum.nat_size);
+ }
+}
+
static void
gtk_cell_area_box_iter_flush_preferred_width (GtkCellAreaIter *iter)
{
@@ -200,24 +308,23 @@ gtk_cell_area_box_iter_flush_preferred_width_for_height (GtkCellAreaIter *iter,
*************************************************************/
void
-gtk_cell_area_box_iter_push_cell_width (GtkCellAreaBoxIter *box_iter,
- GtkCellRenderer *renderer,
- gint minimum_width,
- gint natural_width)
+gtk_cell_area_box_iter_push_group_width (GtkCellAreaBoxIter *box_iter,
+ gint group_id,
+ gint minimum_width,
+ gint natural_width)
{
GtkCellAreaBoxIterPrivate *priv;
CachedSize *size;
g_return_if_fail (GTK_IS_CELL_AREA_BOX_ITER (box_iter));
- g_return_if_fail (GTK_IS_CELL_RENDERER (renderer));
priv = box_iter->priv;
- size = g_hash_table_lookup (priv->base_widths, renderer);
+ size = g_hash_table_lookup (priv->base_widths, GINT_TO_POINTER (group_id));
if (!size)
{
size = cached_size_new (minimum_width, natural_width);
- g_hash_table_insert (priv->base_widths, renderer, size);
+ g_hash_table_insert (priv->base_widths, GINT_TO_POINTER (group_id), size);
}
else
{
@@ -227,36 +334,35 @@ gtk_cell_area_box_iter_push_cell_width (GtkCellAreaBoxIter *box_iter,
}
void
-gtk_cell_area_box_iter_push_cell_height_for_width (GtkCellAreaBoxIter *box_iter,
- GtkCellRenderer *renderer,
- gint for_width,
- gint minimum_height,
- gint natural_height)
+gtk_cell_area_box_iter_push_group_height_for_width (GtkCellAreaBoxIter *box_iter,
+ gint group_id,
+ gint for_width,
+ gint minimum_height,
+ gint natural_height)
{
GtkCellAreaBoxIterPrivate *priv;
- GHashTable *cell_table;
+ GHashTable *group_table;
CachedSize *size;
g_return_if_fail (GTK_IS_CELL_AREA_BOX_ITER (box_iter));
- g_return_if_fail (GTK_IS_CELL_RENDERER (renderer));
- priv = box_iter->priv;
- cell_table = g_hash_table_lookup (priv->heights, GINT_TO_POINTER (for_width));
+ priv = box_iter->priv;
+ group_table = g_hash_table_lookup (priv->heights, GINT_TO_POINTER (for_width));
- if (!cell_table)
+ if (!group_table)
{
- cell_table = g_hash_table_new_full (g_direct_hash, g_direct_equal,
+ group_table = g_hash_table_new_full (g_direct_hash, g_direct_equal,
NULL, (GDestroyNotify)cached_size_free);
- g_hash_table_insert (priv->heights, GINT_TO_POINTER (for_width), cell_table);
+ g_hash_table_insert (priv->heights, GINT_TO_POINTER (for_width), group_table);
}
- size = g_hash_table_lookup (cell_table, renderer);
+ size = g_hash_table_lookup (group_table, GINT_TO_POINTER (group_id));
if (!size)
{
size = cached_size_new (minimum_height, natural_height);
- g_hash_table_insert (cell_table, renderer, size);
+ g_hash_table_insert (group_table, GINT_TO_POINTER (group_id), size);
}
else
{
@@ -266,24 +372,23 @@ gtk_cell_area_box_iter_push_cell_height_for_width (GtkCellAreaBoxIter *box_iter
}
void
-gtk_cell_area_box_iter_push_cell_height (GtkCellAreaBoxIter *box_iter,
- GtkCellRenderer *renderer,
- gint minimum_height,
- gint natural_height)
+gtk_cell_area_box_iter_push_group_height (GtkCellAreaBoxIter *box_iter,
+ gint group_id,
+ gint minimum_height,
+ gint natural_height)
{
GtkCellAreaBoxIterPrivate *priv;
CachedSize *size;
g_return_if_fail (GTK_IS_CELL_AREA_BOX_ITER (box_iter));
- g_return_if_fail (GTK_IS_CELL_RENDERER (renderer));
priv = box_iter->priv;
- size = g_hash_table_lookup (priv->base_heights, renderer);
+ size = g_hash_table_lookup (priv->base_heights, GINT_TO_POINTER (group_id));
if (!size)
{
size = cached_size_new (minimum_height, natural_height);
- g_hash_table_insert (priv->base_widths, renderer, size);
+ g_hash_table_insert (priv->base_widths, GINT_TO_POINTER (group_id), size);
}
else
{
@@ -293,36 +398,35 @@ gtk_cell_area_box_iter_push_cell_height (GtkCellAreaBoxIter *box_iter,
}
void
-gtk_cell_area_box_iter_push_cell_width_for_height (GtkCellAreaBoxIter *box_iter,
- GtkCellRenderer *renderer,
- gint for_height,
- gint minimum_width,
- gint natural_width)
+gtk_cell_area_box_iter_push_group_width_for_height (GtkCellAreaBoxIter *box_iter,
+ gint group_id,
+ gint for_height,
+ gint minimum_width,
+ gint natural_width)
{
GtkCellAreaBoxIterPrivate *priv;
- GHashTable *cell_table;
+ GHashTable *group_table;
CachedSize *size;
g_return_if_fail (GTK_IS_CELL_AREA_BOX_ITER (box_iter));
- g_return_if_fail (GTK_IS_CELL_RENDERER (renderer));
- priv = box_iter->priv;
- cell_table = g_hash_table_lookup (priv->widths, GINT_TO_POINTER (for_height));
+ priv = box_iter->priv;
+ group_table = g_hash_table_lookup (priv->widths, GINT_TO_POINTER (for_height));
- if (!cell_table)
+ if (!group_table)
{
- cell_table = g_hash_table_new_full (g_direct_hash, g_direct_equal,
+ group_table = g_hash_table_new_full (g_direct_hash, g_direct_equal,
NULL, (GDestroyNotify)cached_size_free);
- g_hash_table_insert (priv->widths, GINT_TO_POINTER (for_height), cell_table);
+ g_hash_table_insert (priv->widths, GINT_TO_POINTER (for_height), group_table);
}
- size = g_hash_table_lookup (cell_table, renderer);
+ size = g_hash_table_lookup (group_table, GINT_TO_POINTER (group_id));
if (!size)
{
size = cached_size_new (minimum_width, natural_width);
- g_hash_table_insert (cell_table, renderer, size);
+ g_hash_table_insert (group_table, GINT_TO_POINTER (group_id), size);
}
else
{
@@ -332,19 +436,18 @@ gtk_cell_area_box_iter_push_cell_width_for_height (GtkCellAreaBoxIter *box_iter,
}
void
-gtk_cell_area_box_iter_get_cell_width (GtkCellAreaBoxIter *box_iter,
- GtkCellRenderer *renderer,
- gint *minimum_width,
- gint *natural_width)
+gtk_cell_area_box_iter_get_group_width (GtkCellAreaBoxIter *box_iter,
+ gint group_id,
+ gint *minimum_width,
+ gint *natural_width)
{
GtkCellAreaBoxIterPrivate *priv;
CachedSize *size;
g_return_if_fail (GTK_IS_CELL_AREA_BOX_ITER (box_iter));
- g_return_if_fail (GTK_IS_CELL_RENDERER (renderer));
priv = box_iter->priv;
- size = g_hash_table_lookup (priv->base_widths, renderer);
+ size = g_hash_table_lookup (priv->base_widths, GINT_TO_POINTER (group_id));
if (size)
{
@@ -365,24 +468,23 @@ gtk_cell_area_box_iter_get_cell_width (GtkCellAreaBoxIter *box_iter,
}
void
-gtk_cell_area_box_iter_get_cell_height_for_width (GtkCellAreaBoxIter *box_iter,
- GtkCellRenderer *renderer,
- gint for_width,
- gint *minimum_height,
- gint *natural_height)
+gtk_cell_area_box_iter_get_group_height_for_width (GtkCellAreaBoxIter *box_iter,
+ gint group_id,
+ gint for_width,
+ gint *minimum_height,
+ gint *natural_height)
{
GtkCellAreaBoxIterPrivate *priv;
- GHashTable *cell_table;
+ GHashTable *group_table;
CachedSize *size = NULL;
g_return_if_fail (GTK_IS_CELL_AREA_BOX_ITER (box_iter));
- g_return_if_fail (GTK_IS_CELL_RENDERER (renderer));
- priv = box_iter->priv;
- cell_table = g_hash_table_lookup (priv->heights, GINT_TO_POINTER (for_width));
+ priv = box_iter->priv;
+ group_table = g_hash_table_lookup (priv->heights, GINT_TO_POINTER (for_width));
- if (cell_table)
- size = g_hash_table_lookup (cell_table, renderer);
+ if (group_table)
+ size = g_hash_table_lookup (group_table, GINT_TO_POINTER (group_id));
if (size)
{
@@ -403,19 +505,18 @@ gtk_cell_area_box_iter_get_cell_height_for_width (GtkCellAreaBoxIter *box_iter,
}
void
-gtk_cell_area_box_iter_get_cell_height (GtkCellAreaBoxIter *box_iter,
- GtkCellRenderer *renderer,
- gint *minimum_height,
- gint *natural_height)
+gtk_cell_area_box_iter_get_group_height (GtkCellAreaBoxIter *box_iter,
+ gint group_id,
+ gint *minimum_height,
+ gint *natural_height)
{
GtkCellAreaBoxIterPrivate *priv;
CachedSize *size;
g_return_if_fail (GTK_IS_CELL_AREA_BOX_ITER (box_iter));
- g_return_if_fail (GTK_IS_CELL_RENDERER (renderer));
priv = box_iter->priv;
- size = g_hash_table_lookup (priv->base_heights, renderer);
+ size = g_hash_table_lookup (priv->base_heights, GINT_TO_POINTER (group_id));
if (size)
{
@@ -436,24 +537,23 @@ gtk_cell_area_box_iter_get_cell_height (GtkCellAreaBoxIter *box_iter,
}
void
-gtk_cell_area_box_iter_get_cell_width_for_height (GtkCellAreaBoxIter *box_iter,
- GtkCellRenderer *renderer,
- gint for_height,
- gint *minimum_width,
- gint *natural_width)
+gtk_cell_area_box_iter_get_group_width_for_height (GtkCellAreaBoxIter *box_iter,
+ gint group_id,
+ gint for_height,
+ gint *minimum_width,
+ gint *natural_width)
{
GtkCellAreaBoxIterPrivate *priv;
- GHashTable *cell_table;
+ GHashTable *group_table;
CachedSize *size = NULL;
g_return_if_fail (GTK_IS_CELL_AREA_BOX_ITER (box_iter));
- g_return_if_fail (GTK_IS_CELL_RENDERER (renderer));
- priv = box_iter->priv;
- cell_table = g_hash_table_lookup (priv->widths, GINT_TO_POINTER (for_height));
+ priv = box_iter->priv;
+ group_table = g_hash_table_lookup (priv->widths, GINT_TO_POINTER (for_height));
- if (cell_table)
- size = g_hash_table_lookup (cell_table, renderer);
+ if (group_table)
+ size = g_hash_table_lookup (group_table, GINT_TO_POINTER (group_id));
if (size)
{
@@ -472,3 +572,53 @@ gtk_cell_area_box_iter_get_cell_width_for_height (GtkCellAreaBoxIter *box_iter,
*natural_width = -1;
}
}
+
+static void
+fill_requested_sizes (gpointer group_id_ptr,
+ CachedSize *cached_size,
+ GtkRequestedSize *requested)
+{
+ gint group_id = GPOINTER_TO_INT (group_id_ptr);
+
+ requested[group_id].data = group_id_ptr;
+ requested[group_id].minimum_size = cached_size->min_size;
+ requested[group_id].natural_size = cached_size->nat_size;
+}
+
+GtkRequestedSize *
+gtk_cell_area_box_iter_get_widths (GtkCellAreaBoxIter *box_iter,
+ gint *n_widths)
+{
+ GtkCellAreaBoxIterPrivate *priv;
+ GtkRequestedSize *widths;
+
+ g_return_val_if_fail (GTK_IS_CELL_AREA_BOX_ITER (box_iter), NULL);
+
+ priv = box_iter->priv;
+
+ *n_widths = g_hash_table_size (priv->widths);
+ widths = g_new (GtkRequestedSize, *n_widths);
+
+ g_hash_table_foreach (priv->widths, (GHFunc)fill_requested_sizes, widths);
+
+ return widths;
+}
+
+GtkRequestedSize *
+gtk_cell_area_box_iter_get_heights (GtkCellAreaBoxIter *box_iter,
+ gint *n_heights)
+{
+ GtkCellAreaBoxIterPrivate *priv;
+ GtkRequestedSize *heights;
+
+ g_return_val_if_fail (GTK_IS_CELL_AREA_BOX_ITER (box_iter), NULL);
+
+ priv = box_iter->priv;
+
+ *n_heights = g_hash_table_size (priv->heights);
+ heights = g_new (GtkRequestedSize, *n_heights);
+
+ g_hash_table_foreach (priv->heights, (GHFunc)fill_requested_sizes, heights);
+
+ return heights;
+}
diff --git a/gtk/gtkcellareaboxiter.h b/gtk/gtkcellareaboxiter.h
index 0781c28d78..ada15a7666 100644
--- a/gtk/gtkcellareaboxiter.h
+++ b/gtk/gtkcellareaboxiter.h
@@ -30,6 +30,7 @@
#include <gtk/gtkcellareaiter.h>
#include <gtk/gtkcellrenderer.h>
+#include <gtk/gtksizerequest.h>
G_BEGIN_DECLS
@@ -57,54 +58,59 @@ struct _GtkCellAreaBoxIterClass
};
-GType gtk_cell_area_box_iter_get_type (void) G_GNUC_CONST;
-
-
-/* Update cell alignments */
-void gtk_cell_area_box_iter_push_cell_width (GtkCellAreaBoxIter *box_iter,
- GtkCellRenderer *renderer,
- gint minimum_width,
- gint natural_width);
-
-void gtk_cell_area_box_iter_push_cell_height_for_width (GtkCellAreaBoxIter *box_iter,
- GtkCellRenderer *renderer,
- gint for_width,
- gint minimum_height,
- gint natural_height);
-
-void gtk_cell_area_box_iter_push_cell_height (GtkCellAreaBoxIter *box_iter,
- GtkCellRenderer *renderer,
- gint minimum_height,
- gint natural_height);
-
-void gtk_cell_area_box_iter_push_cell_width_for_height (GtkCellAreaBoxIter *box_iter,
- GtkCellRenderer *renderer,
- gint for_height,
- gint minimum_width,
- gint natural_width);
-
-/* Fetch cell alignments */
-void gtk_cell_area_box_iter_get_cell_width (GtkCellAreaBoxIter *box_iter,
- GtkCellRenderer *renderer,
- gint *minimum_width,
- gint *natural_width);
-
-void gtk_cell_area_box_iter_get_cell_height_for_width (GtkCellAreaBoxIter *box_iter,
- GtkCellRenderer *renderer,
- gint for_width,
- gint *minimum_height,
- gint *natural_height);
-
-void gtk_cell_area_box_iter_get_cell_height (GtkCellAreaBoxIter *box_iter,
- GtkCellRenderer *renderer,
- gint *minimum_height,
- gint *natural_height);
-
-void gtk_cell_area_box_iter_get_cell_width_for_height (GtkCellAreaBoxIter *box_iter,
- GtkCellRenderer *renderer,
- gint for_height,
- gint *minimum_width,
- gint *natural_width);
+GType gtk_cell_area_box_iter_get_type (void) G_GNUC_CONST;
+
+
+/* Update cell-group sizes */
+void gtk_cell_area_box_iter_push_group_width (GtkCellAreaBoxIter *box_iter,
+ gint group_id,
+ gint minimum_width,
+ gint natural_width);
+
+void gtk_cell_area_box_iter_push_group_height_for_width (GtkCellAreaBoxIter *box_iter,
+ gint group_id,
+ gint for_width,
+ gint minimum_height,
+ gint natural_height);
+
+void gtk_cell_area_box_iter_push_group_height (GtkCellAreaBoxIter *box_iter,
+ gint group_id,
+ gint minimum_height,
+ gint natural_height);
+
+void gtk_cell_area_box_iter_push_group_width_for_height (GtkCellAreaBoxIter *box_iter,
+ gint group_id,
+ gint for_height,
+ gint minimum_width,
+ gint natural_width);
+
+/* Fetch cell-group sizes */
+void gtk_cell_area_box_iter_get_group_width (GtkCellAreaBoxIter *box_iter,
+ gint group_id,
+ gint *minimum_width,
+ gint *natural_width);
+
+void gtk_cell_area_box_iter_get_group_height_for_width (GtkCellAreaBoxIter *box_iter,
+ gint group_id,
+ gint for_width,
+ gint *minimum_height,
+ gint *natural_height);
+
+void gtk_cell_area_box_iter_get_group_height (GtkCellAreaBoxIter *box_iter,
+ gint group_id,
+ gint *minimum_height,
+ gint *natural_height);
+
+void gtk_cell_area_box_iter_get_group_width_for_height (GtkCellAreaBoxIter *box_iter,
+ gint group_id,
+ gint for_height,
+ gint *minimum_width,
+ gint *natural_width);
+
+GtkRequestedSize *gtk_cell_area_box_iter_get_widths (GtkCellAreaBoxIter *box_iter,
+ gint *n_widths);
+GtkRequestedSize *gtk_cell_area_box_iter_get_heights (GtkCellAreaBoxIter *box_iter,
+ gint *n_heights);
G_END_DECLS
diff --git a/gtk/gtkcellareaiter.c b/gtk/gtkcellareaiter.c
index d4de66b239..4257f4b754 100644
--- a/gtk/gtkcellareaiter.c
+++ b/gtk/gtkcellareaiter.c
@@ -25,13 +25,19 @@
#include "gtkintl.h"
#include "gtkmarshalers.h"
#include "gtkcellareaiter.h"
+#include "gtkprivate.h"
/* GObjectClass */
static void gtk_cell_area_iter_finalize (GObject *object);
+static void gtk_cell_area_iter_dispose (GObject *object);
static void gtk_cell_area_iter_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec);
+static void gtk_cell_area_iter_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec);
/* GtkCellAreaIterClass */
static void gtk_cell_area_iter_real_flush_preferred_width (GtkCellAreaIter *iter);
@@ -52,17 +58,20 @@ static void cached_size_free (CachedSize *size);
struct _GtkCellAreaIterPrivate
{
- gint min_width;
- gint nat_width;
- gint min_height;
- gint nat_height;
+ GtkCellArea *cell_area;
+
+ gint min_width;
+ gint nat_width;
+ gint min_height;
+ gint nat_height;
- GHashTable *widths;
- GHashTable *heights;
+ GHashTable *widths;
+ GHashTable *heights;
};
enum {
PROP_0,
+ PROP_CELL_AREA,
PROP_MIN_WIDTH,
PROP_NAT_WIDTH,
PROP_MIN_HEIGHT,
@@ -106,7 +115,9 @@ gtk_cell_area_iter_class_init (GtkCellAreaIterClass *class)
/* GObjectClass */
object_class->finalize = gtk_cell_area_iter_finalize;
+ object_class->dispose = gtk_cell_area_iter_dispose;
object_class->get_property = gtk_cell_area_iter_get_property;
+ object_class->set_property = gtk_cell_area_iter_set_property;
class->flush_preferred_width = gtk_cell_area_iter_real_flush_preferred_width;
class->flush_preferred_height_for_width = gtk_cell_area_iter_real_flush_preferred_height_for_width;
@@ -134,6 +145,14 @@ gtk_cell_area_iter_class_init (GtkCellAreaIterClass *class)
G_TYPE_INT, G_TYPE_INT, G_TYPE_INT);
g_object_class_install_property (object_class,
+ PROP_CELL_AREA,
+ g_param_spec_object ("area",
+ P_("Area"),
+ P_("The Cell Area this iter was created for"),
+ GTK_TYPE_CELL_AREA,
+ GTK_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+
+ g_object_class_install_property (object_class,
PROP_MIN_WIDTH,
g_param_spec_int ("minimum-width",
P_("Minimum Width"),
@@ -215,6 +234,42 @@ gtk_cell_area_iter_finalize (GObject *object)
}
static void
+gtk_cell_area_iter_dispose (GObject *object)
+{
+ GtkCellAreaIter *iter = GTK_CELL_AREA_ITER (object);
+ GtkCellAreaIterPrivate *priv = iter->priv;
+
+ if (priv->cell_area)
+ {
+ g_object_unref (priv->cell_area);
+
+ priv->cell_area = NULL;
+ }
+
+ G_OBJECT_CLASS (gtk_cell_area_iter_parent_class)->dispose (object);
+}
+
+static void
+gtk_cell_area_iter_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ GtkCellAreaIter *iter = GTK_CELL_AREA_ITER (object);
+ GtkCellAreaIterPrivate *priv = iter->priv;
+
+ switch (prop_id)
+ {
+ case PROP_CELL_AREA:
+ priv->cell_area = g_value_dup_object (value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
gtk_cell_area_iter_get_property (GObject *object,
guint prop_id,
GValue *value,
@@ -225,6 +280,9 @@ gtk_cell_area_iter_get_property (GObject *object,
switch (prop_id)
{
+ case PROP_CELL_AREA:
+ g_value_set_object (value, priv->cell_area);
+ break;
case PROP_MIN_WIDTH:
g_value_set_int (value, priv->min_width);
break;
@@ -307,6 +365,17 @@ gtk_cell_area_iter_real_flush_preferred_width_for_height (GtkCellAreaIter *iter,
/*************************************************************
* API *
*************************************************************/
+GtkCellArea *
+gtk_cell_area_iter_get_area (GtkCellAreaIter *iter)
+{
+ GtkCellAreaIterPrivate *priv;
+
+ g_return_val_if_fail (GTK_IS_CELL_AREA_ITER (iter), NULL);
+
+ priv = iter->priv;
+
+ return priv->cell_area;
+}
void
gtk_cell_area_iter_get_preferred_width (GtkCellAreaIter *iter,
@@ -410,6 +479,106 @@ gtk_cell_area_iter_get_preferred_width_for_height (GtkCellAreaIter *iter,
}
}
+void
+gtk_cell_area_iter_sum_preferred_width (GtkCellAreaIter *iter)
+{
+ GtkCellAreaIterClass *class;
+
+ g_return_if_fail (GTK_IS_CELL_AREA_ITER (iter));
+
+ class = GTK_CELL_AREA_ITER_GET_CLASS (iter);
+
+ if (class->sum_preferred_width)
+ class->sum_preferred_width (iter);
+}
+
+void
+gtk_cell_area_iter_sum_preferred_height_for_width (GtkCellAreaIter *iter,
+ gint for_width)
+{
+ GtkCellAreaIterClass *class;
+
+ g_return_if_fail (GTK_IS_CELL_AREA_ITER (iter));
+
+ class = GTK_CELL_AREA_ITER_GET_CLASS (iter);
+
+ if (class->sum_preferred_height_for_width)
+ class->sum_preferred_height_for_width (iter, for_width);
+}
+
+void
+gtk_cell_area_iter_sum_preferred_height (GtkCellAreaIter *iter)
+{
+ GtkCellAreaIterClass *class;
+
+ g_return_if_fail (GTK_IS_CELL_AREA_ITER (iter));
+
+ class = GTK_CELL_AREA_ITER_GET_CLASS (iter);
+
+ if (class->sum_preferred_height)
+ class->sum_preferred_height (iter);
+}
+
+void
+gtk_cell_area_iter_sum_preferred_width_for_height (GtkCellAreaIter *iter,
+ gint for_height)
+{
+ GtkCellAreaIterClass *class;
+
+ g_return_if_fail (GTK_IS_CELL_AREA_ITER (iter));
+
+ class = GTK_CELL_AREA_ITER_GET_CLASS (iter);
+
+ if (class->sum_preferred_width_for_height)
+ class->sum_preferred_width_for_height (iter, for_height);
+}
+
+void
+gtk_cell_area_iter_flush (GtkCellAreaIter *iter)
+{
+ g_return_if_fail (GTK_IS_CELL_AREA_ITER (iter));
+
+ gtk_cell_area_iter_flush_preferred_width (iter);
+ gtk_cell_area_iter_flush_preferred_height_for_width (iter, -1);
+ gtk_cell_area_iter_flush_preferred_height (iter);
+ gtk_cell_area_iter_flush_preferred_width_for_height (iter, -1);
+}
+
+void
+gtk_cell_area_iter_flush_preferred_width (GtkCellAreaIter *iter)
+{
+ g_return_if_fail (GTK_IS_CELL_AREA_ITER (iter));
+
+ GTK_CELL_AREA_ITER_GET_CLASS (iter)->flush_preferred_width (iter);
+}
+
+void
+gtk_cell_area_iter_flush_preferred_height_for_width (GtkCellAreaIter *iter,
+ gint for_width)
+{
+ g_return_if_fail (GTK_IS_CELL_AREA_ITER (iter));
+
+ GTK_CELL_AREA_ITER_GET_CLASS (iter)->flush_preferred_height_for_width (iter, for_width);
+}
+
+void
+gtk_cell_area_iter_flush_preferred_height (GtkCellAreaIter *iter)
+{
+ g_return_if_fail (GTK_IS_CELL_AREA_ITER (iter));
+
+ GTK_CELL_AREA_ITER_GET_CLASS (iter)->flush_preferred_height (iter);
+}
+
+void
+gtk_cell_area_iter_flush_preferred_width_for_height (GtkCellAreaIter *iter,
+ gint for_height)
+{
+ g_return_if_fail (GTK_IS_CELL_AREA_ITER (iter));
+
+ GTK_CELL_AREA_ITER_GET_CLASS (iter)->flush_preferred_width_for_height (iter, for_height);
+}
+
+
void
gtk_cell_area_iter_push_preferred_width (GtkCellAreaIter *iter,
@@ -558,48 +727,3 @@ gtk_cell_area_iter_push_preferred_width_for_height (GtkCellAreaIter *iter,
g_signal_emit (iter, cell_area_iter_signals[SIGNAL_WIDTH_CHANGED], 0,
for_height, size->min_size, size->nat_size);
}
-
-void
-gtk_cell_area_iter_flush (GtkCellAreaIter *iter)
-{
- g_return_if_fail (GTK_IS_CELL_AREA_ITER (iter));
-
- gtk_cell_area_iter_flush_preferred_width (iter);
- gtk_cell_area_iter_flush_preferred_height_for_width (iter, -1);
- gtk_cell_area_iter_flush_preferred_height (iter);
- gtk_cell_area_iter_flush_preferred_width_for_height (iter, -1);
-}
-
-void
-gtk_cell_area_iter_flush_preferred_width (GtkCellAreaIter *iter)
-{
- g_return_if_fail (GTK_IS_CELL_AREA_ITER (iter));
-
- GTK_CELL_AREA_ITER_GET_CLASS (iter)->flush_preferred_width (iter);
-}
-
-void
-gtk_cell_area_iter_flush_preferred_height_for_width (GtkCellAreaIter *iter,
- gint for_width)
-{
- g_return_if_fail (GTK_IS_CELL_AREA_ITER (iter));
-
- GTK_CELL_AREA_ITER_GET_CLASS (iter)->flush_preferred_height_for_width (iter, for_width);
-}
-
-void
-gtk_cell_area_iter_flush_preferred_height (GtkCellAreaIter *iter)
-{
- g_return_if_fail (GTK_IS_CELL_AREA_ITER (iter));
-
- GTK_CELL_AREA_ITER_GET_CLASS (iter)->flush_preferred_height (iter);
-}
-
-void
-gtk_cell_area_iter_flush_preferred_width_for_height (GtkCellAreaIter *iter,
- gint for_height)
-{
- g_return_if_fail (GTK_IS_CELL_AREA_ITER (iter));
-
- GTK_CELL_AREA_ITER_GET_CLASS (iter)->flush_preferred_width_for_height (iter, for_height);
-}
diff --git a/gtk/gtkcellareaiter.h b/gtk/gtkcellareaiter.h
index 92f820fb06..b2e0e55a93 100644
--- a/gtk/gtkcellareaiter.h
+++ b/gtk/gtkcellareaiter.h
@@ -28,7 +28,7 @@
#ifndef __GTK_CELL_AREA_ITER_H__
#define __GTK_CELL_AREA_ITER_H__
-#include <glib-object.h>
+#include <gtk/gtkcellarea.h>
G_BEGIN_DECLS
@@ -39,7 +39,6 @@ G_BEGIN_DECLS
#define GTK_IS_CELL_AREA_ITER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_CELL_AREA_ITER))
#define GTK_CELL_AREA_ITER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_CELL_AREA_ITER, GtkCellAreaIterClass))
-typedef struct _GtkCellAreaIter GtkCellAreaIter;
typedef struct _GtkCellAreaIterPrivate GtkCellAreaIterPrivate;
typedef struct _GtkCellAreaIterClass GtkCellAreaIterClass;
@@ -62,6 +61,16 @@ struct _GtkCellAreaIterClass
void (* flush_preferred_width_for_height) (GtkCellAreaIter *iter,
gint height);
+ /* These must be invoked after a series of requests before consulting
+ * the iter values, implementors use this to push the overall
+ * requests while acconting for any internal alignments */
+ void (* sum_preferred_width) (GtkCellAreaIter *iter);
+ void (* sum_preferred_height_for_width) (GtkCellAreaIter *iter,
+ gint width);
+ void (* sum_preferred_height) (GtkCellAreaIter *iter);
+ void (* sum_preferred_width_for_height) (GtkCellAreaIter *iter,
+ gint height);
+
/* Padding for future expansion */
void (*_gtk_reserved1) (void);
void (*_gtk_reserved2) (void);
@@ -69,48 +78,59 @@ struct _GtkCellAreaIterClass
void (*_gtk_reserved4) (void);
};
-GType gtk_cell_area_iter_get_type (void) G_GNUC_CONST;
+GType gtk_cell_area_iter_get_type (void) G_GNUC_CONST;
-/* Apis for GtkCellArea clients to consult cached values for multiple GtkTreeModel rows */
-void gtk_cell_area_iter_get_preferred_width (GtkCellAreaIter *iter,
- gint *minimum_width,
- gint *natural_width);
-void gtk_cell_area_iter_get_preferred_height_for_width (GtkCellAreaIter *iter,
- gint for_width,
- gint *minimum_height,
- gint *natural_height);
-void gtk_cell_area_iter_get_preferred_height (GtkCellAreaIter *iter,
- gint *minimum_height,
- gint *natural_height);
-void gtk_cell_area_iter_get_preferred_width_for_height (GtkCellAreaIter *iter,
- gint for_height,
- gint *minimum_width,
- gint *natural_width);
+GtkCellArea *gtk_cell_area_iter_get_area (GtkCellAreaIter *iter);
-/* Apis for GtkCellArea implementations to update cached values for multiple GtkTreeModel rows */
-void gtk_cell_area_iter_push_preferred_width (GtkCellAreaIter *iter,
- gint minimum_width,
- gint natural_width);
-void gtk_cell_area_iter_push_preferred_height_for_width (GtkCellAreaIter *iter,
- gint for_width,
- gint minimum_height,
- gint natural_height);
-void gtk_cell_area_iter_push_preferred_height (GtkCellAreaIter *iter,
- gint minimum_height,
- gint natural_height);
-void gtk_cell_area_iter_push_preferred_width_for_height (GtkCellAreaIter *iter,
- gint for_height,
- gint minimum_width,
- gint natural_width);
+/* Apis for GtkCellArea clients to consult cached values for multiple GtkTreeModel rows */
+void gtk_cell_area_iter_get_preferred_width (GtkCellAreaIter *iter,
+ gint *minimum_width,
+ gint *natural_width);
+void gtk_cell_area_iter_get_preferred_height_for_width (GtkCellAreaIter *iter,
+ gint for_width,
+ gint *minimum_height,
+ gint *natural_height);
+void gtk_cell_area_iter_get_preferred_height (GtkCellAreaIter *iter,
+ gint *minimum_height,
+ gint *natural_height);
+void gtk_cell_area_iter_get_preferred_width_for_height (GtkCellAreaIter *iter,
+ gint for_height,
+ gint *minimum_width,
+ gint *natural_width);
+
+/* Apis for GtkCellArea clients to sum up the results of a series of requests, this
+ * call is required to reduce the processing while calculating the size of each row */
+void gtk_cell_area_iter_sum_preferred_width (GtkCellAreaIter *iter);
+void gtk_cell_area_iter_sum_preferred_height_for_width (GtkCellAreaIter *iter,
+ gint for_width);
+void gtk_cell_area_iter_sum_preferred_height (GtkCellAreaIter *iter);
+void gtk_cell_area_iter_sum_preferred_width_for_height (GtkCellAreaIter *iter,
+ gint for_height);
/* Apis for GtkCellArea clients to flush the cache */
-void gtk_cell_area_iter_flush (GtkCellAreaIter *iter);
-void gtk_cell_area_iter_flush_preferred_width (GtkCellAreaIter *iter);
-void gtk_cell_area_iter_flush_preferred_height_for_width (GtkCellAreaIter *iter,
- gint for_width);
-void gtk_cell_area_iter_flush_preferred_height (GtkCellAreaIter *iter);
-void gtk_cell_area_iter_flush_preferred_width_for_height (GtkCellAreaIter *iter,
- gint for_height);
+void gtk_cell_area_iter_flush (GtkCellAreaIter *iter);
+void gtk_cell_area_iter_flush_preferred_width (GtkCellAreaIter *iter);
+void gtk_cell_area_iter_flush_preferred_height_for_width (GtkCellAreaIter *iter,
+ gint for_width);
+void gtk_cell_area_iter_flush_preferred_height (GtkCellAreaIter *iter);
+void gtk_cell_area_iter_flush_preferred_width_for_height (GtkCellAreaIter *iter,
+ gint for_height);
+
+/* Apis for GtkCellArea implementations to update cached values for multiple GtkTreeModel rows */
+void gtk_cell_area_iter_push_preferred_width (GtkCellAreaIter *iter,
+ gint minimum_width,
+ gint natural_width);
+void gtk_cell_area_iter_push_preferred_height_for_width (GtkCellAreaIter *iter,
+ gint for_width,
+ gint minimum_height,
+ gint natural_height);
+void gtk_cell_area_iter_push_preferred_height (GtkCellAreaIter *iter,
+ gint minimum_height,
+ gint natural_height);
+void gtk_cell_area_iter_push_preferred_width_for_height (GtkCellAreaIter *iter,
+ gint for_height,
+ gint minimum_width,
+ gint natural_width);
G_END_DECLS