mirror of
https://github.com/brl/mutter.git
synced 2025-02-23 08:24:09 +00:00
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:
parent
06314e9ed8
commit
beb91d7676
@ -63,14 +63,6 @@
|
|||||||
#include "clutter-private.h"
|
#include "clutter-private.h"
|
||||||
#include "clutter-units.h"
|
#include "clutter-units.h"
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
GType value_type;
|
|
||||||
ClutterProgressFunc func;
|
|
||||||
} ProgressData;
|
|
||||||
|
|
||||||
static GHashTable *progress_funcs = NULL;
|
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
PROP_0,
|
PROP_0,
|
||||||
@ -195,23 +187,15 @@ clutter_interval_real_compute_value (ClutterInterval *interval,
|
|||||||
|
|
||||||
value_type = clutter_interval_get_value_type (interval);
|
value_type = clutter_interval_get_value_type (interval);
|
||||||
|
|
||||||
if (G_UNLIKELY (progress_funcs != NULL))
|
if (_clutter_has_progress_function (value_type))
|
||||||
{
|
{
|
||||||
ProgressData *p_data;
|
retval = _clutter_run_progress_function (value_type,
|
||||||
|
initial,
|
||||||
p_data =
|
final,
|
||||||
g_hash_table_lookup (progress_funcs, GUINT_TO_POINTER (value_type));
|
factor,
|
||||||
|
value);
|
||||||
/* if we have a progress function, and that function was
|
if (retval)
|
||||||
* successful in computing the progress, then we bail out
|
return TRUE;
|
||||||
* as fast as we can
|
|
||||||
*/
|
|
||||||
if (p_data != NULL)
|
|
||||||
{
|
|
||||||
retval = p_data->func (initial, final, factor, value);
|
|
||||||
if (retval)
|
|
||||||
return retval;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (G_TYPE_FUNDAMENTAL (value_type))
|
switch (G_TYPE_FUNDAMENTAL (value_type))
|
||||||
@ -413,16 +397,44 @@ clutter_interval_init (ClutterInterval *self)
|
|||||||
priv->values = g_malloc0 (sizeof (GValue) * N_VALUES);
|
priv->values = g_malloc0 (sizeof (GValue) * N_VALUES);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static inline void
|
||||||
clutter_interval_set_interval_valist (ClutterInterval *interval,
|
clutter_interval_set_value_internal (ClutterInterval *interval,
|
||||||
va_list var_args)
|
gint index_,
|
||||||
|
const GValue *value)
|
||||||
|
{
|
||||||
|
ClutterIntervalPrivate *priv = interval->priv;
|
||||||
|
|
||||||
|
g_assert (index_ >= INITIAL && index_ <= RESULT);
|
||||||
|
|
||||||
|
if (G_IS_VALUE (&priv->values[index_]))
|
||||||
|
g_value_unset (&priv->values[index_]);
|
||||||
|
|
||||||
|
g_value_init (&priv->values[index_], priv->value_type);
|
||||||
|
g_value_copy (value, &priv->values[index_]);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
clutter_interval_get_value_internal (ClutterInterval *interval,
|
||||||
|
gint index_,
|
||||||
|
GValue *value)
|
||||||
|
{
|
||||||
|
ClutterIntervalPrivate *priv = interval->priv;
|
||||||
|
|
||||||
|
g_assert (index_ >= INITIAL && index_ <= RESULT);
|
||||||
|
|
||||||
|
g_value_copy (&priv->values[index_], value);
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
clutter_interval_set_initial_internal (ClutterInterval *interval,
|
||||||
|
va_list *args)
|
||||||
{
|
{
|
||||||
GType gtype = interval->priv->value_type;
|
GType gtype = interval->priv->value_type;
|
||||||
GValue value = { 0, };
|
GValue value = { 0, };
|
||||||
gchar *error;
|
gchar *error;
|
||||||
|
|
||||||
/* initial value */
|
/* initial value */
|
||||||
G_VALUE_COLLECT_INIT (&value, gtype, var_args, 0, &error);
|
G_VALUE_COLLECT_INIT (&value, gtype, *args, 0, &error);
|
||||||
|
|
||||||
if (error)
|
if (error)
|
||||||
{
|
{
|
||||||
@ -433,26 +445,42 @@ clutter_interval_set_interval_valist (ClutterInterval *interval,
|
|||||||
* undefined behaviour
|
* undefined behaviour
|
||||||
*/
|
*/
|
||||||
g_free (error);
|
g_free (error);
|
||||||
return;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
clutter_interval_set_initial_value (interval, &value);
|
clutter_interval_set_value_internal (interval, INITIAL, &value);
|
||||||
g_value_unset (&value);
|
g_value_unset (&value);
|
||||||
|
|
||||||
/* final value */
|
return TRUE;
|
||||||
G_VALUE_COLLECT_INIT (&value, gtype, var_args, 0, &error);
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
clutter_interval_set_final_internal (ClutterInterval *interval,
|
||||||
|
va_list *args)
|
||||||
|
{
|
||||||
|
GType gtype = interval->priv->value_type;
|
||||||
|
GValue value = { 0, };
|
||||||
|
gchar *error;
|
||||||
|
|
||||||
|
/* initial value */
|
||||||
|
G_VALUE_COLLECT_INIT (&value, gtype, *args, 0, &error);
|
||||||
|
|
||||||
if (error)
|
if (error)
|
||||||
{
|
{
|
||||||
g_warning ("%s: %s", G_STRLOC, error);
|
g_warning ("%s: %s", G_STRLOC, error);
|
||||||
|
|
||||||
/* see above */
|
/* we leak the value here as it might not be in a valid state
|
||||||
|
* given the error and calling g_value_unset() might lead to
|
||||||
|
* undefined behaviour
|
||||||
|
*/
|
||||||
g_free (error);
|
g_free (error);
|
||||||
return;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
clutter_interval_set_final_value (interval, &value);
|
clutter_interval_set_value_internal (interval, FINAL, &value);
|
||||||
g_value_unset (&value);
|
g_value_unset (&value);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -524,7 +552,13 @@ clutter_interval_new (GType gtype,
|
|||||||
retval = g_object_new (CLUTTER_TYPE_INTERVAL, "value-type", gtype, NULL);
|
retval = g_object_new (CLUTTER_TYPE_INTERVAL, "value-type", gtype, NULL);
|
||||||
|
|
||||||
va_start (args, gtype);
|
va_start (args, gtype);
|
||||||
clutter_interval_set_interval_valist (retval, args);
|
|
||||||
|
if (!clutter_interval_set_initial_internal (retval, &args))
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
clutter_interval_set_final_internal (retval, &args);
|
||||||
|
|
||||||
|
out:
|
||||||
va_end (args);
|
va_end (args);
|
||||||
|
|
||||||
return retval;
|
return retval;
|
||||||
@ -616,34 +650,6 @@ clutter_interval_get_value_type (ClutterInterval *interval)
|
|||||||
return interval->priv->value_type;
|
return interval->priv->value_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
|
||||||
clutter_interval_set_value_internal (ClutterInterval *interval,
|
|
||||||
gint index_,
|
|
||||||
const GValue *value)
|
|
||||||
{
|
|
||||||
ClutterIntervalPrivate *priv = interval->priv;
|
|
||||||
|
|
||||||
g_assert (index_ >= INITIAL && index_ <= RESULT);
|
|
||||||
|
|
||||||
if (G_IS_VALUE (&priv->values[index_]))
|
|
||||||
g_value_unset (&priv->values[index_]);
|
|
||||||
|
|
||||||
g_value_init (&priv->values[index_], priv->value_type);
|
|
||||||
g_value_copy (value, &priv->values[index_]);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void
|
|
||||||
clutter_interval_get_value_internal (ClutterInterval *interval,
|
|
||||||
gint index_,
|
|
||||||
GValue *value)
|
|
||||||
{
|
|
||||||
ClutterIntervalPrivate *priv = interval->priv;
|
|
||||||
|
|
||||||
g_assert (index_ >= INITIAL && index_ <= RESULT);
|
|
||||||
|
|
||||||
g_value_copy (&priv->values[index_], value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* clutter_interval_set_initial_value:
|
* clutter_interval_set_initial_value:
|
||||||
* @interval: a #ClutterInterval
|
* @interval: a #ClutterInterval
|
||||||
@ -652,6 +658,8 @@ clutter_interval_get_value_internal (ClutterInterval *interval,
|
|||||||
* Sets the initial value of @interval to @value. The value is copied
|
* Sets the initial value of @interval to @value. The value is copied
|
||||||
* inside the #ClutterInterval.
|
* inside the #ClutterInterval.
|
||||||
*
|
*
|
||||||
|
* Rename to: clutter_interval_set_initial
|
||||||
|
*
|
||||||
* Since: 1.0
|
* Since: 1.0
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
@ -670,6 +678,33 @@ clutter_interval_set_initial_value (ClutterInterval *interval,
|
|||||||
clutter_interval_set_value_internal (interval, INITIAL, value);
|
clutter_interval_set_value_internal (interval, INITIAL, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* clutter_interval_set_initial: (skip)
|
||||||
|
* @interval: a #ClutterInterval
|
||||||
|
* @...: the initial value of the interval.
|
||||||
|
*
|
||||||
|
* Variadic arguments version of clutter_interval_set_initial_value().
|
||||||
|
*
|
||||||
|
* This function is meant as a convenience for the C API.
|
||||||
|
*
|
||||||
|
* Language bindings should use clutter_interval_set_initial_value()
|
||||||
|
* instead.
|
||||||
|
*
|
||||||
|
* Since: 1.10
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
clutter_interval_set_initial (ClutterInterval *interval,
|
||||||
|
...)
|
||||||
|
{
|
||||||
|
va_list args;
|
||||||
|
|
||||||
|
g_return_if_fail (CLUTTER_IS_INTERVAL (interval));
|
||||||
|
|
||||||
|
va_start (args, interval);
|
||||||
|
clutter_interval_set_initial_internal (interval, &args);
|
||||||
|
va_end (args);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* clutter_interval_get_initial_value:
|
* clutter_interval_get_initial_value:
|
||||||
* @interval: a #ClutterInterval
|
* @interval: a #ClutterInterval
|
||||||
@ -721,6 +756,8 @@ clutter_interval_peek_initial_value (ClutterInterval *interval)
|
|||||||
* Sets the final value of @interval to @value. The value is
|
* Sets the final value of @interval to @value. The value is
|
||||||
* copied inside the #ClutterInterval.
|
* copied inside the #ClutterInterval.
|
||||||
*
|
*
|
||||||
|
* Rename to: clutter_interval_set_final
|
||||||
|
*
|
||||||
* Since: 1.0
|
* Since: 1.0
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
@ -762,6 +799,32 @@ clutter_interval_get_final_value (ClutterInterval *interval,
|
|||||||
clutter_interval_get_value_internal (interval, FINAL, value);
|
clutter_interval_get_value_internal (interval, FINAL, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* clutter_interval_set_final: (skip)
|
||||||
|
* @interval: a #ClutterInterval
|
||||||
|
* @...: the final value of the interval
|
||||||
|
*
|
||||||
|
* Variadic arguments version of clutter_interval_set_final_value().
|
||||||
|
*
|
||||||
|
* This function is meant as a convenience for the C API.
|
||||||
|
*
|
||||||
|
* Language bindings should use clutter_interval_set_final_value() instead.
|
||||||
|
*
|
||||||
|
* Since: 1.10
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
clutter_interval_set_final (ClutterInterval *interval,
|
||||||
|
...)
|
||||||
|
{
|
||||||
|
va_list args;
|
||||||
|
|
||||||
|
g_return_if_fail (CLUTTER_IS_INTERVAL (interval));
|
||||||
|
|
||||||
|
va_start (args, interval);
|
||||||
|
clutter_interval_set_final_internal (interval, &args);
|
||||||
|
va_end (args);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* clutter_interval_peek_final_value:
|
* clutter_interval_peek_final_value:
|
||||||
* @interval: a #ClutterInterval
|
* @interval: a #ClutterInterval
|
||||||
@ -812,7 +875,13 @@ clutter_interval_set_interval (ClutterInterval *interval,
|
|||||||
g_return_if_fail (interval->priv->value_type != G_TYPE_INVALID);
|
g_return_if_fail (interval->priv->value_type != G_TYPE_INVALID);
|
||||||
|
|
||||||
va_start (args, interval);
|
va_start (args, interval);
|
||||||
clutter_interval_set_interval_valist (interval, args);
|
|
||||||
|
if (!clutter_interval_set_initial_internal (interval, &args))
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
clutter_interval_set_final_internal (interval, &args);
|
||||||
|
|
||||||
|
out:
|
||||||
va_end (args);
|
va_end (args);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -941,81 +1010,3 @@ clutter_interval_compute (ClutterInterval *interval,
|
|||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 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;
|
|
||||||
|
|
||||||
g_return_if_fail (value_type != G_TYPE_INVALID);
|
|
||||||
|
|
||||||
if (G_UNLIKELY (progress_funcs == NULL))
|
|
||||||
progress_funcs = g_hash_table_new (NULL, NULL);
|
|
||||||
|
|
||||||
progress_func =
|
|
||||||
g_hash_table_lookup (progress_funcs, GUINT_TO_POINTER (value_type));
|
|
||||||
if (G_UNLIKELY (progress_func))
|
|
||||||
{
|
|
||||||
if (func == NULL)
|
|
||||||
{
|
|
||||||
g_hash_table_remove (progress_funcs, GUINT_TO_POINTER (value_type));
|
|
||||||
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,
|
|
||||||
GUINT_TO_POINTER (value_type),
|
|
||||||
progress_func);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -43,34 +43,6 @@ G_BEGIN_DECLS
|
|||||||
typedef struct _ClutterIntervalPrivate ClutterIntervalPrivate;
|
typedef struct _ClutterIntervalPrivate ClutterIntervalPrivate;
|
||||||
typedef struct _ClutterIntervalClass ClutterIntervalClass;
|
typedef struct _ClutterIntervalClass ClutterIntervalClass;
|
||||||
|
|
||||||
/**
|
|
||||||
* ClutterProgressFunc:
|
|
||||||
* @a: the initial value of an interval
|
|
||||||
* @b: the final value of an interval
|
|
||||||
* @progress: the progress factor, between 0 and 1
|
|
||||||
* @retval: the value used to store the progress
|
|
||||||
*
|
|
||||||
* Prototype of the progress function used to compute the value
|
|
||||||
* between the two ends @a and @b of an interval depending on
|
|
||||||
* the value of @progress.
|
|
||||||
*
|
|
||||||
* The #GValue in @retval is already initialized with the same
|
|
||||||
* type as @a and @b.
|
|
||||||
*
|
|
||||||
* This function will be called by #ClutterInterval if the
|
|
||||||
* type of the values of the interval was registered using
|
|
||||||
* clutter_interval_register_progress_func().
|
|
||||||
*
|
|
||||||
* Return value: %TRUE if the function successfully computed
|
|
||||||
* the value and stored it inside @retval
|
|
||||||
*
|
|
||||||
* Since: 1.0
|
|
||||||
*/
|
|
||||||
typedef gboolean (* ClutterProgressFunc) (const GValue *a,
|
|
||||||
const GValue *b,
|
|
||||||
gdouble progress,
|
|
||||||
GValue *retval);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ClutterInterval:
|
* ClutterInterval:
|
||||||
*
|
*
|
||||||
@ -131,11 +103,16 @@ ClutterInterval *clutter_interval_new_with_values (GType gtype,
|
|||||||
ClutterInterval *clutter_interval_clone (ClutterInterval *interval);
|
ClutterInterval *clutter_interval_clone (ClutterInterval *interval);
|
||||||
|
|
||||||
GType clutter_interval_get_value_type (ClutterInterval *interval);
|
GType clutter_interval_get_value_type (ClutterInterval *interval);
|
||||||
|
|
||||||
|
void clutter_interval_set_initial (ClutterInterval *interval,
|
||||||
|
...);
|
||||||
void clutter_interval_set_initial_value (ClutterInterval *interval,
|
void clutter_interval_set_initial_value (ClutterInterval *interval,
|
||||||
const GValue *value);
|
const GValue *value);
|
||||||
void clutter_interval_get_initial_value (ClutterInterval *interval,
|
void clutter_interval_get_initial_value (ClutterInterval *interval,
|
||||||
GValue *value);
|
GValue *value);
|
||||||
GValue * clutter_interval_peek_initial_value (ClutterInterval *interval);
|
GValue * clutter_interval_peek_initial_value (ClutterInterval *interval);
|
||||||
|
void clutter_interval_set_final (ClutterInterval *interval,
|
||||||
|
...);
|
||||||
void clutter_interval_set_final_value (ClutterInterval *interval,
|
void clutter_interval_set_final_value (ClutterInterval *interval,
|
||||||
const GValue *value);
|
const GValue *value);
|
||||||
void clutter_interval_get_final_value (ClutterInterval *interval,
|
void clutter_interval_get_final_value (ClutterInterval *interval,
|
||||||
|
@ -265,6 +265,13 @@ typedef enum _ClutterCullResult
|
|||||||
CLUTTER_CULL_RESULT_PARTIAL
|
CLUTTER_CULL_RESULT_PARTIAL
|
||||||
} ClutterCullResult;
|
} ClutterCullResult;
|
||||||
|
|
||||||
|
gboolean _clutter_has_progress_function (GType gtype);
|
||||||
|
gboolean _clutter_run_progress_function (GType gtype,
|
||||||
|
const GValue *initial,
|
||||||
|
const GValue *final,
|
||||||
|
gdouble progress,
|
||||||
|
GValue *retval);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
#endif /* __CLUTTER_PRIVATE_H__ */
|
#endif /* __CLUTTER_PRIVATE_H__ */
|
||||||
|
@ -287,6 +287,34 @@ ClutterMargin * clutter_margin_new (void) G_GNUC_MALLOC;
|
|||||||
ClutterMargin * clutter_margin_copy (const ClutterMargin *margin_);
|
ClutterMargin * clutter_margin_copy (const ClutterMargin *margin_);
|
||||||
void clutter_margin_free (ClutterMargin *margin_);
|
void clutter_margin_free (ClutterMargin *margin_);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ClutterProgressFunc:
|
||||||
|
* @a: the initial value of an interval
|
||||||
|
* @b: the final value of an interval
|
||||||
|
* @progress: the progress factor, between 0 and 1
|
||||||
|
* @retval: the value used to store the progress
|
||||||
|
*
|
||||||
|
* Prototype of the progress function used to compute the value
|
||||||
|
* between the two ends @a and @b of an interval depending on
|
||||||
|
* the value of @progress.
|
||||||
|
*
|
||||||
|
* The #GValue in @retval is already initialized with the same
|
||||||
|
* type as @a and @b.
|
||||||
|
*
|
||||||
|
* This function will be called by #ClutterInterval if the
|
||||||
|
* type of the values of the interval was registered using
|
||||||
|
* clutter_interval_register_progress_func().
|
||||||
|
*
|
||||||
|
* Return value: %TRUE if the function successfully computed
|
||||||
|
* the value and stored it inside @retval
|
||||||
|
*
|
||||||
|
* Since: 1.0
|
||||||
|
*/
|
||||||
|
typedef gboolean (* ClutterProgressFunc) (const GValue *a,
|
||||||
|
const GValue *b,
|
||||||
|
gdouble progress,
|
||||||
|
GValue *retval);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
#endif /* __CLUTTER_TYPES_H__ */
|
#endif /* __CLUTTER_TYPES_H__ */
|
||||||
|
@ -37,6 +37,7 @@
|
|||||||
#include <glib/gi18n-lib.h>
|
#include <glib/gi18n-lib.h>
|
||||||
|
|
||||||
#include "clutter-main.h"
|
#include "clutter-main.h"
|
||||||
|
#include "clutter-interval.h"
|
||||||
#include "clutter-private.h"
|
#include "clutter-private.h"
|
||||||
|
|
||||||
#include "deprecated/clutter-util.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->x = dest_x;
|
||||||
dest->y = dest_y;
|
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);
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user