[gtk+/icon-view-refactor] Added apis to GtkCellArea for GtkIconView purposes.
- From: Tristan Van Berkom <tvb src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+/icon-view-refactor] Added apis to GtkCellArea for GtkIconView purposes.
- Date: Sun, 12 Dec 2010 15:19:45 +0000 (UTC)
commit 8eec3b8bdd34ee6d372729d6daa39992852717c6
Author: Tristan Van Berkom <tristan van berkom gmail com>
Date: Mon Dec 13 00:18:00 2010 +0900
Added apis to GtkCellArea for GtkIconView purposes.
Added a few apis,
- GtkCellAreaContext get_preferred_height_for_width &
width for height apis and vfuncs, this lets the icon view
request the collective (and aligned) height for width for
a said row.
- gtk_cell_area_copy_context() this creates a duplicate of
an already created and requested context, this way the icon
view uses a global context to request the widths of all rows
and then makes a copy with all the stored alignments and
uses a separate copy to calculate the height and alignments
of each row separately.
gtk/gtkcellarea.c | 40 ++++++++++++++
gtk/gtkcellarea.h | 4 ++
gtk/gtkcellareabox.c | 20 +++++++
gtk/gtkcellareaboxcontext.c | 127 +++++++++++++++++++++++++++++++++++++++----
gtk/gtkcellareaboxcontext.h | 4 ++
gtk/gtkcellareacontext.c | 60 ++++++++++++++++++++
gtk/gtkcellareacontext.h | 52 ++++++++++++------
7 files changed, 277 insertions(+), 30 deletions(-)
---
diff --git a/gtk/gtkcellarea.c b/gtk/gtkcellarea.c
index c21fdcd..59a1d01 100644
--- a/gtk/gtkcellarea.c
+++ b/gtk/gtkcellarea.c
@@ -1924,6 +1924,46 @@ gtk_cell_area_create_context (GtkCellArea *area)
return NULL;
}
+/**
+ * gtk_cell_area_copy_context:
+ * @area: a #GtkCellArea
+ * @context: the #GtkCellAreaContext to copy
+ *
+ * This is sometimes needed for cases where rows need to share
+ * alignments in one orientation but may be separately grouped
+ * in the opposing orientation.
+ *
+ * For instance, #GtkIconView creates all icons (rows) to have
+ * the same width and the cells theirin to have the same
+ * horizontal alignments. However each row of icons may have
+ * a separate collective height. #GtkIconView uses this to
+ * request the heights of each row based on a context which
+ * was already used to request all the row widths that are
+ * to be displayed.
+ *
+ * Return value: (transfer full): a newly created #GtkCellAreaContext copy of @context.
+ *
+ * Since: 3.0
+ */
+GtkCellAreaContext *
+gtk_cell_area_copy_context (GtkCellArea *area,
+ GtkCellAreaContext *context)
+{
+ GtkCellAreaClass *class;
+
+ g_return_val_if_fail (GTK_IS_CELL_AREA (area), NULL);
+ g_return_val_if_fail (GTK_IS_CELL_AREA_CONTEXT (context), NULL);
+
+ class = GTK_CELL_AREA_GET_CLASS (area);
+
+ if (class->copy_context)
+ return class->copy_context (area, context);
+
+ g_warning ("GtkCellAreaClass::copy_context not implemented for `%s'",
+ g_type_name (G_TYPE_FROM_INSTANCE (area)));
+
+ return NULL;
+}
/**
* gtk_cell_area_get_request_mode:
diff --git a/gtk/gtkcellarea.h b/gtk/gtkcellarea.h
index 8c54b05..6157922 100644
--- a/gtk/gtkcellarea.h
+++ b/gtk/gtkcellarea.h
@@ -202,6 +202,8 @@ struct _GtkCellAreaClass
/* Geometry */
GtkCellAreaContext *(* create_context) (GtkCellArea *area);
+ GtkCellAreaContext *(* copy_context) (GtkCellArea *area,
+ GtkCellAreaContext *context);
GtkSizeRequestMode (* get_request_mode) (GtkCellArea *area);
void (* get_preferred_width) (GtkCellArea *area,
GtkCellAreaContext *context,
@@ -316,6 +318,8 @@ GtkCellRenderer *gtk_cell_area_get_cell_at_position (GtkCellArea
/* Geometry */
GtkCellAreaContext *gtk_cell_area_create_context (GtkCellArea *area);
+GtkCellAreaContext *gtk_cell_area_copy_context (GtkCellArea *area,
+ GtkCellAreaContext *context);
GtkSizeRequestMode gtk_cell_area_get_request_mode (GtkCellArea *area);
void gtk_cell_area_get_preferred_width (GtkCellArea *area,
GtkCellAreaContext *context,
diff --git a/gtk/gtkcellareabox.c b/gtk/gtkcellareabox.c
index 286c670..56a856b 100644
--- a/gtk/gtkcellareabox.c
+++ b/gtk/gtkcellareabox.c
@@ -92,6 +92,8 @@ static void gtk_cell_area_box_get_cell_property (GtkCellArea
GValue *value,
GParamSpec *pspec);
static GtkCellAreaContext *gtk_cell_area_box_create_context (GtkCellArea *area);
+static GtkCellAreaContext *gtk_cell_area_box_copy_context (GtkCellArea *area,
+ GtkCellAreaContext *context);
static GtkSizeRequestMode gtk_cell_area_box_get_request_mode (GtkCellArea *area);
static void gtk_cell_area_box_get_preferred_width (GtkCellArea *area,
GtkCellAreaContext *context,
@@ -273,6 +275,7 @@ gtk_cell_area_box_class_init (GtkCellAreaBoxClass *class)
area_class->get_cell_property = gtk_cell_area_box_get_cell_property;
area_class->create_context = gtk_cell_area_box_create_context;
+ area_class->copy_context = gtk_cell_area_box_copy_context;
area_class->get_request_mode = gtk_cell_area_box_get_request_mode;
area_class->get_preferred_width = gtk_cell_area_box_get_preferred_width;
area_class->get_preferred_height = gtk_cell_area_box_get_preferred_height;
@@ -1301,6 +1304,23 @@ gtk_cell_area_box_create_context (GtkCellArea *area)
return context;
}
+static GtkCellAreaContext *
+gtk_cell_area_box_copy_context (GtkCellArea *area,
+ GtkCellAreaContext *context)
+{
+ GtkCellAreaBox *box = GTK_CELL_AREA_BOX (area);
+ GtkCellAreaBoxPrivate *priv = box->priv;
+ GtkCellAreaContext *copy =
+ (GtkCellAreaContext *)gtk_cell_area_box_context_copy (GTK_CELL_AREA_BOX (area),
+ GTK_CELL_AREA_BOX_CONTEXT (context));
+
+ priv->contexts = g_slist_prepend (priv->contexts, copy);
+
+ g_object_weak_ref (G_OBJECT (copy), (GWeakNotify)context_weak_notify, box);
+
+ return copy;
+}
+
static GtkSizeRequestMode
gtk_cell_area_box_get_request_mode (GtkCellArea *area)
{
diff --git a/gtk/gtkcellareaboxcontext.c b/gtk/gtkcellareaboxcontext.c
index cc4c0b4..fbf6ffe 100644
--- a/gtk/gtkcellareaboxcontext.c
+++ b/gtk/gtkcellareaboxcontext.c
@@ -35,10 +35,23 @@ static void gtk_cell_area_box_context_reset (GtkCellAreaCon
static void gtk_cell_area_box_context_allocate (GtkCellAreaContext *context,
gint width,
gint height);
+static void gtk_cell_area_box_context_get_preferred_height_for_width (GtkCellAreaContext *context,
+ gint width,
+ gint *minimum_height,
+ gint *natural_height);
+static void gtk_cell_area_box_context_get_preferred_width_for_height (GtkCellAreaContext *context,
+ gint height,
+ gint *minimum_width,
+ gint *natural_width);
+
+
/* Internal functions */
-static void gtk_cell_area_box_context_sum (GtkCellAreaBoxContext *context,
- GtkOrientation orientation);
+static void gtk_cell_area_box_context_sum (GtkCellAreaBoxContext *context,
+ GtkOrientation orientation,
+ gint for_size,
+ gint *minimum_size,
+ gint *natural_size);
static void free_cache_array (GArray *array);
static GArray *group_array_new (GtkCellAreaBoxContext *context);
static GArray *get_array (GtkCellAreaBoxContext *context,
@@ -190,8 +203,10 @@ gtk_cell_area_box_context_class_init (GtkCellAreaBoxContextClass *class)
/* GObjectClass */
object_class->finalize = gtk_cell_area_box_context_finalize;
- context_class->reset = gtk_cell_area_box_context_reset;
- context_class->allocate = gtk_cell_area_box_context_allocate;
+ context_class->reset = gtk_cell_area_box_context_reset;
+ context_class->allocate = gtk_cell_area_box_context_allocate;
+ context_class->get_preferred_height_for_width = gtk_cell_area_box_context_get_preferred_height_for_width;
+ context_class->get_preferred_width_for_height = gtk_cell_area_box_context_get_preferred_width_for_height;
g_type_class_add_private (object_class, sizeof (GtkCellAreaBoxContextPrivate));
}
@@ -402,7 +417,10 @@ gtk_cell_area_box_context_allocate (GtkCellAreaContext *context,
static void
gtk_cell_area_box_context_sum (GtkCellAreaBoxContext *context,
- GtkOrientation orientation)
+ GtkOrientation orientation,
+ gint for_size,
+ gint *minimum_size,
+ gint *natural_size)
{
GtkCellArea *area;
GtkOrientation box_orientation;
@@ -413,7 +431,7 @@ gtk_cell_area_box_context_sum (GtkCellAreaBoxContext *context,
area = gtk_cell_area_context_get_area (GTK_CELL_AREA_CONTEXT (context));
spacing = gtk_cell_area_box_get_spacing (GTK_CELL_AREA_BOX (area));
box_orientation = gtk_orientable_get_orientation (GTK_ORIENTABLE (area));
- array = get_array (context, orientation, -1);
+ array = get_array (context, orientation, for_size);
for (i = 0; i < array->len; i++)
{
@@ -440,15 +458,100 @@ gtk_cell_area_box_context_sum (GtkCellAreaBoxContext *context,
}
}
- if (orientation == GTK_ORIENTATION_HORIZONTAL)
- gtk_cell_area_context_push_preferred_width (GTK_CELL_AREA_CONTEXT (context), min_size, nat_size);
- else
- gtk_cell_area_context_push_preferred_height (GTK_CELL_AREA_CONTEXT (context), min_size, nat_size);
+ if (for_size < 0)
+ {
+ if (orientation == GTK_ORIENTATION_HORIZONTAL)
+ gtk_cell_area_context_push_preferred_width (GTK_CELL_AREA_CONTEXT (context), min_size, nat_size);
+ else
+ gtk_cell_area_context_push_preferred_height (GTK_CELL_AREA_CONTEXT (context), min_size, nat_size);
+ }
+
+ if (minimum_size)
+ *minimum_size = min_size;
+ if (natural_size)
+ *natural_size = nat_size;
+}
+
+static void
+gtk_cell_area_box_context_get_preferred_height_for_width (GtkCellAreaContext *context,
+ gint width,
+ gint *minimum_height,
+ gint *natural_height)
+{
+ gtk_cell_area_box_context_sum (GTK_CELL_AREA_BOX_CONTEXT (context), GTK_ORIENTATION_VERTICAL,
+ width, minimum_height, natural_height);
+}
+
+static void
+gtk_cell_area_box_context_get_preferred_width_for_height (GtkCellAreaContext *context,
+ gint height,
+ gint *minimum_width,
+ gint *natural_width)
+{
+ gtk_cell_area_box_context_sum (GTK_CELL_AREA_BOX_CONTEXT (context), GTK_ORIENTATION_HORIZONTAL,
+ height, minimum_width, natural_width);
}
/*************************************************************
* API *
*************************************************************/
+static void
+copy_size_array (GArray *src_array,
+ GArray *dest_array)
+{
+ gint i;
+
+ for (i = 0; i < src_array->len; i++)
+ {
+ CachedSize *src = &g_array_index (src_array, CachedSize, i);
+ CachedSize *dest = &g_array_index (dest_array, CachedSize, i);
+
+ memcpy (dest, src, sizeof (CachedSize));
+ }
+}
+
+static void
+for_size_copy (gpointer key,
+ GArray *size_array,
+ GHashTable *dest_hash)
+{
+ GArray *new_array;
+
+ new_array = g_array_new (FALSE, TRUE, sizeof (CachedSize));
+ g_array_set_size (new_array, size_array->len);
+
+ copy_size_array (size_array, new_array);
+
+ g_hash_table_insert (dest_hash, key, new_array);
+}
+
+GtkCellAreaBoxContext *
+gtk_cell_area_box_context_copy (GtkCellAreaBox *box,
+ GtkCellAreaBoxContext *box_context)
+{
+ GtkCellAreaBoxContext *context;
+
+ context = g_object_new (GTK_TYPE_CELL_AREA_BOX_CONTEXT,
+ "area", box, NULL);
+
+ gtk_cell_area_box_init_groups (context,
+ box_context->priv->base_widths->len,
+ box_context->priv->expand);
+
+ /* Copy all the arrays */
+ copy_size_array (box_context->priv->base_widths,
+ context->priv->base_widths);
+ copy_size_array (box_context->priv->base_heights,
+ context->priv->base_heights);
+
+ g_hash_table_foreach (box_context->priv->heights,
+ (GHFunc)for_size_copy, context->priv->heights);
+ g_hash_table_foreach (box_context->priv->widths,
+ (GHFunc)for_size_copy, context->priv->widths);
+
+ return context;
+}
+
void
gtk_cell_area_box_init_groups (GtkCellAreaBoxContext *box_context,
guint n_groups,
@@ -500,7 +603,7 @@ gtk_cell_area_box_context_push_group_width (GtkCellAreaBoxContext *box_context,
}
if (grew)
- gtk_cell_area_box_context_sum (box_context, GTK_ORIENTATION_HORIZONTAL);
+ gtk_cell_area_box_context_sum (box_context, GTK_ORIENTATION_HORIZONTAL, -1, NULL, NULL);
}
void
@@ -559,7 +662,7 @@ gtk_cell_area_box_context_push_group_height (GtkCellAreaBoxContext *box_context,
}
if (grew)
- gtk_cell_area_box_context_sum (box_context, GTK_ORIENTATION_VERTICAL);
+ gtk_cell_area_box_context_sum (box_context, GTK_ORIENTATION_VERTICAL, -1, NULL, NULL);
}
void
diff --git a/gtk/gtkcellareaboxcontext.h b/gtk/gtkcellareaboxcontext.h
index 7800b0f..1161d38 100644
--- a/gtk/gtkcellareaboxcontext.h
+++ b/gtk/gtkcellareaboxcontext.h
@@ -62,6 +62,10 @@ struct _GtkCellAreaBoxContextClass
GType gtk_cell_area_box_context_get_type (void) G_GNUC_CONST;
+/* Create a duplicate of the context */
+GtkCellAreaBoxContext *gtk_cell_area_box_context_copy (GtkCellAreaBox *box,
+ GtkCellAreaBoxContext *box_context);
+
/* Initialize group array dimensions */
void gtk_cell_area_box_init_groups (GtkCellAreaBoxContext *box_context,
guint n_groups,
diff --git a/gtk/gtkcellareacontext.c b/gtk/gtkcellareacontext.c
index 087b590..f3c14b0 100644
--- a/gtk/gtkcellareacontext.c
+++ b/gtk/gtkcellareacontext.c
@@ -490,6 +490,66 @@ gtk_cell_area_context_get_preferred_height (GtkCellAreaContext *context,
}
/**
+ * gtk_cell_area_context_get_preferred_height_for_width:
+ * @context: a #GtkCellAreaContext
+ * @width: a proposed width for allocation
+ * @minimum_height: (out) (allow-none): location to store the minimum height, or %NULL
+ * @natural_height: (out) (allow-none): location to store the natural height, or %NULL
+ *
+ * Gets the accumulative preferred height for @width for all rows which have been
+ * requested for the same said @width with this context.
+ *
+ * After gtk_cell_area_context_reset() is called and/or before ever requesting
+ * the size of a #GtkCellArea, the returned values are -1.
+ *
+ * Since: 3.0
+ */
+void
+gtk_cell_area_context_get_preferred_height_for_width (GtkCellAreaContext *context,
+ gint width,
+ gint *minimum_height,
+ gint *natural_height)
+{
+ g_return_if_fail (GTK_IS_CELL_AREA_CONTEXT (context));
+
+ if (GTK_CELL_AREA_CONTEXT_GET_CLASS (context)->get_preferred_height_for_width)
+ GTK_CELL_AREA_CONTEXT_GET_CLASS (context)->get_preferred_height_for_width (context,
+ width,
+ minimum_height,
+ natural_height);
+}
+
+/**
+ * gtk_cell_area_context_get_preferred_width_for_height:
+ * @context: a #GtkCellAreaContext
+ * @height: a proposed height for allocation
+ * @minimum_width: (out) (allow-none): location to store the minimum width, or %NULL
+ * @natural_width: (out) (allow-none): location to store the natural width, or %NULL
+ *
+ * Gets the accumulative preferred width for @height for all rows which have
+ * been requested for the same said @height with this context.
+ *
+ * After gtk_cell_area_context_reset() is called and/or before ever requesting
+ * the size of a #GtkCellArea, the returned values are -1.
+ *
+ * Since: 3.0
+ */
+void
+gtk_cell_area_context_get_preferred_width_for_height (GtkCellAreaContext *context,
+ gint height,
+ gint *minimum_width,
+ gint *natural_width)
+{
+ g_return_if_fail (GTK_IS_CELL_AREA_CONTEXT (context));
+
+ if (GTK_CELL_AREA_CONTEXT_GET_CLASS (context)->get_preferred_width_for_height)
+ GTK_CELL_AREA_CONTEXT_GET_CLASS (context)->get_preferred_width_for_height (context,
+ height,
+ minimum_width,
+ natural_width);
+}
+
+/**
* gtk_cell_area_context_get_allocation:
* @context: a #GtkCellAreaContext
* @width: (out) (allow-none): location to store the allocated width, or %NULL.
diff --git a/gtk/gtkcellareacontext.h b/gtk/gtkcellareacontext.h
index 2731a73..d2b462c 100644
--- a/gtk/gtkcellareacontext.h
+++ b/gtk/gtkcellareacontext.h
@@ -65,10 +65,18 @@ struct _GtkCellAreaContextClass
GObjectClass parent_class;
/*< public >*/
- void (* allocate) (GtkCellAreaContext *context,
- gint width,
- gint height);
- void (* reset) (GtkCellAreaContext *context);
+ void (* allocate) (GtkCellAreaContext *context,
+ gint width,
+ gint height);
+ void (* reset) (GtkCellAreaContext *context);
+ void (* get_preferred_height_for_width) (GtkCellAreaContext *context,
+ gint width,
+ gint *minimum_height,
+ gint *natural_height);
+ void (* get_preferred_width_for_height) (GtkCellAreaContext *context,
+ gint height,
+ gint *minimum_width,
+ gint *natural_width);
/*< private >*/
/* Padding for future expansion */
@@ -81,22 +89,30 @@ struct _GtkCellAreaContextClass
GType gtk_cell_area_context_get_type (void) G_GNUC_CONST;
/* Main apis */
-GtkCellArea *gtk_cell_area_context_get_area (GtkCellAreaContext *context);
-void gtk_cell_area_context_allocate (GtkCellAreaContext *context,
- gint width,
- gint height);
-void gtk_cell_area_context_reset (GtkCellAreaContext *context);
+GtkCellArea *gtk_cell_area_context_get_area (GtkCellAreaContext *context);
+void gtk_cell_area_context_allocate (GtkCellAreaContext *context,
+ gint width,
+ gint height);
+void gtk_cell_area_context_reset (GtkCellAreaContext *context);
/* Apis for GtkCellArea clients to consult cached values for a series of GtkTreeModel rows */
-void gtk_cell_area_context_get_preferred_width (GtkCellAreaContext *context,
- gint *minimum_width,
- gint *natural_width);
-void gtk_cell_area_context_get_preferred_height (GtkCellAreaContext *context,
- gint *minimum_height,
- gint *natural_height);
-void gtk_cell_area_context_get_allocation (GtkCellAreaContext *context,
- gint *width,
- gint *height);
+void gtk_cell_area_context_get_preferred_width (GtkCellAreaContext *context,
+ gint *minimum_width,
+ gint *natural_width);
+void gtk_cell_area_context_get_preferred_height (GtkCellAreaContext *context,
+ gint *minimum_height,
+ gint *natural_height);
+void gtk_cell_area_context_get_preferred_height_for_width (GtkCellAreaContext *context,
+ gint width,
+ gint *minimum_height,
+ gint *natural_height);
+void gtk_cell_area_context_get_preferred_width_for_height (GtkCellAreaContext *context,
+ gint height,
+ gint *minimum_width,
+ gint *natural_width);
+void gtk_cell_area_context_get_allocation (GtkCellAreaContext *context,
+ gint *width,
+ gint *height);
/* Apis for GtkCellArea implementations to update cached values for multiple GtkTreeModel rows */
void gtk_cell_area_context_push_preferred_width (GtkCellAreaContext *context,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]