mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-07-21 09:27:51 +02:00
property: Add macros for defining properties
Alongside the macros for defining accessors we may want to use simple macros for defining properties to install on a GObject class. https://bugzilla.gnome.org/show_bug.cgi?id=648526
This commit is contained in:
@@ -431,7 +431,259 @@ void g_property_set_installed (GProperty *property,
|
||||
void g_property_init_default (GProperty *property,
|
||||
gpointer object);
|
||||
|
||||
/* property generation */
|
||||
|
||||
/**
|
||||
* G_PROPERTY_DESCRIBE:
|
||||
* @p_nick: a human readable, translatable name for the property
|
||||
* @p_blurb: a human readable, translatable description for the property
|
||||
*
|
||||
* Sets the property nick and blurb using two static strings.
|
||||
*
|
||||
* This macro can only be called inside %G_DEFINE_PROPERTY_EXTENDED.
|
||||
*
|
||||
* Since: 2.38
|
||||
*/
|
||||
#define G_PROPERTY_DESCRIBE(p_nick, p_blurb) \
|
||||
{ \
|
||||
GParamSpec *__g_param_spec = (GParamSpec *) g_property; \
|
||||
g_param_spec_set_static_nick (__g_param_spec, p_nick); \
|
||||
g_param_spec_set_static_blurb (__g_param_spec, p_blurb); \
|
||||
}
|
||||
|
||||
/**
|
||||
* G_PROPERTY_DEFAULT:
|
||||
* @p_val: the default value of the property
|
||||
*
|
||||
* Sets the default value for the property.
|
||||
*
|
||||
* This macro can only be called inside %G_DEFINE_PROPERTY_EXTENDED.
|
||||
*
|
||||
* Since: 2.38
|
||||
*/
|
||||
#define G_PROPERTY_DEFAULT(p_val) \
|
||||
g_property_set_default (g_property, p_val);
|
||||
|
||||
/**
|
||||
* G_PROPERTY_RANGE:
|
||||
* @p_min: the minimum value of the valid range for the property
|
||||
* @p_max: the maximum value of the valid range for the property
|
||||
*
|
||||
* Sets the range of valid values for the property.
|
||||
*
|
||||
* This macro can only be called inside %G_DEFINE_PROPERTY_EXTENDED.
|
||||
*
|
||||
* Since: 2.38
|
||||
*/
|
||||
#define G_PROPERTY_RANGE(p_min, p_max) \
|
||||
g_property_set_range (g_property, p_min, p_max);
|
||||
|
||||
/**
|
||||
* G_PROPERTY_PREREQUISITE:
|
||||
* @type: the prerequisite type for the property
|
||||
*
|
||||
* Sets the prerequisite type for enumeration, flags, boxed,
|
||||
* and object properties.
|
||||
*
|
||||
* This macro can only be called inside %G_DEFINE_PROPERTY_EXTENDED.
|
||||
*
|
||||
* Since: 2.38
|
||||
*/
|
||||
#define G_PROPERTY_PREREQUISITE(type) \
|
||||
g_property_set_prerequisite (g_property, type);
|
||||
|
||||
#define _G_DEFINE_PROPERTIES_BEGIN() \
|
||||
{ \
|
||||
GPtrArray *g_define_properties = g_ptr_array_new (); \
|
||||
g_ptr_array_add (g_define_properties, NULL);
|
||||
|
||||
#define _G_DEFINE_PROPERTIES_END(T_N, t_n, g_class) \
|
||||
t_n##_properties_len = g_define_properties->len; \
|
||||
t_n##_properties = (GParamSpec **) g_ptr_array_free (g_define_properties, FALSE); \
|
||||
g_object_class_install_properties (G_OBJECT_CLASS (g_class), \
|
||||
t_n##_properties_len, \
|
||||
t_n##_properties); \
|
||||
}
|
||||
|
||||
/**
|
||||
* G_DEFINE_PROPERTIES:
|
||||
* @T_N: the name of the type, in CamelCase
|
||||
* @t_n: the name of the type, in lower case, with spaces replaced by underscores
|
||||
* @g_class: a pointer to the class structure of the type
|
||||
* @_C_: a list of G_DEFINE_PROPERTY_EXTENDED calls
|
||||
*
|
||||
* Defines a list of properties and installs them on the class.
|
||||
*
|
||||
* Note that this macro can only be used with types defined using
|
||||
* G_DEFINE_TYPE_* macros, as it depends on variables defined by
|
||||
* those macros.
|
||||
*
|
||||
* Since: 2.38
|
||||
*/
|
||||
#define G_DEFINE_PROPERTIES(T_N, t_n, g_class, _C_) \
|
||||
_G_DEFINE_PROPERTIES_BEGIN() \
|
||||
{ _C_; } \
|
||||
_G_DEFINE_PROPERTIES_END(T_N, t_n, g_class)
|
||||
|
||||
#define _G_DEFINE_DIRECT_PROPERTY_EXTENDED_BEGIN(T_N, c_type, name, flags) \
|
||||
{ \
|
||||
GProperty *g_property = (GProperty *) \
|
||||
g_##c_type##_property_new (#name, flags, \
|
||||
G_STRUCT_OFFSET (T_N##Private, name), \
|
||||
NULL, \
|
||||
NULL);
|
||||
#define _G_DEFINE_PROPERTY_EXTENDED_BEGIN(T_N, c_type, name, offset, setterFunc, getterFunc, flags) \
|
||||
{ \
|
||||
GProperty *g_property = (GProperty *) \
|
||||
g_##c_type##_property_new (#name, flags, \
|
||||
offset, \
|
||||
setterFunc, \
|
||||
getterFunc);
|
||||
#define _G_DEFINE_PROPERTY_EXTENDED_END \
|
||||
g_ptr_array_add (g_define_properties, g_property); \
|
||||
}
|
||||
|
||||
/**
|
||||
* G_DEFINE_PROPERTY_EXTENDED:
|
||||
* @T_N: the name of the type, in CamelCase
|
||||
* @c_type: the C type of the property, in lower case, minus the "g" if the type
|
||||
* is defined by GLib; for instance "int" for "gint", "uint8" for "guint8",
|
||||
* "boolean" for "gboolean"; strings stored in a gchar* are defined as "string"
|
||||
* @name: the name of the property, in lower case, with '-' replaced by '_'
|
||||
* @offset: the offset of the field in the structure that stores the property, or 0
|
||||
* @setterFunc: the explicit setter function, or %NULL for direct access
|
||||
* @getterFunc: the explicit getter function, or %NULL for direct access
|
||||
* @flags: #GPropertyFlags for the property
|
||||
* @_C_: custom code to be called after the property has been defined; the
|
||||
* GProperty instance is available under the "g_property" variable
|
||||
*
|
||||
* The most generic property definition macro.
|
||||
*
|
||||
* |[
|
||||
* G_DEFINE_PROPERTY_EXTENDED (GtkGadget,
|
||||
* int,
|
||||
* width,
|
||||
* G_STRUCT_OFFSET (GtkGadgetPrivate, width),
|
||||
* NULL, NULL,
|
||||
* G_PROPERTY_READWRITE,
|
||||
* G_PROPERTY_RANGE (0, G_MAXINT))
|
||||
* ]|
|
||||
* expands to
|
||||
* |[
|
||||
* {
|
||||
* GProperty *g_property =
|
||||
* g_int_property_new ("width", G_PROPERTY_READWRITE,
|
||||
* G_STRUCT_OFFSET (GtkGadgetPrivate, width),
|
||||
* NULL, NULL);
|
||||
* g_property_set_range (g_property, 0, G_MAXINT);
|
||||
* gtk_gadget_properties[PROP_GtkGadget_width] = g_property;
|
||||
* }
|
||||
* ]|
|
||||
*
|
||||
* This macro should only be used with G_DEFINE_PROPERTIES() as it depends
|
||||
* on variables and functions defined by that macro.
|
||||
*
|
||||
* Since: 2.38
|
||||
*/
|
||||
#define G_DEFINE_PROPERTY_EXTENDED(T_N, c_type, name, offset, setterFunc, getterFunc, flags, _C_) \
|
||||
_G_DEFINE_PROPERTY_EXTENDED_BEGIN (T_N, c_type, name, offset, setterFunc, getterFunc, flags) \
|
||||
{ _C_; } \
|
||||
_G_DEFINE_PROPERTY_EXTENDED_END
|
||||
|
||||
/**
|
||||
* G_DEFINE_PROPERTY_WITH_CODE:
|
||||
* @T_N: the name of the type, in CamelCase
|
||||
* @c_type: the C type of the property, in lower case, minus the "g" if the type
|
||||
* is defined by GLib; for instance "int" for "gint", "uint8" for "guint8",
|
||||
* "boolean" for "gboolean"; strings stored in a gchar* are defined as "string"
|
||||
* @name: the name of the property, in lower case, with '-' replaced by '_'; the
|
||||
* name of the property must exist as a member of the per-instance private data
|
||||
* structure of the type name
|
||||
* @flags: #GPropertyFlags for the property
|
||||
* @_C_: custom code to be called after the property has been defined; the
|
||||
* GProperty instance is available under the "g_property" variable
|
||||
*
|
||||
* A variant of G_DEFINE_PROPERTY_EXTENDED() that only allows properties
|
||||
* with direct access, stored on the per-instance private data structure
|
||||
* for the given type.
|
||||
*
|
||||
* Since: 2.38
|
||||
*/
|
||||
#define G_DEFINE_PROPERTY_WITH_CODE(T_N, c_type, name, flags, _C_) \
|
||||
_G_DEFINE_DIRECT_PROPERTY_EXTENDED_BEGIN (T_N, c_type, name, flags) \
|
||||
{ _C_; } \
|
||||
_G_DEFINE_PROPERTY_EXTENDED_END
|
||||
|
||||
/**
|
||||
* G_DEFINE_PROPERTY_WITH_DEFAULT:
|
||||
* @T_N: the name of the type, in CamelCase
|
||||
* @c_type: the C type of the property, in lower case, minus the "g" if the type
|
||||
* is defined by GLib; for instance "int" for "gint", "uint8" for "guint8",
|
||||
* "boolean" for "gboolean"; strings stored in a gchar* are defined as "string"
|
||||
* @name: the name of the property, in lower case, with '-' replaced by '_'; the
|
||||
* name of the property must exist as a member of the per-instance private data
|
||||
* structure of the type name
|
||||
* @flags: #GPropertyFlags for the property
|
||||
* @defVal: the default value of the property
|
||||
*
|
||||
* A convenience macro for defining a direct access property with a default
|
||||
* value.
|
||||
*
|
||||
* See G_DEFINE_PROPERTY_WITH_CODE() and G_PROPERTY_DEFAULT().
|
||||
*
|
||||
* Since: 2.38
|
||||
*/
|
||||
#define G_DEFINE_PROPERTY_WITH_DEFAULT(T_N, c_type, name, flags, defVal) \
|
||||
_G_DEFINE_DIRECT_PROPERTY_EXTENDED_BEGIN (T_N, c_type, name, flags) \
|
||||
G_PROPERTY_DEFAULT (defVal) \
|
||||
_G_DEFINE_PROPERTY_EXTENDED_END
|
||||
|
||||
/**
|
||||
* G_DEFINE_PROPERTY_WITH_RANGE:
|
||||
* @T_N: the name of the type, in CamelCase
|
||||
* @c_type: the C type of the property, in lower case, minus the "g" if the type
|
||||
* is defined by GLib; for instance "int" for "gint", "uint8" for "guint8",
|
||||
* "boolean" for "gboolean"; strings stored in a gchar* are defined as "string"
|
||||
* @name: the name of the property, in lower case, with '-' replaced by '_'; the
|
||||
* name of the property must exist as a member of the per-instance private data
|
||||
* structure of the type name
|
||||
* @flags: #GPropertyFlags for the property
|
||||
* @minVal: the minimum value of the property
|
||||
* @maxVal: the maximum value of the property
|
||||
*
|
||||
* A convenience macro for defining a direct access property with a range
|
||||
* of valid values.
|
||||
*
|
||||
* See G_DEFINE_PROPERTY_WITH_CODE() and G_PROPERTY_RANGE().
|
||||
*
|
||||
* Since: 2.38
|
||||
*/
|
||||
#define G_DEFINE_PROPERTY_WITH_RANGE(T_N, c_type, name, flags, minVal, maxVal) \
|
||||
_G_DEFINE_DIRECT_PROPERTY_EXTENDED_BEGIN (T_N, c_type, name, flags) \
|
||||
G_PROPERTY_RANGE (minVal, maxVal) \
|
||||
_G_DEFINE_PROPERTY_EXTENDED_END
|
||||
|
||||
/**
|
||||
* G_DEFINE_PROPERTY:
|
||||
* @T_N: the name of the type, in CamelCase
|
||||
* @c_type: the C type of the property, in lower case, minus the "g" if the type
|
||||
* is defined by GLib; for instance "int" for "gint", "uint8" for "guint8",
|
||||
* "boolean" for "gboolean"; strings stored in a gchar* are defined as "string"
|
||||
* @name: the name of the property, in lower case, with '-' replaced by '_'; the
|
||||
* name of the property must exist as a member of the per-instance private data
|
||||
* structure of the type name
|
||||
* @flags: #GPropertyFlags for the property
|
||||
*
|
||||
* A convenience macro for defining a direct access property.
|
||||
*
|
||||
* See G_DEFINE_PROPERTY_WITH_CODE() and G_DEFINE_PROPERTY_EXTENDED() if
|
||||
* you need more flexibility.
|
||||
*
|
||||
* Since: 2.38
|
||||
*/
|
||||
#define G_DEFINE_PROPERTY(T_N, c_type, name, flags) \
|
||||
_G_DEFINE_DIRECT_PROPERTY_EXTENDED_BEGIN (T_N, c_type, name, flags) \
|
||||
_G_DEFINE_PROPERTY_EXTENDED_END
|
||||
|
||||
/* accessors generation */
|
||||
#define _G_DECLARE_PROPERTY_GETTER(T_n, t_n, f_t, f_n) f_t t_n##_get_##f_n (T_n *self)
|
||||
@@ -456,9 +708,19 @@ void g_property_init_default (GProperty *property,
|
||||
g_return_val_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (self, t_n##_get_type ()), (f_t) 0); \
|
||||
\
|
||||
{ \
|
||||
GObjectClass *_self_class; \
|
||||
_self_class = G_OBJECT_GET_CLASS (self); \
|
||||
g_property = (GProperty *) g_object_class_find_property (_self_class, #f_n); \
|
||||
const char *pname = g_property_canonicalize_name (#f_n); \
|
||||
int i; \
|
||||
\
|
||||
for (i = 1; i < t_n##_properties_len; i++) \
|
||||
{ \
|
||||
GParamSpec *pspec = t_n##_properties[i]; \
|
||||
if (pspec != NULL && pspec->name == pname) \
|
||||
{ \
|
||||
g_property = (GProperty *) pspec; \
|
||||
break; \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
if (G_UNLIKELY (g_property == NULL)) \
|
||||
{ \
|
||||
g_critical (G_STRLOC ": No property " #f_n " found for class %s", \
|
||||
@@ -466,18 +728,6 @@ void g_property_init_default (GProperty *property,
|
||||
return (f_t) 0; \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
if (!G_IS_PROPERTY (g_property)) \
|
||||
{ \
|
||||
g_critical (G_STRLOC ": Property " #f_n " is not a GProperty"); \
|
||||
return (f_t) 0; \
|
||||
} \
|
||||
\
|
||||
if (!g_property_is_readable (g_property)) \
|
||||
{ \
|
||||
g_critical (G_STRLOC ": The property " #f_n " is not readable"); \
|
||||
return (f_t) 0; \
|
||||
} \
|
||||
\
|
||||
if (!g_property_get (g_property, self, &retval)) \
|
||||
{ \
|
||||
@@ -501,27 +751,25 @@ void g_property_init_default (GProperty *property,
|
||||
g_return_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (self, t_n##_get_type ())); \
|
||||
\
|
||||
{ \
|
||||
GObjectClass *_self_class; \
|
||||
_self_class = G_OBJECT_GET_CLASS (self); \
|
||||
g_property = (GProperty *) g_object_class_find_property (_self_class, #f_n); \
|
||||
const char *pname = g_property_canonicalize_name (#f_n); \
|
||||
int i; \
|
||||
\
|
||||
for (i = 1; i < t_n##_properties_len; i++) \
|
||||
{ \
|
||||
GParamSpec *pspec = t_n##_properties[i]; \
|
||||
if (pspec != NULL && pspec->name == pname) \
|
||||
{ \
|
||||
g_property = (GProperty *) pspec; \
|
||||
break; \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
if (G_UNLIKELY (g_property == NULL)) \
|
||||
{ \
|
||||
g_critical (G_STRLOC ": No property " #f_n " found for class %s", G_OBJECT_TYPE_NAME (self)); \
|
||||
return; \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
if (!G_IS_PROPERTY (g_property)) \
|
||||
{ \
|
||||
g_critical (G_STRLOC ": Property " #f_n " is not a GProperty"); \
|
||||
return; \
|
||||
} \
|
||||
\
|
||||
if (!g_property_is_writable (g_property)) \
|
||||
{ \
|
||||
g_critical (G_STRLOC ": The property " #f_n " is not writable"); \
|
||||
return; \
|
||||
} \
|
||||
\
|
||||
if (!g_property_set (g_property, self, value)) \
|
||||
return; \
|
||||
@@ -590,9 +838,8 @@ _G_DECLARE_PROPERTY_GETTER (T_n, t_n, f_t, f_n);
|
||||
* @_C_: C code that should be called after the property has been set
|
||||
*
|
||||
* Defines the setter function for a @field_name property in the
|
||||
* class @TypeName, with the possibility of calling custom code.
|
||||
*
|
||||
* This macro should only be used in C source files.
|
||||
* class @TypeName, with the possibility of calling custom code, for
|
||||
* instance:
|
||||
*
|
||||
* |[
|
||||
* G_DEFINE_PROPERTY_SET_WITH_CODE (ClutterActor, clutter_actor,
|
||||
@@ -633,10 +880,16 @@ _G_DEFINE_PROPERTY_SETTER_END
|
||||
* class @T_n, with the possibility of calling custom code.
|
||||
*
|
||||
* This macro will directly access the field on the private
|
||||
* data structure.
|
||||
* data structure, and should only be used if the property
|
||||
* has been defined to use an offset instead of an explicit
|
||||
* getter. Use G_DEFINE_PROPERTY_COMPUTED_GET_WITH_CODE() if
|
||||
* you have an internal getter function.
|
||||
*
|
||||
* This macro should only be used in C source files.
|
||||
*
|
||||
* Note that this macro should be used with types defined using G_DEFINE_TYPE_*
|
||||
* macros, as it depends on variables and functions defined by those macros.
|
||||
*
|
||||
* Since: 2.38
|
||||
*/
|
||||
#define G_DEFINE_PROPERTY_GET_WITH_CODE(T_n, t_n, f_t, f_n, _C_) \
|
||||
@@ -662,6 +915,9 @@ _G_DEFINE_PROPERTY_GETTER_END
|
||||
*
|
||||
* This macro should only be used in C source files.
|
||||
*
|
||||
* Note that this macro should be used with types defined using G_DEFINE_TYPE_*
|
||||
* macros, as it depends on variables and functions defined by those macros.
|
||||
*
|
||||
* Since: 2.38
|
||||
*/
|
||||
#define G_DEFINE_PROPERTY_INDIRECT_GET_WITH_CODE(T_n, t_n, f_t, f_n, _C_) \
|
||||
@@ -682,6 +938,9 @@ _G_DEFINE_PROPERTY_GETTER_END
|
||||
* Defines the setter function for a @field_name property in the
|
||||
* class @TypeName. This macro should only be used in C source files.
|
||||
*
|
||||
* Note that this macro should be used with types defined using G_DEFINE_TYPE_*
|
||||
* macros, as it depends on variables and functions defined by those macros.
|
||||
*
|
||||
* See also: %G_DEFINE_PROPERTY_SET_WITH_CODE
|
||||
*
|
||||
* Since: 2.38
|
||||
@@ -700,6 +959,9 @@ _G_DEFINE_PROPERTY_GETTER_END
|
||||
* Defines the getter function for a @field_name property in the
|
||||
* class @TypeName. This macro should only be used in C source files.
|
||||
*
|
||||
* Note that this macro should be used with types defined using G_DEFINE_TYPE_*
|
||||
* macros, as it depends on variables and functions defined by those macros.
|
||||
*
|
||||
* See also %G_DEFINE_PROPERTY_GET_WITH_CODE.
|
||||
*
|
||||
* Since: 2.38
|
||||
@@ -718,6 +980,9 @@ _G_DEFINE_PROPERTY_GETTER_END
|
||||
* Defines the getter function for a @field_name property in the
|
||||
* class @TypeName. This macro should only be used in C source files.
|
||||
*
|
||||
* Note that this macro should be used with types defined using G_DEFINE_TYPE_*
|
||||
* macros, as it depends on variables and functions defined by those macros.
|
||||
*
|
||||
* See also %G_DEFINE_PROPERTY_COMPUTED_GET_WITH_CODE.
|
||||
*
|
||||
* Since: 2.38
|
||||
@@ -754,17 +1019,19 @@ _G_DEFINE_PROPERTY_GETTER_END
|
||||
*
|
||||
* priv = clutter_actor_get_instance_private (self);
|
||||
*
|
||||
* if (priv->margin_top == value)
|
||||
* return;
|
||||
* if (priv->margin_top != value)
|
||||
* {
|
||||
* priv->value = value;
|
||||
*
|
||||
* priv->value = value;
|
||||
*
|
||||
* g_object_notify (G_OBJECT (self), "margin-top");
|
||||
* g_object_notify (G_OBJECT (self), "margin-top");
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* int
|
||||
* clutter_actor_get_margin_top (ClutterActor *self)
|
||||
* {
|
||||
* ClutterActorPrivate *priv;
|
||||
*
|
||||
* g_return_val_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (self, clutter_actor_get_type ()), 0);
|
||||
*
|
||||
* priv = clutter_actor_get_instance_private (self);
|
||||
@@ -782,6 +1049,10 @@ _G_DEFINE_PROPERTY_GETTER_END
|
||||
* %G_DEFINE_PROPERTY_GET_WITH_CODE and %G_DEFINE_PROPERTY_SET_WITH_CODE
|
||||
* variants.
|
||||
*
|
||||
* Note that this macro should only be used with types defined using
|
||||
* G_DEFINE_TYPE_* macros, as it depends on variable and functions defined
|
||||
* by those macros.
|
||||
*
|
||||
* Since: 2.38
|
||||
*/
|
||||
#define G_DEFINE_PROPERTY_GET_SET(T_n, t_n, f_t, f_n) \
|
||||
|
@@ -1661,10 +1661,12 @@ static void type_name##_class_intern_init (gpointer klass) \
|
||||
|
||||
#define _G_DEFINE_TYPE_EXTENDED_BEGIN(TypeName, type_name, TYPE_PARENT, flags) \
|
||||
\
|
||||
static void type_name##_init (TypeName *self); \
|
||||
static void type_name##_class_init (TypeName##Class *klass); \
|
||||
static gpointer type_name##_parent_class = NULL; \
|
||||
static gint TypeName##_private_offset; \
|
||||
static void type_name##_init (TypeName *self); \
|
||||
static void type_name##_class_init (TypeName##Class *klass); \
|
||||
static gpointer type_name##_parent_class = NULL; \
|
||||
static gint TypeName##_private_offset; \
|
||||
static GParamSpec **type_name##_properties G_GNUC_UNUSED; \
|
||||
static guint type_name##_properties_len G_GNUC_UNUSED; \
|
||||
\
|
||||
_G_DEFINE_TYPE_EXTENDED_CLASS_INIT(TypeName, type_name) \
|
||||
\
|
||||
|
@@ -5,10 +5,11 @@ typedef struct _TestObjectPrivate TestObjectPrivate;
|
||||
typedef struct _TestObjectClass TestObjectClass;
|
||||
|
||||
typedef enum {
|
||||
TEST_ENUM_UNSET,
|
||||
TEST_ENUM_ONE,
|
||||
TEST_ENUM_TWO,
|
||||
TEST_ENUM_THREE
|
||||
TEST_ENUM_THREE,
|
||||
|
||||
TEST_ENUM_UNSET = -1
|
||||
} TestEnum;
|
||||
|
||||
struct _TestObject
|
||||
@@ -27,14 +28,17 @@ struct _TestObjectPrivate
|
||||
|
||||
double double_val;
|
||||
|
||||
char *str_val;
|
||||
char *string_val;
|
||||
|
||||
gboolean bool_val;
|
||||
|
||||
TestEnum enum_val;
|
||||
guint enum_val_set : 1;
|
||||
gboolean enum_val_set;
|
||||
|
||||
guint8 with_default;
|
||||
|
||||
float width;
|
||||
float height;
|
||||
};
|
||||
|
||||
GType test_enum_get_type (void);
|
||||
@@ -64,28 +68,12 @@ test_enum_get_type (void)
|
||||
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (TestObject, test_object, G_TYPE_OBJECT)
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
|
||||
PROP_INTEGER_VAL,
|
||||
PROP_DOUBLE_VAL,
|
||||
PROP_STRING_VAL,
|
||||
PROP_BOOL_VAL,
|
||||
PROP_ENUM_VAL,
|
||||
PROP_WITH_DEFAULT,
|
||||
|
||||
LAST_PROP
|
||||
};
|
||||
|
||||
static GParamSpec *test_object_properties[LAST_PROP] = { NULL, };
|
||||
|
||||
static void
|
||||
test_object_finalize (GObject *gobject)
|
||||
{
|
||||
TestObjectPrivate *priv = test_object_get_instance_private ((TestObject *) gobject);
|
||||
|
||||
g_free (priv->str_val);
|
||||
g_free (priv->string_val);
|
||||
|
||||
if (priv->enum_val != TEST_ENUM_UNSET)
|
||||
g_assert (priv->enum_val_set);
|
||||
@@ -94,8 +82,8 @@ test_object_finalize (GObject *gobject)
|
||||
}
|
||||
|
||||
static gboolean
|
||||
test_object_set_enum_val (gpointer obj,
|
||||
gint val)
|
||||
test_object_set_enum_val_internal (gpointer obj,
|
||||
gint val)
|
||||
{
|
||||
TestObjectPrivate *priv = test_object_get_instance_private (obj);
|
||||
|
||||
@@ -126,60 +114,73 @@ test_object_class_init (TestObjectClass *klass)
|
||||
gobject_class->constructed = test_object_constructed;
|
||||
gobject_class->finalize = test_object_finalize;
|
||||
|
||||
test_object_properties[PROP_INTEGER_VAL] =
|
||||
g_int_property_new ("integer-val",
|
||||
G_PROPERTY_READWRITE,
|
||||
G_STRUCT_OFFSET (TestObjectPrivate, integer_val),
|
||||
NULL, NULL);
|
||||
|
||||
test_object_properties[PROP_DOUBLE_VAL] =
|
||||
g_double_property_new ("double-val",
|
||||
G_PROPERTY_READWRITE,
|
||||
G_STRUCT_OFFSET (TestObjectPrivate, double_val),
|
||||
NULL, NULL);
|
||||
|
||||
test_object_properties[PROP_STRING_VAL] =
|
||||
g_string_property_new ("string-val",
|
||||
G_PROPERTY_READWRITE | G_PROPERTY_COPY_SET,
|
||||
G_STRUCT_OFFSET (TestObjectPrivate, str_val),
|
||||
NULL, NULL);
|
||||
|
||||
test_object_properties[PROP_BOOL_VAL] =
|
||||
g_boolean_property_new ("bool-val",
|
||||
G_PROPERTY_READWRITE,
|
||||
G_STRUCT_OFFSET (TestObjectPrivate, bool_val),
|
||||
NULL, NULL);
|
||||
|
||||
test_object_properties[PROP_ENUM_VAL] =
|
||||
g_enum_property_new ("enum-val",
|
||||
G_PROPERTY_READWRITE,
|
||||
G_STRUCT_OFFSET (TestObjectPrivate, enum_val),
|
||||
test_object_set_enum_val,
|
||||
NULL);
|
||||
g_property_set_prerequisite ((GProperty *) test_object_properties[PROP_ENUM_VAL],
|
||||
test_enum_get_type ());
|
||||
g_property_set_default ((GProperty *) test_object_properties[PROP_ENUM_VAL],
|
||||
TEST_ENUM_UNSET);
|
||||
|
||||
test_object_properties[PROP_WITH_DEFAULT] =
|
||||
g_uint8_property_new ("with-default",
|
||||
G_PROPERTY_READWRITE,
|
||||
G_STRUCT_OFFSET (TestObjectPrivate, with_default),
|
||||
NULL,
|
||||
NULL);
|
||||
g_property_set_default ((GProperty *) test_object_properties[PROP_WITH_DEFAULT], 255);
|
||||
|
||||
g_object_class_install_properties (gobject_class, LAST_PROP, test_object_properties);
|
||||
G_DEFINE_PROPERTIES (TestObject, test_object, klass,
|
||||
G_DEFINE_PROPERTY (TestObject,
|
||||
int,
|
||||
integer_val,
|
||||
G_PROPERTY_READWRITE)
|
||||
G_DEFINE_PROPERTY (TestObject,
|
||||
double,
|
||||
double_val,
|
||||
G_PROPERTY_READWRITE)
|
||||
G_DEFINE_PROPERTY (TestObject,
|
||||
string,
|
||||
string_val,
|
||||
G_PROPERTY_READWRITE | G_PROPERTY_COPY_SET)
|
||||
G_DEFINE_PROPERTY (TestObject,
|
||||
boolean,
|
||||
bool_val,
|
||||
G_PROPERTY_READWRITE)
|
||||
G_DEFINE_PROPERTY (TestObject,
|
||||
float,
|
||||
width,
|
||||
G_PROPERTY_READWRITE)
|
||||
G_DEFINE_PROPERTY (TestObject,
|
||||
float,
|
||||
height,
|
||||
G_PROPERTY_READWRITE)
|
||||
G_DEFINE_PROPERTY_EXTENDED (TestObject,
|
||||
enum,
|
||||
enum_val,
|
||||
G_STRUCT_OFFSET (TestObjectPrivate, enum_val),
|
||||
test_object_set_enum_val_internal,
|
||||
NULL,
|
||||
G_PROPERTY_READWRITE,
|
||||
G_PROPERTY_DEFAULT (TEST_ENUM_UNSET)
|
||||
g_property_set_prerequisite (g_property, test_enum_get_type ());)
|
||||
G_DEFINE_PROPERTY (TestObject,
|
||||
boolean,
|
||||
enum_val_set,
|
||||
G_PROPERTY_READABLE);
|
||||
G_DEFINE_PROPERTY_WITH_CODE (TestObject,
|
||||
uint8,
|
||||
with_default,
|
||||
G_PROPERTY_READWRITE,
|
||||
G_PROPERTY_DEFAULT (255)
|
||||
G_PROPERTY_DESCRIBE ("With Default",
|
||||
"A property with a default value")))
|
||||
}
|
||||
|
||||
static void
|
||||
test_object_init (TestObject *self)
|
||||
{
|
||||
TestObjectPrivate *priv = test_object_get_private (self);
|
||||
|
||||
g_assert (priv->enum_val == TEST_ENUM_UNSET);
|
||||
g_assert (!priv->enum_val_set);
|
||||
}
|
||||
|
||||
G_DECLARE_PROPERTY_GET_SET (TestObject, test_object, gboolean, bool_val)
|
||||
G_DECLARE_PROPERTY_GET_SET (TestObject, test_object, float, width)
|
||||
G_DECLARE_PROPERTY_GET_SET (TestObject, test_object, float, height)
|
||||
G_DECLARE_PROPERTY_GET_SET (TestObject, test_object, TestEnum, enum_val)
|
||||
G_DECLARE_PROPERTY_GET (TestObject, test_object, gboolean, enum_val_set)
|
||||
|
||||
G_DEFINE_PROPERTY_GET_SET (TestObject, test_object, gboolean, bool_val)
|
||||
G_DEFINE_PROPERTY_GET_SET (TestObject, test_object, float, width)
|
||||
G_DEFINE_PROPERTY_GET_SET (TestObject, test_object, float, height)
|
||||
G_DEFINE_PROPERTY_GET_SET (TestObject, test_object, TestEnum, enum_val)
|
||||
G_DEFINE_PROPERTY_INDIRECT_GET (TestObject, test_object, gboolean, enum_val_set)
|
||||
|
||||
/* test units start here */
|
||||
|
||||
@@ -206,7 +207,7 @@ gproperty_construct (void)
|
||||
|
||||
g_assert_cmpint (priv->integer_val, ==, 42);
|
||||
g_assert (priv->bool_val);
|
||||
g_assert_cmpstr (priv->str_val, ==, "Hello, world");
|
||||
g_assert_cmpstr (priv->string_val, ==, "Hello, world");
|
||||
g_assert_cmpfloat ((float) priv->double_val, ==, 3.14159f);
|
||||
|
||||
g_object_unref (obj);
|
||||
@@ -223,14 +224,14 @@ gproperty_object_set (void)
|
||||
g_signal_connect (obj, "notify::string-val", G_CALLBACK (check_notify_emission), &did_emit_notify);
|
||||
|
||||
g_object_set (obj, "string-val", "Hello!", NULL);
|
||||
g_assert_cmpstr (priv->str_val, ==, "Hello!");
|
||||
g_assert_cmpstr (priv->string_val, ==, "Hello!");
|
||||
|
||||
g_assert (did_emit_notify);
|
||||
|
||||
did_emit_notify = FALSE;
|
||||
|
||||
g_object_set (obj, "string-val", "Hello!", NULL);
|
||||
g_assert_cmpstr (priv->str_val, ==, "Hello!");
|
||||
g_assert_cmpstr (priv->string_val, ==, "Hello!");
|
||||
|
||||
g_assert (!did_emit_notify);
|
||||
|
||||
@@ -264,23 +265,18 @@ gproperty_explicit_set (void)
|
||||
gboolean did_emit_notify = FALSE;
|
||||
TestEnum enum_val;
|
||||
|
||||
TestObjectPrivate *priv =
|
||||
g_type_instance_get_private ((GTypeInstance *) obj, test_object_get_type ());
|
||||
|
||||
g_signal_connect (obj, "notify::enum-val", G_CALLBACK (check_notify_emission), &did_emit_notify);
|
||||
|
||||
g_object_set (obj, "enum-val", TEST_ENUM_THREE, NULL);
|
||||
g_assert_cmpint (priv->enum_val, ==, TEST_ENUM_THREE);
|
||||
g_assert (priv->enum_val_set);
|
||||
|
||||
g_assert_cmpint (test_object_get_enum_val (obj), ==, TEST_ENUM_THREE);
|
||||
g_assert (test_object_get_enum_val_set (obj));
|
||||
g_assert (did_emit_notify);
|
||||
|
||||
did_emit_notify = FALSE;
|
||||
g_object_set (obj, "enum-val", TEST_ENUM_THREE, NULL);
|
||||
g_assert (!did_emit_notify);
|
||||
|
||||
test_object_set_enum_val (obj, TEST_ENUM_THREE);
|
||||
g_object_get (obj, "enum-val", &enum_val, NULL);
|
||||
g_assert_cmpint (enum_val, ==, TEST_ENUM_THREE);
|
||||
g_assert (!did_emit_notify);
|
||||
|
||||
g_object_unref (obj);
|
||||
}
|
||||
|
Reference in New Issue
Block a user