4 * An OpenGL based 'interactive canvas' library.
6 * Copyright (C) 2011 Intel Corporation.
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library. If not, see <http://www.gnu.org/licenses/>.
22 * Emmanuele Bassi <ebassi@linux.intel.com>
26 * SECTION:clutter-content
27 * @Title: ClutterContent
28 * @Short_Description: Delegate for painting the content of an actor
30 * #ClutterContent is an interface to implement types responsible for
31 * painting the content of a #ClutterActor.
33 * Multiple actors can use the same #ClutterContent instance, in order
34 * to share the resources associated with painting the same content.
36 * #ClutterContent is available since Clutter 1.10.
43 #include "clutter-content-private.h"
45 #include "clutter-debug.h"
46 #include "clutter-marshal.h"
47 #include "clutter-private.h"
49 typedef struct _ClutterContentIface ClutterContentInterface;
59 static GQuark quark_content_actors = 0;
61 static guint content_signals[LAST_SIGNAL] = { 0, };
63 G_DEFINE_INTERFACE (ClutterContent, clutter_content, G_TYPE_OBJECT)
66 clutter_content_real_get_preferred_size (ClutterContent *content,
80 clutter_content_real_attached (ClutterContent *content,
86 clutter_content_real_detached (ClutterContent *content,
92 clutter_content_real_invalidate (ClutterContent *content)
97 clutter_content_real_paint_content (ClutterContent *content,
99 ClutterPaintNode *context)
104 clutter_content_default_init (ClutterContentInterface *iface)
106 quark_content_actors = g_quark_from_static_string ("-clutter-content-actors");
108 iface->get_preferred_size = clutter_content_real_get_preferred_size;
109 iface->paint_content = clutter_content_real_paint_content;
110 iface->attached = clutter_content_real_attached;
111 iface->detached = clutter_content_real_detached;
112 iface->invalidate = clutter_content_real_invalidate;
115 * ClutterContent::attached:
116 * @content: the object that emitted the signal
117 * @actor: a #ClutterActor
119 * This signal is emitted each time a #ClutterContent implementation is
120 * assigned to a #ClutterActor.
124 content_signals[ATTACHED] =
125 g_signal_new (I_("attached"),
126 G_TYPE_FROM_INTERFACE (iface),
128 G_STRUCT_OFFSET (ClutterContentIface, attached),
130 _clutter_marshal_VOID__OBJECT,
135 * ClutterContent::detached:
136 * @content: the object that emitted the signal
137 * @actor: a #ClutterActor
139 * This signal is emitted each time a #ClutterContent implementation is
140 * removed from a #ClutterActor.
144 content_signals[DETACHED] =
145 g_signal_new (I_("detached"),
146 G_TYPE_FROM_INTERFACE (iface),
148 G_STRUCT_OFFSET (ClutterContentIface, detached),
150 _clutter_marshal_VOID__OBJECT,
156 * clutter_content_invalidate:
157 * @content: a #ClutterContent
159 * Invalidates a #ClutterContent.
161 * This function should be called by #ClutterContent implementations when
162 * they change the way a the content should be painted regardless of the
168 clutter_content_invalidate (ClutterContent *content)
172 gpointer key_p, value_p;
174 g_return_if_fail (CLUTTER_IS_CONTENT (content));
176 CLUTTER_CONTENT_GET_IFACE (content)->invalidate (content);
178 actors = g_object_get_qdata (G_OBJECT (content), quark_content_actors);
182 g_hash_table_iter_init (&iter, actors);
183 while (g_hash_table_iter_next (&iter, &key_p, &value_p))
185 ClutterActor *actor = key_p;
187 g_assert (actor != NULL);
189 clutter_actor_queue_redraw (actor);
194 * _clutter_content_attached:
195 * @content: a #ClutterContent
196 * @actor: a #ClutterActor
198 * Attaches @actor to the @content.
200 * This function should be used internally every time a #ClutterActor
201 * is associated to a #ClutterContent, to set up a backpointer from
202 * the @content to the @actor.
204 * This function will invoke the #ClutterContentIface.attached() virtual
208 _clutter_content_attached (ClutterContent *content,
211 GObject *obj = G_OBJECT (content);
214 actors = g_object_get_qdata (obj, quark_content_actors);
217 actors = g_hash_table_new (NULL, NULL);
218 g_object_set_qdata_full (obj, quark_content_actors,
220 (GDestroyNotify) g_hash_table_unref);
223 g_hash_table_insert (actors, actor, actor);
225 g_signal_emit (content, content_signals[ATTACHED], 0, actor);
229 * _clutter_content_detached:
230 * @content: a #ClutterContent
231 * @actor: a #ClutterActor
233 * Detaches @actor from @content.
235 * This function should be used internally every time a #ClutterActor
236 * removes the association with a #ClutterContent.
238 * This function will invoke the #ClutterContentIface.detached() virtual
242 _clutter_content_detached (ClutterContent *content,
245 GObject *obj = G_OBJECT (content);
248 actors = g_object_get_qdata (obj, quark_content_actors);
249 g_assert (actors != NULL);
251 g_hash_table_remove (actors, actor);
253 if (g_hash_table_size (actors) == 0)
254 g_object_set_qdata (obj, quark_content_actors, NULL);
256 g_signal_emit (content, content_signals[DETACHED], 0, actor);
260 * _clutter_content_paint_content:
261 * @content: a #ClutterContent
262 * @actor: a #ClutterActor
263 * @context: a #ClutterPaintNode
265 * Creates the render tree for the @content and @actor.
267 * This function will invoke the #ClutterContentIface.paint_content()
271 _clutter_content_paint_content (ClutterContent *content,
273 ClutterPaintNode *node)
275 CLUTTER_CONTENT_GET_IFACE (content)->paint_content (content, actor, node);
279 * clutter_content_get_preferred_size:
280 * @content: a #ClutterContent
281 * @width: (out): return location for the natural width of the content
282 * @height: (out): return location for the natural height of the content
284 * Retrieves the natural size of the @content, if any.
286 * The natural size of a #ClutterContent is defined as the size the content
287 * would have regardless of the allocation of the actor that is painting it,
288 * for instance the size of an image data.
290 * Return value: %TRUE if the content has a preferred size, and %FALSE
296 clutter_content_get_preferred_size (ClutterContent *content,
300 g_return_val_if_fail (CLUTTER_IS_CONTENT (content), FALSE);
302 return CLUTTER_CONTENT_GET_IFACE (content)->get_preferred_size (content,