mirror of
https://gitlab.gnome.org/GNOME/gimp
synced 2024-10-19 22:34:37 +00:00
libgimpbase: add GimpParamSpecValueArray for the same reason
This commit is contained in:
parent
f1a06eafea
commit
ffe74bbb02
|
@ -57,7 +57,9 @@ EXPORTS
|
|||
gimp_param_spec_memsize
|
||||
gimp_param_spec_parasite
|
||||
gimp_param_spec_unit
|
||||
gimp_param_spec_value_array
|
||||
gimp_param_unit_get_type
|
||||
gimp_param_value_array_get_type
|
||||
gimp_parasite_compare
|
||||
gimp_parasite_copy
|
||||
gimp_parasite_data
|
||||
|
|
|
@ -340,3 +340,252 @@ gimp_value_array_truncate (GimpValueArray *value_array,
|
|||
for (i = value_array->n_values; i > n_values; i--)
|
||||
gimp_value_array_remove (value_array, i - 1);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* GIMP_TYPE_PARAM_VALUE_ARRAY
|
||||
*/
|
||||
|
||||
static void gimp_param_value_array_class_init (GParamSpecClass *klass);
|
||||
static void gimp_param_value_array_init (GParamSpec *pspec);
|
||||
static void gimp_param_value_array_finalize (GParamSpec *pspec);
|
||||
static void gimp_param_value_array_set_default (GParamSpec *pspec,
|
||||
GValue *value);
|
||||
static gboolean gimp_param_value_array_validate (GParamSpec *pspec,
|
||||
GValue *value);
|
||||
static gint gimp_param_value_array_values_cmp (GParamSpec *pspec,
|
||||
const GValue *value1,
|
||||
const GValue *value2);
|
||||
|
||||
GType
|
||||
gimp_param_value_array_get_type (void)
|
||||
{
|
||||
static GType type = 0;
|
||||
|
||||
if (! type)
|
||||
{
|
||||
const GTypeInfo info =
|
||||
{
|
||||
sizeof (GParamSpecClass),
|
||||
NULL, NULL,
|
||||
(GClassInitFunc) gimp_param_value_array_class_init,
|
||||
NULL, NULL,
|
||||
sizeof (GimpParamSpecValueArray),
|
||||
0,
|
||||
(GInstanceInitFunc) gimp_param_value_array_init
|
||||
};
|
||||
|
||||
type = g_type_register_static (G_TYPE_PARAM_BOXED,
|
||||
"GimpParamValueArray", &info, 0);
|
||||
}
|
||||
|
||||
return type;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
gimp_param_value_array_class_init (GParamSpecClass *klass)
|
||||
{
|
||||
klass->value_type = GIMP_TYPE_VALUE_ARRAY;
|
||||
klass->finalize = gimp_param_value_array_finalize;
|
||||
klass->value_set_default = gimp_param_value_array_set_default;
|
||||
klass->value_validate = gimp_param_value_array_validate;
|
||||
klass->values_cmp = gimp_param_value_array_values_cmp;
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_param_value_array_init (GParamSpec *pspec)
|
||||
{
|
||||
GimpParamSpecValueArray *aspec = GIMP_PARAM_SPEC_VALUE_ARRAY (pspec);
|
||||
|
||||
aspec->element_spec = NULL;
|
||||
aspec->fixed_n_elements = 0; /* disable */
|
||||
}
|
||||
|
||||
static inline guint
|
||||
gimp_value_array_ensure_size (GimpValueArray *value_array,
|
||||
guint fixed_n_elements)
|
||||
{
|
||||
guint changed = 0;
|
||||
|
||||
if (fixed_n_elements)
|
||||
{
|
||||
while (gimp_value_array_length (value_array) < fixed_n_elements)
|
||||
{
|
||||
gimp_value_array_append (value_array, NULL);
|
||||
changed++;
|
||||
}
|
||||
|
||||
while (gimp_value_array_length (value_array) > fixed_n_elements)
|
||||
{
|
||||
gimp_value_array_remove (value_array,
|
||||
gimp_value_array_length (value_array) - 1);
|
||||
changed++;
|
||||
}
|
||||
}
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_param_value_array_finalize (GParamSpec *pspec)
|
||||
{
|
||||
GimpParamSpecValueArray *aspec = GIMP_PARAM_SPEC_VALUE_ARRAY (pspec);
|
||||
GParamSpecClass *parent_class = g_type_class_peek (g_type_parent (GIMP_TYPE_PARAM_VALUE_ARRAY));
|
||||
|
||||
if (aspec->element_spec)
|
||||
{
|
||||
g_param_spec_unref (aspec->element_spec);
|
||||
aspec->element_spec = NULL;
|
||||
}
|
||||
|
||||
parent_class->finalize (pspec);
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_param_value_array_set_default (GParamSpec *pspec,
|
||||
GValue *value)
|
||||
{
|
||||
GimpParamSpecValueArray *aspec = GIMP_PARAM_SPEC_VALUE_ARRAY (pspec);
|
||||
|
||||
if (!value->data[0].v_pointer && aspec->fixed_n_elements)
|
||||
value->data[0].v_pointer = gimp_value_array_new (aspec->fixed_n_elements);
|
||||
|
||||
if (value->data[0].v_pointer)
|
||||
{
|
||||
/* g_value_reset (value); already done */
|
||||
gimp_value_array_ensure_size (value->data[0].v_pointer,
|
||||
aspec->fixed_n_elements);
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gimp_param_value_array_validate (GParamSpec *pspec,
|
||||
GValue *value)
|
||||
{
|
||||
GimpParamSpecValueArray *aspec = GIMP_PARAM_SPEC_VALUE_ARRAY (pspec);
|
||||
GimpValueArray *value_array = value->data[0].v_pointer;
|
||||
guint changed = 0;
|
||||
|
||||
if (!value->data[0].v_pointer && aspec->fixed_n_elements)
|
||||
value->data[0].v_pointer = gimp_value_array_new (aspec->fixed_n_elements);
|
||||
|
||||
if (value->data[0].v_pointer)
|
||||
{
|
||||
/* ensure array size validity */
|
||||
changed += gimp_value_array_ensure_size (value_array,
|
||||
aspec->fixed_n_elements);
|
||||
|
||||
/* ensure array values validity against a present element spec */
|
||||
if (aspec->element_spec)
|
||||
{
|
||||
GParamSpec *element_spec = aspec->element_spec;
|
||||
gint length = gimp_value_array_length (value_array);
|
||||
gint i;
|
||||
|
||||
for (i = 0; i < length; i++)
|
||||
{
|
||||
GValue *element = gimp_value_array_index (value_array, i);
|
||||
|
||||
/* need to fixup value type, or ensure that the array
|
||||
* value is initialized at all
|
||||
*/
|
||||
if (! g_value_type_compatible (G_VALUE_TYPE (element),
|
||||
G_PARAM_SPEC_VALUE_TYPE (element_spec)))
|
||||
{
|
||||
if (G_VALUE_TYPE (element) != 0)
|
||||
g_value_unset (element);
|
||||
|
||||
g_value_init (element, G_PARAM_SPEC_VALUE_TYPE (element_spec));
|
||||
g_param_value_set_default (element_spec, element);
|
||||
changed++;
|
||||
}
|
||||
|
||||
/* validate array value against element_spec */
|
||||
changed += g_param_value_validate (element_spec, element);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
static gint
|
||||
gimp_param_value_array_values_cmp (GParamSpec *pspec,
|
||||
const GValue *value1,
|
||||
const GValue *value2)
|
||||
{
|
||||
GimpParamSpecValueArray *aspec = GIMP_PARAM_SPEC_VALUE_ARRAY (pspec);
|
||||
GimpValueArray *value_array1 = value1->data[0].v_pointer;
|
||||
GimpValueArray *value_array2 = value2->data[0].v_pointer;
|
||||
gint length1;
|
||||
gint length2;
|
||||
|
||||
if (!value_array1 || !value_array2)
|
||||
return value_array2 ? -1 : value_array1 != value_array2;
|
||||
|
||||
length1 = gimp_value_array_length (value_array1);
|
||||
length2 = gimp_value_array_length (value_array2);
|
||||
|
||||
if (length1 != length2)
|
||||
{
|
||||
return length1 < length2 ? -1 : 1;
|
||||
}
|
||||
else if (! aspec->element_spec)
|
||||
{
|
||||
/* we need an element specification for comparisons, so there's
|
||||
* not much to compare here, try to at least provide stable
|
||||
* lesser/greater result
|
||||
*/
|
||||
return length1 < length2 ? -1 : length1 > length2;
|
||||
}
|
||||
else /* length1 == length2 */
|
||||
{
|
||||
guint i;
|
||||
|
||||
for (i = 0; i < length1; i++)
|
||||
{
|
||||
GValue *element1 = gimp_value_array_index (value_array1, i);
|
||||
GValue *element2 = gimp_value_array_index (value_array2, i);
|
||||
gint cmp;
|
||||
|
||||
/* need corresponding element types, provide stable result
|
||||
* otherwise
|
||||
*/
|
||||
if (G_VALUE_TYPE (element1) != G_VALUE_TYPE (element2))
|
||||
return G_VALUE_TYPE (element1) < G_VALUE_TYPE (element2) ? -1 : 1;
|
||||
|
||||
cmp = g_param_values_cmp (aspec->element_spec, element1, element2);
|
||||
if (cmp)
|
||||
return cmp;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
GParamSpec *
|
||||
gimp_param_spec_value_array (const gchar *name,
|
||||
const gchar *nick,
|
||||
const gchar *blurb,
|
||||
GParamSpec *element_spec,
|
||||
GParamFlags flags)
|
||||
{
|
||||
GimpParamSpecValueArray *aspec;
|
||||
|
||||
if (element_spec)
|
||||
g_return_val_if_fail (G_IS_PARAM_SPEC (element_spec), NULL);
|
||||
|
||||
aspec = g_param_spec_internal (GIMP_TYPE_PARAM_VALUE_ARRAY,
|
||||
name,
|
||||
nick,
|
||||
blurb,
|
||||
flags);
|
||||
if (element_spec)
|
||||
{
|
||||
aspec->element_spec = g_param_spec_ref (element_spec);
|
||||
g_param_spec_sink (element_spec);
|
||||
}
|
||||
|
||||
return G_PARAM_SPEC (aspec);
|
||||
}
|
||||
|
|
|
@ -64,6 +64,32 @@ void gimp_value_array_truncate (GimpValueArray *value_array,
|
|||
gint n_values);
|
||||
|
||||
|
||||
/*
|
||||
* GIMP_TYPE_PARAM_VALUE_ARRAY
|
||||
*/
|
||||
|
||||
#define GIMP_TYPE_PARAM_VALUE_ARRAY (gimp_param_value_array_get_type ())
|
||||
#define GIMP_IS_PARAM_SPEC_VALUE_ARRAY(pspec) (G_TYPE_CHECK_INSTANCE_TYPE ((pspec), GIMP_TYPE_PARAM_VALUE_ARRAY))
|
||||
#define GIMP_PARAM_SPEC_VALUE_ARRAY(pspec) (G_TYPE_CHECK_INSTANCE_CAST ((pspec), GIMP_TYPE_PARAM_VALUE_ARRAY, GimpParamSpecValueArray))
|
||||
|
||||
typedef struct _GimpParamSpecValueArray GimpParamSpecValueArray;
|
||||
|
||||
struct _GimpParamSpecValueArray
|
||||
{
|
||||
GParamSpec parent_instance;
|
||||
GParamSpec *element_spec;
|
||||
gint fixed_n_elements;
|
||||
};
|
||||
|
||||
GType gimp_param_value_array_get_type (void) G_GNUC_CONST;
|
||||
|
||||
GParamSpec * gimp_param_spec_value_array (const gchar *name,
|
||||
const gchar *nick,
|
||||
const gchar *blurb,
|
||||
GParamSpec *element_spec,
|
||||
GParamFlags flags);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GIMP_VALUE_ARRAY_H__ */
|
||||
|
|
Loading…
Reference in a new issue