The {\em hush} interpreter
\c{
The hush library is intended to provide a convenient way to program
Tcl/Tk based applications in C++.
In an ordinary C++ program the
function main is used to start the computation.
Control is effected by creating objects and
calling the appropriate functions.
When programming in a window based application, at a certain
moment control is delegated to the window environment.
Consequently, there needs to be some kind of main loop
which waits for incoming events, in response to which
the control may be delegated to an appropriate
component of the program.
Since programming an event dispatch loop by hand
is very cumbersome, the main (event dispatch) loop
is usually hidden, and instead the programmer
is required to declare callback functions
that will be activated in response to a particular event.
To hide the details of activating the main loop
and the dispatching of events, hush provides
a class session (similar to the session class of
InterViews) of which an instance must be created
to start the computation.
}
\c{
The actual interface to the (embedded) Tcl interpreter
is defined by the class kit.
(The class interfaces we present in the following
are all somewhat simplified.)
}
\sli{
The interpreter {\em kit}
kit
interface kit : hcl {
int eval(char* cmd); \c{to evaluate script commands}
int source(char* file);
void after(int msecs, char* cmd);
void update(char* options="");
char* send(char* it, char* cmd);
char* selection(char* options="");
class event event(); \c{returns the last event}
action(char* name, handler* h);
action(char* name, command f, client* data = 0 );
widget t* root(); \c{returns toplevel (root) widget}
widget* pack(widget* w, char* options);
void trace(int level = 1);
void quit() \c{to terminate the session}
};
}
\c{
The functions eval may be used to execute
commands in the Tcl scripting language directly.
A Tcl command is simply a string conforming to
certain syntactic requirements.
n addition, the function source may be used to read in
a file containing a Tcl script.
Further, we have
the function after, that may be used to have a
Tcl command evaluated after n milliseconds,
and a function update to process any pending events.
To communicate with other (hush-based) applications,
we have the function
send (which may be used to evaluate
a command in a different application) and
the function selection
(that delivers the current X selection).
Another important function is the
function event that delivers the latest event.
It may only be used in a command that is bound
to some particular event.
See section [hush-events].
The functions action may be used to associate a Tcl command to
a command function or handler written in C++.
See section [action] for details.
In theor turn, these Tcl commands may be bound to an event.
To deal with widgets, we have
the function root (that gives access to the toplevel root
widget associated with that particular
instance of the kit) and
the function pack (which may be used to append
widgets to the root widget, in order to map them to the screen).
Finally, we have the function trace
(to trace the activity of the interpreter)
and the function quit (to terminate the session).
}
\c{
Widgets
Widgets are the elements a GUI is made of.
They appear as windows on the screen to display
text or graphics and may respond to events
such as motioning the mouse or pressing
a key by calling an action associated with that event.
}
\c{
Most often, the various widgets constituting the user
interface are (hierarchically) related to each other,
as for instance in a drawing application containing
a canvas to display graphic elements,
a button toolbox for selecting the graphic
items and a menubar offering various options
such as saving the drawing in a file.
}
\sli{
Widget
widget
interface widget : handler {
widget(char* p);
widget(widget& w, char* p);
char* path(); \c{returns path of the widget}
int eval(char* cmd); \c{invokes "path() cmd"}
virtual void configure(char* cmd);
widget* pack(widget* w, char* options = "" );
virtual bind(char *b, action& ac, char* args = "" );
handler(action& ac, char* args = "" );
void destroy(); \c{removes widget from the screen}
};
}
\c{
Widgets in Tk are identified by a path name.
The path name of a widget reflects its possible
subordination to another widget.
The format of a path name may be expressed in BNF form as
-
where denotes the empty string.
For example "." is the path name of the root widget,
whereas ".quit" is the path name of a widget
subordinate to the root widget.
A widget subordinate to another widget
must have the path name of that widget
as part of its own path name.
For example, the widget ".f.m" may have a widget ".f.m.h"
as a subordinate widget.
}
\nop{
Widgets may be configured in a variety of
ways.
For example most widgets allow specification of
a foreground and a background color.
The hush interface delegates most of these issues
to the underlying toolkit.
Users wishing to improve on the default
appearance of the widgets must study
the options provided by Tk.
}
\c{
Naming widgets in a hierarchical fashion does not imply
that the widgets behave accordingly.
To group widgets, they must be packed in a common
ancestor widget, that is a frame or toplevel
widget.
}
\nop{
Alternatively, The Tcl command pack may be used.
To map a widget to the screen it must either
be packed in the root widget, using ,
or to a toplevel widget, using .\ftn{
The pack command offered by Tcl/Tk is likely to
change in the near future. This may affect the
corresponding member functions for kit and widget as well.
\nop{Consult the reference manual for details.}
}
}
\c{
The widget class is an abstract class.
Calling the constructor widget as in
widget* w = new widget(".awry");
does not result in creating an actual
widget but only defines a pointer to the widget
with that particular name.
If a widget with that name exists, it may be treated
as an ordinary widget object, otherwise an error will occur.
The constructor creates
a widget by appending the path name path to the
path name of the argument widget w.
The function path delivers the path name of
a widget object.
Each widget created by Tk actually defines a
Tcl command associated with the
path name of the widget.
In other words, an actual widget may be regarded
as an object which can be asked to evaluate commands.
For example a widget ".b" may be asked to change
its background color by a Tcl command like
.b configure -background blue
The function eval
enables the programmer to apply Tcl commands
to the widget directly, as does the configure
command.
The function pack is used to pack widgets together.
}
\c{
Widgets may respond to particular events.
To associate an event with an action,
an explicit binding must be defined for that
particular widget.
Some widgets provide default bindings.
These may however be overruled by using bind
or handler. See section [userXX].
Finally, we have the function destroy,
to remove the widget from the screen.
}