2008-04-17 Emmanuele Bassi <ebassi@openedhand.com>
authorEmmanuele Bassi <ebassi@openedhand.com>
Thu, 17 Apr 2008 09:13:12 +0000 (09:13 +0000)
committerEmmanuele Bassi <ebassi@openedhand.com>
Thu, 17 Apr 2008 09:13:12 +0000 (09:13 +0000)
* clutter/Makefile.am: Add clutter-units.c

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

* doc/reference/clutter-sections.txt: Document the newly
added API.

ChangeLog
clutter/Makefile.am
clutter/clutter-units.c [new file with mode: 0644]
clutter/clutter-units.h
doc/reference/clutter-sections.txt

index 96e4afb..b786809 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,15 @@
+2008-04-17  Emmanuele Bassi  <ebassi@openedhand.com>
+
+       * clutter/Makefile.am: Add clutter-units.c
+
+       * clutter/clutter-units.[ch]: Add a ClutterUnit fundamental
+       type, and wrappers for storing it into GValues; also add a
+       GParamSpec subclass for defining parameters holding ClutterUnit
+       values. This allows creating GObject properties using units.
+
+       * doc/reference/clutter-sections.txt: Document the newly
+       added API.
+
 2008-04-15  Matthew Allum  <mallum@openedhand.com>
 
         Work related to #873;
index 554e312..bc4ae2b 100644 (file)
@@ -166,6 +166,7 @@ source_c = \
        clutter-texture.c               \
        clutter-timeline.c              \
        clutter-timeout-pool.c          \
+       clutter-units.c                 \
        clutter-util.c                  \
        $(NULL)
 
