This is gtkada_ug.info, produced by makeinfo version 4.0 from
gtkada_ug.texi.


File: gtkada_ug.info,  Node: Creating new widgets in Ada,  Prev: Using tagged types to extend Gtk widgets,  Up: Object-oriented features

Creating new widgets in Ada
===========================

   With GtkAda, you can now create widgets directly in Ada. These new
widgets can be used directly, as if they were part of gtk itself.

   Creating new widgets is a way to create reuseable components. You can
apply to them the same functions as would for any other widget, such as
Show, Hide, ...

   This section will explain how to create two types of widgets:
composite widgets and widgets created from scratch. Two examples are
provided with GtkAda, in the directories `examples/composite_widget' and
`examples/base_widget'. Please also refer to the gtk+ tutorial, which
describes the basic mechanisms that you need to know to create a widget
(even if the Ada code is really different from the C code...)

* Menu:

* Creating composite widgets::
* Creating widgets from scratch::


File: gtkada_ug.info,  Node: Creating composite widgets,  Next: Creating widgets from scratch,  Up: Creating new widgets in Ada

Creating composite widgets
--------------------------

   A composite widget is a widget that does not do much by itself.
Rather, this is a collection of subwidgets grouped into a more general
entity.  For instance, among the standard widgets, `Gtk_File_Selection'
and `Gtk_Font_Selection' belong to this category.

   The good news is that there is nothing special to know. Just create a
new tagged type, extending one of the standard widgets (or even another
of your own widgets), provide a `Gtk_New' function that allocates
memory for this widget, and call the `Initialize' function that does
the actual creation of the widget and the subwidgets.  There is only
one thing to do: `Initialize' should call the parent class's
`Initialize' function, to create the underlying C widget.

   The example directory `examples/composite_widget' reimplements the
`Gtk_Dialog' widget as written in C by the creators of gtk+.


File: gtkada_ug.info,  Node: Creating widgets from scratch,  Prev: Creating composite widgets,  Up: Creating new widgets in Ada

Creating widgets from scratch
-----------------------------

   First, an important note: please do not read this if this is your
first time using GtkAda or if you don't really understand the signal
mechanism.  Creating a nice and working widget really takes a lot of
messing with the low level signals.

   Creating a widget from scratch is what you want to do if your widget
should be drawn in a special way, should create and emit new signals,
...  The example we give in `examples/base_widget' is a small target on
which the user can click, and that sends one of two signals "bullseye"
or "missed", depending on where the user has clicked.

   See also the example in `examples/tutorial/gtkdial' for a more
complex widget, that implements a gauge where the user can move the
arrow to select a new value.

   Once again, the only two functions that you must create are `Gtk_New'
and `Initialize'.  This time, `Initialize' has to do two things:

     Parent_Package.Initialize (Widget);
     
     --  The above line calls the Initialize function from the parent.
     --  This creates the underlying C widget, which we are going to
     --  modify with the following call:
     
     Gtk.Object.Initialize_Class_Record
       (Widget, Signals, Class_Record);
     --  This initializes the "class record" for the widget and
     --  creates the signals.

   In the above example, the new part is the second call. It takes
