traversal.tcl --

       Email: jjddss@my-deja.com

       Copyright (c) 2000 Jay Schmidgall


Provides a conceptual tab group with bindings which enable traversal
between widgets to occur within and between tab groups. Within a tab
group, the arrow keys move the keyboard focus amongst widgets. The
The tab key moves keyboard focus between tab groups.

It is possible to select between three types of traversal. The default
is to have the arrows move keyboard focus in their direction. This is
analogous to the common traversal used in other GUI toolkits. For
example, given the widget layout below:

                 +---+
                 | 1 |     Starting with the focus on 2, using the
   +---+---+---+ +---+     left arrow, focus would move 3-4-5-6-7-1-2.
   | 2 | 3 | 4 | | 5 |     Using the up arrow, focus would move
   +---+---+---+-+-+-+-+   7-5-1-6-4-3-2. Down, 3-4-6-1-5-7-2.
               | 6 | 7 |   Right, focus would move 1-7-6-5-4-3-2.
               +---+---+

Note that in the case of a widget layout as follows:

   +---+   +---+  The traversal order here for standard traversal
   |   +---+   |  with the focus on 1 would be, moving right, 3-2-1.
   | 1 | 2 | 3 |  Moving left, 2-3-1. Moving up, 3-2-1. And down,
   |   +---+   |  2-3-1. This might seem counter-intuitive at first,
   +---+   +---+  but it is actually correct.
   
For example, if you had the following layout:

   +---+   +---+  You would get the same traversal order. This same
   | 1 |   | 3 |  order would occur as button 2 moves upward, until
   +---+---+---+  it reaches the same y position as buttons 1 and 3.
       | 2 |      At that time, the traversal order would change.
       +---+

Another option is to have ordered traversal, wherein up and left move
keyboard focus to the previous ordered widget, and right and down move
keyboard focus to the next ordered widget. In this case, the order is
determined by the order in which the widgets were given when made a
tab group.

The final possibility is to have completely custom traversal wihin a
tab group. In this case, the value of the method parameter to makeTabGroup
is assumed to be a command which will take two arguments, a widget and a
direction, direction being given as either lt, up, rt or dn for moving the
focus either left, up, right or down, respectively. The command is
responsible for moving the focus appropriately.

------------------------------------------------------------------------
INSTALLATION
------------------------------------------------------------------------
If you have wish installed and in your path and you are not on MacOS,
you can simply run 'install.tcl'.

If not, you will need to create a directory 'traversal' in Tk's library,
and copy traversal.tcl and pkgIndex.tcl to that directory.

------------------------------------------------------------------------
USAGE
------------------------------------------------------------------------

traversal::makeTabGroup --

      Establish the given widget as a tab group

      Arguments:
          widget          The widget to make a tabgroup
          container       Optional widget for which widget becomes a tab group.
                          Defaults to widget parent if not specified.
          method          Option method of traversal: standard, order or
                          <name of command>
          widgetlist      Optional list of widgets to make up the tabgroup
                          for widget. Defaults to children of widget, else
                          any widgets packed in the widget, else the widget
                          itself.

      Results:
          The given widget is made a tab group. Note that it is possible to
          invoke multiple times for the same widget if you wish to change
          the traversal method.

traversal::expand --

      Accumulate all widgets which are final descendants of the widgets in
      the given list; that is, if any of the given widgets have children,
      get them and add them to the list if they have no children. If they
      do, get their children and add them to the list. This also applies
      to slaves managed by the widget as well.
      
      This is basically a convenience routine for making a tab group out of
      a complex sequence of nested frames or such.
      
      Arguments:
          widgetlist      The list of widgets
          include         Optional flag whether to include widgets with
                          children in the list
      Results:
          A list containing all bottom-level children

------------------------------------------------------------------------
Example usage
------------------------------------------------------------------------

package require traversal

traversal::makeTabGroup .widget

traversal::expand .widget

------------------------------------------------------------------------
Known bugs: (1)
------------------------------------------------------------------------
There is currently an existing bug when using widgets of all different
heights when the heights are quite close, and the geometry management
of the widgets with similar heights ends up placing those widgets at the
same y position.

I imagine I might argue this is a bug in grid, not in traversal, but
there are probably other ways to produce this problem. Note the bug
occurs in this scenario only when the heights are different.

Since this seems a somewhat pathological case, I've decided to release
the package as a 0.9 version. I would prefer to have an elegant solution
to this problem before updating the package to 1.0 status. If you have
any ideas, please feel free to contact me at jjddss@my-deja.com.

Note that the test suite does exercise this bug in the final set of
tests. The traversal problem is caused because the grid positions the
first and second buttons in the second row at the same height. This
causes the problem.

------------------------------------------------------------------------
Change History
------------------------------------------------------------------------
Apr 07 2000    Version 0.9 released to the world.
 
