[gtk+/treeview-refactor] Revert "Removed tons of api that we dont absolutely need in GtkCellAreaContext:"
- From: Tristan Van Berkom <tvb src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+/treeview-refactor] Revert "Removed tons of api that we dont absolutely need in GtkCellAreaContext:"
- Date: Fri, 26 Nov 2010 12:39:21 +0000 (UTC)
commit fa3c8f182edcddcfb948513fbdadeeec2e059fe0
Author: Tristan Van Berkom <tristan van berkom gmail com>
Date: Fri Nov 26 13:23:01 2010 +0900
Revert "Removed tons of api that we dont absolutely need in GtkCellAreaContext:"
This reverts commit 5f7787ab2ead2cdd11ebe17b16dd9498daaaf9c5.
gtk/gtkcellareabox.c | 57 +++++--
gtk/gtkcellareaboxcontext.c | 303 ++++++++++++++++++++++++++++++++++++
gtk/gtkcellareaboxcontext.h | 27 ++++
gtk/gtkcellareacontext.c | 363 ++++++++++++++++++++++++++++++++++++++++++-
gtk/gtkcellareacontext.h | 32 ++++
5 files changed, 762 insertions(+), 20 deletions(-)
---
diff --git a/gtk/gtkcellareabox.c b/gtk/gtkcellareabox.c
index 8950c53..02ec53f 100644
--- a/gtk/gtkcellareabox.c
+++ b/gtk/gtkcellareabox.c
@@ -1284,7 +1284,8 @@ compute_size (GtkCellAreaBox *box,
for (i = 0; i < priv->groups->len; i++)
{
CellGroup *group = &g_array_index (priv->groups, CellGroup, i);
- gint group_min = 0, group_nat = 0;
+ gint group_min_size = 0;
+ gint group_nat_size = 0;
for (list = group->cells; list; list = list->next)
{
@@ -1304,33 +1305,42 @@ compute_size (GtkCellAreaBox *box,
min_size += priv->spacing;
nat_size += priv->spacing;
}
-
- if (group_min > 0)
+
+ if (group_min_size > 0)
{
- group_min += priv->spacing;
- group_nat += priv->spacing;
+ group_min_size += priv->spacing;
+ group_nat_size += priv->spacing;
}
-
- min_size += renderer_min_size;
- nat_size += renderer_nat_size;
- group_min += renderer_min_size;
- group_nat += renderer_nat_size;
+
+ min_size += renderer_min_size;
+ nat_size += renderer_nat_size;
+ group_min_size += renderer_min_size;
+ group_nat_size += renderer_nat_size;
}
else
{
- min_size = MAX (min_size, renderer_min_size);
- nat_size = MAX (nat_size, renderer_nat_size);
- group_min = MAX (group_min, renderer_min_size);
- group_nat = MAX (group_nat, 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 (for_size < 0)
+ if (orientation == GTK_ORIENTATION_HORIZONTAL)
+ {
+ if (for_size < 0)
+ gtk_cell_area_box_context_push_group_width (context, group->id, group_min_size, group_nat_size);
+ else
+ gtk_cell_area_box_context_push_group_width_for_height (context, group->id, for_size,
+ group_min_size, group_nat_size);
+ }
+ else
{
- if (orientation == GTK_ORIENTATION_HORIZONTAL)
- gtk_cell_area_box_context_push_group_width (context, group->id, group_min, group_nat);
+ if (for_size < 0)
+ gtk_cell_area_box_context_push_group_height (context, group->id, group_min_size, group_nat_size);
else
- gtk_cell_area_box_context_push_group_height (context, group->id, group_min, group_nat);
+ gtk_cell_area_box_context_push_group_height_for_width (context, group->id, for_size,
+ group_min_size, group_nat_size);
}
}
@@ -1519,6 +1529,17 @@ compute_size_for_opposing_orientation (GtkCellAreaBox *box,
min_size = MAX (min_size, group_min);
nat_size = MAX (nat_size, group_nat);
+
+ if (priv->orientation == GTK_ORIENTATION_HORIZONTAL)
+ {
+ gtk_cell_area_box_context_push_group_height_for_width (context, group_idx, for_size,
+ group_min, group_nat);
+ }
+ else
+ {
+ gtk_cell_area_box_context_push_group_width_for_height (context, group_idx, for_size,
+ group_min, group_nat);
+ }
}
*minimum_size = min_size;
diff --git a/gtk/gtkcellareaboxcontext.c b/gtk/gtkcellareaboxcontext.c
index 6ba773c..caf23df 100644
--- a/gtk/gtkcellareaboxcontext.c
+++ b/gtk/gtkcellareaboxcontext.c
@@ -32,15 +32,31 @@ static void gtk_cell_area_box_context_finalize (GOb
/* 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;
@@ -53,6 +69,10 @@ struct _GtkCellAreaBoxContextPrivate
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;
@@ -63,6 +83,12 @@ struct _GtkCellAreaBoxContextPrivate
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;
@@ -75,6 +101,11 @@ gtk_cell_area_box_context_init (GtkCellAreaBoxContext *box_context)
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;
@@ -91,11 +122,15 @@ gtk_cell_area_box_context_class_init (GtkCellAreaBoxContextClass *class)
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;
@@ -114,6 +149,8 @@ gtk_cell_area_box_context_finalize (GObject *object)
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);
@@ -143,6 +180,23 @@ 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)
+{
+ 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);
@@ -162,6 +216,23 @@ 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)
+{
+ 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);
@@ -215,6 +286,55 @@ 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)
+{
+ 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);
@@ -256,6 +376,55 @@ gtk_cell_area_box_context_sum_preferred_height (GtkCellAreaContext *context)
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,
@@ -490,6 +659,36 @@ gtk_cell_area_box_context_push_group_width (GtkCellAreaBoxContext *box_context,
}
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,
@@ -509,6 +708,36 @@ gtk_cell_area_box_context_push_group_height (GtkCellAreaBoxContext *box_context,
}
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,
@@ -532,6 +761,43 @@ gtk_cell_area_box_context_get_group_width (GtkCellAreaBoxContext *box_context,
}
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,
@@ -554,6 +820,43 @@ gtk_cell_area_box_context_get_group_height (GtkCellAreaBoxContext *box_context,
*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)
diff --git a/gtk/gtkcellareaboxcontext.h b/gtk/gtkcellareaboxcontext.h
index 29d9f80..01f7dc6 100644
--- a/gtk/gtkcellareaboxcontext.h
+++ b/gtk/gtkcellareaboxcontext.h
@@ -72,20 +72,47 @@ void gtk_cell_area_box_context_push_group_width (GtkCellAreaBoxCo
gint group_idx,
gint minimum_width,
gint 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);
+
void gtk_cell_area_box_context_push_group_height (GtkCellAreaBoxContext *box_context,
gint group_idx,
gint minimum_height,
gint 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);
+
/* Fetch cell-group sizes */
void gtk_cell_area_box_context_get_group_width (GtkCellAreaBoxContext *box_context,
gint group_idx,
gint *minimum_width,
gint *natural_width);
+
+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);
+
void gtk_cell_area_box_context_get_group_height (GtkCellAreaBoxContext *box_context,
gint group_idx,
gint *minimum_height,
gint *natural_height);
+
+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);
+
GtkRequestedSize *gtk_cell_area_box_context_get_widths (GtkCellAreaBoxContext *box_context,
gint *n_widths);
GtkRequestedSize *gtk_cell_area_box_context_get_heights (GtkCellAreaBoxContext *box_context,
diff --git a/gtk/gtkcellareacontext.c b/gtk/gtkcellareacontext.c
index 1d0598f..6164670 100644
--- a/gtk/gtkcellareacontext.c
+++ b/gtk/gtkcellareacontext.c
@@ -28,6 +28,7 @@
#include "gtkprivate.h"
/* GObjectClass */
+static void gtk_cell_area_context_finalize (GObject *object);
static void gtk_cell_area_context_dispose (GObject *object);
static void gtk_cell_area_context_get_property (GObject *object,
guint prop_id,
@@ -40,13 +41,26 @@ static void gtk_cell_area_context_set_property (GObject
/* GtkCellAreaContextClass */
static void gtk_cell_area_context_real_flush_preferred_width (GtkCellAreaContext *context);
+static void gtk_cell_area_context_real_flush_preferred_height_for_width (GtkCellAreaContext *context,
+ gint width);
static void gtk_cell_area_context_real_flush_preferred_height (GtkCellAreaContext *context);
+static void gtk_cell_area_context_real_flush_preferred_width_for_height (GtkCellAreaContext *context,
+ gint height);
static void gtk_cell_area_context_real_flush_allocation (GtkCellAreaContext *context);
static void gtk_cell_area_context_real_allocate_width (GtkCellAreaContext *context,
gint width);
static void gtk_cell_area_context_real_allocate_height (GtkCellAreaContext *context,
gint height);
+/* CachedSize management */
+typedef struct {
+ gint min_size;
+ gint nat_size;
+} CachedSize;
+
+static CachedSize *cached_size_new (gint min_size, gint nat_size);
+static void cached_size_free (CachedSize *size);
+
struct _GtkCellAreaContextPrivate
{
GtkCellArea *cell_area;
@@ -57,6 +71,9 @@ struct _GtkCellAreaContextPrivate
gint nat_height;
gint alloc_width;
gint alloc_height;
+
+ GHashTable *widths;
+ GHashTable *heights;
};
enum {
@@ -68,6 +85,14 @@ enum {
PROP_NAT_HEIGHT
};
+enum {
+ SIGNAL_WIDTH_CHANGED,
+ SIGNAL_HEIGHT_CHANGED,
+ LAST_SIGNAL
+};
+
+static guint cell_area_context_signals[LAST_SIGNAL] = { 0 };
+
G_DEFINE_TYPE (GtkCellAreaContext, gtk_cell_area_context, G_TYPE_OBJECT);
static void
@@ -84,6 +109,10 @@ gtk_cell_area_context_init (GtkCellAreaContext *context)
priv->nat_width = -1;
priv->min_height = -1;
priv->nat_height = -1;
+ priv->widths = g_hash_table_new_full (g_direct_hash, g_direct_equal,
+ NULL, (GDestroyNotify)cached_size_free);
+ priv->heights = g_hash_table_new_full (g_direct_hash, g_direct_equal,
+ NULL, (GDestroyNotify)cached_size_free);
}
static void
@@ -92,21 +121,46 @@ gtk_cell_area_context_class_init (GtkCellAreaContextClass *class)
GObjectClass *object_class = G_OBJECT_CLASS (class);
/* GObjectClass */
+ object_class->finalize = gtk_cell_area_context_finalize;
object_class->dispose = gtk_cell_area_context_dispose;
object_class->get_property = gtk_cell_area_context_get_property;
object_class->set_property = gtk_cell_area_context_set_property;
/* GtkCellAreaContextClass */
class->flush_preferred_width = gtk_cell_area_context_real_flush_preferred_width;
+ class->flush_preferred_height_for_width = gtk_cell_area_context_real_flush_preferred_height_for_width;
class->flush_preferred_height = gtk_cell_area_context_real_flush_preferred_height;
+ class->flush_preferred_width_for_height = gtk_cell_area_context_real_flush_preferred_width_for_height;
class->flush_allocation = gtk_cell_area_context_real_flush_allocation;
- class->sum_preferred_width = NULL;
- class->sum_preferred_height = NULL;
+ class->sum_preferred_width = NULL;
+ class->sum_preferred_height_for_width = NULL;
+ class->sum_preferred_height = NULL;
+ class->sum_preferred_width_for_height = NULL;
class->allocate_width = gtk_cell_area_context_real_allocate_width;
class->allocate_height = gtk_cell_area_context_real_allocate_height;
+ cell_area_context_signals[SIGNAL_HEIGHT_CHANGED] =
+ g_signal_new (I_("height-changed"),
+ G_TYPE_FROM_CLASS (object_class),
+ G_SIGNAL_RUN_LAST,
+ 0, /* Class offset (just a notification, no class handler) */
+ NULL, NULL,
+ _gtk_marshal_VOID__INT_INT_INT,
+ G_TYPE_NONE, 3,
+ G_TYPE_INT, G_TYPE_INT, G_TYPE_INT);
+
+ cell_area_context_signals[SIGNAL_WIDTH_CHANGED] =
+ g_signal_new (I_("width-changed"),
+ G_TYPE_FROM_CLASS (object_class),
+ G_SIGNAL_RUN_LAST,
+ 0, /* Class offset (just a notification, no class handler) */
+ NULL, NULL,
+ _gtk_marshal_VOID__INT_INT_INT,
+ 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",
@@ -158,10 +212,45 @@ gtk_cell_area_context_class_init (GtkCellAreaContextClass *class)
g_type_class_add_private (object_class, sizeof (GtkCellAreaContextPrivate));
}
+
+
+/*************************************************************
+ * Cached Sizes *
+ *************************************************************/
+static CachedSize *
+cached_size_new (gint min_size,
+ gint nat_size)
+{
+ CachedSize *size = g_slice_new (CachedSize);
+
+ size->min_size = min_size;
+ size->nat_size = nat_size;
+
+ return size;
+}
+
+static void
+cached_size_free (CachedSize *size)
+{
+ g_slice_free (CachedSize, size);
+}
+
/*************************************************************
* GObjectClass *
*************************************************************/
static void
+gtk_cell_area_context_finalize (GObject *object)
+{
+ GtkCellAreaContext *context = GTK_CELL_AREA_CONTEXT (object);
+ GtkCellAreaContextPrivate *priv = context->priv;
+
+ g_hash_table_destroy (priv->widths);
+ g_hash_table_destroy (priv->heights);
+
+ G_OBJECT_CLASS (gtk_cell_area_context_parent_class)->finalize (object);
+}
+
+static void
gtk_cell_area_context_dispose (GObject *object)
{
GtkCellAreaContext *context = GTK_CELL_AREA_CONTEXT (object);
@@ -247,6 +336,40 @@ gtk_cell_area_context_real_flush_preferred_width (GtkCellAreaContext *context)
}
static void
+notify_invalid_height (gpointer width_ptr,
+ CachedSize *size,
+ GtkCellAreaContext *context)
+{
+ gint width = GPOINTER_TO_INT (width_ptr);
+
+ /* Notify size invalidated */
+ g_signal_emit (context, cell_area_context_signals[SIGNAL_HEIGHT_CHANGED],
+ 0, width, -1, -1);
+}
+
+static void
+gtk_cell_area_context_real_flush_preferred_height_for_width (GtkCellAreaContext *context,
+ gint width)
+{
+ GtkCellAreaContextPrivate *priv = context->priv;
+
+ /* Flush all sizes for special -1 value */
+ if (width < 0)
+ {
+ g_hash_table_foreach (priv->heights, (GHFunc)notify_invalid_height, context);
+ g_hash_table_remove_all (priv->heights);
+ }
+ else
+ {
+ g_hash_table_remove (priv->heights, GINT_TO_POINTER (width));
+
+ /* Notify size invalidated */
+ g_signal_emit (context, cell_area_context_signals[SIGNAL_HEIGHT_CHANGED],
+ 0, width, -1, -1);
+ }
+}
+
+static void
gtk_cell_area_context_real_flush_preferred_height (GtkCellAreaContext *context)
{
GtkCellAreaContextPrivate *priv = context->priv;
@@ -261,6 +384,40 @@ gtk_cell_area_context_real_flush_preferred_height (GtkCellAreaContext *context)
}
static void
+notify_invalid_width (gpointer height_ptr,
+ CachedSize *size,
+ GtkCellAreaContext *context)
+{
+ gint height = GPOINTER_TO_INT (height_ptr);
+
+ /* Notify size invalidated */
+ g_signal_emit (context, cell_area_context_signals[SIGNAL_WIDTH_CHANGED],
+ 0, height, -1, -1);
+}
+
+static void
+gtk_cell_area_context_real_flush_preferred_width_for_height (GtkCellAreaContext *context,
+ gint height)
+{
+ GtkCellAreaContextPrivate *priv = context->priv;
+
+ /* Flush all sizes for special -1 value */
+ if (height < 0)
+ {
+ g_hash_table_foreach (priv->widths, (GHFunc)notify_invalid_width, context);
+ g_hash_table_remove_all (priv->widths);
+ }
+ else
+ {
+ g_hash_table_remove (priv->widths, GINT_TO_POINTER (height));
+
+ /* Notify size invalidated */
+ g_signal_emit (context, cell_area_context_signals[SIGNAL_WIDTH_CHANGED],
+ 0, height, -1, -1);
+ }
+}
+
+static void
gtk_cell_area_context_real_flush_allocation (GtkCellAreaContext *context)
{
GtkCellAreaContextPrivate *priv = context->priv;
@@ -309,7 +466,9 @@ gtk_cell_area_context_flush (GtkCellAreaContext *context)
g_return_if_fail (GTK_IS_CELL_AREA_CONTEXT (context));
gtk_cell_area_context_flush_preferred_width (context);
+ gtk_cell_area_context_flush_preferred_height_for_width (context, -1);
gtk_cell_area_context_flush_preferred_height (context);
+ gtk_cell_area_context_flush_preferred_width_for_height (context, -1);
gtk_cell_area_context_flush_allocation (context);
}
@@ -322,6 +481,15 @@ gtk_cell_area_context_flush_preferred_width (GtkCellAreaContext *context)
}
void
+gtk_cell_area_context_flush_preferred_height_for_width (GtkCellAreaContext *context,
+ gint for_width)
+{
+ g_return_if_fail (GTK_IS_CELL_AREA_CONTEXT (context));
+
+ GTK_CELL_AREA_CONTEXT_GET_CLASS (context)->flush_preferred_height_for_width (context, for_width);
+}
+
+void
gtk_cell_area_context_flush_preferred_height (GtkCellAreaContext *context)
{
g_return_if_fail (GTK_IS_CELL_AREA_CONTEXT (context));
@@ -330,6 +498,15 @@ gtk_cell_area_context_flush_preferred_height (GtkCellAreaContext *context)
}
void
+gtk_cell_area_context_flush_preferred_width_for_height (GtkCellAreaContext *context,
+ gint for_height)
+{
+ g_return_if_fail (GTK_IS_CELL_AREA_CONTEXT (context));
+
+ GTK_CELL_AREA_CONTEXT_GET_CLASS (context)->flush_preferred_width_for_height (context, for_height);
+}
+
+void
gtk_cell_area_context_flush_allocation (GtkCellAreaContext *context)
{
g_return_if_fail (GTK_IS_CELL_AREA_CONTEXT (context));
@@ -351,6 +528,20 @@ gtk_cell_area_context_sum_preferred_width (GtkCellAreaContext *context)
}
void
+gtk_cell_area_context_sum_preferred_height_for_width (GtkCellAreaContext *context,
+ gint for_width)
+{
+ GtkCellAreaContextClass *class;
+
+ g_return_if_fail (GTK_IS_CELL_AREA_CONTEXT (context));
+
+ class = GTK_CELL_AREA_CONTEXT_GET_CLASS (context);
+
+ if (class->sum_preferred_height_for_width)
+ class->sum_preferred_height_for_width (context, for_width);
+}
+
+void
gtk_cell_area_context_sum_preferred_height (GtkCellAreaContext *context)
{
GtkCellAreaContextClass *class;
@@ -364,6 +555,20 @@ gtk_cell_area_context_sum_preferred_height (GtkCellAreaContext *context)
}
void
+gtk_cell_area_context_sum_preferred_width_for_height (GtkCellAreaContext *context,
+ gint for_height)
+{
+ GtkCellAreaContextClass *class;
+
+ g_return_if_fail (GTK_IS_CELL_AREA_CONTEXT (context));
+
+ class = GTK_CELL_AREA_CONTEXT_GET_CLASS (context);
+
+ if (class->sum_preferred_width_for_height)
+ class->sum_preferred_width_for_height (context, for_height);
+}
+
+void
gtk_cell_area_context_allocate_width (GtkCellAreaContext *context,
gint width)
{
@@ -408,6 +613,39 @@ gtk_cell_area_context_get_preferred_width (GtkCellAreaContext *context,
}
void
+gtk_cell_area_context_get_preferred_height_for_width (GtkCellAreaContext *context,
+ gint for_width,
+ gint *minimum_height,
+ gint *natural_height)
+{
+ GtkCellAreaContextPrivate *priv;
+ CachedSize *size;
+
+ g_return_if_fail (GTK_IS_CELL_AREA_CONTEXT (context));
+
+ priv = context->priv;
+
+ size = g_hash_table_lookup (priv->heights, GINT_TO_POINTER (for_width));
+
+ 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_context_get_preferred_height (GtkCellAreaContext *context,
gint *minimum_height,
gint *natural_height)
@@ -426,6 +664,39 @@ gtk_cell_area_context_get_preferred_height (GtkCellAreaContext *context,
}
void
+gtk_cell_area_context_get_preferred_width_for_height (GtkCellAreaContext *context,
+ gint for_height,
+ gint *minimum_width,
+ gint *natural_width)
+{
+ GtkCellAreaContextPrivate *priv;
+ CachedSize *size;
+
+ g_return_if_fail (GTK_IS_CELL_AREA_CONTEXT (context));
+
+ priv = context->priv;
+
+ size = g_hash_table_lookup (priv->widths, GINT_TO_POINTER (for_height));
+
+ 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_context_get_allocation (GtkCellAreaContext *context,
gint *width,
gint *height)
@@ -474,6 +745,50 @@ gtk_cell_area_context_push_preferred_width (GtkCellAreaContext *context,
}
void
+gtk_cell_area_context_push_preferred_height_for_width (GtkCellAreaContext *context,
+ gint for_width,
+ gint minimum_height,
+ gint natural_height)
+{
+ GtkCellAreaContextPrivate *priv;
+ CachedSize *size;
+ gboolean changed = FALSE;
+
+ g_return_if_fail (GTK_IS_CELL_AREA_CONTEXT (context));
+
+ priv = context->priv;
+
+ size = g_hash_table_lookup (priv->heights, GINT_TO_POINTER (for_width));
+
+ if (!size)
+ {
+ size = cached_size_new (minimum_height, natural_height);
+
+ g_hash_table_insert (priv->heights, GINT_TO_POINTER (for_width), size);
+
+ changed = TRUE;
+ }
+ else
+ {
+ if (minimum_height > size->min_size)
+ {
+ size->min_size = minimum_height;
+ changed = TRUE;
+ }
+
+ if (natural_height > size->nat_size)
+ {
+ size->nat_size = natural_height;
+ changed = TRUE;
+ }
+ }
+
+ if (changed)
+ g_signal_emit (context, cell_area_context_signals[SIGNAL_HEIGHT_CHANGED], 0,
+ for_width, size->min_size, size->nat_size);
+}
+
+void
gtk_cell_area_context_push_preferred_height (GtkCellAreaContext *context,
gint minimum_height,
gint natural_height)
@@ -502,3 +817,47 @@ gtk_cell_area_context_push_preferred_height (GtkCellAreaContext *context,
g_object_thaw_notify (G_OBJECT (context));
}
+
+void
+gtk_cell_area_context_push_preferred_width_for_height (GtkCellAreaContext *context,
+ gint for_height,
+ gint minimum_width,
+ gint natural_width)
+{
+ GtkCellAreaContextPrivate *priv;
+ CachedSize *size;
+ gboolean changed = FALSE;
+
+ g_return_if_fail (GTK_IS_CELL_AREA_CONTEXT (context));
+
+ priv = context->priv;
+
+ size = g_hash_table_lookup (priv->widths, GINT_TO_POINTER (for_height));
+
+ if (!size)
+ {
+ size = cached_size_new (minimum_width, natural_width);
+
+ g_hash_table_insert (priv->widths, GINT_TO_POINTER (for_height), size);
+
+ changed = TRUE;
+ }
+ else
+ {
+ if (minimum_width > size->min_size)
+ {
+ size->min_size = minimum_width;
+ changed = TRUE;
+ }
+
+ if (natural_width > size->nat_size)
+ {
+ size->nat_size = natural_width;
+ changed = TRUE;
+ }
+ }
+
+ if (changed)
+ g_signal_emit (context, cell_area_context_signals[SIGNAL_WIDTH_CHANGED], 0,
+ for_height, size->min_size, size->nat_size);
+}
diff --git a/gtk/gtkcellareacontext.h b/gtk/gtkcellareacontext.h
index 0782f78..8e3621f 100644
--- a/gtk/gtkcellareacontext.h
+++ b/gtk/gtkcellareacontext.h
@@ -55,14 +55,22 @@ struct _GtkCellAreaContextClass
/* Subclasses can use this to flush their alignments/allocations */
void (* flush_preferred_width) (GtkCellAreaContext *context);
+ void (* flush_preferred_height_for_width) (GtkCellAreaContext *context,
+ gint width);
void (* flush_preferred_height) (GtkCellAreaContext *context);
+ void (* flush_preferred_width_for_height) (GtkCellAreaContext *context,
+ gint height);
void (* flush_allocation) (GtkCellAreaContext *context);
/* These must be invoked after a series of requests before consulting
* the context values, implementors use this to push the overall
* requests while acconting for any internal alignments */
void (* sum_preferred_width) (GtkCellAreaContext *context);
+ void (* sum_preferred_height_for_width) (GtkCellAreaContext *context,
+ gint width);
void (* sum_preferred_height) (GtkCellAreaContext *context);
+ void (* sum_preferred_width_for_height) (GtkCellAreaContext *context,
+ gint height);
/* Store an allocation value for a GtkCellArea contextual to a range of
* treemodel rows */
@@ -85,13 +93,21 @@ GtkCellArea *gtk_cell_area_context_get_area (GtkCellArea
/* Apis for GtkCellArea clients to flush the cache */
void gtk_cell_area_context_flush (GtkCellAreaContext *context);
void gtk_cell_area_context_flush_preferred_width (GtkCellAreaContext *context);
+void gtk_cell_area_context_flush_preferred_height_for_width (GtkCellAreaContext *context,
+ gint for_width);
void gtk_cell_area_context_flush_preferred_height (GtkCellAreaContext *context);
+void gtk_cell_area_context_flush_preferred_width_for_height (GtkCellAreaContext *context,
+ gint for_height);
void gtk_cell_area_context_flush_allocation (GtkCellAreaContext *context);
/* 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_context_sum_preferred_width (GtkCellAreaContext *context);
+void gtk_cell_area_context_sum_preferred_height_for_width (GtkCellAreaContext *context,
+ gint for_width);
void gtk_cell_area_context_sum_preferred_height (GtkCellAreaContext *context);
+void gtk_cell_area_context_sum_preferred_width_for_height (GtkCellAreaContext *context,
+ gint for_height);
/* Apis to set an allocation size in one dimension or another, the subclass specific context
* will store allocated positions/sizes for individual cells or groups of cells */
@@ -104,9 +120,17 @@ void gtk_cell_area_context_allocate_height (GtkCellArea
void gtk_cell_area_context_get_preferred_width (GtkCellAreaContext *context,
gint *minimum_width,
gint *natural_width);
+void gtk_cell_area_context_get_preferred_height_for_width (GtkCellAreaContext *context,
+ gint for_width,
+ gint *minimum_height,
+ gint *natural_height);
void gtk_cell_area_context_get_preferred_height (GtkCellAreaContext *context,
gint *minimum_height,
gint *natural_height);
+void gtk_cell_area_context_get_preferred_width_for_height (GtkCellAreaContext *context,
+ gint for_height,
+ gint *minimum_width,
+ gint *natural_width);
void gtk_cell_area_context_get_allocation (GtkCellAreaContext *context,
gint *width,
gint *height);
@@ -115,9 +139,17 @@ void gtk_cell_area_context_get_allocation (GtkCellArea
void gtk_cell_area_context_push_preferred_width (GtkCellAreaContext *context,
gint minimum_width,
gint natural_width);
+void gtk_cell_area_context_push_preferred_height_for_width (GtkCellAreaContext *context,
+ gint for_width,
+ gint minimum_height,
+ gint natural_height);
void gtk_cell_area_context_push_preferred_height (GtkCellAreaContext *context,
gint minimum_height,
gint natural_height);
+void gtk_cell_area_context_push_preferred_width_for_height (GtkCellAreaContext *context,
+ gint for_height,
+ gint minimum_width,
+ gint natural_width);
G_END_DECLS
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]