summaryrefslogtreecommitdiff
path: root/gtk/gtkcellareacontext.c
diff options
context:
space:
mode:
authorTristan Van Berkom <tristan.van.berkom@gmail.com>2010-11-26 21:26:24 +0900
committerTristan Van Berkom <tristan.van.berkom@gmail.com>2010-11-26 21:38:10 +0900
commit487223d480578457f924470c1a1d73eb261eefd7 (patch)
treee6888ecfc4a29875b54e5ba349a47f36ccc183fd /gtk/gtkcellareacontext.c
parentfa3c8f182edcddcfb948513fbdadeeec2e059fe0 (diff)
downloadgtk+-487223d480578457f924470c1a1d73eb261eefd7.tar.gz
Finally really support rendering of cells in an unallocated context.
What this means is basically that a vertically oriented GtkCellAreaBox will render cells properly even if the height is not constant for every for of data in the said GtkCellAreaContext (i.e. the height was not allocated by gtk_cell_area_context_allocate). This is done completely on the fly and so is much more heavy duty at render time (considerably slower but not visibly noticable in lightweight views like GtkTreeMenu). Note that cell alignments are not possible in an unallocated orientation, each row of data individually receives only enough space to render the independant row and no space is reserved for alignments if the size is not a constant size across rows in the same context.
Diffstat (limited to 'gtk/gtkcellareacontext.c')
-rw-r--r--gtk/gtkcellareacontext.c415
1 files changed, 16 insertions, 399 deletions
diff --git a/gtk/gtkcellareacontext.c b/gtk/gtkcellareacontext.c
index 61646708db..5a3ee8b28a 100644
--- a/gtk/gtkcellareacontext.c
+++ b/gtk/gtkcellareacontext.c
@@ -28,7 +28,6 @@
#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,
@@ -41,26 +40,12 @@ 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,
+static void gtk_cell_area_context_real_allocate (GtkCellAreaContext *context,
+ gint width,
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;
@@ -71,9 +56,6 @@ struct _GtkCellAreaContextPrivate
gint nat_height;
gint alloc_width;
gint alloc_height;
-
- GHashTable *widths;
- GHashTable *heights;
};
enum {
@@ -85,14 +67,6 @@ 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
@@ -109,10 +83,6 @@ 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
@@ -121,45 +91,17 @@ 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_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);
+ class->flush_preferred_width = gtk_cell_area_context_real_flush_preferred_width;
+ class->flush_preferred_height = gtk_cell_area_context_real_flush_preferred_height;
+ class->flush_allocation = gtk_cell_area_context_real_flush_allocation;
+ class->sum_preferred_width = NULL;
+ class->sum_preferred_height = NULL;
+ class->allocate = gtk_cell_area_context_real_allocate;
g_object_class_install_property (object_class,
PROP_CELL_AREA,
@@ -212,45 +154,10 @@ 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);
@@ -336,40 +243,6 @@ 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;
@@ -384,40 +257,6 @@ 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;
@@ -427,24 +266,16 @@ gtk_cell_area_context_real_flush_allocation (GtkCellAreaContext *context)
}
static void
-gtk_cell_area_context_real_allocate_width (GtkCellAreaContext *context,
- gint width)
-{
- GtkCellAreaContextPrivate *priv = context->priv;
-
- priv->alloc_width = width;
-}
-
-static void
-gtk_cell_area_context_real_allocate_height (GtkCellAreaContext *context,
- gint height)
+gtk_cell_area_context_real_allocate (GtkCellAreaContext *context,
+ gint width,
+ gint height)
{
GtkCellAreaContextPrivate *priv = context->priv;
+ priv->alloc_width = width;
priv->alloc_height = height;
}
-
/*************************************************************
* API *
*************************************************************/
@@ -466,9 +297,7 @@ 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);
}
@@ -481,15 +310,6 @@ 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));
@@ -498,15 +318,6 @@ 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));
@@ -528,20 +339,6 @@ 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;
@@ -555,8 +352,9 @@ gtk_cell_area_context_sum_preferred_height (GtkCellAreaContext *context)
}
void
-gtk_cell_area_context_sum_preferred_width_for_height (GtkCellAreaContext *context,
- gint for_height)
+gtk_cell_area_context_allocate (GtkCellAreaContext *context,
+ gint width,
+ gint height)
{
GtkCellAreaContextClass *class;
@@ -564,34 +362,7 @@ gtk_cell_area_context_sum_preferred_width_for_height (GtkCellAreaContext *contex
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)
-{
- GtkCellAreaContextClass *class;
-
- g_return_if_fail (GTK_IS_CELL_AREA_CONTEXT (context));
-
- class = GTK_CELL_AREA_CONTEXT_GET_CLASS (context);
-
- class->allocate_width (context, width);
-}
-
-void
-gtk_cell_area_context_allocate_height (GtkCellAreaContext *context,
- gint height)
-{
- GtkCellAreaContextClass *class;
-
- g_return_if_fail (GTK_IS_CELL_AREA_CONTEXT (context));
-
- class = GTK_CELL_AREA_CONTEXT_GET_CLASS (context);
-
- class->allocate_height (context, height);
+ class->allocate (context, width, height);
}
void
@@ -613,39 +384,6 @@ 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)
@@ -664,39 +402,6 @@ 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)
@@ -745,50 +450,6 @@ 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)
@@ -817,47 +478,3 @@ 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);
-}