mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-11-18 09:00:34 +00:00
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:
parent
0722fbe7c8
commit
468a1d3e7c
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user