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).
This commit is contained in:
		@ -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)
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
@ -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 
 | 
			
		||||
@ -134,6 +163,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                         *
 | 
			
		||||
 *************************************************************/
 | 
			
		||||
@ -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);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -64,7 +64,13 @@ struct _GtkCellAreaBoxClass
 | 
			
		||||
 | 
			
		||||
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
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user