~ubuntu-branches/ubuntu/feisty/fpc/feisty

« back to all changes in this revision

Viewing changes to fpcdocs/gtk1.tex

  • Committer: Bazaar Package Importer
  • Author(s): Torsten Werner
  • Date: 2007-01-27 20:08:50 UTC
  • mfrom: (1.2.3 upstream)
  • Revision ID: james.westby@ubuntu.com-20070127200850-9mrptaqqjsx9nwa7
Tags: 2.0.4-5
* Fixed Build-Depends.
* Add myself to Uploaders in debian/control.
* Make sure that the sources are really patched before building them.
* Build unit 'libc' on powerpc too.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
\documentclass[10pt]{article}
 
2
\usepackage{a4}
 
3
\usepackage{epsfig}
 
4
\usepackage{listings}
 
5
\lstset{language=Delphi}%
 
6
\lstset{basicstyle=\sffamily\small}%
 
7
\lstset{commentstyle=\itshape}%
 
8
\lstset{keywordstyle=\bfseries}%
 
9
\lstset{blankstring=true}%
 
10
\newif\ifpdf
 
11
\ifx\pdfoutput\undefined
 
12
  \pdffalse
 
13
\else
 
14
  \pdfoutput=1
 
15
  \pdftrue
 
16
\fi
 
17
\begin{document}
 
18
\title{Programming GTK in Free Pascal}
 
