<!doctype book PUBLIC "-//Davenport//DTD DocBook V3.0//EN" [
<!entity libglade-glade-build SYSTEM "sgml/glade-build.sgml">
<!entity libglade-glade-sax SYSTEM "sgml/glade-sax.sgml">
<!entity libglade-glade-xml SYSTEM "sgml/glade-xml.sgml">
<!entity libglade-glade SYSTEM "sgml/glade.sgml">
]>

<book id="libglade">
  <bookinfo>
    <title>Libglade Reference Manual</title>
    <authorgroup>
      <author>
	<firstname>James</firstname>
	<surname>Henstridge</surname>
	<affiliation>
	  <address>
	    <email>james@daa.com.au</email>
	  </address>
	</affiliation>
      </author>
    </authorgroup>

    <copyright>
      <year>1999</year>
      <holder>James Henstridge</holder>
    </copyright>

    <legalnotice>
      <para>Permission is granted to make and distribute verbatim
      copies of this manual provided the copyright notice and this
      permission notice are preserved on all copies.</para>

      <para>Permission is granted to copy and distribute modified
      versions of this manual under the conditions for verbatim
      copying, provided also that the entire resulting derived work is
      distributed under the terms of a permission notice identical to
      this one.</para>

      <para>Permission is granted to copy and distribute translations
      of this manual into another language, under the above conditions
      for modified versions.</para>
    </legalnotice>

    <abstract>
      <para>This manual documents the interfaces of the libglade
      library and has some short notes to help get you up to speed
      with using the library.</para>
    </abstract>
  </bookinfo>

  <chapter id="libglade-notes">
    <title>Libglade Programming Notes</title>

    <para>Libglade is an alternative to using Glade's code generation.
    Instead of generating code from the XML interface description,
    libglade loads and parses the description at runtime.  It also
    provides functions that can be used to connect signal handlers to
    parts of the interface.</para>

    <para>In this way, it allows you to separate your program code
    from the interface code.  In fact, if you use the
    glade_xml_signal_autoconnect() function, the GUI code could be as
    simple as the <filename>test-libglade.c</filename> example that
    comes with libglade.  Of course, you would also add your own
    signal handlers to the code.  Note that the signals are connected
    the same way as if you had hand coded the interface.  There is no
    extra overhead to interfaces generated by libglade (after the
    initial generating of course, and this is not much of an overhead)
    when compared to a hand crafted interface.</para>

    <sect1 id=libglade-basics>
      <title>Libglade Programming Basics</title>

      <para>Your basic libglade program will look something like this:</para>
<programlisting>
#include &lt;gtk/gtk.h&gt;
#include &lt;glade/glade.h&gt;

void some_signal_handler_func(GtkWidget *widget, gpointer user_data) {
  /* do something useful here */
}

int main(int argc, char *argv[]) {
    GladeXML *xml;

    gtk_init(&amp;argc, &amp;argv);
    glade_init();

    /* load the interface */
    xml = glade_xml_new("filename-for-interface", NULL);
    /* connect the signals in the interface */
    glade_xml_signal_autoconnect(xml);
    /* start the event loop */
    gtk_main();
    return 0;
}
</programlisting>

      <para>This will create the interface from the file
      <filename>filename-for-interface</filename>, then connect all
      the signals in the interface.  The automatic signal connection
      is done by looking up function names in the symbol table using
      gmodule.  This means that the interface file can use standard
      GTK functions such as <function>gtk_widget_show</function>, or
      <function>gtk_main_quit</function>, or others in the interface
      and not have to write any code to connect the signals.</para>

      <para>The <function>some_signal_handler_func</function> function
      is not referenced anywhere in the program explicitely, but if
      any signals are defined in the interface description that use
      "some_signal_handler_func" as the handler name, then this
      function will automatically be connected.  Note that the
      function can not be static, since we require it to apear in the
      symbol table.  Here is an example of the XML that would cause
      <function>some_signal_handler_func</function> to be
      connected:</para>
<programlisting>
&lt;widget&gt;
  &lt;class&gt;GtkWindow&lt;/class&gt;
  &lt;name&gt;MainWindow&lt;/name&gt;
  &lt;signal&gt;
    &lt;name&gt;destroy&lt;/name&gt;
    &lt;handler&gt;some_signal_handler_func&lt;/handler&gt;
  &lt;/signal&gt;
  ...
</programlisting>

      <para>To compile the program, we would use the following:</para>
<programlisting>
cc -o testprogram testprogram.c `libglade-config --cflags --libs`
</programlisting>
      <para>The <filename>libglade-config</filename> script will give
      the correct parameters used to compile the program.  If you are
      using automake or autoconf, you may want to investigate the
      AM_PATH_LIBGLADE macro that is installed as
      <filename>$(datadir)/aclocal/libglade.m4</filename>.</para>

    </sect1>

    <sect1 id=libglade-gnome>
      <title>Adding GNOME Support</title>
      
      <para>Libglade is starting to support the GNOME widgets (I am
      adding support as it is added to Glade, so that the file formats
      do not get out of sync).  The GNOME support is done in a modular
      way, so that applications that do not use the GNOME support do
      not need to link with the GNOME libraries.</para>

      <para>For this reason, you need to link with an extra library if
      you want GNOME support (add <filename>-lglade-gnome</filename>
      to the start of the library list), and call
      <function>glade_gnome_init</function> to intitialise libglade,
      instead of <function>glade_init</function>.</para>

      <para>To get the link flags for GNOME support, once again you
      use the <filename>libglade-config</filename> script.  To build the
      program, you would now use:</para>
