gtkbuildable.c 10.4 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
/* gtkbuildable.c
 * Copyright (C) 2006-2007 Async Open Source,
 *                         Johan Dahlin <jdahlin@async.com.br>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

21 22 23 24 25
/**
 * SECTION:gtkbuildable
 * @Short_description: Interface for objects that can be built by GtkBuilder
 * @Title: GtkBuildable
 *
26 27 28 29
 * GtkBuildable allows objects to extend and customize thier deserialization 
 * from <link linkend="BUILDER-UI">GtkBuilder UI descriptions</link>.
 * The interface includes methods for setting names and properties of objects, 
 * parsing custom tags and constructing child objects.
30 31 32
 *
 * The GtkBuildable interface is implemented by all widgets and
 * many of the non-widget objects that are provided by GTK+. The
33
 * main user of this interface is #GtkBuilder. There should be
34 35
 * very little need for applications to call any
 * <function>gtk_buildable_...</function> functions.
36 37 38
 *
 * <note><para>An object only needs to implement this interface if it needs
 * to extend the #GtkBuilder format or run any extra routines at deserialization time</para></note>
39
 */
40

41
#include "config.h"
42 43 44 45
#include "gtkbuildable.h"
#include "gtkintl.h"


46 47
typedef GtkBuildableIface GtkBuildableInterface;
G_DEFINE_INTERFACE (GtkBuildable, gtk_buildable, G_TYPE_OBJECT)
48

49 50 51
static void
gtk_buildable_default_init (GtkBuildableInterface *iface)
{
52 53 54 55 56 57 58
}

/**
 * gtk_buildable_set_name:
 * @buildable: a #GtkBuildable
 * @name: name to set
 *
Matthias Clasen's avatar
Matthias Clasen committed
59
 * Sets the name of the @buildable object.
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
 *
 * Since: 2.12
 **/
void
gtk_buildable_set_name (GtkBuildable *buildable,
                        const gchar  *name)
{
  GtkBuildableIface *iface;

  g_return_if_fail (GTK_IS_BUILDABLE (buildable));
  g_return_if_fail (name != NULL);

  iface = GTK_BUILDABLE_GET_IFACE (buildable);

  if (iface->set_name)
    (* iface->set_name) (buildable, name);
  else
    g_object_set_data_full (G_OBJECT (buildable),
			    "gtk-builder-name",
			    g_strdup (name),
			    g_free);
}

/**
 * gtk_buildable_get_name:
 * @buildable: a #GtkBuildable
 *
Matthias Clasen's avatar
Matthias Clasen committed
87 88 89 90 91
 * Gets the name of the @buildable object. 
 * 
 * #GtkBuilder sets the name based on the the 
 * <link linkend="BUILDER-UI">GtkBuilder UI definition</link> 
 * used to construct the @buildable.
92
 *
Matthias Clasen's avatar
Matthias Clasen committed
93 94
 * Returns: the name set with gtk_buildable_set_name()
 *
95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113
 * Since: 2.12
 **/
const gchar *
gtk_buildable_get_name (GtkBuildable *buildable)
{
  GtkBuildableIface *iface;

  g_return_val_if_fail (GTK_IS_BUILDABLE (buildable), NULL);

  iface = GTK_BUILDABLE_GET_IFACE (buildable);

  if (iface->get_name)
    return (* iface->get_name) (buildable);
  else
    return (const gchar*)g_object_get_data (G_OBJECT (buildable),
					    "gtk-builder-name");
}

/**
114
 * gtk_buildable_add_child:
115 116 117
 * @buildable: a #GtkBuildable
 * @builder: a #GtkBuilder
 * @child: child to add
118
 * @type: (allow-none): kind of child or %NULL
119
 *
Matthias Clasen's avatar
Matthias Clasen committed
120
 * Adds a child to @buildable. @type is an optional string
121 122 123 124 125
 * describing how the child should be added.
 *
 * Since: 2.12
 **/
void
126 127 128 129
gtk_buildable_add_child (GtkBuildable *buildable,
			 GtkBuilder   *builder,
			 GObject      *child,
			 const gchar  *type)
130 131 132 133 134 135 136
{
  GtkBuildableIface *iface;

  g_return_if_fail (GTK_IS_BUILDABLE (buildable));
  g_return_if_fail (GTK_IS_BUILDER (builder));

  iface = GTK_BUILDABLE_GET_IFACE (buildable);
137
  g_return_if_fail (iface->add_child != NULL);
138

139
  (* iface->add_child) (buildable, builder, child, type);
140 141 142
}

