Ada Programming/Libraries/GUI/GtkAda

GtkAda is the Ada binding for the popular open-source GTK+ libraries. Can be used on multiple platforms.

Opening a File Chooser Dialog
A file chooser dialog is a convenient tool that gives the user convenient access to the filesystem when opening or saving a file. Gtk provides a handy  type that is fairly easy to setup and use.

As a C library, Gtk's library functions often have a variable number of parameters. Creation of a file chooser dialog typically involves passing the buttons you would want in the dialog's "action bar" as parameters to.

As an Ada library, GtkAda's subprograms never have a variable number of parameters. The following excerpt shows how to create a working file chooser dialog that will save a file.

An interesting implementation detail is that most of the types you want to work with are access types for tagged types. Indeed, the types  and   above are tagged types. The corresponding records will have nearly identical names:  and. Some other types are implemented as an "interface" called, and an example of this would be   ; it has no corresponding type named.

We bring this up primarily to explain why the first parameters in the calls to  have the form  ; the formal parameter has type , but the actual parameter has type. The latter conforms to the former, but Ada requires us to make this explicit.

Callbacks
A key concept of GtkAda is that of the "callback": the programmer can arrange that, when an event occurs relative to some widget, the widget "calls back" to some function. We illustrate how one add a button to a window's "button bar" and set up callback functions that activate whenever the user clicks and releases the button, or whenever the user presses a shortcut key, also called a "mnemonic".

Callback signatures
You typically need to define callbacks in a separate package, and each event's callback function must conform to a certain signature. The signatures that interest us are found in.

Most events allow you to assign a callback in two different ways. We will consider the slightly more complicated option; it offers a slot parameter of type. When you set up the callback, you can pass either the widget itself, another widget, or a custom  of your own making that contains information the callback needs to process the event. This latter type is probably the typical scenario, as most interface elements need to interact with other widgets and program data, and a slot is an easy way to make that work.


 * To handle the  with a slot, a callback must have the following signature:


 * To handle the  with a slot, a callback must have the following signature:

In each case,  refers to the slot parameter given when we assign the callbacks.

Defining the callbacks
In this case, we want the button to do the same thing, regardless of whether we activate it via button click or mnemonic. Since the callbacks' signatures differ, we can't use the same function to handle both. However, in this simple example we can just call one from the other. In a  package body we define the following functions (with corresponding package specification):

(Note: As far as the author can tell, Gtk always passes  to   when the user invokes a button by the mnemonic. The GtkAda documentation provides no information on what   is supposed to communicate.)
 * You may be wondering what the point of  and   are. In this particular application I may have no use for them, and can ignore them, but in some cases you might want to know if the user was holding the Control key when pressing the mouse button (included in the   parameter).


 * You will notice that the callback functions return a  value; its purpose is to indicate whether this callback has "completely handled" the event; if true, other handlers assigned to this widget and this event will not learn the event was handled. This is often the behavior you want, but in this example, returning   from the mnemonic allows Gtk to give visual feedback as if the button had been clicked-and-released. This will not happen if the callback returns.

Assigning the callbacks
Here we illustrate the creation of a button with a mnemonic in its label and the assignment of callbacks for both a mnemonic keypress and a press-and-release. This is not a full example; you will need to  and   the packages that contain the relevant types.

Reading
TBC

Building GUI with Glade3
As of 2012, there is the support of the interactive GTK builder Glade3. We describe a basic example of the different steps needed to build a "hello world" with Glade3.

Prerequisite
You must have GTKAda installed and the environment variable  set to find the project file For Windows,  should look like:

C:\GNAT\2012\lib\gnat;C:\GtkAda\lib\gnat (if you used the default locations)

Creating the XML description file
Glade3 generates interactively XML files that describes the UI. Our basic UI will contain a Main_Window with a label. We must take care of the termination by declaring a signal "destroy" in Main_Window to quit the app, otherwise the program will not end when we close the window.



Ada code
First, we declare the handler/callback that will be attached to the "destroy" signal. The callbacks must be in a package, otherwise you run into accessibility errors.

The Gobject event "destroy" is handled by "Main_Quit" in XML, and "Main_Quit" is implemented by the Ada procedure Simple_Callbacks.Quit.

The logical connection is :

Main program : simple_glade3.adb
Read the XML description, register the termination handler, connect, start the Gtk.Main.Main loop, and that's it.

More
For RAD, gate3 is an Ada code sketcher : you build the User Interface with glade3.8, and gate3 generates an Ada prototype that is a valid Ada code.

Complete demo programs available from Sourceforge


 * Lorenz chaotic attractor: Drawing demo with GTK timer loop.
 * Julia set: GTK interface mixed with Ada tasking.

Wikibook

 * Ada Programming
 * Ada Programming/Libraries
 * Ada Programming/Libraries/GUI

|GtkAda