\c{
Configuring widgets
Widgets are the elements from which a GUI is made.
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.
Usually, the various widgets constituting the user
interface are (hierarchically) related to each other,
such as in the drawtool application which contains
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.
}
\c{
Widgets in Tk are identified by a path name.
The path name of a widget reflects its possible
subordination to another widget.
See slide [widget-hierarchy].
}
.so f_lay
\c{
Pathnames consist of strings separated by dots.
The first character of a path must be a dot.
The first letter of a path must be lower case.
The format of a path name may be expressed in BNF form as
-
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.
Note that the widget hierarchy induced by the path names
is completely orthogonal to the widget class inheritance
hierarchy depicted in
slide [hush-overview] (a) and
slide [widget-classes].
With respect to the path name hierarchy, when speaking of
ancestors we simply mean superordinate widgets.
}
\c{
Pathnames are treated somewhat more liberally in hush.
For example, widget path names may simply be defined
or extended by a string.
The missing dot is then automatically inserted.
}
.so sli-widget
\c{
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.
(It is not an abstract class, technically, since it does not
contain any pure virtual functions, see section [abstract-class].)
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 functions eval, result and evaluate
enable the programmer to apply Tcl commands
to the widget directly, as does the configure
command.
The function geometry sets the width and height of
the widget.
}
\c{
Naming widgets in a hierarchical fashion does not imply
that the widgets behave accordingly.
The widget class interface offers two
pack functions.
The function
applies to individual widgets.
As options one may specify, for example,
{\tt -side X}, where {\tt X} is either
top, bottom, left
or right,
to pack the widget to the appropriate side
of the cavity specified by the ancestor widget.
Other options are -fill x or
-fill y, to fill up the space
in the appropriate dimensions,
or {\tt -padx N} or {\tt -pady N}, for
some integer {\tt N},
to surround the widget with some extra space.
Alternatively, the function
may be used, which allows for the same options
but applies packing to the widget parameter.
This function is convenient when packing
widgets in a frame or toplevel widget.
As a remark, the function may only
be used to pack widgets to the root window.
}
\c{
Binding events
Widgets may respond to events.
To associate an event with an action,
an explicit binding must be specified
for that particular widget.
Some widgets provide default bindings.
These may, however, be overruled.
The function bind is used to associate
handlers or actions with events.
The first string parameter of
bind may be used to specify
the event type.
Common event types are,
for example,
{\tt ButtonPress}, {\tt ButtonRelease}
and {\tt Motion}, which are the
default events for canvas widgets.
Also keystrokes may be defined as events,
for example {\tt Return},
which is the default event for
the entry widget.
The function may be
used to associate a handler object
or
action with the default bindings
for the widget.
Concrete widgets may not override the handler
function itself, but must define the protected
virtual function install.
Typically, the install function consists
of calls to bind
for each of the event types that is
relevant to the widget.
For both the bind and handler
functions, the optional args
parameter may be used to specify
the arguments that will be passed
to the handler or action
when it is invoked.
For the button widget, for example,
the default install function supplies
the text of the button as an additional
argument for its handler.
}
\c{
In addition, the widget class offers four
functions that may be used
when defining compound or mega widgets.
The function must by used
to delegate the invocation
of the eval, configure, bind and handler functions
to the widget w.
The function gives access to the widget
to which the commands are redirected.
After invoking redirect,
the function thepath will deliver
the path that is determined by .
In contrast, the function path will still deliver
the path name of the outer widget.
Calling redirect when creating the compound widget
class suffices for most situations.
However, when the default events must be changed or the
declaration
of a handler must take effect for several component widgets,
the virtual function install must be redefined
to handle the delegation explicitly.
How redirect and install actually work will
become clear in the examples.
}
.so termin