2007-11-30 Emmanuele Bassi <ebassi@openedhand.com>

* clutter/clutter-actor.c (parse_units),
	(clutter_actor_parse_custom_node),
	(clutter_scriptable_iface_init): Override the parsing code
	for the x, y, width and height properties of ClutterActor,
	to allow strings with modifiers when defining the position
	and/or the dimensions of an actor. Bare integers are assumed
	as pixels; floating point values in the [0, 1] interval are
	assumed as percentages; strings can have these modifiers:

	  - px - pixels
	  - mm - millimeters
	  - pt - points (at the current resolution)
	  - %  - percentage of the stage

	* clutter/clutter-units.h: Fix the conversion macros

	* tests/test-script.json: Test the new values.
This commit is contained in:
Emmanuele Bassi 2007-11-30 09:27:10 +00:00
parent 687561dfe2
commit f04a0a4645
4 changed files with 185 additions and 21 deletions

View File

@ -1,3 +1,23 @@
2007-11-30 Emmanuele Bassi <ebassi@openedhand.com>
* clutter/clutter-actor.c (parse_units),
(clutter_actor_parse_custom_node),
(clutter_scriptable_iface_init): Override the parsing code
for the x, y, width and height properties of ClutterActor,
to allow strings with modifiers when defining the position
and/or the dimensions of an actor. Bare integers are assumed
as pixels; floating point values in the [0, 1] interval are
assumed as percentages; strings can have these modifiers:
- px - pixels
- mm - millimeters
- pt - points (at the current resolution)
- % - percentage of the stage
* clutter/clutter-units.h: Fix the conversion macros
* tests/test-script.json: Test the new values.
2007-11-29 Emmanuele Bassi <ebassi@openedhand.com>
* clutter/clutter-model.[ch]: Slight API change in the constructor

View File

@ -150,10 +150,6 @@
#include "clutter-units.h"
#include "cogl.h"
G_DEFINE_ABSTRACT_TYPE (ClutterActor,
clutter_actor,
G_TYPE_INITIALLY_UNOWNED);
static guint32 __id = 0;
@ -220,11 +216,16 @@ enum
static guint actor_signals[LAST_SIGNAL] = { 0, };
static void
_clutter_actor_apply_modelview_transform (ClutterActor * self);
static void clutter_scriptable_iface_init (ClutterScriptableIface *iface);
static void
_clutter_actor_apply_modelview_transform_recursive (ClutterActor * self);
static void _clutter_actor_apply_modelview_transform (ClutterActor *self);
static void _clutter_actor_apply_modelview_transform_recursive (ClutterActor *self);
G_DEFINE_ABSTRACT_TYPE_WITH_CODE (ClutterActor,
clutter_actor,
G_TYPE_INITIALLY_UNOWNED,
G_IMPLEMENT_INTERFACE (CLUTTER_TYPE_SCRIPTABLE,
clutter_scriptable_iface_init));
static gboolean
redraw_update_idle (gpointer data)
@ -3764,6 +3765,149 @@ clutter_actor_set_anchor_point_from_gravity (ClutterActor *self,
priv->anchor_y = y;
}
typedef enum
{
PARSE_X,
PARSE_Y,
PARSE_WIDTH,
PARSE_HEIGHT
} ParseDimension;
static ClutterUnit
parse_units (ParseDimension dimension,
JsonNode *node)
{
GValue value = { 0, };
ClutterUnit retval = 0;
if (JSON_NODE_TYPE (node) != JSON_NODE_VALUE)
return 0;
json_node_get_value (node, &value);
if (G_VALUE_HOLDS (&value, G_TYPE_INT))
{
gint pixels = g_value_get_int (&value);
retval = CLUTTER_UNITS_FROM_DEVICE (pixels);
}
else if (G_VALUE_HOLDS (&value, G_TYPE_STRING))
{
gint64 val;
gchar *end;
val = g_ascii_strtoll (g_value_get_string (&value), &end, 10);
/* assume pixels */
if (*end == '\0')
{
retval = CLUTTER_UNITS_FROM_DEVICE (val);
goto out;
}
if (strcmp (end, "px") == 0)
{
retval = CLUTTER_UNITS_FROM_DEVICE (val);
goto out;
}
if (strcmp (end, "mm") == 0)
{
retval = CLUTTER_UNITS_FROM_MM (val);
goto out;
}
if (strcmp (end, "pt") == 0)
{
retval = CLUTTER_UNITS_FROM_POINTS (val);
goto out;
}
if (end[0] == '%' && end[1] == '\0')
{
if (dimension == PARSE_X || dimension == PARSE_WIDTH)
retval = CLUTTER_UNITS_FROM_STAGE_WIDTH_PERCENTAGE (val);
else
retval = CLUTTER_UNITS_FROM_STAGE_HEIGHT_PERCENTAGE (val);
goto out;
}
g_warning ("Invalid value `%s': integers, strings or floating point "
"values can be used for the x, y, width and height "
"properties. Valid modifiers for strings are `px', 'mm' "
"and '%%'.",
g_value_get_string (&value));
retval = 0;
}
else if (G_VALUE_HOLDS (&value, G_TYPE_DOUBLE))
{
gint val = CLAMP (g_value_get_double (&value) * 100, 0, 100);
if (dimension == PARSE_X || dimension == PARSE_WIDTH)
retval = CLUTTER_UNITS_FROM_STAGE_WIDTH_PERCENTAGE (val);
else
retval = CLUTTER_UNITS_FROM_STAGE_HEIGHT_PERCENTAGE (val);
}
else
{
g_warning ("Invalid value of type `%s': integers, strings of floating "
"point values can be used for the x, y, width and height "
"properties.",
g_type_name (G_VALUE_TYPE (&value)));
}
out:
g_value_unset (&value);
return retval;
}
static gboolean
clutter_actor_parse_custom_node (ClutterScriptable *scriptable,
ClutterScript *script,
GValue *value,
const gchar *name,
JsonNode *node)
{
gboolean retval = FALSE;
if ((name[0] == 'x' && name[1] == '\0') ||
(name[0] == 'y' && name[1] == '\0') ||
(strcmp (name, "width") == 0) ||
(strcmp (name, "height") == 0))
{
ClutterUnit units;
ParseDimension dimension;
if (name[0] == 'x')
dimension = PARSE_X;
else if (name[0] == 'y')
dimension = PARSE_Y;
else if (name[0] == 'w')
dimension = PARSE_WIDTH;
else
dimension = PARSE_HEIGHT;
units = parse_units (dimension, node);
/* convert back to pixels */
g_value_init (value, G_TYPE_INT);
g_value_set_int (value, CLUTTER_UNITS_TO_DEVICE (units));
retval = TRUE;
}
return retval;
}
static void
clutter_scriptable_iface_init (ClutterScriptableIface *iface)
{
iface->parse_custom_node = clutter_actor_parse_custom_node;
}
/*
* ClutterGeometry
*/

