2008-04-17 Emmanuele Bassi <ebassi@openedhand.com>
authorEmmanuele Bassi <ebassi@openedhand.com>
Thu, 17 Apr 2008 10:08:17 +0000 (10:08 +0000)
committerEmmanuele Bassi <ebassi@openedhand.com>
Thu, 17 Apr 2008 10:08:17 +0000 (10:08 +0000)
* 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.

ChangeLog
clutter/clutter-fixed.c
clutter/clutter-fixed.h
doc/reference/clutter-sections.txt

index b786809..6040d26 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,16 @@
 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
 
        * clutter/clutter-units.[ch]: Add a ClutterUnit fundamental
index cf0964e..b92d4e2 100644 (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);
+}
index 2e5c14d..e91d19d 100644 (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);
index d2b2045..dabd822 100644 (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>