[gtk+/treeview-refactor: 80/102] Implemented basic child list handling on GtkCellAreaBox
- From: Tristan Van Berkom <tvb src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+/treeview-refactor: 80/102] Implemented basic child list handling on GtkCellAreaBox
- Date: Tue, 26 Oct 2010 09:22:16 +0000 (UTC)
commit 468a1d3e7c51a7b1964ccfcc680c24a04322338e
Author: Tristan Van Berkom <tristan van berkom gmail com>
Date: Sun Oct 24 20:01:04 2010 +0900
Implemented basic child list handling on GtkCellAreaBox
Added the child list to GtkCellAreaBox, added _pack_start() and
_pack_end() apis to GtkCellAreaBox since they are appropriate there
and implemented GtkCellLayoutIface to override the _pack_start()/end()
methods (since the base GtkCellArea class simply forwards these apis
to the generic ->add() api on the base class).
gtk/gtkcellarea.c | 121 ++++++++++++++++++-----------------
gtk/gtkcellareabox.c | 174 +++++++++++++++++++++++++++++++++++++++++++++++++-
gtk/gtkcellareabox.h | 12 +++-
3 files changed, 244 insertions(+), 63 deletions(-)
---
diff --git a/gtk/gtkcellarea.c b/gtk/gtkcellarea.c
index be47423..c8a2c3e 100644
--- a/gtk/gtkcellarea.c
+++ b/gtk/gtkcellarea.c
@@ -84,6 +84,8 @@ static CellAttribute *cell_attribute_new (GtkCellRenderer *renderer,
const gchar *attribute,
gint column);
static void cell_attribute_free (CellAttribute *attribute);
+static gint cell_attribute_find (CellAttribute *cell_attribute,
+ const gchar *attribute);
/* Struct to pass data along while looping over
* cell renderers to apply attributes
@@ -145,65 +147,8 @@ gtk_cell_area_class_init (GtkCellAreaClass *class)
g_type_class_add_private (object_class, sizeof (GtkCellAreaPrivate));
}
-
/*************************************************************
- * GObjectClass *
- *************************************************************/
-static void
-gtk_cell_area_finalize (GObject *object)
-{
- GtkCellArea *area = GTK_CELL_AREA (object);
- GtkCellAreaPrivate *priv = area->priv;
-
- /* All cell renderers should already be removed at this point,
- * just kill our hash table here.
- */
- g_hash_table_destroy (priv->cell_info);
-
- G_OBJECT_CLASS (gtk_cell_area_parent_class)->finalize (object);
-}
-
-
-static void
-gtk_cell_area_dispose (GObject *object)
-{
- /* This removes every cell renderer that may be added to the GtkCellArea,
- * subclasses should be breaking references to the GtkCellRenderers
- * at this point.
- */
- gtk_cell_layout_clear (GTK_CELL_LAYOUT (object));
-
- G_OBJECT_CLASS (gtk_cell_area_parent_class)->dispose (object);
-}
-
-
-/*************************************************************
- * GtkCellAreaClass *
- *************************************************************/
-static void
-gtk_cell_area_real_get_preferred_height_for_width (GtkCellArea *area,
- GtkWidget *widget,
- gint width,
- gint *minimum_height,
- gint *natural_height)
-{
- /* If the area doesnt do height-for-width, fallback on base preferred height */
- GTK_CELL_AREA_GET_CLASS (area)->get_preferred_width (area, widget, minimum_height, natural_height);
-}
-
-static void
-gtk_cell_area_real_get_preferred_width_for_height (GtkCellArea *area,
- GtkWidget *widget,
- gint height,
- gint *minimum_width,
- gint *natural_width)
-{
- /* If the area doesnt do width-for-height, fallback on base preferred width */
- GTK_CELL_AREA_GET_CLASS (area)->get_preferred_width (area, widget, minimum_width, natural_width);
-}
-
-/*************************************************************
- * GtkCellLayoutIface *
+ * CellInfo Basics *
*************************************************************/
static CellInfo *
cell_info_new (GtkCellLayoutDataFunc func,
@@ -264,6 +209,7 @@ cell_attribute_free (CellAttribute *attribute)
g_slice_free (CellAttribute, attribute);
}
+/* GCompareFunc for g_slist_find_custom() */
static gint
cell_attribute_find (CellAttribute *cell_attribute,
const gchar *attribute)
@@ -271,6 +217,65 @@ cell_attribute_find (CellAttribute *cell_attribute,
return g_strcmp0 (cell_attribute->attribute, attribute);
}
+/*************************************************************
+ * GObjectClass *
+ *************************************************************/
+static void
+gtk_cell_area_finalize (GObject *object)
+{
+ GtkCellArea *area = GTK_CELL_AREA (object);
+ GtkCellAreaPrivate *priv = area->priv;
+
+ /* All cell renderers should already be removed at this point,
+ * just kill our hash table here.
+ */
+ g_hash_table_destroy (priv->cell_info);
+
+ G_OBJECT_CLASS (gtk_cell_area_parent_class)->finalize (object);
+}
+
+
+static void
+gtk_cell_area_dispose (GObject *object)
+{
+ /* This removes every cell renderer that may be added to the GtkCellArea,
+ * subclasses should be breaking references to the GtkCellRenderers
+ * at this point.
+ */
+ gtk_cell_layout_clear (GTK_CELL_LAYOUT (object));
+
+ G_OBJECT_CLASS (gtk_cell_area_parent_class)->dispose (object);
+}
+
+
+/*************************************************************
+ * GtkCellAreaClass *
+ *************************************************************/
+static void
+gtk_cell_area_real_get_preferred_height_for_width (GtkCellArea *area,
+ GtkWidget *widget,
+ gint width,
+ gint *minimum_height,
+ gint *natural_height)
+{
+ /* If the area doesnt do height-for-width, fallback on base preferred height */
+ GTK_CELL_AREA_GET_CLASS (area)->get_preferred_width (area, widget, minimum_height, natural_height);
+}
+
+static void
+gtk_cell_area_real_get_preferred_width_for_height (GtkCellArea *area,
+ GtkWidget *widget,
+ gint height,
+ gint *minimum_width,
+ gint *natural_width)
+{
+ /* If the area doesnt do width-for-height, fallback on base preferred width */
+ GTK_CELL_AREA_GET_CLASS (area)->get_preferred_width (area, widget, minimum_width, natural_width);
+}
+
+/*************************************************************
+ * GtkCellLayoutIface *
+ *************************************************************/
static void
gtk_cell_area_cell_layout_init (GtkCellLayoutIface *iface)
{
diff --git a/gtk/gtkcellareabox.c b/gtk/gtkcellareabox.c
index a635df2..75e004a 100644
--- a/gtk/gtkcellareabox.c
+++ b/gtk/gtkcellareabox.c
@@ -22,6 +22,7 @@
*/
#include "gtkorientable.h"
+#include "gtkcelllayout.h"
#include "gtkcellareabox.h"
/* GObjectClass */
@@ -73,11 +74,37 @@ static void gtk_cell_area_box_get_preferred_width_for_height (GtkCellArea
gint *minimum_width,
gint *natural_width);
+/* GtkCellLayoutIface */
+static void gtk_cell_area_box_cell_layout_init (GtkCellLayoutIface *iface);
+static void gtk_cell_area_box_layout_pack_start (GtkCellLayout *cell_layout,
+ GtkCellRenderer *renderer,
+ gboolean expand);
+static void gtk_cell_area_box_layout_pack_end (GtkCellLayout *cell_layout,
+ GtkCellRenderer *renderer,
+ gboolean expand);
+
+
+/* CellInfo metadata handling */
+typedef struct {
+ GtkCellRenderer *renderer;
+
+ guint expand : 1;
+ guint pack : 1;
+} CellInfo;
+
+static CellInfo *cell_info_new (GtkCellRenderer *renderer,
+ gboolean expand,
+ GtkPackType pack);
+static void cell_info_free (CellInfo *info);
+static gint cell_info_find (CellInfo *info,
+ GtkCellRenderer *renderer);
+
struct _GtkCellAreaBoxPrivate
{
GtkOrientation orientation;
+ GList *cells;
};
enum {
@@ -86,9 +113,10 @@ enum {
};
G_DEFINE_TYPE_WITH_CODE (GtkCellAreaBox, gtk_cell_area_box, GTK_TYPE_CELL_AREA,
+ G_IMPLEMENT_INTERFACE (GTK_TYPE_CELL_LAYOUT,
+ gtk_cell_area_box_cell_layout_init)
G_IMPLEMENT_INTERFACE (GTK_TYPE_ORIENTABLE, NULL));
-
static void
gtk_cell_area_box_init (GtkCellAreaBox *box)
{
@@ -100,6 +128,7 @@ gtk_cell_area_box_init (GtkCellAreaBox *box)
priv = box->priv;
priv->orientation = GTK_ORIENTATION_HORIZONTAL;
+ priv->cells = NULL;
}
static void
@@ -135,6 +164,38 @@ gtk_cell_area_box_class_init (GtkCellAreaBoxClass *class)
/*************************************************************
+ * CellInfo Basics *
+ *************************************************************/
+static CellInfo *
+cell_info_new (GtkCellRenderer *renderer,
+ gboolean expand,
+ GtkPackType pack)
+{
+ CellInfo *info = g_slice_new (CellInfo);
+
+ info->renderer = g_object_ref_sink (renderer);
+ info->expand = expand;
+ info->pack = pack;
+
+ return info;
+}
+
+static void
+cell_info_free (CellInfo *info)
+{
+ g_object_unref (info->renderer);
+
+ g_slice_free (CellInfo, info);
+}
+
+static gint
+cell_info_find (CellInfo *info,
+ GtkCellRenderer *renderer)
+{
+ return (info->renderer == renderer) ? 0 : -1;
+}
+
+/*************************************************************
* GObjectClass *
*************************************************************/
static void
@@ -174,14 +235,31 @@ static void
gtk_cell_area_box_add (GtkCellArea *area,
GtkCellRenderer *renderer)
{
-
+ gtk_cell_area_box_pack_start (GTK_CELL_AREA_BOX (area),
+ renderer, FALSE);
}
static void
gtk_cell_area_box_remove (GtkCellArea *area,
GtkCellRenderer *renderer)
{
+ GtkCellAreaBox *box = GTK_CELL_AREA_BOX (area);
+ GtkCellAreaBoxPrivate *priv = box->priv;
+ GList *node;
+
+ node = g_list_find_custom (priv->cells, renderer,
+ (GCompareFunc)cell_info_find);
+
+ if (node)
+ {
+ CellInfo *info = node->data;
+ cell_info_free (info);
+
+ priv->cells = g_list_delete_link (priv->cells, node);
+ }
+ else
+ g_warning ("Trying to remove a cell renderer that is not present GtkCellAreaBox");
}
static void
@@ -189,7 +267,16 @@ gtk_cell_area_box_forall (GtkCellArea *area,
GtkCellCallback callback,
gpointer callback_data)
{
+ GtkCellAreaBox *box = GTK_CELL_AREA_BOX (area);
+ GtkCellAreaBoxPrivate *priv = box->priv;
+ GList *list;
+
+ for (list = priv->cells; list; list = list->next)
+ {
+ CellInfo *info = list->data;
+ callback (info->renderer, callback_data);
+ }
}
static gint
@@ -262,6 +349,89 @@ gtk_cell_area_box_get_preferred_width_for_height (GtkCellArea *area,
}
+
+
+/*************************************************************
+ * GtkCellLayoutIface *
+ *************************************************************/
+static void
+gtk_cell_area_box_cell_layout_init (GtkCellLayoutIface *iface)
+{
+ iface->pack_start = gtk_cell_area_box_layout_pack_start;
+ iface->pack_end = gtk_cell_area_box_layout_pack_end;
+}
+
+static void
+gtk_cell_area_box_layout_pack_start (GtkCellLayout *cell_layout,
+ GtkCellRenderer *renderer,
+ gboolean expand)
+{
+ gtk_cell_area_box_pack_start (GTK_CELL_AREA_BOX (cell_layout), renderer, expand);
+}
+
+static void
+gtk_cell_area_box_layout_pack_end (GtkCellLayout *cell_layout,
+ GtkCellRenderer *renderer,
+ gboolean expand)
+{
+ gtk_cell_area_box_pack_end (GTK_CELL_AREA_BOX (cell_layout), renderer, expand);
+}
+
/*************************************************************
* API *
*************************************************************/
+GtkCellArea *
+gtk_cell_area_box_new (void)
+{
+ return (GtkCellArea *)g_object_new (GTK_TYPE_CELL_AREA_BOX, NULL);
+}
+
+void
+gtk_cell_area_box_pack_start (GtkCellAreaBox *box,
+ GtkCellRenderer *renderer,
+ gboolean expand)
+{
+ GtkCellAreaBoxPrivate *priv;
+ CellInfo *info;
+
+ g_return_if_fail (GTK_IS_CELL_AREA_BOX (box));
+ g_return_if_fail (GTK_IS_CELL_RENDERER (renderer));
+
+ priv = box->priv;
+
+ if (g_list_find_custom (priv->cells, renderer,
+ (GCompareFunc)cell_info_find))
+ {
+ g_warning ("Refusing to add the same cell renderer to a GtkCellAreaBox twice");
+ return;
+ }
+
+ info = cell_info_new (renderer, expand, GTK_PACK_START);
+
+ priv->cells = g_list_append (priv->cells, info);
+}
+
+void
+gtk_cell_area_box_pack_end (GtkCellAreaBox *box,
+ GtkCellRenderer *renderer,
+ gboolean expand)
+{
+ GtkCellAreaBoxPrivate *priv;
+ CellInfo *info;
+
+ g_return_if_fail (GTK_IS_CELL_AREA_BOX (box));
+ g_return_if_fail (GTK_IS_CELL_RENDERER (renderer));
+
+ priv = box->priv;
+
+ if (g_list_find_custom (priv->cells, renderer,
+ (GCompareFunc)cell_info_find))
+ {
+ g_warning ("Refusing to add the same cell renderer to a GtkCellArea twice");
+ return;
+ }
+
+ info = cell_info_new (renderer, expand, GTK_PACK_END);
+
+ priv->cells = g_list_append (priv->cells, info);
+}
diff --git a/gtk/gtkcellareabox.h b/gtk/gtkcellareabox.h
index 1e188ce..1913995 100644
--- a/gtk/gtkcellareabox.h
+++ b/gtk/gtkcellareabox.h
@@ -62,9 +62,15 @@ struct _GtkCellAreaBoxClass
void (*_gtk_reserved4) (void);
};
-GType gtk_cell_area_box_get_type (void) G_GNUC_CONST;
-
-
+GType gtk_cell_area_box_get_type (void) G_GNUC_CONST;
+
+GtkCellArea *gtk_cell_area_box_new (void);
+void gtk_cell_area_box_pack_start (GtkCellAreaBox *box,
+ GtkCellRenderer *renderer,
+ gboolean expand);
+void gtk_cell_area_box_pack_end (GtkCellAreaBox *box,
+ GtkCellRenderer *renderer,
+ gboolean expand);
G_END_DECLS
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]