+2006-12-04 Emmanuele Bassi <ebassi@openedhand.com>
+
+ * clutter/clutter-private.h: Add our own READABLE,
+ WRITABLE and READWRITE paramspec flags, declaring the
+ string components of the properties GParamSpec as static;
+ this should shave off some bytes in the memory footprint
+ and avoid relocations.
+
+ * clutter/clutter-actor.c:
+ * clutter/clutter-behaviour.c:
+ * clutter/clutter-behaviour-opacity.c:
+ * clutter/clutter-behaviour-path.c:
+ * clutter/clutter-behavuour-scale.c:
+ * clutter/clutter-clone-texture.c:
+ * clutter/clutter-label.c:
+ * clutter/clutter-rectangle.c:
+ * clutter/clutter-stage.c:
+ * clutter/clutter-texture.c:
+ * clutter/clutter-timeline.c: Use the CLUTTER_PARAM_*
+ macros we just added.
+
+ * clutter/clutter-behaviour-scale.c: Add properties for
+ the scale begin, scale end and gravity parameters.
+
+ * clutter/clutter-behaviour-path.h: Mark the ClutterKnot
+ memory management functions as public (for the bindings),
+ since we use the slice allocator for copying knots around;
+ add a clutter_knot_equal() function.
+
+ * clutter/clutter-behaviour-path.c:
+ (node_distance): Use clutter_knot_equal() as a fast path
+ to avoid the sqrt() in case the nodes we are using are
+ at the same position.
+ (path_total_length): Additional check on the existence
+ of the next node.
+
+ * examples/behave.c: Do not leak the ClutterBehaviour
+ objects around.
+
2006-12-03 Emmanuele Bassi <ebassi@openedhand.com>
* clutter/clutter-texture.h: Clean up.
#include "clutter-enum-types.h"
#include "clutter-marshal.h"
#include "clutter-private.h"
+#include "clutter-debug.h"
G_DEFINE_ABSTRACT_TYPE (ClutterActor,
clutter_actor,
"X co-ord of actor",
0, G_MAXINT,
0,
- G_PARAM_READWRITE));
+ CLUTTER_PARAM_READWRITE));
/**
* ClutterActor:y:
*
"Y co-ord of actor",
0, G_MAXINT,
0,
- G_PARAM_READWRITE));
+ CLUTTER_PARAM_READWRITE));
/**
* ClutterActor:width:
*
"Width of actor in pixels",
0, G_MAXINT,
0,
- G_PARAM_READWRITE));
+ CLUTTER_PARAM_READWRITE));
/**
* ClutterActor:height:
*
"Height of actor in pixels",
0, G_MAXINT,
0,
- G_PARAM_READWRITE));
+ CLUTTER_PARAM_READWRITE));
/**
* ClutterActor:opacity:
*
"Opacity of actor",
0, 0xff,
0xff,
- G_PARAM_CONSTRUCT | G_PARAM_READWRITE));
+ G_PARAM_CONSTRUCT | CLUTTER_PARAM_READWRITE));
/**
* ClutterActor:visible:
*
"Visible",
"Whether the actor is visible or not",
FALSE,
- G_PARAM_READWRITE));
+ CLUTTER_PARAM_READWRITE));
/**
* ClutterActor:has-clip:
*
"Has Clip",
"Whether the actor has a clip set or not",
FALSE,
- G_PARAM_READABLE));
+ CLUTTER_PARAM_READABLE));
/**
* ClutterActor:clip:
*
"Clip",
"The clip region for the actor",
CLUTTER_TYPE_GEOMETRY,
- G_PARAM_READWRITE));
+ CLUTTER_PARAM_READWRITE));
/**
* ClutterActor:name:
*
"Name",
"Name of the actor",
NULL,
- G_PARAM_READWRITE));
+ CLUTTER_PARAM_READWRITE));
/**
* ClutterActor::destroy:
"Timeline",
"Timeline",
CLUTTER_TYPE_TIMELINE,
- G_PARAM_READWRITE));
+ CLUTTER_PARAM_READWRITE));
/**
* ClutterAlpha:alpha:
*
0,
CLUTTER_ALPHA_MAX_ALPHA,
0,
- G_PARAM_READABLE));
+ CLUTTER_PARAM_READABLE));
}
static void
"Initial opacity level",
0, 255,
0,
- G_PARAM_READWRITE |
+ CLUTTER_PARAM_READWRITE |
G_PARAM_CONSTRUCT));
/**
"Final opacity level",
0, 255,
0,
- G_PARAM_READWRITE |
+ CLUTTER_PARAM_READWRITE |
G_PARAM_CONSTRUCT));
behave_class->alpha_notify = clutter_behaviour_alpha_notify;
#include "clutter-enum-types.h"
#include "clutter-main.h"
#include "clutter-behaviour-path.h"
+#include "clutter-private.h"
+#include "clutter-debug.h"
#include <math.h>
-static ClutterKnot *
+ClutterKnot *
clutter_knot_copy (const ClutterKnot *knot)
{
ClutterKnot *copy;
return copy;
}
-static void
+void
clutter_knot_free (ClutterKnot *knot)
{
if (G_LIKELY (knot))
}
}
+gboolean
+clutter_knot_equal (const ClutterKnot *knot_a,
+ const ClutterKnot *knot_b)
+{
+ g_return_val_if_fail (knot_a != NULL, FALSE);
+ g_return_val_if_fail (knot_b != NULL, FALSE);
+
+ return knot_a->x == knot_b->x && knot_a->y == knot_b->y;
+}
+
GType
clutter_knot_get_type (void)
{
static GType our_type = 0;
if (G_UNLIKELY (!our_type))
- our_type = g_boxed_type_register_static
- ("ClutterKnot",
- (GBoxedCopyFunc) clutter_knot_copy,
- (GBoxedFreeFunc) clutter_knot_free);
+ {
+ our_type =
+ g_boxed_type_register_static ("ClutterKnot",
+ (GBoxedCopyFunc) clutter_knot_copy,
+ (GBoxedFreeFunc) clutter_knot_free);
+ }
+
return our_type;
}
g_return_val_if_fail (begin != NULL, 0);
g_return_val_if_fail (end != NULL, 0);
+ if (clutter_knot_equal (begin, end))
+ return 0;
+
/* FIXME: need fixed point here */
return sqrt ((end->x - begin->x) * (end->x - begin->x) +
(end->y - begin->y) * (end->y - begin->y));
gint len = 0;
for (l = behave->priv->knots; l != NULL; l = l->next)
- if (l->next)
+ if (l->next && l->next->data)
len += node_distance (l->data, l->next->data);
return len;
"Knot",
"Can be used to append a knot to the path",
CLUTTER_TYPE_KNOT,
- G_PARAM_WRITABLE));
+ CLUTTER_PARAM_WRITABLE));
/**
* ClutterBehaviourPath::knot-reached:
/* FIXME: optionally include bezier control points also ? */
};
-GType clutter_knot_get_type (void) G_GNUC_CONST;
+GType clutter_knot_get_type (void) G_GNUC_CONST;
+ClutterKnot *clutter_knot_copy (const ClutterKnot *knot);
+void clutter_knot_free (ClutterKnot *knot);
+gboolean clutter_knot_equal (const ClutterKnot *knot_a,
+ const ClutterKnot *knot_b);
#define CLUTTER_TYPE_BEHAVIOUR_PATH (clutter_behaviour_path_get_type ())
CLUTTER_TYPE_BEHAVIOUR_SCALE, \
ClutterBehaviourScalePrivate))
+enum
+{
+ PROP_0,
+
+ PROP_SCALE_BEGIN,
+ PROP_SCALE_END,
+ PROP_SCALE_GRAVITY
+};
+
static void
scale_frame_foreach (ClutterActor *actor,
ClutterBehaviourScale *behave)
}
static void
+clutter_behaviour_scale_set_property (GObject *gobject,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ ClutterBehaviourScalePrivate *priv;
+
+ priv = CLUTTER_BEHAVIOUR_SCALE (gobject)->priv;
+
+ switch (prop_id)
+ {
+ case PROP_SCALE_BEGIN:
+ priv->scale_begin = CLUTTER_FLOAT_TO_FIXED (g_value_get_double (value));
+ break;
+ case PROP_SCALE_END:
+ priv->scale_end = CLUTTER_FLOAT_TO_FIXED (g_value_get_double (value));
+ break;
+ case PROP_SCALE_GRAVITY:
+ priv->gravity = g_value_get_enum (value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+clutter_behaviour_scale_get_property (GObject *gobject,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ ClutterBehaviourScalePrivate *priv;
+
+ priv = CLUTTER_BEHAVIOUR_SCALE (gobject)->priv;
+
+ switch (prop_id)
+ {
+ case PROP_SCALE_BEGIN:
+ g_value_set_double (value, CLUTTER_FIXED_TO_FLOAT (priv->scale_begin));
+ break;
+ case PROP_SCALE_END:
+ g_value_set_double (value, CLUTTER_FIXED_TO_FLOAT (priv->scale_end));
+ break;
+ case PROP_SCALE_GRAVITY:
+ g_value_set_enum (value, priv->gravity);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
+ break;
+ }
+}
+
+static void
clutter_behaviour_scale_class_init (ClutterBehaviourScaleClass *klass)
{
- ClutterBehaviourClass *behave_class;
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+ ClutterBehaviourClass *behave_class = CLUTTER_BEHAVIOUR_CLASS (klass);
+
+ gobject_class->set_property = clutter_behaviour_scale_set_property;
+ gobject_class->get_property = clutter_behaviour_scale_get_property;
+
+ /**
+ * ClutterBehaviourScale:scale-begin:
+ *
+ * The initial scaling factor for the actors.
+ *
+ * Since: 0.2
+ */
+ g_object_class_install_property (gobject_class,
+ PROP_SCALE_BEGIN,
+ g_param_spec_double ("scale-begin",
+ "Scale Begin",
+ "Initial scale",
+ 1.0, G_MAXDOUBLE,
+ 1.0,
+ CLUTTER_PARAM_READWRITE));
+ /**
+ * ClutterBehaviourScale:scale-end:
+ *
+ * The final scaling factor for the actors.
+ *
+ * Since: 0.2
+ */
+ g_object_class_install_property (gobject_class,
+ PROP_SCALE_END,
+ g_param_spec_double ("scale-end",
+ "Scale End",
+ "Final scale",
+ 1.0, G_MAXDOUBLE,
+ 1.0,
+ CLUTTER_PARAM_READWRITE));
+ /**
+ * ClutterBehaviourScale:gravity:
+ *
+ * The gravity of the scaling.
+ *
+ * Since: 0.2
+ */
+ g_object_class_install_property (gobject_class,
+ PROP_SCALE_GRAVITY,
+ g_param_spec_enum ("scale-gravity",
+ "Scale Gravity",
+ "The gravity of the scaling",
+ CLUTTER_TYPE_GRAVITY,
+ CLUTTER_GRAVITY_CENTER,
+ CLUTTER_PARAM_READWRITE));
- behave_class = (ClutterBehaviourClass*) klass;
behave_class->alpha_notify = clutter_behaviour_scale_alpha_notify;
* (or properties) of every actor controlled by the behaviour.
*/
+#ifdef HAVE_CONFIG_H
#include "config.h"
+#endif
+#include "clutter-main.h"
#include "clutter-actor.h"
#include "clutter-behaviour.h"
+#include "clutter-debug.h"
+#include "clutter-private.h"
G_DEFINE_ABSTRACT_TYPE (ClutterBehaviour,
clutter_behaviour,
"Alpha Object to drive the behaviour",
CLUTTER_TYPE_ALPHA,
G_PARAM_CONSTRUCT |
- G_PARAM_READWRITE));
+ CLUTTER_PARAM_READWRITE));
g_type_class_add_private (klass, sizeof (ClutterBehaviourPrivate));
}
"Parent Texture",
"The parent texture to clone",
CLUTTER_TYPE_TEXTURE,
- (G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE)));
+ (G_PARAM_CONSTRUCT_ONLY | CLUTTER_PARAM_READWRITE)));
g_type_class_add_private (gobject_class, sizeof (ClutterCloneTexturePrivate));
}
"Font Name",
"Pango font description",
NULL,
- G_PARAM_CONSTRUCT | G_PARAM_READWRITE));
+ G_PARAM_CONSTRUCT | CLUTTER_PARAM_READWRITE));
g_object_class_install_property
(gobject_class, PROP_TEXT,
"Text",
"Text to render",
NULL,
- G_PARAM_CONSTRUCT | G_PARAM_READWRITE));
+ G_PARAM_CONSTRUCT | CLUTTER_PARAM_READWRITE));
g_object_class_install_property
(gobject_class, PROP_COLOR,
"Font Colour",
"Font Colour",
CLUTTER_TYPE_COLOR,
- G_PARAM_READWRITE));
+ CLUTTER_PARAM_READWRITE));
g_object_class_install_property
(gobject_class, PROP_ATTRIBUTES,
"A list of style attributes to apply to the"
"text of the label",
PANGO_TYPE_ATTR_LIST,
- G_PARAM_READWRITE));
+ CLUTTER_PARAM_READWRITE));
g_object_class_install_property
(gobject_class, PROP_USE_MARKUP,
"The text of the label includes XML markup."
"See pango_parse_markup()",
FALSE,
- G_PARAM_READWRITE));
+ CLUTTER_PARAM_READWRITE));
g_object_class_install_property
(gobject_class, PROP_WRAP,
"Line wrap",
"If set, wrap lines if the text becomes too wide",
TRUE,
- G_PARAM_READWRITE));
+ CLUTTER_PARAM_READWRITE));
g_object_class_install_property
(gobject_class, PROP_WRAP_MODE,
"If wrap is set, controls how linewrapping is done",
PANGO_TYPE_WRAP_MODE,
PANGO_WRAP_WORD,
- G_PARAM_READWRITE));
+ CLUTTER_PARAM_READWRITE));
g_object_class_install_property
(gobject_class, PROP_ELLIPSIZE,
"display the entire string",
PANGO_TYPE_ELLIPSIZE_MODE,
PANGO_ELLIPSIZE_NONE,
- G_PARAM_READWRITE));
+ CLUTTER_PARAM_READWRITE));
g_object_class_install_property
(gobject_class, PROP_ALIGNMENT,
"The preferred alignment for the string,",
PANGO_TYPE_ALIGNMENT,
PANGO_ALIGN_LEFT,
- G_PARAM_READWRITE));
+ CLUTTER_PARAM_READWRITE));
g_type_class_add_private (gobject_class, sizeof (ClutterLabelPrivate));
}
#include <pango/pangoft2.h>
-#include <clutter/clutter-debug.h>
-
G_BEGIN_DECLS
typedef struct _ClutterMainContext ClutterMainContext;
void clutter_feature_init (void);
+#define CLUTTER_PARAM_READABLE \
+ G_PARAM_READABLE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB
+#define CLUTTER_PARAM_WRITABLE \
+ G_PARAM_WRITABLE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB
+#define CLUTTER_PARAM_READWRITE \
+ G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK |G_PARAM_STATIC_BLURB
+
G_END_DECLS
#endif
"Color",
"The color of the rectangle",
CLUTTER_TYPE_COLOR,
- G_PARAM_READWRITE));
+ CLUTTER_PARAM_READWRITE));
/**
* ClutterRectangle:border-color:
*
"Border Color",
"The color of the border of the rectangle",
CLUTTER_TYPE_COLOR,
- G_PARAM_READWRITE));
+ CLUTTER_PARAM_READWRITE));
/**
* ClutterRectangle:border-width:
*
"The width of the border of the rectangle",
0, G_MAXUINT,
0,
- G_PARAM_READWRITE));
+ CLUTTER_PARAM_READWRITE));
/**
* ClutterRectangle:has-border:
*
"Has Border",
"Whether the rectangle should have a border",
FALSE,
- G_PARAM_READWRITE));
+ CLUTTER_PARAM_READWRITE));
g_type_class_add_private (gobject_class, sizeof (ClutterRectanglePrivate));
}
"Fullscreen",
"Make Clutter stage fullscreen",
FALSE,
- G_PARAM_CONSTRUCT | G_PARAM_READWRITE));
+ G_PARAM_CONSTRUCT | CLUTTER_PARAM_READWRITE));
g_object_class_install_property
(gobject_class, PROP_OFFSCREEN,
"Offscreen",
"Make Clutter stage offscreen",
FALSE,
- G_PARAM_CONSTRUCT | G_PARAM_READWRITE));
+ G_PARAM_CONSTRUCT | CLUTTER_PARAM_READWRITE));
g_object_class_install_property
"Hide Cursor",
"Make Clutter stage cursor-less",
FALSE,
- G_PARAM_CONSTRUCT | G_PARAM_READWRITE));
+ G_PARAM_CONSTRUCT | CLUTTER_PARAM_READWRITE));
g_object_class_install_property
(gobject_class, PROP_COLOR,
"Color",
"The color of the stage",
CLUTTER_TYPE_COLOR,
- G_PARAM_READWRITE));
+ CLUTTER_PARAM_READWRITE));
stage_signals[INPUT_EVENT] =
g_signal_new ("input-event",
g_param_spec_pointer ("pixbuf",
"Pixbuf source for Texture.",
"Pixbuf source for Texture.",
- G_PARAM_READWRITE));
+ CLUTTER_PARAM_READWRITE));
g_object_class_install_property
(gobject_class, PROP_USE_TILES,
*/
(clutter_feature_available
(CLUTTER_FEATURE_TEXTURE_RECTANGLE) == FALSE),
- G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE));
+ G_PARAM_CONSTRUCT_ONLY | CLUTTER_PARAM_READWRITE));
g_object_class_install_property
(gobject_class, PROP_SYNC_SIZE,
"Auto sync size of actor to underlying pixbuf"
"dimentions",
TRUE,
- G_PARAM_CONSTRUCT | G_PARAM_READWRITE));
+ G_PARAM_CONSTRUCT | CLUTTER_PARAM_READWRITE));
g_object_class_install_property
(gobject_class, PROP_REPEAT_X,
"Reapeat underlying pixbuf rather than scale"
"in x direction. Currently UNWORKING",
FALSE,
- G_PARAM_CONSTRUCT | G_PARAM_READWRITE));
+ G_PARAM_CONSTRUCT | CLUTTER_PARAM_READWRITE));
g_object_class_install_property
(gobject_class, PROP_REPEAT_Y,
"Reapeat underlying pixbuf rather than scale"
"in y direction. Currently UNWORKING",
FALSE,
- G_PARAM_CONSTRUCT | G_PARAM_READWRITE));
+ G_PARAM_CONSTRUCT | CLUTTER_PARAM_READWRITE));
/* FIXME: Ideally this option needs to have some kind of global
* overide as to imporve performance.
0,
G_MAXINT,
1,
- G_PARAM_CONSTRUCT | G_PARAM_READWRITE));
+ G_PARAM_CONSTRUCT | CLUTTER_PARAM_READWRITE));
g_object_class_install_property
(gobject_class, PROP_MAX_TILE_WASTE,
0,
G_MAXINT,
64,
- G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE));
+ G_PARAM_CONSTRUCT_ONLY | CLUTTER_PARAM_READWRITE));
g_object_class_install_property
(gobject_class, PROP_PIXEL_TYPE,
0,
G_MAXINT,
PIXEL_TYPE,
- G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE));
+ G_PARAM_CONSTRUCT_ONLY | CLUTTER_PARAM_READWRITE));
g_object_class_install_property
(gobject_class, PROP_PIXEL_FORMAT,
0,
G_MAXINT,
GL_RGBA,
- G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE));
+ G_PARAM_CONSTRUCT_ONLY | CLUTTER_PARAM_READWRITE));
texture_signals[SIGNAL_SIZE_CHANGE] =
g_signal_new ("size-change",
0,
1000,
50,
- G_PARAM_CONSTRUCT | G_PARAM_READWRITE));
+ G_PARAM_CONSTRUCT | CLUTTER_PARAM_READWRITE));
g_object_class_install_property
(object_class, PROP_NUM_FRAMES,
0,
G_MAXINT,
0,
- G_PARAM_READWRITE));
+ CLUTTER_PARAM_READWRITE));
g_object_class_install_property
(object_class, PROP_LOOP,
"Loop",
"Should the timeline automatically restart",
FALSE,
- G_PARAM_CONSTRUCT | G_PARAM_READWRITE));
+ G_PARAM_CONSTRUCT | CLUTTER_PARAM_READWRITE));
timeline_signals[NEW_FRAME] =
g_signal_new ("new-frame",
{
ClutterTimeline *timeline;
ClutterAlpha *alpha;
- ClutterBehaviour *behave;
+ ClutterBehaviour *o_behave, *p_behave;
ClutterActor *stage;
ClutterActor *group, *rect, *hand;
ClutterColor stage_color = { 0xcc, 0xcc, 0xcc, 0xff };
NULL, NULL);
/* Create a behaviour for that alpha */
- behave = clutter_behaviour_opacity_new (alpha, 0X33, 0xff);
+ o_behave = clutter_behaviour_opacity_new (alpha, 0X33, 0xff);
/* Apply it to our actor */
- clutter_behaviour_apply (behave, group);
+ clutter_behaviour_apply (o_behave, group);
/* Make a path behaviour and apply that too */
- behave = clutter_behaviour_path_new (alpha, knots, 5);
- clutter_behaviour_apply (behave, group);
+ p_behave = clutter_behaviour_path_new (alpha, knots, 5);
+ clutter_behaviour_apply (p_behave, group);
/* start the timeline and thus the animations */
clutter_timeline_start (timeline);
clutter_main();
+ g_object_unref (o_behave);
+ g_object_unref (p_behave);
+
return 0;
}