three or four arguments:
   * `Widget' This is the widget that you want to initialize

   * `Signals' This is an array of string access containing the name of
     the signals you want to create. For instance, you could create
     Signals with
          Signals : Gtkada.Types.Chars_Ptr_Array := "bullseye" + "missed";
     This will create two signals, named "bullseye" and "missed", whose
     callbacks' arguments can be specified with the fourth parameter.

   * `Class_Record' Every widget in C is associated with two records.
     The first one, which exists only once per widget type, is the
     "class record". It contains the list of signals that are known by
     this widget type, the list of default callbacks for the signals,
     ...; the second record is an "instance record", which contains
     data specific to a particular instance.

     In GtkAda, the "instance record" is simply your tagged type and
     its fields.  The call to `Initialize_Class_Record' is provided to
     initialize the "class record". As we said, there should be only
     one such record per widget type. This parameter "Class_Record"
     will point to this records, once it is created, and will be reused
     for every instanciation of the widget.

   * `Parameters' This fourth argument is in fact optional, and is used
     to specify which kind of parameters each new signal is expecting.
     By default (ie if you don't give any value for this parameter),
     all the signals won't expect any argument, except of course a
     possible user_data.  However, you can decide for instance that the
     first signal ("bullseye") should in fact take a second argument
     (say a Gint), and that "missed" will take two parameters (two
     Gints).

     `Parameters' should thus contain a value of
          (1 => (1 => Gtk_Type_Int, 2 => Gtk_Type_None),
           2 => (1 => Gtk_Type_Int, 2 => Gtk_Type_Int));

     Due to the way arrays are handled in Ada, each component must have
     the same number of signals. However, if you specify a type of
     `Gtk_Type_None', this will in fact be considered as no argument.
     Thus, the first signal above has only one parameter.

     Note also that to be able to emit a signal such a the second one,
     ie with multiple arguments, you will have to extend the packages
     defined in Gtk.Handlers. By default, the provided packages can
     only emit up to one argument (and only for a few specific types).
     Creating your own `Emit_By_Name' subprograms should not be hard if
     you look at what is done in `gtk-marshallers.adb'. Basically,
     something like:

          procedure Emit_With_Two_Ints
            (Object : access Widget_Type'Class;
             Name   : String;
             Arg1   : Gint;
             Arg2   : Gint);
          pragma Import (C, Emit_With_Two_Ints,
              "gtk_signal_emit_by_name");
          
          Emit_With_Two_Ints (Gtk.Get_Object (Your_Widget),
              "missed" & ASCII.NUL, 1, 2);

     will emit the "missed" signal with the two parameters 1 and 2.


   Then of course `Initialize' should set up some signal handlers for