19
\author{Florian Kl\"ampfl\\and\\Micha\"el Van Canneyt}
 
20
\date{July 2000}
 
21
\maketitle
 
22
\section{Introduction}
 
23
The GTK library is a popular widget library for the X-Windows system.
 
24
It is used as the basis for the GIMP graphical manipulation program 
 
25
and for the GNOME application framework. With its ports to Microsoft 
 
26
Windows and BeOS, it allows to program a graphical interface for any
 
27
application in a platform independent way.
 
28
 
 
29
GTK is implemented in C, but it is possible to access its functionality from
 
30
Free Pascal. For this, its headers have been translated to Pascal,
 
31
so a program written in Free Pascal can make use of the functionality 
 
32
offered by GTK and its companion libraries GDK and GLIB. In fact, there is
 
33
an open source project (Lazarus) which makes use of GTK in order to build
 
34
an open-source alternative to the visual classes offered by Inprise's
 
35
Delphi.
 
36
 
 
37
This article intends to present an introduction to programming GTK in
 
38
Free Pascal. It by no means covers all of the functionality that GTK 
 
39
offers, as this would probably require a complete manual.
 
40
 
 
41
The first section gives some general considerations on the GTK toolkit.
 
42
 
 
43
\section{GTK is a C library}
 
44
Since GTK is an external library, some import units describing the calls in
 
45
the libraries are needed. Three libraries make up the GTK programming kit:
 
46
\begin{description}
 
47
\item[glib] this library contains some general programming tools, and
 
48
defines platform independent types, which are used throughout the other
 
49
libraries. To use this library, it is sufficient to include the 
 
50
\lstinline|glib| unit in your \lstinline|uses| clause.
 
51
\item[gdk] encapsulates the Windowing system (X or Windows) underlying GTK. 
 
52
It contains routines to draw on the screen, and react to various mouse or 
 
53
keyboard events. To use these
 
54
routines, the \lstinline|gdk| unit must be included in the \lstinline|uses|
 
55
 clause of a unit or program.
 
56
\item[gtk] contains the widget library. This is a series of controls such
 
57
as edit boxes, drop-down lists and many more, which are organised in an OOP
 
58
structure. Since the library is written in C, there is no programming 
 
59
language support for this structure.
 
60
 
 
61
All definitions of the gtk library are contained in the gtk unit, which
 
62
must be included in the \lstinline|uses| clause of any program or unit that needs their
 
63
functionality.
 
64
\end{description}
 
65
 
 
66
The GTK toolkit was programmed in C. This has some consequences for the
 
67
Pascal interface, since some C constructs do not port easily to Pascal.
 
68
When using the Pascal translation of the C headers, the following must be
 
69
kept in mind:
 
70
 
 
71
\begin{enumerate}
 
72
\item Reserved words: Pascal reserved words in types, record element names
 
73
etc. have been prepended with the word 'the'. For example \lstinline|label|
 
74
becomes \lstinline|thelabel|.
 
75
\item Functions and procedures have been kept with the same names. 
 
76
\item Types have been prepended with T, that is, the C type
 
77
\lstinline|GtkWidget| has become \lstinline|TGtkWidget|.
 
78
\item Pointers to types have been defined as the type name, prepended with a
 
79
P.  \lstinline|GtkWidget *| becomes \lstinline|PGtkWidget|. 
 
80
\item Records with bit-size elements: C allows to store parts of a record in 
 
81
individual bits; whereas in Pascal, the minimum size of an element in a
 
82
record is a byte. To accommodate this, functions were defined to retrieve
 
83
or set single bits from a record. The functions to retrieve a bit
 
84
have the name of the record field. The procedure to set a bit has 
 
85
the name of the field prepended with 'set\_'.
 
86
For example
 
87
\begin{lstlisting}[language=c]{cpackedstruct}
 
88
struct SomeStruct
 
89
{
 
90
  gchar *title;
 
91
  guint visible        : 1;
 
92
  guint resizeable     : 1;
 
93
};
 
94
\end{lstlisting}
 
95
translates to 
 
96
\begin{lstlisting}{ppackedstruct}
 
97
TSomeStruct = record
 
98
 title : Pgchar;
 
99
 flag0 : word;
 
100
end;
 
101
function  visible(var a: TGtkCListColumn): guint;
 
102
procedure set_visible(var a: TGtkCListColumn; __visible: guint);
 
103
function  resizeable(var a: TGtkCListColumn): guint;
 
104
procedure set_resizeable(var a: TGtkCListColumn;__resizeable: guint);
 
105
\end{lstlisting}
 
106
\item Macros. Many C macros have not been translated. The typecasting 
 
107
macros have been dropped, since they're useless under Pascal. 
 
108
Macros to access  record members have been translated, but they are to be
 
109
considered as {read-only}. So they can be used to retrieve a value, but 
 
110
not to store one. e.g. 
 
111
\begin{lstlisting}{macro}
 
112
function GTK_WIDGET_FLAGS(wid : pgtkwidget) : longint;
 
113
\end{lstlisting}
 
114
can be used to retrieve the widget flags, but not to set them. so things like 
 
115
\begin{lstlisting}{invaliduseofmacro}
 
116
GTK_WIDGET_FLAGS(wid):=GTK_WIDGET_FLAGS(wid) and someflag;
 
117
\end{lstlisting}
 
118
will not work, since this is a function, and NOT a macro as in C. 
 
119
\item Calling conventions: A C compiler uses another calling convention 
 
120
than the Free Pascal compiler. Since many GTK functions need a callback,
 
121
these callback must use the C calling convention. This means that every
 
122
function that is called by GTK code, should have the \lstinline|cdecl| 
 
123
modifier as a part of its declaration.
 
124
\end{enumerate}
 
125
 
 
126
Compiling a GTK application is no different than compiling any other Free
 
127
Pascal application. The only thing that needs to be done is to tell the free
 
128
Pascal compiler where the gtk, gdk and glib libraries are located on your
 
129
system. This can be done with the \verb|-Fl| command-line switch. For
 
130
example, supposing the gtk library is located in \verb|/usr/X11/lib|, the
 
131
following command-line could be used to compile your application:
 
132
\begin{verbatim}
 
133
ppc386 -Fl/usr/X11/lib mygtkapp.pp
 
134
\end{verbatim}
 
135
This example supposes that the gtk unit is be in your unit search path. If
 
136
it is not, you can add it with the \verb|-Fu| switch.
 
137
 
 
138
\section{The bricks of a GTK application}
 
139
The building-blocks of a a GTK application are the {\em widgets}. 
 
140
Widgets are the equivalent of Delphi's controls. And although GTK 
 
141
is not an object oriented library, the library defines a record 
 
142
\lstinline|TGtkWidget| which contains all settings common to all
 
143
widgets; all widgets start with this record, and add their own 
 
144
specific data to it. This creates a tree-like structure with all 
 
145
the widgets present in the GTK library, to which your own widgets 
 
146
can be added.
 
147
 
 
148
All functions that create a particular widget return a pointer
 
149
to a \lstinline|TGtkWidget| record. It is not recommended to 
 
150
manipulate the contents of the widget record directly; GTK offers 
 
151
many functions to manipulate the members of the record, e.g.  
 
152
\lstinline|gtk_widget_set_parent| or \lstinline|gtk_widget_get_name|.
 
153
To this set of functions, each new widget adds a few functions that are 
 
154
specific to this particular widget. 
 
155
 
 
156
Each widget has a specific function and a specific look; there are many
 
157
widgets to choose from. A complete list of widgets is outside the scope of
 
158
this article; the GTK reference manual offers an overview of available
 
159
widgets. In general it can be said that most widgets one would expect
 
160
are present in the GTK library: Edit fields, buttons, check-boxes, various 
 
161
lists, menus, combo-boxes, tree views, and some pre-defined dialogs. 
 
162
 
 
163
Any of these widgets is created with a \lstinline|gtk_WIDGET NAME_new| call. 
 
164
This call can accept arguments; The number and type of arguments depend 
 
165
on the widget. 
 
166
For example, to create a button that displays a text, the call is defined 
 
167
as follows:
 
168
\begin{lstlisting}{}
 
169
gtk_button_new_with_label(ALAbel : PChar)
 
170
\end{lstlisting}
 
171
All widgets can be destroyed with the \lstinline|gtk_widget_destroy| call,
 
172
irrespective of their type.
 
173
 
 
174
\section{Showing things on the screen}
 
175
To show things on the screen, it is necessary to create a window. A window
 
176
is created with the the \lstinline|gtk_window_new| call. This call accepts 
 
177
as an argument the type of window to be created. 
 
178
 
 
179
Creating a window creates it's structure in memory, but doesn't show it on 
 
180
screen. To show this window on the screen,a call to the 
 
181
\lstinline|gtk_widget_show| function is needed, as can been seen in
 
182
example 1.
 
183
\lstinputlisting{gtkex/ex1.pp}
 
184
If the window contains widgets, the \lstinline|gtk_widget_show| function
 
185
must be called for each widget. 
 
186
 
 
187
Looking at example 1, one notices 2 special calls: \lstinline|gtk_init| and
 
188
\lstinline|gtk_main|. These calls should be present in any program that uses
 
189
the GTK library.  
 
190
 
 
191
The first call initialises the GTK library. Among other things, it reads
 
192
the command-line to see e.g. which display should be used.
 
193
 
 
194
The second call is the heart of the GTK widget library: It starts the
 
195
message loop of GTK. This call will not return, unless somewhere else
 
196
in the program \lstinline|gtk_main_quit| is called. As long as the call
 
197
doesn't return, GTK will wait for events such as mouse clicks, key-presses
 
198
and so on. It will handle these events, but it will not notify you of any 
 
199
of these events except if you specifically ask for it. 
 
200
 
 
201
A window by itself is of course not very interesting. To make it more
 
202
interesting, some elements should be added. 
 
203
 
 
204
Adding a widget to a parent is done with the \lstinline|gtk_container_add|
 
205
call. This call places a widget in a container. A container is a widget 
 
206
which can contain other widgets; not all widgets are containers, however.
 
207
 
 
208
Example 2 shows how to add a widget (a button) to a container (the window
 
209
in this case). It also shows that the container has some specific
 
210
properties, which can be manipulated as well (in this case, the border
 
211
width). Since not each widget is a container, the window pointer must be
 
212
typecasted to \lstinline|GTK_CONTAINER| in order to be accepted by the
 
213
container handling calls.
 
214
 
 
215
\lstinputlisting{gtkex/ex2.pp}
 
216
 
 
217
Adding more than 1 widget to a container is not trivial in GTK. The reason
 
218
for this is that GTK has not been designed to set widgets at a specific
 
219
location in their parent widget. Instead, GTK asks that you 'pack' your
 
220
objects in their parent widget. This means that if the parent widget is
 
221
resized, it's child widgets are resized as well, depending on the packing
 
222
options that were set.
 
223
 
 
224
One of the reasons that the GTK library was set up this way, is that the
 
225
size of a widget is not well-defined. For instance, the size of a button
 
226
depends on whether it is the default widget of the window or not. Given 
 
227
that this is so, the placement of such a button is not well-defined either.
 
228
 
 
229
The most common ways of packing widgets in a parent widget are the
 
230
following:
 
231
\begin{enumerate}
 
232
\item using a vertical box.
 
233
\item using a horizontal box.
 
234
\item using a table.
 
235
\end{enumerate}
 
236
We'll discuss these ways in the subsequent. There are other ways, but these
 
237
are probably the most important ones.
 
238
 
 
239
\subsection{Using boxes}
 
240
 
 
241
A horizontal or vertical box can be used to contain a row or column of
 
242
widgets. Various options can be set to modify the spacing between the 
 
243
widgets, the alignment of the widgets in the box, or the behaviour of 
 
244
the box when the user resizes the parent widget. Boxes work only in 
 
245
one direction. The widgets inside a horizontal box always have the height of
 
246
the box, and widgets in a vertical box always have the width of the vertical
 
247
box.
 
248
 
 
249
You can create a horizontal box with the \lstinline|gtk_hbox_new| call. 
 
250
It accepts 2 arguments: The first one is a boolean. It tells GTK whether the
 
251
children should have the same space in the box. The second one is an
 
252
integer, which tells GTK how much space to leave between the widgets in the
 
253
box. Likewise, a vertical box can be created with the
 
254
\lstinline|gtk_vbox_new| call. This call accepts the same arguments as the
 
255
first box.
 
256
 
 
257
Adding widgets to a box happens with the \lstinline|gtk_box_pack_start| or
 
258
\lstinline|gtk_box_pack_end| calls. The former adds a widget at the start
 
259
of the box, the latter adds a widget at the end of the box. Both functions
 
260
accept the same arguments:
 
261
\begin{lstlisting}{boxarguments}
 
262
(Box : PGtkBox; Widget: PGtkWidget;
 
263
 expand gboolean; fill : gboolean;padding : guint);
 
264
\end{lstlisting}
 
265
The \lstinline|expand| argument tells the box whether it should take the
 
266
size of it's parent widget, or whether it should resize itself so that it is
 
267
just large enough to fit the widgets. The latter allows to justify the
 
268
widgets in the box (but only if the box is {\em not} homogeneous.  
 
269
If the box should keep the size of it's parent, then the \lstinline|fill| 
 
270
argument decides what is done with the extra space available. 
 
271
 
 
272
If \lstinline|fill| is \lstinline|True| then the extra space is
 
273
divided over the widgets. If \lstinline|fill| is \lstinline|False| then the
 
274
extra space is put in between the widgets. 
 
275
 
 
276
The \lstinline|padding| adding tells the box to add extra space for this 
 
277
particular widget.
 
278
 
 
279
The following program shows the use of a box:
 
280
\lstinputlisting{gtkex/ex3.pp}
 
281
What the program does is the following: It creates a window, which it splits
 
282
up in two halves by means of the \lstinline|totalbox| widget. This is a
 
283
vertical box, which will contain two other boxes: a vertical box and a
 
284
horizontal box. Each of these two boxes is filled with buttons.
 
285
The behaviour of the boxes can be seen when the window is resized.
 
286
 
 
287
The effect of the various arguments to the pack calls can be seen by
 
288
changing the arguments and recompiling the example.
 
289
 
 
290
\subsection{Using tables}
 
291
A table is used to set widgets in a grid inside the parent widget. It acts
 
292
like a grid with cells, in which you can 'hang' your widgets. If the user 
 
293
resizes the parent widget, then the size of the grid cells changes, and 
 
294
the widgets will change their location and size, based on the size of the 
 
295
new grid cells. 
 
296
 
 
297
To create a table to manage a window's layout, the \lstinline|gtk_table_new|
 
298
call is used. It accepts 3 arguments: the number of rows, the number of
 
299
columns and a boolean which tells GTK whether the cells should always have
 
300
the same size or not. 
 
301
 
 
302
To add a widget to a table, the \lstinline|gtk_table_attach| call is used.
 
303
It is declared as
 
304
\begin{lstlisting}{}
 
305
gtk_table_attach(Table: PGtkTable;Widget: PGtkWidget;
 
306
                 Left, right, top, bottom : guint;
 
307
                 Xoptions,Yoptions : TGtkAttachOptions;
 
308
                 Xpadding,Ypadding : Guint);
 
309
\end{lstlisting}
 
310
The first two options of this call are self-explanatory. The next four
 
311
options, however, need some explanation. Contrary to what the name 'table'
 
312
suggests, these do {\em not} specify the coordinates of cells; instead, they
 
313
specify the grid lines that delimit the cells. 
 
314
 
 
315
\begin{figure}
 
316
\caption{Placing widgets in a table.\label{fig:table}}
 
317
\begin{center}
 
318
\ifpdf
 
319
\epsfig{file=table.pdf}
 
320
\else
 
321
\epsfig{file=table.eps}
 
322
\fi
 
323
\end{center}
 
324
\end{figure}
 
325
 
 
326
Figure \ref{fig:table} represents a table with 5 rows and 5 columns, with
 
327
cells of the same size. The call to create this table could be:
 
328
\begin{lstlisting}{}
 
329
maintable:=gtk_table_new(5,5,TRUE);
 
330
\end{lstlisting}
 
331
To hang a widget in this table, so it starts in cell (2,1) and ends in cell
 
332
(3,2), where the cells are counted starting with 0, it is necessary to tell 
 
333
GTK that the widget starts at horizontal grid line 2, and ends at horizontal
 
334
grid line 4. Vertically, it starts at grid line 1, and ends at grid line 3. 
 
335
This means that the following call would place the widget at its correct
 
336
location:
 
337
\begin{lstlisting}{}
 
338
gtk_table_attach(maintable,mybutton,
 
339
                 2,4,1,3,
 
340
                 GTK_EXPAND OR GTK_FILL,GTK_EXPAND OR GTK_FILL,
 
341
                 0,0);
 
342
\end{lstlisting}
 
343
GTK delivers a shorter form of this call:
 
344
\begin{lstlisting}{}
 
345
gtk_table_attach_defaults(maintable,mybutton,2,4,1,3);
 
346
\end{lstlisting}
 
347
The parameter \lstinline|GTK_EXPAND or GTK_FILL| tells GTK that the widget 
 
348
should always take up the full space assigned to it.
 
349
 
 
350
The following example program illustrates the use of a table in a gtk
 
351
application:
 
352
\lstinputlisting{gtkex/ex4.pp}
 
353
The example creates a table with 6 rows and 6 columns. It places 3 buttons, 
 
354
each at a different location in the table, with different sizes. The first
 
355
button has a width and height of 1 cell and is located at cell (1,1). The 
 
356
second has a width and height of two cells, and is located at cell (3,1).
 
357
The last button is 4 cells wide and has a height of 1 cell, and is located
 
358
at cell (1,4). When the window is resized, the cells are resized as well,
 
359
and the buttons follow the size of the cells.
 
360
 
 
361
{\em Remark:} because the table has homogeneous cells, the minimum width 
 
362
and height of the cells is determined by the first button (in this case). 
 
363
Since all cells must have the same size, this means that the minimum size 
 
364
of the window is 6 times the size of the first button (plus a border).
 
365
 
 
366
\section{Reacting to user input}
 
367
So far, the example programs did not react to button clicks or any other user
 
368
action other than closing the window. To make a window respond to user
 
369
actions, it is necessary to install signal callbacks or event handlers.
 
370
 
 
371
The difference between signals and events is that signals come from the GTK
 
372
toolkit. Events come from the underlying window system (X or Windows).
 
373
For example, 'button\_pressed' is an event that is generated by the window
 
374
system when the user clicks with his mouse. It is possible to react to 
 
375
this event. 
 
376
 
 
377
On the other hand, a button widget defines a signal 'clicked'. 
 
378
The 'clicked' event will occur when the user clicks on the button. 
 
379
So, many signals that are defined by GTK widgets are just a translation 
 
380
of events to something specific for that widget.
 
381
 
 
382
Since calls to connect to a signal or to an event are the same, in what
 
383
follows the discussion will be restricted to signals, but all that is 
 
384
said is also true for events.
 
385
 
 
386
GTK has essentially 2 ways to install signal callbacks. The only difference
 
387
between these calls is the arguments that the callback function accepts.
 
388
 
 
389
The first way to install a callback is using the
 
390
\lstinline|gtk_signal_connect| function. This function is declared as
 
391
follows:
 
392
\begin{lstlisting}{}
 
393
TGtkSignalFunc = procedure ;cdecl;
 
394
Function gtk_signal_connect(TheObject:PGtkObject;Name:Pgchar;
 
395
                            Func:TGtkSignalFunc;Data:gpointer):guint;cdecl;
 
396
\end{lstlisting}
 
397
 
 
398
The first argument of this call (\lstinline|TheObject|) is the object 
 
399
(usually a widget) to which you want to assign an event handler. The second
 
400
parameter, \lstinline|Name|, is the event you wish to catch with this
 
401
callback (an example could be 'clicked' for a button). The third argument
 
402
(\lstinline|Func|) is the function that should be called when the event occurs. 
 
403
The \lstinline|Data| argument is a pointer to arbitrary data. This pointer
 
404
will be passed on to the callback function \lstinline|func| when the event
 
405
occurs.
 
406
 
 
407
The \lstinline|gtk_signal_connect| function returns an integer. This integer 
 
408
is the number of the callback for this event. It is possible to attach more 
 
409
than one callback to an event in GTK. When the event occurs, the callbacks 
 
410
will be executed in the order that they have been attached to the widget. 
 
411
 
 
412
The declaration of the \lstinline|TGtkSignalFunc| type requires that every
 
413
callback function that is passed to GTK must be typecast. Since GTK defines
 
414
only one function to set a signal handler, this is necessary, since
 
415
callbacks can have different forms. This mechanism is error-prone, since
 
416
in this manner it is possible to pass a function to GTK which has the wrong
 
417
number of arguments.
 
418
 
 
419
However, most callbacks must be of the form:
 
420
\begin{lstlisting}{}
 
421
Function (Widget : PGtkWidget; Data : GPointer) : guint;cdecl;
 
422
\end{lstlisting}
 
423
Such a callback function accepts 2 arguments: the first argument
 
424
(\lstinline|Widget|) is the widget which caused the event 
 
425
(for example, the button which was clicked). The second argument is a
 
426
pointer to arbitrary data. This is the pointer that was passed as
 
427
\lstinline|Data| when the callback was installed.
 
428
 
 
429
Signals are identified by their name. The GTK reference guide contains a
 
430
complete list of supported signals.
 
431
 
 
432
The first example shows how a handler for the 'destroy' signal of the
 
433
window is installed. When the window-manager kills the window, this 
 
434
signal is sent. The \lstinline|gtk_main_quit| instructs GTK that it 
 
435
should stop processing X events and exit the \lstinline|gtk_main| call.
 
436
 
 
437
A second method to connect a callback to a signal is using the
 
438
\lstinline|gtk_signal_connect_object| call. This call is defined as
 
439
follows:
 
440
\begin{lstlisting}{}
 
441
Function gtk_signal_connect_object(theobject:PGtkObject;
 
442
                                   name:Pgchar;
 
443
                                   func:TGtkSignalFunc;
 
444
                                   slot_object:PGtkObject):guint;cdecl
 
445
\end{lstlisting}
 
446
It is similar in function to the \lstinline|gtk_signal_connect| function,
 
447
only it doesn't allow to pass arbitrary data to the signal handler. Instead,
 
448
the handler must {\em always} be of the following form:
 
449
 
 
450
\begin{lstlisting}{}
 
451
Function (AnObject : PGtkObject);
 
452
\end{lstlisting}
 
453
The \lstinline|slot_object| pointer that was provided in the call to
 
454
\lstinline|gtk_signal_connect_object| will be passed as the
 
455
\lstinline|AnObject| argument to this function. Many GTK functions have the
 
456
above form; this makes it possible to attach a GTK internal function to a
 
457
signal.
 
458
 
 
459
To illustrate this, the second example is modified so that clicking the button
 
460
will also close the window:
 
461
\lstinputlisting{gtkex/ex5.pp}
 
462
In the example, the call to \lstinline|gtk_signal_connect_object| will
 
463
connect the 'clicked' signal of the button to the
 
464
\lstinline|gtk_widget_destroy| function of GTK, and passes the pointer to
 
465
the window widget to it. When the user clicks the button, the
 
466
\lstinline|gtk_widget_destroy| function will be called with as argument the
 
467
pointer of the window object. As a result, the window widget will be
 
468
destroyed, it's 'destroy' signal will be activated, and the
 
469
\lstinline|gtk_main_quit| function will be called through the program's
 
470
'destroy' handler for the window.
 
471
 
 
472
Since the signal handler connect call returns an integer by which it can 
 
473
be identified, it is possible to manipulate or even remove the handler 
 
474
once it has been installed.
 
475
 
 
476
For instance it is possible to temporarily disable a signal handler with the 
 
477
\lstinline|gtk_signal_handler_block| call, and to enable it again with the
 
478
\lstinline|gtk_signal_handler_unblock| call. An example of how to do this
 
479
can be found in the following example:
 
480
\lstinputlisting{gtkex/ex6.pp}
 
481
There are other things that one can do with signal handlers, but a complete
 
482
discussion of all possibilities is outside the scope of this article.
 
483
 
 
484
Some widgets do not have their own window; i.e. they do not receive events
 
485
from the underlying windowing system. An example of such a widget is a
 
486
label. A label just draws it's text on it's parent widget, and nothing else.
 
487
 
 
488
To be able to respond to certain events, an event-box must be used, and the 
 
489
window-less widget must be placed in it. An event-box can be created with
 
490
the \lstinline|gtk_event_box_new| call. This call accepts no arguments.
 
491
 
 
492
To this event-box, a window-less widget can be added. The event-bow will
 
493
then capture events for the window-less widget. The following example shows
 
494
how to use an event-box to detect when the mouse pointer is moved over a
 
495
label:
 
496
\lstinputlisting{gtkex/ex7.pp}
 
497
If the mouse pointer is moved over the first label, the text of the second
 
498
label is adapted accordingly. The example also shows the use of
 
499
\lstinline|gtk_widget_show_all|, which shows a widget and all widgets
 
500
contained in it.
 
501
 
 
502
\section{A touch of style}
 
503
The look of a GTK application is controlled through the use of styles. A
 
504
style controls the colors in which a widget is drawn, in various states.
 
505
As an example: a widget may be drawn differently depending on whether it 
 
506
has focus or not. How to draw the widget in each of this states is described
 
507
in the style of the widget.
 
508
 
 
509
GTK recognizes the following states of a widget:
 
510
\begin{description}
 
511
\item[NORMAL] The normal state of a widget. No mouse over it.
 
512
\item[PRELIGHT] Is the state of a widget when the mouse is over it.
 
513
\item[ACTIVE] Is the state of a widget when it is pressed or
 
514
clicked.
 
515
\item[INSENSITIVE] if the widgets is disabled ('grayed').
 
516
\item[SELECTED] When the object is selected.
 
517
The GTK unit has a constant for each of these states; it is the above name
 
518
with \lstinline|GTK_STATE_| prefixed, so e.g. \lstinline|GTK_STATE_NORMAL|
 
519
for the normal state.
 
520
 
 
521
\end{description}
 
522
 
 
523
 
 
524
Each widget class has a default style in which it is drawn. If you wish to
 
525
change the way all these widgets look, you should change the default style
 
526
of this class. If you want to change the way one particular widget looks,
 
527
you should make a new style, and apply it to that particular widget. It is
 
528
possible to make a copy of an existing style and modify the copy before
 
529
applying it.
 
530
 
 
531
It is also possible to change the default style of widgets. Changing the
 
532
default style of widgets will have effect on all widgets created after the
 
533
new style was set. Widgets created before that will be unaffected.
 
534
 
 
535
The following example shows how to set the color of a label. It takes a
 
536
copy of the standard label style, and modifies it so the foreground color
 
537
becomes red. It then applies the modified style to the first label.
 
538
The second label is unaffected by this change
 
539
\lstinputlisting{gtkex/ex8.pp}
 
540
 
 
541
The last example shows how to change the color of a button when the mouse
 
542
moves over it.
 
543
\lstinputlisting{gtkex/ex9.pp}
 
544
 
 
545
\section{Carrying on}
 
546
In the previous sections, some basic concepts of GTK have been introduced.
 
547
However, GTK is a big toolkit and much more can be said about it. It is
 
548
outside of the scope of the current article to describe all Widgets in the
 
549
GTK library. The range of offered widgets is broad, and there probably is a
 
550
widget for each conceivable task. If there is a missing widget, it is always
 
551
possible to write a new widget. 
 
552
 
 
553
In principle, therefore, GTK is suitable to write large applications, also
 
554
when writing in Free Pascal. However, the fact that it is written in C and 
 
555
it's interface is C oriented, justifies the writing of a small Pascal Object 
 
556
Oriented wrapper around it. 
 
557
The following arguments show the need for such a wrapper:
 
558
\begin{enumerate}
 
559
\item C has no object-oriented language constructs. This makes it necessary
 
560
to do a lot of typecasts in GTK calls. Using Classes or Objects, this is no
 
561
longer necessary, and will improve code readability substantially.
 
562
\item C uses null-terminated strings. It can be useful to wrap calls that
 
563
need a null-terminated string into one that accepts a normal string as an
 
564
argument. Using ansistrings will make the conversion to null-terminated
 
565
strings easier.
 
566
\item The signal mechanism of GTK destroys the strong type checking of
 
567
Pascal. When compiling the statement 
 
568
\begin{lstlisting}{}
 
569
  Button.OnClick:=@MyForm.OnButtonClick
 
570
\end{lstlisting}
 
571
The compiler checks that the \lstinline|OnButtonClick| method can be
 
572
assigned to the \lstinline|OnClick| event. Under GTK, it is possible
 
573
to pass any function as a handler for a signal, as in
 
574
\begin{lstlisting}{}
 
575
gtk_signal_connect (PGTKOBJECT (window), 'destroy',
 
576
                    GTK_SIGNAL_FUNC (@destroy), NULL);
 
577
\end{lstlisting}
 
578
This can lead to errors if the \lstinline|destroy| procedure accepts a
 
579
different number of arguments, or other arguments than the ones that 
 
580
GTK provides. Therefore it would be a good idea to implement methods that
 
581
would force type checking, e.g:
 
582
\begin{lstlisting}{}
 
583
Button.AddOnClick(@MyForm.OnButtonClick);
 
584
\end{lstlisting}
 
585
Such a statement would only compile if the \lstinline|OnButtonClick| would
 
586
be of the right type.
 
587
\end{enumerate}
 
588
Additional benefits of making such a wrapper would be simpler code, and
 
589
hence better readability. Both improve the maintainability of the code as well,
 
590
which are all important factors when writing a large application.
 
591
\end{document}