/usr/share/gtk-doc/html/clutter-cookbook/script-signals.html is in libclutter-1.0-doc 1.20.0-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 | <html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"><title>3. Connecting to signals in ClutterScript</title><link rel="stylesheet" type="text/css" href="style.css"><meta name="generator" content="DocBook XSL Stylesheets V1.78.1"><link rel="home" href="index.html" title="The Clutter Cookbook"><link rel="up" href="script.html" title="Chapter 8. Script"><link rel="prev" href="script-ui.html" title="2. Defining a user interface with JSON"><link rel="next" href="script-state.html" title="4. Connecting ClutterState states in ClutterScript"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">3. Connecting to signals in <span class="type">ClutterScript</span></th></tr><tr><td width="20%" align="left"><a accesskey="p" href="script-ui.html">Prev</a> </td><th width="60%" align="center">Chapter 8. Script</th><td width="20%" align="right"> <a accesskey="n" href="script-state.html">Next</a></td></tr></table><hr></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="script-signals"></a>3. Connecting to signals in <span class="type">ClutterScript</span></h2></div></div></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a name="idp73882160"></a>3.1. Problem</h3></div></div></div><p>You have declared an actor using JSON, and want to add
handlers for signals emitted by it.</p></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a name="idp73883584"></a>3.2. Solution</h3></div></div></div><p>Add a <code class="varname">signals</code> property to the actor's
JSON definition.</p><p>Here's how to connect a <span class="type">ClutterStage's</span>
<code class="code">destroy</code> signal to the
<code class="function">clutter_main_quit()</code> function:</p><div class="informalexample"><pre class="programlisting">{
"id" : "stage",
"type" : "ClutterStage",
"width" : 300,
"height" : 300,
<span class="emphasis"><em>"signals" : [
{ "name" : "destroy", "handler" : "clutter_main_quit" }
]</em></span>
}</pre></div><p>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:</p><div class="informalexample"><pre class="programlisting">{
"id" : "rectangle",
"type" : "ClutterRectangle",
"width" : 200,
"height" : 200,
"reactive" : true,
<span class="emphasis"><em>"signals" : [
{ "name" : "motion-event", "handler" : "foo_pointer_motion_cb" }
]</em></span>
}</pre></div><p>This signal handler definition sets
<code class="function">foo_pointer_motion_cb()</code>
as the handler for the <code class="code">motion-event</code>
signal on the rectangle. (NB the rectangle has
<code class="varname">reactive</code> set to true, otherwise it
can't emit this signal.)</p><p>As per standard event handling in Clutter,
you define the handler function next. For example:</p><div class="informalexample"><pre class="programlisting">/* handler which just prints the position of the pointer at each motion event */
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;
}</pre></div><div class="note" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Note</h3><p>See the
<a class="link" href="script-signals.html#script-signals-discussion-writing-handlers" title="3.3.2. Writing handler functions">Discussion</a>
section for more about writing handler functions.</p></div><p>To make the signal connections active in your code,
call the <code class="function">clutter_script_connect_signals()</code>
function after loading the JSON:</p><div class="informalexample"><pre class="programlisting">GError *error = NULL;
/* load JSON from a file */
ClutterScript *ui = clutter_script_new ();
clutter_script_load_from_file (ui, filename, &error);
/* ...handle errors etc... */
/* connect the signals defined in the JSON file
*
* the first argument is the script into which the JSON
* definition was loaded
*
* the second argument is passed as user_data to all
* handlers: in this case, we pass the script as user_data
* to all handlers, so that all the objects in the UI
* are available to callback functions
*/
clutter_script_connect_signals (ui, ui);</pre></div></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a name="script-signals-discussion"></a>3.3. Discussion</h3></div></div></div><div class="section"><div class="titlepage"><div><div><h4 class="title"><a name="idp73901280"></a>3.3.1. Options for connecting signals to handlers</h4></div></div></div><p>Every connection between a signal and handler requires
a JSON object with <code class="varname">name</code> and
<code class="varname">handler</code> keys. The <code class="varname">name</code>
is the name of the signal you're connecting a handler to; the
<code class="varname">handler</code> is the name of the function which
will handle the signal.</p><p>You can also specify these optional keys for a handler
object:</p><div class="orderedlist"><ol class="orderedlist" type="1"><li class="listitem"><p><code class="code">"after" : true</code> configures the handler
to run after the default handler for the signal. (Default is
<code class="code">"after" : false</code>).</p></li><li class="listitem"><p><code class="varname">"swapped" : true</code> 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 <code class="code">"swapped" : false</code>).</p></li></ol></div><div class="note" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Note</h3><p>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 <span class="type">ClutterScript</span> and
connect to its signals with
<code class="function">g_signal_connect()</code>.</p></div></div><div class="section"><div class="titlepage"><div><div><h4 class="title"><a name="script-signals-discussion-writing-handlers"></a>3.3.2. Writing handler functions</h4></div></div></div><p>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
<span class="type">ClutterScript</span> 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.</p><p>You should also ensure that you use the
<code class="option">-export-dynamic</code> flag when you compile your
application: either by passing it on the command line (if you're
calling <span class="command"><strong>gcc</strong></span> directly); or by adding
it to the appropriate <code class="varname">LDFLAGS</code> variable in
your <code class="filename">Makefile</code> (if you're using
<span class="command"><strong>make</strong></span>); or by whatever other mechanism is
appropriate for your build environment.</p></div><div class="section"><div class="titlepage"><div><div><h4 class="title"><a name="idp74135040"></a>3.3.3. Passing objects to handler functions</h4></div></div></div><p>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:</p><div class="informalexample"><pre class="programlisting">g_signal_connect (button,
"clicked",
G_CALLBACK (_button_clicked_cb),
actor_to_move);</pre></div><p>Note how <code class="varname">actor_to_move</code> is passed
as user data to the handler.</p><p>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 <span class="type">ClutterScript</span> to
<span class="emphasis"><em>every</em></span> handler function; then inside
<span class="emphasis"><em>each</em></span> handler function, retrieve
the required objects from the script.</p><p>This was done in the code example above, by passing
the <span class="type">ClutterScript</span> instance as two arguments to
<code class="function">clutter_script_connect_signals()</code>:
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.</p><div class="note" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Note</h3><p>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 <span class="type">ClutterScript</span>.</p></div></div></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a name="idp74144496"></a>3.4. Full examples</h3></div></div></div><div class="example"><a name="script-signals-examples-1"></a><p class="title"><b>Example 8.3. <span class="type">ClutterScript</span> JSON with signal handler
definitions</b></p><div class="example-contents"><pre class="programlisting">[
{
"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" }
]
}
]
}
]
</pre></div></div><br class="example-break"><div class="example"><a name="script-signals-examples-2"></a><p class="title"><b>Example 8.4. Loading a JSON file into a <span class="type">ClutterScript</span>
and connecting signal handlers</b></p><div class="example-contents"><pre class="programlisting">#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)
{
gfloat z_angle;
/* 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 */
z_angle = clutter_actor_get_rotation (rectangle,
CLUTTER_Z_AXIS,
NULL, NULL, NULL);
if (clutter_click_action_get_button (action) == 1)
z_angle += 90.0;
else
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[])
{
ClutterActor *stage;
ClutterScript *ui;
gchar *filename = "script-signals.json";
GError *error = NULL;
if (clutter_init (&argc, &argv) != CLUTTER_INIT_SUCCESS)
return 1;
ui = clutter_script_new ();
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);
}
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;
}
</pre></div></div><br class="example-break"></div></div><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="script-ui.html">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="script.html">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="script-state.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">2. Defining a user interface with JSON </td><td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td><td width="40%" align="right" valign="top"> 4. Connecting <span class="type">ClutterState</span> states in <span class="type">ClutterScript</span></td></tr></table></div></body></html>
|