the functions you want to redefine.  Three signals are especially
useful:

   * "size_request"

     This callback is passed one parameter, as in :
          procedure Size_Request
             (Widget      : access My_Widget_Record;
              Requisition : in out Gtk.Widget.Gtk_Requisition);
     This function should modify Requisition to specify the widget's
     ideal size. This might not be the exact size that will be set,
     since some containers might decide to enlarge or to shrink it.

   * "size_allocate"

     This callback is called every time the widget is moved in its
     parent window, or it is resized. It is passed one paramater, as in
     :
          procedure Size_Allocate
             (Widget     : access My_Widget_Record;
              Allocation : in out Gtk.Widget.Gtk_Allocation)
     This function should take the responsability to move the widget,
     using for instance `Gdk.Window.Move_Resize'.

   * "expose_event"

     This callback is called every time the widget needs to be redrawn.
     It is passed one parameter, the area to be redrawn (to speed
     things up, you don't need to redraw the whole widget, just this
     area).



File: gtkada_ug.info,  Node: Support for Glade the Gtk GUI builder,  Next: Binding new widgets,  Prev: Object-oriented features,  Up: Top

Support for Glade, the Gtk GUI builder
**************************************

Introduction
============

   GtkAda now comes with support for the GUI builder Glade (this is not
the glade released with Gnat for distributed systems).  Using Glade
itself is straightforward: it is an intuitive point and click GUI
builder. The main difference from other builders is that, since GtkAda
builds a UI with blocks by default, you will not be asked to set the
size and position of your windows by default. If you are looking for
this kind of interaction you should consider using the Gtk_Fixed
container. However, please read the GtkAda reference manual before
considering using Gtk_Fixed.

Using Glade
===========

   Note that we only recommend using version 0.5.9 of Glade, as some
previous versions are not compatible. Using this version you can
directly create Ada files from Glade by selecting Ada95 as the language
under project options.  By doing so, you will tell Glade to call Gate
internally when using the "Write Source Code" functionality.  Glade
saves your interface in a project file whose syntax is XML based. In
the following sections, we will refer to this file as either "the XML
file" or "the project file" interchangeably.

Taking advantage of Glade's options
-----------------------------------

   In this XML file, Glade will save various options that Gate can take
advantage of. In particular, going to the project options window, some
General Options in the "C Options" section will also be used by Gate:
Gettext support, if enabled, will generate an additional package called
<project>_intl that will use Gtkada.Intl; The "Set Widget Names" option
is also recognized and will generate additional calls to Set_Name for
each widget.

Associating icons with buttons
------------------------------

   Up to now, the only way to specify an icon for a button was to
associate a pixmap file to it. As an alternative, if the name specified
in the "Icon" field does not contain any dots, Gate will consider the
name as a variable rather than a file name. It is up to you to provide
the necessary definitions in order to compile properly the generated
code.

Note for Linux users
--------------------

   Some Linux systems come with a precompiled version of Glade that
will usually have support for Gnome. GtkAda and Gate currently do not
provide support for Gnome (GtkAda instead provides portable
alternatives to Gnome widgets, see e.g Gtkada.Canvas, Gtkada.Dialogs,
Gtkada.Pixmaps), which means that you should not enable any Gnome
specific features in Glade. In particular, you should disable Gnome
support in the Project Options window, and make sure that you don't use
the "Stock Button" property, nor the list of predefined Gnome icons
provided with various widgets such as toolbar buttons and menu items.

Gate
====

Invoking Gate
-------------

   Gate is the static version of our support. This tool takes the Glade
XML file as an argument and generates a set of Ada files that, when
compiled, will recreate the interface you just designed with Glade.  To
invoke it, simply call gate will a Glade project file This will generate
Ada files in the directory set as the "Source Directory" project option,
or otherwise in the current working directory.

Structure of the generated files
--------------------------------

The main file
.............

   The main file is the name of the program name specified in the XML
Glade file: `<program name>.adb'. It contains initialization and
creation code for each top level widget contained in the XML file. This
is intended as a convenient default to visualize your GUI, but you will
usually want to modify this initialization.

Top level widget files
......................

   For each top level widget, Gate will generate a package
`<widget>_Pkg.Callbacks' in the files `<widget>_pkg-callbacks.ads' and
`.adb'. These packages contain all the GtkAda calls needed to create the
widgets you designed within Glade. You will usually not need to modify
these files yourself.

Main handler file
.................

   This file, called `callbacks_<program name>.ads' contains all the
Handler package instantiations needed by your application. You will
usually not need to modify it.

Top level widget signal files
.............................

   These are the most important files created by Gate. Each is called
`<widget_name>_pkg-callbacks.adb'.  They contain stubs for all the
callbacks related to a top level widget you declared in Glade. With the
main file, this the only files you should modify yourself. Note that it
is recommended that you structure your application such that the real
code is put in separate packages (i.e not generated files) as much as
possible, to avoid potential merging problems when your interface is
significantly changed within Glade. See next section for more details.

   Currently, Gate will generate callback stub procedures that can
handle the expected number of arguments for each signal. This is done
using a relatively low level mechanism explained in the reference manual
(package Gtk.Handlers). Basically, callbacks expecting arguments will
take a Gtk_Argument as their only parameter, and Gate will generate the
appropriate variable declaration and conversion calls to provide the
expected GtkAda arguments. You should not modify this code by hand
unless you know what you are doing.

   For example, given a signal `delete_event', Gate will generate the
following procedure body, giving access to the arguments of this
callback: a `Gtk_Window_Record' (Object) and a `Gdk_Event' (Arg1)

     function On_Main_Window_Delete_Event
       (Object : access Gtk_Window_Record'Class;
        Params : Gtk.Arguments.Gtk_Args) return Boolean
     is
        Arg1 : Gdk_Event := To_Event (Params, 1);
     begin
        return False;
     end On_Main_Window_Delete_Event;

