mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-12-30 15:31:34 +00:00
Implemented "cell properties" on the GtkCellArea
Added cell "packing" properties for generic configuration of child cells inside an area.
This commit is contained in:
parent
6da74b6e1e
commit
d781c226da
@ -21,10 +21,19 @@
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "gtkcelllayout.h"
|
||||
#include "gtkcellarea.h"
|
||||
#include "gtkcellareaiter.h"
|
||||
|
||||
#include <gobject/gvaluecollector.h>
|
||||
|
||||
|
||||
/* GObjectClass */
|
||||
static void gtk_cell_area_dispose (GObject *object);
|
||||
static void gtk_cell_area_finalize (GObject *object);
|
||||
@ -104,6 +113,14 @@ struct _GtkCellAreaPrivate
|
||||
GHashTable *cell_info;
|
||||
};
|
||||
|
||||
/* Keep the paramspec pool internal, no need to deliver notifications
|
||||
* on cells. at least no percieved need for now */
|
||||
static GParamSpecPool *cell_property_pool = NULL;
|
||||
|
||||
#define PARAM_SPEC_PARAM_ID(pspec) ((pspec)->param_id)
|
||||
#define PARAM_SPEC_SET_PARAM_ID(pspec, id) ((pspec)->param_id = (id))
|
||||
|
||||
|
||||
G_DEFINE_ABSTRACT_TYPE_WITH_CODE (GtkCellArea, gtk_cell_area, G_TYPE_INITIALLY_UNOWNED,
|
||||
G_IMPLEMENT_INTERFACE (GTK_TYPE_CELL_LAYOUT,
|
||||
gtk_cell_area_cell_layout_init));
|
||||
@ -148,6 +165,10 @@ gtk_cell_area_class_init (GtkCellAreaClass *class)
|
||||
class->get_preferred_height_for_width = gtk_cell_area_real_get_preferred_height_for_width;
|
||||
class->get_preferred_width_for_height = gtk_cell_area_real_get_preferred_width_for_height;
|
||||
|
||||
/* Cell properties */
|
||||
if (!cell_property_pool)
|
||||
cell_property_pool = g_param_spec_pool_new (FALSE);
|
||||
|
||||
g_type_class_add_private (object_class, sizeof (GtkCellAreaPrivate));
|
||||
}
|
||||
|
||||
@ -419,7 +440,6 @@ gtk_cell_area_get_cells (GtkCellLayout *cell_layout)
|
||||
/*************************************************************
|
||||
* API *
|
||||
*************************************************************/
|
||||
|
||||
void
|
||||
gtk_cell_area_add (GtkCellArea *area,
|
||||
GtkCellRenderer *renderer)
|
||||
@ -644,6 +664,7 @@ gtk_cell_area_get_preferred_width_for_height (GtkCellArea *area,
|
||||
class->get_preferred_width_for_height (area, iter, widget, height, minimum_width, natural_width);
|
||||
}
|
||||
|
||||
/* Attributes */
|
||||
void
|
||||
gtk_cell_area_attribute_connect (GtkCellArea *area,
|
||||
GtkCellRenderer *renderer,
|
||||
@ -776,3 +797,349 @@ gtk_cell_area_apply_attributes (GtkCellArea *area,
|
||||
* apply the data from the treemodel */
|
||||
g_hash_table_foreach (priv->cell_info, (GHFunc)apply_cell_attributes, &data);
|
||||
}
|
||||
|
||||
/* Cell Properties */
|
||||
void
|
||||
gtk_cell_area_class_install_cell_property (GtkCellAreaClass *aclass,
|
||||
guint property_id,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
g_return_if_fail (GTK_IS_CELL_AREA_CLASS (aclass));
|
||||
g_return_if_fail (G_IS_PARAM_SPEC (pspec));
|
||||
if (pspec->flags & G_PARAM_WRITABLE)
|
||||
g_return_if_fail (aclass->set_cell_property != NULL);
|
||||
if (pspec->flags & G_PARAM_READABLE)
|
||||
g_return_if_fail (aclass->get_cell_property != NULL);
|
||||
g_return_if_fail (property_id > 0);
|
||||
g_return_if_fail (PARAM_SPEC_PARAM_ID (pspec) == 0); /* paranoid */
|
||||
g_return_if_fail ((pspec->flags & (G_PARAM_CONSTRUCT | G_PARAM_CONSTRUCT_ONLY)) == 0);
|
||||
|
||||
if (g_param_spec_pool_lookup (cell_property_pool, pspec->name, G_OBJECT_CLASS_TYPE (aclass), TRUE))
|
||||
{
|
||||
g_warning (G_STRLOC ": class `%s' already contains a cell property named `%s'",
|
||||
G_OBJECT_CLASS_NAME (aclass), pspec->name);
|
||||
return;
|
||||
}
|
||||
g_param_spec_ref (pspec);
|
||||
g_param_spec_sink (pspec);
|
||||
PARAM_SPEC_SET_PARAM_ID (pspec, property_id);
|
||||
g_param_spec_pool_insert (cell_property_pool, pspec, G_OBJECT_CLASS_TYPE (aclass));
|
||||
}
|
||||
|
||||
GParamSpec*
|
||||
gtk_cell_area_class_find_cell_property (GtkCellAreaClass *aclass,
|
||||
const gchar *property_name)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_CELL_AREA_CLASS (aclass), NULL);
|
||||
g_return_val_if_fail (property_name != NULL, NULL);
|
||||
|
||||
return g_param_spec_pool_lookup (cell_property_pool,
|
||||
property_name,
|
||||
G_OBJECT_CLASS_TYPE (aclass),
|
||||
TRUE);
|
||||
}
|
||||
|
||||
GParamSpec**
|
||||
gtk_cell_area_class_list_cell_properties (GtkCellAreaClass *aclass,
|
||||
guint *n_properties)
|
||||
{
|
||||
GParamSpec **pspecs;
|
||||
guint n;
|
||||
|
||||
g_return_val_if_fail (GTK_IS_CELL_AREA_CLASS (aclass), NULL);
|
||||
|
||||
pspecs = g_param_spec_pool_list (cell_property_pool,
|
||||
G_OBJECT_CLASS_TYPE (aclass),
|
||||
&n);
|
||||
if (n_properties)
|
||||
*n_properties = n;
|
||||
|
||||
return pspecs;
|
||||
}
|
||||
|
||||
void
|
||||
gtk_cell_area_add_with_properties (GtkCellArea *area,
|
||||
GtkCellRenderer *renderer,
|
||||
const gchar *first_prop_name,
|
||||
...)
|
||||
{
|
||||
GtkCellAreaClass *class;
|
||||
|
||||
g_return_if_fail (GTK_IS_CELL_AREA (area));
|
||||
g_return_if_fail (GTK_IS_CELL_RENDERER (renderer));
|
||||
|
||||
class = GTK_CELL_AREA_GET_CLASS (area);
|
||||
|
||||
if (class->add)
|
||||
{
|
||||
va_list var_args;
|
||||
|
||||
class->add (area, renderer);
|
||||
|
||||
va_start (var_args, first_prop_name);
|
||||
gtk_cell_area_cell_set_valist (area, renderer, first_prop_name, var_args);
|
||||
va_end (var_args);
|
||||
}
|
||||
else
|
||||
g_warning ("GtkCellAreaClass::add not implemented for `%s'",
|
||||
g_type_name (G_TYPE_FROM_INSTANCE (area)));
|
||||
}
|
||||
|
||||
void
|
||||
gtk_cell_area_cell_set (GtkCellArea *area,
|
||||
GtkCellRenderer *renderer,
|
||||
const gchar *first_prop_name,
|
||||
...)
|
||||
{
|
||||
va_list var_args;
|
||||
|
||||
g_return_if_fail (GTK_IS_CELL_AREA (area));
|
||||
g_return_if_fail (GTK_IS_CELL_RENDERER (renderer));
|
||||
|
||||
va_start (var_args, first_prop_name);
|
||||
gtk_cell_area_cell_set_valist (area, renderer, first_prop_name, var_args);
|
||||
va_end (var_args);
|
||||
}
|
||||
|
||||
void
|
||||
gtk_cell_area_cell_get (GtkCellArea *area,
|
||||
GtkCellRenderer *renderer,
|
||||
const gchar *first_prop_name,
|
||||
...)
|
||||
{
|
||||
va_list var_args;
|
||||
|
||||
g_return_if_fail (GTK_IS_CELL_AREA (area));
|
||||
g_return_if_fail (GTK_IS_CELL_RENDERER (renderer));
|
||||
|
||||
va_start (var_args, first_prop_name);
|
||||
gtk_cell_area_cell_get_valist (area, renderer, first_prop_name, var_args);
|
||||
va_end (var_args);
|
||||
}
|
||||
|
||||
static inline void
|
||||
area_get_cell_property (GtkCellArea *area,
|
||||
GtkCellRenderer *renderer,
|
||||
GParamSpec *pspec,
|
||||
GValue *value)
|
||||
{
|
||||
GtkCellAreaClass *class = g_type_class_peek (pspec->owner_type);
|
||||
|
||||
class->get_cell_property (area, renderer, PARAM_SPEC_PARAM_ID (pspec), value, pspec);
|
||||
}
|
||||
|
||||
static inline void
|
||||
area_set_cell_property (GtkCellArea *area,
|
||||
GtkCellRenderer *renderer,
|
||||
GParamSpec *pspec,
|
||||
const GValue *value)
|
||||
{
|
||||
GValue tmp_value = { 0, };
|
||||
GtkCellAreaClass *class = g_type_class_peek (pspec->owner_type);
|
||||
|
||||
/* provide a copy to work from, convert (if necessary) and validate */
|
||||
g_value_init (&tmp_value, G_PARAM_SPEC_VALUE_TYPE (pspec));
|
||||
if (!g_value_transform (value, &tmp_value))
|
||||
g_warning ("unable to set cell property `%s' of type `%s' from value of type `%s'",
|
||||
pspec->name,
|
||||
g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec)),
|
||||
G_VALUE_TYPE_NAME (value));
|
||||
else if (g_param_value_validate (pspec, &tmp_value) && !(pspec->flags & G_PARAM_LAX_VALIDATION))
|
||||
{
|
||||
gchar *contents = g_strdup_value_contents (value);
|
||||
|
||||
g_warning ("value \"%s\" of type `%s' is invalid for property `%s' of type `%s'",
|
||||
contents,
|
||||
G_VALUE_TYPE_NAME (value),
|
||||
pspec->name,
|
||||
g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec)));
|
||||
g_free (contents);
|
||||
}
|
||||
else
|
||||
{
|
||||
class->set_cell_property (area, renderer, PARAM_SPEC_PARAM_ID (pspec), &tmp_value, pspec);
|
||||
}
|
||||
g_value_unset (&tmp_value);
|
||||
}
|
||||
|
||||
void
|
||||
gtk_cell_area_cell_set_valist (GtkCellArea *area,
|
||||
GtkCellRenderer *renderer,
|
||||
const gchar *first_property_name,
|
||||
va_list var_args)
|
||||
{
|
||||
const gchar *name;
|
||||
|
||||
g_return_if_fail (GTK_IS_CELL_AREA (area));
|
||||
g_return_if_fail (GTK_IS_CELL_RENDERER (renderer));
|
||||
|
||||
name = first_property_name;
|
||||
while (name)
|
||||
{
|
||||
GValue value = { 0, };
|
||||
gchar *error = NULL;
|
||||
GParamSpec *pspec =
|
||||
g_param_spec_pool_lookup (cell_property_pool, name,
|
||||
G_OBJECT_TYPE (area), TRUE);
|
||||
if (!pspec)
|
||||
{
|
||||
g_warning ("%s: cell area class `%s' has no cell property named `%s'",
|
||||
G_STRLOC, G_OBJECT_TYPE_NAME (area), name);
|
||||
break;
|
||||
}
|
||||
if (!(pspec->flags & G_PARAM_WRITABLE))
|
||||
{
|
||||
g_warning ("%s: cell property `%s' of cell area class `%s' is not writable",
|
||||
G_STRLOC, pspec->name, G_OBJECT_TYPE_NAME (area));
|
||||
break;
|
||||
}
|
||||
|
||||
g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (pspec));
|
||||
G_VALUE_COLLECT (&value, var_args, 0, &error);
|
||||
if (error)
|
||||
{
|
||||
g_warning ("%s: %s", G_STRLOC, error);
|
||||
g_free (error);
|
||||
|
||||
/* we purposely leak the value here, it might not be
|
||||
* in a sane state if an error condition occoured
|
||||
*/
|
||||
break;
|
||||
}
|
||||
area_set_cell_property (area, renderer, pspec, &value);
|
||||
g_value_unset (&value);
|
||||
name = va_arg (var_args, gchar*);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
gtk_cell_area_cell_get_valist (GtkCellArea *area,
|
||||
GtkCellRenderer *renderer,
|
||||
const gchar *first_property_name,
|
||||
va_list var_args)
|
||||
{
|
||||
const gchar *name;
|
||||
|
||||
g_return_if_fail (GTK_IS_CELL_AREA (area));
|
||||
g_return_if_fail (GTK_IS_CELL_RENDERER (renderer));
|
||||
|
||||
name = first_property_name;
|
||||
while (name)
|
||||
{
|
||||
GValue value = { 0, };
|
||||
GParamSpec *pspec;
|
||||
gchar *error;
|
||||
|
||||
pspec = g_param_spec_pool_lookup (cell_property_pool, name,
|
||||
G_OBJECT_TYPE (area), TRUE);
|
||||
if (!pspec)
|
||||
{
|
||||
g_warning ("%s: cell area class `%s' has no cell property named `%s'",
|
||||
G_STRLOC, G_OBJECT_TYPE_NAME (area), name);
|
||||
break;
|
||||
}
|
||||
if (!(pspec->flags & G_PARAM_READABLE))
|
||||
{
|
||||
g_warning ("%s: cell property `%s' of cell area class `%s' is not readable",
|
||||
G_STRLOC, pspec->name, G_OBJECT_TYPE_NAME (area));
|
||||
break;
|
||||
}
|
||||
|
||||
g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (pspec));
|
||||
area_get_cell_property (area, renderer, pspec, &value);
|
||||
G_VALUE_LCOPY (&value, var_args, 0, &error);
|
||||
if (error)
|
||||
{
|
||||
g_warning ("%s: %s", G_STRLOC, error);
|
||||
g_free (error);
|
||||
g_value_unset (&value);
|
||||
break;
|
||||
}
|
||||
g_value_unset (&value);
|
||||
name = va_arg (var_args, gchar*);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
gtk_cell_area_cell_set_property (GtkCellArea *area,
|
||||
GtkCellRenderer *renderer,
|
||||
const gchar *property_name,
|
||||
const GValue *value)
|
||||
{
|
||||
GParamSpec *pspec;
|
||||
|
||||
g_return_if_fail (GTK_IS_CELL_AREA (area));
|
||||
g_return_if_fail (GTK_IS_CELL_RENDERER (renderer));
|
||||
g_return_if_fail (property_name != NULL);
|
||||
g_return_if_fail (G_IS_VALUE (value));
|
||||
|
||||
pspec = g_param_spec_pool_lookup (cell_property_pool, property_name,
|
||||
G_OBJECT_TYPE (area), TRUE);
|
||||
if (!pspec)
|
||||
g_warning ("%s: cell area class `%s' has no cell property named `%s'",
|
||||
G_STRLOC, G_OBJECT_TYPE_NAME (area), property_name);
|
||||
else if (!(pspec->flags & G_PARAM_WRITABLE))
|
||||
g_warning ("%s: cell property `%s' of cell area class `%s' is not writable",
|
||||
G_STRLOC, pspec->name, G_OBJECT_TYPE_NAME (area));
|
||||
else
|
||||
{
|
||||
area_set_cell_property (area, renderer, pspec, value);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
gtk_cell_area_cell_get_property (GtkCellArea *area,
|
||||
GtkCellRenderer *renderer,
|
||||
const gchar *property_name,
|
||||
GValue *value)
|
||||
{
|
||||
GParamSpec *pspec;
|
||||
|
||||
g_return_if_fail (GTK_IS_CELL_AREA (area));
|
||||
g_return_if_fail (GTK_IS_CELL_RENDERER (renderer));
|
||||
g_return_if_fail (property_name != NULL);
|
||||
g_return_if_fail (G_IS_VALUE (value));
|
||||
|
||||
pspec = g_param_spec_pool_lookup (cell_property_pool, property_name,
|
||||
G_OBJECT_TYPE (area), TRUE);
|
||||
if (!pspec)
|
||||
g_warning ("%s: cell area class `%s' has no cell property named `%s'",
|
||||
G_STRLOC, G_OBJECT_TYPE_NAME (area), property_name);
|
||||
else if (!(pspec->flags & G_PARAM_READABLE))
|
||||
g_warning ("%s: cell property `%s' of cell area class `%s' is not readable",
|
||||
G_STRLOC, pspec->name, G_OBJECT_TYPE_NAME (area));
|
||||
else
|
||||
{
|
||||
GValue *prop_value, tmp_value = { 0, };
|
||||
|
||||
/* auto-conversion of the callers value type
|
||||
*/
|
||||
if (G_VALUE_TYPE (value) == G_PARAM_SPEC_VALUE_TYPE (pspec))
|
||||
{
|
||||
g_value_reset (value);
|
||||
prop_value = value;
|
||||
}
|
||||
else if (!g_value_type_transformable (G_PARAM_SPEC_VALUE_TYPE (pspec), G_VALUE_TYPE (value)))
|
||||
{
|
||||
g_warning ("can't retrieve cell property `%s' of type `%s' as value of type `%s'",
|
||||
pspec->name,
|
||||
g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec)),
|
||||
G_VALUE_TYPE_NAME (value));
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
g_value_init (&tmp_value, G_PARAM_SPEC_VALUE_TYPE (pspec));
|
||||
prop_value = &tmp_value;
|
||||
}
|
||||
|
||||
area_get_cell_property (area, renderer, pspec, prop_value);
|
||||
|
||||
if (prop_value != value)
|
||||
{
|
||||
g_value_transform (prop_value, value);
|
||||
g_value_unset (&tmp_value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -116,6 +116,17 @@ struct _GtkCellAreaClass
|
||||
gint *minimum_width,
|
||||
gint *natural_width);
|
||||
|
||||
/* Cell Properties */
|
||||
void (* set_cell_property) (GtkCellArea *area,
|
||||
GtkCellRenderer *renderer,
|
||||
guint property_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec);
|
||||
void (* get_cell_property) (GtkCellArea *area,
|
||||
GtkCellRenderer *renderer,
|
||||
guint property_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec);
|
||||
|
||||
/* Padding for future expansion */
|
||||
void (*_gtk_reserved1) (void);
|
||||
@ -175,8 +186,7 @@ void gtk_cell_area_get_preferred_width_for_height (GtkCellArea
|
||||
gint *minimum_width,
|
||||
gint *natural_width);
|
||||
|
||||
|
||||
/* Following apis are not class virtual methods */
|
||||
/* Attributes */
|
||||
void gtk_cell_area_apply_attributes (GtkCellArea *area,
|
||||
GtkTreeModel *tree_model,
|
||||
GtkTreeIter *iter);
|
||||
@ -188,6 +198,43 @@ void gtk_cell_area_attribute_disconnect (GtkCellArea
|
||||
GtkCellRenderer *renderer,
|
||||
const gchar *attribute);
|
||||
|
||||
/* Cell Properties */
|
||||
void gtk_cell_area_class_install_cell_property (GtkCellAreaClass *aclass,
|
||||
guint property_id,
|
||||
GParamSpec *pspec);
|
||||
GParamSpec* gtk_cell_area_class_find_cell_property (GtkCellAreaClass *aclass,
|
||||
const gchar *property_name);
|
||||
GParamSpec** gtk_cell_area_class_list_cell_properties (GtkCellAreaClass *aclass,
|
||||
guint *n_properties);
|
||||
void gtk_cell_area_add_with_properties (GtkCellArea *area,
|
||||
GtkCellRenderer *renderer,
|
||||
const gchar *first_prop_name,
|
||||
...) G_GNUC_NULL_TERMINATED;
|
||||
void gtk_cell_area_cell_set (GtkCellArea *area,
|
||||
GtkCellRenderer *renderer,
|
||||
const gchar *first_prop_name,
|
||||
...) G_GNUC_NULL_TERMINATED;
|
||||
void gtk_cell_area_cell_get (GtkCellArea *area,
|
||||
GtkCellRenderer *renderer,
|
||||
const gchar *first_prop_name,
|
||||
...) G_GNUC_NULL_TERMINATED;
|
||||
void gtk_cell_area_cell_set_valist (GtkCellArea *area,
|
||||
GtkCellRenderer *renderer,
|
||||
const gchar *first_property_name,
|
||||
va_list var_args);
|
||||
void gtk_cell_area_cell_get_valist (GtkCellArea *area,
|
||||
GtkCellRenderer *renderer,
|
||||
const gchar *first_property_name,
|
||||
va_list var_args);
|
||||
void gtk_cell_area_cell_set_property (GtkCellArea *area,
|
||||
GtkCellRenderer *renderer,
|
||||
const gchar *property_name,
|
||||
const GValue *value);
|
||||
void gtk_cell_area_cell_get_property (GtkCellArea *area,
|
||||
GtkCellRenderer *renderer,
|
||||
const gchar *property_name,
|
||||
GValue *value);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user