1 /* gtkbuildable.c
2 * Copyright (C) 2006-2007 Async Open Source,
3 * Johan Dahlin <jdahlin@async.com.br>
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Library General Public License for more details.
14 *
15 * You should have received a copy of the GNU Library General Public
16 * License along with this library. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19 /**
20 * SECTION:gtkbuildable
21 * @Short_description: Interface for objects that can be built by GtkBuilder
22 * @Title: GtkBuildable
23 *
24 * GtkBuildable allows objects to extend and customize their deserialization
25 * from [GtkBuilder UI descriptions][BUILDER-UI].
26 * The interface includes methods for setting names and properties of objects,
27 * parsing custom tags and constructing child objects.
28 *
29 * The GtkBuildable interface is implemented by all widgets and
30 * many of the non-widget objects that are provided by GTK+. The
31 * main user of this interface is #GtkBuilder. There should be
32 * very little need for applications to call any of these functions directly.
33 *
34 * An object only needs to implement this interface if it needs to extend the
35 * #GtkBuilder format or run any extra routines at deserialization time.
36 */
37
38 #include "config.h"
39 #include "gtkbuildable.h"
40 #include "gtkintl.h"
41
42
43 typedef GtkBuildableIface GtkBuildableInterface;
G_DEFINE_INTERFACE(GtkBuildable,gtk_buildable,G_TYPE_OBJECT)44 G_DEFINE_INTERFACE (GtkBuildable, gtk_buildable, G_TYPE_OBJECT)
45
46 static void
47 gtk_buildable_default_init (GtkBuildableInterface *iface)
48 {
49 }
50
51 /**
52 * gtk_buildable_set_name:
53 * @buildable: a #GtkBuildable
54 * @name: name to set
55 *
56 * Sets the name of the @buildable object.
57 *
58 * Since: 2.12
59 **/
60 void
gtk_buildable_set_name(GtkBuildable * buildable,const gchar * name)61 gtk_buildable_set_name (GtkBuildable *buildable,
62 const gchar *name)
63 {
64 GtkBuildableIface *iface;
65
66 g_return_if_fail (GTK_IS_BUILDABLE (buildable));
67 g_return_if_fail (name != NULL);
68
69 iface = GTK_BUILDABLE_GET_IFACE (buildable);
70
71 if (iface->set_name)
72 (* iface->set_name) (buildable, name);
73 else
74 g_object_set_data_full (G_OBJECT (buildable),
75 "gtk-builder-name",
76 g_strdup (name),
77 g_free);
78 }
79
80 /**
81 * gtk_buildable_get_name:
82 * @buildable: a #GtkBuildable
83 *
84 * Gets the name of the @buildable object.
85 *
86 * #GtkBuilder sets the name based on the
87 * [GtkBuilder UI definition][BUILDER-UI]
88 * used to construct the @buildable.
89 *
90 * Returns: the name set with gtk_buildable_set_name()
91 *
92 * Since: 2.12
93 **/
94 const gchar *
gtk_buildable_get_name(GtkBuildable * buildable)95 gtk_buildable_get_name (GtkBuildable *buildable)
96 {
97 GtkBuildableIface *iface;
98
99 g_return_val_if_fail (GTK_IS_BUILDABLE (buildable), NULL);
100
101 iface = GTK_BUILDABLE_GET_IFACE (buildable);
102
103 if (iface->get_name)
104 return (* iface->get_name) (buildable);
105 else
106 return (const gchar*)g_object_get_data (G_OBJECT (buildable),
107 "gtk-builder-name");
108 }
109
110 /**
111 * gtk_buildable_add_child:
112 * @buildable: a #GtkBuildable
113 * @builder: a #GtkBuilder
114 * @child: child to add
115 * @type: (allow-none): kind of child or %NULL
116 *
117 * Adds a child to @buildable. @type is an optional string
118 * describing how the child should be added.
119 *
120 * Since: 2.12
121 **/
122 void
gtk_buildable_add_child(GtkBuildable * buildable,GtkBuilder * builder,GObject * child,const gchar * type)123 gtk_buildable_add_child (GtkBuildable *buildable,
124 GtkBuilder *builder,
125 GObject *child,
126 const gchar *type)
127 {
128 GtkBuildableIface *iface;
129
130 g_return_if_fail (GTK_IS_BUILDABLE (buildable));
131 g_return_if_fail (GTK_IS_BUILDER (builder));
132
133 iface = GTK_BUILDABLE_GET_IFACE (buildable);
134 g_return_if_fail (iface->add_child != NULL);
135
136 (* iface->add_child) (buildable, builder, child, type);
137 }
138
139 /**
140 * gtk_buildable_set_buildable_property:
141 * @buildable: a #GtkBuildable
142 * @builder: a #GtkBuilder
143 * @name: name of property
144 * @value: value of property
145 *
146 * Sets the property name @name to @value on the @buildable object.
147 *
148 * Since: 2.12
149 **/
150 void
gtk_buildable_set_buildable_property(GtkBuildable * buildable,GtkBuilder * builder,const gchar * name,const GValue * value)151 gtk_buildable_set_buildable_property (GtkBuildable *buildable,
152 GtkBuilder *builder,
153 const gchar *name,
154 const GValue *value)
155 {
156 GtkBuildableIface *iface;
157
158 g_return_if_fail (GTK_IS_BUILDABLE (buildable));
159 g_return_if_fail (GTK_IS_BUILDER (builder));
160 g_return_if_fail (name != NULL);
161 g_return_if_fail (value != NULL);
162
163 iface = GTK_BUILDABLE_GET_IFACE (buildable);
164 if (iface->set_buildable_property)
165 (* iface->set_buildable_property) (buildable, builder, name, value);
166 else
167 g_object_set_property (G_OBJECT (buildable), name, value);
168 }
169
170 /**
171 * gtk_buildable_parser_finished:
172 * @buildable: a #GtkBuildable
173 * @builder: a #GtkBuilder
174 *
175 * Called when the builder finishes the parsing of a
176 * [GtkBuilder UI definition][BUILDER-UI].
177 * Note that this will be called once for each time
178 * gtk_builder_add_from_file() or gtk_builder_add_from_string()
179 * is called on a builder.
180 *
181 * Since: 2.12
182 **/
183 void
gtk_buildable_parser_finished(GtkBuildable * buildable,GtkBuilder * builder)184 gtk_buildable_parser_finished (GtkBuildable *buildable,
185 GtkBuilder *builder)
186 {
187 GtkBuildableIface *iface;
188
189 g_return_if_fail (GTK_IS_BUILDABLE (buildable));
190 g_return_if_fail (GTK_IS_BUILDER (builder));
191
192 iface = GTK_BUILDABLE_GET_IFACE (buildable);
193 if (iface->parser_finished)
194 (* iface->parser_finished) (buildable, builder);
195 }
196
197 /**
198 * gtk_buildable_construct_child:
199 * @buildable: A #GtkBuildable
200 * @builder: #GtkBuilder used to construct this object
201 * @name: name of child to construct
202 *
203 * Constructs a child of @buildable with the name @name.
204 *
205 * #GtkBuilder calls this function if a “constructor” has been
206 * specified in the UI definition.
207 *
208 * Returns: (transfer full): the constructed child
209 *
210 * Since: 2.12
211 **/
212 GObject *
gtk_buildable_construct_child(GtkBuildable * buildable,GtkBuilder * builder,const gchar * name)213 gtk_buildable_construct_child (GtkBuildable *buildable,
214 GtkBuilder *builder,
215 const gchar *name)
216 {
217 GtkBuildableIface *iface;
218
219 g_return_val_if_fail (GTK_IS_BUILDABLE (buildable), NULL);
220 g_return_val_if_fail (GTK_IS_BUILDER (builder), NULL);
221 g_return_val_if_fail (name != NULL, NULL);
222
223 iface = GTK_BUILDABLE_GET_IFACE (buildable);
224 g_return_val_if_fail (iface->construct_child != NULL, NULL);
225
226 return (* iface->construct_child) (buildable, builder, name);
227 }
228
229 /**
230 * gtk_buildable_custom_tag_start:
231 * @buildable: a #GtkBuildable
232 * @builder: a #GtkBuilder used to construct this object
233 * @child: (allow-none): child object or %NULL for non-child tags
234 * @tagname: name of tag
235 * @parser: (out): a #GMarkupParser to fill in
236 * @data: (out): return location for user data that will be passed in
237 * to parser functions
238 *
239 * This is called for each unknown element under `<child>`.
240 *
241 * Returns: %TRUE if a object has a custom implementation, %FALSE
242 * if it doesn't.
243 *
244 * Since: 2.12
245 **/
246 gboolean
gtk_buildable_custom_tag_start(GtkBuildable * buildable,GtkBuilder * builder,GObject * child,const gchar * tagname,GMarkupParser * parser,gpointer * data)247 gtk_buildable_custom_tag_start (GtkBuildable *buildable,
248 GtkBuilder *builder,
249 GObject *child,
250 const gchar *tagname,
251 GMarkupParser *parser,
252 gpointer *data)
253 {
254 GtkBuildableIface *iface;
255
256 g_return_val_if_fail (GTK_IS_BUILDABLE (buildable), FALSE);
257 g_return_val_if_fail (GTK_IS_BUILDER (builder), FALSE);
258 g_return_val_if_fail (tagname != NULL, FALSE);
259
260 iface = GTK_BUILDABLE_GET_IFACE (buildable);
261 g_return_val_if_fail (iface->custom_tag_start != NULL, FALSE);
262
263 return (* iface->custom_tag_start) (buildable, builder, child,
264 tagname, parser, data);
265 }
266
267 /**
268 * gtk_buildable_custom_tag_end:
269 * @buildable: A #GtkBuildable
270 * @builder: #GtkBuilder used to construct this object
271 * @child: (allow-none): child object or %NULL for non-child tags
272 * @tagname: name of tag
273 * @data: (type gpointer): user data that will be passed in to parser functions
274 *
275 * This is called at the end of each custom element handled by
276 * the buildable.
277 *
278 * Since: 2.12
279 **/
280 void
gtk_buildable_custom_tag_end(GtkBuildable * buildable,GtkBuilder * builder,GObject * child,const gchar * tagname,gpointer * data)281 gtk_buildable_custom_tag_end (GtkBuildable *buildable,
282 GtkBuilder *builder,
283 GObject *child,
284 const gchar *tagname,
285 gpointer *data)
286 {
287 GtkBuildableIface *iface;
288
289 g_return_if_fail (GTK_IS_BUILDABLE (buildable));
290 g_return_if_fail (GTK_IS_BUILDER (builder));
291 g_return_if_fail (tagname != NULL);
292
293 iface = GTK_BUILDABLE_GET_IFACE (buildable);
294 if (iface->custom_tag_end)
295 (* iface->custom_tag_end) (buildable, builder, child, tagname, data);
296 }
297
298 /**
299 * gtk_buildable_custom_finished:
300 * @buildable: a #GtkBuildable
301 * @builder: a #GtkBuilder
302 * @child: (allow-none): child object or %NULL for non-child tags
303 * @tagname: the name of the tag
304 * @data: user data created in custom_tag_start
305 *
306 * This is similar to gtk_buildable_parser_finished() but is
307 * called once for each custom tag handled by the @buildable.
308 *
309 * Since: 2.12
310 **/
311 void
gtk_buildable_custom_finished(GtkBuildable * buildable,GtkBuilder * builder,GObject * child,const gchar * tagname,gpointer data)312 gtk_buildable_custom_finished (GtkBuildable *buildable,
313 GtkBuilder *builder,
314 GObject *child,
315 const gchar *tagname,
316 gpointer data)
317 {
318 GtkBuildableIface *iface;
319
320 g_return_if_fail (GTK_IS_BUILDABLE (buildable));
321 g_return_if_fail (GTK_IS_BUILDER (builder));
322
323 iface = GTK_BUILDABLE_GET_IFACE (buildable);
324 if (iface->custom_finished)
325 (* iface->custom_finished) (buildable, builder, child, tagname, data);
326 }
327
328 /**
329 * gtk_buildable_get_internal_child:
330 * @buildable: a #GtkBuildable
331 * @builder: a #GtkBuilder
332 * @childname: name of child
333 *
334 * Get the internal child called @childname of the @buildable object.
335 *
336 * Returns: (transfer none): the internal child of the buildable object
337 *
338 * Since: 2.12
339 **/
340 GObject *
gtk_buildable_get_internal_child(GtkBuildable * buildable,GtkBuilder * builder,const gchar * childname)341 gtk_buildable_get_internal_child (GtkBuildable *buildable,
342 GtkBuilder *builder,
343 const gchar *childname)
344 {
345 GtkBuildableIface *iface;
346
347 g_return_val_if_fail (GTK_IS_BUILDABLE (buildable), NULL);
348 g_return_val_if_fail (GTK_IS_BUILDER (builder), NULL);
349 g_return_val_if_fail (childname != NULL, NULL);
350
351 iface = GTK_BUILDABLE_GET_IFACE (buildable);
352 if (!iface->get_internal_child)
353 return NULL;
354
355 return (* iface->get_internal_child) (buildable, builder, childname);
356 }
357