Account for the possibility of invisible cells in GtkCellAreaBox/Iter
Also changed the GtkCellAreaBox to keep groups in an array instead of a list, for this code it's generally more useful this way (and more optimized).
This commit is contained in:
@@ -143,14 +143,12 @@ static CellInfo *cell_info_new (GtkCellRenderer *renderer,
|
||||
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 AllocatedCell *allocated_cell_new (GtkCellRenderer *renderer,
|
||||
gint position,
|
||||
gint size);
|
||||
static void allocated_cell_free (AllocatedCell *cell);
|
||||
static GList *list_consecutive_cells (GtkCellAreaBox *box);
|
||||
static GList *construct_cell_groups (GtkCellAreaBox *box);
|
||||
static gint count_expand_groups (GtkCellAreaBox *box);
|
||||
static void iter_weak_notify (GtkCellAreaBox *box,
|
||||
GtkCellAreaBoxIter *dead_iter);
|
||||
@@ -168,7 +166,7 @@ struct _GtkCellAreaBoxPrivate
|
||||
GtkOrientation orientation;
|
||||
|
||||
GList *cells;
|
||||
GList *groups;
|
||||
GArray *groups;
|
||||
|
||||
GSList *iters;
|
||||
|
||||
@@ -208,8 +206,8 @@ gtk_cell_area_box_init (GtkCellAreaBox *box)
|
||||
priv = box->priv;
|
||||
|
||||
priv->orientation = GTK_ORIENTATION_HORIZONTAL;
|
||||
priv->groups = g_array_new (FALSE, TRUE, sizeof (CellGroup));
|
||||
priv->cells = NULL;
|
||||
priv->groups = NULL;
|
||||
priv->iters = NULL;
|
||||
priv->spacing = 0;
|
||||
}
|
||||
@@ -324,23 +322,6 @@ 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 AllocatedCell *
|
||||
allocated_cell_new (GtkCellRenderer *renderer,
|
||||
gint position,
|
||||
@@ -393,21 +374,39 @@ list_consecutive_cells (GtkCellAreaBox *box)
|
||||
return consecutive_cells;
|
||||
}
|
||||
|
||||
static GList *
|
||||
construct_cell_groups (GtkCellAreaBox *box)
|
||||
static void
|
||||
cell_groups_clear (GtkCellAreaBox *box)
|
||||
{
|
||||
GtkCellAreaBoxPrivate *priv = box->priv;
|
||||
CellGroup *group;
|
||||
GtkCellAreaBoxPrivate *priv = box->priv;
|
||||
gint i;
|
||||
|
||||
for (i = 0; i < priv->groups->len; i++)
|
||||
{
|
||||
CellGroup *group = &g_array_index (priv->groups, CellGroup, i);
|
||||
|
||||
g_list_free (group->cells);
|
||||
}
|
||||
|
||||
g_array_set_size (priv->groups, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
cell_groups_rebuild (GtkCellAreaBox *box)
|
||||
{
|
||||
GtkCellAreaBoxPrivate *priv = box->priv;
|
||||
CellGroup group = { 0, };
|
||||
GList *cells, *l;
|
||||
GList *groups = NULL;
|
||||
guint id = 0;
|
||||
|
||||
if (!priv->cells)
|
||||
return NULL;
|
||||
cell_groups_clear (box);
|
||||
|
||||
cells = list_consecutive_cells (box);
|
||||
group = cell_group_new (id++);
|
||||
groups = g_list_prepend (groups, group);
|
||||
if (!priv->cells)
|
||||
return;
|
||||
|
||||
cells = list_consecutive_cells (box);
|
||||
|
||||
/* First group is implied */
|
||||
g_array_append_val (priv->groups, group);
|
||||
|
||||
for (l = cells; l; l = l->next)
|
||||
{
|
||||
@@ -416,39 +415,70 @@ construct_cell_groups (GtkCellAreaBox *box)
|
||||
/* 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);
|
||||
memset (&group, 0x0, sizeof (CellGroup));
|
||||
group.id = ++id;
|
||||
|
||||
g_array_append_val (priv->groups, group);
|
||||
}
|
||||
|
||||
group->cells = g_list_prepend (group->cells, info);
|
||||
group->n_cells++;
|
||||
group.cells = g_list_prepend (group.cells, info);
|
||||
group.n_cells++;
|
||||
|
||||
/* A group expands if it contains any expand cells */
|
||||
if (info->expand)
|
||||
group->expand_cells ++;
|
||||
group.expand_cells++;
|
||||
}
|
||||
|
||||
g_list_free (cells);
|
||||
|
||||
for (l = cells; l; l = l->next)
|
||||
for (id = 0; id < priv->groups->len; id++)
|
||||
{
|
||||
group = l->data;
|
||||
group->cells = g_list_reverse (group->cells);
|
||||
CellGroup *group_ptr = &g_array_index (priv->groups, CellGroup, id);
|
||||
|
||||
group_ptr->cells = g_list_reverse (group_ptr->cells);
|
||||
}
|
||||
|
||||
return g_list_reverse (groups);
|
||||
/* Iters need to be updated with the new grouping information */
|
||||
init_iter_groups (box);
|
||||
}
|
||||
|
||||
static gint
|
||||
count_visible_cells (CellGroup *group,
|
||||
gint *expand_cells)
|
||||
{
|
||||
GList *l;
|
||||
gint visible_cells = 0;
|
||||
gint n_expand_cells = 0;
|
||||
|
||||
for (l = group->cells; l; l = l->next)
|
||||
{
|
||||
CellInfo *info = l->data;
|
||||
|
||||
if (gtk_cell_renderer_get_visible (info->renderer))
|
||||
{
|
||||
visible_cells++;
|
||||
|
||||
if (info->expand)
|
||||
n_expand_cells++;
|
||||
}
|
||||
}
|
||||
|
||||
if (expand_cells)
|
||||
*expand_cells = n_expand_cells;
|
||||
|
||||
return visible_cells;
|
||||
}
|
||||
|
||||
static gint
|
||||
count_expand_groups (GtkCellAreaBox *box)
|
||||
{
|
||||
GtkCellAreaBoxPrivate *priv = box->priv;
|
||||
GList *l;
|
||||
gint i;
|
||||
gint expand_groups = 0;
|
||||
|
||||
for (l = priv->groups; l; l = l->next)
|
||||
for (i = 0; i < priv->groups->len; i++)
|
||||
{
|
||||
CellGroup *group = l->data;
|
||||
CellGroup *group = &g_array_index (priv->groups, CellGroup, i);
|
||||
|
||||
if (group->expand_cells > 0)
|
||||
expand_groups++;
|
||||
@@ -471,20 +501,19 @@ init_iter_group (GtkCellAreaBox *box,
|
||||
GtkCellAreaBoxIter *iter)
|
||||
{
|
||||
GtkCellAreaBoxPrivate *priv = box->priv;
|
||||
gint n_groups, *expand_groups, i;
|
||||
GList *l;
|
||||
gint *expand_groups, i;
|
||||
|
||||
n_groups = g_list_length (priv->groups);
|
||||
expand_groups = g_new (gboolean, n_groups);
|
||||
expand_groups = g_new (gboolean, priv->groups->len);
|
||||
|
||||
for (i = 0, l = priv->groups; l; l = l->next, i++)
|
||||
for (i = 0; i < priv->groups->len; i++)
|
||||
{
|
||||
CellGroup *group = l->data;
|
||||
CellGroup *group = &g_array_index (priv->groups, CellGroup, i);
|
||||
|
||||
expand_groups[i] = (group->expand_cells > 0);
|
||||
}
|
||||
|
||||
gtk_cell_area_box_init_groups (iter, n_groups, expand_groups);
|
||||
/* This call implies flushing the request info */
|
||||
gtk_cell_area_box_init_groups (iter, priv->groups->len, expand_groups);
|
||||
g_free (expand_groups);
|
||||
}
|
||||
|
||||
@@ -534,7 +563,7 @@ get_allocated_cells (GtkCellAreaBox *box,
|
||||
const GtkCellAreaBoxAllocation *group_allocs;
|
||||
GtkCellArea *area = GTK_CELL_AREA (box);
|
||||
GtkCellAreaBoxPrivate *priv = box->priv;
|
||||
GList *group_list, *cell_list;
|
||||
GList *cell_list;
|
||||
GSList *allocated_cells = NULL;
|
||||
gint i, j, n_allocs;
|
||||
|
||||
@@ -547,9 +576,12 @@ get_allocated_cells (GtkCellAreaBox *box,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (i = 0, group_list = priv->groups; group_list; i++, group_list = group_list->next)
|
||||
for (i = 0; i < n_allocs; i++)
|
||||
{
|
||||
CellGroup *group = group_list->data;
|
||||
/* We dont always allocate all groups, sometimes the requested group has only invisible
|
||||
* cells for every row, hence the usage of group_allocs[i].group_idx here
|
||||
*/
|
||||
CellGroup *group = &g_array_index (priv->groups, CellGroup, group_allocs[i].group_idx);
|
||||
|
||||
/* Exception for single cell groups */
|
||||
if (group->n_cells == 1)
|
||||
@@ -562,41 +594,61 @@ get_allocated_cells (GtkCellAreaBox *box,
|
||||
}
|
||||
else
|
||||
{
|
||||
GtkRequestedSize *sizes = g_new (GtkRequestedSize, group->n_cells);
|
||||
gint avail_size = group_allocs[i].size;
|
||||
gint position = group_allocs[i].position;
|
||||
GtkRequestedSize *sizes;
|
||||
gint avail_size, position;
|
||||
gint visible_cells, expand_cells;
|
||||
gint extra_size, extra_extra;
|
||||
|
||||
for (j = 0, cell_list = group->cells; cell_list; j++, cell_list = cell_list->next)
|
||||
visible_cells = count_visible_cells (group, &expand_cells);
|
||||
|
||||
/* If this row has no visible cells in this group, just
|
||||
* skip the allocation */
|
||||
if (visible_cells == 0)
|
||||
continue;
|
||||
|
||||
/* Offset the allocation to the group position and allocate into
|
||||
* the group's available size */
|
||||
position = group_allocs[i].position;
|
||||
avail_size = group_allocs[i].size;
|
||||
|
||||
sizes = g_new (GtkRequestedSize, visible_cells);
|
||||
|
||||
for (j = 0, cell_list = group->cells; cell_list; cell_list = cell_list->next)
|
||||
{
|
||||
CellInfo *info = cell_list->data;
|
||||
|
||||
if (!gtk_cell_renderer_get_visible (info->renderer))
|
||||
continue;
|
||||
|
||||
gtk_cell_area_request_renderer (area, info->renderer,
|
||||
priv->orientation,
|
||||
widget, -1,
|
||||
&sizes[j].minimum_size,
|
||||
&sizes[j].natural_size);
|
||||
|
||||
avail_size -= sizes[j].minimum_size;
|
||||
sizes[j].data = info;
|
||||
avail_size -= sizes[j].minimum_size;
|
||||
|
||||
j++;
|
||||
}
|
||||
|
||||
/* Distribute cells naturally within the group */
|
||||
avail_size -= (group->n_cells - 1) * priv->spacing;
|
||||
avail_size = gtk_distribute_natural_allocation (avail_size, group->n_cells, sizes);
|
||||
avail_size -= (visible_cells - 1) * priv->spacing;
|
||||
avail_size = gtk_distribute_natural_allocation (avail_size, visible_cells, sizes);
|
||||
|
||||
/* Calculate/distribute expand for cells */
|
||||
if (group->expand_cells > 0)
|
||||
if (expand_cells > 0)
|
||||
{
|
||||
extra_size = avail_size / group->expand_cells;
|
||||
extra_extra = avail_size % group->expand_cells;
|
||||
extra_size = avail_size / expand_cells;
|
||||
extra_extra = avail_size % expand_cells;
|
||||
}
|
||||
else
|
||||
extra_size = extra_extra = 0;
|
||||
|
||||
/* Create the allocated cells */
|
||||
for (j = 0, cell_list = group->cells; cell_list; j++, cell_list = cell_list->next)
|
||||
/* Create the allocated cells (loop only over visible cells here) */
|
||||
for (j = 0; j < visible_cells; j++)
|
||||
{
|
||||
CellInfo *info = cell_list->data;
|
||||
CellInfo *info = sizes[j].data;
|
||||
AllocatedCell *cell;
|
||||
|
||||
if (info->expand)
|
||||
@@ -615,12 +667,16 @@ get_allocated_cells (GtkCellAreaBox *box,
|
||||
|
||||
position += sizes[j].minimum_size;
|
||||
position += priv->spacing;
|
||||
|
||||
j++;
|
||||
}
|
||||
|
||||
g_free (sizes);
|
||||
}
|
||||
}
|
||||
|
||||
/* Note it might not be important to reverse the list here at all,
|
||||
* we have the correct positions, no need to allocate from left to right */
|
||||
return g_slist_reverse (allocated_cells);
|
||||
}
|
||||
|
||||
@@ -634,11 +690,17 @@ gtk_cell_area_box_finalize (GObject *object)
|
||||
GtkCellAreaBoxPrivate *priv = box->priv;
|
||||
GSList *l;
|
||||
|
||||
/* Unref/free the iter list */
|
||||
for (l = priv->iters; l; l = l->next)
|
||||
g_object_weak_unref (G_OBJECT (l->data), (GWeakNotify)iter_weak_notify, box);
|
||||
|
||||
g_slist_free (priv->iters);
|
||||
priv->iters = NULL;
|
||||
|
||||
/* Free the cell grouping info */
|
||||
cell_groups_clear (box);
|
||||
g_array_free (priv->groups, TRUE);
|
||||
|
||||
G_OBJECT_CLASS (gtk_cell_area_box_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
@@ -726,12 +788,7 @@ gtk_cell_area_box_remove (GtkCellArea *area,
|
||||
priv->cells = g_list_delete_link (priv->cells, node);
|
||||
|
||||
/* Reconstruct cell groups */
|
||||
g_list_foreach (priv->groups, (GFunc)cell_group_free, NULL);
|
||||
g_list_free (priv->groups);
|
||||
priv->groups = construct_cell_groups (box);
|
||||
|
||||
/* Reinitialize groups on iters */
|
||||
init_iter_groups (box);
|
||||
cell_groups_rebuild (box);
|
||||
}
|
||||
else
|
||||
g_warning ("Trying to remove a cell renderer that is not present GtkCellAreaBox");
|
||||
@@ -880,13 +937,7 @@ gtk_cell_area_box_set_cell_property (GtkCellArea *area,
|
||||
/* Groups need to be rebuilt */
|
||||
if (rebuild)
|
||||
{
|
||||
/* Reconstruct cell groups */
|
||||
g_list_foreach (priv->groups, (GFunc)cell_group_free, NULL);
|
||||
g_list_free (priv->groups);
|
||||
priv->groups = construct_cell_groups (box);
|
||||
|
||||
/* Reinitialize groups on iters */
|
||||
init_iter_groups (box);
|
||||
cell_groups_rebuild (box);
|
||||
}
|
||||
else if (flush)
|
||||
{
|
||||
@@ -973,24 +1024,24 @@ compute_size (GtkCellAreaBox *box,
|
||||
{
|
||||
GtkCellAreaBoxPrivate *priv = box->priv;
|
||||
GtkCellArea *area = GTK_CELL_AREA (box);
|
||||
CellGroup *group;
|
||||
CellInfo *info;
|
||||
GList *cell_list, *group_list;
|
||||
GList *list;
|
||||
gint i;
|
||||
gint min_size = 0;
|
||||
gint nat_size = 0;
|
||||
|
||||
for (group_list = priv->groups; group_list; group_list = group_list->next)
|
||||
for (i = 0; i < priv->groups->len; i++)
|
||||
{
|
||||
gint group_min_size = 0;
|
||||
gint group_nat_size = 0;
|
||||
CellGroup *group = &g_array_index (priv->groups, CellGroup, i);
|
||||
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)
|
||||
for (list = group->cells; list; list = list->next)
|
||||
{
|
||||
gint renderer_min_size, renderer_nat_size;
|
||||
|
||||
info = cell_list->data;
|
||||
CellInfo *info = list->data;
|
||||
gint renderer_min_size, renderer_nat_size;
|
||||
|
||||
if (!gtk_cell_renderer_get_visible (info->renderer))
|
||||
continue;
|
||||
|
||||
gtk_cell_area_request_renderer (area, info->renderer, orientation, widget, for_size,
|
||||
&renderer_min_size, &renderer_nat_size);
|
||||
@@ -1056,19 +1107,24 @@ get_group_sizes (GtkCellArea *area,
|
||||
GList *l;
|
||||
gint i;
|
||||
|
||||
*n_sizes = g_list_length (group->cells);
|
||||
*n_sizes = count_visible_cells (group, NULL);
|
||||
sizes = g_new (GtkRequestedSize, *n_sizes);
|
||||
|
||||
for (l = group->cells, i = 0; l; l = l->next, i++)
|
||||
for (l = group->cells, i = 0; l; l = l->next)
|
||||
{
|
||||
CellInfo *info = l->data;
|
||||
|
||||
if (!gtk_cell_renderer_get_visible (info->renderer))
|
||||
continue;
|
||||
|
||||
sizes[i].data = info;
|
||||
|
||||
gtk_cell_area_request_renderer (area, info->renderer,
|
||||
orientation, widget, -1,
|
||||
&sizes[i].minimum_size,
|
||||
&sizes[i].natural_size);
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
return sizes;
|
||||
@@ -1164,7 +1220,6 @@ compute_size_for_opposing_orientation (GtkCellAreaBox *box,
|
||||
{
|
||||
GtkCellAreaBoxPrivate *priv = box->priv;
|
||||
CellGroup *group;
|
||||
GList *group_list;
|
||||
GtkRequestedSize *orientation_sizes;
|
||||
gint n_groups, n_expand_groups, i;
|
||||
gint avail_size = for_size;
|
||||
@@ -1198,25 +1253,26 @@ compute_size_for_opposing_orientation (GtkCellAreaBox *box,
|
||||
* 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)
|
||||
for (i = 0; i < n_groups; i++)
|
||||
{
|
||||
gint group_min, group_nat;
|
||||
|
||||
group = group_list->data;
|
||||
gint group_idx = GPOINTER_TO_INT (orientation_sizes[i].data);
|
||||
|
||||
group = &g_array_index (priv->groups, CellGroup, group_idx);
|
||||
|
||||
if (group->expand_cells > 0)
|
||||
{
|
||||
orientation_sizes[group->id].minimum_size += extra_size;
|
||||
orientation_sizes[i].minimum_size += extra_size;
|
||||
if (extra_extra)
|
||||
{
|
||||
orientation_sizes[group->id].minimum_size++;
|
||||
orientation_sizes[i].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,
|
||||
orientation_sizes[i].minimum_size,
|
||||
&group_min, &group_nat);
|
||||
|
||||
min_size = MAX (min_size, group_min);
|
||||
@@ -1224,12 +1280,12 @@ compute_size_for_opposing_orientation (GtkCellAreaBox *box,
|
||||
|
||||
if (priv->orientation == GTK_ORIENTATION_HORIZONTAL)
|
||||
{
|
||||
gtk_cell_area_box_iter_push_group_height_for_width (iter, group->id, for_size,
|
||||
gtk_cell_area_box_iter_push_group_height_for_width (iter, group_idx, for_size,
|
||||
group_min, group_nat);
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_cell_area_box_iter_push_group_width_for_height (iter, group->id, for_size,
|
||||
gtk_cell_area_box_iter_push_group_width_for_height (iter, group_idx, for_size,
|
||||
group_min, group_nat);
|
||||
}
|
||||
}
|
||||
@@ -1379,7 +1435,8 @@ gtk_cell_area_box_grab_focus (GtkCellArea *area,
|
||||
GtkCellAreaBox *box = GTK_CELL_AREA_BOX (area);
|
||||
GtkCellAreaBoxPrivate *priv;
|
||||
gboolean first_cell = FALSE;
|
||||
GList *group_list, *cell_list;
|
||||
gint i;
|
||||
GList *list;
|
||||
|
||||
priv = box->priv;
|
||||
|
||||
@@ -1399,28 +1456,17 @@ gtk_cell_area_box_grab_focus (GtkCellArea *area,
|
||||
break;
|
||||
}
|
||||
|
||||
if (first_cell)
|
||||
group_list = g_list_first (priv->groups);
|
||||
else
|
||||
group_list = g_list_last (priv->groups);
|
||||
|
||||
for ( ; group_list;
|
||||
first_cell ? group_list = group_list->next :
|
||||
group_list = group_list->prev)
|
||||
for (i = first_cell ? 0 : priv->groups->len -1;
|
||||
i >= 0 && i < priv->groups->len;
|
||||
i = first_cell ? i + 1 : i - 1)
|
||||
{
|
||||
CellGroup *group = group_list->data;
|
||||
CellGroup *group = &g_array_index (priv->groups, CellGroup, i);
|
||||
|
||||
if (first_cell)
|
||||
cell_list = g_list_first (group->cells);
|
||||
else
|
||||
cell_list = g_list_last (group->cells);
|
||||
|
||||
for ( ; cell_list;
|
||||
first_cell ? cell_list = cell_list->next :
|
||||
cell_list = cell_list->prev)
|
||||
for (list = first_cell ? g_list_first (group->cells) : g_list_last (group->cells);
|
||||
list; list = first_cell ? list->next : list->prev)
|
||||
{
|
||||
GtkCellRendererMode mode;
|
||||
CellInfo *info = cell_list->data;
|
||||
CellInfo *info = list->data;
|
||||
|
||||
/* XXX This does not handle cases where the cell
|
||||
* is not visible as it is not row specific,
|
||||
@@ -1485,13 +1531,7 @@ gtk_cell_area_box_layout_reorder (GtkCellLayout *cell_layout,
|
||||
priv->cells = g_list_delete_link (priv->cells, node);
|
||||
priv->cells = g_list_insert (priv->cells, info, position);
|
||||
|
||||
/* Reconstruct cell groups */
|
||||
g_list_foreach (priv->groups, (GFunc)cell_group_free, NULL);
|
||||
g_list_free (priv->groups);
|
||||
priv->groups = construct_cell_groups (box);
|
||||
|
||||
/* Reinitialize groups on iters */
|
||||
init_iter_groups (box);
|
||||
cell_groups_rebuild (box);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1529,13 +1569,7 @@ gtk_cell_area_box_pack_start (GtkCellAreaBox *box,
|
||||
|
||||
priv->cells = g_list_append (priv->cells, info);
|
||||
|
||||
/* Reconstruct cell groups */
|
||||
g_list_foreach (priv->groups, (GFunc)cell_group_free, NULL);
|
||||
g_list_free (priv->groups);
|
||||
priv->groups = construct_cell_groups (box);
|
||||
|
||||
/* Reinitialize groups on iters */
|
||||
init_iter_groups (box);
|
||||
cell_groups_rebuild (box);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -1563,13 +1597,7 @@ gtk_cell_area_box_pack_end (GtkCellAreaBox *box,
|
||||
|
||||
priv->cells = g_list_append (priv->cells, info);
|
||||
|
||||
/* Reconstruct cell groups */
|
||||
g_list_foreach (priv->groups, (GFunc)cell_group_free, NULL);
|
||||
g_list_free (priv->groups);
|
||||
priv->groups = construct_cell_groups (box);
|
||||
|
||||
/* Reinitialize groups on iters */
|
||||
init_iter_groups (box);
|
||||
cell_groups_rebuild (box);
|
||||
}
|
||||
|
||||
gint
|
||||
|
||||
@@ -263,7 +263,10 @@ gtk_cell_area_box_iter_sum_preferred_width (GtkCellAreaIter *iter)
|
||||
|
||||
if (orientation == GTK_ORIENTATION_HORIZONTAL)
|
||||
{
|
||||
if (min_size > 0)
|
||||
/* Dont add spacing for 0 size groups, they can be 0 size because
|
||||
* they contain only invisible cells for this round of requests
|
||||
*/
|
||||
if (min_size > 0 && size->nat_size > 0)
|
||||
{
|
||||
min_size += spacing;
|
||||
nat_size += spacing;
|
||||
@@ -308,7 +311,10 @@ gtk_cell_area_box_iter_sum_preferred_height_for_width (GtkCellAreaIter *iter,
|
||||
|
||||
if (orientation == GTK_ORIENTATION_VERTICAL)
|
||||
{
|
||||
if (min_size > 0)
|
||||
/* Dont add spacing for 0 size groups, they can be 0 size because
|
||||
* they contain only invisible cells for this round of requests
|
||||
*/
|
||||
if (min_size > 0 && size->nat_size > 0)
|
||||
{
|
||||
min_size += spacing;
|
||||
nat_size += spacing;
|
||||
@@ -348,7 +354,10 @@ gtk_cell_area_box_iter_sum_preferred_height (GtkCellAreaIter *iter)
|
||||
|
||||
if (orientation == GTK_ORIENTATION_VERTICAL)
|
||||
{
|
||||
if (min_size > 0)
|
||||
/* Dont add spacing for 0 size groups, they can be 0 size because
|
||||
* they contain only invisible cells for this round of requests
|
||||
*/
|
||||
if (min_size > 0 && size->nat_size > 0)
|
||||
{
|
||||
min_size += spacing;
|
||||
nat_size += spacing;
|
||||
@@ -393,7 +402,10 @@ gtk_cell_area_box_iter_sum_preferred_width_for_height (GtkCellAreaIter *iter,
|
||||
|
||||
if (orientation == GTK_ORIENTATION_HORIZONTAL)
|
||||
{
|
||||
if (min_size > 0)
|
||||
/* Dont add spacing for 0 size groups, they can be 0 size because
|
||||
* they contain only invisible cells for this round of requests
|
||||
*/
|
||||
if (min_size > 0 && size->nat_size > 0)
|
||||
{
|
||||
min_size += spacing;
|
||||
nat_size += spacing;
|
||||
@@ -413,6 +425,56 @@ gtk_cell_area_box_iter_sum_preferred_width_for_height (GtkCellAreaIter *iter,
|
||||
}
|
||||
}
|
||||
|
||||
static GtkRequestedSize *
|
||||
gtk_cell_area_box_iter_get_requests (GtkCellAreaBoxIter *box_iter,
|
||||
GtkOrientation orientation,
|
||||
gint *n_requests)
|
||||
{
|
||||
GtkCellAreaBoxIterPrivate *priv;
|
||||
GtkRequestedSize *requests;
|
||||
GArray *base_array;
|
||||
BaseSize *size;
|
||||
gint visible_groups = 0;
|
||||
gint i, j;
|
||||
|
||||
g_return_val_if_fail (GTK_IS_CELL_AREA_BOX_ITER (box_iter), NULL);
|
||||
|
||||
priv = box_iter->priv;
|
||||
|
||||
if (orientation == GTK_ORIENTATION_HORIZONTAL)
|
||||
base_array = priv->base_widths;
|
||||
else
|
||||
base_array = priv->base_heights;
|
||||
|
||||
for (i = 0; i < base_array->len; i++)
|
||||
{
|
||||
size = &g_array_index (base_array, BaseSize, i);
|
||||
|
||||
if (size->nat_size > 0)
|
||||
visible_groups++;
|
||||
}
|
||||
|
||||
requests = g_new (GtkRequestedSize, visible_groups);
|
||||
|
||||
for (j = 0, i = 0; i < base_array->len; i++)
|
||||
{
|
||||
size = &g_array_index (base_array, BaseSize, i);
|
||||
|
||||
if (size->nat_size > 0)
|
||||
{
|
||||
requests[j].data = GINT_TO_POINTER (i);
|
||||
requests[j].minimum_size = size->min_size;
|
||||
requests[j].natural_size = size->nat_size;
|
||||
j++;
|
||||
}
|
||||
}
|
||||
|
||||
if (n_requests)
|
||||
*n_requests = visible_groups;
|
||||
|
||||
return requests;
|
||||
}
|
||||
|
||||
static GtkCellAreaBoxAllocation *
|
||||
allocate_for_orientation (GtkCellAreaBoxIter *iter,
|
||||
GtkOrientation orientation,
|
||||
@@ -427,15 +489,21 @@ allocate_for_orientation (GtkCellAreaBoxIter *iter,
|
||||
gint extra_size, extra_extra;
|
||||
gint avail_size = size;
|
||||
|
||||
if (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);
|
||||
orientation_sizes =
|
||||
gtk_cell_area_box_iter_get_requests (iter,
|
||||
GTK_ORIENTATION_HORIZONTAL,
|
||||
&n_groups);
|
||||
|
||||
/* Count groups that expand */
|
||||
for (i = 0; i < n_groups; i++)
|
||||
{
|
||||
BaseSize *size = &g_array_index (priv->base_widths, BaseSize, i);
|
||||
BaseSize *size;
|
||||
gint group_idx = GPOINTER_TO_INT (orientation_sizes[i].data);
|
||||
|
||||
if (orientation == GTK_ORIENTATION_HORIZONTAL)
|
||||
size = &g_array_index (priv->base_widths, BaseSize, group_idx);
|
||||
else
|
||||
size = &g_array_index (priv->base_heights, BaseSize, group_idx);
|
||||
|
||||
if (size->expand)
|
||||
n_expand_groups++;
|
||||
@@ -463,8 +531,9 @@ allocate_for_orientation (GtkCellAreaBoxIter *iter,
|
||||
{
|
||||
BaseSize *base_size = &g_array_index (priv->base_widths, BaseSize, i);
|
||||
|
||||
allocs[i].position = position;
|
||||
allocs[i].size = orientation_sizes[i].minimum_size;
|
||||
allocs[i].group_idx = GPOINTER_TO_INT (orientation_sizes[i].data);
|
||||
allocs[i].position = position;
|
||||
allocs[i].size = orientation_sizes[i].minimum_size;
|
||||
|
||||
if (base_size->expand)
|
||||
{
|
||||
@@ -787,58 +856,14 @@ GtkRequestedSize *
|
||||
gtk_cell_area_box_iter_get_widths (GtkCellAreaBoxIter *box_iter,
|
||||
gint *n_widths)
|
||||
{
|
||||
GtkCellAreaBoxIterPrivate *priv;
|
||||
GtkRequestedSize *widths;
|
||||
BaseSize *size;
|
||||
gint i;
|
||||
|
||||
g_return_val_if_fail (GTK_IS_CELL_AREA_BOX_ITER (box_iter), NULL);
|
||||
|
||||
priv = box_iter->priv;
|
||||
|
||||
widths = g_new (GtkRequestedSize, priv->base_widths->len);
|
||||
|
||||
for (i = 0; i < priv->base_widths->len; i++)
|
||||
{
|
||||
size = &g_array_index (priv->base_widths, BaseSize, i);
|
||||
widths[i].data = GINT_TO_POINTER (i);
|
||||
widths[i].minimum_size = size->min_size;
|
||||
widths[i].natural_size = size->nat_size;
|
||||
}
|
||||
|
||||
if (n_widths)
|
||||
*n_widths = priv->base_widths->len;
|
||||
|
||||
return widths;
|
||||
return gtk_cell_area_box_iter_get_requests (box_iter, GTK_ORIENTATION_HORIZONTAL, n_widths);
|
||||
}
|
||||
|
||||
GtkRequestedSize *
|
||||
gtk_cell_area_box_iter_get_heights (GtkCellAreaBoxIter *box_iter,
|
||||
gint *n_heights)
|
||||
{
|
||||
GtkCellAreaBoxIterPrivate *priv;
|
||||
GtkRequestedSize *heights;
|
||||
BaseSize *size;
|
||||
gint i;
|
||||
|
||||
g_return_val_if_fail (GTK_IS_CELL_AREA_BOX_ITER (box_iter), NULL);
|
||||
|
||||
priv = box_iter->priv;
|
||||
|
||||
heights = g_new (GtkRequestedSize, priv->base_heights->len);
|
||||
|
||||
for (i = 0; i < priv->base_heights->len; i++)
|
||||
{
|
||||
size = &g_array_index (priv->base_heights, BaseSize, i);
|
||||
heights[i].data = GINT_TO_POINTER (i);
|
||||
heights[i].minimum_size = size->min_size;
|
||||
heights[i].natural_size = size->nat_size;
|
||||
}
|
||||
|
||||
if (n_heights)
|
||||
*n_heights = priv->base_heights->len;
|
||||
|
||||
return heights;
|
||||
return gtk_cell_area_box_iter_get_requests (box_iter, GTK_ORIENTATION_VERTICAL, n_heights);
|
||||
}
|
||||
|
||||
G_CONST_RETURN GtkCellAreaBoxAllocation *
|
||||
|
||||
@@ -120,8 +120,9 @@ GtkRequestedSize *gtk_cell_area_box_iter_get_heights (GtkCellAreaBoxIter
|
||||
|
||||
/* Private iter/area interaction */
|
||||
typedef struct {
|
||||
gint position;
|
||||
gint size;
|
||||
gint group_idx; /* Groups containing only invisible cells are not allocated */
|
||||
gint position; /* Relative group allocation position in the orientation of the box */
|
||||
gint size; /* Full allocated size of the cells in this group spacing inclusive */
|
||||
} GtkCellAreaBoxAllocation;
|
||||
|
||||
G_CONST_RETURN GtkCellAreaBoxAllocation *
|
||||
|
||||
Reference in New Issue
Block a user