Modifying generated files
-------------------------

   Note that you can easily go back to Glade any time, modify your
interface, and have Gate re-generate a set of files. All your
modifications will be kept in the new files. For that, Gate creates a
directory `.gate' in the current directory. Please do not delete it if
you want Gate to be able to keep your changes from one version to the
next.

   Also note that to keep track of your modifications, gate relies on
either `merge', or `patch' and `diff' being available on your system.
If you don't have a working set of `diff/patch', `configure' will
simply replace them by null operations, which means that regenerated
files will override the previous ones.

   Under Win32 based systems, GtkAda now comes with a set of unix-like
tools (including `patch' and `diff') that provide the same
functionality.  Note that these tools are provided as is, and we
recommend using your own supported set of utilities. In particular,
these tools have known deficiencies under Windows 95 and Windows 98.
Future versions of GtkAda will provide an alternate implementation of
the shell script gate in Ada, in order to solve this portability issue
in a cleaner way.  You can find the complete package of the GNU
utilities provided at
<http://www.weihenstephan.de/~syring/win32/UnxUtils.html>.

   In some cases, due to major changes in the project file, Gate may
not be able to merge all the changes. In this case, it will notify you
so, and will either keep the old and new sections in the files (if you
are using `merge'), or files with a `.rej' extension will be generated
to help you do the merge manually.

Adding Gate support for new widgets
-----------------------------------

   This section is intended for developpers that wish to add support
for new GtkAda widgets in Gate. Note that this section is not complete
yet.

Implementing the "Generate" procedure
.....................................

   To provide support for a new widget, you first need to write a
"Generate" procedure that will take care of generating the piece of
code related to the widget's properties. Note that the parents
properties do not have to be handled by this function.

   * Glib.Glade API The Glib.Glade package contains a self documented
     API that will help you automate most of the work for common
     widgets.

   * Most common mapping
        * Gen_New

        * Gen_Set

        * Gen_Call_Child

        * example

   * Registering "Generate" functions   Gtk.Glade.Register_Generate
     (Widget, Func) This procedure associates a given Generate
     procedure with a given widget C name.

Dynamic loading of XML files
============================

Introduction to Libglade
------------------------

   Libglade is an external library provided by default on some systems
(e.g Linux, Gnome) that supports dynamic loading of XML files and
creation of widgets at run time. The advantage of using libglade is
that you do not need to recompile your application to change your user
interface. On the other hand, everything is done at run time, meaning
less compile checks, and also the inability to take advantage of the
object oriented features of GtkAda and Ada such as deriving from a
widget creating using the GUI builder, to add fields and properties.
See packages Glade and Glade.XML for more information.

Limitations
===========

   Gate currently support all Gtk+ widgets and properties available
under Glade. But, to help you identify widgets that may not be
supported (e.g Gnome widgets), Gate will generate a warning on the
standard error:

     $ gate warning.glade
     Generating Ada files...
     
     GtkAda-WARNING **: Unsupported widget GnomeCanvas (canvas1)
     The following files have been created/updated in src:
     [...]

   and add a comment in the `<widget>_pkg.adb' file that looks like:

     --  WARNING: Unsupported widget GnomeCanvas (canvas1)

   This means that while generating the file Gate detected an
unsupported widget (in this case GnomeCanvas) whose name is canvas1.
If you get such a warning your file may or may not compile properly, but
you won't get the complete widget hierarchy at run time.

   Feel free to send us (see *Note How to report bugs::) the XML file
that causes this problem. We don't guarantee a rapid fix for each
particular problem but receiving real examples of missing
functionnalities will certainly help implementing them faster.


File: gtkada_ug.info,  Node: Binding new widgets,  Next: How to report bugs,  Prev: Support for Glade the Gtk GUI builder,  Up: Top

Binding new widgets
*******************

   GtkAda comes with a Perl script to help you create a binding to a C
widget (this is the script we have used ourselves).  This will not fully
automate the process, although it should really speed things up. You
will probably need less than 15 min to create a new binding once you
will get used to the way GtkAda works. Note that your C file should
have the same format as is used by Gtk+ itself.

   Here are the steps to create a new binding :

   * Give the 'generate.pl' script the C header file

   * The perl script should ask you for every field in the C structure
     if you want to create a function to make it accessible from Ada.
     Answer y or n (the default value is n, just press ENTER).

          $ generate.pl ../include/gtk/gtkbutton.h > temporary
            Create a function for the field child (of type GtkWidget*) [n]?
            Create a function for the field in_button (of type guint) [n]?
            Create a function for the field button_down (of type guint) [n]?

   * If you answered yes to at least one of the above questions, create
     a new C file, and move  the C part   of the temporary file created
     by generate.pl to this C file.

   * Do a gnatchop on the temporary file created by generate.pl

          $ gnatchop temporary

     This should create two Ada files (specification and body)

   * Edit these two files if needed (generally to change some parameters
      from Gint to Boolean for instance). It can be a little bit tricky
      when one of your functions returns a GList* or a GSList*. Please
     have   a look at `gtk-combo.ads' for examples how to do this.


File: gtkada_ug.info,  Node: How to report bugs,  Next: Bibliography,  Prev: Binding new widgets,  Up: Top

How to report bugs
******************

   GtkAda is becoming more and more stable due to its increasing use,
but you may still find bugs while using it. We have tried to test it as
much as possible, essentially by converting the testgtk.c file found in
the gtk distribution, as well as with generating a significant number
of interfaces using the GUI builder and Gate.  We strongly suggest that
you have a look at testgtk, which gives a lot of examples of how to use
this toolkit.

   There are two kinds of problems you can encounter:
   * If the gtk library itself was compiled with warnings turned on, you
     may get some  warnings messages,  mainly because of types problems.
     These warnings should not appear, as we have tried to be as type
     safe as possible  in this package. To know exactly where the
     problem is, compile your program with debug information, run gdb,
     and set a breakpoint on the function `g_log'. Then run your
     program as usual, using the `run' command. Then send us the result
     of the `where' command. Here is a summary:

          $ gnatmake -f -g <your_program_name> `gtkada-config`
          $ gdb <your_program_name>
          (gdb) break main
          (gdb) run
          (gdb) break g_log
          (gdb) continue
          ....
          (gdb) where

   * In  some  (hopefully) rare cases,   you can even get a
     segmentation fault within gtk.  That means there is definitly
     something wrong either in your program or in the toolkit.  Please
     check your program carefully and, if you think this is a problem
     in GtkAda itself, send us an e-mail.

   If you are a supported user of GNAT, send mail to
`mailto:report@gnat.com' to report errors, otherwise send mail to the
authors (`mailto:gtkada@ada.eu.org') explaining exactly what your are
doing,  what  is  the  expected  result  and  what  you actually get.
Please include the required sources to reproduce the problem, in a
format usable  by `gnatchop'  (basically, insert all  the required
sources at  the end of  the mail). Please  try to provide as small as
possible a  subset of your sources.

   Of course, we will  welcome any patch   you can provide, so  that
this toolkit may be as useful as possible.


File: gtkada_ug.info,  Node: Bibliography,  Prev: How to report bugs,  Up: Top

Bibliography
************

   We recommand the following documents. Most of them were written with
C in mind, but should be easily adapted after you've read the rest of
this document.

   * [1] "Gtk+/Gome Application Development" - Havoc Pennington This
     book, by one of the main authors of the the GNOME environment,
     describes in detail some of the inner mechanisms of gtk+, including
     signal handling, and a complete description of all the widgets and
     all the events found in `Gdk.Event'.

     It is worth noting that this book has been published under the Open
     Publication License. You can get an electronic copy of it at
     <http://www.opencontent.org/>.