<programlisting>
cc -o testprogram testprogram.c `libglade-config --cflags --libs gnome`
</programlisting>
      <para>If you use the AM_PATH_LIBGLADE autoconf macro, giving
      "gnome" as the third parameter will have the same effect.  Note
      that libglade-config will give an error if GNOME support was not
      compiled, and GNOME support is asked for.</para>

    </sect1>

    <sect1 id="libglade-i18n">
      <title>Internationalisation with Libglade</title>

      <para>Libglade now supports i18n through the gettext system.
      The <filename>libglade-xgettext</filename> program that is
      distributed with libglade can be used to extract translatable
      strings from (multiple) XML interface descriptions.  It can
      output in either the standard PO file format, or output a dummy
      C file that can be fed to xgettext with the rest of the source
      of your package.  For full details, run "libglade-xgettext
      --help".  Note that this program requires python.  If this is
      too inconvenient to a lot of people, I may consider rewriting it
      in C (patches welcome :)</para>

      <para>While building the interface, libglade will translate the
      strings it finds, if i18n was not disabled during build.  It
      will default to using the current text domain for the
      translations.  If you want to specify a different domain (this
      would be useful for libglade dialogs provided by a library), you
      can use the <function>glade_xml_new_with_domain</function> to
      create the GladeXML object, rather than
      <function>glade_xml_new</function>.  This will cause the strings
      to be translated using a different translation domain.</para>

    </sect1>

    <sect1 id=libglade-extending>
      <title>Extending Libglade</title>

      <para>In some cases, libglade may not provide support for the
      widgets you want to use, or you may want to insert a bit of hand
      coded interface into the larger libglade generated
      interface.  Libglade provides support for doing this.</para>

      <para>If you are only need a few custom widgets (eg. a word
      processor may have a custom widget for the document editing
      area), the simplest choice is probably Glade's custom widget.
      It allows you to specify a custom function that will be used to
      create the widget.  The signature of the function is as
      follows:</para>
<programlisting>
GtkWidget *custom_func(gchar *widget_name, gchar *string1, gchar *string2,
                       gint int1, gint int2);
</programlisting>
      <para>When calling this function, widget_name is the name of the
      widget given in the XML file, and string1, string2, int1 and
      int2 are arbitrary constants whose values also come from the XML
      file.  Libglade supports the custom widget using gmodule.  For
      most cases, this is sufficient.</para>

      <para>If you wish to get libglade to recognise new widget types,
      you will need to do a bit more work.  You will need to write a
      function that will create the widget from a node in the XML tree
      (the function need not worry about standard options like whether
      the widget is visible or not, or how it is added to its parent).
      If the widget is also a container, you will need to specify a
      child building function (which is also responsible for adding
      the widgets to container).  If the container uses the standard
      <function>gtk_container_add</function> interface, you can use
      the <function>glade_standard_build_children</function> function
      that is provided by libglade.</para>

      <para>For a more extensive example of registering new widget
      types and build functions, see the files
      <filename>glade/glade-gtk.c</filename> or
      <filename>glade/glade-gnome.c</filename> in the libglade
      package.  For more information on the exact API's used to
      register new widget types with libglade, see the <link
      linkend="libglade-Libglade-Build">Libglade Build</link> section
      of this manual.</para>

    </sect1>

    <sect1 id=libglade-embedding>
      <title>Embedding Libglade Interfaces</title>

      <para>Sometimes you will only want to use libglade for a small
      part of your program.  If it is just for some dialogs, this is
      easy -- you just generate the dialogs from the interface files
      when needed (note that libglade caches the XML parse tree
      between calls to <function>glade_xml_new</function>, so you will
      not suffer the performance hit of parsing a particular XML file
      more than once).  On the other hand, you may want to use
      libglade to generate just the menubar or just a notebook for a
      dialog or something.  Libglade allows this as well.</para>

      <para>Libglade allows you to build only part of the interface if
      you want to.  The second argument to
      <function>glade_xml_new</function> specifies the name of the
      base widget to build the interface from.  This way we can limit
      the widgets that are constructed by libglade.</para>

      <para>For the menubar example, we would create a dummy window in
      Glade, and insert a menubar widget into the window.  We would
      then name the menubar in glade ("menubar" isn't a bad name :),
      and customise it as much as we want.  Now in the program, we can
      use the following code:</para>
<programlisting>
GladeXML *xml;
GtkWidget *menubar;

xml = glade_xml_new("some-interface-file", "menubar");
glade_xml_signal_autoconnect(xml);
menubar = glade_xml_get_widget(xml, "menubar");
/* do whatever we want to with the menubar */
</programlisting>
      <para>From here, we can do what ever we want with the menubar
      widget.  The dummy window we created in Glade is never created,
      so does not affect the program.  You can also use similar code
      to only build a single dialog from a file that contains many
      dialogs.</para>

      <para>One thing to note -- if you don't want a widget to be
      displayed as soon as it is built with
      <function>glade_xml_new</function>, you should turn off the
      visible flag on that widget in Glade.  This is the correct
      solution to the problem (putting a hack into libglade so that it
      never shows the toplevel windows is not The Right Thing).</para>

    </sect1>
  </chapter>

  <chapter id="libglade-lib">
    <title>Libglade Library Reference</title>

    <para>This section contains the API reference for libglade.  All
    the public interfaces are documented here.</para>

    &libglade-glade;
    &libglade-glade-xml;
    &libglade-glade-sax;
    &libglade-glade-build;
  </chapter>
</book>
