forked from AuroraMiddleware/gtk
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:
parent
211c39c500
commit
3b1c301a66
@ -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:
|
||||
|
@ -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;
|
||||
gint group_min_size = 0;
|
||||
gint group_nat_size = 0;
|
||||
|
||||
info = l->data;
|
||||
group = group_list->data;
|
||||
|
||||
get_renderer_size (info->renderer, orientation, widget, -1,
|
||||
&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)
|
||||
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;
|
||||
}
|
||||
|
||||
static void
|
||||
update_iter_aligned (GtkCellAreaBox *box,
|
||||
GtkCellAreaBoxIter *iter,
|
||||
gint for_size)
|
||||
GtkRequestedSize *
|
||||
get_group_sizes (CellGroup *group,
|
||||
GtkOrientation orientation,
|
||||
GtkWidget *widget,
|
||||
gint *n_sizes)
|
||||
{
|
||||
GtkCellAreaBoxPrivate *priv = box->priv;
|
||||
CellInfo *info;
|
||||
GList *l;
|
||||
gint min_size = 0;
|
||||
gint nat_size = 0;
|
||||
gboolean first_cell = TRUE;
|
||||
GtkRequestedSize *sizes;
|
||||
GList *l;
|
||||
gint i;
|
||||
|
||||
for (l = priv->cells; l; l = l->next)
|
||||
*n_sizes = g_list_length (group->cells);
|
||||
sizes = g_new (GtkRequestedSize, *n_sizes);
|
||||
|
||||
for (l = group->cells, i = 0; l; l = l->next, i++)
|
||||
{
|
||||
gint aligned_min_size, aligned_nat_size;
|
||||
|
||||
info = l->data;
|
||||
CellInfo *info = l->data;
|
||||
|
||||
if (priv->orientation == GTK_ORIENTATION_HORIZONTAL)
|
||||
{
|
||||
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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
min_size += aligned_min_size;
|
||||
nat_size += aligned_nat_size;
|
||||
sizes[i].data = info;
|
||||
|
||||
if (!first_cell)
|
||||
{
|
||||
min_size += priv->spacing;
|
||||
nat_size += priv->spacing;
|
||||
}
|
||||
|
||||
if (first_cell)
|
||||
first_cell = FALSE;
|
||||
get_renderer_size (info->renderer,
|
||||
orientation, widget, -1,
|
||||
&sizes[i].minimum_size,
|
||||
&sizes[i].natural_size);
|
||||
}
|
||||
|
||||
if (priv->orientation == GTK_ORIENTATION_HORIZONTAL)
|
||||
return sizes;
|
||||
}
|
||||
|
||||
static void
|
||||
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;
|
||||
|
||||
/* Exception for single cell groups */
|
||||
if (!group->cells->next)
|
||||
{
|
||||
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);
|
||||
CellInfo *info = group->cells->data;
|
||||
|
||||
get_renderer_size (info->renderer,
|
||||
OPPOSITE_ORIENTATION (priv->orientation),
|
||||
widget, for_size, minimum_size, natural_size);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (for_size < 0)
|
||||
gtk_cell_area_iter_push_preferred_height (GTK_CELL_AREA_ITER (iter), min_size, nat_size);
|
||||
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)
|
||||
{
|
||||
extra_size = avail_size / n_expand_cells;
|
||||
extra_extra = avail_size % n_expand_cells;
|
||||
}
|
||||
else
|
||||
gtk_cell_area_iter_push_preferred_height_for_width (GTK_CELL_AREA_ITER (iter),
|
||||
for_size, min_size, nat_size);
|
||||
extra_size = extra_extra = 0;
|
||||
|
||||
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)
|
||||
{
|
||||
gtk_cell_area_box_iter_push_group_height_for_width (iter, group->id, for_size,
|
||||
group_min, group_nat);
|
||||
}
|
||||
else
|
||||
{
|
||||
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;
|
||||
@ -590,61 +889,6 @@ gtk_cell_area_box_get_preferred_height (GtkCellArea *area,
|
||||
*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
|
||||
gtk_cell_area_box_get_preferred_height_for_width (GtkCellArea *area,
|
||||
GtkCellAreaIter *iter,
|
||||
@ -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");
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
||||
|
@ -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,58 +398,162 @@ 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,
|
||||
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 *group_table;
|
||||
CachedSize *size;
|
||||
|
||||
g_return_if_fail (GTK_IS_CELL_AREA_BOX_ITER (box_iter));
|
||||
|
||||
priv = box_iter->priv;
|
||||
group_table = g_hash_table_lookup (priv->widths, GINT_TO_POINTER (for_height));
|
||||
|
||||
if (!group_table)
|
||||
{
|
||||
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), group_table);
|
||||
}
|
||||
|
||||
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 (group_table, GINT_TO_POINTER (group_id), size);
|
||||
}
|
||||
else
|
||||
{
|
||||
size->min_size = MAX (size->min_size, minimum_width);
|
||||
size->nat_size = MAX (size->nat_size, natural_width);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
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));
|
||||
|
||||
priv = box_iter->priv;
|
||||
size = g_hash_table_lookup (priv->base_widths, GINT_TO_POINTER (group_id));
|
||||
|
||||
if (size)
|
||||
{
|
||||
if (minimum_width)
|
||||
*minimum_width = size->min_size;
|
||||
|
||||
if (natural_width)
|
||||
*natural_width = size->nat_size;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (minimum_width)
|
||||
*minimum_width = -1;
|
||||
|
||||
if (natural_width)
|
||||
*natural_width = -1;
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
GtkCellAreaBoxIterPrivate *priv;
|
||||
GHashTable *group_table;
|
||||
CachedSize *size = NULL;
|
||||
|
||||
g_return_if_fail (GTK_IS_CELL_AREA_BOX_ITER (box_iter));
|
||||
|
||||
priv = box_iter->priv;
|
||||
group_table = g_hash_table_lookup (priv->heights, GINT_TO_POINTER (for_width));
|
||||
|
||||
if (group_table)
|
||||
size = g_hash_table_lookup (group_table, GINT_TO_POINTER (group_id));
|
||||
|
||||
if (size)
|
||||
{
|
||||
if (minimum_height)
|
||||
*minimum_height = size->min_size;
|
||||
|
||||
if (natural_height)
|
||||
*natural_height = size->nat_size;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (minimum_height)
|
||||
*minimum_height = -1;
|
||||
|
||||
if (natural_height)
|
||||
*natural_height = -1;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
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));
|
||||
|
||||
priv = box_iter->priv;
|
||||
size = g_hash_table_lookup (priv->base_heights, GINT_TO_POINTER (group_id));
|
||||
|
||||
if (size)
|
||||
{
|
||||
if (minimum_height)
|
||||
*minimum_height = size->min_size;
|
||||
|
||||
if (natural_height)
|
||||
*natural_height = size->nat_size;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (minimum_height)
|
||||
*minimum_height = -1;
|
||||
|
||||
if (natural_height)
|
||||
*natural_height = -1;
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
gint *minimum_width,
|
||||
gint *natural_width)
|
||||
{
|
||||
GtkCellAreaBoxIterPrivate *priv;
|
||||
GHashTable *cell_table;
|
||||
CachedSize *size;
|
||||
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)
|
||||
{
|
||||
cell_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);
|
||||
}
|
||||
|
||||
size = g_hash_table_lookup (cell_table, renderer);
|
||||
|
||||
if (!size)
|
||||
{
|
||||
size = cached_size_new (minimum_width, natural_width);
|
||||
g_hash_table_insert (cell_table, renderer, size);
|
||||
}
|
||||
else
|
||||
{
|
||||
size->min_size = MAX (size->min_size, minimum_width);
|
||||
size->nat_size = MAX (size->nat_size, natural_width);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
gtk_cell_area_box_iter_get_cell_width (GtkCellAreaBoxIter *box_iter,
|
||||
GtkCellRenderer *renderer,
|
||||
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);
|
||||
if (group_table)
|
||||
size = g_hash_table_lookup (group_table, GINT_TO_POINTER (group_id));
|
||||
|
||||
if (size)
|
||||
{
|
||||
@ -364,111 +573,52 @@ 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)
|
||||
static void
|
||||
fill_requested_sizes (gpointer group_id_ptr,
|
||||
CachedSize *cached_size,
|
||||
GtkRequestedSize *requested)
|
||||
{
|
||||
GtkCellAreaBoxIterPrivate *priv;
|
||||
GHashTable *cell_table;
|
||||
CachedSize *size = NULL;
|
||||
gint group_id = GPOINTER_TO_INT (group_id_ptr);
|
||||
|
||||
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));
|
||||
|
||||
if (cell_table)
|
||||
size = g_hash_table_lookup (cell_table, renderer);
|
||||
|
||||
if (size)
|
||||
{
|
||||
if (minimum_height)
|
||||
*minimum_height = size->min_size;
|
||||
|
||||
if (natural_height)
|
||||
*natural_height = size->nat_size;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (minimum_height)
|
||||
*minimum_height = -1;
|
||||
|
||||
if (natural_height)
|
||||
*natural_height = -1;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
void
|
||||
gtk_cell_area_box_iter_get_cell_height (GtkCellAreaBoxIter *box_iter,
|
||||
GtkCellRenderer *renderer,
|
||||
gint *minimum_height,
|
||||
gint *natural_height)
|
||||
GtkRequestedSize *
|
||||
gtk_cell_area_box_iter_get_widths (GtkCellAreaBoxIter *box_iter,
|
||||
gint *n_widths)
|
||||
{
|
||||
GtkCellAreaBoxIterPrivate *priv;
|
||||
CachedSize *size;
|
||||
GtkRequestedSize *widths;
|
||||
|
||||
g_return_if_fail (GTK_IS_CELL_AREA_BOX_ITER (box_iter));
|
||||
g_return_if_fail (GTK_IS_CELL_RENDERER (renderer));
|
||||
g_return_val_if_fail (GTK_IS_CELL_AREA_BOX_ITER (box_iter), NULL);
|
||||
|
||||
priv = box_iter->priv;
|
||||
size = g_hash_table_lookup (priv->base_heights, renderer);
|
||||
|
||||
if (size)
|
||||
{
|
||||
if (minimum_height)
|
||||
*minimum_height = size->min_size;
|
||||
*n_widths = g_hash_table_size (priv->widths);
|
||||
widths = g_new (GtkRequestedSize, *n_widths);
|
||||
|
||||
if (natural_height)
|
||||
*natural_height = size->nat_size;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (minimum_height)
|
||||
*minimum_height = -1;
|
||||
g_hash_table_foreach (priv->widths, (GHFunc)fill_requested_sizes, widths);
|
||||
|
||||
if (natural_height)
|
||||
*natural_height = -1;
|
||||
}
|
||||
return widths;
|
||||
}
|
||||
|
||||
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)
|
||||
GtkRequestedSize *
|
||||
gtk_cell_area_box_iter_get_heights (GtkCellAreaBoxIter *box_iter,
|
||||
gint *n_heights)
|
||||
{
|
||||
GtkCellAreaBoxIterPrivate *priv;
|
||||
GHashTable *cell_table;
|
||||
CachedSize *size = NULL;
|
||||
GtkRequestedSize *heights;
|
||||
|
||||
g_return_if_fail (GTK_IS_CELL_AREA_BOX_ITER (box_iter));
|
||||
g_return_if_fail (GTK_IS_CELL_RENDERER (renderer));
|
||||
g_return_val_if_fail (GTK_IS_CELL_AREA_BOX_ITER (box_iter), NULL);
|
||||
|
||||
priv = box_iter->priv;
|
||||
cell_table = g_hash_table_lookup (priv->widths, GINT_TO_POINTER (for_height));
|
||||
priv = box_iter->priv;
|
||||
|
||||
if (cell_table)
|
||||
size = g_hash_table_lookup (cell_table, renderer);
|
||||
*n_heights = g_hash_table_size (priv->heights);
|
||||
heights = g_new (GtkRequestedSize, *n_heights);
|
||||
|
||||
if (size)
|
||||
{
|
||||
if (minimum_width)
|
||||
*minimum_width = size->min_size;
|
||||
g_hash_table_foreach (priv->heights, (GHFunc)fill_requested_sizes, heights);
|
||||
|
||||
if (natural_width)
|
||||
*natural_width = size->nat_size;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (minimum_width)
|
||||
*minimum_width = -1;
|
||||
|
||||
if (natural_width)
|
||||
*natural_width = -1;
|
||||
}
|
||||
return heights;
|
||||
}
|
||||
|
@ -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;
|
||||
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);
|
||||
/* 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_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_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_cell_height (GtkCellAreaBoxIter *box_iter,
|
||||
GtkCellRenderer *renderer,
|
||||
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_cell_width_for_height (GtkCellAreaBoxIter *box_iter,
|
||||
GtkCellRenderer *renderer,
|
||||
gint for_height,
|
||||
gint minimum_width,
|
||||
gint natural_width);
|
||||
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 alignments */
|
||||
void gtk_cell_area_box_iter_get_cell_width (GtkCellAreaBoxIter *box_iter,
|
||||
GtkCellRenderer *renderer,
|
||||
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_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_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_cell_height (GtkCellAreaBoxIter *box_iter,
|
||||
GtkCellRenderer *renderer,
|
||||
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_cell_width_for_height (GtkCellAreaBoxIter *box_iter,
|
||||
GtkCellRenderer *renderer,
|
||||
gint for_height,
|
||||
gint *minimum_width,
|
||||
gint *natural_width);
|
||||
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
|
||||
|
||||
|
@ -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;
|
||||
|
||||
GHashTable *widths;
|
||||
GHashTable *heights;
|
||||
gint min_width;
|
||||
gint nat_width;
|
||||
gint min_height;
|
||||
gint nat_height;
|
||||
|
||||
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;
|
||||
@ -133,6 +144,14 @@ gtk_cell_area_iter_class_init (GtkCellAreaIterClass *class)
|
||||
G_TYPE_NONE, 3,
|
||||
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",
|
||||
@ -214,6 +233,42 @@ gtk_cell_area_iter_finalize (GObject *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
|
||||
gtk_cell_area_iter_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
GtkCellArea *gtk_cell_area_iter_get_area (GtkCellAreaIter *iter);
|
||||
|
||||
/* 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);
|
||||
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 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 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
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user