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 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 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.