diff --git a/clutter/clutter-units.c b/clutter/clutter-units.c
new file mode 100644 (file)
index 0000000..8b0c22f
--- /dev/null
@@ -0,0 +1,282 @@
+/* -*- mode:C; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Clutter.
+ *
+ * An OpenGL based 'interactive canvas' library.
+ *
+ * Authored By Tomas Frydrych  <tf@openedhand.com>
+ *
+ * Copyright (C) 2007 OpenedHand
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/**
+ * SECTION:clutter-units
+ * @short_description: A logical distance unit.
+ *
+ * Clutter units are logical units with granularity greater than that of the
+ * device units; they are used by #ClutterActorBox and the _units() family of
+ * ClutterActor functions. To convert between clutter units and device units,
+ * use #CLUTTER_UNITS_FROM_DEVICE and #CLUTTER_UNITS_TO_DEVICE macros.
+ *
+ * Note: It is expected that as of version 0.6 all dimensions in the public
+ * Clutter API will be given in clutter units. In order to ease the transition,
+ * two extra macros have been provided, #CLUTTER_UNITS_TMP_TO_DEVICE and
+ * #CLUTTER_UNITS_TMP_FROM_DEVICE. In version 0.4 these are identity macros,
+ * but when the API transition happens will map to #CLUTTER_UNITS_TO_DEVICE and
+ * #CLUTTER_UNITS_FROM_DEVICE respectively. You can use these in newly written
+ * code as place holders.
+ *
+ * Since: 0.4
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <glib-object.h>
+#include <gobject/gvaluecollector.h>
+
+#include "clutter-units.h"
+#include "clutter-private.h"
+
+static GTypeInfo _info = {
+ 0,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ 0,
+ 0,
+ NULL,
+ NULL,
+};
+
+static GTypeFundamentalInfo _finfo = { 0, };
+
+static void
+clutter_value_init_unit (GValue *value)
+{
+  value->data[0].v_int = 0;
+}
+
+static void
+clutter_value_copy_unit (const GValue *src,
+                         GValue       *dest)
+{
+  dest->data[0].v_int = src->data[0].v_int;
+}
+
+static gchar *
+clutter_value_collect_unit (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_unit (const GValue *value,
+                          guint         n_collect_values,
+                          GTypeCValue  *collect_values,
+                          guint         collect_flags)
+{
+  gint32 *units_p = collect_values[0].v_pointer;
+
+  if (!units_p)
+    return g_strdup_printf ("value location for `%s' passed as NULL",
+                            G_VALUE_TYPE_NAME (value));
+
+  *units_p = value->data[0].v_int;
+
+  return NULL;
+}
+
+static const GTypeValueTable _clutter_unit_value_table = {
+  clutter_value_init_unit,
+  NULL,
+  clutter_value_copy_unit,
+  NULL,
+  "i",
+  clutter_value_collect_unit,
+  "p",
+  clutter_value_lcopy_unit
+};
+
+GType
+clutter_unit_get_type (void)
+{
+  static GType _clutter_unit_type = 0;
+
+  if (G_UNLIKELY (_clutter_unit_type == 0))
+    {
+      _info.value_table = & _clutter_unit_value_table;
+      _clutter_unit_type =
+        g_type_register_fundamental (g_type_fundamental_next (),
+                                     I_("ClutterUnit"),
+                                     &_info, &_finfo, 0);
+    }
+
+  return _clutter_unit_type;
+}
+
+/**
+ * clutter_value_set_unit:
+ * @value: a #GValue initialized to #CLUTTER_TYPE_UNIT
+ * @units: the units to set
+ *
+ * Sets @value to @units
+ *
+ * Since: 0.8
+ */
+void
+clutter_value_set_unit (GValue      *value,
+                        ClutterUnit  units)
+{
+  g_return_if_fail (CLUTTER_VALUE_HOLDS_UNIT (value));
+
+  value->data[0].v_int = units;
+}
+
+/**
+ * clutter_value_get_unit:
+ * @value: a #GValue initialized to #CLUTTER_TYPE_UNIT
+ *
+ * Gets the #ClutterUnit<!-- -->s contained in @value.
+ *
+ * Return value: the units inside the passed #GValue
+ *
+ * Since: 0.8
+ */
+ClutterUnit
+cluttter_value_get_unit (const GValue *value)
+{
+  g_return_val_if_fail (CLUTTER_VALUE_HOLDS_UNIT (value), 0);
+
+  return value->data[0].v_int;
+}
+
+static void
+param_unit_init (GParamSpec *pspec)
+{
+  ClutterParamSpecUnit *uspec = CLUTTER_PARAM_SPEC_UNIT (pspec);
+
+  uspec->minimum = -G_MAXINT32;
+  uspec->maximum = G_MAXINT32;
+  uspec->default_value = 0;
+}
+
+static void
+param_unit_set_default (GParamSpec *pspec,
+                        GValue     *value)
+{
+  value->data[0].v_int = CLUTTER_PARAM_SPEC_UNIT (pspec)->default_value;
+}
+
+static gboolean
+param_unit_validate (GParamSpec *pspec,
+                     GValue     *value)
+{
+  ClutterParamSpecUnit *uspec = CLUTTER_PARAM_SPEC_UNIT (pspec);
+  gint oval = value->data[0].v_int;
+
+  value->data[0].v_int = CLAMP (value->data[0].v_int,
+                                uspec->minimum,
+                                uspec->maximum);
+
+  return value->data[0].v_int != oval;
+}
+
+static gint
+param_unit_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_unit_get_type (void)
+{
+  static GType pspec_type = 0;
+
+  if (G_UNLIKELY (pspec_type == 0))
+    {
+      const GParamSpecTypeInfo pspec_info = {
+        sizeof (ClutterParamSpecUnit),
+        16,
+        param_unit_init,
+        CLUTTER_TYPE_UNIT,
+        NULL,
+        param_unit_set_default,
+        param_unit_validate,
+        param_unit_values_cmp,
+      };
+
+      pspec_type = g_param_type_register_static (I_("ClutterParamSpecUnit"),
+                                                 &pspec_info);
+    }
+
+  return pspec_type;
+}
+
+/**
+ * clutter_param_spec_unit:
+ * @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 #ClutterUnit<!-- -->s.
+ *
+ * Return value: the newly created #GParamSpec
+ *
+ * Since: 0.8
+ */
+GParamSpec *
+clutter_param_spec_unit (const gchar *name,
+                         const gchar *nick,
+                         const gchar *blurb,
+                         ClutterUnit  minimum,
+                         ClutterUnit  maximum,
+                         ClutterUnit  default_value,
+                         GParamFlags  flags)
+{
+  ClutterParamSpecUnit *uspec;
+
+  g_return_val_if_fail (default_value >= minimum && default_value <= maximum,
+                        NULL);
+
+  uspec = g_param_spec_internal (CLUTTER_TYPE_PARAM_UNIT,
+                                 name, nick, blurb,
+                                 flags);
+  uspec->minimum = minimum;
+  uspec->maximum = maximum;
+  uspec->default_value = default_value;
+
+  return G_PARAM_SPEC (uspec);
+}
index e616702..50af78a 100644 (file)
  * Boston, MA 02111-1307, USA.
  */
 
-/**
- * SECTION:clutter-units
- * @short_description: A logical distance unit.
- *
- * Clutter units are logical units with granularity greater than that of the
- * device units; they are used by #ClutterActorBox and the _units() family of
- * ClutterActor functions. To convert between clutter units and device units,
- * use #CLUTTER_UNITS_FROM_DEVICE and #CLUTTER_UNITS_TO_DEVICE macros.
- *
- * Note: It is expected that as of version 0.6 all dimensions in the public
- * Clutter API will be given in clutter units. In order to ease the transition,
- * two extra macros have been provided, #CLUTTER_UNITS_TMP_TO_DEVICE and
- * #CLUTTER_UNITS_TMP_FROM_DEVICE. In version 0.4 these are identity macros,
- * but when the API transition happens will map to #CLUTTER_UNITS_TO_DEVICE and
- * #CLUTTER_UNITS_FROM_DEVICE respectively. You can use these in newly written
- * code as place holders.
- *
- * Since: 0.4
- */
-
 #ifndef _HAVE_CLUTTER_UNITS_H
 #define _HAVE_CLUTTER_UNITS_H
 
