2008-04-17 Emmanuele Bassi <ebassi@openedhand.com>

* clutter/clutter-fixed.[ch]: Add a ClutterFixed fundamental
	type, and wrappers for storing it into GValues; also add a
	GParamSpec subclass for defining parameters holding
	ClutterFixed values. This allows creating GObject properties
	using fixed point values.

	* doc/reference/clutter-sections.txt: Document the newly
	added API.
This commit is contained in:
Emmanuele Bassi 2008-04-17 10:08:17 +00:00
parent d1ba07d0e7
commit 0ecfa9701f
4 changed files with 311 additions and 1 deletions

View File

@ -1,3 +1,14 @@
2008-04-17 Emmanuele Bassi <ebassi@openedhand.com>
* clutter/clutter-fixed.[ch]: Add a ClutterFixed fundamental
type, and wrappers for storing it into GValues; also add a
GParamSpec subclass for defining parameters holding
ClutterFixed values. This allows creating GObject properties
using fixed point values.
* doc/reference/clutter-sections.txt: Document the newly
added API.
2008-04-17 Emmanuele Bassi <ebassi@openedhand.com>
* clutter/Makefile.am: Add clutter-units.c

View File

@ -27,6 +27,9 @@
#include "config.h"
#endif
#include <glib-object.h>
#include <gobject/gvaluecollector.h>
#include "clutter-fixed.h"
#include "clutter-private.h"
@ -972,3 +975,229 @@ clutter_powx (guint x, ClutterFixed y)
return clutter_pow2x (CFX_MUL (y, clutter_log2x (x)));
}
static GTypeInfo _info = {
0,
NULL,
NULL,
NULL,
NULL,
NULL,
0,
0,
NULL,
NULL,
};
static GTypeFundamentalInfo _finfo = { 0, };
static void
clutter_value_init_fixed (GValue *value)
{
value->data[0].v_int = 0;
}
static void
clutter_value_copy_fixed (const GValue *src,
GValue *dest)
{
dest->data[0].v_int = src->data[0].v_int;
}
static gchar *
clutter_value_collect_fixed (GValue *value,
guint n_collect_values,
GTypeCValue *collect_values,
guint collect_flags)
{
value->data[0].v_int = collect_values[0].v_int;
return NULL;
}
static gchar *
clutter_value_lcopy_fixed (const GValue *value,
guint n_collect_values,
GTypeCValue *collect_values,
guint collect_flags)
{
gint32 *fixed_p = collect_values[0].v_pointer;
if (!fixed_p)
return g_strdup_printf ("value location for `%s' passed as NULL",
G_VALUE_TYPE_NAME (value));
*fixed_p = value->data[0].v_int;
return NULL;
}
static const GTypeValueTable _clutter_fixed_value_table = {
clutter_value_init_fixed,
NULL,
clutter_value_copy_fixed,
NULL,
"i",
clutter_value_collect_fixed,
"p",
clutter_value_lcopy_fixed
};
GType
clutter_fixed_get_type (void)
{
static GType _clutter_fixed_type = 0;
if (G_UNLIKELY (_clutter_fixed_type == 0))
{
_info.value_table = & _clutter_fixed_value_table;
_clutter_fixed_type =
g_type_register_fundamental (g_type_fundamental_next (),
I_("ClutterFixed"),
&_info, &_finfo, 0);
}
return _clutter_fixed_type;
}
/**
* clutter_value_set_fixed:
* @value: a #GValue initialized to #CLUTTER_TYPE_FIXED
* @fixed_: the fixed point value to set
*
* Sets @value to @fixed_.
*
* Since: 0.8
*/
void
clutter_value_set_fixed (GValue *value,
ClutterFixed fixed_)
{
g_return_if_fail (CLUTTER_VALUE_HOLDS_FIXED (value));
value->data[0].v_int = fixed_;
}
/**
* clutter_value_get_fixed:
* @value: a #GValue initialized to #CLUTTER_TYPE_FIXED
*
* Gets the fixed point value stored inside @value.
*
* Return value: the value inside the passed #GValue
*
* Since: 0.8
*/
ClutterFixed
cluttter_value_get_fixed (const GValue *value)
{
g_return_val_if_fail (CLUTTER_VALUE_HOLDS_FIXED (value), 0);
return value->data[0].v_int;
}
static void
param_fixed_init (GParamSpec *pspec)
{
ClutterParamSpecFixed *fspec = CLUTTER_PARAM_SPEC_FIXED (pspec);
fspec->minimum = -G_MAXINT32;
fspec->maximum = G_MAXINT32;
fspec->default_value = 0;
}
static void
param_fixed_set_default (GParamSpec *pspec,
GValue *value)
{
value->data[0].v_int = CLUTTER_PARAM_SPEC_FIXED (pspec)->default_value;
}
static gboolean
param_fixed_validate (GParamSpec *pspec,
GValue *value)
{
ClutterParamSpecFixed *fspec = CLUTTER_PARAM_SPEC_FIXED (pspec);
gint oval = value->data[0].v_int;
value->data[0].v_int = CLAMP (value->data[0].v_int,
fspec->minimum,
fspec->maximum);
return value->data[0].v_int != oval;
}
static gint
param_fixed_values_cmp (GParamSpec *pspec,
const GValue *value1,
const GValue *value2)
{
if (value1->data[0].v_int < value2->data[0].v_int)
return -1;
else
return value1->data[0].v_int > value2->data[0].v_int;
}
GType
clutter_param_fixed_get_type (void)
{
static GType pspec_type = 0;
if (G_UNLIKELY (pspec_type == 0))
{
const GParamSpecTypeInfo pspec_info = {
sizeof (ClutterParamSpecFixed),
16,
param_fixed_init,
CLUTTER_TYPE_FIXED,
NULL,
param_fixed_set_default,
param_fixed_validate,
param_fixed_values_cmp,
};
pspec_type = g_param_type_register_static (I_("ClutterParamSpecFixed"),
&pspec_info);
}
return pspec_type;
}
/**
* clutter_param_spec_fixed:
* @name: name of the property
* @nick: short name
* @blurb: description (can be translatable)
* @minimum: lower boundary
* @maximum: higher boundary
* @default_value: default value
* @flags: flags for the param spec
*
* Creates a #GParamSpec for properties using #ClutterFixed values
*
* Return value: the newly created #GParamSpec
*
* Since: 0.8
*/
GParamSpec *
clutter_param_spec_fixed (const gchar *name,
const gchar *nick,
const gchar *blurb,
ClutterUnit minimum,
ClutterUnit maximum,
ClutterUnit default_value,
GParamFlags flags)
{
ClutterParamSpecFixed *fspec;
g_return_val_if_fail (default_value >= minimum && default_value <= maximum,
NULL);
fspec = g_param_spec_internal (CLUTTER_TYPE_PARAM_FIXED,
name, nick, blurb,
flags);
fspec->minimum = minimum;
fspec->maximum = maximum;
fspec->default_value = default_value;
return G_PARAM_SPEC (fspec);
}