View File

@ -86,28 +86,28 @@ typedef gint32 ClutterUnit;
#define CLUTTER_UNITS_TO_PANGO_UNIT(x) ((x) >> 6)
#define CLUTTER_UNITS_FROM_STAGE_WIDTH_PERCENTAGE(x) \
((clutter_actor_get_widthu (clutter_stage_get_default ()) * x)/100)
((clutter_actor_get_widthu (clutter_stage_get_default ()) * x) / 100)
#define CLUTTER_UNITS_FROM_STAGE_HEIGHT_PERCENTAGE(x) \
((clutter_actor_get_heightu (clutter_stage_get_default ()) * x)/100)
((clutter_actor_get_heightu (clutter_stage_get_default ()) * x) / 100)
#define CLUTTER_UNITS_FROM_PARENT_WIDTH_PERCENTAGE(a, x) \
((clutter_actor_get_widthu (clutter_actor_get_parent (a)) * x)/100)
((clutter_actor_get_widthu (clutter_actor_get_parent (a)) * x) / 100)
#define CLUTTER_UNITS_FROM_PARENT_HEIGHT_PERCENTAGE(a, x) \
((clutter_actor_get_heightu (clutter_actor_get_parent (a)) * x)/100)
((clutter_actor_get_heightu (clutter_actor_get_parent (a)) * x) / 100)
#define CLUTTER_UNITS_FROM_MM(x) \
CLUTTER_UNITS_FROM_FLOAT(((x*clutter_stage_get_resolution (clutter_stage_get_default ())) / 25.4))
(CLUTTER_UNITS_FROM_FLOAT ((((x) * clutter_stage_get_resolution ((ClutterStage *) clutter_stage_get_default ())) / 25.4)))
#define CLUTTER_UNITS_FROM_MMX(x) \
CFX_DIV(CFX_MUL(x,clutter_stage_get_resolutionx(clutter_stage_get_default())),0x196666)
(CFX_DIV (CFX_MUL ((x), clutter_stage_get_resolutionx ((ClutterStage *) clutter_stage_get_default ())), 0x196666))
#define CLUTTER_UNITS_FROM_POINTS(x) \
CLUTTER_UNITS_FROM_FLOAT(((x*clutter_stage_get_resolution(clutter_stage_get_default()))/72.0))
CLUTTER_UNITS_FROM_FLOAT ((((x) * clutter_stage_get_resolution ((ClutterStage *) clutter_stage_get_default ())) / 72.0))
#define CLUTTER_UNITS_FROM_POINTSX(x) \
(CFX_MUL(x,clutter_stage_get_resolutionx(clutter_stage_get_default()))/72)
(CFX_MUL ((x), clutter_stage_get_resolutionx ((ClutterStage *) clutter_stage_get_default ())) / 72)
G_END_DECLS

View File

@ -4,7 +4,7 @@
"type" : "ClutterStage",
"color" : "white",
"width" : 500,
"height" : 400,
"height" : "400px",
"signals" : [
{ "name" : "key-press-event", "handler" : "clutter_main_quit" }
],
@ -38,10 +38,10 @@
"id" : "red-hand",
"type" : "ClutterTexture",
"pixbuf" : "redhand.png",
"x" : 50,
"y" : 150,
"width" : 100,
"height" : 100,
"x" : "50%",
"y" : "50%",
"width" : "20mm",
"height" : "100px",
"opacity" : 100,
"visible" : true,
"behaviours" : [ "rotate-behaviour", "fade-behaviour" ]