Você está na página 1de 50

Rick Duley

Perth, Western Australia


2009
Gadget: Building a Compound Widget with GtkAda


DOCUMENT CURRENT ONLY WHEN PRINTED
c:\documents and settings\rick\desktop\gadget.docx
Printed on Wednesday, 2 February 2011
Page i of 50
i


Table of Contents
1 Preamble....................................................................................................... 1
2 Introduction .................................................................................................. 1
2.1 Why Verbose Code? .............................................................................. 1
2.2 On Being Methodical ............................................................................. 2
3 Getting GtkAda ............................................................................................. 2
3.1 Glade ..................................................................................................... 2
3.2 GtkAda Documentation ......................................................................... 2
4 Preparations.................................................................................................. 2
4.1 The Mud Map ........................................................................................ 2
4.1.1 Connotative Identifiers .................................................................. 2
4.1.2 Base Boxes ..................................................................................... 3
4.1.3 HBoxes and VBoxes ........................................................................ 3
5 The Cardinal Rule .......................................................................................... 4
6 Other Packages Required .............................................................................. 4
6.1 Mainline ................................................................................................ 5
6.1.1 Set_Locale ..................................................................................... 5
6.1.2 Init ................................................................................................. 5
6.1.3 Show_All ........................................................................................ 5
6.1.4 Main .............................................................................................. 5
6.1.5 The Pragma .................................................................................... 5
6.2 Portability Package ................................................................................ 5
6.3 Callbacks Package .................................................................................. 6
6.3.1 Item Types Requiring Callbacks ...................................................... 6
6.4 Handler Packages .................................................................................. 7
6.5 Toplevel Widget Package ...................................................................... 7
7 Playing with LEGO Blocks ............................................................................... 7
7.1 Setting up the Window .......................................................................... 7
7.1.1 Setting Window Characteristics ...................................................... 7
7.1.2 Sneak a Preview ............................................................................. 9
7.2 Boxes in the Window ............................................................................. 9
7.2.1 Create Window_Base_HBox ........................................................... 9
7.2.2 Create Window_VBox .................................................................... 9
7.2.3 Set the Boxes in the Window ......................................................... 9
7.3 Install a Menu Bar .................................................................................. 9
7.3.1 Menu_Base_Box ............................................................................ 9
7.3.2 Menu_Bar ...................................................................................... 9
Gadget: Building a Compound Widget with GtkAda


DOCUMENT CURRENT ONLY WHEN PRINTED
c:\documents and settings\rick\desktop\gadget.docx
Printed on Wednesday, 2 February 2011
Page ii of 50
ii


7.3.3 Create the File Menu.................................................................. 10
7.3.4 The New Tab .............................................................................. 10
7.3.5 Sneak a Preview ........................................................................... 11
7.4 Install Textedit Screen ........................................................................ 11
7.4.1 Scrolled_Window ......................................................................... 11
7.4.2 Setting Screen Characteristics ...................................................... 11
7.5 Install an Horizontal Separator ............................................................. 11
7.5.1 Sneak a Preview ........................................................................... 11
7.6 Create the Keyboard ............................................................................ 12
7.6.1 Create the Boxes for the Keyboard ............................................... 12
7.6.2 Create and Install BigButton........................................................ 12
7.6.3 Create and Install the Vertical Separator ...................................... 12
7.6.4 Create and Install the Three Small Buttons ................................... 12
8 It is Done ..................................................................................................... 13
8.1 Removing the Command Screen .......................................................... 13
9 Gadget: Exploded Diagram .......................................................................... 14
10 Code ........................................................................................................... 15
10.1 Mainline Gadget.adb ....................................................................... 15
10.2 Portability Package .............................................................................. 16
10.2.1 Specification Gadget_Intl.ads ................................................... 16
10.2.2 Implementation Gadget_Intl.adb ............................................. 16
10.3 Callbacks Package ................................................................................ 17
10.3.1 Specification Gadget_Package.Callbacks.ads ............................ 17
10.4.1 Specification Callbacks_Gadget.ads ......................................... 21
10.5 Development Package ......................................................................... 22
10.5.1 Specification Gadget_Pkg.ads .................................................. 22
10.5.2 Implementation Gadget_Pkg.adb ............................................ 25
11 Reference List ............................................................................................. 47










Gadget: Building a Compound Widget with GtkAda


DOCUMENT CURRENT ONLY WHEN PRINTED
c:\documents and settings\rick\desktop\gadget.docx
Printed on Wednesday, 2 February 2011
Page 1 of 50
1


Gadget:
Building a Compound Widget
with GtkAda
Rick Duley
Perth, Western Australia

Under Australian Law (The Copyright Act of 1968 and Amendments)
this work is copyright to the author by fact of its creation and
commission to a storage medium.
Proprietary rights are hereby waived provided the work is used for
educational purposes,
AND that the work is presented in full and unmodified,
AND that this copyright remains attached and unmodified,
All moral rights under the Australian Copyright Amendment (Moral
Rights) Act of 2000 are reserved.