+#include <glib-object.h>
 #include <clutter/clutter-fixed.h>
 
 G_BEGIN_DECLS
@@ -159,6 +140,59 @@ typedef gint32 ClutterUnit;
 #define CLUTTER_UNITS_FROM_POINTSX(x) \
   (CFX_MUL ((x), clutter_stage_get_resolutionx ((ClutterStage *) clutter_stage_get_default ())) / 72)
 
+#define CLUTTER_TYPE_UNIT                 (clutter_unit_get_type ())
+#define CLUTTER_TYPE_PARAM_UNIT           (clutter_param_unit_get_type ())
+#define CLUTTER_PARAM_SPEC_UNIT(pspec)    (G_TYPE_CHECK_INSTANCE_CAST ((pspec), CLUTTER_TYPE_PARAM_UNIT, ClutterParamSpecUnit))
+#define CLUTTER_IS_PARAM_SPEC_UNIT(pspec) (G_TYPE_CHECK_INSTANCE_TYPE ((pspec), CLUTTER_TYPE_PARAM_UNIT))
+
+/**
+ * CLUTTER_VALUE_HOLDS_UNIT:
+ * @x: a #GValue
+ *
+ * Evaluates to %TRUE if @x holds #ClutterUnit<!-- -->s.
+ *
+ * Since: 0.8
+ */
+#define CLUTTER_VALUE_HOLDS_UNIT(x)       (G_VALUE_HOLDS ((x), CLUTTER_TYPE_UNIT))
+
+typedef struct _ClutterParamSpecUnit    ClutterParamSpecUnit;
+
+/**
+ * ClutterParamSpecUnit:
+ * @minimum: lower boundary
+ * @maximum: higher boundary
+ * @default_value: default value
+ *
+ * #GParamSpec subclass for unit based properties.
+ *
+ * Since: 0.8
+ */
+struct _ClutterParamSpecUnit
+{
+  /*< private >*/
+  GParamSpec    parent_instance;
+
+  /*< public >*/
+  ClutterUnit   minimum;
+  ClutterUnit   maximum;
+  ClutterUnit   default_value;
+};
+
+GType       clutter_unit_get_type       (void) G_GNUC_CONST;
+GType       clutter_param_unit_get_type (void) G_GNUC_CONST;
+
+void        clutter_value_set_unit (GValue       *value,
+                                    ClutterUnit   units);
+ClutterUnit clutter_value_get_unit (const GValue *value);
+
+GParamSpec *clutter_param_spec_unit (const gchar *name,
+                                     const gchar *nick,
+                                     const gchar *blurb,
+                                     ClutterUnit  minimum,
+                                     ClutterUnit  maximum,
+                                     ClutterUnit  default_value,
+                                     GParamFlags  flags);
+
 G_END_DECLS
 
 #endif /* _HAVE_CLUTTER_UNITS_H */
index 9206578..d2b2045 100644 (file)
@@ -28,14 +28,15 @@ clutter_media_get_type
 <FILE>clutter-units</FILE>
 <TITLE>Unit conversion</TITLE>
 ClutterUnit
-CLUTTER_UNITS_FROM_DEVICE
-CLUTTER_UNITS_TO_DEVICE
 CLUTTER_UNITS_FROM_FIXED
 CLUTTER_UNITS_TO_FIXED
 CLUTTER_UNITS_FROM_FLOAT
 CLUTTER_UNITS_TO_FLOAT
 CLUTTER_UNITS_FROM_INT
 CLUTTER_UNITS_TO_INT
+<SUBSECTION>
+CLUTTER_UNITS_FROM_DEVICE
+CLUTTER_UNITS_TO_DEVICE
 CLUTTER_UNITS_FROM_PANGO_UNIT
 CLUTTER_UNITS_TO_PANGO_UNIT
 CLUTTER_UNITS_TMP_FROM_DEVICE
@@ -48,6 +49,21 @@ CLUTTER_UNITS_FROM_MM
 CLUTTER_UNITS_FROM_MMX
 CLUTTER_UNITS_FROM_POINTS
 CLUTTER_UNITS_FROM_POINTSX
+<SUBSECTION>
+CLUTTER_VALUE_HOLDS_UNIT
+clutter_value_set_unit
+clutter_value_get_unit
+<SUBSECTION>
+ClutterParamSpecUnit
+clutter_param_spec_unit
+<SUBSECTION Standard>
+CLUTTER_TYPE_UNIT
+CLUTTER_TYPE_PARAM_UNIT
+CLUTTER_PARAM_SPEC_UNIT
+CLUTTER_IS_PARAM_SPEC_UNIT
+<SUBSECTION Private>
+clutter_unit_get_type
+clutter_param_unit_get_type
 </SECTION>
 
 <SECTION>