Made GtkCellAreaBox:align-cells a packing property per cell

Implemented all request apis on GtkCellAreaBox considering
alignment of groups of cells (some cells can be aligned while
others fill space smartly).
This commit is contained in:
Tristan Van Berkom 2010-10-30 17:32:15 +09:00
parent 211c39c500
commit 3b1c301a66
7 changed files with 1059 additions and 541 deletions

View File

@ -31,7 +31,6 @@
#include <gtk/gtkcellrenderer.h> #include <gtk/gtkcellrenderer.h>
#include <gtk/gtkwidget.h> #include <gtk/gtkwidget.h>
#include <gtk/gtktreemodel.h> #include <gtk/gtktreemodel.h>
#include <gtk/gtkcellareaiter.h>
G_BEGIN_DECLS G_BEGIN_DECLS
@ -45,6 +44,7 @@ G_BEGIN_DECLS
typedef struct _GtkCellArea GtkCellArea; typedef struct _GtkCellArea GtkCellArea;
typedef struct _GtkCellAreaClass GtkCellAreaClass; typedef struct _GtkCellAreaClass GtkCellAreaClass;
typedef struct _GtkCellAreaPrivate GtkCellAreaPrivate; typedef struct _GtkCellAreaPrivate GtkCellAreaPrivate;
typedef struct _GtkCellAreaIter GtkCellAreaIter;
/** /**
* GtkCellCallback: * GtkCellCallback:

View File

@ -97,38 +97,53 @@ static void gtk_cell_area_box_layout_reorder (GtkCellLayout
gint position); gint position);
/* CellInfo metadata handling */ /* CellInfo/CellGroup metadata handling */
typedef struct { typedef struct {
GtkCellRenderer *renderer; GtkCellRenderer *renderer;
guint expand : 1; guint expand : 1; /* Whether the cell expands */
guint pack : 1; 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; } CellInfo;
typedef struct {
GList *cells;
guint id : 16;
guint expand : 1;
} CellGroup;
static CellInfo *cell_info_new (GtkCellRenderer *renderer, static CellInfo *cell_info_new (GtkCellRenderer *renderer,
GtkPackType pack,
gboolean expand, gboolean expand,
GtkPackType pack); gboolean align);
static void cell_info_free (CellInfo *info); static void cell_info_free (CellInfo *info);
static gint cell_info_find (CellInfo *info, static gint cell_info_find (CellInfo *info,
GtkCellRenderer *renderer); 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 struct _GtkCellAreaBoxPrivate
{ {
GtkOrientation orientation; GtkOrientation orientation;
GList *cells; GList *cells;
GList *groups;
gint spacing; gint spacing;
guint align_cells : 1;
}; };
enum { enum {
PROP_0, PROP_0,
PROP_ORIENTATION, PROP_ORIENTATION,
PROP_SPACING, PROP_SPACING
PROP_ALIGN_CELLS
}; };
G_DEFINE_TYPE_WITH_CODE (GtkCellAreaBox, gtk_cell_area_box, GTK_TYPE_CELL_AREA, 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) gtk_cell_area_box_cell_layout_init)
G_IMPLEMENT_INTERFACE (GTK_TYPE_ORIENTABLE, NULL)); G_IMPLEMENT_INTERFACE (GTK_TYPE_ORIENTABLE, NULL));
#define OPPOSITE_ORIENTATION(orientation) \
((orientation) == GTK_ORIENTATION_HORIZONTAL ? \
GTK_ORIENTATION_VERTICAL : GTK_ORIENTATION_HORIZONTAL)
static void static void
gtk_cell_area_box_init (GtkCellAreaBox *box) gtk_cell_area_box_init (GtkCellAreaBox *box)
{ {
@ -148,8 +167,8 @@ gtk_cell_area_box_init (GtkCellAreaBox *box)
priv->orientation = GTK_ORIENTATION_HORIZONTAL; priv->orientation = GTK_ORIENTATION_HORIZONTAL;
priv->cells = NULL; priv->cells = NULL;
priv->groups = NULL;
priv->spacing = 0; priv->spacing = 0;
priv->align_cells = TRUE;
} }
static void static void
@ -190,32 +209,25 @@ gtk_cell_area_box_class_init (GtkCellAreaBoxClass *class)
0, 0,
GTK_PARAM_READWRITE)); 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)); g_type_class_add_private (object_class, sizeof (GtkCellAreaBoxPrivate));
} }
/************************************************************* /*************************************************************
* CellInfo Basics * * CellInfo/CellGroup Basics *
*************************************************************/ *************************************************************/
static CellInfo * static CellInfo *
cell_info_new (GtkCellRenderer *renderer, cell_info_new (GtkCellRenderer *renderer,
GtkPackType pack,
gboolean expand, gboolean expand,
GtkPackType pack) gboolean align)
{ {
CellInfo *info = g_slice_new (CellInfo); CellInfo *info = g_slice_new (CellInfo);
info->renderer = g_object_ref_sink (renderer); info->renderer = g_object_ref_sink (renderer);
info->expand = expand;
info->pack = pack; info->pack = pack;
info->expand = expand;
info->align = align;
return info; return info;
} }
@ -235,6 +247,139 @@ cell_info_find (CellInfo *info,
return (info->renderer == renderer) ? 0 : -1; 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 * * GObjectClass *
*************************************************************/ *************************************************************/
@ -256,7 +401,17 @@ gtk_cell_area_box_set_property (GObject *object,
const GValue *value, const GValue *value,
GParamSpec *pspec) 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 static void
@ -265,7 +420,17 @@ gtk_cell_area_box_get_property (GObject *object,
GValue *value, GValue *value,
GParamSpec *pspec) 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) GtkCellRenderer *renderer)
{ {
gtk_cell_area_box_pack_start (GTK_CELL_AREA_BOX (area), gtk_cell_area_box_pack_start (GTK_CELL_AREA_BOX (area),
renderer, FALSE); renderer, FALSE, TRUE);
} }
static void static void
@ -297,6 +462,16 @@ gtk_cell_area_box_remove (GtkCellArea *area,
cell_info_free (info); cell_info_free (info);
priv->cells = g_list_delete_link (priv->cells, node); 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 else
g_warning ("Trying to remove a cell renderer that is not present GtkCellAreaBox"); g_warning ("Trying to remove a cell renderer that is not present GtkCellAreaBox");
@ -387,136 +562,278 @@ compute_size (GtkCellAreaBox *box,
GtkOrientation orientation, GtkOrientation orientation,
GtkCellAreaBoxIter *iter, GtkCellAreaBoxIter *iter,
GtkWidget *widget, GtkWidget *widget,
gint for_size,
gint *minimum_size, gint *minimum_size,
gint *natural_size) gint *natural_size)
{ {
GtkCellAreaBoxPrivate *priv = box->priv; GtkCellAreaBoxPrivate *priv = box->priv;
CellGroup *group;
CellInfo *info; CellInfo *info;
GList *l; GList *cell_list, *group_list;
gint min_size = 0; gint min_size = 0;
gint nat_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 group_min_size = 0;
gint group_nat_size = 0;
group = group_list->data;
for (cell_list = group->cells; cell_list; cell_list = cell_list->next)
{ {
gint renderer_min_size, renderer_nat_size; gint renderer_min_size, renderer_nat_size;
info = l->data; info = cell_list->data;
get_renderer_size (info->renderer, orientation, widget, -1, get_renderer_size (info->renderer, orientation, widget, for_size,
&renderer_min_size, &renderer_nat_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 (orientation == GTK_ORIENTATION_HORIZONTAL)
gtk_cell_area_box_iter_push_cell_width (iter, info->renderer,
renderer_min_size, renderer_nat_size);
else
gtk_cell_area_box_iter_push_cell_height (iter, info->renderer,
renderer_min_size, renderer_nat_size);
}
if (orientation == priv->orientation) if (orientation == priv->orientation)
{ {
min_size += renderer_min_size; if (min_size > 0)
nat_size += renderer_nat_size;
if (!first_cell)
{ {
min_size += priv->spacing; min_size += priv->spacing;
nat_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 else
{ {
min_size = MAX (min_size, renderer_min_size); min_size = MAX (min_size, renderer_min_size);
nat_size = MAX (nat_size, renderer_nat_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 (first_cell) if (orientation == GTK_ORIENTATION_HORIZONTAL)
first_cell = FALSE; {
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
{
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);
}
} }
*minimum_size = min_size; *minimum_size = min_size;
*natural_size = nat_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 static void
update_iter_aligned (GtkCellAreaBox *box, compute_group_size_for_opposing_orientation (GtkCellAreaBox *box,
GtkCellAreaBoxIter *iter, CellGroup *group,
gint for_size) GtkWidget *widget,
gint for_size,
gint *minimum_size,
gint *natural_size)
{ {
GtkCellAreaBoxPrivate *priv = box->priv; GtkCellAreaBoxPrivate *priv = box->priv;
/* Exception for single cell groups */
if (!group->cells->next)
{
CellInfo *info = group->cells->data;
get_renderer_size (info->renderer,
OPPOSITE_ORIENTATION (priv->orientation),
widget, for_size, minimum_size, natural_size);
}
else
{
GtkRequestedSize *orientation_sizes;
CellInfo *info; CellInfo *info;
GList *l; gint n_sizes, i;
gint min_size = 0; gint n_expand_cells = count_expand_cells (group);
gint nat_size = 0; gint avail_size = for_size;
gboolean first_cell = TRUE; gint extra_size, extra_extra;
gint min_size = 0, nat_size = 0;
for (l = priv->cells; l; l = l->next) 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)
{ {
gint aligned_min_size, aligned_nat_size; extra_size = avail_size / n_expand_cells;
extra_extra = avail_size % n_expand_cells;
}
else
extra_size = extra_extra = 0;
info = l->data; for (i = 0; i < n_sizes; i++)
{
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);
}
*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)
{
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)
{
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) if (priv->orientation == GTK_ORIENTATION_HORIZONTAL)
{ {
if (for_size < 0) gtk_cell_area_box_iter_push_group_height_for_width (iter, group->id, for_size,
gtk_cell_area_box_iter_get_cell_width (iter, info->renderer, group_min, group_nat);
&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);
} }
else else
{ {
if (for_size < 0) gtk_cell_area_box_iter_push_group_width_for_height (iter, group->id, for_size,
gtk_cell_area_box_iter_get_cell_height (iter, info->renderer, group_min, group_nat);
&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);
} }
min_size += aligned_min_size; *minimum_size = min_size;
nat_size += aligned_nat_size; *natural_size = nat_size;
if (!first_cell) g_free (orientation_sizes);
{
min_size += priv->spacing;
nat_size += priv->spacing;
} }
if (first_cell)
first_cell = FALSE;
}
if (priv->orientation == GTK_ORIENTATION_HORIZONTAL)
{
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);
}
else
{
if (for_size < 0)
gtk_cell_area_iter_push_preferred_height (GTK_CELL_AREA_ITER (iter), min_size, nat_size);
else
gtk_cell_area_iter_push_preferred_height_for_width (GTK_CELL_AREA_ITER (iter),
for_size, min_size, nat_size);
}
}
static void static void
gtk_cell_area_box_get_preferred_width (GtkCellArea *area, gtk_cell_area_box_get_preferred_width (GtkCellArea *area,
@ -527,25 +844,16 @@ gtk_cell_area_box_get_preferred_width (GtkCellArea *area,
{ {
GtkCellAreaBox *box = GTK_CELL_AREA_BOX (area); GtkCellAreaBox *box = GTK_CELL_AREA_BOX (area);
GtkCellAreaBoxIter *box_iter; GtkCellAreaBoxIter *box_iter;
GtkCellAreaBoxPrivate *priv;
gint min_width, nat_width; gint min_width, nat_width;
g_return_if_fail (GTK_IS_CELL_AREA_BOX_ITER (iter)); g_return_if_fail (GTK_IS_CELL_AREA_BOX_ITER (iter));
box_iter = GTK_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 */ * bumping cell alignments in the iter along the way */
compute_size (box, GTK_ORIENTATION_HORIZONTAL, compute_size (box, GTK_ORIENTATION_HORIZONTAL,
box_iter, widget, &min_width, &nat_width); box_iter, widget, -1, &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);
if (minimum_width) if (minimum_width)
*minimum_width = min_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); GtkCellAreaBox *box = GTK_CELL_AREA_BOX (area);
GtkCellAreaBoxIter *box_iter; GtkCellAreaBoxIter *box_iter;
GtkCellAreaBoxPrivate *priv;
gint min_height, nat_height; gint min_height, nat_height;
g_return_if_fail (GTK_IS_CELL_AREA_BOX_ITER (iter)); g_return_if_fail (GTK_IS_CELL_AREA_BOX_ITER (iter));
box_iter = GTK_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 */ * bumping cell alignments in the iter along the way */
compute_size (box, GTK_ORIENTATION_VERTICAL, compute_size (box, GTK_ORIENTATION_VERTICAL,
box_iter, widget, &min_height, &nat_height); box_iter, widget, -1, &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);
if (minimum_height) if (minimum_height)
*minimum_height = min_height; *minimum_height = min_height;
@ -590,61 +889,6 @@ gtk_cell_area_box_get_preferred_height (GtkCellArea *area,
*natural_height = nat_height; *natural_height = nat_height;
} }
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 static void
gtk_cell_area_box_get_preferred_height_for_width (GtkCellArea *area, gtk_cell_area_box_get_preferred_height_for_width (GtkCellArea *area,
GtkCellAreaIter *iter, GtkCellAreaIter *iter,
@ -665,21 +909,15 @@ gtk_cell_area_box_get_preferred_height_for_width (GtkCellArea *area,
if (priv->orientation == GTK_ORIENTATION_VERTICAL) 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 */ * cached sizes for alignments */
compute_size_for_orientation (box, box_iter, widget, width, &min_height, &nat_height); compute_size (box, priv->orientation, 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);
} }
else 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 */ * 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) if (minimum_height)
@ -709,21 +947,15 @@ gtk_cell_area_box_get_preferred_width_for_height (GtkCellArea *area,
if (priv->orientation == GTK_ORIENTATION_HORIZONTAL) 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 */ * cached sizes for alignments */
compute_size_for_orientation (box, box_iter, widget, height, &min_width, &nat_width); compute_size (box, priv->orientation, 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);
} }
else else
{ {
/* XXX Juice: virtually allocate cells into the for_width possibly using the /* Juice: horizontally allocate cells into the for_height using the
* alignments and then return the overall height for that width, and cache it */ * 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) if (minimum_width)
@ -750,7 +982,7 @@ gtk_cell_area_box_layout_pack_start (GtkCellLayout *cell_layout,
GtkCellRenderer *renderer, GtkCellRenderer *renderer,
gboolean expand) 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 static void
@ -758,7 +990,7 @@ gtk_cell_area_box_layout_pack_end (GtkCellLayout *cell_layout,
GtkCellRenderer *renderer, GtkCellRenderer *renderer,
gboolean expand) 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 static void
@ -795,7 +1027,8 @@ gtk_cell_area_box_new (void)
void void
gtk_cell_area_box_pack_start (GtkCellAreaBox *box, gtk_cell_area_box_pack_start (GtkCellAreaBox *box,
GtkCellRenderer *renderer, GtkCellRenderer *renderer,
gboolean expand) gboolean expand,
gboolean align)
{ {
GtkCellAreaBoxPrivate *priv; GtkCellAreaBoxPrivate *priv;
CellInfo *info; CellInfo *info;
@ -812,15 +1045,21 @@ gtk_cell_area_box_pack_start (GtkCellAreaBox *box,
return; 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); 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 void
gtk_cell_area_box_pack_end (GtkCellAreaBox *box, gtk_cell_area_box_pack_end (GtkCellAreaBox *box,
GtkCellRenderer *renderer, GtkCellRenderer *renderer,
gboolean expand) gboolean expand,
gboolean align)
{ {
GtkCellAreaBoxPrivate *priv; GtkCellAreaBoxPrivate *priv;
CellInfo *info; CellInfo *info;
@ -837,9 +1076,14 @@ gtk_cell_area_box_pack_end (GtkCellAreaBox *box,
return; 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); 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 gint
@ -864,32 +1108,7 @@ gtk_cell_area_box_set_spacing (GtkCellAreaBox *box,
{ {
priv->spacing = spacing; priv->spacing = spacing;
/* TODO, notify created iters that size needs renegotiation */
g_object_notify (G_OBJECT (box), "spacing"); 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");
}
}

View File

@ -67,16 +67,15 @@ GType gtk_cell_area_box_get_type (void) G_GNUC_CONST;
GtkCellArea *gtk_cell_area_box_new (void); GtkCellArea *gtk_cell_area_box_new (void);
void gtk_cell_area_box_pack_start (GtkCellAreaBox *box, void gtk_cell_area_box_pack_start (GtkCellAreaBox *box,
GtkCellRenderer *renderer, GtkCellRenderer *renderer,
gboolean expand); gboolean expand,
gboolean align);
void gtk_cell_area_box_pack_end (GtkCellAreaBox *box, void gtk_cell_area_box_pack_end (GtkCellAreaBox *box,
GtkCellRenderer *renderer, GtkCellRenderer *renderer,
gboolean expand); gboolean expand,
gboolean align);
gint gtk_cell_area_box_get_spacing (GtkCellAreaBox *box); gint gtk_cell_area_box_get_spacing (GtkCellAreaBox *box);
void gtk_cell_area_box_set_spacing (GtkCellAreaBox *box, void gtk_cell_area_box_set_spacing (GtkCellAreaBox *box,
gint spacing); 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 G_END_DECLS

View File

@ -23,12 +23,19 @@
#include "config.h" #include "config.h"
#include "gtkintl.h" #include "gtkintl.h"
#include "gtkcellareabox.h"
#include "gtkcellareaboxiter.h" #include "gtkcellareaboxiter.h"
/* GObjectClass */ /* GObjectClass */
static void gtk_cell_area_box_iter_finalize (GObject *object); static void gtk_cell_area_box_iter_finalize (GObject *object);
/* GtkCellAreaIterClass */ /* 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_width (GtkCellAreaIter *iter);
static void gtk_cell_area_box_iter_flush_preferred_height_for_width (GtkCellAreaIter *iter, static void gtk_cell_area_box_iter_flush_preferred_height_for_width (GtkCellAreaIter *iter,
gint width); gint width);
@ -88,6 +95,11 @@ gtk_cell_area_box_iter_class_init (GtkCellAreaBoxIterClass *class)
/* GObjectClass */ /* GObjectClass */
object_class->finalize = gtk_cell_area_box_iter_finalize; 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_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_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; 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 * * 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 static void
gtk_cell_area_box_iter_flush_preferred_width (GtkCellAreaIter *iter) gtk_cell_area_box_iter_flush_preferred_width (GtkCellAreaIter *iter)
{ {
@ -200,8 +308,8 @@ gtk_cell_area_box_iter_flush_preferred_width_for_height (GtkCellAreaIter *iter,
*************************************************************/ *************************************************************/
void void
gtk_cell_area_box_iter_push_cell_width (GtkCellAreaBoxIter *box_iter, gtk_cell_area_box_iter_push_group_width (GtkCellAreaBoxIter *box_iter,
GtkCellRenderer *renderer, gint group_id,
gint minimum_width, gint minimum_width,
gint natural_width) gint natural_width)
{ {
@ -209,15 +317,14 @@ gtk_cell_area_box_iter_push_cell_width (GtkCellAreaBoxIter *box_iter,
CachedSize *size; CachedSize *size;
g_return_if_fail (GTK_IS_CELL_AREA_BOX_ITER (box_iter)); 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; 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) if (!size)
{ {
size = cached_size_new (minimum_width, natural_width); 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 else
{ {
@ -227,36 +334,35 @@ gtk_cell_area_box_iter_push_cell_width (GtkCellAreaBoxIter *box_iter,
} }
void void
gtk_cell_area_box_iter_push_cell_height_for_width (GtkCellAreaBoxIter *box_iter, gtk_cell_area_box_iter_push_group_height_for_width (GtkCellAreaBoxIter *box_iter,
GtkCellRenderer *renderer, gint group_id,
gint for_width, gint for_width,
gint minimum_height, gint minimum_height,
gint natural_height) gint natural_height)
{ {
GtkCellAreaBoxIterPrivate *priv; GtkCellAreaBoxIterPrivate *priv;
GHashTable *cell_table; GHashTable *group_table;
CachedSize *size; CachedSize *size;
g_return_if_fail (GTK_IS_CELL_AREA_BOX_ITER (box_iter)); 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; priv = box_iter->priv;
cell_table = g_hash_table_lookup (priv->heights, GINT_TO_POINTER (for_width)); 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); 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) if (!size)
{ {
size = cached_size_new (minimum_height, natural_height); 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 else
{ {
@ -266,8 +372,8 @@ gtk_cell_area_box_iter_push_cell_height_for_width (GtkCellAreaBoxIter *box_iter
} }
void void
gtk_cell_area_box_iter_push_cell_height (GtkCellAreaBoxIter *box_iter, gtk_cell_area_box_iter_push_group_height (GtkCellAreaBoxIter *box_iter,
GtkCellRenderer *renderer, gint group_id,
gint minimum_height, gint minimum_height,
gint natural_height) gint natural_height)
{ {
@ -275,15 +381,14 @@ gtk_cell_area_box_iter_push_cell_height (GtkCellAreaBoxIter *box_iter,
CachedSize *size; CachedSize *size;
g_return_if_fail (GTK_IS_CELL_AREA_BOX_ITER (box_iter)); 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; 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) if (!size)
{ {
size = cached_size_new (minimum_height, natural_height); 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 else
{ {
@ -293,36 +398,35 @@ gtk_cell_area_box_iter_push_cell_height (GtkCellAreaBoxIter *box_iter,
} }
void void
gtk_cell_area_box_iter_push_cell_width_for_height (GtkCellAreaBoxIter *box_iter, gtk_cell_area_box_iter_push_group_width_for_height (GtkCellAreaBoxIter *box_iter,
GtkCellRenderer *renderer, gint group_id,
gint for_height, gint for_height,
gint minimum_width, gint minimum_width,
gint natural_width) gint natural_width)
{ {
GtkCellAreaBoxIterPrivate *priv; GtkCellAreaBoxIterPrivate *priv;
GHashTable *cell_table; GHashTable *group_table;
CachedSize *size; CachedSize *size;
g_return_if_fail (GTK_IS_CELL_AREA_BOX_ITER (box_iter)); 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; priv = box_iter->priv;
cell_table = g_hash_table_lookup (priv->widths, GINT_TO_POINTER (for_height)); 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); 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) if (!size)
{ {
size = cached_size_new (minimum_width, natural_width); 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 else
{ {
@ -332,8 +436,8 @@ gtk_cell_area_box_iter_push_cell_width_for_height (GtkCellAreaBoxIter *box_iter,
} }
void void
gtk_cell_area_box_iter_get_cell_width (GtkCellAreaBoxIter *box_iter, gtk_cell_area_box_iter_get_group_width (GtkCellAreaBoxIter *box_iter,
GtkCellRenderer *renderer, gint group_id,
gint *minimum_width, gint *minimum_width,
gint *natural_width) gint *natural_width)
{ {
@ -341,10 +445,9 @@ gtk_cell_area_box_iter_get_cell_width (GtkCellAreaBoxIter *box_iter,
CachedSize *size; CachedSize *size;
g_return_if_fail (GTK_IS_CELL_AREA_BOX_ITER (box_iter)); 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; 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) if (size)
{ {
@ -365,24 +468,23 @@ gtk_cell_area_box_iter_get_cell_width (GtkCellAreaBoxIter *box_iter,
} }
void void
gtk_cell_area_box_iter_get_cell_height_for_width (GtkCellAreaBoxIter *box_iter, gtk_cell_area_box_iter_get_group_height_for_width (GtkCellAreaBoxIter *box_iter,
GtkCellRenderer *renderer, gint group_id,
gint for_width, gint for_width,
gint *minimum_height, gint *minimum_height,
gint *natural_height) gint *natural_height)
{ {
GtkCellAreaBoxIterPrivate *priv; GtkCellAreaBoxIterPrivate *priv;
GHashTable *cell_table; GHashTable *group_table;
CachedSize *size = NULL; CachedSize *size = NULL;
g_return_if_fail (GTK_IS_CELL_AREA_BOX_ITER (box_iter)); 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; priv = box_iter->priv;
cell_table = g_hash_table_lookup (priv->heights, GINT_TO_POINTER (for_width)); group_table = g_hash_table_lookup (priv->heights, GINT_TO_POINTER (for_width));
if (cell_table) if (group_table)
size = g_hash_table_lookup (cell_table, renderer); size = g_hash_table_lookup (group_table, GINT_TO_POINTER (group_id));
if (size) if (size)
{ {
@ -403,8 +505,8 @@ gtk_cell_area_box_iter_get_cell_height_for_width (GtkCellAreaBoxIter *box_iter,
} }
void void
gtk_cell_area_box_iter_get_cell_height (GtkCellAreaBoxIter *box_iter, gtk_cell_area_box_iter_get_group_height (GtkCellAreaBoxIter *box_iter,
GtkCellRenderer *renderer, gint group_id,
gint *minimum_height, gint *minimum_height,
gint *natural_height) gint *natural_height)
{ {
@ -412,10 +514,9 @@ gtk_cell_area_box_iter_get_cell_height (GtkCellAreaBoxIter *box_iter,
CachedSize *size; CachedSize *size;
g_return_if_fail (GTK_IS_CELL_AREA_BOX_ITER (box_iter)); 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; 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) if (size)
{ {
@ -436,24 +537,23 @@ gtk_cell_area_box_iter_get_cell_height (GtkCellAreaBoxIter *box_iter,
} }
void void
gtk_cell_area_box_iter_get_cell_width_for_height (GtkCellAreaBoxIter *box_iter, gtk_cell_area_box_iter_get_group_width_for_height (GtkCellAreaBoxIter *box_iter,
GtkCellRenderer *renderer, gint group_id,
gint for_height, gint for_height,
gint *minimum_width, gint *minimum_width,
gint *natural_width) gint *natural_width)
{ {
GtkCellAreaBoxIterPrivate *priv; GtkCellAreaBoxIterPrivate *priv;
GHashTable *cell_table; GHashTable *group_table;
CachedSize *size = NULL; CachedSize *size = NULL;
g_return_if_fail (GTK_IS_CELL_AREA_BOX_ITER (box_iter)); 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; priv = box_iter->priv;
cell_table = g_hash_table_lookup (priv->widths, GINT_TO_POINTER (for_height)); group_table = g_hash_table_lookup (priv->widths, GINT_TO_POINTER (for_height));
if (cell_table) if (group_table)
size = g_hash_table_lookup (cell_table, renderer); size = g_hash_table_lookup (group_table, GINT_TO_POINTER (group_id));
if (size) if (size)
{ {
@ -472,3 +572,53 @@ gtk_cell_area_box_iter_get_cell_width_for_height (GtkCellAreaBoxIter *box_iter,
*natural_width = -1; *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;
}

View File

@ -30,6 +30,7 @@
#include <gtk/gtkcellareaiter.h> #include <gtk/gtkcellareaiter.h>
#include <gtk/gtkcellrenderer.h> #include <gtk/gtkcellrenderer.h>
#include <gtk/gtksizerequest.h>
G_BEGIN_DECLS G_BEGIN_DECLS
@ -60,52 +61,57 @@ struct _GtkCellAreaBoxIterClass
GType gtk_cell_area_box_iter_get_type (void) G_GNUC_CONST; GType gtk_cell_area_box_iter_get_type (void) G_GNUC_CONST;
/* Update cell alignments */ /* Update cell-group sizes */
void gtk_cell_area_box_iter_push_cell_width (GtkCellAreaBoxIter *box_iter, void gtk_cell_area_box_iter_push_group_width (GtkCellAreaBoxIter *box_iter,
GtkCellRenderer *renderer, gint group_id,
gint minimum_width, gint minimum_width,
gint natural_width); gint natural_width);
void gtk_cell_area_box_iter_push_cell_height_for_width (GtkCellAreaBoxIter *box_iter, void gtk_cell_area_box_iter_push_group_height_for_width (GtkCellAreaBoxIter *box_iter,
GtkCellRenderer *renderer, gint group_id,
gint for_width, gint for_width,
gint minimum_height, gint minimum_height,
gint natural_height); gint natural_height);
void gtk_cell_area_box_iter_push_cell_height (GtkCellAreaBoxIter *box_iter, void gtk_cell_area_box_iter_push_group_height (GtkCellAreaBoxIter *box_iter,
GtkCellRenderer *renderer, gint group_id,
gint minimum_height, gint minimum_height,
gint natural_height); gint natural_height);
void gtk_cell_area_box_iter_push_cell_width_for_height (GtkCellAreaBoxIter *box_iter, void gtk_cell_area_box_iter_push_group_width_for_height (GtkCellAreaBoxIter *box_iter,
GtkCellRenderer *renderer, gint group_id,
gint for_height, gint for_height,
gint minimum_width, gint minimum_width,
gint natural_width); gint natural_width);
/* Fetch cell alignments */ /* Fetch cell-group sizes */
void gtk_cell_area_box_iter_get_cell_width (GtkCellAreaBoxIter *box_iter, void gtk_cell_area_box_iter_get_group_width (GtkCellAreaBoxIter *box_iter,
GtkCellRenderer *renderer, gint group_id,
gint *minimum_width, gint *minimum_width,
gint *natural_width); gint *natural_width);
void gtk_cell_area_box_iter_get_cell_height_for_width (GtkCellAreaBoxIter *box_iter, void gtk_cell_area_box_iter_get_group_height_for_width (GtkCellAreaBoxIter *box_iter,
GtkCellRenderer *renderer, gint group_id,
gint for_width, gint for_width,
gint *minimum_height, gint *minimum_height,
gint *natural_height); gint *natural_height);
void gtk_cell_area_box_iter_get_cell_height (GtkCellAreaBoxIter *box_iter, void gtk_cell_area_box_iter_get_group_height (GtkCellAreaBoxIter *box_iter,
GtkCellRenderer *renderer, gint group_id,
gint *minimum_height, gint *minimum_height,
gint *natural_height); gint *natural_height);
void gtk_cell_area_box_iter_get_cell_width_for_height (GtkCellAreaBoxIter *box_iter, void gtk_cell_area_box_iter_get_group_width_for_height (GtkCellAreaBoxIter *box_iter,
GtkCellRenderer *renderer, gint group_id,
gint for_height, gint for_height,
gint *minimum_width, gint *minimum_width,
gint *natural_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 G_END_DECLS
#endif /* __GTK_CELL_AREA_BOX_ITER_H__ */ #endif /* __GTK_CELL_AREA_BOX_ITER_H__ */

View File

@ -25,13 +25,19 @@
#include "gtkintl.h" #include "gtkintl.h"
#include "gtkmarshalers.h" #include "gtkmarshalers.h"
#include "gtkcellareaiter.h" #include "gtkcellareaiter.h"
#include "gtkprivate.h"
/* GObjectClass */ /* GObjectClass */
static void gtk_cell_area_iter_finalize (GObject *object); 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, static void gtk_cell_area_iter_get_property (GObject *object,
guint prop_id, guint prop_id,
GValue *value, GValue *value,
GParamSpec *pspec); GParamSpec *pspec);
static void gtk_cell_area_iter_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec);
/* GtkCellAreaIterClass */ /* GtkCellAreaIterClass */
static void gtk_cell_area_iter_real_flush_preferred_width (GtkCellAreaIter *iter); static void gtk_cell_area_iter_real_flush_preferred_width (GtkCellAreaIter *iter);
@ -52,6 +58,8 @@ static void cached_size_free (CachedSize *size);
struct _GtkCellAreaIterPrivate struct _GtkCellAreaIterPrivate
{ {
GtkCellArea *cell_area;
gint min_width; gint min_width;
gint nat_width; gint nat_width;
gint min_height; gint min_height;
@ -63,6 +71,7 @@ struct _GtkCellAreaIterPrivate
enum { enum {
PROP_0, PROP_0,
PROP_CELL_AREA,
PROP_MIN_WIDTH, PROP_MIN_WIDTH,
PROP_NAT_WIDTH, PROP_NAT_WIDTH,
PROP_MIN_HEIGHT, PROP_MIN_HEIGHT,
@ -106,7 +115,9 @@ gtk_cell_area_iter_class_init (GtkCellAreaIterClass *class)
/* GObjectClass */ /* GObjectClass */
object_class->finalize = gtk_cell_area_iter_finalize; 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->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_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; class->flush_preferred_height_for_width = gtk_cell_area_iter_real_flush_preferred_height_for_width;
@ -133,6 +144,14 @@ gtk_cell_area_iter_class_init (GtkCellAreaIterClass *class)
G_TYPE_NONE, 3, G_TYPE_NONE, 3,
G_TYPE_INT, G_TYPE_INT, G_TYPE_INT); 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, g_object_class_install_property (object_class,
PROP_MIN_WIDTH, PROP_MIN_WIDTH,
g_param_spec_int ("minimum-width", g_param_spec_int ("minimum-width",
@ -214,6 +233,42 @@ gtk_cell_area_iter_finalize (GObject *object)
G_OBJECT_CLASS (gtk_cell_area_iter_parent_class)->finalize (object); G_OBJECT_CLASS (gtk_cell_area_iter_parent_class)->finalize (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 static void
gtk_cell_area_iter_get_property (GObject *object, gtk_cell_area_iter_get_property (GObject *object,
guint prop_id, guint prop_id,
@ -225,6 +280,9 @@ gtk_cell_area_iter_get_property (GObject *object,
switch (prop_id) switch (prop_id)
{ {
case PROP_CELL_AREA:
g_value_set_object (value, priv->cell_area);
break;
case PROP_MIN_WIDTH: case PROP_MIN_WIDTH:
g_value_set_int (value, priv->min_width); g_value_set_int (value, priv->min_width);
break; break;
@ -307,6 +365,17 @@ gtk_cell_area_iter_real_flush_preferred_width_for_height (GtkCellAreaIter *iter,
/************************************************************* /*************************************************************
* API * * 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 void
gtk_cell_area_iter_get_preferred_width (GtkCellAreaIter *iter, 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 void
gtk_cell_area_iter_push_preferred_width (GtkCellAreaIter *iter, 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, g_signal_emit (iter, cell_area_iter_signals[SIGNAL_WIDTH_CHANGED], 0,
for_height, size->min_size, size->nat_size); 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);
}

View File

@ -28,7 +28,7 @@
#ifndef __GTK_CELL_AREA_ITER_H__ #ifndef __GTK_CELL_AREA_ITER_H__
#define __GTK_CELL_AREA_ITER_H__ #define __GTK_CELL_AREA_ITER_H__
#include <glib-object.h> #include <gtk/gtkcellarea.h>
G_BEGIN_DECLS 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_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)) #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 _GtkCellAreaIterPrivate GtkCellAreaIterPrivate;
typedef struct _GtkCellAreaIterClass GtkCellAreaIterClass; typedef struct _GtkCellAreaIterClass GtkCellAreaIterClass;
@ -62,6 +61,16 @@ struct _GtkCellAreaIterClass
void (* flush_preferred_width_for_height) (GtkCellAreaIter *iter, void (* flush_preferred_width_for_height) (GtkCellAreaIter *iter,
gint height); 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 */ /* Padding for future expansion */
void (*_gtk_reserved1) (void); void (*_gtk_reserved1) (void);
void (*_gtk_reserved2) (void); void (*_gtk_reserved2) (void);
@ -71,6 +80,8 @@ struct _GtkCellAreaIterClass
GType gtk_cell_area_iter_get_type (void) G_GNUC_CONST; GType gtk_cell_area_iter_get_type (void) G_GNUC_CONST;
GtkCellArea *gtk_cell_area_iter_get_area (GtkCellAreaIter *iter);
/* Apis for GtkCellArea clients to consult cached values for multiple GtkTreeModel rows */ /* Apis for GtkCellArea clients to consult cached values for multiple GtkTreeModel rows */
void gtk_cell_area_iter_get_preferred_width (GtkCellAreaIter *iter, void gtk_cell_area_iter_get_preferred_width (GtkCellAreaIter *iter,
gint *minimum_width, gint *minimum_width,
@ -87,6 +98,24 @@ void gtk_cell_area_iter_get_preferred_width_for_height (GtkCellAreaIter *
gint *minimum_width, gint *minimum_width,
gint *natural_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);
/* Apis for GtkCellArea implementations to update cached values for multiple GtkTreeModel rows */ /* Apis for GtkCellArea implementations to update cached values for multiple GtkTreeModel rows */
void gtk_cell_area_iter_push_preferred_width (GtkCellAreaIter *iter, void gtk_cell_area_iter_push_preferred_width (GtkCellAreaIter *iter,
gint minimum_width, gint minimum_width,
@ -103,15 +132,6 @@ void gtk_cell_area_iter_push_preferred_width_for_height (GtkCellAreaIter *
gint minimum_width, gint minimum_width,
gint natural_width); gint natural_width);
/* 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);
G_END_DECLS G_END_DECLS
#endif /* __GTK_CELL_AREA_ITER_H__ */ #endif /* __GTK_CELL_AREA_ITER_H__ */