The TabBook Widget
1. Copyright
Copyright 1995 Computer Generation, Inc. You may reproduce this document
without charge provided the copyright and disclaimer notices appear. The
software described in this document is copyrighted under separate terms.
See the source code available at
ftp://ftp.compgen.com/pub/widgets/TabBook.tar.Z
The software is provided "as is", without warranty of any kind, express or
implied, including but not limited to the warranties of merchantability,
fitness for a particular purpose and noninfringement. In no event shall
Computer Generation, inc. nor the author be liable for any claim, damages
or other liability, whether in an action of contract, tort or otherwise,
arising from, out of or in connection with the software or the use or other
dealings in the software.
The author welcomes comments and suggestions. Gary Aviv Computer
Generation, Inc., gary@compgen.com 404-705-2811
2. Introduction
TabBook is a Motif manager widget which is similar to Motif's own
XmNotebook widget in appearance. It is significantly less complex and
easier to use, though it has fewer features. It is intended for
installations that lack Motif 2.x or just want basic notebook like
functionality.
TabBook sets up a series of "Tabs" along the top of a "page" area. Children
of TabBook must be either push buttons or manager widgets (such as forms,
bulletin boards, row-columns, etc. or a nested TabBook.) The push buttons
are dressed with tab like borders and arranged horizontally. The child
manager widgets are positioned in the page area so they overlap. There
should be an equal number of manager and push button children. The page
area is sized to fit the largest child manager.The overall TabBook widget
then expands horizontally, if required, to fit all its tabs.
There is one active page at a time. Its corresponding tab is drawn to
appear "on top" and attached to the page. The user may press any tab to
bring up its corresponding page and the associated manager widget.
TabBook inherits behavior and resources from Core, Composite, Constraint,
XmManager, and XmBulletinBoard.
The class pointer is xcgTabBookWidgetClass.
The class name is xcgTabBook.
TabBook reliance on Motif is minor. It consists of inheriting behavior from
XmManager, and XmBulletinBoard, setting resources in XmPushButton, knowing
when a widget is an xmManagerWidgetClass subclass, and using XmGetColors.
It should not be difficult adapting TabBook for use with other widget sets.
3. Version Information
Initial.
4. Distribution Kit
The source distribution kit contains the following files:
TabBook.c TabBook.h TabBookP.h
The TabBook widget source code TabBookTest.c
A small demonstration program Imake
an Imake file to build TabBookTest.c. TabBookTest.make
A hand coded make file for several common OSs in case Imake fails.
TabBook.html TabBook.txt
Documentation in HTML, and plain text formats
TabBook has been compiled successfully on NCR MPRAS, Digital OSF/Unix,
Linux, and probably many others.
To build the test program:
xmkmf
make
5. Resources
TabBook adds the following resources to those it inherits. The resource
class is obtained by replacing the N by a C in the resource name (eg:
XtNactivePage is the name XtNactivePage is the class. The access types are
C (resource may be set at create time), S (may be set using XtSetValues),
or G (may be read using XtGetValues).
XcgNactivePage
Type = Integer, Default = 1, Access = CSG
Sets the active page. Page numbering begins with 1. The tab of active
page
is redrawn to appear on top. When the resource autoManage is set, the
corresponding manager widget for the page is managed and the previous
active manager widget is unmanaged. If the widget is realized, the
XcgNnewPageCallback callback is also called. See Section 10 for
details.
XcgNautoManage
Type = Boolean, Default = True, Access = CSG
Controls whether TabBook automatically manages the active page's
manager
widget when the user presses a tab. See Section 10 for details.
XcgNnewPageCallback
Type = Callback Default = None, Access = CSG
The callback invoked when a tab button is pressed. See Section 7.
6. Constraint Resources
TabBook has the following constraint resources that govern how manager
children are positioned within their page.
XcgNresizeChild
Type = Integer, Default = XcgRESIZE_NONE, Access = CG
defines whether a manager child is resized. possible values are:
XcgRESIZE_NONE
the child is not resized.
XcgRESIZE_VERTICAL
the child is resized to be the height of the page. Its width is
not
altered.
XcgRESIZE_HORIZONTAL
the child is resized to be the width of the page. Its height is
not
altered.
XcgRESIZE_BOTH
the child is resized to be the width and height of the page. This
is
the recommended setting for a TabBook that is a child of another
TabBook.
XcgNanchorChild
Type = Integer, Default = XcgANCHOR_NORTHWEST, Access = CG
Controls the placement of the child manager within the page. Possible
values are:
XcgANCHOR_CENTER
The child is centered, horizontally and vertically.
XcgANCHOR_EAST
The child is right aligned and centered vertically.
XcgANCHOR_NORTH
The child is top aligned and centered horizontally.
XcgANCHOR_NORTHEAST
The child is top right aligned.
XcgANCHOR_NORTHWEST
The child is top left aligned.
XcgANCHOR_SOUTH
The child is bottom aligned and centered horizontally.
XcgANCHOR_SOUTHEAST
The child is bottom right aligned.
XcgANCHOR_SOUTHWEST
The child is bottom left aligned.
XcgANCHOR_WEST
The child is left aligned and centered vertically.
7. Callbacks
The XcgNnewPageCallback callback is invoked when the user presses a tab
button for a new page. If the user clicks the tab button of the current
page, no action is taken at all. The callback is also called when the
resource XcgNactivePage changes or optionally on a call of
XcgTabBookSetActivePage. Finally, it is called when the TabBook widget is
initially managed. In that case, the prev_active_page field is zero.
The callback passes a pointer to the following structure:
typedef struct _XcgTabBookCallbackData {
XcgTabBookReasonType reason; /* reason for callback */
XEvent *event; /* button event, NULL if emulated
*/
int prev_active_page; /* 0 when initially called */
int active_page; /* new active page (1,2...) */
Widget button; /* the button widget which was
pressed (emulated or actual*/
Boolean ret_veto; /* caller may set to True to stop
page change */
int future1;
void * future2; } XcgTabBookCallbackData;
reason
set to XcgNewPage event
The XEvent of the button activate, or NULL if the callback was
emulated. prev_active_page
The page number that was previously active, or zero if this is the
first
time. active_page
The page number of the newly active page. button
The push button that was pressed, or NULL if emulated. ret_veto
initialized to False. If the callback sets to True, then the button
press
is ignored. No change is made to a new active page. future
Set to zero
8. Translations
TabBook has no translations.
9. TabBook API
TabBook contains the following functions that control the widget behavior.
9.1 XcgTabBookSetActivePage -- The active page is changed
Function
The active page is changed to the passed page number. Page numbers
begin
with 1. If this results in a new active page, the effect is as if the
user
pressed the corresponding tab button. It is also equivalent to setting
the
resource, XcgNactivePage. However, the NewPage callback that would
normally be called under these circumstances can be optionally
suppressed.
See Section 10 for details.
C-call
Boolean XcgTabBookSetActivePage(Widget w, int page, int option )
Input
w TabBook widget
page the page number to activate.
option
bitmapped
XcgTabBook_OPT_NO_CB - don't call NewPage callback
Output
Nothing
Return
True - page has been changed
False - non-existent page number
9.2 XcgTabBookGetActivePage -- The active page is returned
Function
C-call
int XcgTabBookGetActivePage(Widget w)
Input
w TabBook widget
Output
Nothing
Return
The current active page number (1,2,...)
A zero means the widget has not been managed at least once.
10. Widget Logic
When the resource autoManage is set, TabBook handles all details of page
management. Each child manager widget is forced to be un-managed except for
the one corresponding to the active page. When the user presses a tab
pushbutton, the old manager is un-managed and the new active page's manager
widget is managed so it appears. The order of insertion of child widgets
into TabBook determines the correspondence of pushbutton tabs to manager
widgets. You may insert all pushbuttons then all manager widgets or you may
interleave them. The first pushbutton inserted corresponds to the first
manager widget inserted and these constitute page 1.
In order to monitor when the user changes pages, You may add a callback to
each tab pushbutton or you can use the XcgNnewPageCallback callback. The
latter technique allows you to veto the change in page if, for example, you
detect an error.