View File

@ -27,7 +27,7 @@
#ifndef _HAVE_CLUTTER_FIXED_H
#define _HAVE_CLUTTER_FIXED_H
#include <glib.h>
#include <glib-object.h>
G_BEGIN_DECLS
@ -372,6 +372,59 @@ ClutterFixed clutter_log2x (guint x);
guint clutter_pow2x (ClutterFixed x);
guint clutter_powx (guint x, ClutterFixed y);
#define CLUTTER_TYPE_FIXED (clutter_fixed_get_type ())
#define CLUTTER_TYPE_PARAM_FIXED (clutter_param_fixed_get_type ())
#define CLUTTER_PARAM_SPEC_FIXED(pspec) (G_TYPE_CHECK_INSTANCE_CAST ((pspec), CLUTTER_TYPE_PARAM_FIXED, ClutterParamSpecFixed))
#define CLUTTER_IS_PARAM_SPEC_FIXED(pspec) (G_TYPE_CHECK_INSTANCE_TYPE ((pspec), CLUTTER_TYPE_PARAM_FIXED))
/**
* CLUTTER_VALUE_HOLDS_FIXED:
* @x: a #GValue
*
* Evaluates to %TRUE if @x holds a #ClutterFixed.
*
* Since: 0.8
*/
#define CLUTTER_VALUE_HOLDS_FIXED(x) (G_VALUE_HOLDS ((x), CLUTTER_TYPE_FIXED))
typedef struct _ClutterParamSpecFixed ClutterParamSpecFixed;
/**
* ClutterParamSpecFixed
* @minimum: lower boundary
* @maximum: higher boundary
* @default_value: default value
*
* #GParamSpec subclass for fixed point based properties
*
* Since: 0.8
*/
struct _ClutterParamSpecFixed
{
/*< private >*/
GParamSpec parent_instance;
/*< public >*/
ClutterFixed minimum;
ClutterFixed maximum;
ClutterFixed default_value;
};
GType clutter_fixed_get_type (void) G_GNUC_CONST;
GType clutter_param_fixed_get_type (void) G_GNUC_CONST;
void clutter_value_set_fixed (GValue *value,
ClutterFixed fixed_);
ClutterFixed clutter_value_get_fixed (const GValue *value);
GParamSpec * clutter_param_spec_fixed (const gchar *name,
const gchar *nick,
const gchar *blurb,
ClutterFixed minimum,
ClutterFixed maximum,
ClutterFixed default_value,
GParamFlags flags);
/* <private> */
extern ClutterFixed clutter_double_to_fixed (double value);
extern gint clutter_double_to_int (double value);

View File

@ -872,12 +872,29 @@ clutter_qmulx
clutter_qdivx
clutter_tani
<SUBSECTION>
CLUTTER_VALUE_HOLDS_FIXED
clutter_value_set_fixed
clutter_value_get_fixed
<SUBSECTION>
ClutterParamSpecFixed
clutter_param_spec_fixed
<SUBSECTION Standard>
CLUTTER_PARAM_SPEC_FIXED
CLUTTER_IS_PARAM_SPEC_FIXED
<SUBSECTION Private>
CFX_DIV
CFX_INT
CFX_MUL
CFX_QMUL
CFX_QDIV
CLUTTER_TYPE_FIXED
CLUTTER_TYPE_PARAM_FIXED
clutter_fixed_get_type
clutter_param_fixed_get_type
</SECTION>
<SECTION>