interval: Add variadic arguments for initial/final setters
As a convenience for the C API. Language bindings should already be using the GValue variants. This commit also moves the custom progress functions out of the clutter-interval.c, as they are meant to be generic interpolation functions and not ClutterInterval-specific.
This commit is contained in:
@ -37,6 +37,7 @@
|
||||
#include <glib/gi18n-lib.h>
|
||||
|
||||
#include "clutter-main.h"
|
||||
#include "clutter-interval.h"
|
||||
#include "clutter-private.h"
|
||||
|
||||
#include "deprecated/clutter-util.h"
|
||||
@ -180,3 +181,150 @@ _clutter_util_rectangle_union (const cairo_rectangle_int_t *src1,
|
||||
dest->x = dest_x;
|
||||
dest->y = dest_y;
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GType value_type;
|
||||
ClutterProgressFunc func;
|
||||
} ProgressData;
|
||||
|
||||
G_LOCK_DEFINE_STATIC (progress_funcs);
|
||||
static GHashTable *progress_funcs = NULL;
|
||||
|
||||
gboolean
|
||||
_clutter_has_progress_function (GType gtype)
|
||||
{
|
||||
const char *type_name = g_type_name (gtype);
|
||||
|
||||
if (progress_funcs == NULL)
|
||||
return FALSE;
|
||||
|
||||
return g_hash_table_lookup (progress_funcs, type_name) != NULL;
|
||||
}
|
||||
|
||||
gboolean
|
||||
_clutter_run_progress_function (GType gtype,
|
||||
const GValue *initial,
|
||||
const GValue *final,
|
||||
gdouble progress,
|
||||
GValue *retval)
|
||||
{
|
||||
ProgressData *pdata;
|
||||
gboolean res;
|
||||
|
||||
G_LOCK (progress_funcs);
|
||||
|
||||
if (G_UNLIKELY (progress_funcs == NULL))
|
||||
{
|
||||
res = FALSE;
|
||||
goto out;
|
||||
}
|
||||
|
||||
pdata = g_hash_table_lookup (progress_funcs, g_type_name (gtype));
|
||||
if (G_UNLIKELY (pdata == NULL))
|
||||
{
|
||||
res = FALSE;
|
||||
goto out;
|
||||
}
|
||||
|
||||
res = pdata->func (initial, final, progress, retval);
|
||||
|
||||
out:
|
||||
G_UNLOCK (progress_funcs);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static void
|
||||
progress_data_destroy (gpointer data_)
|
||||
{
|
||||
g_slice_free (ProgressData, data_);
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_interval_register_progress_func: (skip)
|
||||
* @value_type: a #GType
|
||||
* @func: a #ClutterProgressFunc, or %NULL to unset a previously
|
||||
* set progress function
|
||||
*
|
||||
* Sets the progress function for a given @value_type, like:
|
||||
*
|
||||
* |[
|
||||
* clutter_interval_register_progress_func (MY_TYPE_FOO,
|
||||
* my_foo_progress);
|
||||
* ]|
|
||||
*
|
||||
* Whenever a #ClutterInterval instance using the default
|
||||
* #ClutterInterval::compute_value implementation is set as an
|
||||
* interval between two #GValue of type @value_type, it will call
|
||||
* @func to establish the value depending on the given progress,
|
||||
* for instance:
|
||||
*
|
||||
* |[
|
||||
* static gboolean
|
||||
* my_int_progress (const GValue *a,
|
||||
* const GValue *b,
|
||||
* gdouble progress,
|
||||
* GValue *retval)
|
||||
* {
|
||||
* gint ia = g_value_get_int (a);
|
||||
* gint ib = g_value_get_int (b);
|
||||
* gint res = factor * (ib - ia) + ia;
|
||||
*
|
||||
* g_value_set_int (retval, res);
|
||||
*
|
||||
* return TRUE;
|
||||
* }
|
||||
*
|
||||
* clutter_interval_register_progress_func (G_TYPE_INT, my_int_progress);
|
||||
* ]|
|
||||
*
|
||||
* To unset a previously set progress function of a #GType, pass %NULL
|
||||
* for @func.
|
||||
*
|
||||
* Since: 1.0
|
||||
*/
|
||||
void
|
||||
clutter_interval_register_progress_func (GType value_type,
|
||||
ClutterProgressFunc func)
|
||||
{
|
||||
ProgressData *progress_func;
|
||||
const char *type_name;
|
||||
|
||||
g_return_if_fail (value_type != G_TYPE_INVALID);
|
||||
|
||||
type_name = g_type_name (value_type);
|
||||
|
||||
G_LOCK (progress_funcs);
|
||||
|
||||
if (G_UNLIKELY (progress_funcs == NULL))
|
||||
progress_funcs = g_hash_table_new_full (NULL, NULL,
|
||||
NULL,
|
||||
progress_data_destroy);
|
||||
|
||||
progress_func =
|
||||
g_hash_table_lookup (progress_funcs, type_name);
|
||||
|
||||
if (G_UNLIKELY (progress_func))
|
||||
{
|
||||
if (func == NULL)
|
||||
{
|
||||
g_hash_table_remove (progress_funcs, type_name);
|
||||
g_slice_free (ProgressData, progress_func);
|
||||
}
|
||||
else
|
||||
progress_func->func = func;
|
||||
}
|
||||
else
|
||||
{
|
||||
progress_func = g_slice_new (ProgressData);
|
||||
progress_func->value_type = value_type;
|
||||
progress_func->func = func;
|
||||
|
||||
g_hash_table_replace (progress_funcs,
|
||||
(gpointer) type_name,
|
||||
progress_func);
|
||||
}
|
||||
|
||||
G_UNLOCK (progress_funcs);
|
||||
}
|
||||
|
Reference in New Issue
Block a user