+/* Fall back on a completely unaligned dynamic allocation of cells
+ * when not allocated for the said orientation, alignment of cells
+ * is not done when each area gets a different size in the orientation
+ * of the box.
+ */
+static GSList *
+allocate_cells_manually (GtkCellAreaBox *box,
+ GtkWidget *widget,
+ gint width,
+ gint height)
+{
+ GtkCellAreaBoxPrivate *priv = box->priv;
+ GList *cells, *l;
+ GSList *allocated_cells = NULL;
+ GtkRequestedSize *sizes;
+ gint i;
+ gint nvisible = 0, nexpand = 0, group_expand;
+ gint avail_size, extra_size, extra_extra, full_size;
+ gint position = 0, for_size;
+ gboolean rtl;
+
+ if (!priv->cells)
+ return NULL;
+
+ /* For vertical oriented boxes, we just let the cell renderers
+ * realign themselves for rtl
+ */
+ rtl = (priv->orientation == GTK_ORIENTATION_HORIZONTAL &&
+ gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL);
+
+ cells = list_consecutive_cells (box);
+
+ /* Count the visible and expand cells */
+ for (i = 0; i < priv->groups->len; i++)
+ {
+ CellGroup *group = &g_array_index (priv->groups, CellGroup, i);
+
+ nvisible += count_visible_cells (group, &group_expand);
+ nexpand += group_expand;
+ }
+
+ if (nvisible <= 0)
+ {
+ g_list_free (cells);
+ return NULL;
+ }
+
+ if (priv->orientation == GTK_ORIENTATION_HORIZONTAL)
+ {
+ full_size = avail_size = width;
+ for_size = height;
+ }
+ else
+ {
+ full_size = avail_size = height;
+ for_size = width;
+ }
+
+ /* Go ahead and collect the requests on the fly */
+ sizes = g_new0 (GtkRequestedSize, nvisible);
+ for (l = cells, i = 0; l; l = l->next)
+ {
+ CellInfo *info = l->data;
+
+ if (!gtk_cell_renderer_get_visible (info->renderer))
+ continue;
+
+ gtk_cell_area_request_renderer (GTK_CELL_AREA (box), info->renderer,
+ priv->orientation,
+ widget, for_size,
+ &sizes[i].minimum_size,
+ &sizes[i].natural_size);
+
+ avail_size -= sizes[i].minimum_size;
+
+ sizes[i].data = info;
+
+ i++;
+ }
+
+ /* Naturally distribute the allocation */
+ avail_size -= (nvisible - 1) * priv->spacing;
+ if (avail_size > 0)
+ avail_size = gtk_distribute_natural_allocation (avail_size, nvisible, sizes);
+ else
+ avail_size = 0;
+
+ /* Calculate/distribute expand for cells */
+ if (nexpand > 0)
+ {
+ extra_size = avail_size / nexpand;
+ extra_extra = avail_size % nexpand;
+ }
+ else
+ extra_size = extra_extra = 0;
+
+ /* Create the allocated cells */
+ for (i = 0; i < nvisible; i++)
+ {
+ CellInfo *info = sizes[i].data;
+ AllocatedCell *cell;
+
+ if (info->expand)
+ {
+ sizes[i].minimum_size += extra_size;
+ if (extra_extra)
+ {
+ sizes[i].minimum_size++;
+ extra_extra--;
+ }
+ }
+
+ if (rtl)
+ cell = allocated_cell_new (info->renderer,
+ full_size - (position + sizes[i].minimum_size),
+ sizes[i].minimum_size);
+ else
+ cell = allocated_cell_new (info->renderer, position, sizes[i].minimum_size);
+
+ allocated_cells = g_slist_prepend (allocated_cells, cell);
+
+ position += sizes[i].minimum_size;
+ position += priv->spacing;
+ }
+
+ g_free (sizes);
+ g_list_free (cells);
+
+ /* 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);
+}
+