diff options
author | Tristan Van Berkom <tristan.van.berkom@gmail.com> | 2010-11-13 16:23:01 +0900 |
---|---|---|
committer | Tristan Van Berkom <tristan.van.berkom@gmail.com> | 2010-11-13 16:23:01 +0900 |
commit | 1bca6349fb5b5b8130e5a7a7cad275cfc12e7346 (patch) | |
tree | 7464395bbca302770852edf0b329a422a3616788 /gtk/gtkcellareaboxcontext.c | |
parent | bef95590891a7c7c7a85e559093aee9ada4129f0 (diff) | |
download | gtk+-1bca6349fb5b5b8130e5a7a7cad275cfc12e7346.tar.gz |
Mass rename GtkCellAreaIter --> GtkCellAreaContext
Diffstat (limited to 'gtk/gtkcellareaboxcontext.c')
-rw-r--r-- | gtk/gtkcellareaboxcontext.c | 886 |
1 files changed, 886 insertions, 0 deletions
diff --git a/gtk/gtkcellareaboxcontext.c b/gtk/gtkcellareaboxcontext.c new file mode 100644 index 0000000000..e0501e6944 --- /dev/null +++ b/gtk/gtkcellareaboxcontext.c @@ -0,0 +1,886 @@ +/* gtkcellareaboxcontext.c + * + * Copyright (C) 2010 Openismus GmbH + * + * Authors: + * Tristan Van Berkom <tristanvb@openismus.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include "config.h" +#include "gtkintl.h" +#include "gtkcellareabox.h" +#include "gtkcellareaboxcontext.h" +#include "gtkorientable.h" + +/* GObjectClass */ +static void gtk_cell_area_box_context_finalize (GObject *object); + +/* GtkCellAreaContextClass */ +static void gtk_cell_area_box_context_flush_preferred_width (GtkCellAreaContext *context); +static void gtk_cell_area_box_context_flush_preferred_height_for_width (GtkCellAreaContext *context, + gint width); +static void gtk_cell_area_box_context_flush_preferred_height (GtkCellAreaContext *context); +static void gtk_cell_area_box_context_flush_preferred_width_for_height (GtkCellAreaContext *context, + gint height); +static void gtk_cell_area_box_context_flush_allocation (GtkCellAreaContext *context); +static void gtk_cell_area_box_context_sum_preferred_width (GtkCellAreaContext *context); +static void gtk_cell_area_box_context_sum_preferred_height_for_width (GtkCellAreaContext *context, + gint width); +static void gtk_cell_area_box_context_sum_preferred_height (GtkCellAreaContext *context); +static void gtk_cell_area_box_context_sum_preferred_width_for_height (GtkCellAreaContext *context, + gint height); +static void gtk_cell_area_box_context_allocate_width (GtkCellAreaContext *context, + gint width); +static void gtk_cell_area_box_context_allocate_height (GtkCellAreaContext *context, + gint height); + +static void free_cache_array (GArray *array); + +/* CachedSize management */ +typedef struct { + gint min_size; + gint nat_size; +} CachedSize; + +typedef struct { + gint min_size; + gint nat_size; + gboolean expand; +} BaseSize; + +struct _GtkCellAreaBoxContextPrivate +{ + /* Table of per renderer CachedSizes */ + GArray *base_widths; + GArray *base_heights; + + /* Table of per height/width hash tables of per renderer CachedSizes */ + GHashTable *widths; + GHashTable *heights; + + /* Allocation info for this context if any */ + gint alloc_width; + gint alloc_height; + gint n_orientation_allocs; + GtkCellAreaBoxAllocation *orientation_allocs; +}; + +G_DEFINE_TYPE (GtkCellAreaBoxContext, gtk_cell_area_box_context, GTK_TYPE_CELL_AREA_CONTEXT); + +static void +free_cache_array (GArray *array) +{ + g_array_free (array, TRUE); +} + +static void +gtk_cell_area_box_context_init (GtkCellAreaBoxContext *box_context) +{ + GtkCellAreaBoxContextPrivate *priv; + + box_context->priv = G_TYPE_INSTANCE_GET_PRIVATE (box_context, + GTK_TYPE_CELL_AREA_BOX_CONTEXT, + GtkCellAreaBoxContextPrivate); + priv = box_context->priv; + + priv->base_widths = g_array_new (FALSE, TRUE, sizeof (BaseSize)); + priv->base_heights = g_array_new (FALSE, TRUE, sizeof (BaseSize)); + + priv->widths = g_hash_table_new_full (g_direct_hash, g_direct_equal, + NULL, (GDestroyNotify)free_cache_array); + priv->heights = g_hash_table_new_full (g_direct_hash, g_direct_equal, + NULL, (GDestroyNotify)free_cache_array); + + priv->alloc_width = 0; + priv->alloc_height = 0; + priv->orientation_allocs = NULL; + priv->n_orientation_allocs = 0; +} + +static void +gtk_cell_area_box_context_class_init (GtkCellAreaBoxContextClass *class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (class); + GtkCellAreaContextClass *context_class = GTK_CELL_AREA_CONTEXT_CLASS (class); + + /* GObjectClass */ + object_class->finalize = gtk_cell_area_box_context_finalize; + + context_class->flush_preferred_width = gtk_cell_area_box_context_flush_preferred_width; + context_class->flush_preferred_height_for_width = gtk_cell_area_box_context_flush_preferred_height_for_width; + context_class->flush_preferred_height = gtk_cell_area_box_context_flush_preferred_height; + context_class->flush_preferred_width_for_height = gtk_cell_area_box_context_flush_preferred_width_for_height; + context_class->flush_allocation = gtk_cell_area_box_context_flush_allocation; + + context_class->sum_preferred_width = gtk_cell_area_box_context_sum_preferred_width; + context_class->sum_preferred_height_for_width = gtk_cell_area_box_context_sum_preferred_height_for_width; + context_class->sum_preferred_height = gtk_cell_area_box_context_sum_preferred_height; + context_class->sum_preferred_width_for_height = gtk_cell_area_box_context_sum_preferred_width_for_height; + + context_class->allocate_width = gtk_cell_area_box_context_allocate_width; + context_class->allocate_height = gtk_cell_area_box_context_allocate_height; + + g_type_class_add_private (object_class, sizeof (GtkCellAreaBoxContextPrivate)); +} + +/************************************************************* + * GObjectClass * + *************************************************************/ +static void +gtk_cell_area_box_context_finalize (GObject *object) +{ + GtkCellAreaBoxContext *box_context = GTK_CELL_AREA_BOX_CONTEXT (object); + GtkCellAreaBoxContextPrivate *priv = box_context->priv; + + g_array_free (priv->base_widths, TRUE); + g_array_free (priv->base_heights, TRUE); + g_hash_table_destroy (priv->widths); + g_hash_table_destroy (priv->heights); + + g_free (priv->orientation_allocs); + + G_OBJECT_CLASS (gtk_cell_area_box_context_parent_class)->finalize (object); +} + +/************************************************************* + * GtkCellAreaContextClass * + *************************************************************/ +static void +gtk_cell_area_box_context_flush_preferred_width (GtkCellAreaContext *context) +{ + GtkCellAreaBoxContext *box_context = GTK_CELL_AREA_BOX_CONTEXT (context); + GtkCellAreaBoxContextPrivate *priv = box_context->priv; + gint i; + + for (i = 0; i < priv->base_widths->len; i++) + { + BaseSize *size = &g_array_index (priv->base_widths, BaseSize, i); + + size->min_size = 0; + size->nat_size = 0; + } + + GTK_CELL_AREA_CONTEXT_CLASS + (gtk_cell_area_box_context_parent_class)->flush_preferred_width (context); +} + +static void +gtk_cell_area_box_context_flush_preferred_height_for_width (GtkCellAreaContext *context, + gint width) +{ + GtkCellAreaBoxContext *box_context = GTK_CELL_AREA_BOX_CONTEXT (context); + GtkCellAreaBoxContextPrivate *priv = box_context->priv; + + /* Flush all sizes for special -1 value */ + if (width < 0) + g_hash_table_remove_all (priv->heights); + else + g_hash_table_remove (priv->heights, GINT_TO_POINTER (width)); + + GTK_CELL_AREA_CONTEXT_CLASS + (gtk_cell_area_box_context_parent_class)->flush_preferred_height_for_width (context, width); +} + +static void +gtk_cell_area_box_context_flush_preferred_height (GtkCellAreaContext *context) +{ + GtkCellAreaBoxContext *box_context = GTK_CELL_AREA_BOX_CONTEXT (context); + GtkCellAreaBoxContextPrivate *priv = box_context->priv; + gint i; + + for (i = 0; i < priv->base_heights->len; i++) + { + BaseSize *size = &g_array_index (priv->base_heights, BaseSize, i); + + size->min_size = 0; + size->nat_size = 0; + } + + GTK_CELL_AREA_CONTEXT_CLASS + (gtk_cell_area_box_context_parent_class)->flush_preferred_height (context); +} + +static void +gtk_cell_area_box_context_flush_preferred_width_for_height (GtkCellAreaContext *context, + gint height) +{ + GtkCellAreaBoxContext *box_context = GTK_CELL_AREA_BOX_CONTEXT (context); + GtkCellAreaBoxContextPrivate *priv = box_context->priv; + + /* Flush all sizes for special -1 value */ + if (height < 0) + g_hash_table_remove_all (priv->widths); + else + g_hash_table_remove (priv->widths, GINT_TO_POINTER (height)); + + GTK_CELL_AREA_CONTEXT_CLASS + (gtk_cell_area_box_context_parent_class)->flush_preferred_width_for_height (context, height); +} + +static void +gtk_cell_area_box_context_flush_allocation (GtkCellAreaContext *context) +{ + GtkCellAreaBoxContext *box_context = GTK_CELL_AREA_BOX_CONTEXT (context); + GtkCellAreaBoxContextPrivate *priv = box_context->priv; + + g_free (priv->orientation_allocs); + priv->orientation_allocs = NULL; + priv->n_orientation_allocs = 0; +} + +static void +gtk_cell_area_box_context_sum_preferred_width (GtkCellAreaContext *context) +{ + GtkCellAreaBoxContext *box_context = GTK_CELL_AREA_BOX_CONTEXT (context); + GtkCellAreaBoxContextPrivate *priv = box_context->priv; + GtkCellArea *area; + GtkOrientation orientation; + gint spacing, i; + gint min_size = 0, nat_size = 0; + + area = gtk_cell_area_context_get_area (context); + spacing = gtk_cell_area_box_get_spacing (GTK_CELL_AREA_BOX (area)); + orientation = gtk_orientable_get_orientation (GTK_ORIENTABLE (area)); + + for (i = 0; i < priv->base_widths->len; i++) + { + BaseSize *size = &g_array_index (priv->base_widths, BaseSize, i); + + if (orientation == GTK_ORIENTATION_HORIZONTAL) + { + /* 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; + } + + min_size += size->min_size; + nat_size += size->nat_size; + } + else + { + min_size = MAX (min_size, size->min_size); + nat_size = MAX (nat_size, size->nat_size); + } + } + + gtk_cell_area_context_push_preferred_width (context, min_size, nat_size); +} + +static void +gtk_cell_area_box_context_sum_preferred_height_for_width (GtkCellAreaContext *context, + gint width) +{ + GtkCellAreaBoxContext *box_context = GTK_CELL_AREA_BOX_CONTEXT (context); + GtkCellAreaBoxContextPrivate *priv = box_context->priv; + GArray *group_array; + GtkCellArea *area; + GtkOrientation orientation; + gint spacing, i; + gint min_size = 0, nat_size = 0; + + group_array = g_hash_table_lookup (priv->heights, GINT_TO_POINTER (width)); + + if (group_array) + { + area = gtk_cell_area_context_get_area (context); + spacing = gtk_cell_area_box_get_spacing (GTK_CELL_AREA_BOX (area)); + orientation = gtk_orientable_get_orientation (GTK_ORIENTABLE (area)); + + for (i = 0; i < group_array->len; i++) + { + CachedSize *size = &g_array_index (group_array, CachedSize, i); + + if (orientation == GTK_ORIENTATION_VERTICAL) + { + /* 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; + } + + min_size += size->min_size; + nat_size += size->nat_size; + } + else + { + min_size = MAX (min_size, size->min_size); + nat_size = MAX (nat_size, size->nat_size); + } + } + + gtk_cell_area_context_push_preferred_height_for_width (context, width, min_size, nat_size); + } +} + +static void +gtk_cell_area_box_context_sum_preferred_height (GtkCellAreaContext *context) +{ + GtkCellAreaBoxContext *box_context = GTK_CELL_AREA_BOX_CONTEXT (context); + GtkCellAreaBoxContextPrivate *priv = box_context->priv; + GtkCellArea *area; + GtkOrientation orientation; + gint spacing, i; + gint min_size = 0, nat_size = 0; + + area = gtk_cell_area_context_get_area (context); + spacing = gtk_cell_area_box_get_spacing (GTK_CELL_AREA_BOX (area)); + orientation = gtk_orientable_get_orientation (GTK_ORIENTABLE (area)); + + for (i = 0; i < priv->base_heights->len; i++) + { + BaseSize *size = &g_array_index (priv->base_heights, BaseSize, i); + + if (orientation == GTK_ORIENTATION_VERTICAL) + { + /* 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; + } + + min_size += size->min_size; + nat_size += size->nat_size; + } + else + { + min_size = MAX (min_size, size->min_size); + nat_size = MAX (nat_size, size->nat_size); + } + } + + gtk_cell_area_context_push_preferred_height (context, min_size, nat_size); +} + +static void +gtk_cell_area_box_context_sum_preferred_width_for_height (GtkCellAreaContext *context, + gint height) +{ + GtkCellAreaBoxContext *box_context = GTK_CELL_AREA_BOX_CONTEXT (context); + GtkCellAreaBoxContextPrivate *priv = box_context->priv; + GArray *group_array; + GtkCellArea *area; + GtkOrientation orientation; + gint spacing, i; + gint min_size = 0, nat_size = 0; + + group_array = g_hash_table_lookup (priv->widths, GINT_TO_POINTER (height)); + + if (group_array) + { + area = gtk_cell_area_context_get_area (context); + spacing = gtk_cell_area_box_get_spacing (GTK_CELL_AREA_BOX (area)); + orientation = gtk_orientable_get_orientation (GTK_ORIENTABLE (area)); + + for (i = 0; i < group_array->len; i++) + { + CachedSize *size = &g_array_index (group_array, CachedSize, i); + + if (orientation == GTK_ORIENTATION_HORIZONTAL) + { + /* 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; + } + + min_size += size->min_size; + nat_size += size->nat_size; + } + else + { + min_size = MAX (min_size, size->min_size); + nat_size = MAX (nat_size, size->nat_size); + } + } + + gtk_cell_area_context_push_preferred_width_for_height (context, height, min_size, nat_size); + } +} + +static GtkRequestedSize * +gtk_cell_area_box_context_get_requests (GtkCellAreaBoxContext *box_context, + GtkOrientation orientation, + gint *n_requests) +{ + GtkCellAreaBoxContextPrivate *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_CONTEXT (box_context), NULL); + + priv = box_context->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 (GtkCellAreaBoxContext *context, + GtkOrientation orientation, + gint spacing, + gint size, + gint *n_allocs) +{ + GtkCellAreaBoxContextPrivate *priv = context->priv; + GtkRequestedSize *orientation_sizes; + GtkCellAreaBoxAllocation *allocs; + gint n_expand_groups = 0; + gint i, n_groups, position; + gint extra_size, extra_extra; + gint avail_size = size; + + orientation_sizes = + gtk_cell_area_box_context_get_requests (context, orientation, &n_groups); + + /* Count groups that expand */ + for (i = 0; i < n_groups; 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++; + } + + /* First start by naturally allocating space among groups */ + avail_size -= (n_groups - 1) * 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; + + allocs = g_new (GtkCellAreaBoxAllocation, n_groups); + + for (position = 0, i = 0; i < n_groups; i++) + { + BaseSize *base_size = &g_array_index (priv->base_widths, BaseSize, i); + + 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) + { + allocs[i].size += extra_size; + if (extra_extra) + { + allocs[i].size++; + extra_extra--; + } + } + + position += allocs[i].size; + position += spacing; + } + + if (n_allocs) + *n_allocs = n_groups; + + g_free (orientation_sizes); + + return allocs; +} + +static void +gtk_cell_area_box_context_allocate_width (GtkCellAreaContext *context, + gint width) +{ + GtkCellAreaBoxContext *box_context = GTK_CELL_AREA_BOX_CONTEXT (context); + GtkCellAreaBoxContextPrivate *priv = box_context->priv; + GtkCellArea *area; + GtkOrientation orientation; + + area = gtk_cell_area_context_get_area (context); + orientation = gtk_orientable_get_orientation (GTK_ORIENTABLE (area)); + + if (orientation == GTK_ORIENTATION_HORIZONTAL) + { + gint spacing = gtk_cell_area_box_get_spacing (GTK_CELL_AREA_BOX (area)); + + g_free (priv->orientation_allocs); + priv->orientation_allocs = allocate_for_orientation (box_context, orientation, spacing, width, + &priv->n_orientation_allocs); + } + + GTK_CELL_AREA_CONTEXT_CLASS (gtk_cell_area_box_context_parent_class)->allocate_width (context, width); +} + +static void +gtk_cell_area_box_context_allocate_height (GtkCellAreaContext *context, + gint height) +{ + GtkCellAreaBoxContext *box_context = GTK_CELL_AREA_BOX_CONTEXT (context); + GtkCellAreaBoxContextPrivate *priv = box_context->priv; + GtkCellArea *area; + GtkOrientation orientation; + + area = gtk_cell_area_context_get_area (context); + orientation = gtk_orientable_get_orientation (GTK_ORIENTABLE (area)); + + if (orientation == GTK_ORIENTATION_VERTICAL) + { + gint spacing = gtk_cell_area_box_get_spacing (GTK_CELL_AREA_BOX (area)); + + g_free (priv->orientation_allocs); + priv->orientation_allocs = allocate_for_orientation (box_context, orientation, spacing, height, + &priv->n_orientation_allocs); + } + + GTK_CELL_AREA_CONTEXT_CLASS (gtk_cell_area_box_context_parent_class)->allocate_height (context, height); +} + +/************************************************************* + * API * + *************************************************************/ +void +gtk_cell_area_box_init_groups (GtkCellAreaBoxContext *box_context, + guint n_groups, + gboolean *expand_groups) +{ + GtkCellAreaBoxContextPrivate *priv; + gint i; + + g_return_if_fail (GTK_IS_CELL_AREA_BOX_CONTEXT (box_context)); + g_return_if_fail (n_groups == 0 || expand_groups != NULL); + + /* When the group dimensions change, all info must be flushed + * Note this already clears the min/nat values on the BaseSizes + */ + gtk_cell_area_context_flush (GTK_CELL_AREA_CONTEXT (box_context)); + + priv = box_context->priv; + g_array_set_size (priv->base_widths, n_groups); + g_array_set_size (priv->base_heights, n_groups); + + /* Now set the expand info */ + for (i = 0; i < n_groups; i++) + { + BaseSize *base_width = &g_array_index (priv->base_widths, BaseSize, i); + BaseSize *base_height = &g_array_index (priv->base_heights, BaseSize, i); + + base_width->expand = expand_groups[i]; + base_height->expand = expand_groups[i]; + } +} + +void +gtk_cell_area_box_context_push_group_width (GtkCellAreaBoxContext *box_context, + gint group_idx, + gint minimum_width, + gint natural_width) +{ + GtkCellAreaBoxContextPrivate *priv; + BaseSize *size; + + g_return_if_fail (GTK_IS_CELL_AREA_BOX_CONTEXT (box_context)); + + priv = box_context->priv; + g_return_if_fail (group_idx < priv->base_widths->len); + + size = &g_array_index (priv->base_widths, BaseSize, group_idx); + size->min_size = MAX (size->min_size, minimum_width); + size->nat_size = MAX (size->nat_size, natural_width); +} + +void +gtk_cell_area_box_context_push_group_height_for_width (GtkCellAreaBoxContext *box_context, + gint group_idx, + gint for_width, + gint minimum_height, + gint natural_height) +{ + GtkCellAreaBoxContextPrivate *priv; + GArray *group_array; + CachedSize *size; + + g_return_if_fail (GTK_IS_CELL_AREA_BOX_CONTEXT (box_context)); + + priv = box_context->priv; + g_return_if_fail (group_idx < priv->base_widths->len); + + group_array = g_hash_table_lookup (priv->heights, GINT_TO_POINTER (for_width)); + if (!group_array) + { + group_array = g_array_new (FALSE, TRUE, sizeof (CachedSize)); + g_array_set_size (group_array, priv->base_heights->len); + + g_hash_table_insert (priv->heights, GINT_TO_POINTER (for_width), group_array); + } + + size = &g_array_index (group_array, CachedSize, group_idx); + size->min_size = MAX (size->min_size, minimum_height); + size->nat_size = MAX (size->nat_size, natural_height); +} + +void +gtk_cell_area_box_context_push_group_height (GtkCellAreaBoxContext *box_context, + gint group_idx, + gint minimum_height, + gint natural_height) +{ + GtkCellAreaBoxContextPrivate *priv; + BaseSize *size; + + g_return_if_fail (GTK_IS_CELL_AREA_BOX_CONTEXT (box_context)); + + priv = box_context->priv; + g_return_if_fail (group_idx < priv->base_heights->len); + + size = &g_array_index (priv->base_heights, BaseSize, group_idx); + size->min_size = MAX (size->min_size, minimum_height); + size->nat_size = MAX (size->nat_size, natural_height); +} + +void +gtk_cell_area_box_context_push_group_width_for_height (GtkCellAreaBoxContext *box_context, + gint group_idx, + gint for_height, + gint minimum_width, + gint natural_width) +{ + GtkCellAreaBoxContextPrivate *priv; + GArray *group_array; + CachedSize *size; + + g_return_if_fail (GTK_IS_CELL_AREA_BOX_CONTEXT (box_context)); + + priv = box_context->priv; + g_return_if_fail (group_idx < priv->base_widths->len); + + group_array = g_hash_table_lookup (priv->widths, GINT_TO_POINTER (for_height)); + if (!group_array) + { + group_array = g_array_new (FALSE, TRUE, sizeof (CachedSize)); + g_array_set_size (group_array, priv->base_heights->len); + + g_hash_table_insert (priv->widths, GINT_TO_POINTER (for_height), group_array); + } + + size = &g_array_index (group_array, CachedSize, group_idx); + size->min_size = MAX (size->min_size, minimum_width); + size->nat_size = MAX (size->nat_size, natural_width); +} + +void +gtk_cell_area_box_context_get_group_width (GtkCellAreaBoxContext *box_context, + gint group_idx, + gint *minimum_width, + gint *natural_width) +{ + GtkCellAreaBoxContextPrivate *priv; + BaseSize *size; + + g_return_if_fail (GTK_IS_CELL_AREA_BOX_CONTEXT (box_context)); + + priv = box_context->priv; + g_return_if_fail (group_idx < priv->base_widths->len); + + size = &g_array_index (priv->base_widths, BaseSize, group_idx); + + if (minimum_width) + *minimum_width = size->min_size; + + if (natural_width) + *natural_width = size->nat_size; +} + +void +gtk_cell_area_box_context_get_group_height_for_width (GtkCellAreaBoxContext *box_context, + gint group_idx, + gint for_width, + gint *minimum_height, + gint *natural_height) +{ + GtkCellAreaBoxContextPrivate *priv; + GArray *group_array; + + g_return_if_fail (GTK_IS_CELL_AREA_BOX_CONTEXT (box_context)); + + priv = box_context->priv; + g_return_if_fail (group_idx < priv->base_widths->len); + + group_array = g_hash_table_lookup (priv->heights, GINT_TO_POINTER (for_width)); + + if (group_array) + { + CachedSize *size = &g_array_index (group_array, CachedSize, group_idx); + + 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_context_get_group_height (GtkCellAreaBoxContext *box_context, + gint group_idx, + gint *minimum_height, + gint *natural_height) +{ + GtkCellAreaBoxContextPrivate *priv; + BaseSize *size; + + g_return_if_fail (GTK_IS_CELL_AREA_BOX_CONTEXT (box_context)); + + priv = box_context->priv; + g_return_if_fail (group_idx < priv->base_heights->len); + + size = &g_array_index (priv->base_heights, BaseSize, group_idx); + + if (minimum_height) + *minimum_height = size->min_size; + + if (natural_height) + *natural_height = size->nat_size; +} + +void +gtk_cell_area_box_context_get_group_width_for_height (GtkCellAreaBoxContext *box_context, + gint group_idx, + gint for_height, + gint *minimum_width, + gint *natural_width) +{ + GtkCellAreaBoxContextPrivate *priv; + GArray *group_array; + + g_return_if_fail (GTK_IS_CELL_AREA_BOX_CONTEXT (box_context)); + + priv = box_context->priv; + g_return_if_fail (group_idx < priv->base_widths->len); + + group_array = g_hash_table_lookup (priv->widths, GINT_TO_POINTER (for_height)); + + if (group_array) + { + CachedSize *size = &g_array_index (group_array, CachedSize, group_idx); + + 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; + } +} + +GtkRequestedSize * +gtk_cell_area_box_context_get_widths (GtkCellAreaBoxContext *box_context, + gint *n_widths) +{ + return gtk_cell_area_box_context_get_requests (box_context, GTK_ORIENTATION_HORIZONTAL, n_widths); +} + +GtkRequestedSize * +gtk_cell_area_box_context_get_heights (GtkCellAreaBoxContext *box_context, + gint *n_heights) +{ + return gtk_cell_area_box_context_get_requests (box_context, GTK_ORIENTATION_VERTICAL, n_heights); +} + +G_CONST_RETURN GtkCellAreaBoxAllocation * +gtk_cell_area_box_context_get_orientation_allocs (GtkCellAreaBoxContext *context, + gint *n_allocs) +{ + GtkCellAreaBoxContextPrivate *priv; + + g_return_val_if_fail (GTK_IS_CELL_AREA_BOX_CONTEXT (context), NULL); + + priv = context->priv; + + *n_allocs = priv->n_orientation_allocs; + + return priv->orientation_allocs; +} |