From 6c40b100839e3597e9ab5f1d3e32c9d42d1af87c Mon Sep 17 00:00:00 2001 From: Elliot Smith Date: Tue, 31 Aug 2010 14:39:03 +0100 Subject: [PATCH] cookbook: Added recipe for signal handling in ClutterScript Added a recipe explaining how to connect signals to handlers in the JSON definition used by ClutterScript; also shows how to connect the signals in code once the JSON has been loaded. Includes guidelines on writing handlers (i.e. need to use -export-dynamic and non-static functions) and example which connects a handler for motion events on a rectangle. --- doc/cookbook/script.xml | 266 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 266 insertions(+) diff --git a/doc/cookbook/script.xml b/doc/cookbook/script.xml index 690f57028..96a652210 100644 --- a/doc/cookbook/script.xml +++ b/doc/cookbook/script.xml @@ -461,4 +461,270 @@ ClutterStage *stage = CLUTTER_STAGE (clutter_script_get_object (script, "stage)) +
+ Connecting to signals in <type>ClutterScript</type> + +
+ Problem + + You have declared an actor using JSON, and want to add + handlers for signals emitted by it. +
+ +
+ Solution + + Add a signals property to the actor's + JSON definition. + + Here's how to connect a ClutterStage's + destroy signal to the + clutter_main_quit() function: + + + +{ + "id" : "stage", + "type" : "ClutterStage", + "width" : 300, + "height" : 300, + + "signals" : [ + { "name" : "destroy", "handler" : "clutter_main_quit" } + ] +} + + + + The highlighted part of the code is where the + signal is connected. In this case, a Clutter function is used + as the handler; in most cases, you'll want to define your own + handlers, rather than using functions from other libraries, + as follows: + + + +{ + "id" : "rectangle", + "type" : "ClutterRectangle", + "width" : 200, + "height" : 200, + "reactive" : true, + + "signals" : [ + { "name" : "motion-event", "handler" : "foo_pointer_motion_cb" } + ] +} + + + + This signal handler definition sets + foo_pointer_motion_cb() + as the handler for the motion-event + signal on the rectangle. (NB the rectangle has + reactive set to true, otherwise it + can't emit this signal.) + + As per standard event handling in Clutter, + you define the handler function next. For example: + + + + + + + + + See the + Discussion + section for more about writing handler functions. + + + To make the signal connections active in your code, + call the clutter_script_connect_signals() + function after loading the JSON: + + + + + + + +
+ +
+ Discussion + +
+ Options for connecting signals to handlers + + Every connection between a signal and handler requires + a JSON object with name and + handler keys. The name + is the name of the signal you're connecting a handler to; the + handler is the name of the function which + will handle the signal. + + You can also specify these optional keys for a handler + object: + + + + "after" : true configures the handler + to run after the default handler for the signal. (Default is + "after" : false). + + + "swapped" : true specifies that + the instance and the user data passed to the + handler function are swapped around; i.e. the instance emitting + the signal is passed in as the user data argument (usually the + last argument), and any user data is passed in as the first + argument. (Default is "swapped" : false). + + + + + While the connections to signals were specified in JSON + above, it is still possible to connect handlers to signals in + code (e.g. if you need to conditionally connect a handler). Just + retrieve the object from the ClutterScript and + connect to its signals with + g_signal_connect(). + + +
+ +
+ Writing handler functions + + The handler function has the usual signature required + for the signal. However, the function cannot be static, otherwise + the function is invisible to GModule (the mechanism used by + ClutterScript to look up functions named + in the JSON definition). Consequently, callback functions should be + namespaced in such a way that they won't clash with function + definitions in other parts of your code or in libraries you link + to. + + You should also ensure that you use the + flag when you compile your + application: either by passing it on the command line (if you're + calling gcc directly); or by adding + it to the appropriate LDFLAGS variable in + your Makefile (if you're using + make); or by whatever other mechanism is + appropriate for your build environment. + +
+ +
+ Passing objects to handler functions + + In a typical Clutter application, handler functions + require access to objects other than the one which emitted a + signal. For example, a button may move another actor when + clicked. Typically, you would pass any required objects + to the handler function as user data, like this: + + + +g_signal_connect (button, + "clicked", + G_CALLBACK (_button_clicked_cb), + actor_to_move); + + + + Note how actor_to_move is passed + as user data to the handler. + + However, the JSON definition doesn't allow you to specify + that different user data be passed to different handlers. So, + to get at all required objects in the handler, a simple + solution is to pass the ClutterScript to + every handler function; then inside + each handler function, retrieve + the required objects from the script. + + This was done in the code example above, by passing + the ClutterScript instance as two arguments to + clutter_script_connect_signals(): + the first argument specifies the script which defines the + signal handlers; the second specifies the user data passed to every + handler function. This ensures that each handler has access + to all of the elements defined in the JSON file. + + + Alternatively, you could create some other structure to + hold the objects you need and pass it to all handler functions. + But this would effectively be a reimplementation of some aspects + of ClutterScript. + + +
+ +
+ +
+ Full examples + + + <type>ClutterScript</type> JSON with signal handler + definitions + + + a code sample should be here... but isn't + + + + + + Loading a JSON file into a <type>ClutterScript</type> + and connecting signal handlers + + + a code sample should be here... but isn't + + + + +
+ +
+