--- /dev/null
+#include <stdlib.h>
+#include <clutter/clutter.h>
+
+/* callbacks cannot be declared static as they
+ * are looked up dynamically by ClutterScript
+ */
+gboolean
+foo_pointer_motion_cb (ClutterActor *actor,
+ ClutterEvent *event,
+ gpointer user_data)
+{
+ gfloat x, y;
+ clutter_event_get_coords (event, &x, &y);
+
+ g_print ("Pointer movement at %.0f,%.0f\n", x, y);
+
+ return TRUE;
+}
+
+void
+foo_button_clicked_cb (ClutterClickAction *action,
+ ClutterActor *actor,
+ gpointer user_data)
+{
+ /* get the UI definition passed to the handler */
+ ClutterScript *ui = CLUTTER_SCRIPT (user_data);
+
+ /* get the rectangle defined in the JSON */
+ ClutterActor *rectangle;
+ clutter_script_get_objects (ui,
+ "rectangle", &rectangle,
+ NULL);
+
+ /* do nothing if the actor is already animating */
+ if (clutter_actor_get_animation (rectangle) != NULL)
+ return;
+
+ /* get the current rotation and increment it */
+ gfloat z_angle;
+ z_angle = clutter_actor_get_rotation (rectangle,
+ CLUTTER_Z_AXIS,
+ NULL, NULL, NULL);
+
+ z_angle += 90.0;
+
+ /* animate to new rotation angle */
+ clutter_actor_animate (rectangle,
+ CLUTTER_EASE_OUT_CUBIC,
+ 1000,
+ "rotation-angle-z", z_angle,
+ NULL);
+}
+
+int
+main (int argc, char *argv[])
+{
+ clutter_init (&argc, &argv);
+
+ ClutterScript *ui = clutter_script_new ();
+
+ gchar *filename = "script-signals.json";
+ GError *error = NULL;
+
+ clutter_script_load_from_file (ui, filename, &error);
+
+ if (error != NULL)
+ {
+ g_critical ("Error loading ClutterScript file %s\n%s", filename, error->message);
+ g_error_free (error);
+ exit (EXIT_FAILURE);
+ }
+
+ ClutterActor *stage;
+ clutter_script_get_objects (ui,
+ "stage", &stage,
+ NULL);
+
+ /* make the objects in the script available to all signals
+ * by passing the script as the second argument
+ * to clutter_script_connect_signals()
+ */
+ clutter_script_connect_signals (ui, ui);
+
+ clutter_actor_show (stage);
+
+ clutter_main ();
+
+ g_object_unref (ui);
+
+ return EXIT_SUCCESS;
+}
--- /dev/null
+[
+ {
+ "id" : "stage",
+ "type" : "ClutterStage",
+ "width" : 300,
+ "height" : 300,
+ "color" : "#335",
+
+ "signals" : [
+ { "name" : "destroy", "handler" : "clutter_main_quit" }
+ ],
+
+ "children" : [ "rectangle" ]
+ },
+
+ {
+ "id" : "rectangle",
+ "type" : "ClutterRectangle",
+ "width" : 200,
+ "height" : 200,
+ "x" : 50,
+ "y" : 50,
+ "color" : "#a90",
+ "rotation-center-z-gravity" : "center",
+ "reactive" : true,
+
+ "signals" : [
+ { "name" : "motion-event", "handler" : "foo_pointer_motion_cb" }
+ ],
+
+ "actions" : [
+ {
+ "type" : "ClutterClickAction",
+ "signals" : [
+ { "name" : "clicked", "handler" : "foo_button_clicked_cb" }
+ ]
+ }
+ ]
+ }
+]