/**
143
 * gtk_buildable_set_buildable_property:
144 145 146 147 148
 * @buildable: a #GtkBuildable
 * @builder: a #GtkBuilder
 * @name: name of property
 * @value: value of property
 *
Matthias Clasen's avatar
Matthias Clasen committed
149
 * Sets the property name @name to @value on the @buildable object.
150 151 152 153
 *
 * Since: 2.12
 **/
void
154 155 156 157
gtk_buildable_set_buildable_property (GtkBuildable *buildable,
				      GtkBuilder   *builder,
				      const gchar  *name,
				      const GValue *value)
158 159 160 161 162 163 164 165 166
{
  GtkBuildableIface *iface;

  g_return_if_fail (GTK_IS_BUILDABLE (buildable));
  g_return_if_fail (GTK_IS_BUILDER (builder));
  g_return_if_fail (name != NULL);
  g_return_if_fail (value != NULL);

  iface = GTK_BUILDABLE_GET_IFACE (buildable);
167 168
  if (iface->set_buildable_property)
    (* iface->set_buildable_property) (buildable, builder, name, value);
169 170 171 172 173 174 175 176 177
  else
    g_object_set_property (G_OBJECT (buildable), name, value);
}

/**
 * gtk_buildable_parser_finished:
 * @buildable: a #GtkBuildable
 * @builder: a #GtkBuilder
 *
Matthias Clasen's avatar
Matthias Clasen committed
178 179 180 181 182
 * Called when the builder finishes the parsing of a 
 * <link linkend="BUILDER-UI">GtkBuilder UI definition</link>. 
 * Note that this will be called once for each time 
 * gtk_builder_add_from_file() or gtk_builder_add_from_string() 
 * is called on a builder.
183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200
 *
 * Since: 2.12
 **/
void
gtk_buildable_parser_finished (GtkBuildable *buildable,
			       GtkBuilder   *builder)
{
  GtkBuildableIface *iface;

  g_return_if_fail (GTK_IS_BUILDABLE (buildable));
  g_return_if_fail (GTK_IS_BUILDER (builder));

  iface = GTK_BUILDABLE_GET_IFACE (buildable);
  if (iface->parser_finished)
    (* iface->parser_finished) (buildable, builder);
}

/**
Matthias Clasen's avatar
Matthias Clasen committed
201
 * gtk_buildable_construct_child:
202 203 204 205
 * @buildable: A #GtkBuildable
 * @builder: #GtkBuilder used to construct this object
 * @name: name of child to construct
 *
206
 * Constructs a child of @buildable with the name @name.
207
 *
Matthias Clasen's avatar
Matthias Clasen committed
208 209
 * #GtkBuilder calls this function if a "constructor" has been
 * specified in the UI definition.
Matthias Clasen's avatar
Matthias Clasen committed
210
 *
211
 * Returns: (transfer full): the constructed child
212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232
 *
 * Since: 2.12
 **/
GObject *
gtk_buildable_construct_child (GtkBuildable *buildable,
                               GtkBuilder   *builder,
                               const gchar  *name)
{
  GtkBuildableIface *iface;

  g_return_val_if_fail (GTK_IS_BUILDABLE (buildable), NULL);
  g_return_val_if_fail (GTK_IS_BUILDER (builder), NULL);
  g_return_val_if_fail (name != NULL, NULL);

  iface = GTK_BUILDABLE_GET_IFACE (buildable);
  g_return_val_if_fail (iface->construct_child != NULL, NULL);

  return (* iface->construct_child) (buildable, builder, name);
}

/**
Matthias Clasen's avatar
Matthias Clasen committed
233
 * gtk_buildable_custom_tag_start:
234 235
 * @buildable: a #GtkBuildable
 * @builder: a #GtkBuilder used to construct this object
236
 * @child: (allow-none): child object or %NULL for non-child tags
237
 * @tagname: name of tag
238 239
 * @parser: (out): a #GMarkupParser structure to fill in
 * @data: (out): return location for user data that will be passed in 
Matthias Clasen's avatar
Matthias Clasen committed
240
 *   to parser functions
241
 *
Matthias Clasen's avatar
Matthias Clasen committed
242
 * This is called for each unknown element under &lt;child&gt;.
243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270
 * 
 * Returns: %TRUE if a object has a custom implementation, %FALSE
 *          if it doesn't.
 *
 * Since: 2.12
 **/
