diff --git a/ChangeLog b/ChangeLog index 96e4afbb7..b786809a0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,15 @@ +2008-04-17 Emmanuele Bassi + + * 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 Work related to #873; diff --git a/clutter/Makefile.am b/clutter/Makefile.am index 554e31211..bc4ae2bcc 100644 --- a/clutter/Makefile.am +++ b/clutter/Makefile.am @@ -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 index 000000000..8b0c22f77 --- /dev/null +++ b/clutter/clutter-units.c @@ -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 + * + * 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 +#include + +#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 #ClutterUnits 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 #ClutterUnits. + * + * 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); +} diff --git a/clutter/clutter-units.h b/clutter/clutter-units.h index e6167022a..50af78acb 100644 --- a/clutter/clutter-units.h +++ b/clutter/clutter-units.h @@ -24,29 +24,10 @@ * 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 #include 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 #ClutterUnits. + * + * 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 */ diff --git a/doc/reference/clutter-sections.txt b/doc/reference/clutter-sections.txt index 92065787e..d2b2045d4 100644 --- a/doc/reference/clutter-sections.txt +++ b/doc/reference/clutter-sections.txt @@ -28,14 +28,15 @@ clutter_media_get_type clutter-units Unit conversion 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 + +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 + +CLUTTER_VALUE_HOLDS_UNIT +clutter_value_set_unit +clutter_value_get_unit + +ClutterParamSpecUnit +clutter_param_spec_unit + +CLUTTER_TYPE_UNIT +CLUTTER_TYPE_PARAM_UNIT +CLUTTER_PARAM_SPEC_UNIT +CLUTTER_IS_PARAM_SPEC_UNIT + +clutter_unit_get_type +clutter_param_unit_get_type