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 | * GtkBuildable: |
21 | * |
22 | * `GtkBuildable` allows objects to extend and customize their deserialization |
23 | * from ui files. |
24 | * |
25 | * The interface includes methods for setting names and properties of objects, |
26 | * parsing custom tags and constructing child objects. |
27 | * |
28 | * The `GtkBuildable` interface is implemented by all widgets and |
29 | * many of the non-widget objects that are provided by GTK. The |
30 | * main user of this interface is [class@Gtk.Builder]. There should be |
31 | * very little need for applications to call any of these functions directly. |
32 | * |
33 | * An object only needs to implement this interface if it needs to extend the |
34 | * `GtkBuilder` XML format or run any extra routines at deserialization time. |
35 | */ |
36 | |
37 | #include "config.h" |
38 | #include "gtkbuildableprivate.h" |
39 | #include "gtkintl.h" |
40 | |
41 | |
42 | typedef GtkBuildableIface GtkBuildableInterface; |
43 | G_DEFINE_INTERFACE (GtkBuildable, gtk_buildable, G_TYPE_OBJECT) |
44 | |
45 | static void |
46 | gtk_buildable_default_init (GtkBuildableInterface *iface) |
47 | { |
48 | } |
49 | |
50 | /*< private > |
51 | * gtk_buildable_set_buildable_id: |
52 | * @buildable: a `GtkBuildable` |
53 | * @id: name to set |
54 | * |
55 | * Sets the ID of the @buildable object. |
56 | */ |
57 | void |
58 | gtk_buildable_set_buildable_id (GtkBuildable *buildable, |
59 | const char *id) |
60 | { |
61 | GtkBuildableIface *iface; |
62 | |
63 | g_return_if_fail (GTK_IS_BUILDABLE (buildable)); |
64 | g_return_if_fail (id != NULL); |
65 | |
66 | iface = GTK_BUILDABLE_GET_IFACE (buildable); |
67 | |
68 | if (iface->set_id) |
69 | (* iface->set_id) (buildable, id); |
70 | else |
71 | g_object_set_data_full (G_OBJECT (buildable), |
72 | key: "gtk-builder-id" , |
73 | data: g_strdup (str: id), |
74 | destroy: g_free); |
75 | } |
76 | |
77 | /** |
78 | * gtk_buildable_get_buildable_id: |
79 | * @buildable: a `GtkBuildable` |
80 | * |
81 | * Gets the ID of the @buildable object. |
82 | * |
83 | * `GtkBuilder` sets the name based on the ID attribute |
84 | * of the <object> tag used to construct the @buildable. |
85 | * |
86 | * Returns: (nullable): the ID of the buildable object |
87 | **/ |
88 | const char * |
89 | gtk_buildable_get_buildable_id (GtkBuildable *buildable) |
90 | { |
91 | GtkBuildableIface *iface; |
92 | |
93 | g_return_val_if_fail (GTK_IS_BUILDABLE (buildable), NULL); |
94 | |
95 | iface = GTK_BUILDABLE_GET_IFACE (buildable); |
96 | |
97 | if (iface->get_id) |
98 | return (* iface->get_id) (buildable); |
99 | else |
100 | return (const char *)g_object_get_data (G_OBJECT (buildable), |
101 | key: "gtk-builder-id" ); |
102 | } |
103 | |
104 | /*< private > |
105 | * gtk_buildable_add_child: |
106 | * @buildable: a `GtkBuildable` |
107 | * @builder: a `GtkBuilder` |
108 | * @child: child to add |
109 | * @type: (nullable): kind of child |
110 | * |
111 | * Adds a child to @buildable. @type is an optional string |
112 | * describing how the child should be added. |
113 | */ |
114 | void |
115 | gtk_buildable_add_child (GtkBuildable *buildable, |
116 | GtkBuilder *builder, |
117 | GObject *child, |
118 | const char *type) |
119 | { |
120 | GtkBuildableIface *iface; |
121 | |
122 | g_return_if_fail (GTK_IS_BUILDABLE (buildable)); |
123 | g_return_if_fail (GTK_IS_BUILDER (builder)); |
124 | |
125 | iface = GTK_BUILDABLE_GET_IFACE (buildable); |
126 | g_return_if_fail (iface->add_child != NULL); |
127 | |
128 | (* iface->add_child) (buildable, builder, child, type); |
129 | } |
130 | |
131 | /*< private > |
132 | * gtk_buildable_parser_finished: |
133 | * @buildable: a `GtkBuildable` |
134 | * @builder: a `GtkBuilder` |
135 | * |
136 | * Called when the builder finishes the parsing of a |
137 | * GtkBuilder UI definition. |
138 | * |
139 | * Note that this will be called once for each time |
140 | * gtk_builder_add_from_file() or gtk_builder_add_from_string() |
141 | * is called on a builder. |
142 | */ |
143 | void |
144 | gtk_buildable_parser_finished (GtkBuildable *buildable, |
145 | GtkBuilder *builder) |
146 | { |
147 | GtkBuildableIface *iface; |
148 | |
149 | g_return_if_fail (GTK_IS_BUILDABLE (buildable)); |
150 | g_return_if_fail (GTK_IS_BUILDER (builder)); |
151 | |
152 | iface = GTK_BUILDABLE_GET_IFACE (buildable); |
153 | if (iface->parser_finished) |
154 | (* iface->parser_finished) (buildable, builder); |
155 | } |
156 | |
157 | /*< private > |
158 | * gtk_buildable_construct_child: |
159 | * @buildable: A `GtkBuildable` |
160 | * @builder: `GtkBuilder` used to construct this object |
161 | * @name: name of child to construct |
162 | * |
163 | * Constructs a child of @buildable with the name @name. |
164 | * |
165 | * `GtkBuilder` calls this function if a “constructor” has been |
166 | * specified in the UI definition. |
167 | * |
168 | * Returns: (transfer full): the constructed child |
169 | */ |
170 | GObject * |
171 | gtk_buildable_construct_child (GtkBuildable *buildable, |
172 | GtkBuilder *builder, |
173 | const char *name) |
174 | { |
175 | GtkBuildableIface *iface; |
176 | |
177 | g_return_val_if_fail (GTK_IS_BUILDABLE (buildable), NULL); |
178 | g_return_val_if_fail (GTK_IS_BUILDER (builder), NULL); |
179 | g_return_val_if_fail (name != NULL, NULL); |
180 | |
181 | iface = GTK_BUILDABLE_GET_IFACE (buildable); |
182 | g_return_val_if_fail (iface->construct_child != NULL, NULL); |
183 | |
184 | return (* iface->construct_child) (buildable, builder, name); |
185 | } |
186 | |
187 | /*< private > |
188 | * gtk_buildable_custom_tag_start: |
189 | * @buildable: a `GtkBuildable` |
190 | * @builder: a `GtkBuilder` used to construct this object |
191 | * @child: (nullable): child object or %NULL for non-child tags |
192 | * @tagname: name of tag |
193 | * @parser: (out): a `GMarkupParser` to fill in |
194 | * @data: (out): return location for user data that will be passed in |
195 | * to parser functions |
196 | * |
197 | * This is called for each unknown element under <child>. |
198 | * |
199 | * Returns: %TRUE if an object has a custom implementation, %FALSE |
200 | * if it doesn't. |
201 | */ |
202 | gboolean |
203 | gtk_buildable_custom_tag_start (GtkBuildable *buildable, |
204 | GtkBuilder *builder, |
205 | GObject *child, |
206 | const char *tagname, |
207 | GtkBuildableParser *parser, |
208 | gpointer *data) |
209 | { |
210 | GtkBuildableIface *iface; |
211 | |
212 | g_return_val_if_fail (GTK_IS_BUILDABLE (buildable), FALSE); |
213 | g_return_val_if_fail (GTK_IS_BUILDER (builder), FALSE); |
214 | g_return_val_if_fail (tagname != NULL, FALSE); |
215 | |
216 | iface = GTK_BUILDABLE_GET_IFACE (buildable); |
217 | g_return_val_if_fail (iface->custom_tag_start != NULL, FALSE); |
218 | |
219 | return (* iface->custom_tag_start) (buildable, builder, child, |
220 | tagname, parser, data); |
221 | } |
222 | |
223 | /*< private > |
224 | * gtk_buildable_custom_tag_end: |
225 | * @buildable: A `GtkBuildable` |
226 | * @builder: `GtkBuilder` used to construct this object |
227 | * @child: (nullable): child object or %NULL for non-child tags |
228 | * @tagname: name of tag |
229 | * @data: user data that will be passed in to parser functions |
230 | * |
231 | * This is called at the end of each custom element handled by |
232 | * the buildable. |
233 | */ |
234 | void |
235 | gtk_buildable_custom_tag_end (GtkBuildable *buildable, |
236 | GtkBuilder *builder, |
237 | GObject *child, |
238 | const char *tagname, |
239 | gpointer data) |
240 | { |
241 | GtkBuildableIface *iface; |
242 | |
243 | g_return_if_fail (GTK_IS_BUILDABLE (buildable)); |
244 | g_return_if_fail (GTK_IS_BUILDER (builder)); |
245 | g_return_if_fail (tagname != NULL); |
246 | |
247 | iface = GTK_BUILDABLE_GET_IFACE (buildable); |
248 | if (iface->custom_tag_end) |
249 | (* iface->custom_tag_end) (buildable, builder, child, tagname, data); |
250 | } |
251 | |
252 | /*< private > |
253 | * gtk_buildable_custom_finished: |
254 | * @buildable: a `GtkBuildable` |
255 | * @builder: a `GtkBuilder` |
256 | * @child: (nullable): child object or %NULL for non-child tags |
257 | * @tagname: the name of the tag |
258 | * @data: user data created in custom_tag_start |
259 | * |
260 | * This is similar to gtk_buildable_parser_finished() but is |
261 | * called once for each custom tag handled by the @buildable. |
262 | */ |
263 | void |
264 | gtk_buildable_custom_finished (GtkBuildable *buildable, |
265 | GtkBuilder *builder, |
266 | GObject *child, |
267 | const char *tagname, |
268 | gpointer data) |
269 | { |
270 | GtkBuildableIface *iface; |
271 | |
272 | g_return_if_fail (GTK_IS_BUILDABLE (buildable)); |
273 | g_return_if_fail (GTK_IS_BUILDER (builder)); |
274 | |
275 | iface = GTK_BUILDABLE_GET_IFACE (buildable); |
276 | if (iface->custom_finished) |
277 | (* iface->custom_finished) (buildable, builder, child, tagname, data); |
278 | } |
279 | |
280 | /*< private > |
281 | * gtk_buildable_get_internal_child: |
282 | * @buildable: a `GtkBuildable` |
283 | * @builder: a `GtkBuilder` |
284 | * @childname: name of child |
285 | * |
286 | * Get the internal child called @childname of the @buildable object. |
287 | * |
288 | * Returns: (transfer none): the internal child of the buildable object |
289 | */ |
290 | GObject * |
291 | gtk_buildable_get_internal_child (GtkBuildable *buildable, |
292 | GtkBuilder *builder, |
293 | const char *childname) |
294 | { |
295 | GtkBuildableIface *iface; |
296 | |
297 | g_return_val_if_fail (GTK_IS_BUILDABLE (buildable), NULL); |
298 | g_return_val_if_fail (GTK_IS_BUILDER (builder), NULL); |
299 | g_return_val_if_fail (childname != NULL, NULL); |
300 | |
301 | iface = GTK_BUILDABLE_GET_IFACE (buildable); |
302 | if (!iface->get_internal_child) |
303 | return NULL; |
304 | |
305 | return (* iface->get_internal_child) (buildable, builder, childname); |
306 | } |
307 | |