gboolean
gtk_buildable_custom_tag_start (GtkBuildable  *buildable,
                                GtkBuilder    *builder,
                                GObject       *child,
                                const gchar   *tagname,
                                GMarkupParser *parser,
                                gpointer      *data)
{
  GtkBuildableIface *iface;

  g_return_val_if_fail (GTK_IS_BUILDABLE (buildable), FALSE);
  g_return_val_if_fail (GTK_IS_BUILDER (builder), FALSE);
  g_return_val_if_fail (tagname != NULL, FALSE);

  iface = GTK_BUILDABLE_GET_IFACE (buildable);
  g_return_val_if_fail (iface->custom_tag_start != NULL, FALSE);

  return (* iface->custom_tag_start) (buildable, builder, child,
                                      tagname, parser, data);
}

/**
Matthias Clasen's avatar
Matthias Clasen committed
271
 * gtk_buildable_custom_tag_end:
272 273
 * @buildable: A #GtkBuildable
 * @builder: #GtkBuilder used to construct this object
274
 * @child: (allow-none): child object or %NULL for non-child tags
275
 * @tagname: name of tag
276
 * @data: (type gpointer): user data that will be passed in to parser functions
277
 *
Matthias Clasen's avatar
Matthias Clasen committed
278 279
 * This is called at the end of each custom element handled by 
 * the buildable.
280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304
 *
 * Since: 2.12
 **/
void
gtk_buildable_custom_tag_end (GtkBuildable  *buildable,
                              GtkBuilder    *builder,
                              GObject       *child,
                              const gchar   *tagname,
                              gpointer      *data)
{
  GtkBuildableIface *iface;

  g_return_if_fail (GTK_IS_BUILDABLE (buildable));
  g_return_if_fail (GTK_IS_BUILDER (builder));
  g_return_if_fail (tagname != NULL);

  iface = GTK_BUILDABLE_GET_IFACE (buildable);
  if (iface->custom_tag_end)
    (* iface->custom_tag_end) (buildable, builder, child, tagname, data);
}

/**
 * gtk_buildable_custom_finished:
 * @buildable: a #GtkBuildable
 * @builder: a #GtkBuilder
305
 * @child: (allow-none): child object or %NULL for non-child tags
306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331
 * @tagname: the name of the tag
 * @data: user data created in custom_tag_start
 *
 * This is similar to gtk_buildable_parser_finished() but is
 * called once for each custom tag handled by the @buildable.
 * 
 * Since: 2.12
 **/
void
gtk_buildable_custom_finished (GtkBuildable  *buildable,
			       GtkBuilder    *builder,
			       GObject       *child,
			       const gchar   *tagname,
			       gpointer       data)
{
  GtkBuildableIface *iface;

  g_return_if_fail (GTK_IS_BUILDABLE (buildable));
  g_return_if_fail (GTK_IS_BUILDER (builder));

  iface = GTK_BUILDABLE_GET_IFACE (buildable);
  if (iface->custom_finished)
    (* iface->custom_finished) (buildable, builder, child, tagname, data);
}

/**
Matthias Clasen's avatar
Matthias Clasen committed
332
 * gtk_buildable_get_internal_child:
333 334 335 336
 * @buildable: a #GtkBuildable
 * @builder: a #GtkBuilder
 * @childname: name of child
 *
Matthias Clasen's avatar
Matthias Clasen committed
337
 * Get the internal child called @childname of the @buildable object.
338
 *
339
 * Returns: (transfer none): the internal child of the buildable object
340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359
 *
 * Since: 2.12
 **/
GObject *
gtk_buildable_get_internal_child (GtkBuildable *buildable,
                                  GtkBuilder   *builder,
                                  const gchar  *childname)
{
  GtkBuildableIface *iface;

  g_return_val_if_fail (GTK_IS_BUILDABLE (buildable), NULL);
  g_return_val_if_fail (GTK_IS_BUILDER (builder), NULL);
  g_return_val_if_fail (childname != NULL, NULL);

  iface = GTK_BUILDABLE_GET_IFACE (buildable);
  if (!iface->get_internal_child)
    return NULL;

  return (* iface->get_internal_child) (buildable, builder, childname);
}