1 Preamble
The author would like to acknowledge
the gallant and patient assistance of
the people from AdaCore, the Gnat
Academic Program, the GtkAda
Mailing List, and others without which
he would not have made it this far.
This document is humbly presented in
the hope that its availability will
lessen those peoples future torment.
Thanks folks!
2 Introduction
This article is intended to save GtkAda
Newbies from some of the pain they
might experience in learning how to use
the system. It traces the construction
of a compound widget in verbose code
format with comments on the actions of
parameters, what they do and what the
options are.
Gadget will not actually do anything
except allow text to be entered into the
text window. This is merely an exercise
in making the composite widget appear
the way it is planned.
It is almost certainly not perfect
merely an attempt to help. For
resolution of matters not dealt with
here go to
http://libre.adacore.com/libre/tools/gt
kada/ and register with the GtkAda
Mailing list. (Go to the bottom of the
page and the paragraph beginning,
Note that the .
2.1 Why Verbose Code?
GtkAda from AdaCore comes with an
automated developer called Glade (ref:
paragraph 3.1 on page 2). This lets a
programmer create an interface by
sight, then it creates the code to suit.
One of the problems with Newbies
learning GtkAda by working with Glade
is that Glade code does not specify the
origin of the widgets and things it uses.
Glade religiously implements the use
clause. Consequently, beginners do not
learn to work with the GtkAda
Reference Manual. Because of that
they get to know that the code works,
but they do not get to know how it
works.
Verbose style programming changes
this because the relevant package is
named at each procedure or function
call. Furthermore, many of the
procedures and functions implemented
are inherited from ancestor widgets.
Programmers must learn to trace the
ancestry of the current widget to find
the appropriate operation.
Verbose style programming means a lot
of typing, but, in the end, it is quicker
for a beginner. Programmers tend to
think more carefully about each step.
Therefore, they avoid unending
confusion. Time spent typing is more
than compensated for with time saved
debugging.
Meticulously naming formal parameters
and assigning values to them forces
Gadget: Building a Compound Widget with GtkAda


DOCUMENT CURRENT ONLY WHEN PRINTED
c:\documents and settings\rick\desktop\gadget.docx
Printed on Wednesday, 2 February 2011
Page 2 of 50
2


programmer to think carefully about
those values as well.
Another error which is frequent when
assigning parameter values by
association is that of getting the actual
parameters in the wrong order. This
glitch can be one of the hardest to find.
This virtually never happens in verbose
programming, and if it does it doesnt
matter
2.2 On Being Methodical
All programming is methodical in
nature graphics programming
especially so. Consider the exploded
construction diagram on page 14.
Dont Panic! For the moment, note
only that it starts with the base widget
(the window itself) and progressively,
working to the right, adds further
widgets. In turn, each of these widgets
is created, its characteristics are
defined, and it is added to the widget to
its left. (There are other things that go
on but they are not important just yet,)
Keep this idea of being methodical in
mind. It is the basis of the whole
process.
3 Getting GtkAda
For a great start contact gap-
contact@adacore.com and get registered
with the GNAT Academic Program run
by AdaCore. Then you can download
the GAP Package which includes a
quality Integrated Development
Environment, complete with compiler
and support packages including Win32
and GtkAda. The best advice is to
download and install the lot using the
default installation settings.
3.1 Glade
The GtkAda package includes the
executable for Glade, an interactive
GUI-builder package. I unashamedly
used this package to learn many of the
rudiments of GtkAda programming.
However, the true power and range of
the GtkAda package is only realised by
manually coding it. Learning some of
the skills required to do that is the
object of this exercise.
3.2 GtkAda Documentation
Full HTML documentation is included
in the GtkAda package. If you have
used all the default settings it can be
found at
c:\GtkAda\share\doc\gtkada\. I refer
to these documents all the time so I
have shortcuts to them on my desktop.
Information on the functions of widgets
and the meanings of formal parameters
presented here is largely taken from
these documents.
4 Preparations
Building a compound widget with
GtkAda is like building something with
LEGO blocks. You simply take the
pieces and plug them together. This,
however, is not a childs game. Working
with GtkAda requires planning. The
programmer must know exactly what is
to be built before coding starts.
Anything other than forethought and
planning in fine detail is a recipe for
frustration and futility. Be warned!
4.1 The Mud Map
Programmers should draw what
Australians call a Mud Map before doing
anything else. A Mud Map, strictly
speaking, is a sketch scraped in the dirt
with a finger or a stick. Its just
something to get a rough idea. Draw
that sort of a sketch of the layout to be
achieved including all the visible and
invisible widgets to be included in the
compound widget. Leave nothing out,
and name all the parts in a logical,
distinctive and connotative manner.
Such a mud map for Gadget is shown
in Figure 1. Remember, an exploded
diagram of Gadget is shown on page 14
and that may make the design more
clear.
4.1.1 Connotative Identifiers
Make sure the names of the widgets are
distinctive and self-explanatory at the
time you draw your Mud Map, and use
them when you program. Call the
widgets anything you wish, but make
sure the name describes what the
widget or variable does. Do not accept
the identifiers I used as any ultimate.
This idea of the use of connotative
identifiers is one of the foundation
principles of Ada Programming which
is what you will be doing in this
exercise. The Style Manual still offers
these suggestions:
Gadget: Building a Compound Widget with GtkAda


DOCUMENT CURRENT ONLY WHEN PRINTED
c:\documents and settings\rick\desktop\gadget.docx
Printed on Wednesday, 2 February 2011
Page 3 of 50
3


choose names that are as self-
documenting as possible;
use names given by the application;
do not use obscure jargon;
avoid using the same name to declare
different kinds of identifiers;
do not use an abbreviation of a long
word when a shorter synonym exists;
use a consistent abbreviation strategy;
do not use ambiguous abbreviations;
to justify its use, an abbreviation must
save many characters over the full
word;
use abbreviations that are well-
accepted in the application domain;
and
maintain a list of accepted
abbreviations, and use only
abbreviations on that list. (Software
Productivity Consortium, 1995)
4.1.2 Base Boxes
Surround each individual widget below
the Top-level widget, including multiple-
cell boxes, in a single-cell box. It is a
little complicated but it does ensure
that the visible widgets (e.g. buttons,
screens, and separators) will appear as
you expect them to appear.
4.1.3 HBoxes and VBoxes
As you can see, The_Gadget uses two
VBoxes and one HBox. If you have
played with Glade you will know that

Figure 1: Gadget Mud Map
Gadget: Building a Compound Widget with GtkAda


DOCUMENT CURRENT ONLY WHEN PRINTED
c:\documents and settings\rick\desktop\gadget.docx
Printed on Wednesday, 2 February 2011
Page 4 of 50
4


you can specify the number of cells in a
box. When you are coding manually
you do not have, or need, that option.
Programmers arrange things so that
each item added will appear below the
one before (in VBoxes) or to the right of
the one before (for HBoxes).
Gadget uses only HBoxes and VBoxes.
More specific control of layout is
available through use of ButtonBoxes
but that is complexity and
sophistication not warranted here.
5 The Cardinal Rule
As St Paul put it,
"Let all things be done decently and in
order."--1 Corinthians 14:40.
Take a look at the exploded diagram of
Gadget shown on page 14. The General
Plan of Attack is:
1. Create Gadget_Record,
Window_Base_HBox, and
Window_VBox.
2. Install Window_VBox in
Window_Base_HBox, then install
Window_Base_HBox in
Gadget_Record (the window). This
completes the foundation of the
compound widget.
3. Create Menu_Base_HBox and
Menu.
4. Install Menu in Menu_Base_HBox
then install Menu_Base_HBox into
Window_VBox. This will be in the
first, i.e. top, cell of Window_VBox.
5. Create File_Menu and
File_Dropdown.
6. Attach File_Dropdown to File_Menu
then install File_Menu into Menu.
7. Create the submenus with
Callbacks and File_Separator and
install them in the File_Dropdown.
8. CreateScreen_Frame_HBox,
Screen_Frame, Screen_Base_HBox,
Scroll, and Screen; Screen_Buffer is
created with Screen.
9. Install Screen_Frame into
Screen_Frame_HBox; install (Scroll
Bar fitted) Screen into
Screen_HBox; install
Screen_Base_HBox into
Screen_Frame; install
Screen_Frame_HBox into
Window_VBox. This will be the
second cell of Window_VBox.
10. Create H_Sep_HBox and H_Sep.
11. Install H_Sep into H_Sep_HBox;
install H_Sep_HBox into
Window_VBox. This will be the
third cell Window_VBox.
12. Create Buttons_Base_HBox and
Buttons_HBox.
13. Install Buttons_HBox in
Buttons_Base_HBox then install
Buttons_Base_HBox in
Window_VBox. This completes the
foundation of the keyboard.
14. Create Big_Button_Base_HBox and
Big_Button.
15. Install Big_Button in
Big_Button_Base_HBox then
Big_Button_Base_HBox in
Buttons_HBox. This will be in the
left-hand cell of Buttons_HBox.
16. Create V_Sep_Base_HBox and
V_Sep.
17. Install V_Sep into
V_Sep_Base_HBox then
V_Sep_Base_HBox into
Buttons_HBox.
18. Create Three_Buttons_Base_HBox
and Three_Buttons_VBox.
19. Install Three_Buttons_VBox into
Three_Buttons_Base_HBox then
install Three_Buttons_Base_HBox
into Buttons_HBox. This completes
the foundation for the three
buttons.
20. Create B1_Base_HBox and B1 with
its callbacks.
21. Install B1 into B1_Base_HBox then
install B1_Base_HBox into
Three_Buttons_VBox.
22. Repeat steps 20 and 21 for B2.
23. Repeat steps 20 and 21 for B3.
6 Other Packages
Required
Anyone who has used Glade knows that
doing a Build in Glade produces a
number of packages specifications
and bodies and a Mainline. Set
these up before starting to cut code.
Gadget: Building a Compound Widget with GtkAda


DOCUMENT CURRENT ONLY WHEN PRINTED
c:\documents and settings\rick\desktop\gadget.docx
Printed on Wednesday, 2 February 2011
Page 5 of 50
5


Beginner Programmers are always keen
to get down to cutting code. Older
heads get set up first. Follow their
example.
I use the naming conventions used by
Glade. There is no law about that, but
whatever you do, be consistent.
6.1 Mainline
Name: <program name>.adb
This file contains the code to create and
initialise the top-level widget. In the
case of the Gadget project this is a
Window. See Figure 2 for the standard
code as it applies to this project.
6.1.1 Set_Locale
This routine collects local settings, such
as time, from the host system. Always
include this because it means that your
widget can then be used on another
system, which is, after all, what you
want,.
6.1.2 Init
This routine sets up the internal
structure of the interface. It exits with
an error message if something goes
wrong like the computer is not
connected to a VDU.
6.1.3 Show_All
Gadget_Pkg inherits this routine from
Gtk.Widget. It displays The_Gadget and
all of its children. This is the routine
that makes your GUI appear on the
screen.
6.1.4 Main
This procedure starts the operating loop
and ends only when the operating loop
is exited.
6.1.5 The Pragma
Here the pragma is shown commented
out. Put it in when you write the
mainline and uncomment it when you
are finished developing. On a PC, this
pragma removes the command screen
from behind the GUI. However, the
command screen is useful during
development, a matter dealt with later.
6.2 Portability Package
Name:
<program name>_Intl.ads/adb
Graphical User Interfaces are not much
use if they will only run on the machine

Figure 2: Gadget.adb the Mainline

Figure 3: Gadget_Intl.adb
Gadget: Building a Compound Widget with GtkAda


DOCUMENT CURRENT ONLY WHEN PRINTED
c:\documents and settings\rick\desktop\gadget.docx
Printed on Wednesday, 2 February 2011
Page 6 of 50
6


on which they were written. Surely, the
object of the exercise is to write the
whizz-bang program and have people all
over the world using it. Obviously,
then, the program has to be able to
adapt to its environment to things
like changes of time zone. The
Portability Package handles these
problems.
In the GtkAda Reference Manual entry
for Gtkada.Intl we find,
This package provides support for
string internationalization using the
libintl library.
To provide internationalization in your
application, you must install a
number of files along with your
application, and modify your code to
highlight the strings to translate. This
translation is based on the gettext()
library.
Checking gettext() we read,
Depending on the specific
implementation of gettext, the
following environment variables may
be set to change the default settings
of locale parameters:
- LANG Specifies locale name.
- LC_MESSAGES Specifies messaging
locale, and if present overrides LANG
for messages.
- TEXTDOMAIN Specifies the text
domain name, which is identical to
the message object filename without
.mo suffix.
- TEXTDOMAINDIR Specifies the
pathname to the message database,
and if present replaces the default.
See Figure 3. Now you know
everything.
6.3 Callbacks Package
Name:
<program name>_Pkg-
Callbacks.ads/adb
This file contains the code to create the
callback procedures needed for the
project. This is where the Mud Map
becomes useful. Interactive widget
types shown on the Map all need
callback packages.
6.3.1 Item Types Requiring
Callbacks
From the Mud Map we can see that
there are the widgets which will send
messages to the program for
implementation:
Screen
Menu Selection
Button
Note Carefully: Every time you
attach a callback to a widget it
will need a handler. Write the handler
when you attach the callback. This will
save you from confusion later on. It is
a matter of disciplined coding
procedure.
Figure 4 shows the callback required
for the New tab on the menu with the
procedure in stubbed form. If Gadget
was supposed to do anything, there
would be code in place of the null.
During development, a command
window (all black and old fashioned)
appears behind Gadget. This can be
put to testing use in the callback
procedures by using Ada.Text_Io to
write to messages. See, for instance,
Figure 10 on page 11. When Big
Button is clicked a message will appear
on the command window. This shows
that the callback system is working
properly. Before the application is
distributed, a pragma is used to remove
the command window (see paragraph
6.1.5 on page 5).

Figure 4: Gadget_Pkg.Callbacks.adb - stubbed function

Gadget: Building a Compound Widget with GtkAda


DOCUMENT CURRENT ONLY WHEN PRINTED
c:\documents and settings\rick\desktop\gadget.docx
Printed on Wednesday, 2 February 2011
Page 7 of 50
7


6.4 Handler Packages
Name:
Callbacks_<program name>.ads
It is all very well having callback
routines but they will not do anything
unless there is an appropriate Handler
package to deal with them. A callback
handler needed in Gadget is shown in
Figure 5. Since this package only
instantiates new packages there is no
package body. The sequence is:
Instantiate handler package;
Write the handler procedure;
Attach the handler.
Note: the pragma. This simply ensures
that the library code for the
Gtk.Handlers is elaborated before being
called. Good practice.
6.5 Top-level Widget
Package
Name:
<widget name>_pkg.ads/adb
See Figure 6. This is where you build
your composite widget. Read on.
7 Playing with LEGO
Blocks
Building a compound widget with
GtkAda is like building something with
LEGO blocks. You simply take the
pieces and plug them together. (See
paragraph 4 on page 2.)
Sounds simple, doesnt it. Well, it is
if you do it systematically. If you rush
in, youll find out why they say fools do
that.
7.1 Setting up the Window
The first thing to do is to pick a top-
level widget in the case of Gadget,
use a window. Figure 6 shows the
minimum code for the top-level package
specification for Gadget. This would
merely specify an empty window. Other
widgets are added to the record. Of
course, you will need a package body
containing implementations for
Gtk_New and Initialize.
See Gtk_New line 17 in
Gadget_Pkg.adb (page 25). This is the
procedure called by the mainline to
create a new widget. In this case it
creates a new Gadget_Record which is a
child of
Gtk.Window.Gtk_Window_Record and
inherits all the functionality of a
Gtk.Window.Gtk_Window_Record.
Then it sends New_Gadget to the
initialisation procedure where all the
other bits are added.
See Initialize in line 25 in
Gadget_Pkg.adb. Here we get particular
about the characteristics and contents
of the window. In Gadget there are
several things to set.
7.1.1 Setting Window
Characteristics
Note: Gtk.Enums is a package that
contains types used by GtkAda widgets.
Programmers should familiarise
themselves with these as they give good
indication of the range of
characteristics programmers can
specify.
7.1.1.1 Gtk.Window.Initialize
The first call initialises the window
which will contain all the other widgets
as they are created. See line 38 in
Gadget_Pkg.adb.
It is not necessary to name and give
value to the formal parameter The_Type
in this case since the value we want is
the default value. This value ensures
that the window will be visible when

Figure 5: Callbacks_Gadget.ads
Gadget: Building a Compound Widget with GtkAda


DOCUMENT CURRENT ONLY WHEN PRINTED
c:\documents and settings\rick\desktop\gadget.docx
Printed on Wednesday, 2 February 2011
Page 8 of 50
8


created, i.e. not hidden behind other
windows that may be open at the time.
7.1.1.2 Set_Icon_From_File
To an Ada programmer, using a
function to perform an external
operation (see line 45 in
Gadget_Pkg.adb) is something of an
anachronism. This is a practice
traceable to C and on back to the
beginnings of High-level Programming
Languages.
This practice has the immediate
disadvantage that the function returns
an (unneeded) value which must be
stored somewhere. Such a Boolean
value would once have been used to
prove that the operation was
successful, but since it is not needed
here it is assigned to the variable Icon
declared back at line 46; then forgotten
about.
Warning: sending an ICO file
to this function causes
problems. Use BMP, GIF, PNG
etc. In Gadget the GIF format was used
to take advantage of its transparency
capability.
7.1.1.3 Set_Title
As you would expect, this procedure
puts whatever name you like in the top
border of the window. See line 51 in
Gadget_Pkg.adb. It and the other Sets
are part of Gadget_Pkg inherited from
Gtk.Window.
7.1.1.4 Set_Position
The parameter Position is set to
Gtk.Enums.Win_Pos_None at line 57 in
Gadget_Pkg.adb. which means that the
window can appear just about
anywhere on the screen i.e. there is
no defined position at which it has to
appear. There are a variety of available
set positions including appearing where
the cursor is.
7.1.1.5 Set_Modal
Setting the window to Modal => TRUE
(line 62) means that it will take the
input from the keyboard and the mouse
while the window is fully visible. It will
ignore them when the window is hidden
at all.
7.1.1.6 Set_Resizable
Just what you would expect.
7.1.1.7 Connecting the Callback
In paragraph 6.3.1 on page 6 the
statement was made, Every time you
attach a callback to a widget it will need
a handler. Well, here a special
callback must be attached to the
window (line 71).
In the top, right-hand corner of most
main windows is a little button marked
X. This button usually ends the
program that created it as well as
closing down its own window. Here, we
connect that button to its handler
(On_X_Button_Destroy in line 43 of
Gadget_Pkg-Callbacks.adb).
Note carefully: do not forget
this step. In the first place, you
will not be able to get rid of your
window, and, in the second place your
application will continue to run and you
will not be able to rebuild your
program.

Figure 6: Gadget_Pkg.ads


Gadget: Building a Compound Widget with GtkAda


DOCUMENT CURRENT ONLY WHEN PRINTED
c:\documents and settings\rick\desktop\gadget.docx
Printed on Wednesday, 2 February 2011
Page 9 of 50
9


7.1.2 Sneak a Preview
Before you can see what you have done
you must build your application using
the Mainline (page 5).
Figure 7 shows what you will get if you
build your mainline at this stage. There
is a window with a name and an icon
and perilous little else.
7.2 Boxes in the Window
Note Carefully: A window can
only have one child widget. If
more than one widget is to
appear in the window then they have to
be in some container (containers can
have multiple children).
There are two types of box in Gadget;
HBox and VBox. As pointed out in
paragraph 4.1.2 on page 3 it is best to
ensure that each widget, including
frames and multi-cell boxes, is
contained in a single-cell box.
7.2.1 Create
Window_Base_HBox
See line 93 in Gadget_Pkg.adb.
7.2.1.1 Homogeneous
'Homogeneous => TRUE' means the
cells in this box will all be the same
size. There is, in fact only one cell in
this box so the parameter could have
been left at the default value false.
7.2.1.2 Spacing
'Spacing => 0' is the default value and
means that there is no space between
the box and its contents.
7.2.2 Create Window_VBox
This box will sit inside
Window_Base_HBox See line 104 in
Gadget_Pkg.adb.
Window_VBox will hold the Menu in the
top cell and all the other widgets in
successively lower cells.
7.2.2.1 Homogeneous
Homogeneous => false means that the
cells can be different sizes. This is the
default value and could be omitted.
7.2.2.2 Spacing
Spacing => 2 means there will be a
two-pixel gap between the box and its
contents.
7.2.3 Set the Boxes in the
Window
Once again, it is a matter of doing
things in order.
Window_VBox into
Window_Base_HBox
See line 114 in Gadget_Pkg.adb.
Window_Base_HBox into The_Gadget
The_Gadget is the window itself. See
line 122 in Gadget_Pkg.adb.
7.2.3.1 Sneak a Preview
This looks no different to Figure 7
because the boxes are not visible. So,
build something to put in the
Window_VBox.
7.3 Install a Menu Bar
Take these things in order.
7.3.1 Menu_Base_Box
Make a single-cell box to hold the
menu. See line 135 in Gadget_Pkg.adb.
Homogeneous and Spacing have both
been discussed previously.
7.3.2 Menu_Bar
Construct the menu bar to go into
Menu_Base_Box
7.3.2.1 Gtk_New
This procedure creates the menu bar
itself blank. . See line 140 in
Gadget_Pkg.adb.

Figure 7: Gadget - Just a Named
Window

Gadget: Building a Compound Widget with GtkAda


DOCUMENT CURRENT ONLY WHEN PRINTED
c:\documents and settings\rick\desktop\gadget.docx
Printed on Wednesday, 2 February 2011
Page 10 of 50
10


7.3.2.2 Set_Pack_Direction
This procedure stipulates the linear
relationship of the sub-menus in the
menu bar. The choices are Left-to-
Right, Right-To-Left, Top-To-Bottom or
Bottom-To-Top. See line 144 in
Gadget_Pkg.adb.
7.3.2.3 Pack_Start
This routine is called twice; once to
insert Menu_Bar in Menu_Base_Box
then again to install Menu_Base_Box in
Window_VBox. See lines 149 and 156
in Gadget_Pkg.adb. Pack_Start is called
for both HBoxes and VBoxes so the
GtkAda Reference Manual tells us the
call means:
Add a new child to the beginning of
the box (ie left or top part). It is added
to the right (resp. the bottom) of the
previous child added to the beginning
of the box. Note that a child added to
the beginning of the box will always
remain on the left (resp. top) of all the
children added to the end of the box.
In this case, size of the box in question
is, in fact, defined by the number of
items in the menu. Successive words
along the menu line will be added from
left to right and the box expands to
suit.
7.3.3 Create the File Menu
Menu_Bar is just a bar at this stage
and it needs dropdown menus to make
it useful.
7.3.3.1 New_With_Mnemonic.
Firstly, call Gtk_New_With_Mnemonic.
See line 171 in Gadget_Pkg.adb. The
label is created with an underscore
indicating the mnemonic for the menu
item (i.e. pressing the ALT key and the
underscored letter activates the menu
item).
7.3.3.2 Gtk_New
This procedure creates a new dropdown
menu for the menu bar. See line 176 in
Gadget_Pkg.adb. Now attach
File_Dropdown to File_Menu and then
File_Menu to Menu itself.
Note Carefully: because each
parent is a different type of
widget the routines are
different and come from different
packages. This is a prime example of
the need to keep one hand on the
Reference Manual and the other on the
keyboard. Programmers must use the
attachment routine for the appropriate
Widget.
7.3.4 The New Tab
Now there is a dropdown from the
menu but there is nothing on it. See
the lines starting at 193 in
Gadget_Pkg.adb for the creation of the
New tab.
7.3.4.1 Gtk_New_From_Stock
This procedure creates a new stock
item (a tab for the dropdown menu)
which, typically, has an icon next to the
action name. Many of the commonly
required menu items and buttons, with
appropriate icons, are available ex
stock. This saves a lot of time and
coding in the creation of the widget
followed by the design and attachment
of the icon. It also means that the
software created has a consistent look.
To find a list of the available Stock
Items, and assuming default addresses
for your installation, got to
C:\GtkAda\include\gtkada\gtk-
stock.ads.
7.3.4.2 Image_Menu_Item_
Callback.Connect
This procedure connects the new tab to
its callback handler by advising the
callback marshaller which callback
subroutine to use.
7.3.4.3 Append
This procedure attaches the 'New' tab to
the dropdown menu. It is inherited
from 'Gtk.Menu_Shell'.
7.3.4.4 Create the Other Menu
Tabs and the Separator
The above sequence is repeated (more
or less) for the rest of the tabs on the
dropdown menu. See code starting at
line 215 in Gadget_Pkg.adb.

Gadget: Building a Compound Widget with GtkAda


DOCUMENT CURRENT ONLY WHEN PRINTED
c:\documents and settings\rick\desktop\gadget.docx
Printed on Wednesday, 2 February 2011
Page 11 of 50
11


7.3.5 Sneak a Preview
Figure 8 shows the result of building
the mainline at this stage a Gadget
with a dropdown menu.
7.4 Install Text-edit Screen
For Gadget use Gtk.Text_View. Check
the Mud Map on page 3. In the second
cell of Window_VBox sits a single-cell
HBox named Screen_Frame_HBox. In
Screen_Frame_HBox sits a Gtk_Frame
named Screen_Frame and inside that
again sits a single-cell HBox named
Screen_Base_Box. Finally, inside
Screen_Base_Box sits the widget that
does the work, a Gtk.Text_View named
Screen.
When Screen is created several
characteristics such as size and border
width are set.
Creating the Boxes and Screen is
largely familiar territory and will be
simple to follow. See code starting at
line 327 in Gadget_Pkg.adb.
There is one new concept.
7.4.1 Scrolled_Window
It may be that the user enters too much
text into the editing area. Creating
Scroll ensures that, in that case, scroll
bars will appear when they are needed.
They are not displayed when the area is
blank.
The Scrollbars are created at line 368 in
Gadget_Pkg.adb. Scrollbar adjustments
can be set (see Gtk.Adjustment in the
Reference Manual) but that sort of thing
is for the brave, or for those who have
plenty of time to experiment. Using the
null values makes the process
automatic.
Another automation is setting when the
scrollbars appear. The options (see
Gtk.Enums) are Policy_Always,
Policy_Automatic, Policy_Never.
7.4.2 Setting Screen
Characteristics
A variety of characteristics can be set.
These specify the way in which the
editing area appears and interacts with
the user. Starting at line 389 in
Gadget_Pkg.adb we have:
Set_Size_Request
Set_Left_Margin & Set_Right_Margin
Set_Wrap_Mode
(Note: Because entered text will now
word- wrap, the horizontal scroll bar
will not appear.)
Set_Accepts_Tab
7.5 Install an Horizontal
Separator
This is an Ornament. It serves no
practical purpose but visually separates
Screen from the buttons below.
Referring to the Mud Map reveals that
the third cell of Window_VBox sits a
single-cell HBox named H_Sep_Box
which, in turn, holds the Separator
named H_Sep. Creation and
installation procedures used are
familiar territory. See line 434 in
Gadget_Pkg.adb.
7.5.1 Sneak a Preview
Figure 9 shows Gadget to date. Now we
need some buttons to press.

Figure 8: Gadget with Menu

Figure 9: Gadget with Text Screen,
Scrollbar, and Horizontal Separator
Gadget: Building a Compound Widget with GtkAda


DOCUMENT CURRENT ONLY WHEN PRINTED
c:\documents and settings\rick\desktop\gadget.docx
Printed on Wednesday, 2 February 2011
Page 12 of 50
12


7.6 Create the Keyboard
This is where it might seem a bit
complicated. However, it is said that
the way to eat an elephant is to chew
on one mouthful at a time. In coding
the Keyboard, as usual, take little bits
at a time.
7.6.1 Create the Boxes for the
Keyboard
Simple. See lines starting at 469 in
Gadget_Pkg.adb
7.6.2 Create and Install Big-
Button
The only new thing here (starting at line
499) is the introduction of
Ada.Characters.Latin_1. This allows use
of a carriage return character (CR) so
that the title of the button appears in
two lines. All else is familiar.
Note the trick here with the label.
Normally, the text on the button is
added at its creation (line 505) but here
a null entry is used. This is because
the text is to appear in two lines rather
than the default one.
Create a label (line 508) with the two
words separated by a CR (carriage
return relates to the days of the
typewriter and indicates the end of one
line and the start of a new one)
character. This text is then justified
center (line 514) and the label added to
the button (line 519). If the text is not
specifically justified to the centre, the
default will be justified to the left.
7.6.2.1 Debugging Trick
That black screen with white
characters, the Command Screen, that
has been appearing behind Gadget now
comes in useful. Figure 10 shows the
coding of a callback procedure for the
situation when Big_Button is clicked.
This will make the message, Big Button
was Clicked appear in the command
screen. Then the programmer knows
that the handler procedure is connected
properly and is being run by the
appropriate handler package.
In other words it works.
That code line will be replaced when
Big_Button has a job.
7.6.2.2 Connect Callbacks
Note Carefully: Dont forget to
have an appropriate handler
package in
Callbacks_Gadget.ads and to write the
handlers in
Gadget_Pkg.Callbacks.ads/adb.
7.6.2.3 Tooltip
Add a line explaining the function of the
Button for the user. This line will
appear when the cursor is over the
button. See line 530 in
Gadget_Pkg.adb.
Tip_Private contains more information.
Although that information can be
displayed, in most cases, Tip_Private
should simply keep its default empty
value.
7.6.3 Create and Install the
Vertical Separator
Simple. This is the same process as for
the horizontal separator. See line 560
in Gadget_Pkg.adb
7.6.4 Create and Install the
Three Small Buttons
Absolutely nothing new here just
repetition. This is where the
programmer learns the value of Cut-
And-Paste. See lines starting at 592 in
Gadget_Pkg.adb
7.6.4.1 Connect Callbacks
Note Carefully: Dont forget to
have an appropriate handler
package in
Callbacks_Gadget.ads and to write the
handlers in
Gadget_Pkg.Callbacks.ads/adb.

Figure 10: Text Message Test for Big Button


Gadget: Building a Compound Widget with GtkAda


DOCUMENT CURRENT ONLY WHEN PRINTED
c:\documents and settings\rick\desktop\gadget.docx
Printed on Wednesday, 2 February 2011
Page 13 of 50
13


8 It is Done
The_Gadget is complete (Figure 11). It
doesnt actually do much, but it looks
the way it was planned.
There is just on small thing getting
rid of the command screen.
8.1 Removing the
Command Screen
Refer to paragraph 6.1.5 and Figure 2
on page 5. All has been explained.


Figure 11: The_Gadget Completed
Gadget: Building a Compound Widget with GtkAda


DOCUMENT CURRENT ONLY WHEN PRINTED
c:\documents and settings\rick\desktop\gadget.docx
Printed on Wednesday, 2 February 2011
Page 14 of 50
14


9 Gadget: Exploded Diagram




Gadget: Building a Compound Widget with GtkAda


DOCUMENT CURRENT ONLY WHEN PRINTED
c:\documents and settings\rick\desktop\gadget.docx
Printed on Wednesday, 2 February 2011
Page 15 of 50
15


10 Code
Disclaimer: This work is provided as is and without any express or implied warranties including, without limitation,
the implied warranties or merchantability and fitness for a particular purpose.

10.1 Mainline Gadget.adb

1 with Gtk.Main;
2 with Gadget_Pkg;
3 with Callbacks_Gadget;
4 procedure Gadget is
5
6 pragma Linker_Options ("-mwindows");
7
8 The_Gadget : Gadget_Pkg.Gadget_Access;
9 begin -- Gadget
10 Gtk.Main.Set_Locale;
11 Gtk.Main.Init;
12 Gadget_Pkg.Gtk_New (The_Gadget);
13 Gadget_Pkg.Show_All (The_Gadget);
14 Gtk.Main.Main;
15 end Gadget;


Gadget: Building a Compound Widget with GtkAda


DOCUMENT CURRENT ONLY WHEN PRINTED
c:\documents and settings\rick\desktop\gadget.docx
Printed on Wednesday, 2 February 2011
Page 16 of 50
16


10.2 Portability Package
10.2.1 Specification Gadget_Intl.ads

1 package Gadget_Intl is
2
3 function Local_Format (Input : String) return String;
4 -- This function converts the hard-coded text input into a string in a
5 -- format appropriate to the local host. It utilises Gtkada.Intl.Dgettext
6 -- to perform the conversion.
7
8 end Gadget_Intl;
10.2.2 Implementation Gadget_Intl.adb

1 with Gtkada.Intl;
2 package body Gadget_Intl is
3 -- This function converts the hard-coded text input into a string in a
4 -- format appropriate to the local host. It utilises Gtkada.Intl.Dgettext
5 -- to perform the conversion.
6 function Local_Format (Input : String) return String is
7 begin
8 return Gtkada.Intl.Dgettext (Domain => "Gadget",
9 Msg => Input);
10 end Local_Format;
11 end Gadget_Intl;

Gadget: Building a Compound Widget with GtkAda


DOCUMENT CURRENT ONLY WHEN PRINTED
c:\documents and settings\rick\desktop\gadget.docx
Printed on Wednesday, 2 February 2011
Page 17 of 50
17


10.3 Callbacks Package
10.3.1 Specification Gadget_Package.Callbacks.ads

1 with Gtk.Image_Menu_Item;
2
3 package Gadget_Pkg.Callbacks is
4
5 procedure On_X_Button_Destroy
6 (Object : access Gtk.Window.Gtk_Window_Record'Class);
7 -- On_X_Button_Destroy is a callback to destroy the main window and end
8 -- the program run when the [X] button at top right of the window is clicked.
9
10 procedure On_New_Tab_Activate
11 (Object : access Gtk.Image_Menu_Item.Gtk_Image_Menu_Item_Record'Class);
12 -- New_Tab is an available selection on the 'File' dropdown menu. This
13 -- procedure takes the appropriate action when 'New' is clicked.
14
15 procedure On_Open_Tab_Activate
16 (Object : access Gtk.Image_Menu_Item.Gtk_Image_Menu_Item_Record'Class);
17 -- Open_Tab is an available selection on the 'File' dropdown menu. This
18 -- procedure takes the appropriate action when 'Open' is clicked.
19
20 procedure On_Save_Tab_Activate
21 (Object : access Gtk.Image_Menu_Item.Gtk_Image_Menu_Item_Record'Class);
22 -- Save_Tab is an available selection on the 'File' dropdown menu. This
23 -- procedure takes the appropriate action when 'Save' is clicked.
24
25 procedure On_Save_As_Tab_Activate
26 (Object : access Gtk.Image_Menu_Item.Gtk_Image_Menu_Item_Record'Class);
27 -- Save_As_Tab is an available selection on the 'File' dropdown menu. This
28 -- procedure takes the appropriate action when 'Save As' is clicked.
29
30 procedure On_Quit_Tab_Activate
Gadget: Building a Compound Widget with GtkAda


DOCUMENT CURRENT ONLY WHEN PRINTED
c:\documents and settings\rick\desktop\gadget.docx
Printed on Wednesday, 2 February 2011
Page 18 of 50
18


31 (Object : access Gtk.Image_Menu_Item.Gtk_Image_Menu_Item_Record'Class);
32 -- Quit_Tab is an available selection on the 'File' dropdown menu. This
33 -- procedure takes the appropriate action when 'Quit' is clicked.
34
35 procedure On_Big_Button_Clicked
36 (Object : access Gtk.Button.Gtk_Button_Record'Class);
37 -- This procedure takes the appropriate action when 'Big Button' is clicked.
38
39 procedure On_B1_Clicked
40 (Object : access Gtk.Button.Gtk_Button_Record'Class);
41 -- This procedure takes the appropriate action when 'B1' is clicked.
42
43 procedure On_B2_Clicked
44 (Object : access Gtk.Button.Gtk_Button_Record'Class);
45 -- This procedure takes the appropriate action when 'B2' is clicked.
46
47 procedure On_B3_Clicked
48 (Object : access Gtk.Button.Gtk_Button_Record'Class);
49 -- This procedure takes the appropriate action when 'B3' is clicked.
50 end Gadget_Pkg.Callbacks;
10.3.2 Implementation Gadget_Pkg.Callbacks.adb

1 with Gtk.Main;
2
3 package body Gadget_Pkg.Callbacks is
4
5 -- On_X_Button_Destroy is a callback to destroy the main window and end
6 -- the program run when the [X] button at top right of the window is clicked.
7 procedure On_X_Button_Destroy
8 (Object : access Gtk.Window.Gtk_Window_Record'Class) is
9 begin -- On_X_Button_Destroy
10 Gtk.Main.Main_Quit;
11 end On_X_Button_Destroy;
Gadget: Building a Compound Widget with GtkAda


DOCUMENT CURRENT ONLY WHEN PRINTED
c:\documents and settings\rick\desktop\gadget.docx
Printed on Wednesday, 2 February 2011
Page 19 of 50
19


12
13 -- New_Tab is an available selection on the 'File' dropdown menu. This
14 -- procedure takes the appropriate action when 'New' is clicked.
15 procedure On_New_Tab_Activate
16 (Object : access Gtk.Image_Menu_Item.Gtk_Image_Menu_Item_Record'Class) is
17 begin -- On_New_Tab_Activate
18 null;
19 end On_New_Tab_Activate;
20
21 -- Open_Tab is an available selection on the 'File' dropdown menu. This
22 -- procedure takes the appropriate action when 'Open' is clicked.
23 procedure On_Open_Tab_Activate
24 (Object : access Gtk.Image_Menu_Item.Gtk_Image_Menu_Item_Record'Class) is
25 begin -- On_Open_Tab_Activate
26 null;
27 end On_Open_Tab_Activate;
28
29 -- Save_Tab is an available selection on the 'File' dropdown menu. This
30 -- procedure takes the appropriate action when 'Save' is clicked.
31 procedure On_Save_Tab_Activate
32 (Object : access Gtk.Image_Menu_Item.Gtk_Image_Menu_Item_Record'Class) is
33 begin -- On_Save_Tab_Activate
34 null;
35 end On_Save_Tab_Activate;
36
37 -- Save_As_Tab is an available selection on the 'File' dropdown menu. This
38 -- procedure takes the appropriate action when 'Save' is clicked.
39 procedure On_Save_As_Tab_Activate
40 (Object : access Gtk.Image_Menu_Item.Gtk_Image_Menu_Item_Record'Class) is
41 begin -- On_Save_As_Tab_Activate
42 null;
43 end On_Save_As_Tab_Activate;
44
45 -- Quit_Tab is an available selection on the 'File' dropdown menu. This
Gadget: Building a Compound Widget with GtkAda


DOCUMENT CURRENT ONLY WHEN PRINTED
c:\documents and settings\rick\desktop\gadget.docx
Printed on Wednesday, 2 February 2011
Page 20 of 50
20


46 -- procedure takes the appropriate action when 'Quit' is clicked.
47 procedure On_Quit_Tab_Activate
48 (Object : access Gtk.Image_Menu_Item.Gtk_Image_Menu_Item_Record'Class) is
49 begin -- On_Quit_Tab_Activate
50 -- Exit the Main loop.
51 Gtk.Main.Main_Quit;
52 end On_Quit_Tab_Activate;
53
54 -- This procedure takes the appropriate action when 'Big Button' is clicked.
55 procedure On_Big_Button_Clicked
56 (Object : access Gtk.Button.Gtk_Button_Record'Class) is
57 begin -- On_Big_Button_Clicked
58 null;
59 end On_Big_Button_Clicked;
60
61 -- This procedure takes the appropriate action when 'B1' is clicked.
62 procedure On_B1_Clicked
63 (Object : access Gtk.Button.Gtk_Button_Record'Class) is
64 begin -- On_B1_Clicked
65 null;
66 end On_B1_Clicked;
67
68 -- This procedure takes the appropriate action when 'B2' is clicked.
69 procedure On_B2_Clicked
70 (Object : access Gtk.Button.Gtk_Button_Record'Class) is
71 begin -- On_B2_Clicked
72 null;
73 end On_B2_Clicked;
74
75 -- This procedure takes the appropriate action when 'B3' is clicked.
76 procedure On_B3_Clicked
77 (Object : access Gtk.Button.Gtk_Button_Record'Class) is
78 begin -- On_B3_Clicked
79 null;
Gadget: Building a Compound Widget with GtkAda


DOCUMENT CURRENT ONLY WHEN PRINTED
c:\documents and settings\rick\desktop\gadget.docx
Printed on Wednesday, 2 February 2011
Page 21 of 50
21


80 end On_B3_Clicked;
81 end Gadget_Pkg.Callbacks;
10.4 Handler Packages
10.4.1 Specification Callbacks_Gadget.ads

1 with Gtk.Handlers;
2 with Gtk.Widget;
3 with Gtk.Window;
4 with Gtk.Image_Menu_Item;
5 with Gtk.Button;
6
7 pragma Elaborate_All (Gtk.Handlers);
8
9 package Callbacks_Gadget is
10
11 package Window_Callback_Pkg is new
12 Gtk.Handlers.Callback (Gtk.Window.Gtk_Window_Record);
13 -- This instantiation creates a new package to handle
14 -- Gtk_Window_Record.
15
16 package Image_Menu_Item_Callback_Pkg is new
17 Gtk.Handlers.Callback (Gtk.Image_Menu_Item.Gtk_Image_Menu_Item_Record);
18 -- This instantiation creates a new package to handle
19 -- Gtk_Image_Menu_Item_Record.
20
21 package Button_Callback_Pkg is new
22 Gtk.Handlers.Callback (Gtk.Button.Gtk_Button_Record);
23 -- This instantiation creates a new package to handle
24 -- Gtk_Button_Record.
25 end Callbacks_Gadget;
Gadget: Building a Compound Widget with GtkAda


DOCUMENT CURRENT ONLY WHEN PRINTED
c:\documents and settings\rick\desktop\gadget.docx
Printed on Wednesday, 2 February 2011
Page 22 of 50
22


10.5 Development Package
10.5.1 Specification Gadget_Pkg.ads

1 with Gtk.Window; use Gtk.Window;
2 with Glib.Error;
3 with Gtk.Box;
4 with Gtk.Menu;
5 with Gtk.Menu_Bar;
6 with Gtk.Menu_Item;
7 with Gtk.Image_Menu_Item;
8 with Gtk.Separator_Menu_Item;
9 with Gtk.Frame;
10 with Gtk.Scrolled_Window;
11 with Gtk.Text_View;
12 with Gtk.Text_Buffer;
13 with Gtk.Separator;
14 with Gtk.Button;
15 with Gtk.Label;
16 with Gtk.Tooltips;
17
18 package Gadget_Pkg is
19 type Gadget_Record is new Gtk.Window.Gtk_Window_Record with record
20
21 Window_Base_HBox : Gtk.Box.Gtk_Hbox;
22 Window_VBox : Gtk.Box.Gtk_VBox; -- this will have 4 cells
23
24 Menu_Base_HBox : Gtk.Box.Gtk_HBox;
25 Menu : Gtk.Menu_Bar.Gtk_Menu_Bar;
26
27 File_Menu : Gtk.Menu_Item.Gtk_Menu_Item;
28 File_Dropdown : Gtk.Menu.Gtk_Menu;
29
30 New_Tab : Gtk.Image_Menu_Item.Gtk_Image_Menu_Item;
Gadget: Building a Compound Widget with GtkAda


DOCUMENT CURRENT ONLY WHEN PRINTED
c:\documents and settings\rick\desktop\gadget.docx
Printed on Wednesday, 2 February 2011
Page 23 of 50
23


31 Open_Tab : Gtk.Image_Menu_Item.Gtk_Image_Menu_Item;
32 Save_Tab : Gtk.Image_Menu_Item.Gtk_Image_Menu_Item;
33 Save_As_Tab : Gtk.Image_Menu_Item.Gtk_Image_Menu_Item;
34 File_Separator : Gtk.Separator_Menu_Item.Gtk_Separator_Menu_Item;
35 Quit_Tab : Gtk.Image_Menu_Item.Gtk_Image_Menu_Item;
36
37 Screen_Frame_HBox : Gtk.Box.Gtk_HBox;
38 Screen_Frame : Gtk.Frame.Gtk_Frame;
39 Screen_Base_Box : Gtk.Box.Gtk_HBox;
40
41 Scroll : Gtk.Scrolled_Window.Gtk_Scrolled_Window;
42 Screen : Gtk.Text_View.Gtk_Text_View;
43 Screen_Buffer : Gtk.Text_Buffer.Gtk_Text_Buffer;
44
45 H_Sep_Base_HBox : Gtk.Box.Gtk_HBox;
46 H_Sep : Gtk.Separator.Gtk_Hseparator;
47
48 Buttons_Base_Box : Gtk.Box.Gtk_HBox;
49 Buttons_HBox : Gtk.Box.Gtk_HBox; -- this will have 3 cells
50
51 -- LH Cell
52 Big_Button_Base_HBox : Gtk.Box.Gtk_HBox;
53 Big_Button : Gtk.Button.Gtk_Button;
54 Big_Button_Label : Gtk.Label.Gtk_Label;
55 Big_Button_Tooltip : Gtk.Tooltips.Gtk_Tooltips;
56
57 -- Middle Cell
58 V_Sep_HBox : Gtk.Box.Gtk_HBox;
59 V_Sep : Gtk.Separator.Gtk_Hseparator;
60
61 -- RH Cell
62 Three_Buttons_Base_HBox : Gtk.Box.Gtk_HBox;
63 Three_Buttons_VBox : Gtk.Box.Gtk_VBox; -- this will have 3 cells
64
Gadget: Building a Compound Widget with GtkAda


DOCUMENT CURRENT ONLY WHEN PRINTED
c:\documents and settings\rick\desktop\gadget.docx
Printed on Wednesday, 2 February 2011
Page 24 of 50
24


65 -- Top Cell
66 B1_HBox : Gtk.Box.Gtk_HBox;
67 B1 : Gtk.Button.Gtk_Button;
68 B1_Tooltip : Gtk.Tooltips.Gtk_Tooltips;
69
70 -- Middle Cell
71 B2_HBox : Gtk.Box.Gtk_HBox;
72 B2 : Gtk.Button.Gtk_Button;
73 B2_Tooltip : Gtk.Tooltips.Gtk_Tooltips;
74
75 -- Bottom Cell
76 B3_Hbox : Gtk.Box.Gtk_HBox;
77 B3 : Gtk.Button.Gtk_Button;
78 B3_Tooltip : Gtk.Tooltips.Gtk_Tooltips;
79 end record;
80 type Gadget_Access is access all Gadget_Record'Class;
81
82
83 procedure Gtk_New (New_Gadget : out Gadget_Access);
84 -- Gtk_New creates the new widget and passes it to Initialize,
85
86 procedure Initialize (The_Gadget : access Gadget_Record'Class);
87 -- Initialize creates, initialises, installs, shows etc. all the widgets
88 -- which make up the interface.
89 end Gadget_Pkg;

Gadget: Building a Compound Widget with GtkAda


DOCUMENT CURRENT ONLY WHEN PRINTED
c:\documents and settings\rick\desktop\gadget.docx
Printed on Wednesday, 2 February 2011
Page 25 of 50
25


10.5.2 Implementation Gadget_Pkg.adb

1 with Gtk.Enums;
2
3 with Ada.Characters.Latin_1;
4
5 with Gadget_Intl;
6 with Gadget_Pkg.Callbacks;
7 with Callbacks_Gadget;
8 package body Gadget_Pkg is
9
10 Icon : Boolean;
11
12 -- This is the procedure called by the mainline to create a new widget.
13 -- In this case it creates a new Gadget_Record which is a child of
14 -- Gtk.Window.Gtk_Window_Record and inherits all the functionality of
15 -- a Gtk.Window.Gtk_Window_Record.
16 -- Then it sends New_Gadget to the initialisation procedure.
17 procedure Gtk_New (New_Gadget : out Gadget_Access) is
18 begin -- Gtk_New
19 New_Gadget := new Gadget_Record;
20 Initialize (The_Gadget => New_Gadget);
21 end Gtk_New;
22
23
24
25 procedure Initialize (The_Gadget : access Gadget_Record'Class) is
26 begin -- Initialize
27
28 ----------------------------------------------------------------
29 -- CREATE THE WINDOW WHICH WILL CONTAIN ALL THE OTHER WIDGETS --
30 ----------------------------------------------------------------
31
32 -- This procedure call initialises the window which will contain all the
Gadget: Building a Compound Widget with GtkAda


DOCUMENT CURRENT ONLY WHEN PRINTED
c:\documents and settings\rick\desktop\gadget.docx
Printed on Wednesday, 2 February 2011
Page 26 of 50
26


33 -- other widgets as they are created.
34 -- It is not necessary to name and give value to the formal parameter
35 -- The_Type in this case since the value we want is the default value.
36 -- This value ensures that the window will be visible when created, i.e.
37 -- not hidden behind other windows that may be open at the time.
38 Gtk.Window.Initialize
39 (Window => The_Gadget,
40 The_Type => Gtk.Enums.Window_Toplevel);
41
42 -- Give the window a specified icon.
43 -- Using a function to do this is probably a throwback to the
44 -- primordial days of Gtk's 'C' ancestry.
45 Icon := Set_Icon_From_File (Window => The_Gadget,
46 Filename => "Gadget.gif");
47
48 -- Give the created window a name.
49 -- This subroutine, and some below it, are part of Gadget_Pkg inherited
50 -- from Gtk.Window.
51 Set_Title (Window => The_Gadget,
52 Title => Gadget_Intl.Local_Format
53 (Input =>"Shiny New Gadget"));
54
55 -- Display the window anywhere.
56 Set_Position (Window => The_Gadget,
57 Position => Gtk.Enums.Win_Pos_None);
58
59 -- Setting the window to Modal means that it will take the input from the
60 -- keyboard and the mouse while the window is fully visible. It will
61 -- ignore them when the window is hidden at all.
62 Set_Modal (Window => The_Gadget,
63 Modal => TRUE);
64
65 -- Make sure the window can be resized.
66 Set_Resizable (Window => The_Gadget,
Gadget: Building a Compound Widget with GtkAda


DOCUMENT CURRENT ONLY WHEN PRINTED
c:\documents and settings\rick\desktop\gadget.docx
Printed on Wednesday, 2 February 2011
Page 27 of 50
27


67 Resizable => TRUE);
68
69 -- Make sure the window can be destroyed and the program stopped when
70 -- the [X] button on the main window is clicked.
71 Callbacks_Gadget.Window_Callback_Pkg.Connect
72 (Widget => The_Gadget,
73 Name => "destroy",
74 Marsh => Callbacks_Gadget.Window_Callback_Pkg.To_Marshaller
75 (Gadget_Pkg.Callbacks.On_X_Button_Destroy'Access));
76
77
78
79 ------------------------------------------
80 -- CREATE THE BOXES TO HOLD THE WIDGETS --
81 ------------------------------------------
82
83 -- Create the Base Box for all the widgets in the window. It is created
84 -- as an HBox which means that, as each successive widget is added to it
85 -- the will show in sequence one lower than the other.
86 -- 'Homogeneous(TRUE)' means the cells in this box will all be the
87 -- same size. There is, in fact only one cell in this box.
88 -- 'Spacing(0)' is the default value and means that there is no space
89 -- between the box and its contents. Although it is default value it
90 -- must be specified because the value of Homogeneous has been specified
91 -- non-default.
92 -- Window_HBase_Box will sit inside The_Gadget (the window).
93 Gtk.Box.Gtk_New_HBox (Box => The_Gadget.Window_Base_HBox,
94 Homogeneous => TRUE,
95 Spacing => 0);
96
97 -- Create the VBox to hold the Menu in the top cell and all the other
98 -- widgets in the bottom cell.
99 -- Homogeneous(false) means that the cells can be different sizes. This
100 -- is the default value and could be omitted.
Gadget: Building a Compound Widget with GtkAda


DOCUMENT CURRENT ONLY WHEN PRINTED
c:\documents and settings\rick\desktop\gadget.docx
Printed on Wednesday, 2 February 2011
Page 28 of 50
28


101 -- Spacing(2) means there will be a two-pixel gap between the box and its
102 -- contents.
103 -- Window_VBox will sit inside Window_Base_Box.
104 Gtk.Box.Gtk_New_VBox (Box => The_Gadget.Window_VBox,
105 Homogeneous => false,
106 Spacing => 2);
107
108
109 -----------------------
110 -- INSTALL THE BOXES --
111 -----------------------
112
113 -- Install Window_VBox in Window_Base_HBox.
114 Gtk.Box.Pack_Start
115 (In_Box => The_Gadget.Window_Base_HBox,
116 Child => The_Gadget.Window_VBox,
117 Expand => TRUE,
118 Fill => TRUE,
119 Padding => 0);
120
121 -- Install Window_Base_HBox in The_Gadget.
122 Gadget_Pkg.Add (Container => The_Gadget,
123 Widget => The_Gadget.Window_Base_HBox);
124
125
126
127 -----------------------------------------
128 -----------------------------------------
129 ---- NOW WE CREATE AND INSTALL -----
130 ---- MENU_BAR AT THE TOP OF GADGET -----
131 -----------------------------------------
132 -----------------------------------------
133
134 -- Create Menu_Base_HBox to hold Menu.
Gadget: Building a Compound Widget with GtkAda


DOCUMENT CURRENT ONLY WHEN PRINTED
c:\documents and settings\rick\desktop\gadget.docx
Printed on Wednesday, 2 February 2011
Page 29 of 50
29


135 Gtk.Box.Gtk_New_HBox (Box => The_Gadget.Menu_Base_HBox,
136 Homogeneous => TRUE,
137 Spacing => 0);
138
139 -- Create Menu to sit in Gadget_Menu_Box.
140 Gtk.Menu_Bar.Gtk_New (Menu_Bar => The_Gadget.Menu);
141
142 -- Set the direction in which the items in the menu bar are aligned.
143 -- In this bar the items will appear aligned Left to Right.
144 Gtk.Menu_Bar.Set_Pack_Direction
145 (Menubar => The_Gadget.Menu,
146 Pack_Dir => Gtk.Enums.Pack_Direction_LTR);
147
148 -- Install Menu_Bar in Menu_Base_Box.
149 Gtk.Box.Pack_Start (In_Box => The_Gadget.Menu_Base_HBox,
150 Child => The_Gadget.Menu,
151 Expand => TRUE,
152 Fill => TRUE,
153 Padding => 2);
154
155 -- Install Menu_Base_Box in Window_VBox.
156 Gtk.Box.Pack_Start (In_Box => The_Gadget.Window_VBox,
157 Child => The_Gadget.Menu_Base_HBox,
158 Expand => false,
159 Fill => TRUE,
160 Padding => 0);
161
162
163
164 ----------------------------------------------------------
165 -- CREATE THE 'FILE' MENU AND ATTACH IT TO THE MENU_BAR --
166 ----------------------------------------------------------
167
168 -- The underscore before the name means that the 'F' in File will be
Gadget: Building a Compound Widget with GtkAda


DOCUMENT CURRENT ONLY WHEN PRINTED
c:\documents and settings\rick\desktop\gadget.docx
Printed on Wednesday, 2 February 2011
Page 30 of 50
30


169 -- underlined indicating that the dropdown can be called from the
170 -- keyboard using ALT+F.
171 Gtk.Menu_Item.Gtk_New_With_Mnemonic
172 (Menu_Item => The_Gadget.File_Menu,
173 Label => Gadget_Intl.Local_Format(Input => "_File"));
174
175 -- Create a new dropdown file for the menu bar.
176 Gtk.Menu.Gtk_New (Widget => The_Gadget.File_Dropdown);
177
178 -- Attach the File_Dropdown to File_Menu.
179 Gtk.Menu_Item.Set_Submenu (Menu_Item => The_Gadget.File_Menu,
180 Submenu => The_Gadget.File_Dropdown);
181
182 -- Attach File_Menu to Menu_Bar.
183 Gtk.Menu_Bar.Append (Menu_Shell => The_Gadget.Menu,
184 Child => The_Gadget.File_Menu);
185
186
187
188 --------------------
189 -- CREATE NEW_TAB --
190 --------------------
191
192 -- Create New_Tab to go on File_Dropdown.
193 Gtk.Image_Menu_Item.Gtk_New_From_Stock (Widget => The_Gadget.New_Tab,
194 Stock_Id => "gtk-new");
195
196 -- Connect New_Tab to its callback procedure.
197 Callbacks_Gadget.Image_Menu_Item_Callback_Pkg.Connect
198 (Widget => The_Gadget.New_Tab,
199 Name => "activate",
200 Marsh => Callbacks_Gadget.Image_Menu_Item_Callback_Pkg.To_Marshaller
201 (Gadget_Pkg.Callbacks.On_New_Tab_Activate'Access));
202
Gadget: Building a Compound Widget with GtkAda


DOCUMENT CURRENT ONLY WHEN PRINTED
c:\documents and settings\rick\desktop\gadget.docx
Printed on Wednesday, 2 February 2011
Page 31 of 50
31


203 -- Attach New_Tab to File_Dropdown.
204 -- The procedure 'Append' is inherited from 'Gtk.Menu_Shell'.
205 Gtk.Menu.Append (Menu_Shell => The_Gadget.File_Dropdown,
206 Child => The_Gadget.New_Tab);
207
208
209
210 -------------------------------------------------------
211 -- REPEAT THE PROCESS FOR 'OPEN_TAB' ON THE DROPDOWN --
212 -------------------------------------------------------
213
214 -- Create Open_Tab to go on File_Dropdown.
215 Gtk.Image_Menu_Item.Gtk_New_From_Stock (Widget => The_Gadget.Open_Tab,
216 Stock_Id => "gtk-open");
217
218 -- connect Open_Tab to its callback procedure.
219 Callbacks_Gadget.Image_Menu_Item_Callback_Pkg.Connect
220 (Widget => The_Gadget.Open_Tab,
221 Name => "activate",
222 Marsh => Callbacks_Gadget.Image_Menu_Item_Callback_Pkg.To_Marshaller
223 (Gadget_Pkg.Callbacks.On_Open_Tab_Activate'Access));
224
225 -- Attach Open_Tab to File_Dropdown.
226 -- The procedure 'Append' is inherited from 'Gtk.Menu_Shell'.
227 Gtk.Menu.Append (Menu_Shell => The_Gadget.File_Dropdown,
228 Child => The_Gadget.Open_Tab);
229
230
231
232
-------------------------------------------------------
234 -- REPEAT THE PROCESS FOR 'SAVE_TAB' ON THE DROPDOWN --
235 -------------------------------------------------------
236
Gadget: Building a Compound Widget with GtkAda


DOCUMENT CURRENT ONLY WHEN PRINTED
c:\documents and settings\rick\desktop\gadget.docx
Printed on Wednesday, 2 February 2011
Page 32 of 50
32


237 -- Create Save_Tab to go on File_Dropdown.
238 Gtk.Image_Menu_Item.Gtk_New_From_Stock
239 (Widget => The_Gadget.Save_Tab,
240 Stock_Id => "gtk-save");
241
242 -- connect Save_Tab to its callback procedure.
243 Callbacks_Gadget.Image_Menu_Item_Callback_Pkg.Connect
244 (Widget => The_Gadget.Save_Tab,
245 Name => "activate",
246 Marsh => Callbacks_Gadget.Image_Menu_Item_Callback_Pkg.To_Marshaller
247 (Gadget_Pkg.Callbacks.On_Save_Tab_Activate'Access));
248
249 -- Attach Save_Tab tab to File_Dropdown.
250 -- The procedure 'Append' is inherited from 'Gtk.Menu_Shell'.
251 Gtk.Menu.Append (Menu_Shell => The_Gadget.File_Dropdown,
252 Child => The_Gadget.Save_Tab);
253
254
255
256 -------------------------------------------------------------
257 -- REPEAT THE PROCESS FOR A 'SAVE_AS' ITEM ON THE DROPDOWN --
258 -------------------------------------------------------------
259
260 -- Create Save_As_Tab to go on File_Dropdown.
261 Gtk.Image_Menu_Item.Gtk_New_From_Stock
262 (Widget => The_Gadget.Save_As_Tab,
263 Stock_Id => "gtk-save-as");
264
265 -- Connect Save_As_Tab to its callback procedure.
266 Callbacks_Gadget.Image_Menu_Item_Callback_Pkg.Connect
267 (Widget => The_Gadget.Save_As_Tab,
268 Name => "activate",
269 Marsh => Callbacks_Gadget.Image_Menu_Item_Callback_Pkg.To_Marshaller
270 (Gadget_Pkg.Callbacks.On_Save_As_Tab_Activate'Access));
Gadget: Building a Compound Widget with GtkAda


DOCUMENT CURRENT ONLY WHEN PRINTED
c:\documents and settings\rick\desktop\gadget.docx
Printed on Wednesday, 2 February 2011
Page 33 of 50
33


271
272 -- Attach the 'Save As' tab to File_Dropdown.
273 -- The procedure 'Append' is inherited from 'Gtk.Menu_Shell'.
274 Gtk.Menu.Append (Menu_Shell => The_Gadget.File_Dropdown,
275 Child => The_Gadget.Save_As_Tab);
276
277
278
279 -------------------------------------
280 -- PUT A SEPARATOR ON THE DROPDOWN --
281 -------------------------------------
282
283 -- Creste File_Separator.
284 Gtk.Separator_Menu_Item.Gtk_New (Widget => The_Gadget.File_Separator);
285
286 -- Install File_Separator on File_Dropdown.
287 Gtk.Menu.Append (Menu_Shell => The_Gadget.File_Dropdown,
288 Child => The_Gadget.File_Separator);
289
290
291
292 --------------------------------------------------------------
293 -- REPEAT THE TAB PROCESS FOR A 'QUIT' ITEM ON THE DROPDOWN --
294 --------------------------------------------------------------
295
296 -- Create Quit_Tab to go on File_Dropdown.
297 Gtk.Image_Menu_Item.Gtk_New_From_Stock
298 (Widget => The_Gadget.Quit_Tab,
299 Stock_Id => "gtk-quit");
300
301 -- connect that new item to its callback procedure.
302 Callbacks_Gadget.Image_Menu_Item_Callback_Pkg.Connect
303 (Widget => The_Gadget.Quit_Tab,
304 Name => "activate",
Gadget: Building a Compound Widget with GtkAda


DOCUMENT CURRENT ONLY WHEN PRINTED
c:\documents and settings\rick\desktop\gadget.docx
Printed on Wednesday, 2 February 2011
Page 34 of 50
34


305 Marsh => Callbacks_Gadget.Image_Menu_Item_Callback_Pkg.To_Marshaller
306 (Gadget_Pkg.Callbacks.On_Quit_Tab_Activate'Access));
307
308 -- Attach Quit_Tab to File_Dropdown.
309 -- The procedure 'Append' is inherited from 'Gtk.Menu_Shell'.
310 Gtk.Menu.Append (Menu_Shell => The_Gadget.File_Dropdown,
311 Child => The_Gadget.Quit_Tab);
312
313
314
315 -----------------------------------
316 -----------------------------------
317 ---- NOW WE CREATE AND INSTALL ----
318 ---- THE EDITING SCREEN ----
319 -----------------------------------
320 -----------------------------------
321
322 -----------------------------------------
323 -- CREATE AND INSTALL THE SCREEN_FRAME --
324 -----------------------------------------
325
326 -- Create Screen_Frame_HBox to hold Screen_Frame.
327 Gtk.Box.Gtk_New_HBox (Box => The_Gadget.Screen_Frame_HBox,
328 Homogeneous => TRUE,
329 Spacing => 0);
330
331 -- Create Screen_Frame.
332 Gtk.Frame.Gtk_New (Frame => The_Gadget.Screen_Frame,
333 Label => "Add Text");
334
335 -- Specify the border width of Screen_Frame.
336 -- Set_Border_Width inherited from Gtk.Container.
337 Gtk.Frame.Set_Border_Width (Container => The_Gadget.Screen_Frame,
338 Border_Width => 4);
Gadget: Building a Compound Widget with GtkAda


DOCUMENT CURRENT ONLY WHEN PRINTED
c:\documents and settings\rick\desktop\gadget.docx
Printed on Wednesday, 2 February 2011
Page 35 of 50
35


339
340 -- Specify what the frame looks like.
341 Gtk.Frame.Set_Shadow_Type (Frame => The_Gadget.Screen_Frame,
342 The_Type => Gtk.Enums.Shadow_In);
343
344 -- Install Screen_Frame in Screen_Frame_HBox.
345 Gtk.Box.Pack_Start (In_Box => The_Gadget.Screen_Frame_Hbox,
346 Child => The_Gadget.Screen_Frame);
347
348 -- Install Screen_Frame_HBox in Window_VBox where it will appear below
349 -- Menu_Bar.
350 Gtk.Box.Pack_Start (In_Box => The_Gadget.Window_VBox,
351 Child => The_Gadget.Screen_Frame_HBox,
352 Expand => TRUE,
353 Fill => TRUE,
354 Padding => 0);
355
356
357
358 -----------------------------------------------
359 -- CREATE AND INSTALL SCREEN WITH SCROLLBARS --
360 -----------------------------------------------
361
362 -- Create the HBox to hold Screen.
363 Gtk.Box.Gtk_New_HBox (Box => The_Gadget.Screen_Base_Box,
364 Homogeneous => TRUE,
365 Spacing => 3);
366
367 -- Create the Scrollbars for Screen.
368 Gtk.Scrolled_Window.Gtk_New (Scrolled_Window => The_Gadget.Scroll,
369 Hadjustment => null,
370 Vadjustment => null);
371
372 -- Specify the way Scroll looks.
Gadget: Building a Compound Widget with GtkAda


DOCUMENT CURRENT ONLY WHEN PRINTED
c:\documents and settings\rick\desktop\gadget.docx
Printed on Wednesday, 2 February 2011
Page 36 of 50
36


373 Gtk.Scrolled_Window.Set_Shadow_Type
374 (Scrolled_Window => The_Gadget.Scroll,
375 Shadow_Type => Gtk.Enums.Shadow_Out);
376
377 -- Specify the way Scroll operates.
378 Gtk.Scrolled_Window.Set_Policy
379 (Scrolled_Window => The_Gadget.Scroll,
380 H_Scrollbar_Policy => Gtk.Enums.Policy_Automatic,
381 V_Scrollbar_Policy => Gtk.Enums.Policy_Automatic);
382
383 -- Create Screen.
384 Gtk.Text_View.Gtk_New (Widget => The_Gadget.Screen,
385 Buffer => The_Gadget.Screen_Buffer);
386
387 -- Set minimum size of The_Gadget.Screen.
388 -- Inherited from Gtk.Widget.
389 Gtk.Text_View.Set_Size_Request (Widget => The_Gadget.Screen,
390 Width => 300,
391 Height => 200);
392
393 -- Set margins of The_Gadget.Screen.
394 Gtk.Text_View.Set_Left_Margin (Text_View => The_Gadget.Screen,
395 Left_Margin => 5);
396 Gtk.Text_View.Set_Right_Margin (Text_View => The_Gadget.Screen,
397 Right_Margin => 5);
398
399 -- Set The_Gadget.Screen. to word wrap.
400 Gtk.Text_View.Set_Wrap_Mode (Text_View => The_Gadget.Screen,
401 Wrap_Mode => Gtk.Enums.Wrap_Word);
402
403 -- Activate the TAB button for The_Gadget.Screen..
404 Gtk.Text_View.Set_Accepts_Tab (Text_View => The_Gadget.Screen,
405 Accepts_Tab => TRUE);
406
Gadget: Building a Compound Widget with GtkAda


DOCUMENT CURRENT ONLY WHEN PRINTED
c:\documents and settings\rick\desktop\gadget.docx
Printed on Wednesday, 2 February 2011
Page 37 of 50
37


407 -- Install Screen in Scroll.
408 -- 'Add' inherited from Gtk.Container.
409 Gtk.Scrolled_Window.Add (Container => The_Gadget.Scroll,
410 Widget => The_Gadget.Screen);
411
412 -- Install Scroll in Screen_Base_Box.
413 Gtk.Box.Pack_Start (In_Box => The_Gadget.Screen_Base_Box,
414 Child => The_Gadget.Scroll,
415 Expand => TRUE,
416 Fill => TRUE,
417 Padding => 5);
418
419 -- Install the Screen_Base_Box in the Screen_Frame.
420 -- 'Add' is inherited from Gtk.Container.
421 Gtk.Frame.Add (Container => The_Gadget.Screen_Frame,
422 Widget => The_Gadget.Screen_Base_Box);
423
424
425
426 -----------------------------------
427 -----------------------------------
428 ---- NOW WE CREATE AND INSTALL ----
429 ---- THE HORIZONTAL SEPARATOR ----
430 -----------------------------------
431 -----------------------------------
432
433 -- Create H_Sep_Base_HBox to hold H_Sep.
434 Gtk.Box.Gtk_New_HBox (Box => The_Gadget.H_Sep_Base_HBox,
435 Homogeneous => TRUE,
436 Spacing => 0);
437
438 -- Create the Separator.
439 Gtk.Separator.Gtk_New_Hseparator (Separator => The_Gadget.H_Sep);
440
Gadget: Building a Compound Widget with GtkAda


DOCUMENT CURRENT ONLY WHEN PRINTED
c:\documents and settings\rick\desktop\gadget.docx
Printed on Wednesday, 2 February 2011
Page 38 of 50
38


441 -- Install H_Sep in H_Sep_Base_HBox.
442 Gtk.Box.Pack_Start (In_Box => The_Gadget.H_Sep_Base_HBox,
443 Child => The_Gadget.H_Sep,
444 Expand => TRUE,
445 Fill => TRUE,
446 Padding => 0);
447
448 -- Install H_Sep_Base_HBox in Window_VBox.
449 Gtk.Box.Pack_Start (In_Box => The_Gadget.Window_VBox,
450 Child => The_Gadget.H_Sep_Base_HBox,
451 Expand => false,
452 Fill => TRUE,
453 Padding => 0);
454
455
456
457 ------------------------------
458 ------------------------------
459 ---- NOW WE CREATE AND ----
460 ---- INSTALL THE KEYBOARD ----
461 ------------------------------
462 ------------------------------
463
464 ---------------------------------------
465 -- CREATE THE BOXES FOR THE KEYBOARD --
466 ---------------------------------------
467
468 -- Create Buttons_Base_Box.
469 Gtk.Box.Gtk_New_HBox (Box => The_Gadget.Buttons_Base_Box,
470 Homogeneous => TRUE,
471 Spacing => 0);
472
473 -- Install Buttons_Base_Box in Window_VBox.
474 Gtk.Box.Pack_Start (In_Box => The_Gadget.Window_VBox,
Gadget: Building a Compound Widget with GtkAda


DOCUMENT CURRENT ONLY WHEN PRINTED
c:\documents and settings\rick\desktop\gadget.docx
Printed on Wednesday, 2 February 2011
Page 39 of 50
39


475 Child => The_Gadget.Buttons_Base_Box,
476 Expand => false,
477 Fill => TRUE,
478 Padding => 5);
479
480 -- Create Buttons_HBox which will eventually have 3 cells.
481 Gtk.Box.Gtk_New_HBox (Box => The_Gadget.Buttons_HBox,
482 Homogeneous => false,
483 Spacing => 0);
484
485 -- Install Buttons_HBox in Buttons_Base_Box.
486 Gtk.Box.Pack_Start (In_Box => The_Gadget.Buttons_Base_Box,
487 Child => The_Gadget.Buttons_HBox,
488 Expand => TRUE,
489 Fill => TRUE,
490 Padding => 0);
491
492
493
-----------------------------------
495 -- CREATE AND INSTALL BIG_BUTTON --
496 -----------------------------------
497
498 -- Create Big_Button_Base_HBox.
499 Gtk.Box.Gtk_New_HBox (Box => The_Gadget.Big_Button_Base_HBox,
500 Homogeneous => TRUE,
501 Spacing => 0);
502
503 -- Create Big_Button.
504 Gtk.Button.Gtk_New (Button => The_Gadget.Big_Button,
505 Label => "");
506
507 -- Create Big_Button_Label.
508 Gtk.Label.Gtk_New (Label => The_Gadget.Big_Button_Label,
Gadget: Building a Compound Widget with GtkAda


DOCUMENT CURRENT ONLY WHEN PRINTED
c:\documents and settings\rick\desktop\gadget.docx
Printed on Wednesday, 2 February 2011
Page 40 of 50
40


509 Str => "BIG"
510 & Ada.Characters.Latin_1.CR
511 & "BUTTON");
512
513 -- Justify the text in Big_Button_Label.
514 Gtk.Label.Set_Justify (Label => The_Gadget.Big_Button_Label,
515 Jtype => Gtk.Enums.Justify_Center);
516
517 -- Insert Big_Button_Label into Big_Button.
518 -- Procedure inherited from Gtk.Container.
519 Gtk.Button.Add (Container => The_Gadget.Big_Button,
520 Widget => The_Gadget.Big_Button_Label);
521
522 -- Connect Big_Button to its callback procedure.
523 Callbacks_Gadget.Button_Callback_Pkg.Connect
524 (Widget => The_Gadget.Big_Button,
525 Name => "clicked",
526 Marsh => Callbacks_Gadget.Button_Callback_Pkg.To_Marshaller
527 (Gadget_Pkg.Callbacks.On_Big_Button_Clicked'Access));
528
529 -- Create a tooltip to tell the user what Big_Button is.
530 Gtk.Tooltips.Gtk_New (Widget => The_Gadget.Big_Button_Tooltip);
531
532 Gtk.Tooltips.Set_Tip (Tooltips => The_Gadget.Big_Button_Tooltip,
533 Widget => The_Gadget.Big_Button,
534 Tip_Text => Gadget_Intl.Local_Format
535 (Input => "This is a big button"),
536 Tip_Private => Gadget_Intl.Local_Format
537 (Input => ""));
538
539 -- Install Big_Button_Base_HBox in Buttons_HBox.
540 Gtk.Box.Pack_Start (In_Box => The_Gadget.Buttons_HBox,
541 Child => The_Gadget.Big_Button_Base_HBox,
542 Expand => TRUE,
Gadget: Building a Compound Widget with GtkAda


DOCUMENT CURRENT ONLY WHEN PRINTED
c:\documents and settings\rick\desktop\gadget.docx
Printed on Wednesday, 2 February 2011
Page 41 of 50
41


543 Fill => TRUE,
544 Padding => 3);
545
546 -- Install Big_Button in Big_Button_Base_HBox.
547 Gtk.Box.Pack_Start (In_Box => The_Gadget.Big_Button_Base_HBox,
548 Child => The_Gadget.Big_Button,
549 Expand => TRUE,
550 Fill => TRUE,
551 Padding => 0);
552
553
554
555 ------------------------------
556 -- CREATE AND INSTALL V_SEP --
557 ------------------------------
558
559 -- Create V_Sep_HBox.
560 Gtk.Box.Gtk_New_HBox (Box => The_Gadget.V_Sep_HBox,
561 Homogeneous => TRUE,
562 Spacing => 0);
563
564 -- Create V_Sep.
565 Gtk.Separator.Gtk_New_Vseparator (Separator => The_Gadget.V_Sep);
566
567 -- Install V_Sep in V_Sep_HBox.
568 -- V_Sep_HBox is a single-cell box so Expand and fill don't have much
569 -- effect on the width of the Separator area.
570 Gtk.Box.Pack_Start (In_Box => The_Gadget.V_Sep_HBox,
571 Child => The_Gadget.V_Sep,
572 Expand => TRUE,
573 Fill => TRUE,
574 Padding => 0);
575
576 -- Install V_Sep_HBox in Buttons_HBox.
Gadget: Building a Compound Widget with GtkAda


DOCUMENT CURRENT ONLY WHEN PRINTED
c:\documents and settings\rick\desktop\gadget.docx
Printed on Wednesday, 2 February 2011
Page 42 of 50
42


577 -- Buttons_HBox is the three-cell box so don't expand here and the
578 -- Separator will appear as a narrow line only.
579 Gtk.Box.Pack_Start (In_Box => The_Gadget.Buttons_HBox,
580 Child => The_Gadget.V_Sep_HBox,
581 Expand => false,
582 Fill => TRUE,
583 Padding => 3);
584
585
586
587 --------------------------------------
588 -- CREATE AND INSTALL THREE BUTTONS --
589 --------------------------------------
590
591 -- Create Three_Buttons_Base_HBox.
592 Gtk.Box.Gtk_New_HBox (Box => The_Gadget.Three_Buttons_Base_HBox,
593 Homogeneous => TRUE,
594 Spacing => 2);
595
596 -- Install Three_Buttons_Base_HBox in Buttons_HBox.
597 Gtk.Box.Pack_Start (In_Box => The_Gadget.Buttons_HBox,
598 Child => The_Gadget.Three_Buttons_Base_HBox,
599 Expand => TRUE,
600 Fill => TRUE,
601 Padding => 0);
602
603 -- Create Three_Buttons_VBox.
604 -- This box will have 3 cells.
605 Gtk.Box.Gtk_New_VBox (Box => The_Gadget.Three_Buttons_VBox,
606 Homogeneous => TRUE,
607 Spacing => 0);
608
609 -- Install Three_Buttons_VBox in Three_Buttons_Base_HBox.
610 Gtk.Box.Pack_Start (In_Box => The_Gadget.Three_Buttons_Base_HBox,
Gadget: Building a Compound Widget with GtkAda


DOCUMENT CURRENT ONLY WHEN PRINTED
c:\documents and settings\rick\desktop\gadget.docx
Printed on Wednesday, 2 February 2011
Page 43 of 50
43


611 Child => The_Gadget.Three_Buttons_VBox,
612 Expand => TRUE,
613 Fill => TRUE,
614 Padding => 0);
615
616

618 -----------------------------------------------------
619 -- CREATE AND INSTALL THREE BUTTONS WITH CALLBACKS --
620 -----------------------------------------------------
621
622 -- Create B1_HBox.
623 Gtk.Box.Gtk_New_HBox (Box => The_Gadget.B1_HBox,
624 Homogeneous => TRUE,
625 Spacing => 0);
626
627 -- Create B1.
628 Gtk.Button.Gtk_New (Button => The_Gadget.B1,
629 Label => "B1");
630
631 -- Connect B1 to its callback procedure.
632 Callbacks_Gadget.Button_Callback_Pkg.Connect
633 (Widget => The_Gadget.B1,
634 Name => "clicked",
635 Marsh => Callbacks_Gadget.Button_Callback_Pkg.To_Marshaller
636 (Gadget_Pkg.Callbacks.On_B1_Clicked'Access));
637
638 -- Create a tooltip to tell the user what B1 is.
639 Gtk.Tooltips.Gtk_New (Widget => The_Gadget.B1_Tooltip);
640
641 Gtk.Tooltips.Set_Tip (Tooltips => The_Gadget.B1_Tooltip,
642 Widget => The_Gadget.B1,
643 Tip_Text => Gadget_Intl.Local_Format
644 (Input => "This is B1"),
Gadget: Building a Compound Widget with GtkAda


DOCUMENT CURRENT ONLY WHEN PRINTED
c:\documents and settings\rick\desktop\gadget.docx
Printed on Wednesday, 2 February 2011
Page 44 of 50
44


645 Tip_Private => Gadget_Intl.Local_Format
646 (Input => ""));
647
648 -- Install B1 in B1_HBox.
649 Gtk.Box.Pack_Start (In_Box => The_Gadget.B1_HBox,
650 Child => The_Gadget.B1,
651 Expand => TRUE,
652 Fill => TRUE,
653 Padding => 3);
654
655 -- Install B1_HBox in Three_Buttons_VBox.
656 Gtk.Box.Pack_Start (In_Box => The_Gadget.Three_Buttons_VBox,
657 Child => The_Gadget.B1_HBox,
658 Expand => TRUE,
659 Fill => TRUE,
660 Padding => 3);
661
662
664 -- Create B2_HBox.
665 Gtk.Box.Gtk_New_HBox (Box => The_Gadget.B2_HBox,
666 Homogeneous => TRUE,
667 Spacing => 3);
668
669 -- Create B2.
670 Gtk.Button.Gtk_New (Button => The_Gadget.B2,
671 Label => "B2");
672
673 -- Connect B2 to its callback procedure.
674 Callbacks_Gadget.Button_Callback_Pkg.Connect
675 (Widget => The_Gadget.B2,
676 Name => "clicked",
677 Marsh => Callbacks_Gadget.Button_Callback_Pkg.To_Marshaller
678 (Gadget_Pkg.Callbacks.On_B2_Clicked'Access));
679
Gadget: Building a Compound Widget with GtkAda


DOCUMENT CURRENT ONLY WHEN PRINTED
c:\documents and settings\rick\desktop\gadget.docx
Printed on Wednesday, 2 February 2011
Page 45 of 50
45


680 -- Create a tooltip to tell the user what B2 is.
681 Gtk.Tooltips.Gtk_New (Widget => The_Gadget.B2_Tooltip);
682
683 Gtk.Tooltips.Set_Tip (Tooltips => The_Gadget.B2_Tooltip,
684 Widget => The_Gadget.B2,
685 Tip_Text => Gadget_Intl.Local_Format
686 (Input => "This is B2"),
687 Tip_Private => Gadget_Intl.Local_Format
688 (Input => ""));
689
690 -- Install B2 in B2_HBox.
691 Gtk.Box.Pack_Start (In_Box => The_Gadget.B2_HBox,
692 Child => The_Gadget.B2,
693 Expand => TRUE,
694 Fill => TRUE,
695 Padding => 3);
696
697 -- Install B2_HBox in Three_Buttons_VBox.
698 Gtk.Box.Pack_Start (In_Box => The_Gadget.Three_Buttons_VBox,
699 Child => The_Gadget.B2_HBox,
700 Expand => TRUE,
701 Fill => TRUE,
702 Padding => 3);
703
704
706 -- Create B3_HBox.
707 Gtk.Box.Gtk_New_HBox (Box => The_Gadget.B3_HBox,
708 Homogeneous => TRUE,
709 Spacing => 0);
710
711 -- Create B3.
712 Gtk.Button.Gtk_New (Button => The_Gadget.B3,
713 Label => "B3");
714
Gadget: Building a Compound Widget with GtkAda


DOCUMENT CURRENT ONLY WHEN PRINTED
c:\documents and settings\rick\desktop\gadget.docx
Printed on Wednesday, 2 February 2011
Page 46 of 50
46


715 -- Connect B3 to its callback procedure.
716 Callbacks_Gadget.Button_Callback_Pkg.Connect
717 (Widget => The_Gadget.B3,
718 Name => "clicked",
719 Marsh => Callbacks_Gadget.Button_Callback_Pkg.To_Marshaller
720 (Gadget_Pkg.Callbacks.On_B3_Clicked'Access));
721
722 -- Create a tooltip to tell the user what B3 is.
723 Gtk.Tooltips.Gtk_New (Widget => The_Gadget.B3_Tooltip);
724
Gtk.Tooltips.Set_Tip (Tooltips => The_Gadget.B3_Tooltip,
726 Widget => The_Gadget.B3,
727 Tip_Text => Gadget_Intl.Local_Format
728 (Input => "This is B3"),
729 Tip_Private => Gadget_Intl.Local_Format
730 (Input => ""));
731
-- Install B3 in B3_HBox.
733 Gtk.Box.Pack_Start (In_Box => The_Gadget.B3_HBox,
734 Child => The_Gadget.B3,
735 Expand => TRUE,
736 Fill => TRUE,
737 Padding => 3);
738
739 -- Install B3_HBox in Three_Buttons_VBox.
740 Gtk.Box.Pack_Start (In_Box => The_Gadget.Three_Buttons_VBox,
741 Child => The_Gadget.B3_HBox,
742 Expand => TRUE,
743 Fill => TRUE,
744 Padding => 3);
745 end Initialize;
746
747 end Gadget_Pkg;

Gadget: Building a Compound Widget with GtkAda


DOCUMENT CURRENT ONLY WHEN PRINTED
c:\documents and settings\rick\desktop\gadget.docx
Printed on Wednesday, 2 February 2011
Page 47 of 50
47


11 Reference List
Software Productivity Consortium (1995). Ada 95 Quality and Style:
Guidelines for Professional Programmers. Department of Defense
Ada Joint Program Office.

Você também pode gostar